summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/Makefile64
-rw-r--r--lib/libc/amd64/SYS.h73
-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.c66
-rw-r--r--lib/libc/amd64/gen/ldexp.c74
-rw-r--r--lib/libc/amd64/gen/setjmp.S93
-rw-r--r--lib/libc/amd64/gen/sigsetjmp.S105
-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.inc10
-rw-r--r--lib/libc/amd64/sys/brk.S92
-rw-r--r--lib/libc/amd64/sys/cerror.S58
-rw-r--r--lib/libc/amd64/sys/exect.S55
-rw-r--r--lib/libc/amd64/sys/pipe.S51
-rw-r--r--lib/libc/amd64/sys/ptrace.S61
-rw-r--r--lib/libc/amd64/sys/reboot.S47
-rw-r--r--lib/libc/amd64/sys/sbrk.S96
-rw-r--r--lib/libc/amd64/sys/setlogin.S59
-rw-r--r--lib/libc/amd64/sys/sigreturn.S57
-rw-r--r--lib/libc/amd64/sys/vfork.S81
-rw-r--r--lib/libc/compat-43/Makefile.inc16
-rw-r--r--lib/libc/compat-43/creat.260
-rw-r--r--lib/libc/compat-43/creat.c49
-rw-r--r--lib/libc/compat-43/gethostid.375
-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.295
-rw-r--r--lib/libc/compat-43/killpg.c58
-rw-r--r--lib/libc/compat-43/sethostid.c57
-rw-r--r--lib/libc/compat-43/setpgrp.c49
-rw-r--r--lib/libc/compat-43/setrgid.c50
-rw-r--r--lib/libc/compat-43/setruid.379
-rw-r--r--lib/libc/compat-43/setruid.c50
-rw-r--r--lib/libc/compat-43/sigblock.284
-rw-r--r--lib/libc/compat-43/sigcompat.c81
-rw-r--r--lib/libc/compat-43/sigpause.274
-rw-r--r--lib/libc/compat-43/sigsetmask.282
-rw-r--r--lib/libc/compat-43/sigvec.2325
-rw-r--r--lib/libc/db/Makefile.inc10
-rw-r--r--lib/libc/db/VERSION97
-rw-r--r--lib/libc/db/btree/Makefile.inc7
-rw-r--r--lib/libc/db/btree/bt_close.c204
-rw-r--r--lib/libc/db/btree/bt_conv.c221
-rw-r--r--lib/libc/db/btree/bt_debug.c331
-rw-r--r--lib/libc/db/btree/bt_delete.c324
-rw-r--r--lib/libc/db/btree/bt_get.c238
-rw-r--r--lib/libc/db/btree/bt_open.c440
-rw-r--r--lib/libc/db/btree/bt_overflow.c224
-rw-r--r--lib/libc/db/btree/bt_page.c93
-rw-r--r--lib/libc/db/btree/bt_put.c318
-rw-r--r--lib/libc/db/btree/bt_search.c235
-rw-r--r--lib/libc/db/btree/bt_seq.c380
-rw-r--r--lib/libc/db/btree/bt_split.c825
-rw-r--r--lib/libc/db/btree/bt_stack.c92
-rw-r--r--lib/libc/db/btree/bt_utils.c247
-rw-r--r--lib/libc/db/btree/btree.h353
-rw-r--r--lib/libc/db/btree/extern.h70
-rw-r--r--lib/libc/db/db/Makefile.inc5
-rw-r--r--lib/libc/db/db/db.c99
-rw-r--r--lib/libc/db/doc/hash.usenix.ps12209
-rw-r--r--lib/libc/db/doc/libtp.usenix.ps12340
-rw-r--r--lib/libc/db/hash/Makefile.inc6
-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.c994
-rw-r--r--lib/libc/db/hash/hash.h284
-rw-r--r--lib/libc/db/hash/hash_bigkey.c667
-rw-r--r--lib/libc/db/hash/hash_buf.c347
-rw-r--r--lib/libc/db/hash/hash_func.c212
-rw-r--r--lib/libc/db/hash/hash_log2.c52
-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.c202
-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.inc8
-rw-r--r--lib/libc/db/man/btree.3226
-rw-r--r--lib/libc/db/man/dbopen.3476
-rw-r--r--lib/libc/db/man/hash.3152
-rw-r--r--lib/libc/db/man/mpool.3219
-rw-r--r--lib/libc/db/man/recno.3196
-rw-r--r--lib/libc/db/mpool/Makefile.inc5
-rw-r--r--lib/libc/db/mpool/README7
-rw-r--r--lib/libc/db/mpool/mpool.c534
-rw-r--r--lib/libc/db/recno/Makefile.inc6
-rw-r--r--lib/libc/db/recno/extern.h54
-rw-r--r--lib/libc/db/recno/rec_close.c163
-rw-r--r--lib/libc/db/recno/rec_delete.c197
-rw-r--r--lib/libc/db/recno/rec_get.c298
-rw-r--r--lib/libc/db/recno/rec_open.c230
-rw-r--r--lib/libc/db/recno/rec_put.c253
-rw-r--r--lib/libc/db/recno/rec_search.c127
-rw-r--r--lib/libc/db/recno/rec_seq.c131
-rw-r--r--lib/libc/db/recno/rec_utils.c114
-rw-r--r--lib/libc/db/recno/recno.h39
-rw-r--r--lib/libc/db/test/Makefile17
-rw-r--r--lib/libc/db/test/README55
-rw-r--r--lib/libc/db/test/btree.tests/main.c765
-rw-r--r--lib/libc/db/test/dbtest.c666
-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.test699
-rw-r--r--lib/libc/gen/Makefile.inc114
-rw-r--r--lib/libc/gen/__xuname.c125
-rw-r--r--lib/libc/gen/_rand48.c46
-rw-r--r--lib/libc/gen/alarm.386
-rw-r--r--lib/libc/gen/alarm.c59
-rw-r--r--lib/libc/gen/assert.c53
-rw-r--r--lib/libc/gen/clock.367
-rw-r--r--lib/libc/gen/clock.c57
-rw-r--r--lib/libc/gen/closedir.c60
-rw-r--r--lib/libc/gen/config.c187
-rw-r--r--lib/libc/gen/config_open.373
-rw-r--r--lib/libc/gen/confstr.3123
-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.393
-rw-r--r--lib/libc/gen/ctermid.c53
-rw-r--r--lib/libc/gen/daemon.374
-rw-r--r--lib/libc/gen/daemon.c71
-rw-r--r--lib/libc/gen/devname.366
-rw-r--r--lib/libc/gen/devname.c80
-rw-r--r--lib/libc/gen/directory.3183
-rw-r--r--lib/libc/gen/disklabel.c169
-rw-r--r--lib/libc/gen/drand48.c22
-rw-r--r--lib/libc/gen/erand48.c23
-rw-r--r--lib/libc/gen/err.3144
-rw-r--r--lib/libc/gen/err.c216
-rw-r--r--lib/libc/gen/errlst.c141
-rw-r--r--lib/libc/gen/exec.3258
-rw-r--r--lib/libc/gen/exec.c269
-rw-r--r--lib/libc/gen/fnmatch.3127
-rw-r--r--lib/libc/gen/fnmatch.c171
-rw-r--r--lib/libc/gen/frexp.385
-rw-r--r--lib/libc/gen/fstab.c227
-rw-r--r--lib/libc/gen/ftok.388
-rw-r--r--lib/libc/gen/ftok.c47
-rw-r--r--lib/libc/gen/fts-compat.c971
-rw-r--r--lib/libc/gen/fts-compat.h125
-rw-r--r--lib/libc/gen/fts.3748
-rw-r--r--lib/libc/gen/fts.c971
-rw-r--r--lib/libc/gen/getbootfile.371
-rw-r--r--lib/libc/gen/getbootfile.c55
-rw-r--r--lib/libc/gen/getbsize.379
-rw-r--r--lib/libc/gen/getbsize.c106
-rw-r--r--lib/libc/gen/getcap.3511
-rw-r--r--lib/libc/gen/getcap.c1049
-rw-r--r--lib/libc/gen/getcwd.3154
-rw-r--r--lib/libc/gen/getcwd.c234
-rw-r--r--lib/libc/gen/getdiskbyname.364
-rw-r--r--lib/libc/gen/getdomainname.398
-rw-r--r--lib/libc/gen/getdomainname.c59
-rw-r--r--lib/libc/gen/getfsent.3148
-rw-r--r--lib/libc/gen/getgrent.3204
-rw-r--r--lib/libc/gen/getgrent.c438
-rw-r--r--lib/libc/gen/getgrouplist.392
-rw-r--r--lib/libc/gen/getgrouplist.c91
-rw-r--r--lib/libc/gen/gethostname.397
-rw-r--r--lib/libc/gen/gethostname.c55
-rw-r--r--lib/libc/gen/getloadavg.364
-rw-r--r--lib/libc/gen/getloadavg.c71
-rw-r--r--lib/libc/gen/getlogin.c58
-rw-r--r--lib/libc/gen/getmntinfo.3108
-rw-r--r--lib/libc/gen/getmntinfo.c70
-rw-r--r--lib/libc/gen/getnetgrent.3128
-rw-r--r--lib/libc/gen/getnetgrent.c608
-rw-r--r--lib/libc/gen/getosreldate.c63
-rw-r--r--lib/libc/gen/getpagesize.361
-rw-r--r--lib/libc/gen/getpagesize.c53
-rw-r--r--lib/libc/gen/getpass.392
-rw-r--r--lib/libc/gen/getpass.c125
-rw-r--r--lib/libc/gen/getpwent.3217
-rw-r--r--lib/libc/gen/getpwent.c775
-rw-r--r--lib/libc/gen/getttyent.3177
-rw-r--r--lib/libc/gen/getttyent.c199
-rw-r--r--lib/libc/gen/getusershell.397
-rw-r--r--lib/libc/gen/getusershell.c137
-rw-r--r--lib/libc/gen/getvfsent.3226
-rw-r--r--lib/libc/gen/getvfsent.c248
-rw-r--r--lib/libc/gen/glob.3444
-rw-r--r--lib/libc/gen/glob.c846
-rw-r--r--lib/libc/gen/initgroups.383
-rw-r--r--lib/libc/gen/initgroups.c59
-rw-r--r--lib/libc/gen/isatty.c48
-rw-r--r--lib/libc/gen/isinf.372
-rw-r--r--lib/libc/gen/jrand48.c21
-rw-r--r--lib/libc/gen/lcong48.c30
-rw-r--r--lib/libc/gen/ldexp.377
-rw-r--r--lib/libc/gen/lrand48.c23
-rw-r--r--lib/libc/gen/modf.372
-rw-r--r--lib/libc/gen/mrand48.c23
-rw-r--r--lib/libc/gen/msgctl.c15
-rw-r--r--lib/libc/gen/msgget.c14
-rw-r--r--lib/libc/gen/msgrcv.c17
-rw-r--r--lib/libc/gen/msgsnd.c16
-rw-r--r--lib/libc/gen/nice.367
-rw-r--r--lib/libc/gen/nice.c58
-rw-r--r--lib/libc/gen/nlist.378
-rw-r--r--lib/libc/gen/nlist.c158
-rw-r--r--lib/libc/gen/nrand48.c21
-rw-r--r--lib/libc/gen/ntp_gettime.c59
-rw-r--r--lib/libc/gen/opendir.c101
-rw-r--r--lib/libc/gen/pause.384
-rw-r--r--lib/libc/gen/pause.c49
-rw-r--r--lib/libc/gen/popen.3182
-rw-r--r--lib/libc/gen/popen.c160
-rw-r--r--lib/libc/gen/psignal.392
-rw-r--r--lib/libc/gen/psignal.c65
-rw-r--r--lib/libc/gen/pw_scan.c141
-rw-r--r--lib/libc/gen/pw_scan.h36
-rw-r--r--lib/libc/gen/pwcache.390
-rw-r--r--lib/libc/gen/pwcache.c113
-rw-r--r--lib/libc/gen/raise.377
-rw-r--r--lib/libc/gen/raise.c45
-rw-r--r--lib/libc/gen/rand48.3160
-rw-r--r--lib/libc/gen/rand48.h30
-rw-r--r--lib/libc/gen/readdir.c72
-rw-r--r--lib/libc/gen/rewinddir.c48
-rw-r--r--lib/libc/gen/scandir.3106
-rw-r--r--lib/libc/gen/scandir.c136
-rw-r--r--lib/libc/gen/seed48.c36
-rw-r--r--lib/libc/gen/seekdir.c52
-rw-r--r--lib/libc/gen/semconfig.c13
-rw-r--r--lib/libc/gen/semctl.c15
-rw-r--r--lib/libc/gen/semget.c15
-rw-r--r--lib/libc/gen/semop.c15
-rw-r--r--lib/libc/gen/setdomainname.c62
-rw-r--r--lib/libc/gen/setflags.c150
-rw-r--r--lib/libc/gen/setflagsbyname.c150
-rw-r--r--lib/libc/gen/sethostname.c58
-rw-r--r--lib/libc/gen/setjmp.3172
-rw-r--r--lib/libc/gen/setjmperr.c53
-rw-r--r--lib/libc/gen/setmode.3105
-rw-r--r--lib/libc/gen/setmode.c453
-rw-r--r--lib/libc/gen/setproctitle.3111
-rw-r--r--lib/libc/gen/setproctitle.c119
-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.3106
-rw-r--r--lib/libc/gen/siginterrupt.c61
-rw-r--r--lib/libc/gen/siglist.c109
-rw-r--r--lib/libc/gen/signal.3222
-rw-r--r--lib/libc/gen/signal.c60
-rw-r--r--lib/libc/gen/sigsetops.3108
-rw-r--r--lib/libc/gen/sigsetops.c83
-rw-r--r--lib/libc/gen/sleep.383
-rw-r--r--lib/libc/gen/sleep.c97
-rw-r--r--lib/libc/gen/srand48.c30
-rw-r--r--lib/libc/gen/strtofflags.c150
-rw-r--r--lib/libc/gen/sysconf.3184
-rw-r--r--lib/libc/gen/sysconf.c188
-rw-r--r--lib/libc/gen/sysctl.3652
-rw-r--r--lib/libc/gen/sysctl.c178
-rw-r--r--lib/libc/gen/syslog.3263
-rw-r--r--lib/libc/gen/syslog.c312
-rw-r--r--lib/libc/gen/tcgetpgrp.379
-rw-r--r--lib/libc/gen/tcsendbreak.3154
-rw-r--r--lib/libc/gen/tcsetattr.3330
-rw-r--r--lib/libc/gen/tcsetpgrp.3100
-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.3136
-rw-r--r--lib/libc/gen/times.c67
-rw-r--r--lib/libc/gen/timezone.367
-rw-r--r--lib/libc/gen/timezone.c134
-rw-r--r--lib/libc/gen/ttyname.3126
-rw-r--r--lib/libc/gen/ttyname.c112
-rw-r--r--lib/libc/gen/ttyslot.c68
-rw-r--r--lib/libc/gen/tzset.3324
-rw-r--r--lib/libc/gen/ualarm.390
-rw-r--r--lib/libc/gen/ualarm.c65
-rw-r--r--lib/libc/gen/uname.392
-rw-r--r--lib/libc/gen/uname.c125
-rw-r--r--lib/libc/gen/unvis.3162
-rw-r--r--lib/libc/gen/unvis.c247
-rw-r--r--lib/libc/gen/usleep.385
-rw-r--r--lib/libc/gen/usleep.c99
-rw-r--r--lib/libc/gen/utime.387
-rw-r--r--lib/libc/gen/utime.c57
-rw-r--r--lib/libc/gen/valloc.375
-rw-r--r--lib/libc/gen/valloc.c50
-rw-r--r--lib/libc/gen/vis.3263
-rw-r--r--lib/libc/gen/vis.c186
-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.inc12
-rw-r--r--lib/libc/gmon/gmon.c254
-rw-r--r--lib/libc/gmon/mcount.c326
-rw-r--r--lib/libc/gmon/moncontrol.3101
-rw-r--r--lib/libc/i386/DEFS.h83
-rw-r--r--lib/libc/i386/SYS.h73
-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.c66
-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.S93
-rw-r--r--lib/libc/i386/gen/sigsetjmp.S105
-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.inc8
-rw-r--r--lib/libc/i386/string/bcmp.S70
-rw-r--r--lib/libc/i386/string/bcopy.S89
-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/memmove.S92
-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.inc10
-rw-r--r--lib/libc/i386/sys/Ovfork.S81
-rw-r--r--lib/libc/i386/sys/brk.S92
-rw-r--r--lib/libc/i386/sys/cerror.S58
-rw-r--r--lib/libc/i386/sys/exect.S55
-rw-r--r--lib/libc/i386/sys/fork.S51
-rw-r--r--lib/libc/i386/sys/i386_get_ldt.298
-rw-r--r--lib/libc/i386/sys/i386_get_ldt.c55
-rw-r--r--lib/libc/i386/sys/i386_set_ldt.c55
-rw-r--r--lib/libc/i386/sys/mount.S48
-rw-r--r--lib/libc/i386/sys/pipe.S51
-rw-r--r--lib/libc/i386/sys/ptrace.S61
-rw-r--r--lib/libc/i386/sys/reboot.S47
-rw-r--r--lib/libc/i386/sys/sbrk.S96
-rw-r--r--lib/libc/i386/sys/setlogin.S59
-rw-r--r--lib/libc/i386/sys/sigpending.S50
-rw-r--r--lib/libc/i386/sys/sigprocmask.S67
-rw-r--r--lib/libc/i386/sys/sigreturn.S57
-rw-r--r--lib/libc/i386/sys/sigsuspend.S57
-rw-r--r--lib/libc/i386/sys/syscall.S56
-rw-r--r--lib/libc/locale/Makefile.inc21
-rw-r--r--lib/libc/locale/ansi.c148
-rw-r--r--lib/libc/locale/collate.c213
-rw-r--r--lib/libc/locale/collate.h69
-rw-r--r--lib/libc/locale/ctype.3107
-rw-r--r--lib/libc/locale/ctype.c72
-rw-r--r--lib/libc/locale/euc.4231
-rw-r--r--lib/libc/locale/euc.5231
-rw-r--r--lib/libc/locale/euc.c222
-rw-r--r--lib/libc/locale/frune.c103
-rw-r--r--lib/libc/locale/isalnum.385
-rw-r--r--lib/libc/locale/isalpha.383
-rw-r--r--lib/libc/locale/isascii.358
-rw-r--r--lib/libc/locale/isblank.355
-rw-r--r--lib/libc/locale/iscntrl.375
-rw-r--r--lib/libc/locale/isctype.c174
-rw-r--r--lib/libc/locale/isdigit.370
-rw-r--r--lib/libc/locale/isgraph.387
-rw-r--r--lib/libc/locale/islower.374
-rw-r--r--lib/libc/locale/isprint.387
-rw-r--r--lib/libc/locale/ispunct.378
-rw-r--r--lib/libc/locale/isspace.370
-rw-r--r--lib/libc/locale/isupper.374
-rw-r--r--lib/libc/locale/isxdigit.373
-rw-r--r--lib/libc/locale/lconv.c70
-rw-r--r--lib/libc/locale/localeconv.c49
-rw-r--r--lib/libc/locale/mbrune.3157
-rw-r--r--lib/libc/locale/mbrune.c112
-rw-r--r--lib/libc/locale/multibyte.3241
-rw-r--r--lib/libc/locale/nomacros.c9
-rw-r--r--lib/libc/locale/none.c91
-rw-r--r--lib/libc/locale/rune.3269
-rw-r--r--lib/libc/locale/rune.c173
-rw-r--r--lib/libc/locale/runetype.c73
-rw-r--r--lib/libc/locale/setinvalidrune.c44
-rw-r--r--lib/libc/locale/setlocale.3324
-rw-r--r--lib/libc/locale/setlocale.c284
-rw-r--r--lib/libc/locale/setrunelocale.c119
-rw-r--r--lib/libc/locale/table.c192
-rw-r--r--lib/libc/locale/toascii.369
-rw-r--r--lib/libc/locale/tolower.388
-rw-r--r--lib/libc/locale/tolower.c69
-rw-r--r--lib/libc/locale/toupper.388
-rw-r--r--lib/libc/locale/toupper.c68
-rw-r--r--lib/libc/locale/utf2.486
-rw-r--r--lib/libc/locale/utf2.586
-rw-r--r--lib/libc/locale/utf2.c150
-rw-r--r--lib/libc/net/Makefile.inc43
-rw-r--r--lib/libc/net/byteorder.376
-rw-r--r--lib/libc/net/ether_addr.c219
-rw-r--r--lib/libc/net/ethers.3185
-rw-r--r--lib/libc/net/gethostbydns.c551
-rw-r--r--lib/libc/net/gethostbyht.c182
-rw-r--r--lib/libc/net/gethostbyname.3249
-rw-r--r--lib/libc/net/gethostbynis.c115
-rw-r--r--lib/libc/net/gethostnamadr.c195
-rw-r--r--lib/libc/net/getnetbyaddr.c56
-rw-r--r--lib/libc/net/getnetbydns.c305
-rw-r--r--lib/libc/net/getnetbyht.c159
-rw-r--r--lib/libc/net/getnetbynis.c134
-rw-r--r--lib/libc/net/getnetent.3151
-rw-r--r--lib/libc/net/getnetnamadr.c198
-rw-r--r--lib/libc/net/getproto.c55
-rw-r--r--lib/libc/net/getprotoent.3144
-rw-r--r--lib/libc/net/getprotoent.c119
-rw-r--r--lib/libc/net/getprotoname.c62
-rw-r--r--lib/libc/net/getservbyname.c65
-rw-r--r--lib/libc/net/getservbyport.c60
-rw-r--r--lib/libc/net/getservent.3155
-rw-r--r--lib/libc/net/getservent.c189
-rw-r--r--lib/libc/net/herror.c112
-rw-r--r--lib/libc/net/inet.3195
-rw-r--r--lib/libc/net/inet_addr.c152
-rw-r--r--lib/libc/net/inet_lnaof.c59
-rw-r--r--lib/libc/net/inet_makeaddr.c62
-rw-r--r--lib/libc/net/inet_netof.c58
-rw-r--r--lib/libc/net/inet_network.c93
-rw-r--r--lib/libc/net/inet_ntoa.c59
-rw-r--r--lib/libc/net/iso_addr.3110
-rw-r--r--lib/libc/net/iso_addr.c117
-rw-r--r--lib/libc/net/linkaddr.3131
-rw-r--r--lib/libc/net/linkaddr.c158
-rw-r--r--lib/libc/net/ns.3130
-rw-r--r--lib/libc/net/ns_addr.c227
-rw-r--r--lib/libc/net/ns_ntoa.c100
-rw-r--r--lib/libc/net/rcmd.3203
-rw-r--r--lib/libc/net/rcmd.c501
-rw-r--r--lib/libc/net/recv.c50
-rw-r--r--lib/libc/net/res_comp.c100
-rw-r--r--lib/libc/net/res_config.h7
-rw-r--r--lib/libc/net/res_debug.c153
-rw-r--r--lib/libc/net/res_init.c261
-rw-r--r--lib/libc/net/res_mkquery.c52
-rw-r--r--lib/libc/net/res_query.c64
-rw-r--r--lib/libc/net/res_send.c184
-rw-r--r--lib/libc/net/resolver.3323
-rw-r--r--lib/libc/net/send.c50
-rw-r--r--lib/libc/nls/Makefile.inc6
-rw-r--r--lib/libc/nls/catclose.354
-rw-r--r--lib/libc/nls/catclose.c25
-rw-r--r--lib/libc/nls/catgets.367
-rw-r--r--lib/libc/nls/catgets.c28
-rw-r--r--lib/libc/nls/catopen.382
-rw-r--r--lib/libc/nls/catopen.c26
-rw-r--r--lib/libc/nls/msgcat.c394
-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.inc14
-rw-r--r--lib/libc/regex/WHATSNEW94
-rw-r--r--lib/libc/regex/cclass.h70
-rw-r--r--lib/libc/regex/cname.h141
-rw-r--r--lib/libc/regex/engine.c1092
-rw-r--r--lib/libc/regex/re_format.7269
-rw-r--r--lib/libc/regex/regcomp.c1696
-rw-r--r--lib/libc/regex/regerror.c178
-rw-r--r--lib/libc/regex/regex.3538
-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.inc23
-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_none.c136
-rw-r--r--lib/libc/rpc/auth_unix.c349
-rw-r--r--lib/libc/rpc/authunix_prot.c68
-rw-r--r--lib/libc/rpc/bindresvport.327
-rw-r--r--lib/libc/rpc/bindresvport.c86
-rw-r--r--lib/libc/rpc/clnt_generic.c114
-rw-r--r--lib/libc/rpc/clnt_perror.c304
-rw-r--r--lib/libc/rpc/clnt_raw.c241
-rw-r--r--lib/libc/rpc/clnt_simple.c116
-rw-r--r--lib/libc/rpc/clnt_tcp.c471
-rw-r--r--lib/libc/rpc/clnt_udp.c447
-rw-r--r--lib/libc/rpc/get_myaddress.c100
-rw-r--r--lib/libc/rpc/getrpcent.3109
-rw-r--r--lib/libc/rpc/getrpcent.c299
-rw-r--r--lib/libc/rpc/getrpcport.331
-rw-r--r--lib/libc/rpc/getrpcport.c58
-rw-r--r--lib/libc/rpc/pmap_clnt.c118
-rw-r--r--lib/libc/rpc/pmap_getmaps.c87
-rw-r--r--lib/libc/rpc/pmap_getport.c90
-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.c399
-rw-r--r--lib/libc/rpc/rpc.31729
-rw-r--r--lib/libc/rpc/rpc.571
-rw-r--r--lib/libc/rpc/rpc_callmsg.c193
-rw-r--r--lib/libc/rpc/rpc_commondata.c46
-rw-r--r--lib/libc/rpc/rpc_dtablesize.c63
-rw-r--r--lib/libc/rpc/rpc_prot.c291
-rw-r--r--lib/libc/rpc/rstat.157
-rw-r--r--lib/libc/rpc/rstat_svc.821
-rw-r--r--lib/libc/rpc/svc.c483
-rw-r--r--lib/libc/rpc/svc_auth.c117
-rw-r--r--lib/libc/rpc/svc_auth_unix.c137
-rw-r--r--lib/libc/rpc/svc_raw.c168
-rw-r--r--lib/libc/rpc/svc_run.c73
-rw-r--r--lib/libc/rpc/svc_simple.c147
-rw-r--r--lib/libc/rpc/svc_tcp.c422
-rw-r--r--lib/libc/rpc/svc_udp.c482
-rw-r--r--lib/libc/stdio/Makefile.inc40
-rw-r--r--lib/libc/stdio/clrerr.c49
-rw-r--r--lib/libc/stdio/fclose.393
-rw-r--r--lib/libc/stdio/fclose.c67
-rw-r--r--lib/libc/stdio/fdopen.c89
-rw-r--r--lib/libc/stdio/feof.c52
-rw-r--r--lib/libc/stdio/ferror.3100
-rw-r--r--lib/libc/stdio/ferror.c52
-rw-r--r--lib/libc/stdio/fflush.3110
-rw-r--r--lib/libc/stdio/fflush.c89
-rw-r--r--lib/libc/stdio/fgetc.c47
-rw-r--r--lib/libc/stdio/fgetln.3123
-rw-r--r--lib/libc/stdio/fgetln.c160
-rw-r--r--lib/libc/stdio/fgetpos.c48
-rw-r--r--lib/libc/stdio/fgets.3151
-rw-r--r--lib/libc/stdio/fgets.c104
-rw-r--r--lib/libc/stdio/fileno.c52
-rw-r--r--lib/libc/stdio/findfp.c169
-rw-r--r--lib/libc/stdio/flags.c89
-rw-r--r--lib/libc/stdio/floatio.h46
-rw-r--r--lib/libc/stdio/fopen.3237
-rw-r--r--lib/libc/stdio/fopen.c84
-rw-r--r--lib/libc/stdio/fprintf.c68
-rw-r--r--lib/libc/stdio/fpurge.c65
-rw-r--r--lib/libc/stdio/fputc.c48
-rw-r--r--lib/libc/stdio/fputs.3107
-rw-r--r--lib/libc/stdio/fputs.c60
-rw-r--r--lib/libc/stdio/fread.3106
-rw-r--r--lib/libc/stdio/fread.c81
-rw-r--r--lib/libc/stdio/freopen.c155
-rw-r--r--lib/libc/stdio/fscanf.c68
-rw-r--r--lib/libc/stdio/fseek.3188
-rw-r--r--lib/libc/stdio/fseek.c246
-rw-r--r--lib/libc/stdio/fsetpos.c51
-rw-r--r--lib/libc/stdio/ftell.c88
-rw-r--r--lib/libc/stdio/funopen.3168
-rw-r--r--lib/libc/stdio/funopen.c81
-rw-r--r--lib/libc/stdio/fvwrite.c189
-rw-r--r--lib/libc/stdio/fvwrite.h56
-rw-r--r--lib/libc/stdio/fwalk.c59
-rw-r--r--lib/libc/stdio/fwrite.c72
-rw-r--r--lib/libc/stdio/getc.3136
-rw-r--r--lib/libc/stdio/getc.c52
-rw-r--r--lib/libc/stdio/getchar.c51
-rw-r--r--lib/libc/stdio/gets.c71
-rw-r--r--lib/libc/stdio/getw.c49
-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.3136
-rw-r--r--lib/libc/stdio/mktemp.c127
-rw-r--r--lib/libc/stdio/perror.c67
-rw-r--r--lib/libc/stdio/printf.3638
-rw-r--r--lib/libc/stdio/printf.c67
-rw-r--r--lib/libc/stdio/putc.3129
-rw-r--r--lib/libc/stdio/putc.c53
-rw-r--r--lib/libc/stdio/putchar.c54
-rw-r--r--lib/libc/stdio/puts.c63
-rw-r--r--lib/libc/stdio/putw.c56
-rw-r--r--lib/libc/stdio/refill.c128
-rw-r--r--lib/libc/stdio/remove.378
-rw-r--r--lib/libc/stdio/remove.c48
-rw-r--r--lib/libc/stdio/rewind.c51
-rw-r--r--lib/libc/stdio/rget.c56
-rw-r--r--lib/libc/stdio/scanf.3430
-rw-r--r--lib/libc/stdio/scanf.c67
-rw-r--r--lib/libc/stdio/setbuf.3202
-rw-r--r--lib/libc/stdio/setbuf.c50
-rw-r--r--lib/libc/stdio/setbuffer.c62
-rw-r--r--lib/libc/stdio/setvbuf.c160
-rw-r--r--lib/libc/stdio/snprintf.c76
-rw-r--r--lib/libc/stdio/sprintf.c75
-rw-r--r--lib/libc/stdio/sscanf.c88
-rw-r--r--lib/libc/stdio/stdio.3287
-rw-r--r--lib/libc/stdio/stdio.c104
-rw-r--r--lib/libc/stdio/tempnam.c86
-rw-r--r--lib/libc/stdio/tmpfile.c79
-rw-r--r--lib/libc/stdio/tmpnam.3219
-rw-r--r--lib/libc/stdio/tmpnam.c58
-rw-r--r--lib/libc/stdio/ungetc.395
-rw-r--r--lib/libc/stdio/ungetc.c148
-rw-r--r--lib/libc/stdio/vfprintf.c867
-rw-r--r--lib/libc/stdio/vfscanf.c748
-rw-r--r--lib/libc/stdio/vprintf.c48
-rw-r--r--lib/libc/stdio/vscanf.c49
-rw-r--r--lib/libc/stdio/vsnprintf.c60
-rw-r--r--lib/libc/stdio/vsprintf.c58
-rw-r--r--lib/libc/stdio/vsscanf.c69
-rw-r--r--lib/libc/stdio/wbuf.c88
-rw-r--r--lib/libc/stdio/wsetup.c90
-rw-r--r--lib/libc/stdlib/Makefile.inc30
-rw-r--r--lib/libc/stdlib/abort.370
-rw-r--r--lib/libc/stdlib/abort.c65
-rw-r--r--lib/libc/stdlib/abs.373
-rw-r--r--lib/libc/stdlib/abs.c45
-rw-r--r--lib/libc/stdlib/alloca.378
-rw-r--r--lib/libc/stdlib/atexit.377
-rw-r--r--lib/libc/stdlib/atexit.c66
-rw-r--r--lib/libc/stdlib/atexit.h45
-rw-r--r--lib/libc/stdlib/atof.387
-rw-r--r--lib/libc/stdlib/atof.c46
-rw-r--r--lib/libc/stdlib/atoi.373
-rw-r--r--lib/libc/stdlib/atoi.c45
-rw-r--r--lib/libc/stdlib/atol.374
-rw-r--r--lib/libc/stdlib/atol.c46
-rw-r--r--lib/libc/stdlib/bsearch.390
-rw-r--r--lib/libc/stdlib/bsearch.c81
-rw-r--r--lib/libc/stdlib/calloc.370
-rw-r--r--lib/libc/stdlib/calloc.c52
-rw-r--r--lib/libc/stdlib/div.367
-rw-r--r--lib/libc/stdlib/div.c79
-rw-r--r--lib/libc/stdlib/exit.383
-rw-r--r--lib/libc/stdlib/exit.c60
-rw-r--r--lib/libc/stdlib/getenv.3151
-rw-r--r--lib/libc/stdlib/getenv.c91
-rw-r--r--lib/libc/stdlib/getopt.3252
-rw-r--r--lib/libc/stdlib/getopt.c117
-rw-r--r--lib/libc/stdlib/getsubopt.3145
-rw-r--r--lib/libc/stdlib/getsubopt.c98
-rw-r--r--lib/libc/stdlib/heapsort.c184
-rw-r--r--lib/libc/stdlib/labs.366
-rw-r--r--lib/libc/stdlib/labs.c45
-rw-r--r--lib/libc/stdlib/ldiv.370
-rw-r--r--lib/libc/stdlib/ldiv.c58
-rw-r--r--lib/libc/stdlib/malloc.3191
-rw-r--r--lib/libc/stdlib/malloc.c1155
-rw-r--r--lib/libc/stdlib/memory.370
-rw-r--r--lib/libc/stdlib/merge.c347
-rw-r--r--lib/libc/stdlib/putenv.c58
-rw-r--r--lib/libc/stdlib/qsort.3233
-rw-r--r--lib/libc/stdlib/qsort.c179
-rw-r--r--lib/libc/stdlib/radixsort.3160
-rw-r--r--lib/libc/stdlib/radixsort.c318
-rw-r--r--lib/libc/stdlib/rand.384
-rw-r--r--lib/libc/stdlib/rand.c54
-rw-r--r--lib/libc/stdlib/random.3166
-rw-r--r--lib/libc/stdlib/random.c363
-rw-r--r--lib/libc/stdlib/realpath.3125
-rw-r--r--lib/libc/stdlib/realpath.c158
-rw-r--r--lib/libc/stdlib/setenv.c116
-rw-r--r--lib/libc/stdlib/strhash.c432
-rw-r--r--lib/libc/stdlib/strtod.3132
-rw-r--r--lib/libc/stdlib/strtod.c2443
-rw-r--r--lib/libc/stdlib/strtol.3168
-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.3163
-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.393
-rw-r--r--lib/libc/stdlib/system.c76
-rw-r--r--lib/libc/stdtime/Makefile.inc10
-rw-r--r--lib/libc/stdtime/asctime.c56
-rw-r--r--lib/libc/stdtime/ctime.3258
-rw-r--r--lib/libc/stdtime/difftime.c74
-rw-r--r--lib/libc/stdtime/localtime.c1612
-rw-r--r--lib/libc/stdtime/private.h200
-rw-r--r--lib/libc/stdtime/strftime.3214
-rw-r--r--lib/libc/stdtime/strftime.c576
-rw-r--r--lib/libc/stdtime/time2posix.3119
-rw-r--r--lib/libc/stdtime/tzfile.5122
-rw-r--r--lib/libc/stdtime/tzfile.h180
-rw-r--r--lib/libc/string/Makefile.inc97
-rw-r--r--lib/libc/string/bcmp.372
-rw-r--r--lib/libc/string/bcmp.c59
-rw-r--r--lib/libc/string/bcopy.371
-rw-r--r--lib/libc/string/bcopy.c139
-rw-r--r--lib/libc/string/bstring.3109
-rw-r--r--lib/libc/string/bzero.368
-rw-r--r--lib/libc/string/ffs.361
-rw-r--r--lib/libc/string/ffs.c54
-rw-r--r--lib/libc/string/index.380
-rw-r--r--lib/libc/string/index.c57
-rw-r--r--lib/libc/string/memccpy.372
-rw-r--r--lib/libc/string/memccpy.c59
-rw-r--r--lib/libc/string/memchr.381
-rw-r--r--lib/libc/string/memchr.c59
-rw-r--r--lib/libc/string/memcmp.382
-rw-r--r--lib/libc/string/memcmp.c61
-rw-r--r--lib/libc/string/memcpy.383
-rw-r--r--lib/libc/string/memmove.375
-rw-r--r--lib/libc/string/memset.370
-rw-r--r--lib/libc/string/memset.c130
-rw-r--r--lib/libc/string/rindex.382
-rw-r--r--lib/libc/string/rindex.c59
-rw-r--r--lib/libc/string/strcasecmp.386
-rw-r--r--lib/libc/string/strcasecmp.c115
-rw-r--r--lib/libc/string/strcat.393
-rw-r--r--lib/libc/string/strcat.c50
-rw-r--r--lib/libc/string/strchr.387
-rw-r--r--lib/libc/string/strcmp.393
-rw-r--r--lib/libc/string/strcmp.c55
-rw-r--r--lib/libc/string/strcoll.372
-rw-r--r--lib/libc/string/strcoll.c78
-rw-r--r--lib/libc/string/strcpy.3121
-rw-r--r--lib/libc/string/strcpy.c50
-rw-r--r--lib/libc/string/strcspn.384
-rw-r--r--lib/libc/string/strcspn.c68
-rw-r--r--lib/libc/string/strdup.363
-rw-r--r--lib/libc/string/strdup.c54
-rw-r--r--lib/libc/string/strerror.3124
-rw-r--r--lib/libc/string/strerror.c71
-rw-r--r--lib/libc/string/string.3155
-rw-r--r--lib/libc/string/strlen.370
-rw-r--r--lib/libc/string/strlen.c50
-rw-r--r--lib/libc/string/strmode.3147
-rw-r--r--lib/libc/string/strmode.c147
-rw-r--r--lib/libc/string/strncat.c68
-rw-r--r--lib/libc/string/strncmp.c56
-rw-r--r--lib/libc/string/strncpy.c68
-rw-r--r--lib/libc/string/strpbrk.379
-rw-r--r--lib/libc/string/strpbrk.c57
-rw-r--r--lib/libc/string/strrchr.390
-rw-r--r--lib/libc/string/strsep.3107
-rw-r--r--lib/libc/string/strsep.c80
-rw-r--r--lib/libc/string/strspn.379
-rw-r--r--lib/libc/string/strspn.c61
-rw-r--r--lib/libc/string/strstr.388
-rw-r--r--lib/libc/string/strstr.c65
-rw-r--r--lib/libc/string/strtok.3110
-rw-r--r--lib/libc/string/strtok.c90
-rw-r--r--lib/libc/string/strxfrm.377
-rw-r--r--lib/libc/string/strxfrm.c92
-rw-r--r--lib/libc/string/swab.365
-rw-r--r--lib/libc/string/swab.c65
-rw-r--r--lib/libc/sys/Makefile.inc141
-rw-r--r--lib/libc/sys/_exit.2112
-rw-r--r--lib/libc/sys/accept.2166
-rw-r--r--lib/libc/sys/access.2130
-rw-r--r--lib/libc/sys/acct.2115
-rw-r--r--lib/libc/sys/adjtime.2111
-rw-r--r--lib/libc/sys/bind.2126
-rw-r--r--lib/libc/sys/brk.2146
-rw-r--r--lib/libc/sys/chdir.2129
-rw-r--r--lib/libc/sys/chflags.2154
-rw-r--r--lib/libc/sys/chmod.2182
-rw-r--r--lib/libc/sys/chown.2148
-rw-r--r--lib/libc/sys/chroot.297
-rw-r--r--lib/libc/sys/close.2120
-rw-r--r--lib/libc/sys/connect.2147
-rw-r--r--lib/libc/sys/dup.2132
-rw-r--r--lib/libc/sys/execve.2261
-rw-r--r--lib/libc/sys/fcntl.2481
-rw-r--r--lib/libc/sys/flock.2145
-rw-r--r--lib/libc/sys/fork.2108
-rw-r--r--lib/libc/sys/fsync.281
-rw-r--r--lib/libc/sys/ftruncate.c52
-rw-r--r--lib/libc/sys/getdirentries.2152
-rw-r--r--lib/libc/sys/getdtablesize.260
-rw-r--r--lib/libc/sys/getfh.296
-rw-r--r--lib/libc/sys/getfsstat.2135
-rw-r--r--lib/libc/sys/getgid.279
-rw-r--r--lib/libc/sys/getgroups.290
-rw-r--r--lib/libc/sys/getitimer.2166
-rw-r--r--lib/libc/sys/getlogin.2126
-rw-r--r--lib/libc/sys/getpeername.289
-rw-r--r--lib/libc/sys/getpgrp.2101
-rw-r--r--lib/libc/sys/getpid.272
-rw-r--r--lib/libc/sys/getpriority.2142
-rw-r--r--lib/libc/sys/getrlimit.2182
-rw-r--r--lib/libc/sys/getrusage.2165
-rw-r--r--lib/libc/sys/getsockname.287
-rw-r--r--lib/libc/sys/getsockopt.2354
-rw-r--r--lib/libc/sys/gettimeofday.2119
-rw-r--r--lib/libc/sys/getuid.280
-rw-r--r--lib/libc/sys/intro.2668
-rw-r--r--lib/libc/sys/ioctl.2106
-rw-r--r--lib/libc/sys/kill.2131
-rw-r--r--lib/libc/sys/ktrace.2162
-rw-r--r--lib/libc/sys/link.2151
-rw-r--r--lib/libc/sys/listen.2120
-rw-r--r--lib/libc/sys/lseek.2135
-rw-r--r--lib/libc/sys/lseek.c54
-rw-r--r--lib/libc/sys/madvise.266
-rw-r--r--lib/libc/sys/mincore.261
-rw-r--r--lib/libc/sys/mkdir.2113
-rw-r--r--lib/libc/sys/mkfifo.2124
-rw-r--r--lib/libc/sys/mknod.2127
-rw-r--r--lib/libc/sys/mlock.2161
-rw-r--r--lib/libc/sys/mmap.2210
-rw-r--r--lib/libc/sys/mmap.c58
-rw-r--r--lib/libc/sys/mount.2314
-rw-r--r--lib/libc/sys/mprotect.258
-rw-r--r--lib/libc/sys/msync.291
-rw-r--r--lib/libc/sys/munmap.278
-rw-r--r--lib/libc/sys/nfssvc.2238
-rw-r--r--lib/libc/sys/open.2257
-rw-r--r--lib/libc/sys/pathconf.2163
-rw-r--r--lib/libc/sys/pipe.2123
-rw-r--r--lib/libc/sys/profil.2129
-rw-r--r--lib/libc/sys/quotactl.2213
-rw-r--r--lib/libc/sys/read.2189
-rw-r--r--lib/libc/sys/readlink.296
-rw-r--r--lib/libc/sys/reboot.2158
-rw-r--r--lib/libc/sys/recv.2263
-rw-r--r--lib/libc/sys/rename.2199
-rw-r--r--lib/libc/sys/revoke.2105
-rw-r--r--lib/libc/sys/rmdir.2106
-rw-r--r--lib/libc/sys/rtprio.2106
-rw-r--r--lib/libc/sys/select.2188
-rw-r--r--lib/libc/sys/semctl.2173
-rw-r--r--lib/libc/sys/semget.2137
-rw-r--r--lib/libc/sys/semop.2192
-rw-r--r--lib/libc/sys/send.2179
-rw-r--r--lib/libc/sys/setgroups.283
-rw-r--r--lib/libc/sys/setpgid.289
-rw-r--r--lib/libc/sys/setregid.291
-rw-r--r--lib/libc/sys/setreuid.289
-rw-r--r--lib/libc/sys/setsid.279
-rw-r--r--lib/libc/sys/setuid.2122
-rw-r--r--lib/libc/sys/shmat.2110
-rw-r--r--lib/libc/sys/shmctl.2136
-rw-r--r--lib/libc/sys/shmget.2138
-rw-r--r--lib/libc/sys/shutdown.281
-rw-r--r--lib/libc/sys/sigaction.2370
-rw-r--r--lib/libc/sys/sigaltstack.2165
-rw-r--r--lib/libc/sys/sigpending.272
-rw-r--r--lib/libc/sys/sigprocmask.2120
-rw-r--r--lib/libc/sys/sigreturn.297
-rw-r--r--lib/libc/sys/sigstack.251
-rw-r--r--lib/libc/sys/sigsuspend.280
-rw-r--r--lib/libc/sys/socket.2270
-rw-r--r--lib/libc/sys/socketpair.291
-rw-r--r--lib/libc/sys/stat.2276
-rw-r--r--lib/libc/sys/statfs.2161
-rw-r--r--lib/libc/sys/swapon.2113
-rw-r--r--lib/libc/sys/symlink.2139
-rw-r--r--lib/libc/sys/sync.273
-rw-r--r--lib/libc/sys/syscall.276
-rw-r--r--lib/libc/sys/truncate.2123
-rw-r--r--lib/libc/sys/truncate.c52
-rw-r--r--lib/libc/sys/umask.282
-rw-r--r--lib/libc/sys/unlink.2112
-rw-r--r--lib/libc/sys/utimes.2118
-rw-r--r--lib/libc/sys/vfork.2126
-rw-r--r--lib/libc/sys/wait.2295
-rw-r--r--lib/libc/sys/write.2205
-rw-r--r--lib/libc/xdr/Makefile.inc7
-rw-r--r--lib/libc/xdr/xdr.3823
-rw-r--r--lib/libc/xdr/xdr.c579
-rw-r--r--lib/libc/xdr/xdr_array.c156
-rw-r--r--lib/libc/xdr/xdr_float.c283
-rw-r--r--lib/libc/xdr/xdr_mem.c186
-rw-r--r--lib/libc/xdr/xdr_rec.c585
-rw-r--r--lib/libc/xdr/xdr_reference.c136
-rw-r--r--lib/libc/xdr/xdr_stdio.c191
-rw-r--r--lib/libc/yp/Makefile.inc17
-rw-r--r--lib/libc/yp/xdryp.c115
-rw-r--r--lib/libc/yp/yplib.c910
919 files changed, 163114 insertions, 555 deletions
diff --git a/lib/libc/Makefile b/lib/libc/Makefile
new file mode 100644
index 0000000..c52d671
--- /dev/null
+++ b/lib/libc/Makefile
@@ -0,0 +1,64 @@
+# @(#)Makefile 8.2 (Berkeley) 2/3/94
+#
+# 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= 2
+SHLIB_MINOR= 2
+CFLAGS+=-DLIBC_RCS -DSYSLIBC_RCS
+AINC= -I${.CURDIR}/${MACHINE}
+CLEANFILES+=tags
+INSTALL_PIC_ARCHIVE= yes
+PRECIOUSLIB= yes
+
+.include "${.CURDIR}/db/Makefile.inc"
+.include "${.CURDIR}/compat-43/Makefile.inc"
+.include "${.CURDIR}/gen/Makefile.inc"
+.include "${.CURDIR}/gmon/Makefile.inc"
+.include "${.CURDIR}/locale/Makefile.inc"
+.include "${.CURDIR}/net/Makefile.inc"
+.include "${.CURDIR}/nls/Makefile.inc"
+.include "${.CURDIR}/quad/Makefile.inc"
+.include "${.CURDIR}/regex/Makefile.inc"
+.include "${.CURDIR}/stdio/Makefile.inc"
+.include "${.CURDIR}/stdlib/Makefile.inc"
+.include "${.CURDIR}/stdtime/Makefile.inc"
+.include "${.CURDIR}/string/Makefile.inc"
+.include "${.CURDIR}/sys/Makefile.inc"
+.include "${.CURDIR}/rpc/Makefile.inc"
+.include "${.CURDIR}/xdr/Makefile.inc"
+.if !defined(NO_YP_LIBC)
+CFLAGS+= -DYP
+.include "${.CURDIR}/yp/Makefile.inc"
+.endif
+.include "${.CURDIR}/${MACHINE}/sys/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}
+
+libkern.gen: ${KQSRCS} ${KSRCS}
+ cp -p ${.CURDIR}/quad/quad.h ${.ALLSRC} /sys/libkern
+
+libkern.${MACHINE}:: ${KMSRCS}
+.if defined(KMSRCS) && !empty(KMSRCS)
+ cp -p ${.ALLSRC} /sys/libkern/${MACHINE}
+.endif
+
+#beforeinstall: tags
+# ${INSTALL} ${COPY} -o bin -g bin -m 444 tags /var/db/libc.tags
+
+tags: ${SRCS}
+ ctags ${.ALLSRC:M*.c}
+ egrep -o "^ENTRY(.*)|^FUNC(.*)|^SYSCALL(.*)" ${.ALLSRC:M*.s} | \
+ sed "s;\([^:]*\):\([^(]*\)(\([^, )]*\)\(.*\);\3 \1 /^\2(\3\4$$/;" \
+ >> tags; sort -o tags tags
+
+.include <bsd.lib.mk>
diff --git a/lib/libc/amd64/SYS.h b/lib/libc/amd64/SYS.h
new file mode 100644
index 0000000..53837ab
--- /dev/null
+++ b/lib/libc/amd64/SYS.h
@@ -0,0 +1,73 @@
+/*-
+ * 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
+ *
+ * $Id: SYS.h,v 1.3 1993/11/04 00:01:17 paul Exp $
+ */
+
+#include <sys/syscall.h>
+#include "DEFS.h"
+
+#ifdef PIC
+#define PIC_PROLOGUE \
+ pushl %ebx; \
+ call 1f; \
+1: \
+ popl %ebx; \
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+#define PIC_EPILOGUE \
+ popl %ebx
+#define PIC_PLT(x) x@PLT
+#define PIC_GOT(x) x@GOT(%ebx)
+#define PIC_GOTOFF(x) x@GOTOFF(%ebx)
+#else
+#define PIC_PROLOGUE
+#define PIC_EPILOGUE
+#define PIC_PLT(x) x
+#define PIC_GOT(x) x
+#define PIC_GOTOFF(x) x
+#endif
+
+#define SYSCALL(x) 2: jmp cerror; ENTRY(x); lea SYS_/**/x,%eax; LCALL(7,0); jb 2b
+#define RSYSCALL(x) SYSCALL(x); ret
+#define PSEUDO(x,y) ENTRY(x); lea SYS_/**/y, %eax; ; LCALL(7,0); ret
+#define CALL(x,y) call _/**/y; addl $4*x,%esp
+/* gas fucks up offset -- although we don't currently need it, do for BCS */
+#define LCALL(x,y) .byte 0x9a ; .long y; .word x
+
+#define ASMSTR .asciz
+
+ .globl cerror
diff --git a/lib/libc/amd64/gen/Makefile.inc b/lib/libc/amd64/gen/Makefile.inc
new file mode 100644
index 0000000..387aebf
--- /dev/null
+++ b/lib/libc/amd64/gen/Makefile.inc
@@ -0,0 +1,5 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $Id: Makefile.inc,v 1.5 1995/01/23 01:26:39 davidg Exp $
+
+SRCS+= isinf.c infinity.c
+SRCS+= _setjmp.S alloca.S fabs.S 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..abd2684
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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 28(%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 28(%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..aba4802
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$Id$";
+#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..e46f676
--- /dev/null
+++ b/lib/libc/amd64/gen/infinity.c
@@ -0,0 +1,9 @@
+/*
+ * infinity.c
+ * $Id$
+ */
+
+#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..c328449
--- /dev/null
+++ b/lib/libc/amd64/gen/isinf.c
@@ -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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$Id$";
+#endif /* LIBC_RCS and not lint */
+
+#include <sys/types.h>
+
+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));
+}
+
+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..8b63f52
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$Id$";
+#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..fa52b83
--- /dev/null
+++ b/lib/libc/amd64/gen/setjmp.S
@@ -0,0 +1,93 @@
+/*-
+ * 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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)
+ pushl $0
+ call PIC_PLT(_sigblock)
+ popl %edx
+ 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)
+ movl %eax,24(%ecx)
+ fnstcw 28(%ecx)
+ xorl %eax,%eax
+ ret
+
+ENTRY(longjmp)
+ movl 4(%esp),%edx
+ pushl 24(%edx)
+ call PIC_PLT(_sigsetmask) /* XXX this is not reentrant */
+ popl %eax
+ 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 28(%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..4f592a3
--- /dev/null
+++ b/lib/libc/amd64/gen/sigsetjmp.S
@@ -0,0 +1,105 @@
+/*-
+ * 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.
+ *
+ * $Id: sigsetjmp.S,v 1.3 1994/12/27 13:34:04 bde Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: sigsetjmp.S,v 1.3 1994/12/27 13:34:04 bde Exp $"
+#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)
+ movl 8(%esp),%eax
+ movl 4(%esp),%ecx
+ movl %eax,32(%ecx)
+ testl %eax,%eax
+ jz 1f
+ pushl $0
+ call PIC_PLT(_sigblock)
+ addl $4,%esp
+ movl 4(%esp),%ecx
+ movl %eax,24(%ecx)
+1: 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 28(%ecx)
+ xorl %eax,%eax
+ ret
+
+ENTRY(siglongjmp)
+ movl 4(%esp),%edx
+ cmpl $0,32(%edx)
+ jz 1f
+ pushl 24(%edx)
+ call PIC_PLT(_sigsetmask)
+ addl $4,%esp
+1: 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 28(%edx)
+ testl %eax,%eax
+ jnz 2f
+ incl %eax
+2: 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..dff7fd1
--- /dev/null
+++ b/lib/libc/amd64/net/Makefile.inc
@@ -0,0 +1,4 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $Id$
+
+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..095c40a
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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..238dfc2
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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..5af5008
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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..4bed4a2
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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..6774dd3
--- /dev/null
+++ b/lib/libc/amd64/sys/Makefile.inc
@@ -0,0 +1,10 @@
+# from: Makefile.inc,v 1.1 1993/09/03 19:04:23 jtc Exp
+# $Id$
+
+.PATH: ${.CURDIR}/${MACHINE}/sys
+
+SRCS+= i386_get_ldt.c i386_set_ldt.c
+
+MAN2+= i386/sys/i386_get_ldt.2
+
+MLINKS+=i386_get_ldt.2 i386_set_ldt.2
diff --git a/lib/libc/amd64/sys/brk.S b/lib/libc/amd64/sys/brk.S
new file mode 100644
index 0000000..c8311bb
--- /dev/null
+++ b/lib/libc/amd64/sys/brk.S
@@ -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.
+ *
+ * $Id: brk.S,v 1.1 1994/08/05 01:18:39 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+#define SYS_brk 17
+
+ .globl curbrk
+ .globl minbrk
+ENTRY(_brk)
+ jmp ok
+
+ENTRY(brk)
+#ifdef PIC
+ movl 4(%esp),%eax
+ PIC_PROLOGUE
+ movl PIC_GOT(curbrk),%edx # set up GOT addressing
+ movl PIC_GOT(minbrk),%ecx #
+ cmpl %eax,(%ecx)
+ PIC_EPILOGUE
+ jl ok
+ movl (%ecx),%eax
+ movl %eax,4(%esp)
+ok:
+ lea SYS_brk,%eax
+ LCALL(7,0)
+ jb err
+ movl 4(%esp),%eax
+ movl %eax,(%edx)
+ movl $0,%eax
+ ret
+err:
+ jmp PIC_PLT(cerror)
+
+#else
+
+ movl 4(%esp),%eax
+ cmpl %eax,minbrk
+ jl ok
+ movl minbrk,%eax
+ movl %eax,4(%esp)
+ok:
+ lea SYS_brk,%eax
+ LCALL(7,0)
+ jb err
+ movl 4(%esp),%eax
+ movl %eax,curbrk
+ movl $0,%eax
+ ret
+err:
+ jmp cerror
+#endif
diff --git a/lib/libc/amd64/sys/cerror.S b/lib/libc/amd64/sys/cerror.S
new file mode 100644
index 0000000..875f6db
--- /dev/null
+++ b/lib/libc/amd64/sys/cerror.S
@@ -0,0 +1,58 @@
+/*-
+ * 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.
+ *
+ * $Id: cerror.S,v 1.2 1994/08/13 14:00:26 davidg Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ .globl _errno
+cerror:
+#ifdef PIC
+ PIC_PROLOGUE
+ movl PIC_GOT(_errno),%ecx
+ movl %eax,(%ecx)
+ PIC_EPILOGUE
+#else
+ movl %eax,_errno
+#endif
+ 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..74a055b
--- /dev/null
+++ b/lib/libc/amd64/sys/exect.S
@@ -0,0 +1,55 @@
+/*-
+ * 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.
+ *
+ * $Id: exect.S,v 1.1 1994/08/05 01:18:42 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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
+ LCALL(7,0)
+ jmp 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..cf3264c
--- /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.
+ *
+ * $Id: pipe.S,v 1.1 1994/08/05 01:18:46 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+SYSCALL(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..e3ac3a5
--- /dev/null
+++ b/lib/libc/amd64/sys/ptrace.S
@@ -0,0 +1,61 @@
+/*-
+ * 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.
+ *
+ * $Id: ptrace.S,v 1.1 1994/08/05 01:18:47 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ENTRY(ptrace)
+ xorl %eax,%eax
+#ifdef PIC
+ PIC_PROLOGUE
+ movl PIC_GOT(_errno),%edx
+ movl %eax,(%edx)
+ PIC_EPILOGUE
+#else
+ movl %eax,_errno
+#endif
+ lea SYS_ptrace,%eax
+ LCALL(7,0)
+ jb err
+ ret
+err:
+ jmp cerror
diff --git a/lib/libc/amd64/sys/reboot.S b/lib/libc/amd64/sys/reboot.S
new file mode 100644
index 0000000..f90cca0
--- /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.
+ *
+ * $Id: reboot.S,v 1.1 1994/08/05 01:18:48 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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..2d65b59
--- /dev/null
+++ b/lib/libc/amd64/sys/sbrk.S
@@ -0,0 +1,96 @@
+/*-
+ * 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.
+ *
+ * $Id: sbrk.S,v 1.2 1995/01/23 01:30:04 davidg Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: sbrk.S,v 1.2 1995/01/23 01:30:04 davidg Exp $"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+#define SYS_brk 17
+
+ .globl _end
+ .globl minbrk
+ .globl curbrk
+
+ .data
+minbrk: .long _end
+curbrk: .long _end
+ .text
+
+ENTRY(sbrk)
+#ifdef PIC
+ movl 4(%esp),%ecx
+ PIC_PROLOGUE
+ movl PIC_GOT(curbrk),%edx
+ movl (%edx),%eax
+ PIC_EPILOGUE
+ testl %ecx,%ecx
+ jz back
+ addl %eax,4(%esp)
+ lea SYS_brk,%eax
+ LCALL(7,0)
+ jb err
+ PIC_PROLOGUE
+ movl PIC_GOT(curbrk),%edx
+ movl (%edx),%eax
+ addl %ecx,(%edx)
+ PIC_EPILOGUE
+back:
+ ret
+err:
+ jmp PIC_PLT(cerror)
+
+#else /* !PIC */
+
+ movl 4(%esp),%ecx
+ movl curbrk,%eax
+ testl %ecx,%ecx
+ jz back
+ addl %eax,4(%esp)
+ lea SYS_brk,%eax
+ LCALL(7,0)
+ jb err
+ movl curbrk,%eax
+ addl %ecx,curbrk
+back:
+ ret
+err:
+ jmp 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..96c7886
--- /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.
+ *
+ * $Id: setlogin.S,v 1.1 1994/08/05 01:18:50 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* LIBC_RCS and not lint */
+
+#include "SYS.h"
+
+.globl __logname_valid /* in getlogin() */
+
+SYSCALL(setlogin)
+#ifdef PIC
+ PIC_PROLOGUE
+ pushl %eax
+ movl PIC_GOT(__logname_valid),%eax
+ movl $0,(%eax)
+ popl %eax
+ PIC_EPILOGUE
+#else
+ movl $0,__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..ac0ffd6
--- /dev/null
+++ b/lib/libc/amd64/sys/sigreturn.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.
+ *
+ * $Id: sigreturn.S,v 1.1 1994/08/05 01:18:53 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+/*
+ * We must preserve the state of the registers as the user has set them up.
+ */
+#ifdef PROF
+#undef ENTRY
+#define ENTRY(x) \
+ .globl _/**/x; .align 2; _/**/x: pusha ; \
+ .data; 1:; .long 0; .text; movl $1b,%eax; call mcount; popa ; nop
+#endif /* PROF */
+
+SYSCALL(sigreturn)
+ ret
diff --git a/lib/libc/amd64/sys/vfork.S b/lib/libc/amd64/sys/vfork.S
new file mode 100644
index 0000000..06e3eb6
--- /dev/null
+++ b/lib/libc/amd64/sys/vfork.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.
+ *
+ * $Id: Ovfork.S,v 1.1 1994/08/05 01:18:38 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#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.
+ *
+ */
+ .set vfork,66
+.globl _vfork
+.type _vfork,@function
+
+_vfork:
+ popl %ecx /* my rta into ecx */
+ movl $vfork, %eax
+ LCALL(7,0)
+ jb verror
+vforkok:
+ cmpl $0,%edx /* child process? */
+ jne child /* yes */
+ jmp parent
+.globl _errno
+verror:
+#ifdef PIC
+ PIC_PROLOGUE
+ movl PIC_GOT(_errno), %edx
+ movl %eax,(%edx)
+ PIC_EPILOGUE
+#else
+ movl %eax,_errno
+#endif
+ movl $-1,%eax
+ jmp %ecx
+child:
+ movl $0,%eax
+parent:
+ jmp %ecx
diff --git a/lib/libc/compat-43/Makefile.inc b/lib/libc/compat-43/Makefile.inc
new file mode 100644
index 0000000..1d06c57d
--- /dev/null
+++ b/lib/libc/compat-43/Makefile.inc
@@ -0,0 +1,16 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/2/93
+
+# compat-43 sources
+.PATH: ${.CURDIR}/${MACHINE}/compat-43 ${.CURDIR}/compat-43
+
+SRCS+= creat.c gethostid.c getwd.c killpg.c sethostid.c setpgrp.c \
+ setrgid.c setruid.c sigcompat.c
+
+MAN2+= compat-43/creat.2 compat-43/killpg.2 \
+ compat-43/sigblock.2 \
+ compat-43/sigpause.2 compat-43/sigsetmask.2 compat-43/sigvec.2
+
+MAN3+= compat-43/gethostid.3 compat-43/setruid.3
+
+MLINKS+=setruid.3 setrgid.3
+MLINKS+=gethostid.3 sethostid.3
diff --git a/lib/libc/compat-43/creat.2 b/lib/libc/compat-43/creat.2
new file mode 100644
index 0000000..826909a
--- /dev/null
+++ b/lib/libc/compat-43/creat.2
@@ -0,0 +1,60 @@
+.\" 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
+.\"
+.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 "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
+.Nm
+function call appeared in Version 6 AT&T UNIX.
diff --git a/lib/libc/compat-43/creat.c b/lib/libc/compat-43/creat.c
new file mode 100644
index 0000000..31d60b8
--- /dev/null
+++ b/lib/libc/compat-43/creat.c
@@ -0,0 +1,49 @@
+/*
+ * 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>
+
+#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..8f56a28
--- /dev/null
+++ b/lib/libc/compat-43/gethostid.3
@@ -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.
+.\"
+.\" @(#)gethostid.3 8.1 (Berkeley) 6/2/93
+.\"
+.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 int
+.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 2 .
+.Sh SEE ALSO
+.Xr sysctl 2 ,
+.Xr gethostname 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..f105150e
--- /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..b57e406
--- /dev/null
+++ b/lib/libc/compat-43/killpg.2
@@ -0,0 +1,95 @@
+.\" 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
+.\"
+.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 <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 kill 2 ,
+.Xr getpgrp 2 ,
+.Xr sigaction 2
+.Sh HISTORY
+The
+.Nm
+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..f9b7901
--- /dev/null
+++ b/lib/libc/compat-43/killpg.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[] = "@(#)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().
+ */
+#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..df63ebd
--- /dev/null
+++ b/lib/libc/compat-43/setpgrp.c
@@ -0,0 +1,49 @@
+/*-
+ * 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>
+
+#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..7342b21
--- /dev/null
+++ b/lib/libc/compat-43/setruid.3
@@ -0,0 +1,79 @@
+.\" 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
+.\"
+.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 <sys/types.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 setuid 2 ,
+.Xr setgid 2 ,
+.Xr seteuid 2 ,
+.Xr setegid 2 ,
+.Xr getuid 2 ,
+.Xr getgid 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..60e4251
--- /dev/null
+++ b/lib/libc/compat-43/sigblock.2
@@ -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.
+.\"
+.\" @(#)sigblock.2 8.1 (Berkeley) 6/2/93
+.\"
+.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 sigprocmask 2 ,
+.Xr sigaction 2 ,
+.Xr sigsetmask 2 ,
+.Xr sigsetops 3
+.Sh HISTORY
+The
+.Nm
+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..69b1870
--- /dev/null
+++ b/lib/libc/compat-43/sigcompat.c
@@ -0,0 +1,81 @@
+/*
+ * 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[] = "@(#)sigcompat.c 8.1 (Berkeley) 6/2/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <signal.h>
+
+sigvec(signo, sv, osv)
+ int signo;
+ struct sigvec *sv, *osv;
+{
+ int ret;
+
+ if (sv)
+ sv->sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */
+ ret = sigaction(signo, (struct sigaction *)sv, (struct sigaction *)osv);
+ if (ret == 0 && osv)
+ osv->sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */
+ return (ret);
+}
+
+sigsetmask(mask)
+ int mask;
+{
+ int omask, n;
+
+ n = sigprocmask(SIG_SETMASK, (sigset_t *) &mask, (sigset_t *) &omask);
+ if (n)
+ return (n);
+ return (omask);
+}
+
+sigblock(mask)
+ int mask;
+{
+ int omask, n;
+
+ n = sigprocmask(SIG_BLOCK, (sigset_t *) &mask, (sigset_t *) &omask);
+ if (n)
+ return (n);
+ return (omask);
+}
+
+sigpause(mask)
+ int mask;
+{
+ return (sigsuspend((sigset_t *)&mask));
+}
diff --git a/lib/libc/compat-43/sigpause.2 b/lib/libc/compat-43/sigpause.2
new file mode 100644
index 0000000..7c6c097
--- /dev/null
+++ b/lib/libc/compat-43/sigpause.2
@@ -0,0 +1,74 @@
+.\" 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
+.\"
+.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 sigsuspend 2 ,
+.Xr kill 2 ,
+.Xr sigaction 2 ,
+.Xr sigprocmask 2 ,
+.Xr sigblock 2 ,
+.Xr sigvec 2
+.Sh HISTORY
+The
+.Nm
+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..13b7c1a
--- /dev/null
+++ b/lib/libc/compat-43/sigsetmask.2
@@ -0,0 +1,82 @@
+.\" 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
+.\"
+.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 sigprocmask 2 ,
+.Xr kill 2 ,
+.Xr sigaction 2 ,
+.Xr sigsuspend 2 ,
+.Xr sigvec 2 ,
+.Xr sigblock 2 ,
+.Xr sigsetops 3
+.Sh HISTORY
+The
+.Nm
+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..1b5244f
--- /dev/null
+++ b/lib/libc/compat-43/sigvec.2
@@ -0,0 +1,325 @@
+.\" 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
+.\"
+.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)();
+ sigset_t sv_mask;
+ int sv_flags;
+};
+.Ed
+.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
+or
+.Xr sigsetmask
+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 2
+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" " system call given invalid argument"
+.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..77af9c5
--- /dev/null
+++ b/lib/libc/db/Makefile.inc
@@ -0,0 +1,10 @@
+# @(#)Makefile.inc 8.2 (Berkeley) 2/21/94
+#
+CFLAGS+=-D__DBINTERFACE_PRIVATE
+
+.include "${.CURDIR}/db/btree/Makefile.inc"
+.include "${.CURDIR}/db/db/Makefile.inc"
+.include "${.CURDIR}/db/hash/Makefile.inc"
+.include "${.CURDIR}/db/man/Makefile.inc"
+.include "${.CURDIR}/db/mpool/Makefile.inc"
+.include "${.CURDIR}/db/recno/Makefile.inc"
diff --git a/lib/libc/db/VERSION b/lib/libc/db/VERSION
new file mode 100644
index 0000000..be08b78
--- /dev/null
+++ b/lib/libc/db/VERSION
@@ -0,0 +1,97 @@
+# @(#)VERSION 8.9 (Berkeley) 4/2/94
+
+This is version 1.74 of the Berkeley DB code.
+
+If your version of the DB code doesn't have a copy
+of this version file, it's really old, please update it!
+
+New versions of this software are periodically made
+available by anonymous ftp from ftp.cs.berkeley.edu,
+in the file ucb/4bsd/db.tar.Z, or from ftp.uu.net.
+If you'd like to get 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.
+VERSION This file.
+btree B+tree routines.
+db Dbopen(3) interface routine.
+doc USENIX papers, formatted manual pages.
+hash Extended linear hashing routines.
+man Unformatted manual pages.
+mpool Memory pool routines.
+recno Fixed/variable length record routines.
+test Test package.
+
+============================================
+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/btree/Makefile.inc b/lib/libc/db/btree/Makefile.inc
new file mode 100644
index 0000000..71f8dfc
--- /dev/null
+++ b/lib/libc/db/btree/Makefile.inc
@@ -0,0 +1,7 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+
+.PATH: ${.CURDIR}/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_stack.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..6269bd5
--- /dev/null
+++ b/lib/libc/db/btree/bt_close.c
@@ -0,0 +1,204 @@
+/*-
+ * 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[] = "@(#)bt_close.c 8.3 (Berkeley) 2/21/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;
+ }
+
+ /*
+ * Delete any already deleted record that we've been saving
+ * because the cursor pointed to it.
+ */
+ if (ISSET(t, B_DELCRSR) && __bt_crsrdel(t, &t->bt_bcursor))
+ return (RET_ERROR);
+
+ if (__bt_sync(dbp, 0) == RET_ERROR)
+ return (RET_ERROR);
+
+ if (mpool_close(t->bt_mp) == RET_ERROR)
+ return (RET_ERROR);
+
+ if (t->bt_stack)
+ free(t->bt_stack);
+ if (t->bt_kbuf)
+ free(t->bt_kbuf);
+ if (t->bt_dbuf)
+ free(t->bt_dbuf);
+
+ 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;
+ PAGE *h;
+ void *p;
+
+ 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 (ISSET(t, B_INMEM | B_RDONLY) || !ISSET(t, B_MODIFIED))
+ return (RET_SUCCESS);
+
+ if (ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)
+ return (RET_ERROR);
+
+ /*
+ * Nastiness. If the cursor has been marked for deletion, but not
+ * actually deleted, we have to make a copy of the page, delete the
+ * key/data item, sync the file, and then restore the original page
+ * contents.
+ */
+ if (ISSET(t, B_DELCRSR)) {
+ if ((p = (void *)malloc(t->bt_psize)) == NULL)
+ return (RET_ERROR);
+ if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL)
+ return (RET_ERROR);
+ memmove(p, h, t->bt_psize);
+ if ((status =
+ __bt_dleaf(t, h, t->bt_bcursor.index)) == RET_ERROR)
+ goto ecrsr;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ }
+
+ if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS)
+ CLR(t, B_MODIFIED);
+
+ecrsr: if (ISSET(t, B_DELCRSR)) {
+ if ((h = mpool_get(t->bt_mp, t->bt_bcursor.pgno, 0)) == NULL)
+ return (RET_ERROR);
+ memmove(h, p, t->bt_psize);
+ free(p);
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ }
+ 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.m_magic = BTREEMAGIC;
+ m.m_version = BTREEVERSION;
+ m.m_psize = t->bt_psize;
+ m.m_free = t->bt_free;
+ m.m_nrecs = t->bt_nrecs;
+ m.m_flags = t->bt_flags & 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..eb49340
--- /dev/null
+++ b/lib/libc/db/btree/bt_conv.c
@@ -0,0 +1,221 @@
+/*-
+ * 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[] = "@(#)bt_conv.c 8.2 (Berkeley) 2/21/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 (!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(size_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(size_t);
+ P_32_SWAP(p);
+ p += sizeof(size_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(size_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 (!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(size_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(size_t);
+ P_32_SWAP(p);
+ p += sizeof(size_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(size_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); /* m_magic */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* m_version */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* m_psize */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* m_free */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* m_nrecs */
+ p += sizeof(u_int32_t);
+ P_32_SWAP(p); /* m_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..5f9ac1d
--- /dev/null
+++ b/lib/libc/db/btree/bt_debug.c
@@ -0,0 +1,331 @@
+/*-
+ * 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[] = "@(#)bt_debug.c 8.2 (Berkeley) 2/21/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",
+ ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize);
+ if (ISSET(t, R_RECNO))
+ (void)fprintf(stderr, " keys %lu", t->bt_nrecs);
+#undef X
+#define X(flag, name) \
+ if (ISSET(t, flag)) { \
+ (void)fprintf(stderr, "%s%s", sep, name); \
+ sep = ", "; \
+ }
+ if (t->bt_flags) {
+ sep = " flags (";
+ X(B_DELCRSR, "DELCRSR");
+ X(R_FIXLEN, "FIXLEN");
+ X(B_INMEM, "INMEM");
+ X(B_NODUPS, "NODUPS");
+ X(B_RDONLY, "RDONLY");
+ X(R_RECNO, "RECNO");
+ X(B_SEQINIT, "SEQINIT");
+ 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->m_magic);
+ (void)fprintf(stderr, "version %lu\n", m->m_version);
+ (void)fprintf(stderr, "psize %lu\n", m->m_psize);
+ (void)fprintf(stderr, "free %lu\n", m->m_free);
+ (void)fprintf(stderr, "nrecs %lu\n", m->m_nrecs);
+ (void)fprintf(stderr, "flags %lu", m->m_flags);
+#undef X
+#define X(flag, name) \
+ if (m->m_flags & flag) { \
+ (void)fprintf(stderr, "%s%s", sep, name); \
+ sep = ", "; \
+ }
+ if (m->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,
+ *(size_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),
+ *(size_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,
+ *(size_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 = 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 (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..5dba534
--- /dev/null
+++ b/lib/libc/db/btree/bt_delete.c
@@ -0,0 +1,324 @@
+/*-
+ * 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[] = "@(#)bt_delete.c 8.3 (Berkeley) 2/21/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 *));
+
+/*
+ * __BT_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
+__bt_delete(dbp, key, flags)
+ const DB *dbp;
+ const DBT *key;
+ 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;
+ }
+
+ if (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 the record. For
+ * the delete cursor bit to have been set requires that the
+ * scan be initialized, so no reason to check.
+ */
+ if (!ISSET(t, B_SEQINIT))
+ goto einval;
+ status = ISSET(t, B_DELCRSR) ?
+ RET_SPECIAL : __bt_crsrdel(t, &t->bt_bcursor);
+ break;
+ default:
+einval: errno = EINVAL;
+ return (RET_ERROR);
+ }
+ if (status == RET_SUCCESS)
+ SET(t, B_MODIFIED);
+ return (status);
+}
+
+/*
+ * BT_BDELETE -- Delete all key/data pairs matching the specified key.
+ *
+ * Parameters:
+ * tree: 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, save;
+ PAGE *h;
+ pgno_t cpgno, pg;
+ indx_t cindex;
+ int deleted, dirty1, dirty2, exact;
+
+ /* Find any matching record; __bt_search pins the page. */
+ if ((e = __bt_search(t, key, &exact)) == NULL)
+ return (RET_ERROR);
+ if (!exact) {
+ mpool_put(t->bt_mp, e->page, 0);
+ return (RET_SPECIAL);
+ }
+
+ /*
+ * Delete forward, then delete backward, from the found key. The
+ * ordering is so that the deletions don't mess up the page refs.
+ * The first loop deletes the key from the original page, the second
+ * unpins the original page. In the first loop, dirty1 is set if
+ * the original page is modified, and dirty2 is set if any subsequent
+ * pages are modified. In the second loop, dirty1 starts off set if
+ * the original page has been modified, and is set if any subsequent
+ * pages are modified.
+ *
+ * If find the key referenced by the cursor, don't delete it, just
+ * flag it for future deletion. The cursor page number is P_INVALID
+ * unless the sequential scan is initialized, so no reason to check.
+ * A special case is when the already deleted cursor record was the
+ * only record found. If so, then the delete opertion fails as no
+ * records were deleted.
+ *
+ * Cycle in place in the current page until the current record doesn't
+ * match the key or the page is empty. If the latter, walk forward,
+ * skipping empty pages and repeating until a record doesn't match
+ * the key or the end of the tree is reached.
+ */
+ cpgno = t->bt_bcursor.pgno;
+ cindex = t->bt_bcursor.index;
+ save = *e;
+ dirty1 = 0;
+ for (h = e->page, deleted = 0;;) {
+ dirty2 = 0;
+ do {
+ if (h->pgno == cpgno && e->index == cindex) {
+ if (!ISSET(t, B_DELCRSR)) {
+ SET(t, B_DELCRSR);
+ deleted = 1;
+ }
+ ++e->index;
+ } else {
+ if (__bt_dleaf(t, h, e->index)) {
+ if (h->pgno != save.page->pgno)
+ mpool_put(t->bt_mp, h, dirty2);
+ mpool_put(t->bt_mp, save.page, dirty1);
+ return (RET_ERROR);
+ }
+ if (h->pgno == save.page->pgno)
+ dirty1 = MPOOL_DIRTY;
+ else
+ dirty2 = MPOOL_DIRTY;
+ deleted = 1;
+ }
+ } while (e->index < NEXTINDEX(h) && __bt_cmp(t, key, e) == 0);
+
+ /*
+ * Quit if didn't find a match, no next page, or first key on
+ * the next page doesn't match. Don't unpin the original page
+ * unless an error occurs.
+ */
+ if (e->index < NEXTINDEX(h))
+ break;
+ for (;;) {
+ if ((pg = h->nextpg) == P_INVALID)
+ goto done1;
+ if (h->pgno != save.page->pgno)
+ mpool_put(t->bt_mp, h, dirty2);
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) {
+ mpool_put(t->bt_mp, save.page, dirty1);
+ return (RET_ERROR);
+ }
+ if (NEXTINDEX(h) != 0) {
+ e->page = h;
+ e->index = 0;
+ break;
+ }
+ }
+
+ if (__bt_cmp(t, key, e) != 0)
+ break;
+ }
+
+ /*
+ * Reach here with the original page and the last page referenced
+ * pinned (they may be the same). Release it if not the original.
+ */
+done1: if (h->pgno != save.page->pgno)
+ mpool_put(t->bt_mp, h, dirty2);
+
+ /*
+ * Walk backwards from the record previous to the record returned by
+ * __bt_search, skipping empty pages, until a record doesn't match
+ * the key or reach the beginning of the tree.
+ */
+ *e = save;
+ for (;;) {
+ if (e->index)
+ --e->index;
+ for (h = e->page; e->index; --e->index) {
+ if (__bt_cmp(t, key, e) != 0)
+ goto done2;
+ if (h->pgno == cpgno && e->index == cindex) {
+ if (!ISSET(t, B_DELCRSR)) {
+ SET(t, B_DELCRSR);
+ deleted = 1;
+ }
+ } else {
+ if (__bt_dleaf(t, h, e->index) == RET_ERROR) {
+ mpool_put(t->bt_mp, h, dirty1);
+ return (RET_ERROR);
+ }
+ if (h->pgno == save.page->pgno)
+ dirty1 = MPOOL_DIRTY;
+ deleted = 1;
+ }
+ }
+
+ if ((pg = h->prevpg) == P_INVALID)
+ goto done2;
+ mpool_put(t->bt_mp, h, dirty1);
+ dirty1 = 0;
+ if ((e->page = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+ e->index = NEXTINDEX(e->page);
+ }
+
+ /*
+ * Reach here with the last page that was looked at pinned. Release
+ * it.
+ */
+done2: mpool_put(t->bt_mp, h, dirty1);
+ return (deleted ? RET_SUCCESS : RET_SPECIAL);
+}
+
+/*
+ * __BT_DLEAF -- Delete a single record from a leaf page.
+ *
+ * Parameters:
+ * t: tree
+ * index: index on current page to delete
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__bt_dleaf(t, h, index)
+ BTREE *t;
+ PAGE *h;
+ indx_t index;
+{
+ register BLEAF *bl;
+ register indx_t cnt, *ip, offset;
+ register size_t nbytes;
+ char *from;
+ void *to;
+
+ /*
+ * Delete a record from a btree 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 = 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);
+ nbytes = NBLEAF(bl);
+
+ /*
+ * 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 = 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);
+ return (RET_SUCCESS);
+}
diff --git a/lib/libc/db/btree/bt_get.c b/lib/libc/db/btree/bt_get.c
new file mode 100644
index 0000000..28b2d60
--- /dev/null
+++ b/lib/libc/db/btree/bt_get.c
@@ -0,0 +1,238 @@
+/*-
+ * 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[] = "@(#)bt_get.c 8.2 (Berkeley) 9/7/93";
+#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);
+ }
+
+ /*
+ * A special case is if we found the record but it's flagged for
+ * deletion. In this case, we want to find another record with the
+ * same key, if it exists. Rather than look around the tree we call
+ * __bt_first and have it redo the search, as __bt_first will not
+ * return keys marked for deletion. Slow, but should never happen.
+ */
+ if (ISSET(t, B_DELCRSR) && e->page->pgno == t->bt_bcursor.pgno &&
+ e->index == t->bt_bcursor.index) {
+ mpool_put(t->bt_mp, e->page, 0);
+ if ((e = __bt_first(t, key, &exact)) == NULL)
+ return (RET_ERROR);
+ if (!exact)
+ return (RET_SPECIAL);
+ }
+
+ status = __bt_ret(t, e, NULL, data);
+ /*
+ * If the user is doing concurrent access, we copied the
+ * key/data, toss the page.
+ */
+ if (ISSET(t, B_DB_LOCK))
+ mpool_put(t->bt_mp, e->page, 0);
+ else
+ t->bt_pinned = e->page;
+ return (status);
+}
+
+/*
+ * __BT_FIRST -- Find the first entry.
+ *
+ * Parameters:
+ * t: the tree
+ * key: the key
+ *
+ * Returns:
+ * The first entry in the tree greater than or equal to key.
+ */
+EPG *
+__bt_first(t, key, exactp)
+ BTREE *t;
+ const DBT *key;
+ int *exactp;
+{
+ register PAGE *h;
+ register EPG *e;
+ EPG save;
+ pgno_t cpgno, pg;
+ indx_t cindex;
+ int found;
+
+ /*
+ * Find any matching record; __bt_search pins the page. Only exact
+ * matches are tricky, otherwise just return the location of the key
+ * if it were to be inserted into the tree.
+ */
+ if ((e = __bt_search(t, key, exactp)) == NULL)
+ return (NULL);
+ if (!*exactp)
+ return (e);
+
+ if (ISSET(t, B_DELCRSR)) {
+ cpgno = t->bt_bcursor.pgno;
+ cindex = t->bt_bcursor.index;
+ } else {
+ cpgno = P_INVALID;
+ cindex = 0; /* GCC thinks it's uninitialized. */
+ }
+
+ /*
+ * Walk backwards, skipping empty pages, 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. A special case is that we don't return a match
+ * on records that the cursor references that have already been flagged
+ * for deletion.
+ */
+ save = *e;
+ h = e->page;
+ found = 0;
+ do {
+ if (cpgno != h->pgno || cindex != e->index) {
+ if (save.page->pgno != e->page->pgno) {
+ mpool_put(t->bt_mp, save.page, 0);
+ save = *e;
+ } else
+ save.index = e->index;
+ found = 1;
+ }
+ /*
+ * Make a special effort not to unpin the page the last (or
+ * original) match was on, but also make sure it's unpinned
+ * if an error occurs.
+ */
+ while (e->index == 0) {
+ if (h->prevpg == P_INVALID)
+ goto done1;
+ 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 (NULL);
+ }
+ e->page = h;
+ e->index = NEXTINDEX(h);
+ }
+ --e->index;
+ } while (__bt_cmp(t, key, e) == 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.
+ */
+done1: if (h->pgno != save.page->pgno)
+ mpool_put(t->bt_mp, h, 0);
+
+ /*
+ * If still haven't found a record, the only possibility left is the
+ * next one. Move forward one slot, skipping empty pages and check.
+ */
+ if (!found) {
+ h = save.page;
+ if (++save.index == NEXTINDEX(h)) {
+ do {
+ pg = h->nextpg;
+ mpool_put(t->bt_mp, h, 0);
+ if (pg == P_INVALID) {
+ *exactp = 0;
+ return (e);
+ }
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (NULL);
+ } while ((save.index = NEXTINDEX(h)) == 0);
+ save.page = h;
+ }
+ if (__bt_cmp(t, key, &save) != 0) {
+ *exactp = 0;
+ return (e);
+ }
+ }
+ *e = save;
+ *exactp = 1;
+ return (e);
+}
diff --git a/lib/libc/db/btree/bt_open.c b/lib/libc/db/btree/bt_open.c
new file mode 100644
index 0000000..f156745
--- /dev/null
+++ b/lib/libc/db/btree/bt_open.c
@@ -0,0 +1,440 @@
+/*-
+ * 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[] = "@(#)bt_open.c 8.5 (Berkeley) 2/21/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"
+
+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_bcursor.pgno = P_INVALID;
+ 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;
+ t->bt_flags = 0;
+ if (t->bt_lorder != machine_lorder)
+ 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:
+ 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;
+ 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) {
+ nr = read(t->bt_fd, &m, sizeof(BTMETA));
+ if (nr < 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.m_magic == BTREEMAGIC)
+ CLR(t, B_NEEDSWAP);
+ else {
+ SET(t, B_NEEDSWAP);
+ M_32_SWAP(m.m_magic);
+ M_32_SWAP(m.m_version);
+ M_32_SWAP(m.m_psize);
+ M_32_SWAP(m.m_free);
+ M_32_SWAP(m.m_nrecs);
+ M_32_SWAP(m.m_flags);
+ }
+ if (m.m_magic != BTREEMAGIC || m.m_version != BTREEVERSION)
+ goto eftype;
+ if (m.m_psize < MINPSIZE || m.m_psize > MAX_PAGE_OFFSET + 1 ||
+ m.m_psize & sizeof(indx_t) - 1)
+ goto eftype;
+ if (m.m_flags & ~SAVEMETA)
+ goto eftype;
+ b.psize = m.m_psize;
+ t->bt_flags |= m.m_flags;
+ t->bt_free = m.m_free;
+ t->bt_nrecs = m.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))
+ SET(t, B_NODUPS);
+
+ t->bt_free = P_INVALID;
+ t->bt_nrecs = 0;
+ 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 (!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)
+ SET(t, B_DB_LOCK);
+ if (dflags & DB_SHMEM)
+ SET(t, B_DB_SHMEM);
+ if (dflags & DB_TXN)
+ 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)
+ return (RET_ERROR);
+
+ 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;
+ char path[MAXPATHLEN];
+
+ 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 (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..0057a03
--- /dev/null
+++ b/lib/libc/db/btree/bt_overflow.c
@@ -0,0 +1,224 @@
+/*-
+ * 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[] = "@(#)bt_overflow.c 8.2 (Berkeley) 2/21/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, size_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;
+ char **buf;
+ size_t *bufsz;
+{
+ PAGE *h;
+ pgno_t pg;
+ size_t nb, plen, sz;
+
+ memmove(&pg, p, sizeof(pgno_t));
+ memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(size_t));
+ *ssz = sz;
+
+#ifdef DEBUG
+ if (pg == P_INVALID || sz == 0)
+ abort();
+#endif
+ /* Make the buffer bigger as necessary. */
+ if (*bufsz < sz) {
+ if ((*buf = (char *)realloc(*buf, sz)) == 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, 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, size_t }
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__ovfl_delete(t, p)
+ BTREE *t;
+ void *p;
+{
+ PAGE *h;
+ pgno_t pg;
+ size_t plen, sz;
+
+ memmove(&pg, p, sizeof(pgno_t));
+ memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(size_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..f71a40d
--- /dev/null
+++ b/lib/libc/db/btree/bt_page.c
@@ -0,0 +1,93 @@
+/*-
+ * 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[] = "@(#)bt_page.c 8.2 (Berkeley) 2/21/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
+ */
+int
+__bt_free(t, h)
+ BTREE *t;
+ PAGE *h;
+{
+ /* Insert the page at the start of the free list. */
+ h->prevpg = P_INVALID;
+ h->nextpg = t->bt_free;
+ t->bt_free = h->pgno;
+
+ /* 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;
+ 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..11a211b
--- /dev/null
+++ b/lib/libc/db/btree/bt_put.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
+ * 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.3 (Berkeley) 9/16/93";
+#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;
+ size_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;
+ }
+
+ switch (flags) {
+ case R_CURSOR:
+ if (!ISSET(t, B_SEQINIT))
+ goto einval;
+ if (ISSET(t, B_DELCRSR))
+ goto einval;
+ break;
+ case 0:
+ case R_NOOVERWRITE:
+ break;
+ default:
+einval: errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ if (ISSET(t, B_RDONLY)) {
+ errno = EPERM;
+ return (RET_ERROR);
+ }
+
+ /*
+ * If the key/data won't fit on a page, store it on indirect pages.
+ * Only store the key on the overflow page if it's too big after the
+ * data is on an overflow page.
+ *
+ * XXX
+ * If the insert fails later on, these 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(size_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(size_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_bcursor.pgno, 0)) == NULL)
+ return (RET_ERROR);
+ index = t->bt_bcursor.index;
+ goto delete;
+ }
+
+ /*
+ * Find the key to delete, or, the location at which to insert. Bt_fast
+ * and __bt_search 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 specified 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.
+ *
+ * Pages are split as required.
+ */
+ switch (flags) {
+ case R_NOOVERWRITE:
+ if (!exact)
+ break;
+ /*
+ * One special case is if the cursor references the record and
+ * it's been flagged for deletion. Then, we delete the record,
+ * leaving the cursor there -- this means that the inserted
+ * record will not be seen in a cursor scan.
+ */
+ if (ISSET(t, B_DELCRSR) && t->bt_bcursor.pgno == h->pgno &&
+ t->bt_bcursor.index == index) {
+ CLR(t, B_DELCRSR);
+ goto delete;
+ }
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_SPECIAL);
+ default:
+ if (!exact || !ISSET(t, B_NODUPS))
+ break;
+delete: if (__bt_dleaf(t, 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 (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) {
+ t->bt_bcursor.pgno = e->page->pgno;
+ t->bt_bcursor.index = e->index;
+ }
+ 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;
+ size_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..ff33421
--- /dev/null
+++ b/lib/libc/db/btree/bt_search.c
@@ -0,0 +1,235 @@
+/*-
+ * 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[] = "@(#)bt_search.c 8.6 (Berkeley) 3/15/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, and duplicates aren't allowed, we're
+ * done. If duplicates are allowed, it's possible that there
+ * were duplicate keys on duplicate pages, and they were later
+ * deleted, so we could be on a page with no matches while
+ * there are matches on other pages. If we're at the start or
+ * end of a page, check on both sides.
+ */
+ if (h->flags & P_BLEAF) {
+ t->bt_cur.index = base;
+ *exactp = 0;
+ if (!ISSET(t, B_NODUPS)) {
+ if (base == 0 &&
+ bt_sprev(t, h, key, exactp))
+ return (&t->bt_cur);
+ if (base == NEXTINDEX(h) &&
+ bt_snext(t, h, key, exactp))
+ return (&t->bt_cur);
+ }
+ 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: if (__bt_push(t, h->pgno, index) == RET_ERROR)
+ return (NULL);
+ 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 to search
+ * h: current page.
+ * key: key to find
+ * 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;
+ PAGE *tp;
+ pgno_t pg;
+
+ /* Skip until reach the end of the tree or a key. */
+ for (pg = h->nextpg; pg != P_INVALID;) {
+ if ((tp = mpool_get(t->bt_mp, pg, 0)) == NULL) {
+ mpool_put(t->bt_mp, h, 0);
+ return (NULL);
+ }
+ if (NEXTINDEX(tp) != 0)
+ break;
+ pg = tp->prevpg;
+ mpool_put(t->bt_mp, tp, 0);
+ }
+ /*
+ * The key is either an exact match, or not as good as
+ * the one we already have.
+ */
+ if (pg != P_INVALID) {
+ e.page = tp;
+ e.index = NEXTINDEX(tp) - 1;
+ if (__bt_cmp(t, key, &e) == 0) {
+ mpool_put(t->bt_mp, h, 0);
+ t->bt_cur = e;
+ *exactp = 1;
+ return (1);
+ }
+ }
+ return (0);
+}
+
+/*
+ * BT_SPREV -- Check for an exact match before the key.
+ *
+ * Parameters:
+ * t: tree to search
+ * h: current page.
+ * key: key to find
+ * 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;
+ PAGE *tp;
+ pgno_t pg;
+
+ /* Skip until reach the beginning of the tree or a key. */
+ for (pg = h->prevpg; pg != P_INVALID;) {
+ if ((tp = mpool_get(t->bt_mp, pg, 0)) == NULL) {
+ mpool_put(t->bt_mp, h, 0);
+ return (NULL);
+ }
+ if (NEXTINDEX(tp) != 0)
+ break;
+ pg = tp->prevpg;
+ mpool_put(t->bt_mp, tp, 0);
+ }
+ /*
+ * The key is either an exact match, or not as good as
+ * the one we already have.
+ */
+ if (pg != P_INVALID) {
+ e.page = tp;
+ e.index = NEXTINDEX(tp) - 1;
+ if (__bt_cmp(t, key, &e) == 0) {
+ mpool_put(t->bt_mp, h, 0);
+ t->bt_cur = e;
+ *exactp = 1;
+ return (1);
+ }
+ }
+ 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..182ef70
--- /dev/null
+++ b/lib/libc/db/btree/bt_seq.c
@@ -0,0 +1,380 @@
+/*-
+ * 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[] = "@(#)bt_seq.c 8.2 (Berkeley) 9/7/93";
+#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_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.
+ *
+ * Each tree has an EPGNO which has the current position of the cursor. The
+ * cursor has to survive deletions/insertions in the tree without losing its
+ * position. This is done by noting deletions without doing them, and then
+ * doing them when the cursor moves (or the tree is closed).
+ */
+
+/*
+ * __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 (ISSET(t, B_SEQINIT)) {
+ status = bt_seqadv(t, &e, flags);
+ break;
+ }
+ /* FALLTHROUGH */
+ case R_CURSOR:
+ case R_FIRST:
+ case R_LAST:
+ status = bt_seqset(t, &e, key, flags);
+ break;
+ default:
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ if (status == RET_SUCCESS) {
+ status = __bt_ret(t, &e, key, data);
+
+ /* Update the actual cursor. */
+ t->bt_bcursor.pgno = e.page->pgno;
+ t->bt_bcursor.index = e.index;
+
+ /*
+ * If the user is doing concurrent access, we copied the
+ * key/data, toss the page.
+ */
+ if (ISSET(t, B_DB_LOCK))
+ mpool_put(t->bt_mp, e.page, 0);
+ else
+ t->bt_pinned = e.page;
+ SET(t, B_SEQINIT);
+ }
+ 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;
+{
+ EPG *e;
+ PAGE *h;
+ pgno_t pg;
+ int exact;
+
+ /*
+ * Delete any already deleted record that we've been saving because
+ * the cursor pointed to it. Since going to a specific key, should
+ * delete any logically deleted records so they aren't found.
+ */
+ if (ISSET(t, B_DELCRSR) && __bt_crsrdel(t, &t->bt_bcursor))
+ return (RET_ERROR);
+
+ /*
+ * 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 run out
+ * of keys, return RET_SPECIAL.
+ */
+ if (key->data == NULL || key->size == 0) {
+ errno = EINVAL;
+ return (RET_ERROR);
+ }
+ e = __bt_first(t, key, &exact); /* Returns pinned page. */
+ if (e == NULL)
+ return (RET_ERROR);
+ /*
+ * If at the end of a page, skip any empty pages and find the
+ * next entry.
+ */
+ if (e->index == NEXTINDEX(e->page)) {
+ h = e->page;
+ do {
+ 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);
+ } while (NEXTINDEX(h) == 0);
+ e->index = 0;
+ e->page = h;
+ }
+ *ep = *e;
+ break;
+ 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);
+ if (h->flags & (P_BLEAF | P_RLEAF))
+ break;
+ pg = GETBINTERNAL(h, 0)->pgno;
+ mpool_put(t->bt_mp, h, 0);
+ }
+
+ /* Skip any empty pages. */
+ while (NEXTINDEX(h) == 0 && h->nextpg != P_INVALID) {
+ pg = h->nextpg;
+ mpool_put(t->bt_mp, h, 0);
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+ }
+
+ if (NEXTINDEX(h) == 0) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_SPECIAL);
+ }
+
+ 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);
+ if (h->flags & (P_BLEAF | P_RLEAF))
+ break;
+ pg = GETBINTERNAL(h, NEXTINDEX(h) - 1)->pgno;
+ mpool_put(t->bt_mp, h, 0);
+ }
+
+ /* Skip any empty pages. */
+ while (NEXTINDEX(h) == 0 && h->prevpg != P_INVALID) {
+ pg = h->prevpg;
+ mpool_put(t->bt_mp, h, 0);
+ if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
+ return (RET_ERROR);
+ }
+
+ if (NEXTINDEX(h) == 0) {
+ mpool_put(t->bt_mp, h, 0);
+ return (RET_SPECIAL);
+ }
+
+ 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, e, flags)
+ BTREE *t;
+ EPG *e;
+ int flags;
+{
+ EPGNO *c, delc;
+ PAGE *h;
+ indx_t index;
+ pgno_t pg;
+
+ /* Save the current cursor if going to delete it. */
+ c = &t->bt_bcursor;
+ if (ISSET(t, B_DELCRSR))
+ delc = *c;
+
+ if ((h = mpool_get(t->bt_mp, c->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.
+ */
+ index = c->index;
+ switch(flags) {
+ case R_NEXT: /* Next record. */
+ if (++index == NEXTINDEX(h)) {
+ do {
+ 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);
+ } while (NEXTINDEX(h) == 0);
+ index = 0;
+ }
+ break;
+ case R_PREV: /* Previous record. */
+ if (index-- == 0) {
+ do {
+ 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);
+ } while (NEXTINDEX(h) == 0);
+ index = NEXTINDEX(h) - 1;
+ }
+ break;
+ }
+
+ e->page = h;
+ e->index = index;
+
+ /*
+ * Delete any already deleted record that we've been saving because the
+ * cursor pointed to it. This could cause the new index to be shifted
+ * down by one if the record we're deleting is on the same page and has
+ * a larger index.
+ */
+ if (ISSET(t, B_DELCRSR)) {
+ CLR(t, B_DELCRSR); /* Don't try twice. */
+ if (c->pgno == delc.pgno && c->index > delc.index)
+ --c->index;
+ if (__bt_crsrdel(t, &delc))
+ return (RET_ERROR);
+ }
+ return (RET_SUCCESS);
+}
+
+/*
+ * __BT_CRSRDEL -- Delete the record referenced by the cursor.
+ *
+ * Parameters:
+ * t: tree
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__bt_crsrdel(t, c)
+ BTREE *t;
+ EPGNO *c;
+{
+ PAGE *h;
+ int status;
+
+ CLR(t, B_DELCRSR); /* Don't try twice. */
+ if ((h = mpool_get(t->bt_mp, c->pgno, 0)) == NULL)
+ return (RET_ERROR);
+ status = __bt_dleaf(t, h, c->index);
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ return (status);
+}
diff --git a/lib/libc/db/btree/bt_split.c b/lib/libc/db/btree/bt_split.c
new file mode 100644
index 0000000..4a572c0
--- /dev/null
+++ b/lib/libc/db/btree/bt_split.c
@@ -0,0 +1,825 @@
+/*-
+ * 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[] = "@(#)bt_split.c 8.3 (Berkeley) 2/21/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, skip)
+ BTREE *t;
+ PAGE *sp;
+ const DBT *key, *data;
+ int flags;
+ size_t ilen;
+ indx_t skip;
+{
+ BINTERNAL *bi;
+ BLEAF *bl, *tbl;
+ DBT a, b;
+ EPGNO *parent;
+ PAGE *h, *l, *r, *lchild, *rchild;
+ indx_t nxtindex;
+ size_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.
+ */
+ 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 (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 &&
+ (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 &&
+ (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);
+ }
+ 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, 0);
+ }
+
+ /*
+ * 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;
+ size_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;
+ RLEAF *rl;
+ EPGNO *c;
+ PAGE *rval;
+ void *src;
+ indx_t full, half, nxt, off, skip, top, used;
+ size_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 >= full) {
+ --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;
+ 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.
+ *
+ * Don't bother checking for the B_SEQINIT flag, the page number will
+ * be P_INVALID.
+ */
+ c = &t->bt_bcursor;
+ if (c->pgno == h->pgno) {
+ if (c->index >= skip)
+ ++c->index;
+ if (c->index < nxt) /* Left page. */
+ c->pgno = l->pgno;
+ else { /* Right page. */
+ c->pgno = r->pgno;
+ c->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_stack.c b/lib/libc/db/btree/bt_stack.c
new file mode 100644
index 0000000..5c7fab9
--- /dev/null
+++ b/lib/libc/db/btree/bt_stack.c
@@ -0,0 +1,92 @@
+/*-
+ * 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[] = "@(#)bt_stack.c 8.3 (Berkeley) 2/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <db.h>
+#include "btree.h"
+
+/*
+ * When a page splits, a new record has to be inserted into its parent page.
+ * This page may have to split as well, all the way up to the root. Since
+ * parent pointers in each page would be expensive, we maintain a stack of
+ * parent pages as we descend the tree.
+ *
+ * XXX
+ * This is a concurrency problem -- if user a builds a stack, then user b
+ * splits the tree, then user a tries to split the tree, there's a new level
+ * in the tree that user a doesn't know about.
+ */
+
+/*
+ * __BT_PUSH -- Push parent page info onto the stack (LIFO).
+ *
+ * Parameters:
+ * t: tree
+ * pgno: page
+ * index: page index
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+__bt_push(t, pgno, index)
+ BTREE *t;
+ pgno_t pgno;
+ indx_t index;
+{
+ if (t->bt_sp == t->bt_maxstack) {
+ t->bt_maxstack += 50;
+ if ((t->bt_stack = (EPGNO *)realloc(t->bt_stack,
+ t->bt_maxstack * sizeof(EPGNO))) == NULL) {
+ t->bt_maxstack -= 50;
+ return (RET_ERROR);
+ }
+ }
+
+ t->bt_stack[t->bt_sp].pgno = pgno;
+ t->bt_stack[t->bt_sp].index = index;
+ ++t->bt_sp;
+ return (RET_SUCCESS);
+}
diff --git a/lib/libc/db/btree/bt_utils.c b/lib/libc/db/btree/bt_utils.c
new file mode 100644
index 0000000..d2d1f73
--- /dev/null
+++ b/lib/libc/db/btree/bt_utils.c
@@ -0,0 +1,247 @@
+/*-
+ * 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[] = "@(#)bt_utils.c 8.4 (Berkeley) 2/21/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 as a result of search or scan.
+ *
+ * Parameters:
+ * t: tree
+ * d: LEAF to be returned to the user.
+ * key: user's key structure (NULL if not to be filled in)
+ * data: user's data structure
+ *
+ * Returns:
+ * RET_SUCCESS, RET_ERROR.
+ */
+int
+__bt_ret(t, e, key, data)
+ BTREE *t;
+ EPG *e;
+ DBT *key, *data;
+{
+ register BLEAF *bl;
+ register void *p;
+
+ bl = GETBLEAF(e->page, e->index);
+
+ /*
+ * We always copy big keys/data to make them contigous. Otherwise,
+ * we leave the page pinned and don't copy unless the user specified
+ * concurrent access.
+ */
+ if (bl->flags & P_BIGDATA) {
+ if (__ovfl_get(t, bl->bytes + bl->ksize,
+ &data->size, &t->bt_dbuf, &t->bt_dbufsz))
+ return (RET_ERROR);
+ data->data = t->bt_dbuf;
+ } else if (ISSET(t, B_DB_LOCK)) {
+ /* Use +1 in case the first record retrieved is 0 length. */
+ if (bl->dsize + 1 > t->bt_dbufsz) {
+ if ((p =
+ (void *)realloc(t->bt_dbuf, bl->dsize + 1)) == NULL)
+ return (RET_ERROR);
+ t->bt_dbuf = p;
+ t->bt_dbufsz = bl->dsize + 1;
+ }
+ memmove(t->bt_dbuf, bl->bytes + bl->ksize, bl->dsize);
+ data->size = bl->dsize;
+ data->data = t->bt_dbuf;
+ } else {
+ data->size = bl->dsize;
+ data->data = bl->bytes + bl->ksize;
+ }
+
+ if (key == NULL)
+ return (RET_SUCCESS);
+
+ if (bl->flags & P_BIGKEY) {
+ if (__ovfl_get(t, bl->bytes,
+ &key->size, &t->bt_kbuf, &t->bt_kbufsz))
+ return (RET_ERROR);
+ key->data = t->bt_kbuf;
+ } else if (ISSET(t, B_DB_LOCK)) {
+ if (bl->ksize > t->bt_kbufsz) {
+ if ((p =
+ (void *)realloc(t->bt_kbuf, bl->ksize)) == NULL)
+ return (RET_ERROR);
+ t->bt_kbuf = p;
+ t->bt_kbufsz = bl->ksize;
+ }
+ memmove(t->bt_kbuf, bl->bytes, bl->ksize);
+ key->size = bl->ksize;
+ key->data = t->bt_kbuf;
+ } else {
+ key->size = bl->ksize;
+ key->data = bl->bytes;
+ }
+ 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_dbuf, &t->bt_dbufsz))
+ return (RET_ERROR);
+ k2.data = t->bt_dbuf;
+ }
+ 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..dd798ec
--- /dev/null
+++ b/lib/libc/db/btree/btree.h
@@ -0,0 +1,353 @@
+/*-
+ * Copyright (c) 1991, 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.
+ *
+ * @(#)btree.h 8.5 (Berkeley) 2/21/94
+ */
+
+#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(size_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 {
+ size_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(size_t) + sizeof(pgno_t) + sizeof(u_char) + (len))
+
+/* Copy a BINTERNAL entry to the page. */
+#define WR_BINTERNAL(p, size, pgno, flags) { \
+ *(size_t *)p = size; \
+ p += sizeof(size_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 {
+ size_t ksize; /* size of key */
+ size_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(size_t) + sizeof(size_t) + sizeof(u_char) + \
+ (ksize) + (dsize))
+
+/* Copy a BLEAF entry to the page. */
+#define WR_BLEAF(p, key, data, flags) { \
+ *(size_t *)p = key->size; \
+ p += sizeof(size_t); \
+ *(size_t *)p = data->size; \
+ p += sizeof(size_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 {
+ size_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(size_t) + sizeof(u_char) + (dsize))
+
+/* Copy a RLEAF entry to the page. */
+#define WR_RLEAF(p, data, flags) { \
+ *(size_t *)p = data->size; \
+ p += sizeof(size_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.
+ *
+ * One comment about cursors. The cursor key is never removed from the tree,
+ * even if deleted. This is because it is quite difficult to decide where the
+ * cursor should be when other keys have been inserted/deleted in the tree;
+ * duplicate keys make it impossible. This scheme does require extra work
+ * though, to make sure that we don't perform an operation on a deleted key.
+ */
+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;
+
+/*
+ * The metadata of the tree. The m_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 m_magic; /* magic number */
+ u_int32_t m_version; /* version */
+ u_int32_t m_psize; /* page size */
+ u_int32_t m_free; /* page number of first free page */
+ u_int32_t m_nrecs; /* R: number of records */
+#define SAVEMETA (B_NODUPS | R_RECNO)
+ u_int32_t m_flags; /* bt_flags & SAVEMETA */
+ u_int32_t m_unused; /* unused */
+} 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 */
+
+ EPGNO bt_bcursor; /* B: btree cursor */
+ recno_t bt_rcursor; /* R: recno cursor (1-based) */
+
+#define BT_POP(t) (t->bt_sp ? t->bt_stack + --t->bt_sp : NULL)
+#define BT_CLR(t) (t->bt_sp = 0)
+ EPGNO *bt_stack; /* stack of parent pages */
+ u_int bt_sp; /* current stack pointer */
+ u_int bt_maxstack; /* largest stack */
+
+ char *bt_kbuf; /* key buffer */
+ size_t bt_kbufsz; /* key buffer size */
+ char *bt_dbuf; /* data buffer */
+ size_t bt_dbufsz; /* data buffer size */
+
+ 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_DELCRSR 0x00001 /* cursor has been deleted */
+#define B_INMEM 0x00002 /* in-memory tree */
+#define B_METADIRTY 0x00004 /* need to write metadata */
+#define B_MODIFIED 0x00008 /* tree modified */
+#define B_NEEDSWAP 0x00010 /* if byte order requires swapping */
+#define B_NODUPS 0x00020 /* no duplicate keys permitted */
+#define B_RDONLY 0x00040 /* read-only tree */
+#define R_RECNO 0x00080 /* record oriented tree */
+#define B_SEQINIT 0x00100 /* sequential scan initialized */
+
+#define R_CLOSEFP 0x00200 /* opened a file pointer */
+#define R_EOF 0x00400 /* end of input file reached. */
+#define R_FIXLEN 0x00800 /* fixed length records */
+#define R_MEMMAPPED 0x01000 /* memory mapped file. */
+#define R_INMEM 0x02000 /* in-memory file */
+#define R_MODIFIED 0x04000 /* modified file */
+#define R_RDONLY 0x08000 /* read-only file */
+
+#define B_DB_LOCK 0x10000 /* DB_LOCK specified. */
+#define B_DB_SHMEM 0x20000 /* DB_SHMEM specified. */
+#define B_DB_TXN 0x40000 /* DB_TXN specified. */
+
+ u_int32_t bt_flags; /* btree state */
+} BTREE;
+
+#define SET(t, f) ((t)->bt_flags |= (f))
+#define CLR(t, f) ((t)->bt_flags &= ~(f))
+#define ISSET(t, f) ((t)->bt_flags & (f))
+
+#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..4007bc7
--- /dev/null
+++ b/lib/libc/db/btree/extern.h
@@ -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.
+ *
+ * @(#)extern.h 8.3 (Berkeley) 2/21/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 *, PAGE *, int));
+int __bt_fd __P((const DB *));
+EPG *__bt_first __P((BTREE *, const DBT *, int *));
+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 *));
+EPG *__bt_search __P((BTREE *, const DBT *, int *));
+int __bt_seq __P((const DB *, DBT *, DBT *, u_int));
+int __bt_split __P((BTREE *, PAGE *,
+ const DBT *, const DBT *, int, size_t, indx_t));
+int __bt_sync __P((const DB *, u_int));
+
+int __ovfl_delete __P((BTREE *, void *));
+int __ovfl_get __P((BTREE *, void *, size_t *, char **, 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/db/Makefile.inc b/lib/libc/db/db/Makefile.inc
new file mode 100644
index 0000000..59478ba1
--- /dev/null
+++ b/lib/libc/db/db/Makefile.inc
@@ -0,0 +1,5 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+
+.PATH: ${.CURDIR}/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/doc/hash.usenix.ps b/lib/libc/db/doc/hash.usenix.ps
new file mode 100644
index 0000000..c884778
--- /dev/null
+++ b/lib/libc/db/doc/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: $Header: psdit.pro,v 2.1 85/11/24 12:19:43 shore Rel $
+
+% 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/doc/libtp.usenix.ps b/lib/libc/db/doc/libtp.usenix.ps
new file mode 100644
index 0000000..ea821a9
--- /dev/null
+++ b/lib/libc/db/doc/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: $Header: psdit.pro,v 2.1 85/11/24 12:19:43 shore Rel $
+
+% 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..cac96fe
--- /dev/null
+++ b/lib/libc/db/hash/Makefile.inc
@@ -0,0 +1,6 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+
+.PATH: ${.CURDIR}/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..b7ef37a
--- /dev/null
+++ b/lib/libc/db/hash/extern.h
@@ -0,0 +1,65 @@
+/*-
+ * 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.2 (Berkeley) 2/21/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_int, SPLIT_RETURN *));
+int __buf_free __P((HTAB *, int, int));
+void __buf_init __P((HTAB *, int));
+u_int __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_short __find_last_page __P((HTAB *, BUFHEAD **));
+void __free_ovflpage __P((HTAB *, BUFHEAD *));
+BUFHEAD *__get_buf __P((HTAB *, u_int, BUFHEAD *, int));
+int __get_page __P((HTAB *, char *, u_int, int, int, int));
+int __init_bitmap __P((HTAB *, int, int, int));
+u_int __log2 __P((u_int));
+int __put_page __P((HTAB *, char *, u_int, int, int));
+void __reclaim_buf __P((HTAB *, BUFHEAD *));
+int __split_page __P((HTAB *, u_int, u_int));
+
+/* Default hash routine. */
+extern u_int32_t (*__default_hash) __P((const void *, size_t));
+
+#ifdef HASH_STATISTICS
+extern long 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..6a23f3d
--- /dev/null
+++ b/lib/libc/db/hash/hash.c
@@ -0,0 +1,994 @@
+/*-
+ * 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.c 8.7 (Berkeley) 2/21/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_int));
+static int hash_fd __P((const DB *));
+static int hash_get __P((const DB *, const DBT *, DBT *, u_int));
+static int hash_put __P((const DB *, DBT *, const DBT *, u_int));
+static void *hash_realloc __P((SEGMENT **, int, int));
+static int hash_seq __P((const DB *, DBT *, DBT *, u_int));
+static int hash_sync __P((const DB *, u_int));
+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
+long 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);
+ (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_long *));
+ }
+
+ /* 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 (__init_bitmap(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_int 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->errno = 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_int flag;
+{
+ HTAB *hashp;
+
+ hashp = (HTAB *)dbp->internal;
+ if (flag) {
+ hashp->errno = 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_int flag;
+{
+ HTAB *hashp;
+
+ hashp = (HTAB *)dbp->internal;
+ if (flag && flag != R_NOOVERWRITE) {
+ hashp->errno = errno = EINVAL;
+ return (ERROR);
+ }
+ if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
+ hashp->errno = 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_int flag; /* Ignored */
+{
+ HTAB *hashp;
+
+ hashp = (HTAB *)dbp->internal;
+ if (flag && flag != R_CURSOR) {
+ hashp->errno = errno = EINVAL;
+ return (ERROR);
+ }
+ if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
+ hashp->errno = 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_short *bp;
+ register int n, ndx, off, size;
+ register char *kp;
+ u_short 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_short *)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_short *)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_short *)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_short *)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_int flag;
+{
+ register u_int bucket;
+ register BUFHEAD *bufp;
+ HTAB *hashp;
+ u_short *bp, ndx;
+
+ hashp = (HTAB *)dbp->internal;
+ if (flag && flag != R_FIRST && flag != R_NEXT) {
+ hashp->errno = 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_short *)bufp->page;
+ if (bp[0])
+ break;
+ }
+ hashp->cbucket = bucket;
+ if (hashp->cbucket > hashp->MAX_BUCKET) {
+ hashp->cbucket = -1;
+ return (ABNORMAL);
+ }
+ } else
+ bp = (u_short *)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_short *)(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_int 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_int
+__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..1c80f83
--- /dev/null
+++ b/lib/libc/db/hash/hash.h
@@ -0,0 +1,284 @@
+/*-
+ * 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.
+ *
+ * @(#)hash.h 8.2 (Berkeley) 2/21/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_int 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 */
+ long 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_short 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 errno; /* 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_long *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_int)0xFFFFFFFF)
+#define ALL_CLEAR 0
+
+#define PTROF(X) ((BUFHEAD *)((u_int)(X)&~0x3))
+#define ISMOD(X) ((u_int)(X)&0x1)
+#define DOMOD(X) ((X) = (char *)((u_int)(X)|0x1))
+#define ISDISK(X) ((u_int)(X)&0x2)
+#define DODISK(X) ((X) = (char *)((u_int)(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_int)(N)) >> SPLITSHIFT)
+#define OPAGENUM(N) ((N) & SPLITMASK)
+#define OADDR_OF(S,O) ((u_int)((u_int)(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..b747fbc
--- /dev/null
+++ b/lib/libc/db/hash/hash_bigkey.c
@@ -0,0 +1,667 @@
+/*-
+ * 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_bigkey.c 8.2 (Berkeley) 2/21/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_short *p;
+ int key_size, n, val_size;
+ u_short space, move_bytes, off;
+ char *cp, *key_data, *val_data;
+
+ cp = bufp->page; /* Character pointer of p. */
+ p = (u_short *)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_short *)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_short *)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_short *bp, pageno;
+ int key_done, n;
+
+ rbufp = bufp;
+ last_bfp = NULL;
+ bp = (u_short *)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_short *)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_short *)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_short *bp;
+ register char *p;
+ int ksize;
+ u_short bytes;
+ char *kkey;
+
+ bp = (u_short *)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_short *)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_short
+__find_last_page(hashp, bpp)
+ HTAB *hashp;
+ BUFHEAD **bpp;
+{
+ BUFHEAD *bufp;
+ u_short *bp, pageno;
+ int n;
+
+ bufp = *bpp;
+ bp = (u_short *)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_short *)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_short *bp, len, off, save_addr;
+ char *tp;
+
+ bp = (u_short *)bufp->page;
+ while (bp[ndx + 1] == PARTIAL_KEY) {
+ bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
+ if (!bufp)
+ return (-1);
+ bp = (u_short *)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_short *)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_short *)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_short *)
+ 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_short *bp;
+ register char *p;
+ BUFHEAD *xbp;
+ u_short save_addr;
+ int mylen, totlen;
+
+ p = bufp->page;
+ bp = (u_short *)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_short *)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_short *bp, save_addr;
+
+ p = bufp->page;
+ bp = (u_short *)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_int obucket;/* Old Bucket */
+ SPLIT_RETURN *ret;
+{
+ register BUFHEAD *tmpp;
+ register u_short *tp;
+ BUFHEAD *bp;
+ DBT key, val;
+ u_int change;
+ u_short 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_short *)tmpp->page;
+#ifdef DEBUG
+ assert(FREESPACE(tp) >= OVFLSIZE);
+#endif
+ n = tp[0];
+ off = OFFSET(tp);
+ free_space = FREESPACE(tp);
+ tp[++n] = (u_short)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_short *)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..1362c83
--- /dev/null
+++ b/lib/libc/db/hash/hash_buf.c
@@ -0,0 +1,347 @@
+/*-
+ * 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_buf.c 8.2 (Berkeley) 2/21/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 <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_int, 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_int addr;
+ BUFHEAD *prev_bp;
+ int newpage; /* If prev_bp set, indicates a new overflow page. */
+{
+ register BUFHEAD *bp;
+ register u_int 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 *)((u_int)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_int 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_short 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);
+ if ((bp->page = (char *)malloc(hashp->BSIZE)) == NULL) {
+ free(bp);
+ return (NULL);
+ }
+ 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_short *)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_short *)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..b773707
--- /dev/null
+++ b/lib/libc/db/hash/hash_log2.c
@@ -0,0 +1,52 @@
+/*-
+ * 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_log2.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+u_int
+__log2(num)
+ u_int num;
+{
+ register u_int 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..7b018cb
--- /dev/null
+++ b/lib/libc/db/hash/hash_page.c
@@ -0,0 +1,944 @@
+/*-
+ * 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_page.c 8.4 (Berkeley) 2/21/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_long *fetch_bitmap __P((HTAB *, int));
+static u_long first_free __P((u_long));
+static int open_temp __P((HTAB *));
+static u_short overflow_page __P((HTAB *));
+static void putpair __P((char *, const DBT *, const DBT *));
+static void squeeze_key __P((u_short *, const DBT *, const DBT *));
+static int ugly_split
+ __P((HTAB *, u_int, BUFHEAD *, BUFHEAD *, int, int));
+
+#define PAGE_INIT(P) { \
+ ((u_short *)(P))[0] = 0; \
+ ((u_short *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_short); \
+ ((u_short *)(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_short *bp, n, off;
+
+ bp = (u_short *)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_short));
+ bp[n + 2] = off;
+}
+
+/*
+ * Returns:
+ * 0 OK
+ * -1 error
+ */
+extern int
+__delpair(hashp, bufp, ndx)
+ HTAB *hashp;
+ BUFHEAD *bufp;
+ register int ndx;
+{
+ register u_short *bp, newoff;
+ register int n;
+ u_short pairlen;
+
+ bp = (u_short *)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_short);
+ 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_int obucket, nbucket;
+{
+ register BUFHEAD *new_bufp, *old_bufp;
+ register u_short *ino;
+ register char *np;
+ DBT key, val;
+ int n, ndx, retval;
+ u_short copyto, diff, off, moved;
+ char *op;
+
+ copyto = (u_short)hashp->BSIZE;
+ off = (u_short)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_short *)(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_short) * (ino[0] + 3);
+ OFFSET(ino) = copyto;
+
+#ifdef DEBUG3
+ (void)fprintf(stderr, "split %d/%d\n",
+ ((u_short *)np)[0] / 2,
+ ((u_short *)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_int 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_short *ino; /* Page keys come off of */
+ register u_short *np; /* New page */
+ register u_short *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_short n, off, ov_addr, scopyto;
+ char *cino; /* Character value of ino */
+
+ bufp = old_bufp;
+ ino = (u_short *)old_bufp->page;
+ np = (u_short *)new_bufp->page;
+ op = (u_short *)old_bufp->page;
+ last_bfp = NULL;
+ scopyto = (u_short)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_short *)old_bufp->page;
+ new_bufp = ret.newp;
+ if (!new_bufp)
+ return (-1);
+ np = (u_short *)new_bufp->page;
+ bufp = ret.nextp;
+ if (!bufp)
+ return (0);
+ cino = (char *)bufp->page;
+ ino = (u_short *)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_short) * (ino[0] + 3);
+ OFFSET(ino) = scopyto;
+
+ bufp = __get_buf(hashp, ov_addr, bufp, 0);
+ if (!bufp)
+ return (-1);
+
+ ino = (u_short *)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_short *)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_short *)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_short *bp, *sop;
+ int do_expand;
+
+ bp = (u_short *)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_short *)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_short *)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_short *)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_short *sp;
+ u_short ndx, ovfl_num;
+#ifdef DEBUG1
+ int tmp1, tmp2;
+#endif
+ sp = (u_short *)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_int bucket;
+ int is_bucket, is_disk, is_bitmap;
+{
+ register int fd, page, size;
+ int rsize;
+ u_short *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_short *)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(((long *)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_int 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(((long *)p)[i]);
+ } else {
+ max = ((u_short *)p)[0] + 2;
+ for (i = 0; i <= max; i++)
+ M_16_SWAP(((u_short *)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
+__init_bitmap(hashp, pnum, nbits, ndx)
+ HTAB *hashp;
+ int pnum, nbits, ndx;
+{
+ u_long *ip;
+ int clearbytes, clearints;
+
+ if ((ip = (u_long *)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_short)pnum;
+ hashp->mapp[ndx] = ip;
+ return (0);
+}
+
+static u_long
+first_free(map)
+ u_long map;
+{
+ register u_long i, mask;
+
+ mask = 0x1;
+ for (i = 0; i < BITS_PER_MAP; i++) {
+ if (!(mask & map))
+ return (i);
+ mask = mask << 1;
+ }
+ return (i);
+}
+
+static u_short
+overflow_page(hashp)
+ HTAB *hashp;
+{
+ register u_long *freep;
+ register int max_free, offset, splitnum;
+ u_short 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_long *)hashp->mapp[i]) &&
+ !(freep = fetch_bitmap(hashp, i)))
+ return (NULL);
+ 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 (NULL);
+ }
+ 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 (NULL);
+ }
+ /*
+ * 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 (__init_bitmap(hashp, (int)OADDR_OF(splitnum, offset),
+ 1, free_page))
+ return (NULL);
+ 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 (NULL);
+ }
+ 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 (NULL); /* 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_short addr;
+ u_long *freep;
+ int bit_address, free_page, free_bit;
+ u_short ndx;
+
+ addr = obufp->addr;
+#ifdef DEBUG1
+ (void)fprintf(stderr, "Freeing %d\n", addr);
+#endif
+ ndx = (((u_short)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_short *sp;
+ const DBT *key, *val;
+{
+ register char *p;
+ u_short 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_long *
+fetch_bitmap(hashp, ndx)
+ HTAB *hashp;
+ int ndx;
+{
+ if (ndx >= hashp->nmaps)
+ return (NULL);
+ if ((hashp->mapp[ndx] = (u_long *)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..e4914b1
--- /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.3 (Berkeley) 2/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 = NULL;
+ info.hash = NULL;
+ info.lorder = 0;
+ dbp = (DB *)__hash_open(NULL, O_CREAT | O_RDWR, 0600, &info, 0);
+ return ((int)dbp);
+}
+
+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..89b9916
--- /dev/null
+++ b/lib/libc/db/hash/ndbm.c
@@ -0,0 +1,202 @@
+/*-
+ * 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.2 (Berkeley) 9/11/93";
+#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 <ndbm.h>
+#include <stdio.h>
+#include <string.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 = NULL;
+ info.hash = NULL;
+ info.lorder = 0;
+ (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 retval;
+ int status;
+
+ status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0);
+ if (status) {
+ retval.dptr = NULL;
+ retval.dsize = 0;
+ }
+ return (retval);
+}
+
+/*
+ * Returns:
+ * DATUM on success
+ * NULL on failure
+ */
+extern datum
+dbm_firstkey(db)
+ DBM *db;
+{
+ int status;
+ datum retdata, retkey;
+
+ status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
+ if (status)
+ retkey.dptr = NULL;
+ return (retkey);
+}
+
+/*
+ * Returns:
+ * DATUM on success
+ * NULL on failure
+ */
+extern datum
+dbm_nextkey(db)
+ DBM *db;
+{
+ int status;
+ datum retdata, retkey;
+
+ status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
+ if (status)
+ retkey.dptr = NULL;
+ return (retkey);
+}
+/*
+ * Returns:
+ * 0 on success
+ * <0 failure
+ */
+extern int
+dbm_delete(db, key)
+ DBM *db;
+ datum key;
+{
+ int status;
+
+ status = (db->del)(db, (DBT *)&key, 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, content, flags)
+ DBM *db;
+ datum key, content;
+ int flags;
+{
+ return ((db->put)(db, (DBT *)&key, (DBT *)&content,
+ (flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
+}
+
+extern int
+dbm_error(db)
+ DBM *db;
+{
+ HTAB *hp;
+
+ hp = (HTAB *)db->internal;
+ return (hp->errno);
+}
+
+extern int
+dbm_clearerr(db)
+ DBM *db;
+{
+ HTAB *hp;
+
+ hp = (HTAB *)db->internal;
+ hp->errno = 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..dae82ae
--- /dev/null
+++ b/lib/libc/db/hash/page.h
@@ -0,0 +1,92 @@
+/*-
+ * 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.
+ *
+ * @(#)page.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * 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_short) + (K)->size + (D)->size)
+#define BIGOVERHEAD (4*sizeof(u_short))
+#define KEYSIZE(K) (4*sizeof(u_short) + (K)->size);
+#define OVFLSIZE (2*sizeof(u_short))
+#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_short))
+
+typedef struct {
+ BUFHEAD *newp;
+ BUFHEAD *oldp;
+ BUFHEAD *nextp;
+ u_short 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..f55b9f4
--- /dev/null
+++ b/lib/libc/db/man/Makefile.inc
@@ -0,0 +1,8 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+
+.PATH: ${.CURDIR}/db/man
+
+# mpool.3
+MAN3+= db/man/btree.3 db/man/dbopen.3 db/man/hash.3 db/man/recno.3
+MAN3+= db/man/mpool.3
+MLINKS+= dbopen.3 db.3
diff --git a/lib/libc/db/man/btree.3 b/lib/libc/db/man/btree.3
new file mode 100644
index 0000000..a51e1e5
--- /dev/null
+++ b/lib/libc/db/man/btree.3
@@ -0,0 +1,226 @@
+.\" 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.3 (Berkeley) 2/21/94
+.\"
+.TH BTREE 3 "February 21, 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 "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..f06a4ef
--- /dev/null
+++ b/lib/libc/db/man/dbopen.3
@@ -0,0 +1,476 @@
+.\" 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
+.\"
+.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..3ae00a2
--- /dev/null
+++ b/lib/libc/db/man/hash.3
@@ -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.
+.\"
+.\" @(#)hash.3 8.5 (Berkeley) 2/21/94
+.\"
+.TH HASH 3 "February 21, 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 routines described in
+.IR dbm (3),
+and
+.IR ndbm (3)
+are provided, however these interfaces are not compatible with
+previous file formats.
+.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..c17606e
--- /dev/null
+++ b/lib/libc/db/man/mpool.3
@@ -0,0 +1,219 @@
+.\" 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
+.\"
+.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 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..a40e6c9
--- /dev/null
+++ b/lib/libc/db/man/recno.3
@@ -0,0 +1,196 @@
+.\" 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.3 (Berkeley) 2/21/94
+.\"
+.TH RECNO 3 "February 21, 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.
+.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
+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 "SEE ALSO"
+.IR dbopen (3),
+.IR hash (3),
+.IR mpool (3),
+.IR recno (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..93210c8
--- /dev/null
+++ b/lib/libc/db/mpool/Makefile.inc
@@ -0,0 +1,5 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+
+.PATH: ${.CURDIR}/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..562c7f5
--- /dev/null
+++ b/lib/libc/db/mpool/mpool.c
@@ -0,0 +1,534 @@
+/*-
+ * 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[] = "@(#)mpool.c 8.2 (Berkeley) 2/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.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 *));
+#ifdef DEBUG
+static void __mpoolerr __P((const char *fmt, ...));
+#endif
+
+/*
+ * MPOOL_OPEN -- initialize a memory pool.
+ *
+ * Parameters:
+ * key: Shared buffer key.
+ * fd: File descriptor.
+ * pagesize: File page size.
+ * maxcache: Max number of cached pages.
+ *
+ * Returns:
+ * MPOOL pointer, NULL on error.
+ */
+MPOOL *
+mpool_open(key, fd, pagesize, maxcache)
+ DBT *key;
+ int fd;
+ pgno_t pagesize, maxcache;
+{
+ struct stat sb;
+ MPOOL *mp;
+ int entry;
+
+ if (fstat(fd, &sb))
+ return (NULL);
+ /* XXX
+ * We should only set st_size to 0 for pipes -- 4.4BSD has the fix so
+ * that stat(2) returns true for ISSOCK on pipes. Until then, this is
+ * fairly close.
+ */
+ if (!S_ISREG(sb.st_mode)) {
+ errno = ESPIPE;
+ return (NULL);
+ }
+
+ if ((mp = (MPOOL *)malloc(sizeof(MPOOL))) == NULL)
+ return (NULL);
+ mp->free.cnext = mp->free.cprev = (BKT *)&mp->free;
+ mp->lru.cnext = mp->lru.cprev = (BKT *)&mp->lru;
+ for (entry = 0; entry < HASHSIZE; ++entry)
+ mp->hashtable[entry].hnext = mp->hashtable[entry].hprev =
+ mp->hashtable[entry].cnext = mp->hashtable[entry].cprev =
+ (BKT *)&mp->hashtable[entry];
+ mp->curcache = 0;
+ mp->maxcache = maxcache;
+ mp->pagesize = pagesize;
+ mp->npages = sb.st_size / pagesize;
+ mp->fd = fd;
+ mp->pgcookie = NULL;
+ mp->pgin = mp->pgout = NULL;
+
+#ifdef STATISTICS
+ mp->cachehit = mp->cachemiss = mp->pagealloc = mp->pageflush =
+ mp->pageget = mp->pagenew = mp->pageput = mp->pageread =
+ mp->pagewrite = 0;
+#endif
+ return (mp);
+}
+
+/*
+ * MPOOL_FILTER -- initialize input/output filters.
+ *
+ * Parameters:
+ * pgin: Page in conversion routine.
+ * pgout: Page out conversion routine.
+ * pgcookie: Cookie for page in/out routines.
+ */
+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
+ *
+ * Parameters:
+ * mp: mpool cookie
+ * pgnoadddr: place to store new page number
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+void *
+mpool_new(mp, pgnoaddr)
+ MPOOL *mp;
+ pgno_t *pgnoaddr;
+{
+ BKT *b;
+ BKTHDR *hp;
+
+#ifdef STATISTICS
+ ++mp->pagenew;
+#endif
+ /*
+ * Get a BKT from the cache. Assign a new page number, attach it to
+ * the hash and lru chains and return.
+ */
+ if ((b = mpool_bkt(mp)) == NULL)
+ return (NULL);
+ *pgnoaddr = b->pgno = mp->npages++;
+ b->flags = MPOOL_PINNED;
+ inshash(b, b->pgno);
+ inschain(b, &mp->lru);
+ return (b->page);
+}
+
+/*
+ * MPOOL_GET -- get a page from the pool
+ *
+ * Parameters:
+ * mp: mpool cookie
+ * pgno: page number
+ * flags: not used
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+void *
+mpool_get(mp, pgno, flags)
+ MPOOL *mp;
+ pgno_t pgno;
+ u_int flags; /* XXX not used? */
+{
+ BKT *b;
+ BKTHDR *hp;
+ off_t off;
+ int nr;
+
+ /*
+ * If asking for a specific page that is already in the cache, find
+ * it and return it.
+ */
+ if (b = mpool_look(mp, pgno)) {
+#ifdef STATISTICS
+ ++mp->pageget;
+#endif
+#ifdef DEBUG
+ if (b->flags & MPOOL_PINNED)
+ __mpoolerr("mpool_get: page %d already pinned",
+ b->pgno);
+#endif
+ rmchain(b);
+ inschain(b, &mp->lru);
+ b->flags |= MPOOL_PINNED;
+ return (b->page);
+ }
+
+ /* Not allowed to retrieve a non-existent page. */
+ if (pgno >= mp->npages) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /* Get a page from the cache. */
+ if ((b = mpool_bkt(mp)) == NULL)
+ return (NULL);
+ b->pgno = pgno;
+ b->flags = MPOOL_PINNED;
+
+#ifdef STATISTICS
+ ++mp->pageread;
+#endif
+ /* Read in the contents. */
+ off = mp->pagesize * pgno;
+ if (lseek(mp->fd, off, SEEK_SET) != off)
+ return (NULL);
+ if ((nr = read(mp->fd, b->page, mp->pagesize)) != mp->pagesize) {
+ if (nr >= 0)
+ errno = EFTYPE;
+ return (NULL);
+ }
+ if (mp->pgin)
+ (mp->pgin)(mp->pgcookie, b->pgno, b->page);
+
+ inshash(b, b->pgno);
+ inschain(b, &mp->lru);
+#ifdef STATISTICS
+ ++mp->pageget;
+#endif
+ return (b->page);
+}
+
+/*
+ * MPOOL_PUT -- return a page to the pool
+ *
+ * Parameters:
+ * mp: mpool cookie
+ * page: page pointer
+ * pgno: page number
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+mpool_put(mp, page, flags)
+ MPOOL *mp;
+ void *page;
+ u_int flags;
+{
+ BKT *baddr;
+#ifdef DEBUG
+ BKT *b;
+#endif
+
+#ifdef STATISTICS
+ ++mp->pageput;
+#endif
+ baddr = (BKT *)((char *)page - sizeof(BKT));
+#ifdef DEBUG
+ if (!(baddr->flags & MPOOL_PINNED))
+ __mpoolerr("mpool_put: page %d not pinned", b->pgno);
+ for (b = mp->lru.cnext; b != (BKT *)&mp->lru; b = b->cnext) {
+ if (b == (BKT *)&mp->lru)
+ __mpoolerr("mpool_put: %0x: bad address", baddr);
+ if (b == baddr)
+ break;
+ }
+#endif
+ baddr->flags &= ~MPOOL_PINNED;
+ baddr->flags |= flags & MPOOL_DIRTY;
+ return (RET_SUCCESS);
+}
+
+/*
+ * MPOOL_CLOSE -- close the buffer pool
+ *
+ * Parameters:
+ * mp: mpool cookie
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+mpool_close(mp)
+ MPOOL *mp;
+{
+ BKT *b, *next;
+
+ /* Free up any space allocated to the lru pages. */
+ for (b = mp->lru.cprev; b != (BKT *)&mp->lru; b = next) {
+ next = b->cprev;
+ free(b);
+ }
+ free(mp);
+ return (RET_SUCCESS);
+}
+
+/*
+ * MPOOL_SYNC -- sync the file to disk.
+ *
+ * Parameters:
+ * mp: mpool cookie
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+int
+mpool_sync(mp)
+ MPOOL *mp;
+{
+ BKT *b;
+
+ for (b = mp->lru.cprev; b != (BKT *)&mp->lru; b = b->cprev)
+ if (b->flags & MPOOL_DIRTY && mpool_write(mp, b) == RET_ERROR)
+ return (RET_ERROR);
+ return (fsync(mp->fd) ? RET_ERROR : RET_SUCCESS);
+}
+
+/*
+ * MPOOL_BKT -- get/create a BKT from the cache
+ *
+ * Parameters:
+ * mp: mpool cookie
+ *
+ * Returns:
+ * NULL on failure and a pointer to the BKT on success
+ */
+static BKT *
+mpool_bkt(mp)
+ MPOOL *mp;
+{
+ BKT *b;
+
+ if (mp->curcache < mp->maxcache)
+ goto new;
+
+ /*
+ * If the cache is maxxed out, search 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 (b = mp->lru.cprev; b != (BKT *)&mp->lru; b = b->cprev)
+ if (!(b->flags & MPOOL_PINNED)) {
+ if (b->flags & MPOOL_DIRTY &&
+ mpool_write(mp, b) == RET_ERROR)
+ return (NULL);
+ rmhash(b);
+ rmchain(b);
+#ifdef STATISTICS
+ ++mp->pageflush;
+#endif
+#ifdef DEBUG
+ {
+ void *spage;
+ spage = b->page;
+ memset(b, 0xff, sizeof(BKT) + mp->pagesize);
+ b->page = spage;
+ }
+#endif
+ return (b);
+ }
+
+new: if ((b = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL)
+ return (NULL);
+#ifdef STATISTICS
+ ++mp->pagealloc;
+#endif
+#ifdef DEBUG
+ memset(b, 0xff, sizeof(BKT) + mp->pagesize);
+#endif
+ b->page = (char *)b + sizeof(BKT);
+ ++mp->curcache;
+ return (b);
+}
+
+/*
+ * MPOOL_WRITE -- sync a page to disk
+ *
+ * Parameters:
+ * mp: mpool cookie
+ *
+ * Returns:
+ * RET_ERROR, RET_SUCCESS
+ */
+static int
+mpool_write(mp, b)
+ MPOOL *mp;
+ BKT *b;
+{
+ off_t off;
+
+ if (mp->pgout)
+ (mp->pgout)(mp->pgcookie, b->pgno, b->page);
+
+#ifdef STATISTICS
+ ++mp->pagewrite;
+#endif
+ off = mp->pagesize * b->pgno;
+ if (lseek(mp->fd, off, SEEK_SET) != off)
+ return (RET_ERROR);
+ if (write(mp->fd, b->page, mp->pagesize) != mp->pagesize)
+ return (RET_ERROR);
+ b->flags &= ~MPOOL_DIRTY;
+ return (RET_SUCCESS);
+}
+
+/*
+ * MPOOL_LOOK -- lookup a page
+ *
+ * Parameters:
+ * mp: mpool cookie
+ * pgno: page number
+ *
+ * Returns:
+ * NULL on failure and a pointer to the BKT on success
+ */
+static BKT *
+mpool_look(mp, pgno)
+ MPOOL *mp;
+ pgno_t pgno;
+{
+ register BKT *b;
+ register BKTHDR *tb;
+
+ /* XXX
+ * If find the buffer, put it first on the hash chain so can
+ * find it again quickly.
+ */
+ tb = &mp->hashtable[HASHKEY(pgno)];
+ for (b = tb->hnext; b != (BKT *)tb; b = b->hnext)
+ if (b->pgno == pgno) {
+#ifdef STATISTICS
+ ++mp->cachehit;
+#endif
+ return (b);
+ }
+#ifdef STATISTICS
+ ++mp->cachemiss;
+#endif
+ return (NULL);
+}
+
+#ifdef STATISTICS
+/*
+ * MPOOL_STAT -- cache statistics
+ *
+ * Parameters:
+ * mp: mpool cookie
+ */
+void
+mpool_stat(mp)
+ MPOOL *mp;
+{
+ BKT *b;
+ 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 (b = mp->lru.cnext; b != (BKT *)&mp->lru; b = b->cnext) {
+ (void)fprintf(stderr, "%s%d", sep, b->pgno);
+ if (b->flags & MPOOL_DIRTY)
+ (void)fprintf(stderr, "d");
+ if (b->flags & MPOOL_PINNED)
+ (void)fprintf(stderr, "P");
+ if (++cnt == 10) {
+ sep = "\n";
+ cnt = 0;
+ } else
+ sep = ", ";
+
+ }
+ (void)fprintf(stderr, "\n");
+}
+#endif
+
+#ifdef DEBUG
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+static void
+#if __STDC__
+__mpoolerr(const char *fmt, ...)
+#else
+__mpoolerr(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void)fprintf(stderr, "\n");
+ abort();
+ /* NOTREACHED */
+}
+#endif
diff --git a/lib/libc/db/recno/Makefile.inc b/lib/libc/db/recno/Makefile.inc
new file mode 100644
index 0000000..e49e225
--- /dev/null
+++ b/lib/libc/db/recno/Makefile.inc
@@ -0,0 +1,6 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+
+.PATH: ${.CURDIR}/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..2188131
--- /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.2 (Berkeley) 2/21/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 *, indx_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..a96d4f1
--- /dev/null
+++ b/lib/libc/db/recno/rec_close.c
@@ -0,0 +1,163 @@
+/*-
+ * 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_close.c 8.3 (Berkeley) 2/21/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 (ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize))
+ status = RET_ERROR;
+
+ if (!ISSET(t, R_INMEM))
+ if (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 (ISSET(t, R_RDONLY | R_INMEM) || !ISSET(t, R_MODIFIED))
+ return (RET_SUCCESS);
+
+ /* Read any remaining records into the tree. */
+ if (!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);
+
+ iov[1].iov_base = "\n";
+ iov[1].iov_len = 1;
+ scursor = t->bt_rcursor;
+
+ key.size = sizeof(recno_t);
+ key.data = &trec;
+
+ 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);
+ }
+ t->bt_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);
+ 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..35f56b9
--- /dev/null
+++ b/lib/libc/db/recno/rec_delete.c
@@ -0,0 +1,197 @@
+/*-
+ * 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[] = "@(#)rec_delete.c 8.4 (Berkeley) 2/21/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 (!ISSET(t, B_SEQINIT))
+ goto einval;
+ if (t->bt_nrecs == 0)
+ return (RET_SPECIAL);
+ status = rec_rdelete(t, t->bt_rcursor - 1);
+ if (status == RET_SUCCESS)
+ --t->bt_rcursor;
+ break;
+ default:
+einval: errno = EINVAL;
+ return (RET_ERROR);
+ }
+
+ if (status == RET_SUCCESS)
+ 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;
+ indx_t index;
+{
+ register RLEAF *rl;
+ register indx_t *ip, cnt, offset;
+ register size_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..3555575
--- /dev/null
+++ b/lib/libc/db/recno/rec_get.c
@@ -0,0 +1,298 @@
+/*-
+ * 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_get.c 8.4 (Berkeley) 3/1/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 (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 (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;
+ char *p;
+
+ if (t->bt_dbufsz < t->bt_reclen) {
+ if ((t->bt_dbuf =
+ (char *)realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
+ return (RET_ERROR);
+ t->bt_dbufsz = t->bt_reclen;
+ }
+ data.data = t->bt_dbuf;
+ data.size = t->bt_reclen;
+
+ for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
+ len = t->bt_reclen;
+ for (p = t->bt_dbuf;; *p++ = ch)
+ if ((ch = getc(t->bt_rfp)) == EOF || !len--) {
+ if (__rec_iput(t, nrec, &data, 0)
+ != RET_SUCCESS)
+ return (RET_ERROR);
+ break;
+ }
+ if (ch == EOF)
+ break;
+ }
+ if (nrec < top) {
+ 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;
+ char *p;
+
+ bval = t->bt_bval;
+ for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
+ for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) {
+ if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
+ data.data = t->bt_dbuf;
+ data.size = p - t->bt_dbuf;
+ 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 - t->bt_dbuf;
+ t->bt_dbufsz += (sz = 256);
+ if ((t->bt_dbuf = (char *)realloc(t->bt_dbuf,
+ t->bt_dbufsz)) == NULL)
+ return (RET_ERROR);
+ p = t->bt_dbuf + len;
+ }
+ }
+ if (ch == EOF)
+ break;
+ }
+ if (nrec < top) {
+ 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;
+ caddr_t sp, ep;
+ size_t len;
+ char *p;
+
+ if (t->bt_dbufsz < t->bt_reclen) {
+ if ((t->bt_dbuf =
+ (char *)realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
+ return (RET_ERROR);
+ t->bt_dbufsz = t->bt_reclen;
+ }
+ data.data = t->bt_dbuf;
+ data.size = t->bt_reclen;
+
+ sp = t->bt_cmap;
+ ep = t->bt_emap;
+ for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
+ if (sp >= ep) {
+ SET(t, R_EOF);
+ return (RET_SPECIAL);
+ }
+ len = t->bt_reclen;
+ for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++);
+ memset(p, t->bt_bval, len);
+ if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
+ return (RET_ERROR);
+ }
+ t->bt_cmap = 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;
+ caddr_t sp, ep;
+ recno_t nrec;
+ int bval;
+
+ sp = t->bt_cmap;
+ ep = t->bt_emap;
+ bval = t->bt_bval;
+
+ for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
+ if (sp >= ep) {
+ SET(t, R_EOF);
+ return (RET_SPECIAL);
+ }
+ for (data.data = sp; sp < ep && *sp != bval; ++sp);
+ data.size = sp - (caddr_t)data.data;
+ if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
+ return (RET_ERROR);
+ ++sp;
+ }
+ t->bt_cmap = 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..2a0f354
--- /dev/null
+++ b/lib/libc/db/recno/rec_open.c
@@ -0,0 +1,230 @@
+/*-
+ * 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[] = "@(#)rec_open.c 8.6 (Berkeley) 2/22/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) {
+ 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';
+
+ SET(t, R_RECNO);
+ if (fname == NULL)
+ SET(t, R_EOF | R_INMEM);
+ else
+ t->bt_rfd = rfd;
+ t->bt_rcursor = 0;
+
+ 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:
+ SET(t, R_RDONLY);
+ break;
+ default:
+ goto einval;
+ }
+slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL)
+ goto err;
+ SET(t, R_CLOSEFP);
+ t->bt_irec =
+ ISSET(t, R_FIXLEN) ? __rec_fpipe : __rec_vpipe;
+ } else {
+ switch (flags & O_ACCMODE) {
+ case O_RDONLY:
+ 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)
+ SET(t, R_EOF);
+ else {
+ t->bt_msize = sb.st_size;
+ if ((t->bt_smap = mmap(NULL, t->bt_msize,
+ PROT_READ, MAP_PRIVATE, rfd,
+ (off_t)0)) == (caddr_t)-1)
+ goto slow;
+ t->bt_cmap = t->bt_smap;
+ t->bt_emap = t->bt_smap + sb.st_size;
+ t->bt_irec = ISSET(t, R_FIXLEN) ?
+ __rec_fmap : __rec_vmap;
+ SET(t, R_MEMMAPPED);
+ }
+ }
+ }
+
+ /* 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) {
+ h->flags = h->flags & ~P_TYPE | P_RLEAF;
+ mpool_put(t->bt_mp, h, MPOOL_DIRTY);
+ } else
+ mpool_put(t->bt_mp, h, 0);
+
+ if (openinfo && openinfo->flags & R_SNAPSHOT &&
+ !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 (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..590d45b
--- /dev/null
+++ b/lib/libc/db/recno/rec_put.c
@@ -0,0 +1,253 @@
+/*-
+ * 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_put.c 8.3 (Berkeley) 3/1/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 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;
+ }
+
+ switch (flags) {
+ case R_CURSOR:
+ if (!ISSET(t, B_SEQINIT))
+ goto einval;
+ nrec = t->bt_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 (!ISSET(t, R_EOF | R_INMEM) &&
+ t->bt_irec(t, nrec) == RET_ERROR)
+ return (RET_ERROR);
+ if (nrec > t->bt_nrecs + 1) {
+ if (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 (ISSET(t, R_FIXLEN))
+ free(tdata.data);
+ }
+ }
+
+ if ((status = __rec_iput(t, nrec - 1, data, flags)) != RET_SUCCESS)
+ return (status);
+
+ if (flags == R_SETCURSOR)
+ t->bt_rcursor = nrec;
+
+ 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;
+ size_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;
+ *(size_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;
+ 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..a1feff8
--- /dev/null
+++ b/lib/libc/db/recno/rec_search.c
@@ -0,0 +1,127 @@
+/*-
+ * 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.3 (Berkeley) 2/21/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;
+ }
+
+ if (__bt_push(t, pg, index - 1) == RET_ERROR)
+ return (NULL);
+
+ 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..56f78e7
--- /dev/null
+++ b/lib/libc/db/recno/rec_seq.c
@@ -0,0 +1,131 @@
+/*-
+ * 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[] = "@(#)rec_seq.c 8.2 (Berkeley) 9/7/93";
+#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 (ISSET(t, B_SEQINIT)) {
+ nrec = t->bt_rcursor + 1;
+ break;
+ }
+ /* FALLTHROUGH */
+ case R_FIRST:
+ nrec = 1;
+ break;
+ case R_PREV:
+ if (ISSET(t, B_SEQINIT)) {
+ if ((nrec = t->bt_rcursor - 1) == 0)
+ return (RET_SPECIAL);
+ break;
+ }
+ /* FALLTHROUGH */
+ case R_LAST:
+ if (!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 (!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);
+
+ SET(t, B_SEQINIT);
+ t->bt_rcursor = nrec;
+
+ status = __rec_ret(t, e, nrec, key, data);
+ if (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..f7fb145
--- /dev/null
+++ b/lib/libc/db/recno/rec_utils.c
@@ -0,0 +1,114 @@
+/*-
+ * 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_utils.c 8.3 (Berkeley) 2/21/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 as a result of search or scan.
+ *
+ * Parameters:
+ * t: tree
+ * d: LEAF to be returned to the user.
+ * 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;
+{
+ register RLEAF *rl;
+ register void *p;
+
+ if (data == NULL)
+ goto retkey;
+
+ rl = GETRLEAF(e->page, e->index);
+
+ /*
+ * We always copy big data to make it contigous. Otherwise, we
+ * leave the page pinned and don't copy unless the user specified
+ * concurrent access.
+ */
+ if (rl->flags & P_BIGDATA) {
+ if (__ovfl_get(t, rl->bytes,
+ &data->size, &t->bt_dbuf, &t->bt_dbufsz))
+ return (RET_ERROR);
+ data->data = t->bt_dbuf;
+ } else if (ISSET(t, B_DB_LOCK)) {
+ /* Use +1 in case the first record retrieved is 0 length. */
+ if (rl->dsize + 1 > t->bt_dbufsz) {
+ if ((p =
+ (void *)realloc(t->bt_dbuf, rl->dsize + 1)) == NULL)
+ return (RET_ERROR);
+ t->bt_dbuf = p;
+ t->bt_dbufsz = rl->dsize + 1;
+ }
+ memmove(t->bt_dbuf, rl->bytes, rl->dsize);
+ data->size = rl->dsize;
+ data->data = t->bt_dbuf;
+ } else {
+ data->size = rl->dsize;
+ data->data = rl->bytes;
+ }
+
+retkey: if (key == NULL)
+ return (RET_SUCCESS);
+
+ /* We have to copy the key, it's not on the page. */
+ if (sizeof(recno_t) > t->bt_kbufsz) {
+ if ((p = (void *)realloc(t->bt_kbuf, sizeof(recno_t))) == NULL)
+ return (RET_ERROR);
+ t->bt_kbuf = p;
+ t->bt_kbufsz = sizeof(recno_t);
+ }
+ memmove(t->bt_kbuf, &nrec, sizeof(recno_t));
+ key->size = sizeof(recno_t);
+ key->data = t->bt_kbuf;
+ 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..c816432
--- /dev/null
+++ b/lib/libc/db/test/Makefile
@@ -0,0 +1,17 @@
+# @(#)Makefile 8.9 (Berkeley) 2/21/94
+
+PROG= dbtest
+OBJS= dbtest.o strerror.o
+
+# Add -DSTATISTICS to CFLAGS to get btree statistical use info.
+# Note, the db library has to be compiled for statistics as well.
+CFLAGS= -D__DBINTERFACE_PRIVATE -DDEBUG -O ${INC}
+
+dbtest: ${OBJS} ${LIB}
+ ${CC} -o $@ ${OBJS} ${LIB}
+
+strerror.o: ../PORT/clib/strerror.c
+ ${CC} -c ../PORT/clib/strerror.c
+
+clean:
+ rm -f gmon.out ${OBJS} ${PROG} t1 t2 t3
diff --git a/lib/libc/db/test/README b/lib/libc/db/test/README
new file mode 100644
index 0000000..8631c77
--- /dev/null
+++ b/lib/libc/db/test/README
@@ -0,0 +1,55 @@
+# @(#)README 8.2 (Berkeley) 2/21/94
+
+To build this portably, try something like:
+
+ make INC="-I../PORT/MACH/ -I../PORT/MACH/include" LIB=../PORT/MACH/libdb.a
+
+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.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+The script file consists of lines with a initial character which is
+the "command" for that line. Legal 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.
+g: do a get command
+ + must be followed by [kK]
+ + writes out the retrieved data DBT.
+p: do a put command
+ + must be followed by [kK][dD]
+r: do a del command
+ + must be followed by [kK]
+s: do a seq command
+ + writes out the retrieved data DBT.
+f: set the flags for the next command
+ + no value zero's the flags
+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.
+o [r]: dump [reverse]
+ + dump the database out, if 'r' is set, in reverse order.
+
+Options to dbtest are as follows:
+
+ -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.
+
+Dbtest requires two arguments, the type of access "hash", "recno" or
+"btree", and the script name.
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..c526415
--- /dev/null
+++ b/lib/libc/db/test/dbtest.c
@@ -0,0 +1,666 @@
+/*-
+ * 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 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[] = "@(#)dbtest.c 8.8 (Berkeley) 2/21/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 *));
+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;
+void *infop;
+u_long lineno;
+u_int flags;
+int ofd = STDOUT_FILENO;
+
+DB *XXdbp; /* Global 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;
+ char *fname, *infoarg, *p, buf[8 * 1024];
+
+ infoarg = NULL;
+ fname = NULL;
+ oflags = O_CREAT | O_RDWR;
+ while ((ch = getopt(argc, argv, "f:i:lo:")) != 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 '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 2)
+ usage();
+
+ /* Set the type. */
+ type = dbtype(*argv++);
+
+ /* Open the descriptor file. */
+ if (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. */
+ if (fname == NULL) {
+ p = getenv("TMPDIR");
+ if (p == NULL)
+ p = "/var/tmp";
+ (void)sprintf(buf, "%s/__dbtest", p);
+ fname = buf;
+ (void)unlink(buf);
+ }
+ 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) {
+ len = strlen(buf);
+ 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)
+ 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);
+ state = KEY;
+ command = REMOVE;
+ 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)
+ free(key.data);
+ state = COMMAND;
+ break;
+ case SEQ:
+ seq(dbp, &key);
+ if (type != DB_RECNO)
+ 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",
+ p, lineno);
+ }
+ }
+#ifdef STATISTICS
+ if (type == DB_BTREE)
+ __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"
+#define NOSUCHKEY "get failed, no such 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);
+ break;
+ case -1:
+ err("line %lu: get: %s", lineno, strerror(errno));
+ /* NOTREACHED */
+ case 1:
+ (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
+ (void)fprintf(stderr, "%d: %.*s: %s\n",
+ lineno, kp->size, kp->data, 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: get 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: get: %s", lineno, strerror(errno));
+ /* NOTREACHED */
+ case 1:
+ (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
+ break;
+ }
+}
+
+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);
+ break;
+ case -1:
+ err("line %lu: seq: %s", lineno, strerror(errno));
+ /* NOTREACHED */
+ case 1:
+ (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
+ 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);
+ 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')
+ 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 */
+}
+
+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..5eeaf74
--- /dev/null
+++ b/lib/libc/db/test/run.test
@@ -0,0 +1,699 @@
+#!/bin/sh -
+#
+# @(#)run.test 8.7 (Berkeley) 9/16/93
+#
+
+# db regression tests
+main()
+{
+
+DICT=/usr/share/dict/words
+#DICT=/usr/dict/words
+PROG=./dbtest
+TMP1=t1
+TMP2=t2
+TMP3=t3
+
+ 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("get 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\nk120\n");
+ printf("fR_NEXT\ns\n");
+ printf("fR_CURSOR\ns\nk1\n");
+ printf("r\nk1\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)\r\n", i);
+ } else
+ printf("e\t%d of 10 \r\n", i);
+ printf("r\nkkey1\nr\nkkey2\n");
+ }
+ printf("e\n");
+ printf("eend of test8 run\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\nk1\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 -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..69a434d
--- /dev/null
+++ b/lib/libc/gen/Makefile.inc
@@ -0,0 +1,114 @@
+# From: @(#)Makefile.inc 8.3 (Berkeley) 4/16/94
+# $Id: Makefile.inc,v 1.15 1994/12/18 14:06:38 guido Exp $
+
+# machine-independent gen sources
+.PATH: ${.CURDIR}/${MACHINE}/gen ${.CURDIR}/gen
+
+SRCS+= alarm.c assert.c clock.c closedir.c config.c confstr.c crypt.c \
+ ctermid.c daemon.c devname.c disklabel.c err.c errlst.c \
+ exec.c fnmatch.c frexp.c fstab.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 \
+ getosreldate.c getpagesize.c getpass.c getpwent.c getttyent.c \
+ getusershell.c getvfsent.c glob.c initgroups.c isatty.c msgctl.c \
+ msgget.c msgrcv.c msgsnd.c nice.c nlist.c ntp_gettime.c opendir.c \
+ pause.c popen.c psignal.c pwcache.c raise.c readdir.c rewinddir.c \
+ scandir.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 sysconf.c sysctl.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
+
+# *rand48 family, from 1.1.5
+SRCS+= _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \
+ mrand48.c nrand48.c seed48.c srand48.c
+
+# machine-dependent gen sources
+.include "${.CURDIR}/${MACHINE}/gen/Makefile.inc"
+
+.if (${MACHINE} == "tahoe" || ${MACHINE} == "vax")
+errlst.o errlst.po:
+ ${CC} -S ${CFLAGS} ${.IMPSRC}
+ ed - < ${.CURDIR}/${MACHINE}/:errfix errlst.s
+ ${AS} -o ${.TARGET} errlst.s
+ rm -f errlst.s
+.endif
+
+MAN3+= gen/alarm.3 gen/clock.3 gen/confstr.3 gen/config_open.3 \
+ gen/crypt.3 gen/ctermid.3 \
+ gen/daemon.3 gen/devname.3 gen/directory.3 gen/err.3 gen/exec.3 \
+ gen/fnmatch.3 gen/frexp.3 gen/fts.3 gen/getbsize.3 gen/getbootfile.3 \
+ gen/getcap.3 gen/getcwd.3 gen/getdiskbyname.3 gen/getdomainname.3 \
+ gen/getfsent.3 gen/getgrent.3 gen/getgrouplist.3 gen/gethostname.3 \
+ gen/getloadavg.3 \
+ gen/getmntinfo.3 gen/getnetgrent.3 gen/getpagesize.3 gen/getpass.3 \
+ gen/getpwent.3 gen/getttyent.3 gen/getvfsent.3 gen/getusershell.3 \
+ gen/glob.3 \
+ gen/initgroups.3 gen/isinf.3 gen/ldexp.3 gen/modf.3 gen/nice.3 \
+ gen/nlist.3 gen/pause.3 gen/popen.3 gen/psignal.3 gen/pwcache.3 \
+ gen/raise.3 gen/rand48.3 gen/scandir.3 gen/setjmp.3 gen/setmode.3 \
+ gen/siginterrupt.3 gen/signal.3 gen/sigsetops.3 gen/sleep.3 \
+ gen/sysconf.3 gen/sysctl.3 gen/syslog.3 gen/tcgetpgrp.3 \
+ gen/tcsendbreak.3 gen/tcsetattr.3 gen/tcsetpgrp.3 gen/time.3 \
+ gen/times.3 gen/timezone.3 gen/ttyname.3 gen/tzset.3 gen/ualarm.3 \
+ gen/uname.3 gen/unvis.3 gen/usleep.3 gen/utime.3 gen/valloc.3 gen/vis.3
+
+MLINKS+=config_open.3 config_next.3 config_open.3 config_close.3 \
+ config_open.3 config_skip.3
+MLINKS+=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+=exec.3 execl.3 exec.3 execle.3 exec.3 execlp.3 exec.3 execv.3 \
+ exec.3 execvp.3
+MLINKS+=err.3 verr.3 err.3 errx.3 err.3 verrx.3 err.3 warn.3 err.3 vwarn.3 \
+ err.3 warnx.3 err.3 vwarnx.3
+MLINKS+=isinf.3 isnan.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+=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 setgroupent.3 getgrent.3 getgrgid.3 \
+ getgrent.3 getgrnam.3 getgrent.3 setgrent.3 getgrent.3 setgrfile.3
+MLINKS+=gethostname.3 sethostname.3
+MLINKS+=getdomainname.3 setdomainname.3
+MLINKS+=getnetgrent.3 endnetgrent.3 getnetgrent.3 setnetgrent.3 \
+ getnetgrent.3 innetgr.3
+MLINKS+=getpwent.3 endpwent.3 getpwent.3 setpassent.3 getpwent.3 getpwnam.3 \
+ getpwent.3 getpwuid.3 getpwent.3 setpwent.3 getpwent.3 setpwfile.3
+MLINKS+=getttyent.3 endttyent.3 getttyent.3 getttynam.3 getttyent.3 setttyent.3
+MLINKS+=getvfsent.3 getvfsbyname.3 getvfsent.3 getvfsbytype.3 \
+ getvfsent.3 setvfsent.3 getvfsent.3 endvfsent.3 \
+ getvfsent.3 vfsisloadable.3 getvfsent.3 vfsload.3
+MLINKS+=getusershell.3 endusershell.3 getusershell.3 setusershell.3
+MLINKS+=glob.3 globfree.3
+MLINKS+=popen.3 pclose.3
+MLINKS+=psignal.3 sys_siglist.3
+MLINKS+=pwcache.3 user_from_uid.3 pwcache.3 group_from_gid.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 sigsetjmp.3 setjmp.3 siglongjmp.3
+MLINKS+=setmode.3 getmode.3
+MLINKS+=sigsetops.3 sigemptyset.3 sigsetops.3 sigfillset.3 \
+ sigsetops.3 sigaddset.3 sigsetops.3 sigdelset.3 \
+ sigsetops.3 sigismember.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 tcflush.3 tcsendbreak.3 tcflow.3
+MLINKS+=tcsetattr.3 tcgetattr.3 tcsetattr.3 cfsetospeed.3 \
+ tcsetattr.3 cfgetospeed.3 tcsetattr.3 cfgetispeed.3 \
+ tcsetattr.3 cfsetispeed.3 tcsetattr.3 cfsetspeed.3 \
+ tcsetattr.3 cfmakeraw.3
+MLINKS+=ttyname.3 isatty.3 ttyname.3 ttyslot.3
+MLINKS+=tzset.3 tzsetwall.3
+MLINKS+=vis.3 strvis.3 vis.3 strvisx.3
diff --git a/lib/libc/gen/__xuname.c b/lib/libc/gen/__xuname.c
new file mode 100644
index 0000000..93f659e
--- /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[] =
+ "$Id: uname.c,v 1.3 1995/05/30 05:40:29 rgrimes Exp $";
+#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/alarm.3 b/lib/libc/gen/alarm.3
new file mode 100644
index 0000000..fb1893f
--- /dev/null
+++ b/lib/libc/gen/alarm.3
@@ -0,0 +1,86 @@
+.\" 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
+.\"
+.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 u_int
+.Fn alarm "u_int seconds"
+.Sh DESCRIPTION
+.Bf -symbolic
+This interface is made obsolete by setitimer(2).
+.Ef
+.Pp
+The
+.Fn alarm
+function
+waits a count of
+.Ar seconds
+before asserting the terminating signal
+.Dv SIGALRM .
+When the signal has successfully been caught,
+.Fn alarm
+returns the amount of time left on the clock.
+The maximum number of
+.Ar seconds
+allowed
+is 2147483647.
+.Pp
+If an alarm has been set with
+.Fn alarm ,
+another call to
+.Fn alarm
+will supersede the prior call.
+The request
+.Fn alarm "0"
+voids the current
+alarm.
+.Sh SEE ALSO
+.Xr sigaction 2 ,
+.Xr setitimer 2 ,
+.Xr sigpause 2 ,
+.Xr sigvec 2 ,
+.Xr signal 3 ,
+.Xr sleep 3 ,
+.Xr ualarm 3 ,
+.Xr usleep 3
+.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/assert.c b/lib/libc/gen/assert.c
new file mode 100644
index 0000000..4914aca
--- /dev/null
+++ b/lib/libc/gen/assert.c
@@ -0,0 +1,53 @@
+/*-
+ * 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 <sys/types.h>
+#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..739a7ea
--- /dev/null
+++ b/lib/libc/gen/clock.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.
+.\"
+.\" @(#)clock.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt CLOCK 3
+.Os
+.Sh NAME
+.Nm clock
+.Nd determine processor time used
+.Sh SYNOPSIS
+.Fd #include <sys/types.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
+.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..3a4fc9d
--- /dev/null
+++ b/lib/libc/gen/closedir.c
@@ -0,0 +1,60 @@
+/*
+ * 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>
+
+/*
+ * 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/config.c b/lib/libc/gen/config.c
new file mode 100644
index 0000000..ffe2766
--- /dev/null
+++ b/lib/libc/gen/config.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
+ * ----------------------------------------------------------------------------
+ *
+ * $Id: config.c,v 1.1 1994/11/13 20:47:43 phk Exp $
+ *
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: config.c,v 1.1 1994/11/13 20:47:43 phk Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * This file contains four procedures used to read config-files.
+ *
+ * char * config_open(const char *filename,int contlines)
+ * Will open the named file, read it into a private malloc'ed area,
+ * and close the file again.
+ * All lines where the first !isspace() char is '#' are deleted.
+ * If contlines are non-zero lines where the first char is isspace()
+ * will be joined to the preceeding line.
+ * In case of trouble the name of the offending system call will be
+ * returned. On success NULL is returned.
+ *
+ * void config_close()
+ * This will free the internal malloc'ed area.
+ *
+ * char * config_next()
+ * This will return a pointer to the next entry in the area. NULL is
+ * returned at "end of file". The return value is '\0' terminated, and
+ * can be modified, but the contents must be copied somewhere else for
+ * permanent use.
+ *
+ * char * config_skip(char **p)
+ * This will pick out the next word from the string. The return-value
+ * points to the word found, and *p is advanced past the word. NULL is
+ * returned at "end of string".
+ *
+ * Many programs have a n*100 bytes config-file and N*1000 bytes of source
+ * to read it. Doing pointer-aerobics on files that small is a waste of
+ * time, and bashing around with getchar/ungetc isn't much better. These
+ * routines implement a simple algorithm and syntax.
+ *
+ * config_skip consider a contiguous string of !isspace() chars a word.
+ *
+ * 13nov1994 Poul-Henning Kamp phk@login.dknet.dk
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+
+static char *file_buf;
+static char *ptr;
+
+char *
+config_open(const char *filename, int contlines)
+{
+ int fd;
+ struct stat st;
+ char *p, *q;
+
+ if ((fd = open(filename, O_RDONLY)) < 0)
+ return "open";
+ if (fstat(fd, &st) < 0) {
+ close(fd);
+ return "fstat";
+ }
+ if (file_buf)
+ free(file_buf);
+ file_buf = malloc(st.st_size + 2);
+ if (!file_buf) {
+ close(fd);
+ return "malloc";
+ }
+ if (st.st_size != read(fd, file_buf, st.st_size)) {
+ free(file_buf);
+ file_buf = (char *) 0;
+ close(fd);
+ return "read";
+ }
+ close(fd);
+ file_buf[st.st_size] = '\n';
+ file_buf[st.st_size + 1] = '\0';
+
+ /*
+ * /^[ \t]*#[^\n]*$/d
+ *
+ * Delete all lines where the first !isspace() char is '#'
+ */
+
+ ptr = file_buf;
+ for (p = ptr; *p;) {
+ for (q = p; *q != '\n' && isspace(*q); q++)
+ continue;
+ if (*q == '#') {
+ p = strchr(p, '\n');
+ if (p)
+ p++;
+ } else {
+ q = strchr(p, '\n');
+ q++;
+ memcpy(ptr, p, q - p);
+ ptr += q - p;
+ p = q;
+ }
+ }
+ *ptr = '\0';
+ ptr = file_buf;
+
+ if (!contlines)
+ return 0;
+
+ /* Join all lines starting with a isspace() char to the preceeding
+ * line */
+
+ for (p = ptr; *p;) {
+ q = strchr(p, '\n');
+ if (isspace(*(q + 1)))
+ *q = ' ';
+ p = q + 1;
+ }
+
+ return 0;
+}
+
+void
+config_close(void)
+{
+ if (file_buf)
+ free(file_buf);
+ ptr = file_buf = 0;
+}
+
+/*
+ * Get next entry. config_open did all the weird stuff, so just return
+ * the next line.
+ */
+
+char *
+config_next(void)
+{
+ char *p;
+
+ /* We might be done already ! */
+ if (!ptr || !*ptr)
+ return 0;
+
+ while (isspace(*ptr))
+ ptr++;
+ p = ptr;
+ ptr = strchr(p, '\n');
+ if (ptr) {
+ *ptr = '\0';
+ ptr++;
+ }
+ return p;
+}
+
+/*
+ * Return next word
+ */
+
+char *
+config_skip(char **p)
+{
+ char *q, *r;
+
+ if (!*p || !**p)
+ return 0;
+ for (q = *p; isspace(*q); q++);
+ if (!*q)
+ return 0;
+ for (r = q; *r && !isspace(*r); r++);
+ if (*r)
+ *r++ = '\0';
+ *p = r;
+ return q;
+}
diff --git a/lib/libc/gen/config_open.3 b/lib/libc/gen/config_open.3
new file mode 100644
index 0000000..f51bc6c
--- /dev/null
+++ b/lib/libc/gen/config_open.3
@@ -0,0 +1,73 @@
+.\" ----------------------------------------------------------------------------
+.\" "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
+.\" ----------------------------------------------------------------------------
+.\"
+.\" $Id$
+.\"
+.Dd November 13, 1994
+.Dt config_open 3
+.Os FreeBSD
+.Sh NAME
+.Nm config_open ,
+.Nm config_close ,
+.Nm config_next ,
+.Nm config_skip
+.Nd read config files
+.Sh SYNOPSIS
+.Ft char *
+.Fn config_open "const char *filename" "int contlines"
+.Ft void
+.Fn config_close
+.Ft char *
+.Fn config_next
+.Ft char *
+.Fn config_skip "char **string"
+.Sh DESCRIPTION
+These functions are used to read config files with the following syntax:
+.Bl -bullet -compact
+.It
+All lines where the first
+.Sq !isspace()
+is '#' are comments which are discarded.
+.It
+If continuation-lines are enabled, any line starting with a
+.Sq isspace()
+character is joined to the preceeding line and blank lines are discarded.
+.It
+An entry starts at the first
+.Sq !isspace()
+character and ends at the first
+.Sq Li \en
+.Li .
+.El
+.Pp
+.Fn config_open
+will open the specified
+.Fa filename
+and read it into a private malloced area, and close the file again. If
+.Fa contlines
+is non-zero, continuation lines will be allowed.
+In case of trouble, the name of the system-call causing the trouble will
+be returned. If successful,
+.Fn config_open
+returns NULL.
+.Pp
+.Fn config_close
+will free the malloced area.
+.Pp
+.Fn config_next
+returns the next entry in the area. NULL is returned to indicate End-of-file.
+The returned string is null-terminated.
+.Pp
+.Fn config_skip
+returns the next word from the string
+.Fa *string
+.Li .
+.Fa *string
+will be advanced to point to the next word.
+NULL is returned to indicate the end of the string.
+.Sh AUTHOR
+Poul-Henning Kamp <phk@login.dknet.dk>
diff --git a/lib/libc/gen/confstr.3 b/lib/libc/gen/confstr.3
new file mode 100644
index 0000000..8714452
--- /dev/null
+++ b/lib/libc/gen/confstr.3
@@ -0,0 +1,123 @@
+.\" 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
+.\"
+.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 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
+.Nm 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
+.Nm 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
+.Nm confstr
+function first appeared in 4.4BSD.
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..d95f704
--- /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
+.\"
+.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
+.Ft char
+.Fn *crypt "const char *key" "const char *setting"
+.Ft int
+.Fn setkey "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
+.Xr 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
+.sp
+.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..c1417b8
--- /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[] = "$Header: /home/ncvs/src/lib/libc/gen/crypt.c,v 1.3 1995/05/30 05:40:10 rgrimes Exp $";
+#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..ff92420
--- /dev/null
+++ b/lib/libc/gen/ctermid.3
@@ -0,0 +1,93 @@
+.\" 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
+.\"
+.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"
+.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
+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
+.Xr 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..262d6df
--- /dev/null
+++ b/lib/libc/gen/ctermid.c
@@ -0,0 +1,53 @@
+/*-
+ * 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[] = "@(#)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(s)
+ char *s;
+{
+ static char def[] = _PATH_TTY;
+
+ if (s) {
+ bcopy(def, s, sizeof(_PATH_TTY));
+ return(s);
+ }
+ return(def);
+}
diff --git a/lib/libc/gen/daemon.3 b/lib/libc/gen/daemon.3
new file mode 100644
index 0000000..1905923
--- /dev/null
+++ b/lib/libc/gen/daemon.3
@@ -0,0 +1,74 @@
+.\" 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
+.Dd June 9, 1993
+.Dt DAEMON 3
+.Os
+.Sh NAME
+.Nm daemon
+.Nd run in the background
+.Sh SYNOPSIS
+.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
+The function
+.Fn daemon
+may fail and set
+.Va errno
+for any of the errors specified for the library functions
+.Xr fork 2
+and
+.Xr setsid 2 .
+.Sh SEE ALSO
+.Xr setsid 2
+.Sh HISTORY
+The
+.Fn daemon
+function first appeared in 4.4BSD.
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..7583bb4
--- /dev/null
+++ b/lib/libc/gen/devname.3
@@ -0,0 +1,66 @@
+.\" 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.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.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, the string
+.Dq ??
+is returned.
+.Sh SEE ALSO
+.Xr stat 2 ,
+.Xr dev_mkdb 8
+.Sh HISTORY
+The
+.Nm 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..3929f92
--- /dev/null
+++ b/lib/libc/gen/devname.c
@@ -0,0 +1,80 @@
+/*
+ * 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.1 (Berkeley) 6/4/93";
+#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>
+
+char *
+devname(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 ("??");
+
+ /*
+ * 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) ? "??" : (char *)data.data);
+}
diff --git a/lib/libc/gen/directory.3 b/lib/libc/gen/directory.3
new file mode 100644
index 0000000..0503989
--- /dev/null
+++ b/lib/libc/gen/directory.3
@@ -0,0 +1,183 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt DIRECTORY 3
+.Os BSD 4.2
+.Sh NAME
+.Nm opendir ,
+.Nm readdir ,
+.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 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
+The
+.Fn telldir
+function
+returns the current location associated with the named
+.Em directory stream .
+.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. 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, the
+.Fn telldir
+value may be invalidated due to undetected directory compaction.
+It is safe to use a previous
+.Fn telldir
+value immediately after a call to
+.Fn opendir
+and before any calls to
+.Fn readdir .
+.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 searchs 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 open 2 ,
+.Xr close 2 ,
+.Xr read 2 ,
+.Xr lseek 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..883607b
--- /dev/null
+++ b/lib/libc/gen/disklabel.c
@@ -0,0 +1,169 @@
+/*
+ * 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
+static char sccsid[] = "@(#)disklabel.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+#include <sys/param.h>
+#define DKTYPENAMES
+#include <sys/disklabel.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_long *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);
+ cgetnum(buf, "nt",(long *) &dp->d_ntracks);
+ cgetnum(buf, "ns",(long *) &dp->d_nsectors);
+ cgetnum(buf, "nc",(long *) &dp->d_ncylinders);
+
+ 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++) {
+ psize[1] = pbsize[1] = pfsize[1] = poffset[1] = ptype[1] = p;
+ if (cgetnum(buf, psize,(long *) &pp->p_size) == -1)
+ pp->p_size = 0;
+ else {
+ cgetnum(buf, poffset, (long *) &pp->p_offset);
+ 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(*t))
+ return (atoi(t));
+ return (0);
+}
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..a80edeb
--- /dev/null
+++ b/lib/libc/gen/err.3
@@ -0,0 +1,144 @@
+.\" 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
+.\" $Id$
+.\"
+.Dd April 13, 1995
+.Dt ERR 3
+.Os BSD 4
+.Sh NAME
+.Nm err ,
+.Nm verr ,
+.Nm errx ,
+.Nm verrx ,
+.Nm warn ,
+.Nm vwarn ,
+.Nm warnx ,
+.Nm vwarnx ,
+.Nm err_set_file ,
+.Nm err_set_exit
+.Nd formatted error messages
+.Sh SYNOPSIS
+.Fd #include <err.h>
+.Ft void
+.Fn err "int eval" "const char *fmt" "..."
+.Ft void
+.Fn verr "int eval" "const char *fmt" "va_list args"
+.Ft void
+.Fn errx "int eval" "const char *fmt" "..."
+.Ft void
+.Fn verrx "int eval" "const char *fmt" "va_list args"
+.Ft void
+.Fn warn "const char *fmt" "..."
+.Ft void
+.Fn vwarn "const char *fmt" "va_list args"
+.Ft void
+.Fn warnx "const char *fmt" "..."
+.Ft void
+.Fn vwarnx "const char *fmt" "va_list args"
+.Ft void
+.Fn err_set_file "void *fp"
+.Ft void
+.Fn err_set_exit "void (*exitf)(int)"
+.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, a colon character,
+and a space are output.
+In the case of the
+.Fn err ,
+.Fn verr ,
+.Fn warn ,
+and
+.Fn vwarn
+functions, the error message string affiliated with the current value of
+the global variable
+.Va errno
+is output.
+In all cases, the output is followed by a newline character.
+.Pp
+The
+.Fn err ,
+.Fn verr ,
+.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 2
+to perform any necessary cleanup; passing a null function pointer for
+.Va exitf
+resets the hook to do nothing.
+.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
+.Sh SEE ALSO
+.Xr strerror 3
+.Sh HISTORY
+The
+.Fn err
+and
+.Fn warn
+functions first appeared in 4.4BSD.
diff --git a/lib/libc/gen/err.c b/lib/libc/gen/err.c
new file mode 100644
index 0000000..63ef8a4
--- /dev/null
+++ b/lib/libc/gen/err.c
@@ -0,0 +1,216 @@
+/*-
+ * 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[] = "@(#)err.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+extern char *__progname; /* Program name, from crt0. */
+
+static FILE *err_file; /* file to use for error output */
+static void (*err_exit)(int);
+
+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;
+}
+
+__dead void
+#ifdef __STDC__
+err(int eval, const char *fmt, ...)
+#else
+err(eval, fmt, va_alist)
+ int eval;
+ const char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ verr(eval, fmt, ap);
+ va_end(ap);
+}
+
+__dead void
+verr(eval, fmt, ap)
+ int eval;
+ const char *fmt;
+ va_list ap;
+{
+ int sverrno;
+
+ sverrno = errno;
+ if (! err_file)
+ err_set_file((FILE *)0);
+ (void)fprintf(err_file, "%s: ", __progname);
+ if (fmt != NULL) {
+ (void)vfprintf(err_file, fmt, ap);
+ (void)fprintf(err_file, ": ");
+ }
+ (void)fprintf(err_file, "%s\n", strerror(sverrno));
+ if(err_exit)
+ err_exit(eval);
+ exit(eval);
+}
+
+__dead void
+#if __STDC__
+errx(int eval, const char *fmt, ...)
+#else
+errx(eval, fmt, va_alist)
+ int eval;
+ const char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ verrx(eval, fmt, ap);
+ va_end(ap);
+}
+
+__dead void
+verrx(eval, fmt, ap)
+ int eval;
+ const char *fmt;
+ va_list ap;
+{
+ if (! err_file)
+ err_set_file((FILE *)0);
+ (void)fprintf(err_file, "%s: ", __progname);
+ if (fmt != NULL)
+ (void)vfprintf(err_file, fmt, ap);
+ (void)fprintf(err_file, "\n");
+ if (err_exit)
+ err_exit(eval);
+ exit(eval);
+}
+
+void
+#if __STDC__
+warn(const char *fmt, ...)
+#else
+warn(fmt, va_alist)
+ const char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ vwarn(fmt, ap);
+ va_end(ap);
+}
+
+void
+vwarn(fmt, ap)
+ const char *fmt;
+ va_list ap;
+{
+ int sverrno;
+
+ sverrno = errno;
+ if (! err_file)
+ err_set_file((FILE *)0);
+ (void)fprintf(err_file, "%s: ", __progname);
+ if (fmt != NULL) {
+ (void)vfprintf(err_file, fmt, ap);
+ (void)fprintf(err_file, ": ");
+ }
+ (void)fprintf(err_file, "%s\n", strerror(sverrno));
+}
+
+void
+#ifdef __STDC__
+warnx(const char *fmt, ...)
+#else
+warnx(fmt, va_alist)
+ const char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#ifdef __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ vwarnx(fmt, ap);
+ va_end(ap);
+}
+
+void
+vwarnx(fmt, ap)
+ const char *fmt;
+ va_list ap;
+{
+ if (! err_file)
+ err_set_file((FILE *)0);
+ (void)fprintf(err_file, "%s: ", __progname);
+ if (fmt != NULL)
+ (void)vfprintf(err_file, fmt, ap);
+ (void)fprintf(err_file, "\n");
+}
diff --git a/lib/libc/gen/errlst.c b/lib/libc/gen/errlst.c
new file mode 100644
index 0000000..cd7e719
--- /dev/null
+++ b/lib/libc/gen/errlst.c
@@ -0,0 +1,141 @@
+/*
+ * 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 */
+};
+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..3438bec
--- /dev/null
+++ b/lib/libc/gen/exec.3
@@ -0,0 +1,258 @@
+.\" 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
+.\"
+.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" ... "char *const envp[]"
+.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
+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 permission is denied for a file (the attempted
+.Xr execve
+returned
+.Er EACCES ) ,
+these functions will continue searching the rest of
+the search path.
+If no other file is found, however, they will return with the global variable
+.Va errno
+set to
+.Er EACCES .
+.Pp
+If the header of a file isn't recognized (the attempted
+.Xr 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
+If the file is currently busy (the attempted
+.Xr execve
+returned
+.Er ETXTBUSY ) ,
+these functions will sleep for several seconds,
+periodically re-attempting to execute the file.
+.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
+.Xr 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 trace 2 ,
+.Xr environ 7 ,
+.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 historic
+practice, but 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 ENOMEM
+and
+.Er E2BIG ,
+upon which they returned.
+They now return if any error other than the ones described above occurs.
+.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..6af8868
--- /dev/null
+++ b/lib/libc/gen/exec.c
@@ -0,0 +1,269 @@
+/*-
+ * 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[] = "@(#)exec.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.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;
+
+static char **
+buildargv(ap, arg, envpp)
+ va_list ap;
+ const char *arg;
+ char ***envpp;
+{
+ register char **argv, **nargv;
+ register int memsize, off;
+
+ argv = NULL;
+ for (off = memsize = 0;; ++off) {
+ if (off >= memsize) {
+ memsize += 50; /* Starts out at 0. */
+ memsize *= 2; /* Ramp up fast. */
+ nargv = realloc(argv, memsize * sizeof(char *));
+ if (nargv == NULL) {
+ free(argv);
+ return (NULL);
+ }
+ argv = nargv;
+ if (off == 0) {
+ argv[0] = (char *)arg;
+ off = 1;
+ }
+ }
+ if (!(argv[off] = va_arg(ap, char *)))
+ break;
+ }
+ /* Get environment pointer if user supposed to provide one. */
+ if (envpp)
+ *envpp = va_arg(ap, char **);
+ return (argv);
+}
+
+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;
+ int sverrno;
+ char **argv;
+
+#if __STDC__
+ va_start(ap, arg);
+#else
+ va_start(ap);
+#endif
+ if (argv = buildargv(ap, arg, NULL))
+ (void)execve(name, argv, environ);
+ va_end(ap);
+ sverrno = errno;
+ free(argv);
+ errno = sverrno;
+ return (-1);
+}
+
+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;
+ int sverrno;
+ char **argv, **envp;
+
+#if __STDC__
+ va_start(ap, arg);
+#else
+ va_start(ap);
+#endif
+ if (argv = buildargv(ap, arg, &envp))
+ (void)execve(name, argv, envp);
+ va_end(ap);
+ sverrno = errno;
+ free(argv);
+ errno = sverrno;
+ return (-1);
+}
+
+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;
+
+#if __STDC__
+ va_start(ap, arg);
+#else
+ va_start(ap);
+#endif
+ if (argv = buildargv(ap, arg, NULL))
+ (void)execvp(name, argv);
+ va_end(ap);
+ sverrno = errno;
+ free(argv);
+ errno = sverrno;
+ return (-1);
+}
+
+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, etxtbsy;
+ char *bp, *cur, *path, buf[MAXPATHLEN];
+
+ /* 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;
+
+ /* Get the path we're searching. */
+ if (!(path = getenv("PATH")))
+ path = _PATH_DEFPATH;
+ cur = path = strdup(path);
+
+ eacces = etxtbsy = 0;
+ 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 EACCES:
+ eacces = 1;
+ break;
+ case ENOENT:
+ break;
+ case ENOEXEC:
+ for (cnt = 0; argv[cnt]; ++cnt)
+ ;
+ memp = malloc((cnt + 2) * sizeof(char *));
+ if (memp == NULL)
+ goto done;
+ memp[0] = "sh";
+ memp[1] = bp;
+ bcopy(argv + 1, memp + 2, cnt * sizeof(char *));
+ (void)execve(_PATH_BSHELL, memp, environ);
+ free(memp);
+ goto done;
+ case ETXTBSY:
+ if (etxtbsy < 3)
+ (void)sleep(++etxtbsy);
+ goto retry;
+ default:
+ goto done;
+ }
+ }
+ if (eacces)
+ errno = EACCES;
+ else if (!errno)
+ errno = ENOENT;
+done: if (path)
+ free(path);
+ return (-1);
+}
diff --git a/lib/libc/gen/fnmatch.3 b/lib/libc/gen/fnmatch.3
new file mode 100644
index 0000000..5d5dfd5
--- /dev/null
+++ b/lib/libc/gen/fnmatch.3
@@ -0,0 +1,127 @@
+.\" 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.2 (Berkeley) 4/16/94
+.\"
+.Dd April 16, 1994
+.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 strings match periods in patterns.
+The definition of ``leading'' is related to the specification of
+.Dv FNM_PATHNAME.
+A period is always ``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.
+.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 ,
+.Xr wordexp 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..0c2ca13
--- /dev/null
+++ b/lib/libc/gen/fnmatch.c
@@ -0,0 +1,171 @@
+/*
+ * 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 <fnmatch.h>
+#include <string.h>
+
+#define EOS '\0'
+
+static const char *rangematch __P((const char *, int, int));
+
+int
+fnmatch(pattern, string, flags)
+ const char *pattern, *string;
+ int flags;
+{
+ const char *stringstart;
+ char c, test;
+
+ for (stringstart = string;;)
+ switch (c = *pattern++) {
+ case EOS:
+ 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 (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 ((pattern =
+ rangematch(pattern, *string, flags)) == NULL)
+ return (FNM_NOMATCH);
+ ++string;
+ break;
+ case '\\':
+ if (!(flags & FNM_NOESCAPE)) {
+ if ((c = *pattern++) == EOS) {
+ c = '\\';
+ --pattern;
+ }
+ }
+ /* FALLTHROUGH */
+ default:
+ if (c != *string++)
+ return (FNM_NOMATCH);
+ break;
+ }
+ /* NOTREACHED */
+}
+
+static const char *
+rangematch(pattern, test, flags)
+ const char *pattern;
+ int test, flags;
+{
+ 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;
+
+ for (ok = 0; (c = *pattern++) != ']';) {
+ if (c == '\\' && !(flags & FNM_NOESCAPE))
+ c = *pattern++;
+ if (c == EOS)
+ return (NULL);
+ if (*pattern == '-'
+ && (c2 = *(pattern+1)) != EOS && c2 != ']') {
+ pattern += 2;
+ if (c2 == '\\' && !(flags & FNM_NOESCAPE))
+ c2 = *pattern++;
+ if (c2 == EOS)
+ return (NULL);
+ if (c <= test && test <= c2)
+ ok = 1;
+ } else if (c == test)
+ ok = 1;
+ }
+ return (ok == negate ? NULL : pattern);
+}
diff --git a/lib/libc/gen/frexp.3 b/lib/libc/gen/frexp.3
new file mode 100644
index 0000000..574efa3
--- /dev/null
+++ b/lib/libc/gen/frexp.3
@@ -0,0 +1,85 @@
+.\" 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
+.\"
+.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 modf 3 ,
+.Xr math 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..a526068
--- /dev/null
+++ b/lib/libc/gen/fstab.c
@@ -0,0 +1,227 @@
+/*
+ * 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 <errno.h>
+#include <fstab.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 int fstabscan __P((void));
+
+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");
+ _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;
+ 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..9b25bf2
--- /dev/null
+++ b/lib/libc/gen/ftok.3
@@ -0,0 +1,88 @@
+.\" 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.
+.\"
+.\" $Id: ftok.3,v 1.1 1994/06/26 16:24:57 jtc Exp $
+.Dd June 24, 1994
+.Os
+.Dt ftok 3
+.Sh NAME
+.Nm ftok
+.Nd create IPC indentifier from path name
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/ipc.h>
+.Ft key_t
+.Fn ftok "const char *path" "char 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 2 ,
+.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 msgget 2 ,
+.Xr semget 2 ,
+.Xr shmget 2
+.Sh HISTORY
+The
+.Fn ftok
+function originate with System V and is typically used by programs
+that use the System V IPC routines.
+.Sh AUTHOR
+.Bl -tag
+Thorsten Lockert <tholo@sigmasoft.com>
+.El
+.Sh BUGS
+The returned key is computed based on the device and inode of the
+specified
+.Fa path
+in combination with the given
+.Fa id .
+Thus is is quite possible for the routine to return duplicate keys
+given that those fields are not 8- and 16-bit quantities like they
+were on System V based systems where this library routine's ancestor
+were originally created.
diff --git a/lib/libc/gen/ftok.c b/lib/libc/gen/ftok.c
new file mode 100644
index 0000000..8861509
--- /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 = "$Id: ftok.c,v 1.2 1994/06/26 16:27:34 jtc Exp $";
+#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..3915b00
--- /dev/null
+++ b/lib/libc/gen/fts-compat.c
@@ -0,0 +1,971 @@
+/*-
+ * 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[] = "@(#)fts.c 8.4 (Berkeley) 4/16/94";
+#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 *, void *));
+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));
+
+#define ISDOT(a) (a[0] == '.' && (!a[1] || a[1] == '.' && !a[2]))
+
+#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)();
+{
+ 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;
+
+ /* 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 insure
+ * 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);
+ }
+
+ /* Free up the stream pointer. */
+ free(sp);
+
+ /* Set errno and return. */
+ if (!ISSET(FTS_NOCHDIR) && saved_errno) {
+ errno = saved_errno;
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * Special case a root of "/" so that slashes aren't appended which would
+ * cause paths to be written as "//foo".
+ */
+#define NAPPEND(p) \
+ (p->fts_level == FTS_ROOTLEVEL && p->fts_pathlen == 1 && \
+ p->fts_path[0] == '/' ? 0 : 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 && sp->fts_options & FTS_NAMEONLY) {
+ sp->fts_options &= ~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 (CHDIR(sp, p->fts_accpath)) {
+ 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, and
+ * load the paths for the next root.
+ */
+ if (p->fts_level == FTS_ROOTLEVEL) {
+ if (!ISSET(FTS_NOCHDIR) && 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 (!ISSET(FTS_NOCHDIR) && 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) {
+ sp->fts_options |= 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 *adjaddr;
+ int cderrno, descend, len, level, maxlen, nlinks, saved_errno;
+ 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.
+ */
+ if ((dirp = opendir(cur->fts_accpath)) == 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;
+ else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL))
+ nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
+ else
+ nlinks = -1;
+
+#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 (FCHDIR(sp, dirfd(dirp))) {
+ if (nlinks && type == BREAD)
+ cur->fts_errno = errno;
+ cur->fts_flags |= FTS_DONTCHDIR;
+ descend = 0;
+ cderrno = errno;
+ } 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.
+ */
+ maxlen = sp->fts_pathlen - cur->fts_pathlen - 1;
+ len = NAPPEND(cur);
+ if (ISSET(FTS_NOCHDIR)) {
+ cp = sp->fts_path + len;
+ *cp++ = '/';
+ }
+
+ level = cur->fts_level + 1;
+
+ /* Read the directory, attaching each entry to the `link' pointer. */
+ adjaddr = NULL;
+ for (head = tail = NULL, nitems = 0; 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) {
+ if (fts_palloc(sp, (size_t)dp->d_namlen)) {
+ /*
+ * 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);
+ errno = saved_errno;
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ adjaddr = sp->fts_path;
+ maxlen = sp->fts_pathlen - sp->fts_cur->fts_pathlen - 1;
+ }
+
+ p->fts_pathlen = len + dp->d_namlen + 1;
+ p->fts_parent = sp->fts_cur;
+ p->fts_level = level;
+
+ 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
+ || nlinks > 0 &&
+ 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;
+ }
+ (void)closedir(dirp);
+
+ /*
+ * If had to realloc the path, adjust the addresses for the rest
+ * of the tree.
+ */
+ if (adjaddr)
+ fts_padjust(sp, adjaddr);
+
+ /*
+ * If not changing directories, reset the path back to original
+ * state.
+ */
+ if (ISSET(FTS_NOCHDIR)) {
+ if (cp - 1 > sp->fts_path)
+ --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;
+
+ /*
+ * 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) {
+ sp->fts_nitems = nitems + 40;
+ if ((sp->fts_array = realloc(sp->fts_array,
+ (size_t)(sp->fts_nitems * sizeof(FTSENT *)))) == NULL) {
+ sp->fts_nitems = 0;
+ return (head);
+ }
+ }
+ 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 plus the trailing NULL. */
+ memmove(p->fts_name, name, namelen + 1);
+
+ 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;
+{
+ sp->fts_pathlen += more + 256;
+ sp->fts_path = realloc(sp->fts_path, (size_t)sp->fts_pathlen);
+ return (sp->fts_path == NULL);
+}
+
+/*
+ * When the path is realloc'd, have to fix all of the pointers in structures
+ * already returned.
+ */
+static void
+fts_padjust(sp, addr)
+ FTS *sp;
+ void *addr;
+{
+ FTSENT *p;
+
+#define ADJUST(p) { \
+ (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. */
+ for (p = sp->fts_cur; 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);
+}
diff --git a/lib/libc/gen/fts-compat.h b/lib/libc/gen/fts-compat.h
new file mode 100644
index 0000000..84dbe14
--- /dev/null
+++ b/lib/libc/gen/fts-compat.h
@@ -0,0 +1,125 @@
+/*
+ * 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.1 (Berkeley) 6/2/93
+ */
+
+#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_OPTIONMASK 0x07f /* valid user option mask */
+
+#define FTS_NAMEONLY 0x080 /* (private) child names only */
+#define FTS_STOP 0x100 /* (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 */
+ 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 */
+ 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..dde076d
--- /dev/null
+++ b/lib/libc/gen/fts.3
@@ -0,0 +1,748 @@
+.\" 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
+.\"
+.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 ``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 ``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, ``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 */
+ short fts_pathlen; /* strlen(fts_path) */
+ char *fts_name; /* file name */
+ 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 flags 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 NULL 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 NULL 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..3915b00
--- /dev/null
+++ b/lib/libc/gen/fts.c
@@ -0,0 +1,971 @@
+/*-
+ * 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[] = "@(#)fts.c 8.4 (Berkeley) 4/16/94";
+#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 *, void *));
+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));
+
+#define ISDOT(a) (a[0] == '.' && (!a[1] || a[1] == '.' && !a[2]))
+
+#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)();
+{
+ 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;
+
+ /* 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 insure
+ * 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);
+ }
+
+ /* Free up the stream pointer. */
+ free(sp);
+
+ /* Set errno and return. */
+ if (!ISSET(FTS_NOCHDIR) && saved_errno) {
+ errno = saved_errno;
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * Special case a root of "/" so that slashes aren't appended which would
+ * cause paths to be written as "//foo".
+ */
+#define NAPPEND(p) \
+ (p->fts_level == FTS_ROOTLEVEL && p->fts_pathlen == 1 && \
+ p->fts_path[0] == '/' ? 0 : 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 && sp->fts_options & FTS_NAMEONLY) {
+ sp->fts_options &= ~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 (CHDIR(sp, p->fts_accpath)) {
+ 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, and
+ * load the paths for the next root.
+ */
+ if (p->fts_level == FTS_ROOTLEVEL) {
+ if (!ISSET(FTS_NOCHDIR) && 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 (!ISSET(FTS_NOCHDIR) && 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) {
+ sp->fts_options |= 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 *adjaddr;
+ int cderrno, descend, len, level, maxlen, nlinks, saved_errno;
+ 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.
+ */
+ if ((dirp = opendir(cur->fts_accpath)) == 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;
+ else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL))
+ nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
+ else
+ nlinks = -1;
+
+#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 (FCHDIR(sp, dirfd(dirp))) {
+ if (nlinks && type == BREAD)
+ cur->fts_errno = errno;
+ cur->fts_flags |= FTS_DONTCHDIR;
+ descend = 0;
+ cderrno = errno;
+ } 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.
+ */
+ maxlen = sp->fts_pathlen - cur->fts_pathlen - 1;
+ len = NAPPEND(cur);
+ if (ISSET(FTS_NOCHDIR)) {
+ cp = sp->fts_path + len;
+ *cp++ = '/';
+ }
+
+ level = cur->fts_level + 1;
+
+ /* Read the directory, attaching each entry to the `link' pointer. */
+ adjaddr = NULL;
+ for (head = tail = NULL, nitems = 0; 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) {
+ if (fts_palloc(sp, (size_t)dp->d_namlen)) {
+ /*
+ * 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);
+ errno = saved_errno;
+ cur->fts_info = FTS_ERR;
+ SET(FTS_STOP);
+ return (NULL);
+ }
+ adjaddr = sp->fts_path;
+ maxlen = sp->fts_pathlen - sp->fts_cur->fts_pathlen - 1;
+ }
+
+ p->fts_pathlen = len + dp->d_namlen + 1;
+ p->fts_parent = sp->fts_cur;
+ p->fts_level = level;
+
+ 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
+ || nlinks > 0 &&
+ 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;
+ }
+ (void)closedir(dirp);
+
+ /*
+ * If had to realloc the path, adjust the addresses for the rest
+ * of the tree.
+ */
+ if (adjaddr)
+ fts_padjust(sp, adjaddr);
+
+ /*
+ * If not changing directories, reset the path back to original
+ * state.
+ */
+ if (ISSET(FTS_NOCHDIR)) {
+ if (cp - 1 > sp->fts_path)
+ --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;
+
+ /*
+ * 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) {
+ sp->fts_nitems = nitems + 40;
+ if ((sp->fts_array = realloc(sp->fts_array,
+ (size_t)(sp->fts_nitems * sizeof(FTSENT *)))) == NULL) {
+ sp->fts_nitems = 0;
+ return (head);
+ }
+ }
+ 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 plus the trailing NULL. */
+ memmove(p->fts_name, name, namelen + 1);
+
+ 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;
+{
+ sp->fts_pathlen += more + 256;
+ sp->fts_path = realloc(sp->fts_path, (size_t)sp->fts_pathlen);
+ return (sp->fts_path == NULL);
+}
+
+/*
+ * When the path is realloc'd, have to fix all of the pointers in structures
+ * already returned.
+ */
+static void
+fts_padjust(sp, addr)
+ FTS *sp;
+ void *addr;
+{
+ FTSENT *p;
+
+#define ADJUST(p) { \
+ (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. */
+ for (p = sp->fts_cur; 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);
+}
diff --git a/lib/libc/gen/getbootfile.3 b/lib/libc/gen/getbootfile.3
new file mode 100644
index 0000000..cfab748
--- /dev/null
+++ b/lib/libc/gen/getbootfile.3
@@ -0,0 +1,71 @@
+.\" 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
+.\" $Id$
+.\"
+.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
+.Nm 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 2
+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 2
+.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
+.Nm
+function call appeared in
+.Tn FreeBSD
+2.0.
diff --git a/lib/libc/gen/getbootfile.c b/lib/libc/gen/getbootfile.c
new file mode 100644
index 0000000..3d03851
--- /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[] =
+ "$Id: getbootfile.c,v 1.1 1994/09/23 20:22:01 wollman Exp $";
+#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..0455573
--- /dev/null
+++ b/lib/libc/gen/getbsize.3
@@ -0,0 +1,79 @@
+.\" 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
+.\"
+.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
+.Nm 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
+.Nm 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
+.Nm getbsize
+function call 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..fc7b123
--- /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 %dG", 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), "%d%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..c423a98
--- /dev/null
+++ b/lib/libc/gen/getcap.3
@@ -0,0 +1,511 @@
+.\" 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.3 (Berkeley) 4/19/94
+.\"
+.Dd "April 19, 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" "char 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 rec
+.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 .
+.Nm Cgetent
+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 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
+.Nm Cgetset
+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
+.Nm cgetent .
+The entry is passed in
+.Fa ent .
+If
+.Fa ent
+is
+.Dv NULL ,
+the current entry is removed from the database.
+.Nm Cgetset
+must precede the database traversal. It must be called before the
+.Nm cgetent
+call. If a sequential access is being performed (see below), it must be called
+before the first sequential access call (
+.Nm cgetfirst
+or
+.Nm cgetnext
+), or be directly preceded by a
+.Nm cgetclose
+call.
+On success 0 is returned and \-1 on failure.
+.Pp
+.Nm Cgetmatch
+will return 0 if
+.Fa name
+is one of the names of the capability record
+.Fa buf ,
+\-1 if
+not.
+.Pp
+.Nm Cgetcap
+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
+.Nm Cgetnum
+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
+.Nm Cgetstr
+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
+.Nm Cgetustr
+is identical to
+.Nm cgetstr
+except that it does not expand special characters, but rather returns each
+character of the capability string literally.
+.Pp
+.Nm Cgetfirst ,
+.Nm cgetnext ,
+comprise a function group that provides for sequential
+access of the
+.Dv NULL
+pointer terminated array of file names,
+.Fa db_array .
+.Nm Cgetfirst
+returns the first record in the database and resets the access
+to the first record.
+.Nm Cgetnext
+returns the next record in the database with respect to the
+record returned by the previous
+.Nm cgetfirst
+or
+.Nm 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
+.Nm Cgetclose
+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
+.Nm 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 .
+.Nm Cgetcap
+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
+.Nm cgetnum
+and
+.Nm 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
+.Nm 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
+.Nm cgetnum
+and
+.Nm 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 ('\fIX\fP' & 037) control-\fIX\fP
+\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\|\fInnn\fP (ASCII octal \fInnn\fP)
+.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
+.Nm Cgetent ,
+.Nm cgetset ,
+.Nm cgetmatch ,
+.Nm cgetnum ,
+.Nm cgetstr ,
+.Nm cgetustr ,
+.Nm cgetfirst ,
+and
+.Nm cgetnext
+return a value greater than or equal to 0 on success and a value less
+than 0 on failure.
+.Nm Cgetcap
+returns a character pointer on success and a
+.Dv NULL
+on failure.
+.Pp
+.Nm Cgetent ,
+and
+.Nm cgetseq
+may fail and set
+.Va errno
+for any of the errors specified for the library functions:
+.Xr fopen 2 ,
+.Xr fclose 2 ,
+.Xr open 2 ,
+and
+.Xr close 2 .
+.Pp
+.Nm Cgetent ,
+.Nm cgetset ,
+.Nm cgetstr ,
+and
+.Nm 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
+.Nm cgetent .
+.Pp
+The buffer added to the database by a call to
+.Nm 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..93d1952
--- /dev/null
+++ b/lib/libc/gen/getcap.c
@@ -0,0 +1,1049 @@
+/*-
+ * 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.
+ */
+
+#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, L_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) {
+ /* No error on unfound file. */
+ if (errno == ENOENT)
+ continue;
+ free(record);
+ return (-2);
+ }
+ 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 = realloc(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 = realloc(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 =
+ realloc(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(*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 != NULL; 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 = realloc(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 = realloc(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 = realloc(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 = realloc(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..8740a75
--- /dev/null
+++ b/lib/libc/gen/getcwd.3
@@ -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.
+.\"
+.\" @(#)getcwd.3 8.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.Dt GETCWD 3
+.Os BSD 4.2
+.Sh NAME
+.Nm getcwd
+.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 [EACCESS]
+.It Bq Er EACCESS
+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..fbd445d
--- /dev/null
+++ b/lib/libc/gen/getcwd.c
@@ -0,0 +1,234 @@
+/*
+ * 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getcwd.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define ISDOT(dp) \
+ (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
+ dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
+
+char *
+getcwd(pt, size)
+ char *pt;
+ size_t size;
+{
+ register struct dirent *dp;
+ register DIR *dir;
+ 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;
+
+ /*
+ * 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;
+ }
+ 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 = realloc(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++ = '/';
+
+ /*
+ * 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);
+
+ /* 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:
+ if (ptsize)
+ free(pt);
+ free(up);
+ return (NULL);
+}
diff --git a/lib/libc/gen/getdiskbyname.3 b/lib/libc/gen/getdiskbyname.3
new file mode 100644
index 0000000..14841aa
--- /dev/null
+++ b/lib/libc/gen/getdiskbyname.3
@@ -0,0 +1,64 @@
+.\" 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
+.\"
+.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..8ba5995
--- /dev/null
+++ b/lib/libc/gen/getdomainname.3
@@ -0,0 +1,98 @@
+.\" Copyright (c) 1983, 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: @(#)getdomainname.2 6.7 (Berkeley) 3/10/91
+.\" $Id: getdomainname.2,v 1.1 1993/10/25 03:11:30 rgrimes Exp $
+.\"
+.Dd March 10, 1991
+.Dt GETDOMAINNAME 3
+.Os BSD 4.2
+.Sh NAME
+.Nm getdomainname ,
+.Nm setdomainname
+.Nd get/set 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 host 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 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 domainname and was not the super-user.
+.El
+.Sh SEE ALSO
+.Xr sysctl 2
+.Xr gethostid 3
+.Sh BUGS
+Host names are limited to
+.Dv MAXHOSTNAMELEN
+(from
+.Ao Pa sys/param.h Ac )
+characters, currently 256.
+.Sh HISTORY
+The
+.Nm
+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..990d9f3
--- /dev/null
+++ b/lib/libc/gen/getdomainname.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[] = "From: @(#)gethostname.c 8.1 (Berkeley) 6/4/93";
+*/
+static const char rcsid[] =
+ "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+long
+getdomainname(name, namelen)
+ char *name;
+ int namelen;
+{
+ int mib[2];
+ size_t size;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_DOMAINNAME;
+ 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..1051837
--- /dev/null
+++ b/lib/libc/gen/getfsent.3
@@ -0,0 +1,148 @@
+.\" 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
+.\"
+.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 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; /* type of file system */
+ char *fs_mntops; /* comma separated mount options */
+ char *fs_type; /* rw, ro, sw, or xx */
+ int fs_freq; /* dump frequency, in days */
+ int fs_passno; /* pass number on parallel dump */
+};
+.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 null pointer (0) 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..132ba6b
--- /dev/null
+++ b/lib/libc/gen/getgrent.3
@@ -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.
+.\"
+.\" From: @(#)getgrent.3 8.2 (Berkeley) 4/19/94
+.\" $Id$
+.\"
+.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 <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 struct group *
+.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 */
+ gid_t 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
+.Fn getpwent 3 ,
+.Fn group 5 ,
+.Fn yp 4
+.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..6451dc9
--- /dev/null
+++ b/lib/libc/gen/getgrent.c
@@ -0,0 +1,438 @@
+/*
+ * 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
+
+#define MAXGRP 200
+static char *members[MAXGRP];
+#define MAXLINELENGTH 1024
+static char line[MAXLINELENGTH];
+
+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] && !_gr_yp_enabled) {
+ _gr_yp_enabled = 1;
+ } else {
+ _gr_yp_enabled = -1;
+ break;
+ }
+ }
+ }
+ rewind(_gr_fp);
+ }
+#endif
+ 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 = 0;
+#endif;
+ for (;;) {
+ if (!fgets(line, sizeof(line), _gr_fp))
+ return(0);
+ bp = line;
+ /* skip lines that are too big */
+ if (!index(line, '\n')) {
+ int ch;
+
+ while ((ch = getc(_gr_fp)) != '\n' && ch != EOF)
+ ;
+ continue;
+ }
+ 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 {
+ if (!_getypgroup(&_gr_group, &_gr_group.gr_name[1],
+ "group.byname"))
+ continue;
+ /* We're going to override -- tell the world. */
+ members[0] = NULL;
+ _ypfound++;
+ }
+ }
+#else
+ if (_gr_group.gr_name[0] == '+')
+ continue;
+#endif /* YP */
+ if (search && name) {
+ if(strcmp(_gr_group.gr_name, name)) {
+ continue;
+ }
+ }
+ if ((_gr_group.gr_passwd = strsep(&bp, ":\n")) == NULL)
+ break;;
+ if (!(cp = strsep(&bp, ":\n")))
+ continue;
+#ifdef YP
+ if (!_ypfound)
+#endif
+ _gr_group.gr_gid = atoi(cp);
+ if (search && name == NULL && _gr_group.gr_gid != gid)
+ continue;
+ cp = NULL;
+ for (m = _gr_group.gr_mem = members;; bp++) {
+ if (m == &members[MAXGRP - 1])
+ break;
+ 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;
+ }
+ *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 = _gr_group.gr_mem = members; /**/; s++) {
+ if (m == &members[MAXGRP - 1]) {
+ break;
+ }
+ 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;
+ }
+ }
+ *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[1024];
+ 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;
+ strcpy(resultbuf, result);
+ result = resultbuf;
+ return(_gr_breakout_yp(gr, resultbuf));
+
+}
+
+
+static int
+_nextypgroup(struct group *gr)
+{
+ static char *key;
+ static int keylen;
+ char *lastkey, *result;
+ static char resultbuf[1024];
+ 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;
+ }
+
+ strcpy(resultbuf, result);
+ 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..7878574
--- /dev/null
+++ b/lib/libc/gen/getgrouplist.3
@@ -0,0 +1,92 @@
+.\" 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
+.\"
+.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 4.4BSD.
+.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..c65e1fa
--- /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.1 (Berkeley) 6/4/93";
+#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;
+ }
+ if (ngroups >= maxgroups) {
+ ret = -1;
+ break;
+ }
+ for (i = 0; grp->gr_mem[i]; i++) {
+ if (!strcmp(grp->gr_mem[i], uname)) {
+ 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..fcb0303
--- /dev/null
+++ b/lib/libc/gen/gethostname.3
@@ -0,0 +1,97 @@
+.\" 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
+.\"
+.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 sysctl 2
+.Xr gethostid 3
+.Sh BUGS
+Host names are limited to
+.Dv MAXHOSTNAMELEN
+(from
+.Ao Pa sys/param.h Ac )
+characters, currently 256.
+.Sh HISTORY
+The
+.Nm
+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..058e4b6
--- /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>
+
+long
+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..2eafd5b
--- /dev/null
+++ b/lib/libc/gen/getloadavg.3
@@ -0,0 +1,64 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt GETLOADAVG 3
+.Os
+.Sh NAME
+.Nm getloadavg
+.Nd get system load averages
+.Sh SYNOPSIS
+.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 sysctl 2 ,
+.Xr kvm_getloadavg 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..b6f55a4
--- /dev/null
+++ b/lib/libc/gen/getlogin.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[] = "@(#)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 + 1];
+
+ if (_logname_valid == 0) {
+ if (_getlogin(logname, sizeof(logname) - 1) < 0)
+ 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..f0e83ea3
--- /dev/null
+++ b/lib/libc/gen/getmntinfo.3
@@ -0,0 +1,108 @@
+.\" 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
+.\"
+.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
+.Xr 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 statfs 2 ,
+.Xr mount 2 ,
+.Xr mount 8
+.Sh HISTORY
+The
+.Fn getmntinfo
+function first appeared in 4.4BSD.
+.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 2 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..1e38538
--- /dev/null
+++ b/lib/libc/gen/getnetgrent.3
@@ -0,0 +1,128 @@
+.\" 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
+.\"
+.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
+.Fn 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 free'd 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..2997f63
--- /dev/null
+++ b/lib/libc/gen/getnetgrent.c
@@ -0,0 +1,608 @@
+/*
+ * 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getnetgrent.c 8.1 (Berkeley) 6/4/93";
+#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;
+
+ while (ptr != (char *)(list + len)) {
+ if (!strncmp(group, ptr, strlen(group)))
+ return(1);
+ 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)
+ char *group, *host, *user, *dom;
+{
+ char *hst, *usr, *dm;
+#ifdef YP
+ char *result;
+ int resultlen;
+#endif
+ /* Sanity check */
+
+ if (group == NULL || !strlen(group))
+ return (0);
+
+#ifdef YP
+ _yp_innetgr = 1;
+#endif
+ setnetgrent(group);
+#ifdef YP
+ /*
+ * 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;
+
+ if(yp_get_default_domain(&_netgr_yp_domain))
+ return(0);
+ while(_buildkey(&_key, user ? user : host, dom, &rot)) {
+ if (yp_match(_netgr_yp_domain, user? "netgroup.byuser":
+ "netgroup.byhost", _key, strlen(_key), &result,
+ &resultlen))
+ free(result);
+ else {
+ if (_listmatch(result, group, resultlen)) {
+ free(result);
+ return(1);
+ }
+ }
+ }
+ free(result);
+#ifdef CHARITABLE
+ }
+ /*
+ * Couldn't match using NIS-exclusive mode -- try
+ * standard mode.
+ */
+ _yp_innetgr = 0;
+ setnetgrent(group);
+#else
+ return(0);
+ }
+#endif /* CHARITABLE */
+#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;
+ }
+ /* Watch for null pointer dereferences, dammit! */
+ if (pos != NULL)
+ 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 + 1];
+#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;
+ }
+ }
+ sprintf(line, "%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/getosreldate.c b/lib/libc/gen/getosreldate.c
new file mode 100644
index 0000000..808e16b
--- /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[] =
+ "$Id$";
+#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..1a26297
--- /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
+.\"
+.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
+.Xr system
+page size and may not be the same as the underlying
+hardware page size.
+.Sh SEE ALSO
+.Xr sbrk 2 ,
+.Xr pagesize 1
+.Sh HISTORY
+The
+.Nm
+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..d586cf6
--- /dev/null
+++ b/lib/libc/gen/getpagesize.c
@@ -0,0 +1,53 @@
+/*
+ * 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>
+
+int
+getpagesize()
+{
+ int mib[2], value;
+ size_t size;
+
+ 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..f312d42
--- /dev/null
+++ b/lib/libc/gen/getpass.3
@@ -0,0 +1,92 @@
+.\" 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
+.\"
+.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,
+.Nm 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
+.Nm Getpass
+turns off character echoing while reading the password.
+.Pp
+.Sh RETURN VALUES
+.Nm Getpass
+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
+.Nm getpass
+function appeared in
+.At v7 .
+.Sh BUGS
+The
+.Nm getpass
+function leaves its result in an internal static object and returns
+a pointer to that object.
+Subsequent calls to
+.Nm 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..658f5b6
--- /dev/null
+++ b/lib/libc/gen/getpass.c
@@ -0,0 +1,125 @@
+/*
+ * 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 sig_t ointhandler, oquithandler, otstphandler, oconthandler;
+static FILE *fp;
+
+static void
+sighandler(int signo)
+{
+ /* restore tty state */
+ (void)tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &oterm);
+
+ /* restore old sig handlers */
+ (void)signal(SIGINT, ointhandler);
+ (void)signal(SIGQUIT, oquithandler);
+ (void)signal(SIGTSTP, otstphandler);
+
+ /* resend us this signal */
+ (void)kill(getpid(), signo);
+}
+
+/* ARGSUSED */
+static void
+sigconthandler(int signo)
+{
+ /* re-install our signal handlers */
+ ointhandler = signal(SIGINT, sighandler);
+ oquithandler = signal(SIGQUIT, sighandler);
+ otstphandler = signal(SIGTSTP, sighandler);
+
+ /* turn off echo again */
+ (void)tcsetattr(fileno(fp), TCSAFLUSH|TCSASOFT, &term);
+}
+
+
+char *
+getpass(prompt)
+ const char *prompt;
+{
+ register int ch;
+ register char *p;
+ FILE *outfp;
+ long omask;
+ static char buf[_PASSWORD_LEN + 1];
+
+ /*
+ * 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;
+ }
+
+ ointhandler = signal(SIGINT, sighandler);
+ oquithandler = signal(SIGQUIT, sighandler);
+ otstphandler = signal(SIGTSTP, sighandler);
+ oconthandler = signal(SIGCONT, sigconthandler);
+
+ (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);
+
+ /* restore old sig handlers */
+ (void)signal(SIGINT, ointhandler);
+ (void)signal(SIGQUIT, oquithandler);
+ (void)signal(SIGTSTP, otstphandler);
+ (void)signal(SIGCONT, oconthandler);
+
+ 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..6c23f49
--- /dev/null
+++ b/lib/libc/gen/getpwent.3
@@ -0,0 +1,217 @@
+.\" 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
+.\"
+.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 int
+.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 */
+};
+.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 functions
+.Fn setpassent
+and
+.Fn setpwent
+return 0 on failure and 1 on success.
+The
+.Fn endpwent
+function
+has no return value.
+.Sh FILES
+.Bl -tag -width /etc/master.passwd -compact
+.It Pa /var/db/pwd.db
+The insecure password database file
+.It Pa /var/db/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 3 ,
+.Xr getgrent 3 ,
+.Xr passwd 5 ,
+.Xr pwd_mkdb 8 ,
+.Xr vipw 8 ,
+.Xr yp 4
+.Sh HISTORY
+The
+.Nm getpwent ,
+.Nm getpwnam ,
+.Nm getpwuid ,
+.Nm setpwent,
+and
+.Nm endpwent
+functions appeared in
+.At v7 .
+The
+.Nm 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..a3e32ad
--- /dev/null
+++ b/lib/libc/gen/getpwent.c
@@ -0,0 +1,775 @@
+/*
+ * 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[] = "@(#)getpwent.c 8.1 (Berkeley) 6/4/93";
+#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>
+
+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>
+struct _namelist {
+ char *name;
+ struct _namelist *next;
+};
+static struct passwd _pw_copy;
+struct _pw_cache {
+ struct passwd pw_entry;
+ struct _namelist *namelist;
+ struct _pw_cache *next;
+};
+static int _pluscnt, _minuscnt;
+static struct _pw_cache *_plushead = NULL, *_minushead = NULL;
+static void _createcaches(), _freecaches();
+static int _scancaches(char *);
+static int _yp_enabled; /* set true when yp enabled */
+static int _pw_stepping_yp; /* set true when stepping thru map */
+static int _yp_done;
+static int _gotmaster;
+static char *_pw_yp_domain;
+static int _havemaster(char *);
+static int _getyppass(struct passwd *, const char *, const char *);
+static int _nextyppass(struct passwd *);
+#endif
+static int __hashpw(), __initdb();
+
+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 (_nextyppass(&_pw_passwd))
+ return (&_pw_passwd);
+ else
+ _yp_done = 1;
+ }
+#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] == '-') {
+ _pw_copy = _pw_passwd;
+ if (_yp_done || !_nextyppass(&_pw_passwd))
+ 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);
+ bcopy(name, bf + 1, MIN(len, UT_NAMESIZE));
+ key.data = (u_char *)bf;
+ key.size = len + 1;
+ rval = __hashpw(&key);
+
+#ifdef YP
+ if (!rval && _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;
+
+ endpwent();
+ return(rval ? &_pw_passwd : (struct passwd *)NULL);
+}
+
+struct passwd *
+#ifdef __STDC__
+getpwuid(uid_t uid)
+#else
+getpwuid(uid)
+ int uid;
+#endif
+{
+ 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 && _yp_enabled) {
+ char ypbuf[16]; /* big enough for 32-bit uids and then some */
+ 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;
+
+ endpwent();
+ return(rval ? &_pw_passwd : (struct passwd *)NULL);
+}
+
+int
+setpassent(stayopen)
+ int stayopen;
+{
+ _pw_keynum = 0;
+#ifdef YP
+ _pw_stepping_yp = _yp_done = 0;
+#endif
+ _pw_stayopen = stayopen;
+ return(1);
+}
+
+int
+setpwent()
+{
+ _pw_keynum = 0;
+#ifdef YP
+ _pw_stepping_yp = _yp_done = 0;
+#endif
+ _pw_stayopen = 0;
+ return(1);
+}
+
+void
+endpwent()
+{
+ _pw_keynum = 0;
+#ifdef YP
+ _pw_stepping_yp = _yp_done = 0;
+#endif
+ if (_pw_db) {
+ (void)(_pw_db->close)(_pw_db);
+ _pw_db = (DB *)NULL;
+#ifdef YP
+ _freecaches();
+#endif
+ }
+}
+
+static
+__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) {
+#ifdef YP
+ DBT key, data;
+ char buf[] = { _PW_KEYYPENABLED };
+ key.data = buf;
+ key.size = 1;
+ if ((_pw_db->get)(_pw_db, &key, &data, 0)) {
+ _yp_enabled = 0;
+ } else {
+ _yp_enabled = (int)*((char *)data.data) - 2;
+ _createcaches();
+ /* 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(1);
+ _gotmaster = _havemaster(_pw_yp_domain);
+ } else _gotmaster = 0;
+ }
+#endif
+ return(1);
+ }
+ if (!warned)
+ syslog(LOG_ERR, "%s: %m", p);
+ return(0);
+}
+
+static
+__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;
+ if (data.size > max && !(line = realloc(line, max += 1024)))
+ return(0);
+
+ t = line;
+#define EXPAND(e) e = t; while (*t++ = *p++);
+ EXPAND(_pw_passwd.pw_name);
+ EXPAND(_pw_passwd.pw_passwd);
+ bcopy(p, (char *)&_pw_passwd.pw_uid, sizeof(int));
+ p += sizeof(int);
+ bcopy(p, (char *)&_pw_passwd.pw_gid, sizeof(int));
+ p += sizeof(int);
+ bcopy(p, (char *)&_pw_passwd.pw_change, sizeof(time_t));
+ p += sizeof(time_t);
+ EXPAND(_pw_passwd.pw_class);
+ EXPAND(_pw_passwd.pw_gecos);
+ EXPAND(_pw_passwd.pw_dir);
+ EXPAND(_pw_passwd.pw_shell);
+ bcopy(p, (char *)&_pw_passwd.pw_expire, sizeof(time_t));
+ p += sizeof(time_t);
+ bcopy(p, (char *)&_pw_passwd.pw_fields, sizeof _pw_passwd.pw_fields);
+ p += sizeof _pw_passwd.pw_fields;
+ return(1);
+}
+
+#ifdef YP
+/*
+ * Build special +@netgroup and -@netgroup caches. We also handle ordinary
+ * +user/-user entries, *and* +@group/-@group entries, which are special
+ * cases of the +@netgroup/-@netgroup substitutions: if we can't find
+ * netgroup 'foo', we look for a regular user group called 'foo' and
+ * match against that instead. The netgroup takes precedence since the
+ * +group/-group support is basically just a hack to make Justin T. Gibbs
+ * happy. :) Sorting out all the funny business here lets us have a
+ * yp_enabled flag with a simple on or off value instead of the somewhat
+ * bogus setup we had before.
+ *
+ * We cache everything here in one shot so that we only have to scan
+ * each netgroup/group once. The alternative is to use innetgr() inside the
+ * NIS lookup functions, which would make retrieving the whole password
+ * database though getpwent() very slow. +user/-user entries are treated
+ * like @groups/@netgroups with only one member.
+ */
+static void
+_createcaches()
+{
+ DBT key, data;
+ int i;
+ char bf[UT_NAMESIZE + 2];
+ struct _pw_cache *p, *m;
+ struct _namelist *n, *namehead;
+ char *user, *host, *domain;
+ struct group *grp;
+
+ /*
+ * Assume that the database has already been initialized
+ * but be paranoid and check that YP is in fact enabled.
+ */
+
+ if (!_yp_enabled)
+ return;
+ /*
+ * For the plus list, we have to store both the linked list of
+ * names and the +entries from the password database so we can
+ * do the substitution later if we find a match.
+ */
+ bf[0] = _PW_KEYPLUSCNT;
+ key.data = (u_char*)bf;
+ key.size = 1;
+ if (!(_pw_db->get)(_pw_db, &key, &data, 0)) {
+ _pluscnt = (int)*((char *)data.data);
+ for (i = 0; i < _pluscnt; i++) {
+ bf[0] = _PW_KEYPLUSBYNUM;
+ bcopy(&i, bf + 1, sizeof(i) + 1);
+ key.size = (sizeof(i)) + 1;
+ if (__hashpw(&key)) {
+ p = (struct _pw_cache *)malloc(sizeof (struct _pw_cache));
+ if (strlen(_pw_passwd.pw_name) > 2 && _pw_passwd.pw_name[1] == '@') {
+ setnetgrent(_pw_passwd.pw_name+2);
+ namehead = NULL;
+ while(getnetgrent(&host, &user, &domain)) {
+ n = (struct _namelist *)malloc(sizeof (struct _namelist));
+ n->name = strdup(user);
+ n->next = namehead;
+ namehead = n;
+ }
+ /*
+ * If netgroup 'foo' doesn't exist,
+ * try group 'foo' instead.
+ */
+ if (namehead == NULL && (grp = getgrnam(_pw_passwd.pw_name+2)) != NULL) {
+ while(*grp->gr_mem) {
+ n = (struct _namelist *)malloc(sizeof (struct _namelist));
+ n->name = strdup(*grp->gr_mem);
+ n->next = namehead;
+ namehead = n;
+ grp->gr_mem++;
+ }
+ }
+ } else {
+ if (_pw_passwd.pw_name[1] != '@') {
+ namehead = (struct _namelist *)malloc(sizeof (struct _namelist));
+ namehead->name = strdup(_pw_passwd.pw_name+1);
+ namehead->next = NULL;
+ }
+ }
+ p->namelist = namehead;
+ p->pw_entry.pw_name = strdup(_pw_passwd.pw_name);
+ p->pw_entry.pw_passwd = strdup(_pw_passwd.pw_passwd);
+ p->pw_entry.pw_uid = _pw_passwd.pw_uid;
+ p->pw_entry.pw_gid = _pw_passwd.pw_gid;
+ p->pw_entry.pw_expire = _pw_passwd.pw_expire;
+ p->pw_entry.pw_change = _pw_passwd.pw_change;
+ p->pw_entry.pw_class = strdup(_pw_passwd.pw_class);
+ p->pw_entry.pw_gecos = strdup(_pw_passwd.pw_gecos);
+ p->pw_entry.pw_dir = strdup(_pw_passwd.pw_dir);
+ p->pw_entry.pw_shell = strdup(_pw_passwd.pw_shell);
+ p->pw_entry.pw_fields = _pw_passwd.pw_fields;
+ p->next = _plushead;
+ _plushead = p;
+ }
+ }
+ }
+
+ /*
+ * All we need for the minuslist is the usernames.
+ * The actual -entries data can be ignored since no substitution
+ * will be done: anybody on the minus list is treated like a
+ * non-person.
+ */
+ bf[0] = _PW_KEYMINUSCNT;
+ key.data = (u_char*)bf;
+ key.size = 1;
+ if (!(_pw_db->get)(_pw_db, &key, &data, 0)) {
+ _minuscnt = (int)*((char *)data.data);
+ for (i = _minuscnt; i > -1; i--) {
+ bf[0] = _PW_KEYMINUSBYNUM;
+ bcopy(&i, bf + 1, sizeof(i) + 1);
+ key.size = (sizeof(i)) + 1;
+ if (__hashpw(&key)) {
+ m = (struct _pw_cache *)malloc(sizeof (struct _pw_cache));
+ if (strlen (_pw_passwd.pw_name) > 2 && _pw_passwd.pw_name[1] == '@') {
+ namehead = NULL;
+ setnetgrent(_pw_passwd.pw_name+2);
+ while(getnetgrent(&host, &user, &domain)) {
+ n = (struct _namelist *)malloc(sizeof (struct _namelist));
+ n->name = strdup(user);
+ n->next = namehead;
+ namehead = n;
+ }
+ /*
+ * If netgroup 'foo' doesn't exist,
+ * try group 'foo' instead.
+ */
+ if (namehead == NULL && (grp = getgrnam(_pw_passwd.pw_name+2)) != NULL) {
+ while(*grp->gr_mem) {
+ n = (struct _namelist *)malloc(sizeof (struct _namelist));
+ n->name = strdup(*grp->gr_mem);
+ n->next = namehead;
+ namehead = n;
+ grp->gr_mem++;
+ }
+ }
+ } else {
+ if (_pw_passwd.pw_name[1] != '@') {
+ namehead = (struct _namelist *)malloc(sizeof (struct _namelist));
+ namehead->name = strdup(_pw_passwd.pw_name+1);
+ namehead->next = NULL;
+ }
+ }
+ /* Save just the name */
+ m->pw_entry.pw_name = strdup(_pw_passwd.pw_name);
+ m->namelist = namehead;
+ m->next = _minushead;
+ _minushead = m;
+ }
+ }
+ }
+ endgrent();
+ endnetgrent();
+}
+
+/*
+ * Free the +@netgroup/-@netgroup caches. Should be called
+ * from endpwent(). We have to blow away both the list of
+ * netgroups and the attached linked lists of usernames.
+ */
+static void
+_freecaches()
+{
+struct _pw_cache *p, *m;
+struct _namelist *n;
+
+ while (_plushead) {
+ while(_plushead->namelist) {
+ n = _plushead->namelist->next;
+ free(_plushead->namelist->name);
+ free(_plushead->namelist);
+ _plushead->namelist = n;
+ }
+ free(_plushead->pw_entry.pw_name);
+ free(_plushead->pw_entry.pw_passwd);
+ free(_plushead->pw_entry.pw_class);
+ free(_plushead->pw_entry.pw_gecos);
+ free(_plushead->pw_entry.pw_dir);
+ free(_plushead->pw_entry.pw_shell);
+ p = _plushead->next;
+ free(_plushead);
+ _plushead = p;
+ }
+
+ while(_minushead) {
+ while(_minushead->namelist) {
+ n = _minushead->namelist->next;
+ free(_minushead->namelist->name);
+ free(_minushead->namelist);
+ _minushead->namelist = n;
+ }
+ m = _minushead->next;
+ free(_minushead);
+ _minushead = m;
+ }
+ _pluscnt = _minuscnt = 0;
+}
+
+static int _scancaches(user)
+char *user;
+{
+ register struct _pw_cache *m, *p;
+ register struct _namelist *n;
+
+ if (_minuscnt && _minushead) {
+ m = _minushead;
+ while (m) {
+ n = m->namelist;
+ while (n) {
+ if (!strcmp(n->name,user) || *n->name == '\0')
+ return (1);
+ n = n->next;
+ }
+ m = m->next;
+ }
+ }
+ if (_pluscnt && _plushead) {
+ p = _plushead;
+ while (p) {
+ n = p->namelist;
+ while (n) {
+ if (!strcmp(n->name, user) || *n->name == '\0')
+ bcopy((char *)&p->pw_entry,
+ (char *)&_pw_passwd, sizeof(p->pw_entry));
+ n = n->next;
+ }
+ p = p->next;
+ }
+ }
+ return(0);
+}
+
+static int
+_pw_breakout_yp(struct passwd *pw, char *res, 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, YPMAXRECORD);
+ 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)) {
+ 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) {
+ 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 *_pw_yp_domain)
+{
+ int keylen, resultlen;
+ char *key, *result;
+
+ if (yp_first(_pw_yp_domain, "master.passwd.byname",
+ &key, &keylen, &result, &resultlen)) {
+ free(result);
+ return 0;
+ }
+ free(result);
+ return 1;
+}
+
+static int
+_getyppass(struct passwd *pw, const char *name, const char *map)
+{
+ char *result, *s;
+ int resultlen;
+ int rv;
+ char mastermap[1024];
+
+ if(!_pw_yp_domain) {
+ if(yp_get_default_domain(&_pw_yp_domain))
+ return 0;
+ }
+
+ sprintf(mastermap,"%s",map);
+
+ if (_gotmaster)
+ sprintf(mastermap,"master.%s", map);
+
+ if(yp_match(_pw_yp_domain, (char *)&mastermap, name, strlen(name),
+ &result, &resultlen))
+ return 0;
+
+ s = strchr(result, ':');
+ if (s) {
+ *s = '\0';
+ } else {
+ /* Must be a malformed entry if no colons. */
+ free(result);
+ return(0);
+ }
+ _pw_passwd.pw_fields = -1; /* Impossible value */
+ if (_scancaches(result)) {
+ free(result);
+ return(0);
+ }
+ /* No hits in the plus or minus lists: Bzzt! reject. */
+ if (_pw_passwd.pw_fields == -1) {
+ free(result);
+ return(0);
+ }
+ *s = ':'; /* Put back the colon we previously replaced with a NUL. */
+ rv = _pw_breakout_yp(pw, result, _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)
+ 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 colon. */
+ free(result);
+ goto tryagain;
+ }
+ _pw_passwd.pw_fields = -1; /* Impossible value */
+ if (_scancaches(result)) {
+ free(result);
+ goto tryagain;
+ }
+ /* No plus or minus hits: Bzzzt! reject. */
+ if (_pw_passwd.pw_fields == -1) {
+ free(result);
+ goto tryagain;
+ }
+ *s = ':'; /* Put back colon we previously replaced with a NUL. */
+ if(s = strchr(result, '\n')) *s = '\0';
+ if (_pw_breakout_yp(pw, result, _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..7ee453d
--- /dev/null
+++ b/lib/libc/gen/getttyent.3
@@ -0,0 +1,177 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt GETTTYENT 3
+.Os BSD 4.3
+.Sh NAME
+.Nm getttyent ,
+.Nm getttynam ,
+.Nm setttyent ,
+.Nm endttyent
+.Nd get ttys file entry
+.Sh SYNOPSIS
+.Fd #include <ttyent.h>
+.Ft struct ttyent *
+.Fn getttyent
+.Ft struct ttyent *
+.Fn getttynam "char *name"
+.Ft int
+.Fn setttyent void
+.Ft int
+.Fn endttyent void
+.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 */
+ char *ty_type; /* terminal type */
+#define TTY_ON 0x01 /* enable logins */
+#define TTY_SECURE 0x02 /* allow uid of 0 to login */
+ int ty_status; /* flag values */
+ char *ty_window; /* command for window manager */
+ char *ty_comment; /* comment field */
+};
+.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_SECURE
+.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.
+.El
+.It Fa ty_window
+The command to execute for a window system associated with the line.
+.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.
+.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..83f97e8
--- /dev/null
+++ b/lib/libc/gen/getttyent.c
@@ -0,0 +1,199 @@
+/*
+ * 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[] = "@(#)getttyent.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <ttyent.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+static char zapchar;
+static FILE *tf;
+
+struct ttyent *
+getttynam(tty)
+ const char *tty;
+{
+ register struct ttyent *t;
+
+ setttyent();
+ while (t = getttyent())
+ if (!strcmp(tty, t->ty_name))
+ break;
+ endttyent();
+ return (t);
+}
+
+struct ttyent *
+getttyent()
+{
+ static struct ttyent tty;
+ register int c;
+ register char *p;
+#define MAXLINELENGTH 100
+ static char line[MAXLINELENGTH];
+ static char *skip(), *value();
+
+ if (!tf && !setttyent())
+ return (NULL);
+ for (;;) {
+ if (!fgets(p = line, sizeof(line), tf))
+ return (NULL);
+ /* skip lines that are too big */
+ if (!index(p, '\n')) {
+ while ((c = getc(tf)) != '\n' && c != EOF)
+ ;
+ continue;
+ }
+ while (isspace(*p))
+ ++p;
+ if (*p && *p != '#')
+ break;
+ }
+
+ 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
+ p = skip(p);
+ }
+ tty.ty_status = 0;
+ tty.ty_window = NULL;
+
+#define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace(p[sizeof(e) - 1])
+#define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
+ 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 (vcmp(_TTYS_WINDOW))
+ tty.ty_window = 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 (tf) {
+ rewind(tf);
+ return (1);
+ } else if (tf = fopen(_PATH_TTYS, "r"))
+ return (1);
+ return (0);
+}
+
+int
+endttyent()
+{
+ int rval;
+
+ if (tf) {
+ rval = !(fclose(tf) == EOF);
+ tf = NULL;
+ return (rval);
+ }
+ return (1);
+}
diff --git a/lib/libc/gen/getusershell.3 b/lib/libc/gen/getusershell.3
new file mode 100644
index 0000000..48aa859
--- /dev/null
+++ b/lib/libc/gen/getusershell.3
@@ -0,0 +1,97 @@
+.\" 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
+.\"
+.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
+.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..408f9f3
--- /dev/null
+++ b/lib/libc/gen/getusershell.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.
+ */
+
+#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(*cp) && *cp != '#' && *cp != '\0')
+ cp++;
+ *cp++ = '\0';
+ }
+ *sp = NULL;
+ (void)fclose(fp);
+ return (shells);
+}
diff --git a/lib/libc/gen/getvfsent.3 b/lib/libc/gen/getvfsent.3
new file mode 100644
index 0000000..a8151b0
--- /dev/null
+++ b/lib/libc/gen/getvfsent.3
@@ -0,0 +1,226 @@
+.\" $Id$
+.\" Written by Garrett A. Wollman, September 1994.
+.\" This manual page is in the public domain.
+.\"
+.Dd September 24, 1994
+.Dt GETVFSBYNAME 3
+.Os
+.Sh NAME
+.Nm getvfsbyname ,
+.Nm getvfsbytype ,
+.Nm getvfsent ,
+.Nm setvfsent ,
+.Nm endvfsent ,
+.Nm vfsisloadable ,
+.Nm vfsload
+.Nd manage virtual filesystem modules
+.Sh SYNOPSIS
+.Fd #include <sys/mount.h>
+.Ft struct vfsconf *
+.Fn getvfsbyname "const char *name"
+.Ft struct vfsconf *
+.Fn getvfsbytype "int type"
+.Ft struct vfsconf *
+.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 getvfsbyname ,
+.Fn getvfsbytype ,
+and
+.Fn getvfsent
+functions provide convenient access to a list of installed virtual
+filesystem modules managed by the kernel.
+.Fn getvfsbyname
+and
+.Fn getvfsbytype
+provide direct access to a single filesystem's information;
+.Fn getvfsent
+steps through the list of filesystems one at a time. All three
+functions return a null pointer when no data is available. The fields
+in a
+.Dq Li struct vfsconf
+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 ``likely'' because the conditions
+checked by
+.Fn vfsisloadable
+are only a small subset of the conditions necessary for
+.Fn vfsload
+to succeed. In particular,
+.Fn vfsisloadable
+checks that
+.Pa /dev/lkm
+is present and can be opened for writing, and that
+.Pa Ns Fa name Ns _mod.o
+can be found in one of the directories designated for LKMs.
+.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 name
+has been called and returned a null pointer.
+.It
+.Fn vfsisloadable name
+has been called and returned a non-zero value.
+.It
+sufficient temporary file space is available
+.Em and writable
+in one of
+.No Ns \&${ Ns Ev TMPDIR Ns \&} ,
+.Pa /var/tmp ,
+or
+.Pa /tmp .
+.El
+.Pp
+Here is an example, taken from the source to
+.Xr mount_cd9660 8 :
+.Bd -literal -offset indent
+
+struct vfsconf *vfc;
+
+/* setup code here */
+
+vfc = getvfsbyname("cd9660");
+if(!vfc && vfsisloadable("cd9660")) {
+ if(vfsload("cd9660"))
+ err(1, "vfsload(cd9660)");
+ endvfsent(); /* flush cache */
+ vfc = getvfsbyname("cd9660");
+}
+
+mount(vfc ? vfc->vfc_index : MOUNT_CD9660, /* more arguments */
+
+.Ed
+The odd conditional in the call to
+.Xr mount 2
+is present for compatibility with old, non-LKM cognizant kernels, and
+will be removed (along with all vestiges of
+.Dv MOUNT_* )
+in a future release.
+.Sh RETURN VALUES
+The
+.Fn getvfsbyname ,
+.Fn getvfsbytype ,
+and
+.Fn getvfsent
+routines all return a pointer to the same static data structure when
+they succeed, and return a null pointer when they fail. 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 fork 2 ,
+.Xr waitpid 3 ,
+.Xr chdir 2 ,
+or
+.Xr execlp 3 ,
+or the return status of the
+.Xr modload 8
+program, which is not currently particularly useful but eventually
+will be. In addition, if
+.Xr modload 8
+exits on a signal,
+.Fn vfsload
+will fail and set
+.Va errno
+to
+.Er EINVAL .
+.Sh ENVIRONMENT
+.Bl -tag -compact -width TMPDIRx
+.It Ev TMPDIR
+location for temporary file created by
+.Xr modload 8
+on behalf of
+.Fn vfsload .
+.It Ev LKMDIR
+alternate directory for
+.Fn vfsisloadable
+and
+.Fn vfsload
+to search for loadable modules.
+.Sh SEE ALSO
+.Xr modload 8 ,
+.Xr mount 2 ,
+.Xr mount 8
+.Sh BUGS
+The return value of the
+.Xr modload 8
+command isn't particularly useful when interpreted as an
+.Va errno
+value (or anything else, for that matter).
+.Sh AUTHOR
+The loadable filesystem support was written by Garrett A. Wollman,
+based on generic loadable kernel module support by Terry Lambert.
+.Sh HISTORY
+The
+.Fn getvfsbyname
+family of functions first appeared in FreeBSD 2.0.
diff --git a/lib/libc/gen/getvfsent.c b/lib/libc/gen/getvfsent.c
new file mode 100644
index 0000000..63fb1da
--- /dev/null
+++ b/lib/libc/gen/getvfsent.c
@@ -0,0 +1,248 @@
+/*
+ * 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>
+
+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_FS, FS_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;
+}
+
+static const char *vfs_lkmdirs[] = {
+ "/lkm",
+ "/usr/lkm",
+ 0,
+ 0
+};
+#define NLKMDIRS ((sizeof vfs_lkmdirs) / (sizeof vfs_lkmdirs[0]))
+
+static const char *
+vfspath(const char *name)
+{
+ static char pnbuf[MAXPATHLEN];
+ char *userdir = getenv("LKMDIR");
+ int i;
+
+ if(userdir) {
+ vfs_lkmdirs[NLKMDIRS - 2] = userdir;
+ }
+
+ for(i = 0; vfs_lkmdirs[i]; i++) {
+ snprintf(pnbuf, sizeof pnbuf, "%s/%s_mod.o", vfs_lkmdirs[i], name);
+ if( ! access(pnbuf, R_OK) )
+ return pnbuf;
+ }
+
+ return 0;
+}
+
+int
+vfsisloadable(const char *name)
+{
+ int fd;
+
+ fd = open("/dev/lkm", O_RDWR, 0);
+ if(fd < 0) {
+ return 0;
+ }
+ close(fd);
+
+ return !!vfspath(name);
+}
+
+int
+vfsload(const char *name)
+{
+ const char *path = vfspath(name);
+ char name_mod[sizeof("_mod") + strlen(name)];
+ pid_t pid;
+ int status;
+
+ if(!path) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ pid = fork();
+ if(pid < 0)
+ return -1;
+
+ if(pid > 0) {
+ waitpid(pid, &status, 0);
+ if(WIFEXITED(status)) {
+ errno = WEXITSTATUS(status);
+ return errno ? -1 : 0;
+ }
+ errno = EINVAL; /* not enough errno values, >sigh< */
+ return -1;
+ }
+
+ status = -1;
+ if(getenv("TMPDIR")) {
+ status = chdir(getenv("TMPDIR"));
+ }
+ if(status) {
+ status = chdir(_PATH_VARTMP);
+ }
+ if(status) {
+ status = chdir(_PATH_TMP);
+ }
+ if(status) {
+ exit(status ? errno : 0);
+ }
+
+ snprintf(name_mod, sizeof name_mod, "%s%s", name, "_mod");
+ status = execlp("modload", "modload", "-e", name_mod, "-o", name_mod,
+ "-u", "-q", path, (const char *)0);
+
+ exit(status ? errno : 0);
+}
+
diff --git a/lib/libc/gen/glob.3 b/lib/libc/gen/glob.3
new file mode 100644
index 0000000..f28bc2a
--- /dev/null
+++ b/lib/libc/gen/glob.3
@@ -0,0 +1,444 @@
+.\" 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
+.\"
+.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" "const 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
+.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 4.4BSD.
+.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..2105f2a
--- /dev/null
+++ b/lib/libc/gen/glob.c
@@ -0,0 +1,846 @@
+/*
+ * 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>
+
+#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 *, 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, pglob)
+ const Char *pattern;
+ Char *patbuf;
+ glob_t *pglob;
+{
+ struct passwd *pwd;
+ char *h;
+ const Char *p;
+ Char *b;
+
+ if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
+ return pattern;
+
+ /* Copy up to the end of the string or / */
+ for (p = pattern + 1, h = (char *) patbuf; *p && *p != SLASH;
+ *h++ = *p++)
+ continue;
+
+ *h = EOS;
+
+ if (((char *) patbuf)[0] == EOS) {
+ /*
+ * handle a plain ~ or ~/ by expanding $HOME
+ * first and then trying the password file
+ */
+ if ((h = getenv("HOME")) == NULL) {
+ if ((pwd = getpwuid(getuid())) == NULL)
+ return pattern;
+ else
+ h = pwd->pw_dir;
+ }
+ }
+ else {
+ /*
+ * Expand a ~user
+ */
+ if ((pwd = getpwnam((char*) patbuf)) == NULL)
+ return pattern;
+ else
+ h = pwd->pw_dir;
+ }
+
+ /* Copy the home directory */
+ for (b = patbuf; *h; *b++ = *h++)
+ continue;
+
+ /* Append the rest of the pattern */
+ while ((*b++ = *p++) != EOS)
+ continue;
+
+ 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, 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 (c <= k && k <= pat[1])
+ 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..a0b1c4f
--- /dev/null
+++ b/lib/libc/gen/initgroups.3
@@ -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.
+.\"
+.\" @(#)initgroups.3 8.1 (Berkeley) 6/4/93
+.\"
+.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
+.Nm
+function appeared in
+.Bx 4.2 .
+.Sh BUGS
+The
+.Fn getgrouplist
+function called by
+.Nm
+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..da64187
--- /dev/null
+++ b/lib/libc/gen/initgroups.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[] = "@(#)initgroups.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <err.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..f6bb04b
--- /dev/null
+++ b/lib/libc/gen/isatty.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[] = "@(#)isatty.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <termios.h>
+#include <unistd.h>
+
+int
+isatty(fd)
+ int fd;
+{
+ struct termios t;
+
+ return(tcgetattr(fd, &t) != -1);
+}
diff --git a/lib/libc/gen/isinf.3 b/lib/libc/gen/isinf.3
new file mode 100644
index 0000000..02ca3c5
--- /dev/null
+++ b/lib/libc/gen/isinf.3
@@ -0,0 +1,72 @@
+.\" 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
+.\"
+.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 isninf
+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..bffcacf
--- /dev/null
+++ b/lib/libc/gen/ldexp.3
@@ -0,0 +1,77 @@
+.\" 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
+.\"
+.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 modf 3 ,
+.Xr math 3
+.Sh STANDARDS
+The
+.Fn ldexp
+function conforms
+.St -ansiC .
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..22b4c4c
--- /dev/null
+++ b/lib/libc/gen/modf.3
@@ -0,0 +1,72 @@
+.\" 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
+.\"
+.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.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.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.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.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..64a87c6
--- /dev/null
+++ b/lib/libc/gen/nice.3
@@ -0,0 +1,67 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt NICE 3
+.Os BSD 4
+.Sh NAME
+.Nm nice
+.Nd set program scheduling priority
+.Sh SYNOPSIS
+.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 setpriority 2 ,
+.Xr fork 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..8b37c06
--- /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 <unistd.h>
+
+/*
+ * Backwards compatible nice.
+ */
+int
+nice(incr)
+ int incr;
+{
+ int prio;
+ extern int errno;
+
+ 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..11c9ee4
--- /dev/null
+++ b/lib/libc/gen/nlist.3
@@ -0,0 +1,78 @@
+.\" 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
+.\"
+.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..cbece18
--- /dev/null
+++ b/lib/libc/gen/nlist.c
@@ -0,0 +1,158 @@
+/*
+ * 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[] = "@(#)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>
+
+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);
+}
+
+#define ISLAST(p) (p->n_un.n_name == 0 || p->n_un.n_name[0] == 0)
+
+int
+__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, 0, fd, (off_t)0);
+ if (a_out_mmap == (char *)-1)
+ 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);
+}
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..feae846
--- /dev/null
+++ b/lib/libc/gen/ntp_gettime.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 const char rcsid[] =
+ "$Id: ntp_gettime.c,v 1.1 1994/09/18 20:29:46 wollman Exp $";
+#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)
+{
+ int mib[3];
+ struct ntptimeval tv;
+ size_t size = sizeof tv;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_NTP_PLL;
+ mib[2] = NTP_PLL_GETTIME;
+ if (sysctl(mib, 3, &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..b3c0e09
--- /dev/null
+++ b/lib/libc/gen/opendir.c
@@ -0,0 +1,101 @@
+/*
+ * 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.2 (Berkeley) 2/12/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.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;
+{
+ register DIR *dirp;
+ register int fd;
+ int saved_errno;
+ struct stat sb;
+
+ if ((fd = open(name, O_RDONLY | O_NONBLOCK)) == -1)
+ return NULL;
+ dirp = NULL;
+ if (fstat(fd, &sb) != 0)
+ goto fail;
+ if (!S_ISDIR(sb.st_mode)) {
+ errno = ENOTDIR;
+ goto fail;
+ }
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1 ||
+ (dirp = malloc(sizeof(DIR))) == NULL)
+ goto fail;
+ /*
+ * If CLBYTES is an exact multiple of DIRBLKSIZ, use a CLBYTES
+ * buffer that it cluster boundary aligned.
+ * Hopefully this can be a big win someday by allowing page trades
+ * to user space to be done by getdirentries()
+ */
+ if ((CLBYTES % DIRBLKSIZ) == 0) {
+ dirp->dd_buf = malloc(CLBYTES);
+ dirp->dd_len = CLBYTES;
+ } else {
+ dirp->dd_buf = malloc(DIRBLKSIZ);
+ dirp->dd_len = DIRBLKSIZ;
+ }
+ if (dirp->dd_buf == NULL)
+ goto fail;
+ dirp->dd_fd = fd;
+ dirp->dd_loc = 0;
+ dirp->dd_seek = 0;
+ /*
+ * Set up seek point for rewinddir.
+ */
+ dirp->dd_rewind = telldir(dirp);
+ return dirp;
+
+fail:
+ saved_errno = errno;
+ free(dirp);
+ 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..b5fd207
--- /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
+.\"
+.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
+.Bf -symbolic
+Pause is made obsolete by sigpause(3).
+.Ef
+.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 sigpause 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..6f89a5c
--- /dev/null
+++ b/lib/libc/gen/popen.3
@@ -0,0 +1,182 @@
+.\" 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.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.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 pipe,
+forking,
+and invoking the shell.
+Since a pipe is by definition unidirectional, the
+.Fa type
+argument may specify only reading or writing, not both;
+the resulting stream is correspondingly read-only or write-only.
+.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.
+The
+.Fa mode
+argument is a pointer to a null-terminated string
+which must be either
+.Ql r
+for reading
+or
+.Ql w
+for writing.
+.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 fork 2 ,
+.Xr sh 1 ,
+.Xr pipe 2 ,
+.Xr wait4 2 ,
+.Xr fflush 3 ,
+.Xr fclose 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 ,
+never calls
+.Xr csh .
+.Sh HISTORY
+A
+.Fn popen
+and a
+.Fn pclose
+function appeared in
+.At v7 .
diff --git a/lib/libc/gen/popen.c b/lib/libc/gen/popen.c
new file mode 100644
index 0000000..0b8bda5
--- /dev/null
+++ b/lib/libc/gen/popen.c
@@ -0,0 +1,160 @@
+/*
+ * 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.1 (Berkeley) 6/4/93";
+#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>
+
+static struct pid {
+ struct pid *next;
+ FILE *fp;
+ pid_t pid;
+} *pidlist;
+
+FILE *
+popen(program, type)
+ const char *program;
+ const char *type;
+{
+ struct pid *cur;
+ FILE *iop;
+ int pdes[2], pid;
+
+ if (*type != 'r' && *type != 'w' || type[1])
+ return (NULL);
+
+ if ((cur = malloc(sizeof(struct pid))) == NULL)
+ return (NULL);
+
+ if (pipe(pdes) < 0) {
+ free(cur);
+ return (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') {
+ if (pdes[1] != STDOUT_FILENO) {
+ (void)dup2(pdes[1], STDOUT_FILENO);
+ (void)close(pdes[1]);
+ }
+ (void) close(pdes[0]);
+ } else {
+ if (pdes[0] != STDIN_FILENO) {
+ (void)dup2(pdes[0], STDIN_FILENO);
+ (void)close(pdes[0]);
+ }
+ (void)close(pdes[1]);
+ }
+ execl(_PATH_BSHELL, "sh", "-c", program, NULL);
+ _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;
+ union wait pstat;
+ pid_t pid;
+
+ (void)fclose(iop);
+
+ /* 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);
+
+ /* Get the status of the process. */
+ omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
+ do {
+ pid = waitpid(cur->pid, (int *) &pstat, 0);
+ } while (pid == -1 && errno == EINTR);
+ (void)sigsetmask(omask);
+
+ /* 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.w_status);
+}
diff --git a/lib/libc/gen/psignal.3 b/lib/libc/gen/psignal.3
new file mode 100644
index 0000000..4e7cfb8
--- /dev/null
+++ b/lib/libc/gen/psignal.3
@@ -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.
+.\"
+.\" @(#)psignal.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt PSIGNAL 3
+.Os BSD 4.2
+.Sh NAME
+.Nm psignal ,
+.Nm sys_siglist
+.Nm sys_signame
+.Nd system signal messages
+.Sh SYNOPSIS
+.Fd #include <sys/signal.h>
+.Ft void
+.Fn psignal "unsigned sig" "const char *s"
+.Vt extern char *sys_siglist[];
+.Vt extern char *sys_signame[];
+.Sh DESCRIPTION
+The
+.Fn psignal
+function locates the descriptive message
+string for the given signal number
+.Fa sig
+and writes it to the standard error.
+.Pp
+If the argument
+.Fa s
+is
+.Pf non- Dv NULL
+it 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
+.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..b7e7ab6
--- /dev/null
+++ b/lib/libc/gen/psignal.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[] = "@(#)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;
+ register int n;
+
+ if (sig < NSIG)
+ c = sys_siglist[sig];
+ else
+ c = "Unknown signal";
+ n = strlen(s);
+ if (n) {
+ (void)write(STDERR_FILENO, s, n);
+ (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..9d280f7
--- /dev/null
+++ b/lib/libc/gen/pw_scan.c
@@ -0,0 +1,141 @@
+/*-
+ * 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 char sccsid[] = "@(#)pw_scan.c 8.3 (Berkeley) 4/2/94";
+#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 <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "pw_scan.h"
+
+int
+pw_scan(bp, pw)
+ char *bp;
+ struct passwd *pw;
+{
+ long id;
+ int root;
+ char *p, *sh;
+
+ 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;
+ id = atol(p);
+ if (root && id) {
+ warnx("root uid should be 0");
+ return (0);
+ }
+ if (id > USHRT_MAX) {
+ warnx("%s > max uid value (%d)", p, USHRT_MAX);
+ return (0);
+ }
+ pw->pw_uid = id;
+
+ if (!(p = strsep(&bp, ":"))) /* gid */
+ goto fmt;
+ if(p[0]) pw->pw_fields |= _PWF_GID;
+ id = atol(p);
+ if (id > USHRT_MAX) {
+ warnx("%s > max gid value (%d)", p, USHRT_MAX);
+ return (0);
+ }
+ 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..d1d4bc1
--- /dev/null
+++ b/lib/libc/gen/pw_scan.h
@@ -0,0 +1,36 @@
+/*-
+ * 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
+ */
+
+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..74afa74
--- /dev/null
+++ b/lib/libc/gen/pwcache.3
@@ -0,0 +1,90 @@
+.\" 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
+.\"
+.Dd June 9, 1993
+.Dt PWCACHE 3
+.Os
+.Sh NAME
+.Nm pwcache
+.Nd cache password and group entries
+.Sh SYNOPSIS
+.Fn user_from_uid "uid_t uid" "int nouser"
+.Fn group_from_gid "gid_t 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_id
+and
+.Fn group_from_id
+functions first appeared in 4.4BSD.
diff --git a/lib/libc/gen/pwcache.c b/lib/libc/gen/pwcache.c
new file mode 100644
index 0000000..7c266c1
--- /dev/null
+++ b/lib/libc/gen/pwcache.c
@@ -0,0 +1,113 @@
+/*
+ * 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;
+ char name[UT_NAMESIZE + 1];
+ } c_uid[NCACHE];
+ static int pwopen;
+ static char nbuf[15]; /* 32 bits == 10 digits */
+ 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;
+ }
+ if ((pw = getpwuid(uid)) == NULL) {
+ if (nouser)
+ return (NULL);
+ (void)snprintf(nbuf, sizeof(nbuf), "%u", uid);
+ return (nbuf);
+ }
+ cp->uid = uid;
+ (void)strncpy(cp->name, pw->pw_name, UT_NAMESIZE);
+ cp->name[UT_NAMESIZE] = '\0';
+ }
+ return (cp->name);
+}
+
+char *
+group_from_gid(gid, nogroup)
+ gid_t gid;
+ int nogroup;
+{
+ static struct ncache {
+ gid_t gid;
+ char name[UT_NAMESIZE + 1];
+ } c_gid[NCACHE];
+ static int gropen;
+ static char nbuf[15]; /* 32 bits == 10 digits */
+ struct group *gr;
+ struct ncache *cp;
+
+ cp = c_gid + (gid & MASK);
+ if (cp->gid != gid || !*cp->name) {
+ if (gropen == 0) {
+ setgroupent(1);
+ gropen = 1;
+ }
+ if ((gr = getgrgid(gid)) == NULL) {
+ if (nogroup)
+ return (NULL);
+ (void)snprintf(nbuf, sizeof(nbuf), "%u", gid);
+ return (nbuf);
+ }
+ cp->gid = gid;
+ (void)strncpy(cp->name, gr->gr_name, UT_NAMESIZE);
+ cp->name[UT_NAMESIZE] = '\0';
+ }
+ return (cp->name);
+}
diff --git a/lib/libc/gen/raise.3 b/lib/libc/gen/raise.3
new file mode 100644
index 0000000..9df3124
--- /dev/null
+++ b/lib/libc/gen/raise.3
@@ -0,0 +1,77 @@
+.\" 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
+.\"
+.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..75ecaa1
--- /dev/null
+++ b/lib/libc/gen/raise.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[] = "@(#)raise.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <signal.h>
+#include <unistd.h>
+
+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..9fadeb2
--- /dev/null
+++ b/lib/libc/gen/rand48.3
@@ -0,0 +1,160 @@
+\" 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
+.\"
+.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 modul 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 AUTHOR
+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..d0651da
--- /dev/null
+++ b/lib/libc/gen/readdir.c
@@ -0,0 +1,72 @@
+/*
+ * 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[] = "@(#)readdir.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <dirent.h>
+
+/*
+ * get next entry in a directory.
+ */
+struct dirent *
+readdir(dirp)
+ register DIR *dirp;
+{
+ register struct dirent *dp;
+
+ for (;;) {
+ if (dirp->dd_loc == 0) {
+ dirp->dd_size = getdirentries(dirp->dd_fd,
+ dirp->dd_buf, dirp->dd_len, &dirp->dd_seek);
+ if (dirp->dd_size <= 0)
+ return NULL;
+ }
+ if (dirp->dd_loc >= dirp->dd_size) {
+ dirp->dd_loc = 0;
+ continue;
+ }
+ dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc);
+ if ((int)dp & 03) /* 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;
+ return (dp);
+ }
+}
diff --git a/lib/libc/gen/rewinddir.c b/lib/libc/gen/rewinddir.c
new file mode 100644
index 0000000..b46bcf3
--- /dev/null
+++ b/lib/libc/gen/rewinddir.c
@@ -0,0 +1,48 @@
+/*-
+ * 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>
+
+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..49e15d1
--- /dev/null
+++ b/lib/libc/gen/scandir.3
@@ -0,0 +1,106 @@
+.\" 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
+.\"
+.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..e6e8408
--- /dev/null
+++ b/lib/libc/gen/scandir.c
@@ -0,0 +1,136 @@
+/*
+ * 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;
+ register size_t nitems;
+ struct stat stb;
+ long arraysz;
+ DIR *dirp;
+
+ if ((dirp = opendir(dirname)) == NULL)
+ return(-1);
+ if (fstat(dirp->dd_fd, &stb) < 0)
+ return(-1);
+
+ /*
+ * 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)
+ return(-1);
+
+ nitems = 0;
+ 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)
+ return(-1);
+ 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) {
+ if (fstat(dirp->dd_fd, &stb) < 0)
+ return(-1); /* just might have grown */
+ arraysz = stb.st_size / 12;
+ names = (struct dirent **)realloc((char *)names,
+ arraysz * sizeof(struct dirent *));
+ if (names == NULL)
+ return(-1);
+ }
+ names[nitems-1] = p;
+ }
+ closedir(dirp);
+ if (nitems && dcomp != NULL)
+ qsort(names, nitems, sizeof(struct dirent *), dcomp);
+ *namelist = names;
+ return(nitems);
+}
+
+/*
+ * 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..48b4646
--- /dev/null
+++ b/lib/libc/gen/seekdir.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[] = "@(#)seekdir.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <dirent.h>
+
+/*
+ * 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..313a1db
--- /dev/null
+++ b/lib/libc/gen/semctl.c
@@ -0,0 +1,15 @@
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+
+#if __STDC__
+int semctl(int semid, int semnum, int cmd, union semun semun)
+#else
+int semctl(semid, int semnum, cmd, semun)
+ int semid, semnum;
+ int cmd;
+ union semun semun;
+#endif
+{
+ return (semsys(0, semid, semnum, cmd, &semun));
+}
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..6471762
--- /dev/null
+++ b/lib/libc/gen/setdomainname.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[] = "From: @(#)sethostname.c 8.1 (Berkeley) 6/4/93";
+*/
+static const char rcsid[] =
+ "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#if __STDC__
+long
+setdomainname(const char *name, int namelen)
+#else
+long
+setdomainname(name, namelen)
+ char *name;
+ int namelen;
+#endif
+{
+ int mib[2];
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_DOMAINNAME;
+ 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..d62a0fd
--- /dev/null
+++ b/lib/libc/gen/setflags.c
@@ -0,0 +1,150 @@
+/*-
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)stat_flags.c 8.1 (Berkeley) 5/31/93";
+#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");
+ if (flags & UF_NODUMP)
+ SAPPEND("nodump");
+ if (flags & SF_APPEND)
+ SAPPEND("sappnd");
+ if (flags & SF_ARCHIVED)
+ SAPPEND("arch");
+ if (flags & SF_IMMUTABLE)
+ SAPPEND("schg");
+ 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;
+
+ clear = 0;
+ if (setp)
+ *setp = 0;
+ if (clrp)
+ *clrp = 0;
+ string = *stringp;
+ while ((p = strsep(&string, "\t ,")) != NULL) {
+ *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 '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);
+ 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);
+ /* 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..d62a0fd
--- /dev/null
+++ b/lib/libc/gen/setflagsbyname.c
@@ -0,0 +1,150 @@
+/*-
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)stat_flags.c 8.1 (Berkeley) 5/31/93";
+#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");
+ if (flags & UF_NODUMP)
+ SAPPEND("nodump");
+ if (flags & SF_APPEND)
+ SAPPEND("sappnd");
+ if (flags & SF_ARCHIVED)
+ SAPPEND("arch");
+ if (flags & SF_IMMUTABLE)
+ SAPPEND("schg");
+ 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;
+
+ clear = 0;
+ if (setp)
+ *setp = 0;
+ if (clrp)
+ *clrp = 0;
+ string = *stringp;
+ while ((p = strsep(&string, "\t ,")) != NULL) {
+ *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 '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);
+ 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);
+ /* 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..639837e
--- /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__
+long
+sethostname(const char *name, int namelen)
+#else
+long
+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..47cdfa5
--- /dev/null
+++ b/lib/libc/gen/setjmp.3
@@ -0,0 +1,172 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt SETJMP 3
+.Os BSD 4
+.Sh NAME
+.Nm sigsetjmp ,
+.Nm siglongjmp ,
+.Nm setjmp ,
+.Nm longjmp ,
+.Nm _setjmp ,
+.Nm _longjmp 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 sigmask 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 2 ) .
+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..4a236b2
--- /dev/null
+++ b/lib/libc/gen/setmode.3
@@ -0,0 +1,105 @@
+.\" 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.1 (Berkeley) 6/9/93
+.\"
+.Dd June 9, 1993
+.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,
+.Fn setmode
+returns
+.Dv NULL .
+.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 4.4BSD.
diff --git a/lib/libc/gen/setmode.c b/lib/libc/gen/setmode.c
new file mode 100644
index 0000000..c69d775
--- /dev/null
+++ b/lib/libc/gen/setmode.c
@@ -0,0 +1,453 @@
+/*
+ * 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)
+static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94";
+#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(*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 & ~S_IRWXO)
+ perm |= S_ISUID|S_ISGID;
+ break;
+ case 't':
+ /* If only "other" bits ignore sticky. */
+ if (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..5eefe60
--- /dev/null
+++ b/lib/libc/gen/setproctitle.3
@@ -0,0 +1,111 @@
+.\" 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.
+.\"
+.\" $Id: setproctitle.3,v 1.1 1995/12/26 22:50:08 peter Exp $
+.\"
+.\" 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
+#include <libutil.h>
+.Pp
+.Ft void
+.Fn setproctitle "const char *fmt" "..."
+.Pp
+Link with
+.Va -lutil
+on the
+.Xr cc 1
+command line.
+.Sh DESCRIPTION
+The
+.Nm 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 reset to simply the name of the executable.
+.\" The following requests should be uncommented and used where appropriate.
+.\" This next request is for sections 2 and 3 function return values only.
+.\" .Sh RETURN VALUES
+.\" This next request is for sections 1, 6, 7 & 8 only
+.\" .Sh ENVIRONMENT
+.\" .Sh FILES
+.Sh EXAMPLES
+To set the title on a daemon to indicate it's activity:
+.Bd -literal -offset indent
+setproctitle("talking to %s", inet_ntoa(addr));
+.Ed
+.\" This next request is for sections 1, 6, 7 & 8 only
+.\" (command return values (to shell) and fprintf/stderr type diagnostics)
+.\" .Sh DIAGNOSTICS
+.\" The next request is for sections 2 and 3 error and signal handling only.
+.\" .Sh ERRORS
+.Sh SEE ALSO
+.Xr ps 1 ,
+.Xr w 1 ,
+.Xr kvm 3 ,
+.Xr kvm_getargv 3 ,
+.Xr printf 3
+.Sh STANDARDS
+.Nm 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
+.Nm setproctitle
+if present.
+.Pp
+Unfortunately, it is possible that there are other calling conventions
+to other versions of
+.Nm 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 compatable with other systems,
+including
+.Nm NetBSD
+and
+.Nm BSD/OS .
+.Sh HISTORY
+.Nm setproctitle
+first appeared in FreeBSD at version 2.2. Other operating systems have
+similar functions.
+.Sh AUTHORS
+.Nm Peter Wemm <peter@FreeBSD.org>
+stole the idea from the
+.Nm Sendmail 8.7.3
+source code by
+.Nm Eric Allman <eric@sendmail.org> .
+.\" .Sh BUGS
diff --git a/lib/libc/gen/setproctitle.c b/lib/libc/gen/setproctitle.c
new file mode 100644
index 0000000..2faf976
--- /dev/null
+++ b/lib/libc/gen/setproctitle.c
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/exec.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.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
+{
+ char *p;
+ int len;
+ static char buf[SPT_BUFSIZE];
+ static char *ps_argv[2];
+ va_list ap;
+
+#if defined(__STDC__)
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+
+ buf[sizeof(buf) - 1] = '\0';
+ if (fmt) {
+
+ /* print program name heading for grep */
+ (void) snprintf(buf, sizeof(buf) - 1, "%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) - 1 - len, fmt, ap);
+ } else {
+ /* Idea from NetBSD - reset the title on fmt == NULL */
+ strncpy(buf, __progname, sizeof(buf) - 1);
+ }
+
+ va_end(ap);
+
+ /* PS_STRINGS points to zeroed memory on a style #2 kernel */
+ if (PS_STRINGS->ps_argvstr) {
+ /* style #3 */
+ ps_argv[0] = buf;
+ ps_argv[1] = NULL;
+ PS_STRINGS->ps_nargvstr = 1;
+ PS_STRINGS->ps_argvstr = ps_argv;
+ } else {
+ /* style #2 */
+ OLD_PS_STRINGS->old_ps_nargvstr = 1;
+ OLD_PS_STRINGS->old_ps_argvstr = buf;
+ }
+}
diff --git a/lib/libc/gen/shmat.c b/lib/libc/gen/shmat.c
new file mode 100644
index 0000000..b38a6a5
--- /dev/null
+++ b/lib/libc/gen/shmat.c
@@ -0,0 +1,19 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$Id: shmat.c,v 1.2 1993/10/10 12:01:26 rgrimes Exp $";
+#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..1bb384c
--- /dev/null
+++ b/lib/libc/gen/shmctl.c
@@ -0,0 +1,19 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$Id: shmctl.c,v 1.2 1993/10/10 12:01:28 rgrimes Exp $";
+#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..fde6078
--- /dev/null
+++ b/lib/libc/gen/shmdt.c
@@ -0,0 +1,17 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$Id: shmdt.c,v 1.2 1993/10/10 12:01:29 rgrimes Exp $";
+#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..455ea88
--- /dev/null
+++ b/lib/libc/gen/shmget.c
@@ -0,0 +1,19 @@
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$Id: shmget.c,v 1.1 1993/09/27 00:57:49 rgrimes Exp $";
+#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..1dadb28
--- /dev/null
+++ b/lib/libc/gen/siginterrupt.3
@@ -0,0 +1,106 @@
+.\" 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
+.\"
+.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 is the default behavior on
+.Bx 4.2 .
+.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 .
+.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..3105d13
--- /dev/null
+++ b/lib/libc/gen/siginterrupt.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[] = "@(#)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.
+ */
+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..be6334d
--- /dev/null
+++ b/lib/libc/gen/siglist.c
@@ -0,0 +1,109 @@
+/*
+ * 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 */
+};
diff --git a/lib/libc/gen/signal.3 b/lib/libc/gen/signal.3
new file mode 100644
index 0000000..86189f1
--- /dev/null
+++ b/lib/libc/gen/signal.3
@@ -0,0 +1,222 @@
+.\" 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
+.\"
+.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>
+.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 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 2
+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" " system call given invalid argument"
+.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
+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 with 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).
+.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, \-1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Xr 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 ptrace 2 ,
+.Xr kill 2 ,
+.Xr sigaction 2 ,
+.Xr sigaltstack 2 ,
+.Xr sigprocmask 2 ,
+.Xr sigsuspend 2 ,
+.Xr setjmp 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..b62253e
--- /dev/null
+++ b/lib/libc/gen/sigsetops.3
@@ -0,0 +1,108 @@
+.\" 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
+.\"
+.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>
+.Fn sigemptyset "sigset_t *set"
+.Fn sigfillset "sigset_t *set"
+.Fn sigaddset "sigset_t *set" "int signo"
+.Fn sigdelset "sigset_t *set" "int signo"
+.Fn sigismember "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..e6acb77
--- /dev/null
+++ b/lib/libc/gen/sigsetops.c
@@ -0,0 +1,83 @@
+/*-
+ * 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)
+static char sccsid[] = "@(#)sigsetops.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <signal.h>
+
+#undef sigemptyset
+#undef sigfillset
+#undef sigaddset
+#undef sigdelset
+#undef sigismember
+
+sigemptyset(set)
+ sigset_t *set;
+{
+ *set = 0;
+ return (0);
+}
+
+sigfillset(set)
+ sigset_t *set;
+{
+ *set = ~(sigset_t)0;
+ return (0);
+}
+
+sigaddset(set, signo)
+ sigset_t *set;
+ int signo;
+{
+ *set |= sigmask(signo);
+ return (0);
+}
+
+sigdelset(set, signo)
+ sigset_t *set;
+ int signo;
+{
+ *set &= ~sigmask(signo);
+ return (0);
+}
+
+sigismember(set, signo)
+ const sigset_t *set;
+ int signo;
+{
+ return ((*set & ~sigmask(signo)) != 0);
+}
diff --git a/lib/libc/gen/sleep.3 b/lib/libc/gen/sleep.3
new file mode 100644
index 0000000..9e3c797
--- /dev/null
+++ b/lib/libc/gen/sleep.3
@@ -0,0 +1,83 @@
+.\" 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 June 4, 1993
+.Dt SLEEP 3
+.Os
+.Sh NAME
+.Nm sleep
+.Nd suspend process execution for interval of seconds
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft u_int
+.Fn sleep "u_int seconds"
+.Sh DESCRIPTION
+The
+.Fn sleep
+function
+suspends execution of the calling process
+for
+.Fa seconds
+of time.
+System activity or time spent in processing the
+call may lengthen the sleep by a second.
+.Pp
+If a timer is already running on the process its state is saved.
+If the value
+.Fa seconds
+is more than or equal to the remaining clock time for the saved timer,
+the sleep time is set to
+the remaining clock time.
+The state of the previous timer
+is restored after
+.Fa seconds
+has passed.
+.Pp
+This function is implemented using
+.Xr setitimer 2 ;
+it requires eight system calls each time it is invoked.
+A similar but less compatible function can be obtained with a single
+.Xr select 2 ;
+such a function would not restart after signals, but would not interfere
+with other uses of
+.Xr setitimer .
+.Sh RETURN VALUES
+.Sh SEE ALSO
+.Xr setitimer 2 ,
+.Xr sigpause 2 ,
+.Xr usleep 3
+.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..98d997d
--- /dev/null
+++ b/lib/libc/gen/sleep.c
@@ -0,0 +1,97 @@
+/*
+ * 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[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/time.h>
+#include <signal.h>
+#include <unistd.h>
+
+#define setvec(vec, a) \
+ vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0
+
+static int ringring;
+
+unsigned int
+sleep(seconds)
+ unsigned int seconds;
+{
+ register struct itimerval *itp;
+ struct itimerval itv, oitv;
+ struct sigvec vec, ovec;
+ long omask;
+ static void sleephandler();
+
+ itp = &itv;
+ if (!seconds)
+ return 0;
+ timerclear(&itp->it_interval);
+ timerclear(&itp->it_value);
+ if (setitimer(ITIMER_REAL, itp, &oitv) < 0)
+ return seconds;
+ itp->it_value.tv_sec = seconds;
+ if (timerisset(&oitv.it_value)) {
+ if (timercmp(&oitv.it_value, &itp->it_value, >))
+ oitv.it_value.tv_sec -= itp->it_value.tv_sec;
+ else {
+ itp->it_value = oitv.it_value;
+ /*
+ * This is a hack, but we must have time to return
+ * from the setitimer after the alarm or else it'll
+ * be restarted. And, anyway, sleep never did
+ * anything more than this before.
+ */
+ oitv.it_value.tv_sec = 1;
+ oitv.it_value.tv_usec = 0;
+ }
+ }
+ setvec(vec, sleephandler);
+ (void) sigvec(SIGALRM, &vec, &ovec);
+ omask = sigblock(sigmask(SIGALRM));
+ ringring = 0;
+ (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0);
+ while (!ringring)
+ sigpause(omask &~ sigmask(SIGALRM));
+ (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0);
+ (void) sigsetmask(omask);
+ (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0);
+ return 0;
+}
+
+static void
+sleephandler()
+{
+ ringring = 1;
+}
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/strtofflags.c b/lib/libc/gen/strtofflags.c
new file mode 100644
index 0000000..d62a0fd
--- /dev/null
+++ b/lib/libc/gen/strtofflags.c
@@ -0,0 +1,150 @@
+/*-
+ * 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.
+ *
+ * $Id$
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)stat_flags.c 8.1 (Berkeley) 5/31/93";
+#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");
+ if (flags & UF_NODUMP)
+ SAPPEND("nodump");
+ if (flags & SF_APPEND)
+ SAPPEND("sappnd");
+ if (flags & SF_ARCHIVED)
+ SAPPEND("arch");
+ if (flags & SF_IMMUTABLE)
+ SAPPEND("schg");
+ 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;
+
+ clear = 0;
+ if (setp)
+ *setp = 0;
+ if (clrp)
+ *clrp = 0;
+ string = *stringp;
+ while ((p = strsep(&string, "\t ,")) != NULL) {
+ *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 '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);
+ 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);
+ /* 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..53622f6
--- /dev/null
+++ b/lib/libc/gen/sysconf.3
@@ -0,0 +1,184 @@
+.\" 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
+.\"
+.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 exec 2 .
+.It Li _SC_CHILD_MAX
+The maximum number of simultaneous processes per user id.
+.It Li _SC_CLK_TCK
+Number of micro-seconds per hz tick.
+.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
+.Nm 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
+The
+.Fn sysconf
+function conforms to
+.St -p1003.1-88 .
+.Sh HISTORY
+The
+.Nm sysconf
+function first appeared in 4.4BSD.
diff --git a/lib/libc/gen/sysconf.c b/lib/libc/gen/sysconf.c
new file mode 100644
index 0000000..16a3efa
--- /dev/null
+++ b/lib/libc/gen/sysconf.c
@@ -0,0 +1,188 @@
+/*-
+ * 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/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;
+
+ len = sizeof(value);
+
+ 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;
+yesno: if (sysctl(mib, 2, &value, &len, NULL, 0) == -1)
+ return (-1);
+ if (value == 0)
+ return (-1);
+ 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..a7cffcf
--- /dev/null
+++ b/lib/libc/gen/sysctl.3
@@ -0,0 +1,652 @@
+.\" 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.1 (Berkeley) 6/4/93
+.\"
+.Dd "June 4, 1993"
+.Dt SYSCTL 3
+.Os
+.Sh NAME
+.Nm sysctl
+.Nd get or set system information
+.Sh SYNOPSIS
+.Fd #include <sys/sysctl.h>
+.Ft int
+.Fn sysctl "int *name" "u_int namelen" "void *oldp" "size_t *oldlenp" "void *newp" "size_t newlen"
+.Sh DESCRIPTION
+The
+.Nm sysctl
+function retrieves system information and allows processes with
+appropriate privileges to set system information.
+The information available from
+.Nm sysctl
+consists of integers, strings, and tables.
+Information may be retrieved and set from the command interface
+using the
+.Xr sysctl 1
+utility.
+.Pp
+Unless explicitly noted below,
+.Nm 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
+.Nm 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 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.
+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
+.Nm 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\_FS sys/sysctl.h File system
+.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:
+.Bd -literal -offset indent -compact
+int mib[2], maxproc;
+size_t len;
+.sp
+mib[0] = CTL_KERN;
+mib[1] = KERN_MAXPROC;
+len = sizeof(maxproc);
+sysctl(mib, 2, &maxproc, &len, NULL, 0);
+.Ed
+.sp
+To retrieve the standard search path for the system utilities:
+.Bd -literal -offset indent -compact
+int mib[2];
+size_t len;
+char *p;
+.sp
+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
+.Nm sysctl
+to know about it.
+Each time it runs,
+.Nm 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_FS
+There are currently no second level names for the file system.
+.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\_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.
+.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 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 "KERNXCHOWNXRESTRICTEDXXX" "struct clockrateXXX" -offset indent
+.It Sy Pa Second level name Type Changeable
+.It KERN\_ARGMAX integer no
+.It KERN\_BOOTTIME struct timeval no
+.It KERN\_CHOWN\_RESTRICTED integer 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\_LINK\_MAX integer no
+.It KERN\_MAXFILES integer yes
+.It KERN\_MAXPROC integer yes
+.It KERN\_MAXVNODES integer yes
+.It KERN\_MAX\_CANON integer no
+.It KERN\_MAX\_INPUT integer no
+.It KERN\_NAME\_MAX integer no
+.It KERN\_NGROUPS integer no
+.It KERN\_NO\_TRUNC integer no
+.It KERN\_OSRELEASE string no
+.It KERN\_OSREV integer no
+.It KERN\_OSTYPE string no
+.It KERN\_PATH\_MAX integer no
+.It KERN\_PIPE\_BUF integer 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\_VDISABLE integer no
+.It KERN\_VERSION string no
+.It KERN\_VNODE struct vnode no
+.El
+.Pp
+.Bl -tag -width "123456"
+.It Li KERN_ARGMAX
+The maximum bytes of argument to
+.Xr exec 2 .
+.It Li KERN_BOOTTIME
+A
+.Va struct timeval
+structure is returned.
+This structure contains the time that the system was booted.
+.It Li KERN_CHOWN_RESTRICTED
+Return 1 if appropriate privileges are required for the
+.Xr chown 2
+system call, otherwise 0.
+.It Li KERN_CLOCKRATE
+A
+.Va struct clockinfo
+structure is returned.
+This structure contains the clock, statistics clock and profiling clock
+frequencies, and the number of micro-seconds per hz tick.
+.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_LINK_MAX
+The maximum file link count.
+.It Li KERN_MAXFILES
+The maximum number of open files that may be open in the system.
+.It Li KERN_MAXPROC
+The maximum number of simultaneous processes the system will allow.
+.It Li KERN_MAXVNODES
+The maximum number of vnodes available on the system.
+.It Li KERN_MAX_CANON
+The maximum number of bytes in terminal canonical input line.
+.It Li KERN_MAX_INPUT
+The minimum maximum number of bytes for which space is available in
+a terminal input queue.
+.It Li KERN_NAME_MAX
+The maximum number of bytes in a file name.
+.It Li KERN_NGROUPS
+The maximum number of supplemental groups.
+.It Li KERN_NO_TRUNC
+Return 1 if file names longer than KERN_NAME_MAX are truncated.
+.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_PATH_MAX
+The maximum number of bytes in a pathname.
+.It Li KERN_PIPE_BUF
+The maximum number of bytes which will be written atomically to a pipe.
+.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
+.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 only be lowered by process 1.
+.It Li KERN_VDISABLE
+Returns the terminal character disabling value.
+.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 .
+.El
+.Sh CTL_MACHDEP
+The set of variables defined is architecture dependent.
+Most architectures define at least the following variables.
+.Bl -column "CONSOLE_DEVICEXXX" "integerXXX" -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
+.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:
+.Bl -column "Protocol nameXXXXXX" "Variable nameXXX" "integerXXX" -offset indent
+.It Pa Protocol name Variable name Type Changeable
+.It ip forwarding integer yes
+.It ip redirect integer yes
+.It ip ttl integer yes
+.It icmp maskrepl integer yes
+.It udp checksum integer yes
+.El
+.Pp
+The variables are as follows:
+.Bl -tag -width "123456"
+.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 icmp.maskrepl
+Returns 1 if ICMP network mask requests are to be answered.
+.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.
+.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
+.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 .
+.El
+.Sh RETURN VALUES
+If the call to
+.Nm sysctl
+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 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 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 sysctl 8
+.Sh HISTORY
+The
+.Nm sysctl
+function first appeared in 4.4BSD.
diff --git a/lib/libc/gen/sysctl.c b/lib/libc/gen/sysctl.c
new file mode 100644
index 0000000..cb7448a
--- /dev/null
+++ b/lib/libc/gen/sysctl.c
@@ -0,0 +1,178 @@
+/*-
+ * 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))
+ return (ENOMEM);
+ *oldlenp = sizeof(_PATH_STDPATH);
+ if (oldp != NULL)
+ memmove(oldp, _PATH_STDPATH, sizeof(_PATH_STDPATH));
+ return (0);
+ }
+
+ if (oldp && *oldlenp < sizeof(int))
+ return (ENOMEM);
+ *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/syslog.3 b/lib/libc/gen/syslog.3
new file mode 100644
index 0000000..8a46d05
--- /dev/null
+++ b/lib/libc/gen/syslog.3
@@ -0,0 +1,263 @@
+.\" 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
+.\"
+.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
+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
+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 clock daemon.
+.It Dv LOG_DAEMON
+System daemons, such as
+.Xr routed 8 ,
+that are not provided for explicitly by other facilities.
+.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_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.
+.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_DAEMON);
+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..1ef9a66
--- /dev/null
+++ b/lib/libc/gen/syslog.c
@@ -0,0 +1,312 @@
+/*
+ * 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[] = "From: @(#)syslog.c 8.4 (Berkeley) 3/18/94";
+*/
+static const char rcsid[] =
+ "$Id: syslog.c,v 1.6 1995/10/21 07:05:01 peter Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/syslog.h>
+#include <sys/uio.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 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. */
+
+/*
+ * 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 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 (!connected)
+ openlog(LogTag, LogStat | LOG_NDELAY, 0);
+ 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 struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
+
+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 (LogFile == -1) {
+ SyslogAddr.sa_family = AF_UNIX;
+ (void)strncpy(SyslogAddr.sa_data, _PATH_LOG,
+ sizeof(SyslogAddr.sa_data));
+ if (LogStat & LOG_NDELAY) {
+ if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
+ return;
+ (void)fcntl(LogFile, F_SETFD, 1);
+ }
+ }
+ if (LogFile != -1 && !connected)
+ if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) {
+ (void)close(LogFile);
+ LogFile = -1;
+ } else
+ connected = 1;
+}
+
+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..e97c256
--- /dev/null
+++ b/lib/libc/gen/tcgetpgrp.3
@@ -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.
+.\"
+.\" @(#)tcgetpgrp.3 8.1 (Berkeley) 6/4/93
+.\"
+.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
+.Nm 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,
+.Nm tcgetpgrp
+returns an invalid process ID.
+.Sh ERRORS
+If an error occurs,
+.Nm 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 3 ,
+.Xr setsid 2 ,
+.Xr tcsetpgrp 3
+.Sh STANDARDS
+The
+.Nm 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..2ff9ece
--- /dev/null
+++ b/lib/libc/gen/tcsendbreak.3
@@ -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.
+.\"
+.\" @(#)tcsendbreak.3 8.1 (Berkeley) 6/4/93
+.\"
+.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
+.Nm tcdrain
+function waits until all output written to the terminal referenced by
+.Fa fd
+has been transmitted to the terminal.
+.Pp
+The
+.Nm 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
+.Nm 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
+.Nm 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
+.Nm tcdrain
+function.
+.El
+.Sh SEE ALSO
+.Xr tcsetattr 3 ,
+.Xr termios 4
+.Sh STANDARDS
+The
+.Nm tcsendbreak ,
+.Nm tcdrain ,
+.Nm tcflush
+and
+.Nm 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..d3b2b4f
--- /dev/null
+++ b/lib/libc/gen/tcsetattr.3
@@ -0,0 +1,330 @@
+.\" 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
+.\"
+.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 "struct termios *t"
+.Ft int
+.Fn cfsetispeed "struct termios *t" "speed_t speed"
+.Ft speed_t
+.Fn cfgetospeed "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" "struct termios *t"
+.Sh DESCRIPTION
+The
+.Nm cfmakeraw ,
+.Nm tcgetattr
+and
+.Nm tcsetattr
+functions are provided for getting and setting the termios structure.
+.Pp
+The
+.Nm cfgetispeed ,
+.Nm cfsetispeed ,
+.Nm cfgetospeed ,
+.Nm cfsetospeed
+and
+.Nm 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
+.Nm tcsetattr
+function is called.
+Certain values for baud rates set in the termios structure and passed to
+.Nm tcsetattr
+have special meanings.
+These are discussed in the portion of the manual page that describes the
+.Nm 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
+.Nm cfgetispeed
+function returns the input baud rate in the termios structure referenced by
+.Fa tp .
+.Pp
+The
+.Nm cfsetispeed
+function sets the input baud rate in the termios structure referenced by
+.Fa tp
+to
+.Fa speed .
+.Pp
+The
+.Nm cfgetospeed
+function returns the output baud rate in the termios structure referenced by
+.Fa tp .
+.Pp
+The
+.Nm cfsetospeed
+function sets the output baud rate in the termios structure referenced by
+.Fa tp
+to
+.Fa speed .
+.Pp
+The
+.Nm 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
+.Nm cfsetispeed ,
+.Nm cfsetospeed ,
+and
+.Nm 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
+.Nm 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
+.Nm tcgetattr ,
+setting raw mode with
+.Nm cfmakeraw
+and the subsequent
+.Nm tcsetattr ,
+and then using another
+.Nm tcsetattr
+with the saved state to revert to the previous terminal state.
+.Pp
+The
+.Nm 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
+.Nm 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
+.Nm 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
+.Nm tcsetattr ,
+the input baud rate will be set to the same value as that specified by
+the output baud rate.
+.Pp
+If
+.Nm 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
+.Nm tcgetattr
+and
+.Nm 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
+.Nm tcgetattr
+or
+.Nm tcsetattr
+was not a valid file descriptor.
+.It Bq Er EINTR
+The
+.Nm tcsetattr
+function was interrupted by a signal.
+.It Bq Er EINVAL
+The
+.Fa action
+argument to the
+.Nm 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
+.Nm tcgetattr
+or
+.Nm tcsetattr
+is not a terminal.
+.El
+.Sh SEE ALSO
+.Xr tcsendbreak 3 ,
+.Xr termios 4
+.Sh STANDARDS
+The
+.Nm cfgetispeed ,
+.Nm cfsetispeed ,
+.Nm cfgetospeed ,
+.Nm cfsetospeed ,
+.Nm tcgetattr
+and
+.Nm tcsetattr
+functions are expected to be compliant with the
+.St -p1003.1-88
+specification.
+The
+.Nm cfmakeraw
+and
+.Nm cfsetspeed
+functions,
+as well as the
+.Li TCSASOFT
+option to the
+.Nm 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..e1f8af0
--- /dev/null
+++ b/lib/libc/gen/tcsetpgrp.3
@@ -0,0 +1,100 @@
+.\" 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
+.\"
+.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 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 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 3 ,
+.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..3625ae0
--- /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;
+ 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..6283393
--- /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
+.\"
+.Dd June 4, 1993
+.Dt TIME 3
+.Os BSD 4
+.Sh NAME
+.Nm time
+.Nd get time of day
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.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..93207b1
--- /dev/null
+++ b/lib/libc/gen/times.3
@@ -0,0 +1,136 @@
+.\" 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
+.\"
+.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
+.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..68adeb9
--- /dev/null
+++ b/lib/libc/gen/timezone.3
@@ -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.
+.\"
+.\" @(#)timezone.3 8.2 (Berkeley) 4/19/94
+.\"
+.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..370493b
--- /dev/null
+++ b/lib/libc/gen/timezone.c
@@ -0,0 +1,134 @@
+/*
+ * 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)sprintf(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..742de5f
--- /dev/null
+++ b/lib/libc/gen/ttyname.3
@@ -0,0 +1,126 @@
+.\" 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
+.\"
+.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
+.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..f024f52
--- /dev/null
+++ b/lib/libc/gen/ttyname.c
@@ -0,0 +1,112 @@
+/*
+ * 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 <termios.h>
+#include <db.h>
+#include <string.h>
+#include <paths.h>
+
+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);
+}
diff --git a/lib/libc/gen/ttyslot.c b/lib/libc/gen/ttyslot.c
new file mode 100644
index 0000000..066f2f9
--- /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..d9606c5
--- /dev/null
+++ b/lib/libc/gen/tzset.3
@@ -0,0 +1,324 @@
+.\" 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
+.\"
+.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
+.Nm tzset
+and
+.Nm tzsetwall
+functions first appeared in 4.4BSD.
diff --git a/lib/libc/gen/ualarm.3 b/lib/libc/gen/ualarm.3
new file mode 100644
index 0000000..666029a
--- /dev/null
+++ b/lib/libc/gen/ualarm.3
@@ -0,0 +1,90 @@
+.\" 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.
+.\"
+.\" @(#)ualarm.3 8.2 (Berkeley) 4/19/94
+.\"
+.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).
+.Sh RETURN VALUES
+When the signal has successfully been caught,
+.Fn alarm
+returns the amount of time left on the clock.
+The maximum number of
+.Ar microseconds
+allowed
+is 2147483647.
+.Sh SEE ALSO
+.Xr getitimer 2 ,
+.Xr setitimer 2 ,
+.Xr sigpause 2 ,
+.Xr sigvec 2 ,
+.Xr signal 3 ,
+.Xr sleep 3 ,
+.Xr alarm 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..a72e21f
--- /dev/null
+++ b/lib/libc/gen/uname.3
@@ -0,0 +1,92 @@
+.\" 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
+.\"
+.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
+.Nm 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
+.Nm uname
+function first appeared in 4.4BSD.
diff --git a/lib/libc/gen/uname.c b/lib/libc/gen/uname.c
new file mode 100644
index 0000000..93f659e
--- /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[] =
+ "$Id: uname.c,v 1.3 1995/05/30 05:40:29 rgrimes Exp $";
+#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..807a851
--- /dev/null
+++ b/lib/libc/gen/unvis.3
@@ -0,0 +1,162 @@
+.\" 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
+.\"
+.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 "u_char *cp" "u_char c" "int *astate" "int flag"
+.Ft int
+.Fn strunvis "char *dst" "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
+.Xr 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 4.4BSD.
diff --git a/lib/libc/gen/unvis.c b/lib/libc/gen/unvis.c
new file mode 100644
index 0000000..ebeb771
--- /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..630e386
--- /dev/null
+++ b/lib/libc/gen/usleep.3
@@ -0,0 +1,85 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt USLEEP 3
+.Os BSD 4.3
+.Sh NAME
+.Nm usleep
+.Nd suspend execution for interval of microseconds
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft void
+.Fn usleep "u_int microseconds"
+.Sh DESCRIPTION
+The
+.Fn usleep
+function
+suspends execution of the calling process
+for
+.Fa microseconds
+of time.
+System activity or time spent in processing the
+call may lengthen the sleep slightly.
+.Pp
+If a timer is already running on the process its state is saved.
+If the value
+.Fa microseconds
+is more than or equal to the remaining clock time for the saved timer,
+the sleep time is set to
+the remaining clock time.
+The state of the previous timer
+is restored after
+.Fa microseconds
+has passed.
+.Pp
+This routine is implemented using
+.Xr setitimer 2 ;
+it requires eight system calls each time it is invoked.
+A similar but less compatible function can be obtained with a single
+.Xr select 2 ;
+such a function would not restart after signals, but would not interfere
+with other uses of
+.Xr setitimer .
+.Sh SEE ALSO
+.Xr setitimer 2 ,
+.Xr getitimer 2 ,
+.Xr sigpause 2 ,
+.Xr ualarm 3 ,
+.Xr sleep 3 ,
+.Xr alarm 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..3f4a7f5
--- /dev/null
+++ b/lib/libc/gen/usleep.c
@@ -0,0 +1,99 @@
+/*
+ * 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[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/time.h>
+#include <signal.h>
+#include <unistd.h>
+
+#define TICK 10000 /* system clock resolution in microseconds */
+#define USPS 1000000 /* number of microseconds in a second */
+
+#define setvec(vec, a) \
+ vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0
+
+static int ringring;
+
+void
+usleep(useconds)
+ unsigned int useconds;
+{
+ register struct itimerval *itp;
+ struct itimerval itv, oitv;
+ struct sigvec vec, ovec;
+ long omask;
+ static void sleephandler();
+
+ itp = &itv;
+ if (!useconds)
+ return;
+ timerclear(&itp->it_interval);
+ timerclear(&itp->it_value);
+ if (setitimer(ITIMER_REAL, itp, &oitv) < 0)
+ return;
+ itp->it_value.tv_sec = useconds / USPS;
+ itp->it_value.tv_usec = useconds % USPS;
+ if (timerisset(&oitv.it_value)) {
+ if (timercmp(&oitv.it_value, &itp->it_value, >)) {
+ oitv.it_value.tv_sec -= itp->it_value.tv_sec;
+ oitv.it_value.tv_usec -= itp->it_value.tv_usec;
+ if (oitv.it_value.tv_usec < 0) {
+ oitv.it_value.tv_usec += USPS;
+ oitv.it_value.tv_sec--;
+ }
+ } else {
+ itp->it_value = oitv.it_value;
+ oitv.it_value.tv_sec = 0;
+ oitv.it_value.tv_usec = 2 * TICK;
+ }
+ }
+ setvec(vec, sleephandler);
+ (void) sigvec(SIGALRM, &vec, &ovec);
+ omask = sigblock(sigmask(SIGALRM));
+ ringring = 0;
+ (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0);
+ while (!ringring)
+ sigpause(omask &~ sigmask(SIGALRM));
+ (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0);
+ (void) sigsetmask(omask);
+ (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0);
+}
+
+static void
+sleephandler()
+{
+ ringring = 1;
+}
diff --git a/lib/libc/gen/utime.3 b/lib/libc/gen/utime.3
new file mode 100644
index 0000000..3397bb7
--- /dev/null
+++ b/lib/libc/gen/utime.3
@@ -0,0 +1,87 @@
+.\" 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
+.\"
+.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 utimes 2 ,
+.Xr stat 2
+.Sh HISTORY
+A
+.Fn utime
+function appeared in
+.At v7 .
+.Sh STANDARDS
+The
+.Nm 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..c428552
--- /dev/null
+++ b/lib/libc/gen/valloc.3
@@ -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.
+.\"
+.\" @(#)valloc.3 8.1 (Berkeley) 6/4/93
+.\"
+.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 char *
+.Fn valloc "unsigned 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..ec6e2e8
--- /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;
+{
+ int valsiz = getpagesize(), j;
+ void *cp = malloc(i + (valsiz-1));
+
+ j = ((int)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..ee77b72
--- /dev/null
+++ b/lib/libc/gen/vis.3
@@ -0,0 +1,263 @@
+.\" 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.
+.\"
+.\" @(#)vis.3 8.1 (Berkeley) 6/9/93
+.\"
+.Dd June 9, 1993
+.Dt VIS 3
+.Os
+.Sh NAME
+.Nm vis
+.Nd visually encode characters
+.Sh SYNOPSIS
+.Fd #include <vis.h>
+.Ft char *
+.Fn vis "char *dst" "char c" "int flag" "char nextc"
+.Ft int
+.Fn strvis "char *dst" "char *src" "int flag"
+.Ft int
+.Fn strvisx "char *dst" "char *src" "int 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 NULL ) ;
+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 NULL .
+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 NULL .
+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 NULL Ns 's).
+Both forms
+.Dv NULL
+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 NULL ) .
+Both
+forms return the number of characters in dst (not including
+the trailing
+.Dv NULL ) .
+.Pp
+The encoding is a unique, invertible representation comprised 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 NULL
+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 unvis 3
+.Xr strunvis 3
+.Sh HISTORY
+These functions first appeared in 4.4BSD.
+
diff --git a/lib/libc/gen/vis.c b/lib/libc/gen/vis.c
new file mode 100644
index 0000000..066ea2d
--- /dev/null
+++ b/lib/libc/gen/vis.c
@@ -0,0 +1,186 @@
+/*-
+ * 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;
+{
+ 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..57dc293
--- /dev/null
+++ b/lib/libc/gmon/Makefile.inc
@@ -0,0 +1,12 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+
+# gmon sources
+.PATH: ${.CURDIR}/gmon
+
+SRCS+= gmon.c mcount.c
+MAN3+= gmon/moncontrol.3
+MLINKS+= moncontrol.3 monstartup.3
+
+# 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..572b7eb
--- /dev/null
+++ b/lib/libc/gmon/gmon.c
@@ -0,0 +1,254 @@
+/*-
+ * 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 <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+extern char *minbrk asm ("minbrk");
+
+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;
+ 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);
+ fd = open("gmon.out", O_CREAT|O_TRUNC|O_WRONLY, 0666);
+ if (fd < 0) {
+ perror("mcount: gmon.out");
+ return;
+ }
+#ifdef DEBUG
+ log = open("gmon.log", O_CREAT|O_TRUNC|O_WRONLY, 0664);
+ if (log < 0) {
+ perror("mcount: 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, (int)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..b0c4072
--- /dev/null
+++ b/lib/libc/gmon/mcount.c
@@ -0,0 +1,326 @@
+/*-
+ * 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[] =
+ "$Id$";
+#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 fptrint_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
+ register int s; /* XXX */
+ u_long save_eflags; /* XXX */
+#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;
+#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
+ >= (fptrint_t)(VM_MAXUSER_ADDRESS + UPAGES * NBPG))
+ goto done;
+ frompci = (fptrint_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 ((fptrint_t)selfpc >= (fptrint_t)btrap
+ && (fptrint_t)selfpc < (fptrint_t)eintr) {
+ if ((fptrint_t)selfpc >= (fptrint_t)bintr)
+ frompci = (fptrint_t)bintr - p->lowpc;
+ else
+ frompci = (fptrint_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;
+#else
+ p->state = GMON_PROF_ON;
+#endif
+ return;
+overflow:
+ p->state = GMON_PROF_ERROR;
+#ifdef KERNEL
+ MCOUNT_EXIT;
+#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)
+ fptrint_t selfpc;
+{
+ struct gmonparam *p;
+ fptrint_t selfpcdiff;
+
+ p = &_gmonparam;
+ selfpcdiff = selfpc - (fptrint_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..9b01f2b
--- /dev/null
+++ b/lib/libc/gmon/moncontrol.3
@@ -0,0 +1,101 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt MONCONTROL 3
+.Os BSD 4
+.Sh NAME
+.Nm moncontrol ,
+.Nm monstartup
+.Nd control execution profile
+.Sh SYNOPSIS
+.Fn moncontrol "int mode"
+.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 gmon.out ,
+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 gmon.out execution data file
+.El
+.Sh SEE ALSO
+.Xr cc 1 ,
+.Xr gprof 1 ,
+.Xr profil 2
diff --git a/lib/libc/i386/DEFS.h b/lib/libc/i386/DEFS.h
new file mode 100644
index 0000000..6df18a1
--- /dev/null
+++ b/lib/libc/i386/DEFS.h
@@ -0,0 +1,83 @@
+/*-
+ * 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
+ *
+ * $Id: DEFS.h,v 1.4 1994/05/03 16:29:13 jkh Exp $
+ */
+
+/* XXX should use align 4,0x90 for -m486. */
+#define _START_ENTRY .align 2,0x90;
+#if 0
+/* Data is not used, except perhaps by non-g prof, which we don't support. */
+#define _MID_ENTRY .data; .align 2; 8:; .long 0; \
+ .text; lea 8b,%eax;
+#else
+#define _MID_ENTRY
+#endif
+
+#ifdef PROF
+
+#define ALTENTRY(x) _START_ENTRY \
+ .globl _/**/x; .type _/**/x,@function; _/**/x:; \
+ _MID_ENTRY \
+ call mcount; jmp 9f
+
+#define ENTRY(x) _START_ENTRY \
+ .globl _/**/x; .type _/**/x,@function; _/**/x:; \
+ _MID_ENTRY \
+ call mcount; 9:
+
+
+#define ALTASENTRY(x) _START_ENTRY \
+ .globl x; .type x,@function; x:; \
+ _MID_ENTRY \
+ call mcount; jmp 9f
+
+#define ASENTRY(x) _START_ENTRY \
+ .globl x; .type x,@function; x:; \
+ _MID_ENTRY \
+ call mcount; 9:
+
+#else /* !PROF */
+
+#define ENTRY(x) _START_ENTRY .globl _/**/x; .type _/**/x,@function; \
+ _/**/x:
+#define ALTENTRY(x) ENTRY(x)
+
+#define ASENTRY(x) _START_ENTRY .globl x; .type x,@function; x:
+#define ALTASENTRY(x) ASENTRY(x)
+
+#endif
diff --git a/lib/libc/i386/SYS.h b/lib/libc/i386/SYS.h
new file mode 100644
index 0000000..53837ab
--- /dev/null
+++ b/lib/libc/i386/SYS.h
@@ -0,0 +1,73 @@
+/*-
+ * 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
+ *
+ * $Id: SYS.h,v 1.3 1993/11/04 00:01:17 paul Exp $
+ */
+
+#include <sys/syscall.h>
+#include "DEFS.h"
+
+#ifdef PIC
+#define PIC_PROLOGUE \
+ pushl %ebx; \
+ call 1f; \
+1: \
+ popl %ebx; \
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+#define PIC_EPILOGUE \
+ popl %ebx
+#define PIC_PLT(x) x@PLT
+#define PIC_GOT(x) x@GOT(%ebx)
+#define PIC_GOTOFF(x) x@GOTOFF(%ebx)
+#else
+#define PIC_PROLOGUE
+#define PIC_EPILOGUE
+#define PIC_PLT(x) x
+#define PIC_GOT(x) x
+#define PIC_GOTOFF(x) x
+#endif
+
+#define SYSCALL(x) 2: jmp cerror; ENTRY(x); lea SYS_/**/x,%eax; LCALL(7,0); jb 2b
+#define RSYSCALL(x) SYSCALL(x); ret
+#define PSEUDO(x,y) ENTRY(x); lea SYS_/**/y, %eax; ; LCALL(7,0); ret
+#define CALL(x,y) call _/**/y; addl $4*x,%esp
+/* gas fucks up offset -- although we don't currently need it, do for BCS */
+#define LCALL(x,y) .byte 0x9a ; .long y; .word x
+
+#define ASMSTR .asciz
+
+ .globl cerror
diff --git a/lib/libc/i386/gen/Makefile.inc b/lib/libc/i386/gen/Makefile.inc
new file mode 100644
index 0000000..387aebf
--- /dev/null
+++ b/lib/libc/i386/gen/Makefile.inc
@@ -0,0 +1,5 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $Id: Makefile.inc,v 1.5 1995/01/23 01:26:39 davidg Exp $
+
+SRCS+= isinf.c infinity.c
+SRCS+= _setjmp.S alloca.S fabs.S 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..abd2684
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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 28(%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 28(%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..f76b37b
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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..5ae5370
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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..aba4802
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$Id$";
+#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..e46f676
--- /dev/null
+++ b/lib/libc/i386/gen/infinity.c
@@ -0,0 +1,9 @@
+/*
+ * infinity.c
+ * $Id$
+ */
+
+#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..c328449
--- /dev/null
+++ b/lib/libc/i386/gen/isinf.c
@@ -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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$Id$";
+#endif /* LIBC_RCS and not lint */
+
+#include <sys/types.h>
+
+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));
+}
+
+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..8b63f52
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$Id$";
+#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..35b993a
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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. */
+.text
+.globl _modf
+.type _modf,@function
+_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..fa52b83
--- /dev/null
+++ b/lib/libc/i386/gen/setjmp.S
@@ -0,0 +1,93 @@
+/*-
+ * 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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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)
+ pushl $0
+ call PIC_PLT(_sigblock)
+ popl %edx
+ 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)
+ movl %eax,24(%ecx)
+ fnstcw 28(%ecx)
+ xorl %eax,%eax
+ ret
+
+ENTRY(longjmp)
+ movl 4(%esp),%edx
+ pushl 24(%edx)
+ call PIC_PLT(_sigsetmask) /* XXX this is not reentrant */
+ popl %eax
+ 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 28(%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..4f592a3
--- /dev/null
+++ b/lib/libc/i386/gen/sigsetjmp.S
@@ -0,0 +1,105 @@
+/*-
+ * 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.
+ *
+ * $Id: sigsetjmp.S,v 1.3 1994/12/27 13:34:04 bde Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: sigsetjmp.S,v 1.3 1994/12/27 13:34:04 bde Exp $"
+#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)
+ movl 8(%esp),%eax
+ movl 4(%esp),%ecx
+ movl %eax,32(%ecx)
+ testl %eax,%eax
+ jz 1f
+ pushl $0
+ call PIC_PLT(_sigblock)
+ addl $4,%esp
+ movl 4(%esp),%ecx
+ movl %eax,24(%ecx)
+1: 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 28(%ecx)
+ xorl %eax,%eax
+ ret
+
+ENTRY(siglongjmp)
+ movl 4(%esp),%edx
+ cmpl $0,32(%edx)
+ jz 1f
+ pushl 24(%edx)
+ call PIC_PLT(_sigsetmask)
+ addl $4,%esp
+1: 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 28(%edx)
+ testl %eax,%eax
+ jnz 2f
+ incl %eax
+2: 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..dff7fd1
--- /dev/null
+++ b/lib/libc/i386/net/Makefile.inc
@@ -0,0 +1,4 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $Id$
+
+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..095c40a
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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..238dfc2
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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..5af5008
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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..4bed4a2
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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..65ce348
--- /dev/null
+++ b/lib/libc/i386/stdlib/Makefile.inc
@@ -0,0 +1,4 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $Id$
+
+SRCS+= abs.S
diff --git a/lib/libc/i386/stdlib/abs.S b/lib/libc/i386/stdlib/abs.S
new file mode 100644
index 0000000..4915d16
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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..b4f89d2
--- /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.
+ *
+ * $Id: div.S,v 1.1 1993/12/04 21:46:15 ats Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: div.S,v 1.1 1993/12/04 21:46:15 ats Exp $"
+#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..5c5afe1
--- /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.
+ *
+ * $Id$
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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..de7bb94
--- /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.
+ *
+ * $Id: ldiv.S,v 1.1 1993/12/04 21:46:17 ats Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: ldiv.S,v 1.1 1993/12/04 21:46:17 ats Exp $"
+#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..be5827f
--- /dev/null
+++ b/lib/libc/i386/string/Makefile.inc
@@ -0,0 +1,8 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+# $Id$
+
+SRCS+= bcmp.S bcopy.S bzero.S ffs.S index.S memchr.S memcmp.S \
+ memmove.S memset.S \
+ rindex.S strcat.S strchr.S strcmp.S strcpy.S strcspn.c \
+ strlen.S strncat.c strncmp.S strncpy.c strpbrk.c strsep.c \
+ strspn.c strrchr.S strstr.c swab.S
diff --git a/lib/libc/i386/string/bcmp.S b/lib/libc/i386/string/bcmp.S
new file mode 100644
index 0000000..c15975a
--- /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.
+ *
+ * $Id: bcmp.S,v 1.1 1994/08/05 01:18:23 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: bcmp.S,v 1.1 1994/08/05 01:18:23 wollman Exp $"
+#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..6d99938
--- /dev/null
+++ b/lib/libc/i386/string/bcopy.S
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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: bcopy.S,v 1.2 1995/01/23 01:28:49 davidg Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: bcopy.S,v 1.2 1995/01/23 01:28:49 davidg Exp $"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+ /*
+ * (ov)bcopy (src,dst,cnt)
+ * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
+ */
+
+ENTRY(bcopy)
+ pushl %esi
+ pushl %edi
+ movl 12(%esp),%esi
+ movl 16(%esp),%edi
+ 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
+ popl %edi
+ popl %esi
+ ret
+1:
+ addl %ecx,%edi /* copy backwards. */
+ addl %ecx,%esi
+ decl %edi
+ decl %esi
+ andl $3,%ecx /* any fractional bytes? */
+ std
+ rep
+ movsb
+ movl 20(%esp),%ecx /* copy remainder by words */
+ shrl $2,%ecx
+ subl $3,%esi
+ subl $3,%edi
+ rep
+ movsl
+ 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..74a1d03
--- /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.
+ *
+ * $Id: bzero.S,v 1.1 1994/08/05 01:18:25 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: bzero.S,v 1.1 1994/08/05 01:18:25 wollman Exp $"
+#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..69ef90e
--- /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.
+ *
+ * $Id: ffs.S,v 1.1 1994/08/05 01:18:26 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: ffs.S,v 1.1 1994/08/05 01:18:26 wollman Exp $"
+#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..f7b0d8d
--- /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.
+ *
+ * $Id: index.S,v 1.1 1994/08/05 01:18:27 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: index.S,v 1.1 1994/08/05 01:18:27 wollman Exp $"
+#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..dd989d4
--- /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.
+ *
+ * $Id: memchr.S,v 1.4 1994/11/25 08:58:53 davidg Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: memchr.S,v 1.4 1994/11/25 08:58:53 davidg Exp $"
+#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..f43329d
--- /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.
+ *
+ * $Id: memcmp.S,v 1.1 1994/08/05 01:18:29 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: memcmp.S,v 1.1 1994/08/05 01:18:29 wollman Exp $"
+#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/memmove.S b/lib/libc/i386/string/memmove.S
new file mode 100644
index 0000000..497af4f
--- /dev/null
+++ b/lib/libc/i386/string/memmove.S
@@ -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
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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: memmove.S,v 1.2 1995/01/23 01:29:02 davidg Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: memmove.S,v 1.2 1995/01/23 01:29:02 davidg Exp $"
+#endif /* LIBC_RCS and not lint */
+
+#include "DEFS.h"
+
+ /*
+ * (ov)bcopy (src,dst,cnt)
+ * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
+ */
+
+ALTENTRY(memcpy)
+ENTRY(memmove)
+ pushl %esi
+ pushl %edi
+ movl 12(%esp),%edi
+ movl 16(%esp),%esi
+ movl 20(%esp),%ecx
+ movl %edi,%eax
+ subl %esi,%eax
+ cmpl %ecx,%eax
+ 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
+ movl 12(%esp),%eax
+ popl %edi
+ popl %esi
+ ret
+1:
+ addl %ecx,%edi /* copy backwards. */
+ addl %ecx,%esi
+ decl %edi
+ decl %esi
+ andl $3,%ecx /* any fractional bytes? */
+ std
+ rep
+ movsb
+ movl 20(%esp),%ecx /* copy remainder by words */
+ shrl $2,%ecx
+ subl $3,%esi
+ subl $3,%edi
+ rep
+ movsl
+ movl 12(%esp),%eax
+ popl %edi
+ popl %esi
+ cld
+ ret
diff --git a/lib/libc/i386/string/memset.S b/lib/libc/i386/string/memset.S
new file mode 100644
index 0000000..412bcbb
--- /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.
+ *
+ * $Id: memset.S,v 1.1 1994/08/05 01:18:30 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: memset.S,v 1.1 1994/08/05 01:18:30 wollman Exp $"
+#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..53af042
--- /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.
+ *
+ * $Id: rindex.S,v 1.1 1994/08/05 01:18:31 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: rindex.S,v 1.1 1994/08/05 01:18:31 wollman Exp $"
+#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..9d5e119
--- /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.
+ *
+ * $Id: strcat.S,v 1.1 1994/08/05 01:18:32 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: strcat.S,v 1.1 1994/08/05 01:18:32 wollman Exp $"
+#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..dd2e680
--- /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.
+ *
+ * $Id: strchr.S,v 1.1 1994/08/05 01:18:33 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: strchr.S,v 1.1 1994/08/05 01:18:33 wollman Exp $"
+#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..ef076c5
--- /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.
+ *
+ * $Id: strcmp.S,v 1.1 1994/08/05 01:18:34 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: strcmp.S,v 1.1 1994/08/05 01:18:34 wollman Exp $"
+#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..2d93e46
--- /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.
+ *
+ * $Id: strcpy.S,v 1.1 1994/08/05 01:18:34 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: strcpy.S,v 1.1 1994/08/05 01:18:34 wollman Exp $"
+#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..16eee1a
--- /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.
+ *
+ * $Id: strlen.S,v 1.1 1994/08/05 01:18:35 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: strlen.S,v 1.1 1994/08/05 01:18:35 wollman Exp $"
+#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..20788bd
--- /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.
+ *
+ * $Id: strncmp.S,v 1.2 1994/12/27 13:12:34 bde Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: strncmp.S,v 1.2 1994/12/27 13:12:34 bde Exp $"
+#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..28f0637
--- /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.
+ *
+ * $Id: strrchr.S,v 1.1 1994/08/05 01:18:37 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: strrchr.S,v 1.1 1994/08/05 01:18:37 wollman Exp $"
+#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..87deded
--- /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.
+ *
+ * $Id: swab.S,v 1.1 1995/01/22 21:36:15 davidg Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: swab.S,v 1.1 1995/01/22 21:36:15 davidg Exp $"
+#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..6774dd3
--- /dev/null
+++ b/lib/libc/i386/sys/Makefile.inc
@@ -0,0 +1,10 @@
+# from: Makefile.inc,v 1.1 1993/09/03 19:04:23 jtc Exp
+# $Id$
+
+.PATH: ${.CURDIR}/${MACHINE}/sys
+
+SRCS+= i386_get_ldt.c i386_set_ldt.c
+
+MAN2+= i386/sys/i386_get_ldt.2
+
+MLINKS+=i386_get_ldt.2 i386_set_ldt.2
diff --git a/lib/libc/i386/sys/Ovfork.S b/lib/libc/i386/sys/Ovfork.S
new file mode 100644
index 0000000..06e3eb6
--- /dev/null
+++ b/lib/libc/i386/sys/Ovfork.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.
+ *
+ * $Id: Ovfork.S,v 1.1 1994/08/05 01:18:38 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#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.
+ *
+ */
+ .set vfork,66
+.globl _vfork
+.type _vfork,@function
+
+_vfork:
+ popl %ecx /* my rta into ecx */
+ movl $vfork, %eax
+ LCALL(7,0)
+ jb verror
+vforkok:
+ cmpl $0,%edx /* child process? */
+ jne child /* yes */
+ jmp parent
+.globl _errno
+verror:
+#ifdef PIC
+ PIC_PROLOGUE
+ movl PIC_GOT(_errno), %edx
+ movl %eax,(%edx)
+ PIC_EPILOGUE
+#else
+ movl %eax,_errno
+#endif
+ movl $-1,%eax
+ jmp %ecx
+child:
+ movl $0,%eax
+parent:
+ jmp %ecx
diff --git a/lib/libc/i386/sys/brk.S b/lib/libc/i386/sys/brk.S
new file mode 100644
index 0000000..c8311bb
--- /dev/null
+++ b/lib/libc/i386/sys/brk.S
@@ -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.
+ *
+ * $Id: brk.S,v 1.1 1994/08/05 01:18:39 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+#define SYS_brk 17
+
+ .globl curbrk
+ .globl minbrk
+ENTRY(_brk)
+ jmp ok
+
+ENTRY(brk)
+#ifdef PIC
+ movl 4(%esp),%eax
+ PIC_PROLOGUE
+ movl PIC_GOT(curbrk),%edx # set up GOT addressing
+ movl PIC_GOT(minbrk),%ecx #
+ cmpl %eax,(%ecx)
+ PIC_EPILOGUE
+ jl ok
+ movl (%ecx),%eax
+ movl %eax,4(%esp)
+ok:
+ lea SYS_brk,%eax
+ LCALL(7,0)
+ jb err
+ movl 4(%esp),%eax
+ movl %eax,(%edx)
+ movl $0,%eax
+ ret
+err:
+ jmp PIC_PLT(cerror)
+
+#else
+
+ movl 4(%esp),%eax
+ cmpl %eax,minbrk
+ jl ok
+ movl minbrk,%eax
+ movl %eax,4(%esp)
+ok:
+ lea SYS_brk,%eax
+ LCALL(7,0)
+ jb err
+ movl 4(%esp),%eax
+ movl %eax,curbrk
+ movl $0,%eax
+ ret
+err:
+ jmp cerror
+#endif
diff --git a/lib/libc/i386/sys/cerror.S b/lib/libc/i386/sys/cerror.S
new file mode 100644
index 0000000..875f6db
--- /dev/null
+++ b/lib/libc/i386/sys/cerror.S
@@ -0,0 +1,58 @@
+/*-
+ * 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.
+ *
+ * $Id: cerror.S,v 1.2 1994/08/13 14:00:26 davidg Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ .globl _errno
+cerror:
+#ifdef PIC
+ PIC_PROLOGUE
+ movl PIC_GOT(_errno),%ecx
+ movl %eax,(%ecx)
+ PIC_EPILOGUE
+#else
+ movl %eax,_errno
+#endif
+ 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..74a055b
--- /dev/null
+++ b/lib/libc/i386/sys/exect.S
@@ -0,0 +1,55 @@
+/*-
+ * 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.
+ *
+ * $Id: exect.S,v 1.1 1994/08/05 01:18:42 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#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
+ LCALL(7,0)
+ jmp 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..fe4c36d
--- /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.
+ *
+ * $Id: fork.S,v 1.1 1994/08/05 01:18:44 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+SYSCALL(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_ldt.2 b/lib/libc/i386/sys/i386_get_ldt.2
new file mode 100644
index 0000000..ade7e10
--- /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
+.\" $Id: i386_get_ldt.2,v 1.2 1993/10/09 00:59:10 cgd Exp $
+.\"
+.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 architecure
+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 EACESS
+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..8c4e5d2
--- /dev/null
+++ b/lib/libc/i386/sys/i386_get_ldt.c
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ *
+ * $Id: i386_get_ldt.c,v 1.2 1995/01/23 01:29:50 davidg Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$Id: i386_get_ldt.c,v 1.2 1995/01/23 01:29:50 davidg Exp $";
+#endif /* LIBC_RCS and not lint */
+
+#include <sys/cdefs.h>
+#include <machine/segments.h>
+#include <machine/sysarch.h>
+
+struct parms {
+ int start;
+ union descriptor *descs;
+ int num;
+};
+
+int
+i386_get_ldt(int start, union descriptor *descs, int num)
+{
+ struct parms 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_ldt.c b/lib/libc/i386/sys/i386_set_ldt.c
new file mode 100644
index 0000000..8754fd1
--- /dev/null
+++ b/lib/libc/i386/sys/i386_set_ldt.c
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ *
+ * $Id: i386_set_ldt.c,v 1.2 1995/01/23 01:29:53 davidg Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+static const char rcsid[] = "$Id: i386_set_ldt.c,v 1.2 1995/01/23 01:29:53 davidg Exp $";
+#endif /* LIBC_RCS and not lint */
+
+#include <sys/cdefs.h>
+#include <machine/segments.h>
+#include <machine/sysarch.h>
+
+struct parms {
+ int start;
+ union descriptor *descs;
+ int num;
+};
+
+int
+i386_set_ldt(int start, union descriptor *descs, int num)
+{
+ struct parms p;
+
+ p.start = start;
+ p.descs = descs;
+ p.num = num;
+
+ return sysarch(I386_SET_LDT, (char *)&p);
+}
diff --git a/lib/libc/i386/sys/mount.S b/lib/libc/i386/sys/mount.S
new file mode 100644
index 0000000..3fbcd63
--- /dev/null
+++ b/lib/libc/i386/sys/mount.S
@@ -0,0 +1,48 @@
+/*-
+ * 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.
+ *
+ * $Id: mount.S,v 1.1 1994/08/05 01:18:45 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+SYSCALL(mount)
+ movl $0,%eax
+ ret
diff --git a/lib/libc/i386/sys/pipe.S b/lib/libc/i386/sys/pipe.S
new file mode 100644
index 0000000..cf3264c
--- /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.
+ *
+ * $Id: pipe.S,v 1.1 1994/08/05 01:18:46 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+SYSCALL(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..e3ac3a5
--- /dev/null
+++ b/lib/libc/i386/sys/ptrace.S
@@ -0,0 +1,61 @@
+/*-
+ * 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.
+ *
+ * $Id: ptrace.S,v 1.1 1994/08/05 01:18:47 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ENTRY(ptrace)
+ xorl %eax,%eax
+#ifdef PIC
+ PIC_PROLOGUE
+ movl PIC_GOT(_errno),%edx
+ movl %eax,(%edx)
+ PIC_EPILOGUE
+#else
+ movl %eax,_errno
+#endif
+ lea SYS_ptrace,%eax
+ LCALL(7,0)
+ jb err
+ ret
+err:
+ jmp cerror
diff --git a/lib/libc/i386/sys/reboot.S b/lib/libc/i386/sys/reboot.S
new file mode 100644
index 0000000..f90cca0
--- /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.
+ *
+ * $Id: reboot.S,v 1.1 1994/08/05 01:18:48 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+SYSCALL(reboot)
+ iret
diff --git a/lib/libc/i386/sys/sbrk.S b/lib/libc/i386/sys/sbrk.S
new file mode 100644
index 0000000..2d65b59
--- /dev/null
+++ b/lib/libc/i386/sys/sbrk.S
@@ -0,0 +1,96 @@
+/*-
+ * 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.
+ *
+ * $Id: sbrk.S,v 1.2 1995/01/23 01:30:04 davidg Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id: sbrk.S,v 1.2 1995/01/23 01:30:04 davidg Exp $"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+#define SYS_brk 17
+
+ .globl _end
+ .globl minbrk
+ .globl curbrk
+
+ .data
+minbrk: .long _end
+curbrk: .long _end
+ .text
+
+ENTRY(sbrk)
+#ifdef PIC
+ movl 4(%esp),%ecx
+ PIC_PROLOGUE
+ movl PIC_GOT(curbrk),%edx
+ movl (%edx),%eax
+ PIC_EPILOGUE
+ testl %ecx,%ecx
+ jz back
+ addl %eax,4(%esp)
+ lea SYS_brk,%eax
+ LCALL(7,0)
+ jb err
+ PIC_PROLOGUE
+ movl PIC_GOT(curbrk),%edx
+ movl (%edx),%eax
+ addl %ecx,(%edx)
+ PIC_EPILOGUE
+back:
+ ret
+err:
+ jmp PIC_PLT(cerror)
+
+#else /* !PIC */
+
+ movl 4(%esp),%ecx
+ movl curbrk,%eax
+ testl %ecx,%ecx
+ jz back
+ addl %eax,4(%esp)
+ lea SYS_brk,%eax
+ LCALL(7,0)
+ jb err
+ movl curbrk,%eax
+ addl %ecx,curbrk
+back:
+ ret
+err:
+ jmp 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..96c7886
--- /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.
+ *
+ * $Id: setlogin.S,v 1.1 1994/08/05 01:18:50 wollman Exp $
+ */
+
+#if defined(LIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* LIBC_RCS and not lint */
+
+#include "SYS.h"
+
+.globl __logname_valid /* in getlogin() */
+
+SYSCALL(setlogin)
+#ifdef PIC
+ PIC_PROLOGUE
+ pushl %eax
+ movl PIC_GOT(__logname_valid),%eax
+ movl $0,(%eax)
+ popl %eax
+ PIC_EPILOGUE
+#else
+ movl $0,__logname_valid
+#endif
+ ret /* setlogin(name) */
diff --git a/lib/libc/i386/sys/sigpending.S b/lib/libc/i386/sys/sigpending.S
new file mode 100644
index 0000000..fdc1e9f
--- /dev/null
+++ b/lib/libc/i386/sys/sigpending.S
@@ -0,0 +1,50 @@
+/*-
+ * 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.
+ *
+ * $Id: sigpending.S,v 1.1 1994/08/05 01:18:51 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+SYSCALL(sigpending)
+ movl 4(%esp),%ecx # fetch pointer to...
+ movl %eax,(%ecx) # store old mask
+ xorl %eax,%eax
+ ret
diff --git a/lib/libc/i386/sys/sigprocmask.S b/lib/libc/i386/sys/sigprocmask.S
new file mode 100644
index 0000000..1757a3a
--- /dev/null
+++ b/lib/libc/i386/sys/sigprocmask.S
@@ -0,0 +1,67 @@
+/*-
+ * 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.
+ *
+ * $Id: sigprocmask.S,v 1.1 1994/08/05 01:18:52 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+err:
+ jmp cerror
+
+ENTRY(sigprocmask)
+ movl 8(%esp),%ecx # fetch new sigset pointer
+ cmpl $0,%ecx # check new sigset pointer
+ jne 1f # if not null, indirect
+/* movl $0,8(%esp) # null mask pointer: block empty set */
+ movl $1,4(%esp) # SIG_BLOCK
+ jmp 2f
+1: movl (%ecx),%ecx # fetch indirect ...
+ movl %ecx,8(%esp) # to new mask arg
+2: movl $ SYS_sigprocmask , %eax
+ LCALL(0x7,0)
+ jb err
+ movl 12(%esp),%ecx # fetch old mask requested
+ cmpl $0,%ecx # test if old mask requested
+ je out
+ movl %eax,(%ecx) # store old mask
+out:
+ xorl %eax,%eax
+ ret
diff --git a/lib/libc/i386/sys/sigreturn.S b/lib/libc/i386/sys/sigreturn.S
new file mode 100644
index 0000000..ac0ffd6
--- /dev/null
+++ b/lib/libc/i386/sys/sigreturn.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.
+ *
+ * $Id: sigreturn.S,v 1.1 1994/08/05 01:18:53 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+/*
+ * We must preserve the state of the registers as the user has set them up.
+ */
+#ifdef PROF
+#undef ENTRY
+#define ENTRY(x) \
+ .globl _/**/x; .align 2; _/**/x: pusha ; \
+ .data; 1:; .long 0; .text; movl $1b,%eax; call mcount; popa ; nop
+#endif /* PROF */
+
+SYSCALL(sigreturn)
+ ret
diff --git a/lib/libc/i386/sys/sigsuspend.S b/lib/libc/i386/sys/sigsuspend.S
new file mode 100644
index 0000000..a72154a
--- /dev/null
+++ b/lib/libc/i386/sys/sigsuspend.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.
+ *
+ * $Id$
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+err:
+ jmp cerror
+
+ENTRY(sigsuspend)
+ movl 4(%esp),%eax # fetch mask arg
+ movl (%eax),%eax # indirect to mask arg
+ movl %eax,4(%esp)
+ movl $ SYS_sigsuspend ,%eax
+ LCALL(0x7,0)
+ jb err
+ xorl %eax,%eax # shouldn t happen
+ ret
diff --git a/lib/libc/i386/sys/syscall.S b/lib/libc/i386/sys/syscall.S
new file mode 100644
index 0000000..8fcbec9
--- /dev/null
+++ b/lib/libc/i386/sys/syscall.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.
+ *
+ * $Id: syscall.S,v 1.1 1994/08/05 01:18:55 wollman Exp $
+ */
+
+#if defined(SYSLIBC_RCS) && !defined(lint)
+ .text
+ .asciz "$Id$"
+#endif /* SYSLIBC_RCS and not lint */
+
+#include "SYS.h"
+
+ENTRY(syscall)
+ pop %ecx /* rta */
+ pop %eax /* syscall number */
+ push %ecx
+ LCALL(7,0)
+ 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:
+ jmp cerror
diff --git a/lib/libc/locale/Makefile.inc b/lib/libc/locale/Makefile.inc
new file mode 100644
index 0000000..5fd09d2
--- /dev/null
+++ b/lib/libc/locale/Makefile.inc
@@ -0,0 +1,21 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+
+# locale sources
+.PATH: ${.CURDIR}/${MACHINE}/locale ${.CURDIR}/locale
+
+SRCS+= ansi.c ctype.c euc.c frune.c isctype.c lconv.c localeconv.c \
+ mbrune.c none.c rune.c setlocale.c table.c utf2.c setrunelocale.c \
+ runetype.c tolower.c toupper.c nomacros.c collate.c setinvalidrune.c
+
+MAN3+= locale/ctype.3 locale/isalnum.3 locale/isalpha.3 locale/isascii.3 \
+ locale/isblank.3 locale/iscntrl.3 locale/isdigit.3 locale/isgraph.3 \
+ locale/islower.3 locale/isprint.3 locale/ispunct.3 locale/isspace.3 \
+ locale/isupper.3 locale/isxdigit.3 locale/mbrune.3 locale/multibyte.3 \
+ locale/rune.3 locale/setlocale.3 locale/toascii.3 locale/tolower.3 \
+ locale/toupper.3
+MAN4+= locale/euc.4 locale/utf2.4
+MLINKS+= rune.3 setrunelocale.3 rune.3 setinvalidrune.3 rune.3 sgetrune.3 \
+ rune.3 sputrune.3 rune.3 fgetrune.3 rune.3 fungetrune.3 \
+ rune.3 fputrune.3 mbrune.3 mbrrune.3 mbrune.3 mbmb.3 \
+ multibyte.3 mblen.3 multibyte.3 mbstowcs.3 multibyte.3 mbtowc.3 \
+ multibyte.3 wcstombs.3 multibyte.3 wctomb.3 setlocale.3 localeconv.3
diff --git a/lib/libc/locale/ansi.c b/lib/libc/locale/ansi.c
new file mode 100644
index 0000000..e5c8e8f
--- /dev/null
+++ b/lib/libc/locale/ansi.c
@@ -0,0 +1,148 @@
+/*-
+ * 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, (int)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, (int)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 = 0;
+
+ if (!pwcs || !s)
+ return (-1);
+
+ while (n > 0) {
+ if (*pwcs == 0) {
+ *s = 0;
+ break;
+ }
+ if (!sputrune(*pwcs++, s, (int)n, &e))
+ return (-1); /* encoding error */
+ if (!e) /* too long */
+ return (cnt);
+ cnt += e - s;
+ s = e;
+ }
+ return (cnt);
+}
diff --git a/lib/libc/locale/collate.c b/lib/libc/locale/collate.c
new file mode 100644
index 0000000..ef73cef
--- /dev/null
+++ b/lib/libc/locale/collate.c
@@ -0,0 +1,213 @@
+/*-
+ * 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.
+ *
+ * $Id: collate.c,v 1.4 1995/05/30 05:40:40 rgrimes Exp $
+ */
+
+#include <rune.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sysexits.h>
+#include "collate.h"
+
+char *_PathLocale;
+int __collate_load_error = 1;
+u_char __collate_charmap_table[UCHAR_MAX + 1][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_name_pri __collate_name_pri_table[TABLE_SIZE];
+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)
+
+__dead void __collate_err(int ex, const char *f) __dead2;
+
+int
+__collate_load_tables(encoding)
+ char *encoding;
+{
+ char buf[PATH_MAX];
+ FILE *fp;
+ int save_load_error;
+
+ save_load_error = __collate_load_error;
+ __collate_load_error = 1;
+ if (!encoding) {
+ __collate_load_error = save_load_error;
+ return -1;
+ }
+ if (!*encoding || !strcmp(encoding, "C") || !strcmp(encoding, "POSIX"))
+ return 0;
+ if (!_PathLocale && !(_PathLocale = getenv("PATH_LOCALE")))
+ _PathLocale = _PATH_LOCALE;
+ strcpy(buf, _PathLocale);
+ strcat(buf, "/");
+ strcat(buf, encoding);
+ strcat(buf, "/LC_COLLATE");
+ if ((fp = fopen(buf, "r")) == NULL) {
+ __collate_load_error = save_load_error;
+ return -1;
+ }
+ FREAD(__collate_charmap_table, sizeof(__collate_charmap_table), 1, fp);
+ 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);
+ FREAD(__collate_name_pri_table, sizeof(__collate_name_pri_table), 1,
+ fp);
+ fclose(fp);
+ __collate_load_error = 0;
+ return 0;
+}
+
+u_char *
+__collate_substitute(s)
+ const u_char *s;
+{
+ int dest_len = 0, len = 0;
+ int delta = strlen(s);
+ u_char *dest_str = NULL;
+
+ if(s == NULL || *s == '\0')
+ return __collate_strdup("");
+ while(*s) {
+ len += strlen(__collate_substitute_table[*s]);
+ while(dest_len <= len) {
+ if(!dest_str)
+ dest_str = calloc(dest_len = delta, 1);
+ else
+ dest_str = realloc(dest_str, dest_len += delta);
+ if(dest_str == NULL)
+ __collate_err(EX_OSERR, __FUNCTION__);
+ }
+ strcat(dest_str, __collate_substitute_table[*s++]);
+ }
+ return dest_str;
+}
+
+void
+__collate_lookup(t, len, prim, sec)
+ u_char *t;
+ int *len, *prim, *sec;
+{
+ struct __collate_st_name_pri *p;
+ struct __collate_st_chain_pri *p2;
+
+ *len = 1;
+ *prim = *sec = 0;
+ if(__collate_charmap_table[*t][0]) {
+ for(p = __collate_name_pri_table; p->str[0]; p++) {
+ if(strncmp(__collate_charmap_table[*t], p->str, strlen(p->str))
+ == 0) {
+ *prim = p->prim;
+ *sec = p->sec;
+ return;
+ }
+ }
+ return;
+ }
+ 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;
+}
+
+__dead 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_name_pri *p;
+ struct __collate_st_chain_pri *p2;
+
+ printf("Substitute table:\n");
+ for (i = 0; i < UCHAR_MAX + 1; i++)
+ printf("\t'%c' --> \"%s\"\n", i,
+ __collate_substitute_table[i]);
+ printf("Charmap table:\n");
+ for (i = 0; i < UCHAR_MAX + 1; i++) {
+ if (__collate_charmap_table[i][0])
+ printf("\t\\x%02x --> \"%s\"\n", i,
+ __collate_charmap_table[i]);
+ }
+ printf("Name priority table:\n");
+ for (p = __collate_name_pri_table; p->str[0]; p++)
+ printf("\t\"%s\" : %d %d\n\n", p->str, p->prim, p->sec);
+ 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..c7c0b6d
--- /dev/null
+++ b/lib/libc/locale/collate.h
@@ -0,0 +1,69 @@
+/*-
+ * 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.
+ *
+ * $Id: collate.h,v 1.4 1995/01/27 12:51:06 alex Exp alex $
+ */
+
+#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
+
+struct __collate_st_char_pri {
+ int prim, sec;
+};
+struct __collate_st_name_pri {
+ u_char str[STR_LEN];
+ int prim, sec;
+};
+struct __collate_st_chain_pri {
+ u_char str[STR_LEN];
+ int prim, sec;
+};
+
+extern int __collate_load_error;
+extern u_char __collate_charmap_table[UCHAR_MAX + 1][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_name_pri __collate_name_pri_table[TABLE_SIZE];
+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((u_char *, int *, 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/ctype.3 b/lib/libc/locale/ctype.3
new file mode 100644
index 0000000..528df27
--- /dev/null
+++ b/lib/libc/locale/ctype.3
@@ -0,0 +1,107 @@
+.\" 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
+.\"
+.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 islower ,
+.Nm isprint ,
+.Nm ispunct ,
+.Nm isspace ,
+.Nm isupper ,
+.Nm isxdigit ,
+.Nm toascii
+.Nm tolower ,
+.Nm toupper ,
+.Nd character classification macros
+.Sh SYNOPSIS
+.Fd #include <ctype.h>
+.Fa int c
+.br
+.Fn isalnum "int c"
+.Fn isalpha "int c"
+.Fn isascii "int c"
+.Fn iscntrl "int c"
+.Fn isdigit "int c"
+.Fn isgraph "int c"
+.Fn islower "int c"
+.Fn isprint "int c"
+.Fn ispunct "int c"
+.Fn isspace "int c"
+.Fn isupper "int c"
+.Fn isxdigit "int c"
+.Fn toascii "int c"
+.Fn tolower "int c"
+.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 isblank ,
+.Fn toupper ,
+.Fn tolower
+and
+.Fn toascii ,
+conform to
+.St -ansiC .
diff --git a/lib/libc/locale/ctype.c b/lib/libc/locale/ctype.c
new file mode 100644
index 0000000..0418b1a
--- /dev/null
+++ b/lib/libc/locale/ctype.c
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 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[] = "@(#)ctype.c 8.2 (Berkeley) 1/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+#define _U 0x01
+#define _L 0x02
+#define _N 0x04
+#define _S 0x08
+#define _P 0x10
+#define _C 0x20
+#define _X 0x40
+#define _B 0x80
+
+char __ctype[1 + 256] = {
+ 0,
+ _C, _C, _C, _C, _C, _C, _C, _C,
+ _C, _C|_S, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C,
+ _C, _C, _C, _C, _C, _C, _C, _C,
+ _C, _C, _C, _C, _C, _C, _C, _C,
+ _S|_B, _P, _P, _P, _P, _P, _P, _P,
+ _P, _P, _P, _P, _P, _P, _P, _P,
+ _N, _N, _N, _N, _N, _N, _N, _N,
+ _N, _N, _P, _P, _P, _P, _P, _P,
+ _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U,
+ _U, _U, _U, _U, _U, _U, _U, _U,
+ _U, _U, _U, _U, _U, _U, _U, _U,
+ _U, _U, _U, _P, _P, _P, _P, _P,
+ _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L,
+ _L, _L, _L, _L, _L, _L, _L, _L,
+ _L, _L, _L, _L, _L, _L, _L, _L,
+ _L, _L, _L, _P, _P, _P, _P, _C
+};
+
+char *_ctype_ = __ctype; /* Backward compatibility. */
diff --git a/lib/libc/locale/euc.4 b/lib/libc/locale/euc.4
new file mode 100644
index 0000000..966b896
--- /dev/null
+++ b/lib/libc/locale/euc.4
@@ -0,0 +1,231 @@
+.\" 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
+.\"
+.Dd "June 4, 1993"
+.Dt EUC 4
+.Os
+.Sh NAME
+.Nm EUC
+.Nd EUC encoding of runes
+.Sh SYNOPSIS
+\fBENCODING "EUC"\fP
+.br
+\fBVARIABLE \fP\fIlen1 mask1 len2 mask2 len3 mask3 len4 mask4 mask\fP
+.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
+.sp
+The result is then ANDed with
+.Ar ~mask
+and ORed with
+.Ar mask\fPN.
+Codesets 2 and 3 are special in that the leading byte (0x8e or 0x8f) is
+first removed and the
+.Ar len\fPN
+argument is reduced by 1.
+.sp
+For example, the Japanese locale has the following
+.Ev VARIABLE
+line:
+.Bd -literal
+VARIABLE 1 0x0000 2 0x8080 2 0x0080 3 0x8000 0x8080
+.Ed
+.sp
+Codeset 1 consists of the values 0x0000 - 0x007f.
+.sp
+Codeset 2 consists of the values who have the bits 0x8080 set.
+.sp
+Codeset 3 consists of the values 0x0080 - 0x00ff.
+.sp
+Codeset 4 consists of the values 0x8000 - 0xff7f excluding the values
+which have the 0x0080 bit set.
+.sp
+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..966b896
--- /dev/null
+++ b/lib/libc/locale/euc.5
@@ -0,0 +1,231 @@
+.\" 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
+.\"
+.Dd "June 4, 1993"
+.Dt EUC 4
+.Os
+.Sh NAME
+.Nm EUC
+.Nd EUC encoding of runes
+.Sh SYNOPSIS
+\fBENCODING "EUC"\fP
+.br
+\fBVARIABLE \fP\fIlen1 mask1 len2 mask2 len3 mask3 len4 mask4 mask\fP
+.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
+.sp
+The result is then ANDed with
+.Ar ~mask
+and ORed with
+.Ar mask\fPN.
+Codesets 2 and 3 are special in that the leading byte (0x8e or 0x8f) is
+first removed and the
+.Ar len\fPN
+argument is reduced by 1.
+.sp
+For example, the Japanese locale has the following
+.Ev VARIABLE
+line:
+.Bd -literal
+VARIABLE 1 0x0000 2 0x8080 2 0x0080 3 0x8000 0x8080
+.Ed
+.sp
+Codeset 1 consists of the values 0x0000 - 0x007f.
+.sp
+Codeset 2 consists of the values who have the bits 0x8080 set.
+.sp
+Codeset 3 consists of the values 0x0080 - 0x00ff.
+.sp
+Codeset 4 consists of the values 0x8000 - 0xff7f excluding the values
+which have the 0x0080 bit set.
+.sp
+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..bc33ff6
--- /dev/null
+++ b/lib/libc/locale/euc.c
@@ -0,0 +1,222 @@
+/*-
+ * 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>
+
+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..ad92c41
--- /dev/null
+++ b/lib/libc/locale/isalnum.3
@@ -0,0 +1,85 @@
+.\" 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
+.\"
+.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:
+.sp
+.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 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..a36dd4b
--- /dev/null
+++ b/lib/libc/locale/isalpha.3
@@ -0,0 +1,83 @@
+.\" 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
+.\"
+.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:
+.sp
+.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 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..9509dc5
--- /dev/null
+++ b/lib/libc/locale/isascii.3
@@ -0,0 +1,58 @@
+.\" 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
+.\"
+.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..7c83d18
--- /dev/null
+++ b/lib/libc/locale/isblank.3
@@ -0,0 +1,55 @@
+.\" 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
+.\"
+.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..33859a2
--- /dev/null
+++ b/lib/libc/locale/iscntrl.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.
+.\"
+.\" @(#)iscntrl.3 8.1 (Berkeley) 6/4/93
+.\"
+.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:
+.sp
+.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..55cfdf0
--- /dev/null
+++ b/lib/libc/locale/isctype.c
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+
+#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 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 islower
+int
+islower(c)
+ int c;
+{
+ return (__istype((c), _L));
+}
+
+#undef isprint
+int
+isprint(c)
+ int c;
+{
+ return (__istype((c), _R));
+}
+
+#undef ispunct
+int
+ispunct(c)
+ int c;
+{
+ return (__istype((c), _P));
+}
+
+#undef isspace
+int
+isspace(c)
+ int c;
+{
+ return (__istype((c), _S));
+}
+
+#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..aa70c30
--- /dev/null
+++ b/lib/libc/locale/isdigit.3
@@ -0,0 +1,70 @@
+.\" 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
+.\"
+.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:
+.sp
+.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..e8b1ee5
--- /dev/null
+++ b/lib/libc/locale/isgraph.3
@@ -0,0 +1,87 @@
+.\" 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
+.\"
+.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:
+.sp
+.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\ ``\''
+.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..e985498
--- /dev/null
+++ b/lib/libc/locale/islower.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.
+.\"
+.\" @(#)islower.3 8.1 (Berkeley) 6/4/93
+.\"
+.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:
+.sp
+.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..dc04d50
--- /dev/null
+++ b/lib/libc/locale/isprint.3
@@ -0,0 +1,87 @@
+.\" 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
+.\"
+.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:
+.sp
+.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\ ``\'' \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..d5b3722
--- /dev/null
+++ b/lib/libc/locale/ispunct.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.
+.\"
+.\" @(#)ispunct.3 8.1 (Berkeley) 6/4/93
+.\"
+.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:
+.sp
+.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\ ``\'' \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..fb077e4
--- /dev/null
+++ b/lib/libc/locale/isspace.3
@@ -0,0 +1,70 @@
+.\" 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
+.\"
+.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:
+.sp
+.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..6035f09
--- /dev/null
+++ b/lib/libc/locale/isupper.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.
+.\"
+.\" @(#)isupper.3 8.1 (Berkeley) 6/4/93
+.\"
+.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:
+.sp
+.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
+.Xr 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..ec1a502
--- /dev/null
+++ b/lib/libc/locale/isxdigit.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.
+.\"
+.\" @(#)isxdigit.3 8.1 (Berkeley) 6/4/93
+.\"
+.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:
+.sp
+.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..d843a02
--- /dev/null
+++ b/lib/libc/locale/mbrune.3
@@ -0,0 +1,157 @@
+.\" 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
+.\"
+.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 NULL
+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 euc 4 ,
+.Xr mbrune 3 ,
+.Xr rune 3 ,
+.Xr setlocale 3 ,
+.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/multibyte.3 b/lib/libc/locale/multibyte.3
new file mode 100644
index 0000000..3ea10e5
--- /dev/null
+++ b/lib/libc/locale/multibyte.3
@@ -0,0 +1,241 @@
+.\" 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
+.\"
+.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" "int 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 euc 4 ,
+.Xr mbrune 3 ,
+.Xr rune 3 ,
+.Xr setlocale 3 ,
+.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..659133f
--- /dev/null
+++ b/lib/libc/locale/rune.3
@@ -0,0 +1,269 @@
+.\" 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
+.\"
+.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"
+.sp
+.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
+\fB<ctype.h>\fP.
+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
+.Fa 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/\fIlocale\fP/LC_CTYPE
+.It Pa /usr/share/locale/\fIlocale\fP/LC_CTYPE
+binary LC_CTYPE file for the locale \fIlocale\fP.
+.El
+.Sh "SEE ALSO
+.Xr euc 4 ,
+.Xr mbrune 3 ,
+.Xr setlocale 3 ,
+.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..ba128c6
--- /dev/null
+++ b/lib/libc/locale/runetype.c
@@ -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
+ * 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_RUNE_T_ c;
+{
+#ifdef XPG4
+ int x;
+ _RuneRange *rr = &_CurrentRuneLocale->runetype_ext;
+ _RuneEntry *re = rr->ranges;
+#endif
+
+ if (c == EOF)
+ return(0);
+ if (c < 0) {
+ if (c >= -128) /* signed char */
+ return(_CurrentRuneLocale->runetype[(unsigned char)c]);
+ else
+ return(0);
+ }
+
+#ifdef XPG4
+ 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..f6b75b6
--- /dev/null
+++ b/lib/libc/locale/setlocale.3
@@ -0,0 +1,324 @@
+.\" 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
+.\"
+.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_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/\fIlocale\fP/\fIcategory\fP
+.It Pa /usr/share/locale/\fIlocale\fP/\fIcategory\fP
+locale file for the locale \fIlocale\fP
+and the category \fIcategory\fP.
+.El
+.Sh "SEE ALSO
+.Xr euc 4 ,
+.Xr mbrune 3 ,
+.Xr multibyte 3 ,
+.Xr rune 3 ,
+.Xr strcoll 3 ,
+.Xr strxfrm 3 ,
+.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 4.4BSD.
+.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..11f2139
--- /dev/null
+++ b/lib/libc/locale/setlocale.c
@@ -0,0 +1,284 @@
+/*
+ * 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)setlocale.c 8.1 (Berkeley) 7/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <locale.h>
+#include <rune.h>
+#include <stdlib.h>
+#include <string.h>
+#include "collate.h"
+
+/*
+ * Category names for getenv()
+ */
+static char *categories[_LC_LAST] = {
+ "LC_ALL",
+ "LC_COLLATE",
+ "LC_CTYPE",
+ "LC_MONETARY",
+ "LC_NUMERIC",
+ "LC_TIME",
+};
+
+/*
+ * Current locales for each category
+ */
+static char current_categories[_LC_LAST][32] = {
+ "C",
+ "C",
+ "C",
+ "C",
+ "C",
+ "C",
+};
+
+/*
+ * The locales we are going to try and load
+ */
+static char new_categories[_LC_LAST][32];
+
+static char current_locale_string[_LC_LAST * 33];
+char *_PathLocale;
+
+static char *currentlocale __P((void));
+static char *loadlocale __P((int));
+
+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 found, i, len;
+ char *env, *r;
+
+ if (!_PathLocale && !(_PathLocale = getenv("PATH_LOCALE")))
+ _PathLocale = _PATH_LOCALE;
+
+ if (category < 0 || category >= _LC_LAST)
+ return (NULL);
+
+ if (!locale)
+ return (category ?
+ 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 (!env)
+ env = getenv(categories[0]);
+
+ if (!env)
+ env = getenv("LANG");
+
+ if (!env)
+ env = "C";
+
+ (void) strncpy(new_categories[category], env, 31);
+ new_categories[category][31] = 0;
+ if (!category) {
+ for (i = 1; i < _LC_LAST; ++i) {
+ if (!(env = getenv(categories[i])))
+ env = new_categories[0];
+ (void)strncpy(new_categories[i], env, 31);
+ new_categories[i][31] = 0;
+ }
+ }
+ } else if (category) {
+ (void)strncpy(new_categories[category], locale, 31);
+ new_categories[category][31] = 0;
+ } else {
+ if ((r = strchr(locale, '/')) == 0) {
+ for (i = 1; i < _LC_LAST; ++i) {
+ (void)strncpy(new_categories[i], locale, 31);
+ new_categories[i][31] = 0;
+ }
+ } else {
+ for (i = 1; r[1] == '/'; ++r);
+ if (!r[1])
+ return (NULL); /* Hmm, just slashes... */
+ do {
+ len = r - locale > 31 ? 31 : r - locale;
+ (void)strncpy(new_categories[i++], locale, len);
+ new_categories[i++][len] = 0;
+ locale = r;
+ while (*locale == '/')
+ ++locale;
+ while (*++r && *r != '/');
+ } while (*locale);
+ while (i < _LC_LAST)
+ (void)strcpy(new_categories[i],
+ new_categories[i-1]);
+ }
+ }
+
+ if (category)
+ return (loadlocale(category));
+
+ found = 0;
+ for (i = 1; i < _LC_LAST; ++i)
+ if (loadlocale(i) != NULL)
+ found = 1;
+ if (found)
+ return (currentlocale());
+ return (NULL);
+}
+
+/* To be compatible with crt0 hack */
+void
+_startup_setlocale(category, locale)
+ int category;
+ const char *locale;
+{
+#ifndef XPG4
+ (void) setlocale(category, locale);
+#endif
+}
+
+static char *
+currentlocale()
+{
+ int i, len;
+
+ (void)strcpy(current_locale_string, current_categories[1]);
+
+ for (i = 2; i < _LC_LAST; ++i)
+ if (strcmp(current_categories[1], current_categories[i])) {
+ len = strlen(current_categories[1]) + 1 +
+ strlen(current_categories[2]) + 1 +
+ strlen(current_categories[3]) + 1 +
+ strlen(current_categories[4]) + 1 +
+ strlen(current_categories[5]) + 1;
+ if (len > sizeof(current_locale_string))
+ return NULL;
+ (void) strcpy(current_locale_string, current_categories[1]);
+ (void) strcat(current_locale_string, "/");
+ (void) strcat(current_locale_string, current_categories[2]);
+ (void) strcat(current_locale_string, "/");
+ (void) strcat(current_locale_string, current_categories[3]);
+ (void) strcat(current_locale_string, "/");
+ (void) strcat(current_locale_string, current_categories[4]);
+ (void) strcat(current_locale_string, "/");
+ (void) strcat(current_locale_string, current_categories[5]);
+ break;
+ }
+ return (current_locale_string);
+}
+
+static char *
+loadlocale(category)
+ int category;
+{
+#if 0
+ char name[PATH_MAX];
+#endif
+ if (strcmp(new_categories[category],
+ current_categories[category]) == 0)
+ return (current_categories[category]);
+
+ if (category == LC_CTYPE) {
+#ifdef XPG4
+ if (_xpg4_setrunelocale(new_categories[LC_CTYPE]))
+#else
+ if (setrunelocale(new_categories[LC_CTYPE]))
+#endif
+ return (NULL);
+ (void)strcpy(current_categories[LC_CTYPE],
+ new_categories[LC_CTYPE]);
+ return (current_categories[LC_CTYPE]);
+ }
+
+ if (category == LC_COLLATE) {
+ if (__collate_load_tables(new_categories[LC_COLLATE]) < 0)
+ return (NULL);
+ (void)strcpy(current_categories[LC_COLLATE],
+ new_categories[LC_COLLATE]);
+ return (current_categories[LC_COLLATE]);
+ }
+
+ if (category == LC_TIME) {
+ if (__time_load_locale(new_categories[LC_TIME]) < 0)
+ return (NULL);
+ (void)strcpy(current_categories[LC_TIME],
+ new_categories[LC_TIME]);
+ return (current_categories[LC_TIME]);
+ }
+
+ if (!strcmp(new_categories[category], "C") ||
+ !strcmp(new_categories[category], "POSIX")) {
+
+ /*
+ * Some day this will need to reset the locale to the default
+ * C locale. Since we have no way to change them as of yet,
+ * there is no need to reset them.
+ */
+ (void)strcpy(current_categories[category],
+ new_categories[category]);
+ return (current_categories[category]);
+ }
+#if 0
+ /*
+ * Some day we will actually look at this file.
+ */
+ (void)snprintf(name, sizeof(name), "%s/%s/%s",
+ _PathLocale, new_categories[category], categories[category]);
+#endif
+ switch (category) {
+ case LC_MONETARY:
+ case LC_NUMERIC:
+ return (NULL);
+ }
+ /* Just in case...*/
+ return (NULL);
+}
diff --git a/lib/libc/locale/setrunelocale.c b/lib/libc/locale/setrunelocale.c
new file mode 100644
index 0000000..4889667
--- /dev/null
+++ b/lib/libc/locale/setrunelocale.c
@@ -0,0 +1,119 @@
+/*-
+ * 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>
+
+char *_PathLocale;
+
+extern int _none_init __P((_RuneLocale *));
+#ifdef XPG4
+extern int _UTF2_init __P((_RuneLocale *));
+extern int _EUC_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)
+ return(EFAULT);
+
+ /*
+ * The "C" and "POSIX" locale are always here.
+ */
+ if (!*encoding || !strcmp(encoding, "C") || !strcmp(encoding, "POSIX")) {
+ _CurrentRuneLocale = &_DefaultRuneLocale;
+ return(0);
+ }
+
+ if (!_PathLocale && !(_PathLocale = getenv("PATH_LOCALE")))
+ _PathLocale = _PATH_LOCALE;
+
+ (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));
+#endif
+ } else
+ return(EINVAL);
+}
+
diff --git a/lib/libc/locale/table.c b/lib/libc/locale/table.c
new file mode 100644
index 0000000..e9de306
--- /dev/null
+++ b/lib/libc/locale/table.c
@@ -0,0 +1,192 @@
+/*-
+ * 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[] = "@(#)table.c 8.1 (Berkeley) 6/27/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+
+#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,
+ /*80*/ _C, _C, _C, _C,
+ _C, _C, _C, _C,
+ /*88*/ _C, _C, _C, _C,
+ _C, _C, _C, _C,
+ /*90*/ _C, _C, _C, _C,
+ _C, _C, _C, _C,
+ /*98*/ _C, _C, _C, _C,
+ _C, _C, _C, _C,
+ /*A0*/ _R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ /*A8*/ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ /*B0*/ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ /*B8*/ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ _P|_R|_G, _P|_R|_G, _P|_R|_G, _P|_R|_G,
+ /*C0*/ _R|_G, _R|_G, _R|_G, _R|_G,
+ _R|_G, _R|_G, _R|_G, _R|_G,
+ /*C8*/ _R|_G, _R|_G, _R|_G, _R|_G,
+ _R|_G, _R|_G, _R|_G, _R|_G,
+ /*D0*/ _R|_G, _R|_G, _R|_G, _R|_G,
+ _R|_G, _R|_G, _R|_G, _P|_R|_G,
+ /*D8*/ _R|_G, _R|_G, _R|_G, _R|_G,
+ _R|_G, _R|_G, _R|_G, _R|_G,
+ /*E0*/ _R|_G, _R|_G, _R|_G, _R|_G,
+ _R|_G, _R|_G, _R|_G, _R|_G,
+ /*E8*/ _R|_G, _R|_G, _R|_G, _R|_G,
+ _R|_G, _R|_G, _R|_G, _R|_G,
+ /*F0*/ _R|_G, _R|_G, _R|_G, _R|_G,
+ _R|_G, _R|_G, _R|_G, _P|_R|_G,
+ /*F8*/ _R|_G, _R|_G, _R|_G, _R|_G,
+ _R|_G, _R|_G, _R|_G, _R|_G,
+ },
+ { 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;
diff --git a/lib/libc/locale/toascii.3 b/lib/libc/locale/toascii.3
new file mode 100644
index 0000000..54fa292
--- /dev/null
+++ b/lib/libc/locale/toascii.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.
+.\"
+.\" @(#)toascii.3 8.1 (Berkeley) 6/4/93
+.\"
+.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 isascii 3 ,
+.Xr isalnum 3 ,
+.Xr isalpha 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 tolower 3 ,
+.Xr toupper 3 ,
+.Xr stdio 3 ,
+.Xr ascii 7
diff --git a/lib/libc/locale/tolower.3 b/lib/libc/locale/tolower.3
new file mode 100644
index 0000000..49ce819
--- /dev/null
+++ b/lib/libc/locale/tolower.3
@@ -0,0 +1,88 @@
+.\" 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
+.\"
+.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 isascii 3 ,
+.Xr isalnum 3 ,
+.Xr isalpha 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 toupper 3 ,
+.Xr stdio 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..e72a52c
--- /dev/null
+++ b/lib/libc/locale/tolower.c
@@ -0,0 +1,69 @@
+/*-
+ * 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_RUNE_T_
+___tolower(c)
+ _BSD_RUNE_T_ c;
+{
+#ifdef XPG4
+ int x;
+ _RuneRange *rr = &_CurrentRuneLocale->maplower_ext;
+ _RuneEntry *re = rr->ranges;
+#endif
+
+ if (c == EOF)
+ return(EOF);
+ if (c < 0) {
+ if (c >= -128) /* signed char */
+ return(_CurrentRuneLocale->maplower[(unsigned char)c]);
+ else
+ return(c);
+ }
+#ifdef XPG4
+ 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..cd0b36e
--- /dev/null
+++ b/lib/libc/locale/toupper.3
@@ -0,0 +1,88 @@
+.\" 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
+.\"
+.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 isascii 3 ,
+.Xr isalnum 3 ,
+.Xr isalpha 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 stdio 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..08be64b
--- /dev/null
+++ b/lib/libc/locale/toupper.c
@@ -0,0 +1,68 @@
+/*-
+ * 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_RUNE_T_
+___toupper(c)
+ _BSD_RUNE_T_ c;
+{
+#ifdef XPG4
+ int x;
+ _RuneRange *rr = &_CurrentRuneLocale->mapupper_ext;
+ _RuneEntry *re = rr->ranges;
+#endif
+
+ if (c == EOF)
+ return(EOF);
+ if (c < 0) {
+ if (c >= -128) /* signed char */
+ return(_CurrentRuneLocale->mapupper[(unsigned char)c]);
+ else
+ return(c);
+ }
+#ifdef XPG4
+ 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..20a9587
--- /dev/null
+++ b/lib/libc/locale/utf2.4
@@ -0,0 +1,86 @@
+.\" 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
+.\"
+.Dd "June 4, 1993"
+.Dt UTF2 4
+.Os
+.Sh NAME
+.Nm UTF2
+.Nd "Universal character set Transformation Format encoding of runes
+.Sh SYNOPSIS
+\fBENCODING "UTF2"\fP
+.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 - 0x03ff] [00000bbb.bbbbbbbb] -> 110bbbbb, 10bbbbbb
+[0x0400 - 0xffff] [bbbbbbbb.bbbbbbbb] -> 1110bbbb, 10bbbbbb, 10bbbbbb
+.Ed
+.sp
+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
+.sp
+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..20a9587
--- /dev/null
+++ b/lib/libc/locale/utf2.5
@@ -0,0 +1,86 @@
+.\" 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
+.\"
+.Dd "June 4, 1993"
+.Dt UTF2 4
+.Os
+.Sh NAME
+.Nm UTF2
+.Nd "Universal character set Transformation Format encoding of runes
+.Sh SYNOPSIS
+\fBENCODING "UTF2"\fP
+.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 - 0x03ff] [00000bbb.bbbbbbbb] -> 110bbbbb, 10bbbbbb
+[0x0400 - 0xffff] [bbbbbbbb.bbbbbbbb] -> 1110bbbb, 10bbbbbb, 10bbbbbb
+.Ed
+.sp
+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
+.sp
+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..c46dd93
--- /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 _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/net/Makefile.inc b/lib/libc/net/Makefile.inc
new file mode 100644
index 0000000..4bcd682
--- /dev/null
+++ b/lib/libc/net/Makefile.inc
@@ -0,0 +1,43 @@
+# @(#)Makefile.inc 8.2 (Berkeley) 9/5/93
+
+# machine-independent net sources
+.PATH: ${.CURDIR}/${MACHINE}/net ${.CURDIR}/net
+
+SRCS+= 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 inet_lnaof.c \
+ inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \
+ iso_addr.c linkaddr.c ns_addr.c ns_ntoa.c rcmd.c recv.c res_comp.c \
+ res_debug.c res_init.c res_mkquery.c res_query.c res_send.c \
+ send.c ether_addr.c
+
+# machine-dependent net sources
+.include "${.CURDIR}/${MACHINE}/net/Makefile.inc"
+
+MAN3+= net/byteorder.3 net/ethers.3 net/gethostbyname.3 net/getnetent.3 \
+ net/getprotoent.3 net/getservent.3 net/inet.3 net/linkaddr.3 \
+ net/ns.3 net/rcmd.3 net/resolver.3
+
+MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \
+ byteorder.3 ntohs.3
+MLINKS+=ethers.3 ether_line.3 ethers.3 ether_aton.3 ethers.3 ether_ntoa.3 \
+ ethers.3 ether_ntohost.3 ethers.3 ether_hostton.3
+MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \
+ gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \
+ gethostbyname.3 herror.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_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 inet.3 inet_aton.3
+MLINKS+=linkaddr.3 linkntoa.3
+MLINKS+=ns.3 ns_addr.3 ns.3 ns_ntoa.3
+MLINKS+=rcmd.3 rresvport.3 rcmd.3 iruserok.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_send.3 resolver.3 res_query.3 \
+ resolver.3 res_search.3
diff --git a/lib/libc/net/byteorder.3 b/lib/libc/net/byteorder.3
new file mode 100644
index 0000000..666521b
--- /dev/null
+++ b/lib/libc/net/byteorder.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.
+.\"
+.\" @(#)byteorder.3 8.1 (Berkeley) 6/4/93
+.\"
+.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..711bb7d
--- /dev/null
+++ b/lib/libc/net/ether_addr.c
@@ -0,0 +1,219 @@
+/*
+ * 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
+ *
+ * $Id: ether_addr.c,v 1.1 1995/04/02 01:31:17 wpaul Exp $
+ */
+
+
+#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/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.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;
+
+ i = sscanf(a, "%x:%x:%x:%x:%x:%x", o.octet[0], o.octet[1], o.octet[2],
+ o.octet[3], o.octet[4], o.octet[5]);
+ if (i != 6)
+ return (NULL);
+ 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];
+ 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)) {
+ free(result);
+ continue;
+ }
+ strncpy((char *)&buf, result, resultlen);
+ 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, (char *)&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];
+ 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)) {
+ free(result);
+ continue;
+ }
+ strncpy((char *)&buf, result, resultlen);
+ free(result);
+ }
+#endif
+ if (!ether_line(&buf, &local_ether, &local_host)) {
+ if (!strcmp(hostname, (char *)&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..337618e
--- /dev/null
+++ b/lib/libc/net/ethers.3
@@ -0,0 +1,185 @@
+.\" 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.
+.\"
+.\" $Id$
+.\"
+.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/if.h>
+.Fd #include <netinet/in.h>
+.Fd #include <netinet/if_ether.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
+/*
+ * Structure of a 48-bit Ethernet address.
+ */
+struct ether_addr {
+ u_char octet[6];
+};
+.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 NULL pointer. Likewise,
+.Fn ether_aton
+returns a pointer to an
+.Ar ether_addr
+structure on success and a 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
+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 ethers 5 ,
+.Xr yp 8
+.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 was written for and first appeared in FreeBSD 2.1.
diff --git a/lib/libc/net/gethostbydns.c b/lib/libc/net/gethostbydns.c
new file mode 100644
index 0000000..7b1e2d6
--- /dev/null
+++ b/lib/libc/net/gethostbydns.c
@@ -0,0 +1,551 @@
+/*-
+ * 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[] = "$Id: gethostbydns.c,v 1.6 1995/08/21 09:15:32 bde Exp $";
+#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 <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 MAXALIASES 35
+#define MAXADDRS 35
+
+#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */
+
+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 struct in_addr host_addr;
+static FILE *hostf = NULL;
+static int stayopen = 0;
+
+#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;
+
+#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
+
+
+#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
+
+static struct hostent *
+gethostanswer(answer, anslen, qname, qclass, qtype)
+ const querybuf *answer;
+ int anslen;
+ const char *qname;
+ int qclass, qtype;
+{
+ register const HEADER *hp;
+ register const u_char *cp;
+ register int n;
+ const u_char *eom;
+ char *bp, **ap, **hap;
+ int type, class, buflen, ancount, qdcount;
+ int haveanswer, had_error;
+ int toobig = 0;
+ char tbuf[MAXDNAME+1];
+
+ host.h_name = NULL;
+ eom = answer->buf + anslen;
+ /*
+ * find first satisfactory answer
+ */
+ hp = &answer->hdr;
+ ancount = ntohs(hp->ancount);
+ qdcount = ntohs(hp->qdcount);
+ bp = hostbuf;
+ buflen = sizeof hostbuf;
+ cp = answer->buf + HFIXEDSZ;
+ if (qdcount != 1) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ if ((n = dn_expand(answer->buf, eom, cp, bp, buflen)) < 0) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ cp += n + QFIXEDSZ;
+ if (qtype == T_A) {
+ /* 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 */
+ 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;
+ while (ancount-- > 0 && cp < eom && !had_error) {
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if (n < 0) {
+ had_error++;
+ continue;
+ }
+ cp += n; /* name */
+ type = _getshort(cp);
+ cp += INT16SZ; /* type */
+ class = _getshort(cp);
+ cp += INT16SZ + INT32SZ; /* class, TTL */
+ n = _getshort(cp);
+ cp += INT16SZ; /* len */
+ if (class != qclass) {
+ /* XXX - debug? syslog? */
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ if (qtype == T_A && type == T_CNAME) {
+ if (ap >= &host_aliases[MAXALIASES-1])
+ continue;
+ n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
+ if (n < 0) {
+ had_error++;
+ continue;
+ }
+ cp += n;
+ if (host.h_name && strcasecmp(host.h_name, bp) != 0) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "gethostby*.gethostanswer: asked for \"%s\", got CNAME for \"%s\"",
+ host.h_name, bp);
+ continue; /* XXX - had_error++ ? */
+ }
+ /* Store alias. */
+ *ap++ = bp;
+ n = strlen(bp) + 1; /* for the \0 */
+ bp += n;
+ buflen -= n;
+ /* Get canonical name. */
+ n = strlen(tbuf) + 1; /* for the \0 */
+ if (n > buflen) {
+ had_error++;
+ continue;
+ }
+ strcpy(bp, tbuf);
+ host.h_name = bp;
+ bp += n;
+ buflen -= n;
+ continue;
+ }
+ if (type != qtype) {
+ /* CNAME->PTR should not cause a log message. */
+ if (!(qtype == T_PTR && type == T_CNAME))
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"",
+ qname, p_class(qclass), p_type(qtype),
+ p_type(type));
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ switch (type) {
+ case T_PTR:
+ if (strcasecmp(qname, 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) {
+ had_error++;
+ break;
+ }
+#if MULTI_PTRS_ARE_ALIASES
+ cp += n;
+ 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 */
+ bp += n;
+ buflen -= n;
+ }
+ break;
+#else
+ host.h_name = bp;
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+#endif
+ case T_A:
+ if (strcasecmp(host.h_name, bp) != 0) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ AskedForGot, host.h_name, bp);
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ if (haveanswer) {
+ if (n != host.h_length) {
+ cp += n;
+ continue;
+ }
+ } else {
+ register int nn;
+
+ host.h_length = n;
+ host.h_addrtype = (class == C_IN)
+ ? AF_INET
+ : AF_UNSPEC;
+ 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;
+ cp += n;
+ break;
+ default:
+ dprintf("Impossible condition (type=%d)\n", type);
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ } /*switch*/
+ if (!had_error)
+ haveanswer++;
+ } /*while*/
+ 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 &&
+ qclass == C_IN && qtype == T_A)
+ addrsort(h_addr_ptrs, haveanswer);
+# endif /*RESOLVSORT*/
+ if (!host.h_name) {
+ n = strlen(qname) + 1; /* for the \0 */
+ strcpy(bp, qname);
+ host.h_name = bp;
+ }
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+ } else {
+ h_errno = TRY_AGAIN;
+ return (NULL);
+ }
+}
+
+struct hostent *
+_gethostbydnsname(name)
+ const char *name;
+{
+ querybuf buf;
+ register const char *cp;
+ int n;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+
+ /*
+ * 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(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_aton(name, &host_addr)) {
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ strncpy(hostbuf, name, MAXDNAME);
+ hostbuf[MAXDNAME] = '\0';
+ host.h_name = hostbuf;
+ host.h_aliases = host_aliases;
+ host_aliases[0] = NULL;
+ host.h_addrtype = AF_INET;
+ host.h_length = INT32SZ;
+ h_addr_ptrs[0] = (char *)&host_addr;
+ h_addr_ptrs[1] = NULL;
+ host.h_addr_list = h_addr_ptrs;
+ return (&host);
+ }
+ if (!isdigit(*cp) && *cp != '.')
+ break;
+ }
+
+ if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
+ dprintf("res_search failed (%d)\n", n);
+ return (NULL);
+ }
+ return (gethostanswer(&buf, n, name, C_IN, T_A));
+}
+
+struct hostent *
+_gethostbydnsaddr(addr, len, type)
+ const char *addr;
+ int len, type;
+{
+ int n;
+ querybuf buf;
+ register struct hostent *hp;
+ char qbuf[MAXDNAME+1];
+#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 (type != AF_INET) {
+ errno = EAFNOSUPPORT;
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
+ ((unsigned)addr[3] & 0xff),
+ ((unsigned)addr[2] & 0xff),
+ ((unsigned)addr[1] & 0xff),
+ ((unsigned)addr[0] & 0xff));
+ 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, C_IN, T_PTR)))
+ return (NULL); /* h_errno was set by gethostanswer() */
+#ifdef SUNSECURITY
+ /*
+ * 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 = type;
+ hp->h_length = len;
+ h_addr_ptrs[0] = (char *)&host_addr;
+ h_addr_ptrs[1] = NULL;
+ host_addr = *(struct in_addr *)addr;
+ h_errno = NETDB_SUCCESS;
+ return (hp);
+}
+
+void
+_sethostdnsent(stayopen)
+ int stayopen;
+{
+ 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..4b616cd
--- /dev/null
+++ b/lib/libc/net/gethostbyht.c
@@ -0,0 +1,182 @@
+/*-
+ * 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[] = "$Id: gethostbyht.c,v 1.1 1994/09/25 02:12:11 pst Exp $";
+#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>
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+
+static struct hostent host;
+static char *host_aliases[MAXALIASES];
+static char hostbuf[BUFSIZ+1];
+static FILE *hostf = NULL;
+static char hostaddr[MAXADDRS];
+static char *host_addrs[2];
+static int stayopen = 0;
+
+void
+_sethosthtent(f)
+ int f;
+{
+ if (hostf == NULL)
+ 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;
+
+ if (hostf == NULL && (hostf = fopen(_PATH_HOSTS, "r" )) == NULL)
+ return (NULL);
+again:
+ if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
+ return (NULL);
+ if (*p == '#')
+ goto again;
+ cp = strpbrk(p, "#\n");
+ if (cp == NULL)
+ goto again;
+ *cp = '\0';
+ cp = strpbrk(p, " \t");
+ if (cp == NULL)
+ goto again;
+ *cp++ = '\0';
+ /* THIS STUFF IS INTERNET SPECIFIC */
+ host.h_addr_list = host_addrs;
+ host.h_addr = hostaddr;
+ *((u_int32_t *)host.h_addr) = inet_addr(p);
+ host.h_length = sizeof (u_int32_t);
+ host.h_addrtype = AF_INET;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ host.h_name = cp;
+ q = host.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 (&host);
+}
+
+struct hostent *
+_gethostbyhtname(name)
+ char *name;
+{
+ register struct hostent *p;
+ register char **cp;
+
+ sethostent(0);
+ while ((p = gethostent())) {
+ 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, type)
+ const char *addr;
+ int len, type;
+{
+ register struct hostent *p;
+
+ sethostent(0);
+ while ((p = gethostent()))
+ if (p->h_addrtype == type && !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..702a116
--- /dev/null
+++ b/lib/libc/net/gethostbyname.3
@@ -0,0 +1,249 @@
+.\" 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.
+.\"
+.\" @(#)gethostbyname.3 8.2 (Berkeley) 4/19/94
+.\"
+.Dd April 19, 1994
+.Dt GETHOSTBYNAME 3
+.Os BSD 4.2
+.Sh NAME
+.Nm gethostbyname ,
+.Nm gethostbyaddr ,
+.Nm gethostent ,
+.Nm sethostent ,
+.Nm endhostent ,
+.Nm herror
+.Nd get network host entry
+.Sh SYNOPSIS
+.Fd #include <netdb.h>
+.Fd extern struct h_errno;
+.Ft struct hostent *
+.Fn gethostbyname "char *name"
+.Ft struct hostent *
+.Fn gethostbyaddr "char *addr" "int len" "int type"
+.Ft struct hostent *
+.Fn gethostent void
+.Fn sethostent "int stayopen"
+.Fn endhostent void
+.Fn herror "char *string"
+.Sh DESCRIPTION
+The
+.Fn gethostbyname
+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 zero terminated array of alternate names for the host.
+.It Fa h_addrtype
+The type of address being returned; currently always
+.Dv AF_INET .
+.It Fa h_length
+The length, in bytes, of the address.
+.It Fa h_addr_list
+A zero 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.
+.Pp
+When using the nameserver,
+.Fn gethostbyname
+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 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
+or
+.Fn gethostbyaddr .
+Otherwise, queries are performed using
+.Tn UDP
+datagrams.
+.Pp
+The
+.Fn endhostent
+function
+closes the
+.Tn TCP
+connection.
+.Sh FILES
+.Bl -tag -width /etc/hosts -compact
+.It Pa /etc/hosts
+.El
+.Sh DIAGNOSTICS
+Error return status from
+.Fn gethostbyname
+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
+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 .
+.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..53b426d
--- /dev/null
+++ b/lib/libc/net/gethostbynis.c
@@ -0,0 +1,115 @@
+/*-
+ * 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[] = "@(#)$Id$";
+static char rcsid[] = "$Id$";
+#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>
+
+#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)
+ char *name, *map;
+{
+#ifdef YP
+ register char *cp, **q;
+ char *result;
+ int resultlen;
+ static struct hostent h;
+ static char *domain = (char *)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);
+
+ 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 = sizeof(u_long);
+ 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)
+ char *name;
+{
+ return _gethostbynis(name, "hosts.byname");
+}
+
+struct hostent *
+_gethostbynisaddr(name)
+ char *name;
+{
+ return _gethostbynis(name, "hosts.byaddr");
+}
diff --git a/lib/libc/net/gethostnamadr.c b/lib/libc/net/gethostnamadr.c
new file mode 100644
index 0000000..54f78d0
--- /dev/null
+++ b/lib/libc/net/gethostnamadr.c
@@ -0,0 +1,195 @@
+/*-
+ * 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[] = "@(#)$Id: gethostnamadr.c,v 1.6 1995/03/24 15:38:54 ache Exp $";
+static char rcsid[] = "$Id: gethostnamadr.c,v 1.6 1995/03/24 15:38:54 ache Exp $";
+#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>
+
+extern struct hostent * _gethostbyhtname __P((const char *));
+extern struct hostent * _gethostbydnsname __P((const char *));
+extern struct hostent * _gethostbynisname __P((const char *));
+extern struct hostent * _gethostbyhtaddr __P((const char *, int, int));
+extern struct hostent * _gethostbydnsaddr __P((const char *, int, int));
+extern struct hostent * _gethostbynisaddr __P((const char *, int, int));
+
+#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(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 = 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);
+ break;
+ case SERVICE_BIND:
+ hp = _gethostbydnsname(name);
+ break;
+ case SERVICE_NIS:
+ hp = _gethostbynisname(name);
+ 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;
+}
+
+void
+sethostent(stayopen)
+ int stayopen;
+{
+ _sethosthtent(stayopen);
+ _sethostdnsent(stayopen);
+}
+
+void
+endhostent()
+{
+ _endhosthtent();
+ _endhostdnsent();
+}
diff --git a/lib/libc/net/getnetbyaddr.c b/lib/libc/net/getnetbyaddr.c
new file mode 100644
index 0000000..fd3f260
--- /dev/null
+++ b/lib/libc/net/getnetbyaddr.c
@@ -0,0 +1,56 @@
+/*
+ * 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[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <netdb.h>
+
+extern int _net_stayopen;
+
+struct netent *
+getnetbyaddr(net, type)
+ register 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/getnetbydns.c b/lib/libc/net/getnetbydns.c
new file mode 100644
index 0000000..440ebf8
--- /dev/null
+++ b/lib/libc/net/getnetbydns.c
@@ -0,0 +1,305 @@
+/*-
+ * 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[] = "$Id: getnetbydns.c,v 1.3 1995/05/30 05:40:46 rgrimes Exp $";
+#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 <resolv.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <syslog.h>
+
+#define BYNAME 0
+#define BYADDR 1
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+
+#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;
+
+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[30], aux2[30], ans[30],
+ *in, *st, *pauxt, *bp, **ap,
+ *paux1 = &aux1[0],
+ *paux2 = &aux2[0],
+ flag = 0;
+static struct netent net_entry;
+static char *net_aliases[MAXALIASES],
+ netbuf[BUFSIZ+1];
+
+ /*
+ * 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 ((struct netent *) 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)
+ break;
+ cp += n;
+ ans[0] = '\0';
+ (void)strcpy(&ans[0], bp);
+ 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) {
+ 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);
+ }
+ net_entry.n_aliases++;
+ return (&net_entry);
+ } else {
+ h_errno = TRY_AGAIN;
+ return ((struct netent *) NULL);
+ }
+}
+
+struct netent *
+_getnetbydnsaddr(net, net_type)
+ register 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 */
+ (void)sprintf(qbuf, "0.0.0.%u.in-addr.arpa",
+ netbr[3]);
+ break;
+ case 2: /* Class B */
+ (void)sprintf(qbuf, "0.0.%u.%u.in-addr.arpa",
+ netbr[3], netbr[2]);
+ break;
+ case 1: /* Class C */
+ (void)sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa",
+ netbr[3], netbr[2], netbr[1]);
+ break;
+ case 0: /* Class D - E */
+ (void)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, buf.buf, sizeof buf.buf);
+ if (anslen < 0) {
+ if (_res.options & RES_DEBUG)
+ printf("res_query failed\n");
+ 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);
+}
+
+struct netent *
+_getnetbydnsname(net)
+ register const char *net;
+{
+ int anslen;
+ querybuf buf;
+ char qbuf[MAXDNAME];
+
+ (void)strcpy(&qbuf[0],net);
+ anslen = res_search(qbuf, C_IN, T_PTR, buf.buf, sizeof buf.buf);
+ if (anslen < 0) {
+ if (_res.options & RES_DEBUG)
+ printf("res_query failed\n");
+ 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..4f6439c
--- /dev/null
+++ b/lib/libc/net/getnetbyht.c
@@ -0,0 +1,159 @@
+/*
+ * 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[] = "@(#)getnetent.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 <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, BUFSIZ, 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 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..d87ca0f
--- /dev/null
+++ b/lib/libc/net/getnetbynis.c
@@ -0,0 +1,134 @@
+/*-
+ * 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[] = "@(#)$Id: getnetbynis.c,v 1.3 1995/05/30 05:40:47 rgrimes Exp $";
+static char rcsid[] = "$Id: getnetbynis.c,v 1.3 1995/05/30 05:40:47 rgrimes Exp $";
+#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>
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+
+#ifdef YP
+static char *host_aliases[MAXALIASES];
+#endif /* YP */
+
+static struct netent *
+_getnetbynis(name, map)
+ char *name, *map;
+{
+#ifdef YP
+ register char *cp, **q;
+ static char *result;
+ int resultlen;
+ static struct netent h;
+ static char *domain = (char *)NULL;
+
+ if (domain == (char *)NULL)
+ if (yp_get_default_domain (&domain))
+ return (NULL);
+
+ if (result) {
+ free(result);
+ result = 0;
+ }
+
+ if (yp_match(domain, map, name, strlen(name), &result, &resultlen))
+ return (NULL);
+
+ 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)
+ char *name;
+{
+ return _getnetbynis(name, "networks.byname");
+}
+
+struct netent *
+_getnetbynisaddr(addr, type)
+ long addr;
+ int type;
+{
+ struct in_addr in;
+ char *str, *cp;
+
+ if (type != AF_INET)
+ return (NULL);
+
+ in.s_addr = addr;
+ str = inet_ntoa(in);
+ cp = str + strlen(str) - 2;
+ while(!strcmp(cp, ".0")) {
+ *cp = '\0';
+ cp = str + strlen(str) - 2;
+ }
+
+ return _getnetbynis(str, "networks.byaddr");
+}
diff --git a/lib/libc/net/getnetent.3 b/lib/libc/net/getnetent.3
new file mode 100644
index 0000000..7514371c
--- /dev/null
+++ b/lib/libc/net/getnetent.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.
+.\"
+.\" @(#)getnetent.3 8.1 (Berkeley) 6/4/93
+.\"
+.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
+.Ft struct netent *
+.Fn getnetbyname "char *name"
+.Ft struct netent *
+.Fn getnetbyaddr "long net" "int type"
+.Fn setnetent "int stayopen"
+.Fn endnetent
+.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.
+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
+.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..5d99c8f
--- /dev/null
+++ b/lib/libc/net/getnetnamadr.c
@@ -0,0 +1,198 @@
+/*-
+ * 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[] = "@(#)$Id: getnetnamadr.c,v 1.3 1995/03/24 15:51:30 ache Exp $";
+static char rcsid[] = "$Id: getnetnamadr.c,v 1.3 1995/03/24 15:51:30 ache Exp $";
+#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>
+
+extern struct netent * _getnetbyhtname __P((const char *));
+extern struct netent * _getnetbydnsname __P((const char *));
+extern struct netent * _getnetbynisname __P((const char *));
+extern struct netent * _getnetbyhtaddr __P((long, int));
+extern struct netent * _getnetbydnsaddr __P((long, int));
+extern struct netent * _getnetbynisaddr __P((long, int));
+
+#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(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, type)
+ long addr;
+ int type;
+{
+ 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, type);
+ break;
+ case SERVICE_BIND:
+ hp = _getnetbydnsaddr(addr, type);
+ break;
+ case SERVICE_NIS:
+ hp = _getnetbynisaddr(addr, type);
+ 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..92f562b
--- /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..d5d610e
--- /dev/null
+++ b/lib/libc/net/getprotoent.3
@@ -0,0 +1,144 @@
+.\" 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
+.\"
+.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
+.Ft struct protoent *
+.Fn getprotobyname "char *name"
+.Ft struct protoent *
+.Fn getprotobynumber "int proto"
+.Fn setprotoent "int stayopen"
+.Fn endprotoent
+.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..3ee6754
--- /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..77bf813
--- /dev/null
+++ b/lib/libc/net/getservbyname.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[] = "@(#)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;
+
+ 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();
+ return (p);
+}
diff --git a/lib/libc/net/getservbyport.c b/lib/libc/net/getservbyport.c
new file mode 100644
index 0000000..0acb31b
--- /dev/null
+++ b/lib/libc/net/getservbyport.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[] = "@(#)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;
+
+ 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();
+ return (p);
+}
diff --git a/lib/libc/net/getservent.3 b/lib/libc/net/getservent.3
new file mode 100644
index 0000000..b9b2585
--- /dev/null
+++ b/lib/libc/net/getservent.3
@@ -0,0 +1,155 @@
+.\" 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.
+.\"
+.\" @(#)getservent.3 8.3 (Berkeley) 1/12/94
+.\"
+.Dd January 12, 1994
+.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 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..9fb47b6
--- /dev/null
+++ b/lib/libc/net/getservent.c
@@ -0,0 +1,189 @@
+/*
+ * 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;
+#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
+static int
+_getypservent(line)
+ char *line;
+{
+ static char *key = NULL;
+ static int keylen;
+ static char *yp_domain = NULL;
+ 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))) {
+ free(result);
+ 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);
+ }
+ }
+
+ strncpy(line, result, BUFSIZ - 1);
+ /* getservent() expects lines terminated with \n -- make it happy */
+ strcat(line, "\n");
+
+ 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 && _getypservent(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 == '+') {
+ if (!_getypservent(&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..9b94ee4
--- /dev/null
+++ b/lib/libc/net/herror.c
@@ -0,0 +1,112 @@
+/*-
+ * 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) 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[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: herror.c,v 1.2 1995/05/30 05:40:49 rgrimes Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.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]) };
+
+extern 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/inet.3 b/lib/libc/net/inet.3
new file mode 100644
index 0000000..9318f45
--- /dev/null
+++ b/lib/libc/net/inet.3
@@ -0,0 +1,195 @@
+.\" 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.
+.\"
+.\" @(#)inet.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.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/socket.h>
+.Fd #include <netinet/in.h>
+.Fd #include <arpa/inet.h>
+.Ft int
+.Fn inet_aton "char *cp" "struct in_addr *pin"
+.Ft unsigned long
+.Fn inet_addr "char *cp"
+.Ft unsigned long
+.Fn inet_network "char *cp"
+.Ft char *
+.Fn inet_ntoa "struct in_addr in"
+.Ft struct in_addr
+.Fn inet_makeaddr "int net" "int 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).
+.Sh DIAGNOSTICS
+The constant
+.Dv INADDR_NONE
+is returned by
+.Fn inet_addr
+and
+.Fn inet_network
+for malformed requests.
+.Sh SEE ALSO
+.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..f69d0fc
--- /dev/null
+++ b/lib/libc/net/inet_addr.c
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+
+/*
+ * Ascii internet address interpretation routine.
+ * The value returned is in network order.
+ */
+u_long
+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;
+{
+ register u_long val;
+ register int base, 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; base = 10;
+ if (*cp == '0') {
+ if (*++cp == 'x' || *cp == 'X')
+ base = 16, cp++;
+ else
+ base = 8;
+ }
+ while ((c = *cp) != '\0') {
+ if (isascii(c) && isdigit(c)) {
+ val = (val * base) + (c - '0');
+ cp++;
+ continue;
+ }
+ if (base == 16 && isascii(c) && isxdigit(c)) {
+ val = (val << 4) +
+ (c + 10 - (islower(c) ? 'a' : 'A'));
+ 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)
+ return (0);
+ *pp++ = val, cp++;
+ } else
+ break;
+ }
+ /*
+ * Check for trailing characters.
+ */
+ if (*cp && (!isascii(*cp) || !isspace(*cp)))
+ return (0);
+ /*
+ * 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)
+ return (0);
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+ if (addr)
+ addr->s_addr = htonl(val);
+ return (1);
+}
diff --git a/lib/libc/net/inet_lnaof.c b/lib/libc/net/inet_lnaof.c
new file mode 100644
index 0000000..406be30
--- /dev/null
+++ b/lib/libc/net/inet_lnaof.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[] = "@(#)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);
+}
diff --git a/lib/libc/net/inet_makeaddr.c b/lib/libc/net/inet_makeaddr.c
new file mode 100644
index 0000000..7976188
--- /dev/null
+++ b/lib/libc/net/inet_makeaddr.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[] = "@(#)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);
+}
diff --git a/lib/libc/net/inet_netof.c b/lib/libc/net/inet_netof.c
new file mode 100644
index 0000000..d6de694
--- /dev/null
+++ b/lib/libc/net/inet_netof.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[] = "@(#)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);
+}
diff --git a/lib/libc/net/inet_network.c b/lib/libc/net/inet_network.c
new file mode 100644
index 0000000..fda53b6
--- /dev/null
+++ b/lib/libc/net/inet_network.c
@@ -0,0 +1,93 @@
+/*
+ * 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_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;
+ register char c;
+ u_long parts[4], *pp = parts;
+ register int i;
+
+again:
+ val = 0; base = 10;
+ if (*cp == '0')
+ base = 8, cp++;
+ if (*cp == 'x' || *cp == 'X')
+ base = 16, cp++;
+ while (c = *cp) {
+ if (isdigit(c)) {
+ val = (val * base) + (c - '0');
+ cp++;
+ continue;
+ }
+ if (base == 16 && isxdigit(c)) {
+ val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
+ cp++;
+ continue;
+ }
+ break;
+ }
+ if (*cp == '.') {
+ if (pp >= parts + 4)
+ return (INADDR_NONE);
+ *pp++ = val, cp++;
+ goto again;
+ }
+ if (*cp && !isspace(*cp))
+ return (INADDR_NONE);
+ *pp++ = val;
+ n = pp - parts;
+ if (n > 4)
+ return (INADDR_NONE);
+ for (val = 0, i = 0; i < n; i++) {
+ val <<= 8;
+ val |= parts[i] & 0xff;
+ }
+ return (val);
+}
diff --git a/lib/libc/net/inet_ntoa.c b/lib/libc/net/inet_ntoa.c
new file mode 100644
index 0000000..a37b1db
--- /dev/null
+++ b/lib/libc/net/inet_ntoa.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[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Convert network-format internet address
+ * to base 256 d.d.d.d representation.
+ */
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+
+char *
+inet_ntoa(in)
+ struct in_addr in;
+{
+ static char b[18];
+ register char *p;
+
+ p = (char *)&in;
+#define UC(b) (((int)b)&0xff)
+ (void)snprintf(b, sizeof(b),
+ "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
+ return (b);
+}
diff --git a/lib/libc/net/iso_addr.3 b/lib/libc/net/iso_addr.3
new file mode 100644
index 0000000..0565373
--- /dev/null
+++ b/lib/libc/net/iso_addr.3
@@ -0,0 +1,110 @@
+.\" 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
+.\"
+.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..54e3206
--- /dev/null
+++ b/lib/libc/net/linkaddr.3
@@ -0,0 +1,131 @@
+.\" 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.
+.\"
+.\" @(#)linkaddr.3 8.1 (Berkeley) 7/28/93
+.\"
+.Dd July 28, 1993
+.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 4 ,
+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.
+.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 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/ns.3 b/lib/libc/net/ns.3
new file mode 100644
index 0000000..8646826
--- /dev/null
+++ b/lib/libc/net/ns.3
@@ -0,0 +1,130 @@
+.\" 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
+.\"
+.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..da8f8b4
--- /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, '#'))
+ 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_ntoa.c b/lib/libc/net/ns_ntoa.c
new file mode 100644
index 0000000..0f01f0b
--- /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", 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/rcmd.3 b/lib/libc/net/rcmd.3
new file mode 100644
index 0000000..641ed7f
--- /dev/null
+++ b/lib/libc/net/rcmd.3
@@ -0,0 +1,203 @@
+.\" 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.
+.\"
+.\" @(#)rcmd.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.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 writeable 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 2 )
+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..405dd8e
--- /dev/null
+++ b/lib/libc/net/rcmd.c
@@ -0,0 +1,501 @@
+/*
+ * 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.
+ */
+
+#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
+
+#define max(a, b) ((a > b) ? a : b)
+
+int __ivaliduser __P((FILE *, u_long, const char *, const char *));
+static int __icheckhost __P((u_long, 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);
+ sin.sin_family = hp->h_addrtype;
+ bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length);
+ sin.sin_port = rport;
+ 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, hp->h_length);
+ (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;
+ }
+ 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);
+ (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;
+
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ if (s < 0)
+ return (-1);
+ for (;;) {
+ 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);
+ }
+ (*alport)--;
+ if (*alport == IPPORT_RESERVED/2) {
+ (void)close(s);
+ errno = EAGAIN; /* close */
+ return (-1);
+ }
+ }
+}
+
+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_long 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)
+ u_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, 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_long 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_long),
+ AF_INET)) == NULL)
+ return (-1);
+ strcpy(hname, hp->h_name);
+
+ 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(*p) ? tolower(*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_long raddr;
+ register char *lhost;
+{
+ register struct hostent *hp;
+ register u_long laddr;
+ register char **pp;
+
+ /* Try for raw ip address first. */
+ if (isdigit(*lhost) && (long)(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_long)))
+ 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
index 6250f8f..a78a798 100644
--- a/lib/libc/net/res_comp.c
+++ b/lib/libc/net/res_comp.c
@@ -1,9 +1,7 @@
-/*
- * ++Copyright++ 1985, 1993
- * -
+/*-
* Copyright (c) 1985, 1993
- * The Regents of the University of California. All rights reserved.
- *
+ * The Regents of the University of California. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -14,12 +12,12 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -33,14 +31,14 @@
* 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
@@ -55,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_comp.c,v 8.3 1995/12/06 20:34:50 vixie Exp $";
+static char rcsid[] = "$Id: res_comp.c,v 1.2 1994/09/25 02:12:32 pst Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -66,12 +64,8 @@ static char rcsid[] = "$Id: res_comp.c,v 8.3 1995/12/06 20:34:50 vixie Exp $";
#include <resolv.h>
#include <ctype.h>
-#if defined(BSD) && (BSD >= 199103)
-# include <unistd.h>
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
+#include <unistd.h>
+#include <string.h>
static int dn_find __P((u_char *exp_dn, u_char *msg,
u_char **dnptrs, u_char **lastdnptr));
@@ -101,7 +95,7 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
/*
* fetch next label in domain name
*/
- while (n = *cp++) {
+ while ((n = *cp++)) {
/*
* Check for indirection
*/
@@ -116,14 +110,14 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
return (-1);
checked += n + 1;
while (--n >= 0) {
- if (((c = *cp++) == '.') || (c == '\\')) {
+ if ((c = *cp++) == '.') {
if (dn + n + 2 >= eom)
return (-1);
*dn++ = '\\';
}
*dn++ = c;
if (cp >= eomorig) /* out of range */
- return (-1);
+ return(-1);
}
break;
@@ -132,7 +126,7 @@ dn_expand(msg, eomorig, comp_dn, exp_dn, length)
len = cp - comp_dn + 1;
cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
if (cp < msg || cp >= eomorig) /* out of range */
- return (-1);
+ return(-1);
checked += 2;
/*
* Check for loops in the compressed name;
@@ -268,12 +262,12 @@ __dn_skipname(comp_dn, eom)
cp++;
break;
default: /* illegal type */
- return (-1);
+ return -1;
}
break;
}
if (cp > eom)
- return (-1);
+ return -1;
return (cp - comp_dn);
}
@@ -304,7 +298,7 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
dn = exp_dn;
sp = cp = *cpp;
- while (n = *cp++) {
+ while ((n = *cp++)) {
/*
* check for indirection
*/
@@ -324,12 +318,11 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
continue;
goto next;
- case INDIR_MASK: /* indirection */
- cp = msg + (((n & 0x3f) << 8) | *cp);
- break;
-
default: /* illegal type */
return (-1);
+
+ case INDIR_MASK: /* indirection */
+ cp = msg + (((n & 0x3f) << 8) | *cp);
}
}
if (*dn == '\0')
@@ -340,7 +333,11 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr)
}
/*
- * Routines to insert/extract short/long's.
+ * Routines to insert/extract short/long's. Must account for byte
+ * order and non-alignment problems. This code at least has the
+ * advantage of being portable.
+ *
+ * used by sendmail.
*/
u_int16_t
@@ -353,18 +350,6 @@ _getshort(msgp)
return (u);
}
-#ifdef NeXT
-/*
- * nExt machines have some funky library conventions, which we must maintain.
- */
-u_int16_t
-res_getshort(msgp)
- register const u_char *msgp;
-{
- return (_getshort(msgp));
-}
-#endif
-
u_int32_t
_getlong(msgp)
register const u_char *msgp;
@@ -394,36 +379,3 @@ __putlong(l, msgp)
{
PUTLONG(l, msgp);
}
-
-#ifdef ultrix
-/* ultrix 4.0 had some icky packaging in its libc.a. alias for it here.
- * there is more gunk of this kind over in res_debug.c.
- */
-#undef putshort
-void
-#if defined(__STDC__) || defined(__cplusplus)
-putshort(register u_short s, register u_char *msgp)
-#else
-putshort(s, msgp)
- register u_short s;
- register u_char *msgp;
-#endif
-{
- __putshort(s, msgp);
-}
-#undef putlong
-void
-putlong(l, msgp)
- register u_int32_t l;
- register u_char *msgp;
-{
- __putlong(l, msgp);
-}
-
-#undef dn_skipname
-dn_skipname(comp_dn, eom)
- const u_char *comp_dn, *eom;
-{
- return (__dn_skipname(comp_dn, eom));
-}
-#endif /* Ultrix 4.0 hackery */
diff --git a/lib/libc/net/res_config.h b/lib/libc/net/res_config.h
new file mode 100644
index 0000000..a1339d9
--- /dev/null
+++ b/lib/libc/net/res_config.h
@@ -0,0 +1,7 @@
+#define DEBUG 1 /* enable debugging code (needed for dig) */
+#undef ALLOW_T_UNSPEC /* enable the "unspec" RR type for old athena */
+#define RESOLVSORT /* allow sorting of addresses in gethostbyname */
+#undef RFC1535 /* comply with RFC1535 */
+#undef ALLOW_UPDATES /* destroy your system security */
+#undef USELOOPBACK /* res_init() bind to localhost */
+#undef SUNSECURITY /* verify gethostbyaddr() calls - WE DONT NEED IT */
diff --git a/lib/libc/net/res_debug.c b/lib/libc/net/res_debug.c
index aff28a4..b0a82b2 100644
--- a/lib/libc/net/res_debug.c
+++ b/lib/libc/net/res_debug.c
@@ -1,9 +1,7 @@
-/*
- * ++Copyright++ 1985, 1990, 1993
- * -
+/*-
* Copyright (c) 1985, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
+ * The Regents of the University of California. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -14,12 +12,12 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -33,14 +31,14 @@
* 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
@@ -55,29 +53,59 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_debug.c,v 8.7 1995/12/22 10:20:39 vixie Exp $";
+static char rcsid[] = "$Id: res_debug.c,v 1.4 1995/08/20 20:02:48 peter Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <netinet/in.h>
+#include <netiso/iso.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <stdio.h>
-#include <netdb.h>
#include <resolv.h>
-#if defined(BSD) && (BSD >= 199103)
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
-
-#if defined(USE_OPTIONS_H)
-# include "../conf/options.h"
-#endif
+#include <string.h>
+#include <netdb.h>
-extern const char *_res_opcodes[];
-extern const char *_res_resultcodes[];
+#include "res_config.h"
+
+const char *_res_opcodes[] = {
+ "QUERY",
+ "IQUERY",
+ "CQUERYM",
+ "CQUERYU", /* experimental */
+ "NOTIFY", /* experimental */
+ "5",
+ "6",
+ "7",
+ "8",
+ "UPDATEA",
+ "UPDATED",
+ "UPDATEDA",
+ "UPDATEM",
+ "UPDATEMA",
+ "ZONEINIT",
+ "ZONEREF",
+};
+
+const char *_res_resultcodes[] = {
+ "NOERROR",
+ "FORMERR",
+ "SERVFAIL",
+ "NXDOMAIN",
+ "NOTIMP",
+ "REFUSED",
+ "6",
+ "7",
+ "8",
+ "9",
+ "10",
+ "11",
+ "12",
+ "13",
+ "14",
+ "NOCHANGE",
+};
/* XXX: we should use getservbyport() instead. */
static const char *
@@ -175,13 +203,13 @@ do_rrset(msg, len, cp, cnt, pflag, file, hs)
* Print answer records.
*/
sflag = (_res.pfcode & pflag);
- if (n = ntohs(cnt)) {
+ if ((n = ntohs(cnt))) {
if ((!_res.pfcode) ||
((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
fprintf(file, hs);
while (--n >= 0) {
if ((!_res.pfcode) || sflag) {
- cp = p_rr(cp, msg, file);
+ cp = p_rr(cp, msg, file);
} else {
unsigned int dlen;
cp += __dn_skipname(cp, cp + MAXCDNAME);
@@ -209,18 +237,6 @@ __p_query(msg)
__fp_query(msg, stdout);
}
-#ifdef ultrix
-/* ultrix 4.0's packaging has some icky packaging. alias for it here.
- * there is more junk of this kind over in res_comp.c.
- */
-void
-p_query(msg)
- const u_char *msg;
-{
- __p_query(msg);
-}
-#endif
-
/*
* Print the current options.
* This is intended to be primarily a debugging routine.
@@ -274,10 +290,9 @@ __fp_nquery(msg, len, file)
ntohs(hp->id));
putc('\n', file);
}
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
- putc(';', file);
+ putc(';', file);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
- fprintf(file, "; flags:");
+ fprintf(file,"; flags:");
if (hp->qr)
fprintf(file, " qr");
if (hp->aa)
@@ -295,7 +310,7 @@ __fp_nquery(msg, len, file)
fprintf(file, ", Auth: %d", ntohs(hp->nscount));
fprintf(file, ", Addit: %d", ntohs(hp->arcount));
}
- if ((!_res.pfcode) || (_res.pfcode &
+ if ((!_res.pfcode) || (_res.pfcode &
(RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
putc('\n',file);
}
@@ -304,23 +319,11 @@ __fp_nquery(msg, len, file)
*/
if (n = ntohs(hp->qdcount)) {
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file, ";; QUESTIONS:\n");
+ fprintf(file,";; QUESTIONS:\n");
while (--n >= 0) {
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- fprintf(file, ";;\t");
+ fprintf(file,";;\t");
TruncTest(cp);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- cp = p_cdnname(cp, msg, len, file);
- else {
- int n;
- char name[MAXDNAME];
-
- if ((n = dn_expand(msg, msg+len, cp, name,
- sizeof name)) < 0)
- cp = NULL;
- else
- cp += n;
- }
+ cp = p_cdnname(cp, msg, len, file);
ErrorTest(cp);
TruncTest(cp);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
@@ -332,8 +335,7 @@ __fp_nquery(msg, len, file)
fprintf(file, ", class = %s\n",
__p_class(_getshort((u_char*)cp)));
cp += INT16SZ;
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
- putc('\n', file);
+ putc('\n', file);
}
}
/*
@@ -434,6 +436,7 @@ __p_rr(cp, msg, file)
{
int type, class, dlen, n, c;
struct in_addr inaddr;
+ struct iso_addr isoa;
const u_char *cp1, *cp2;
u_int32_t tmpttl, t;
int lcnt;
@@ -468,7 +471,7 @@ __p_rr(cp, msg, file)
case C_HS:
bcopy(cp, (char *)&inaddr, INADDRSZ);
if (dlen == 4) {
- fprintf(file, "\t%s", inet_ntoa(inaddr));
+ fprintf(file,"\t%s", inet_ntoa(inaddr));
cp += dlen;
} else if (dlen == 7) {
char *address;
@@ -504,11 +507,11 @@ __p_rr(cp, msg, file)
case T_ISDN:
cp2 = cp + dlen;
if (n = *cp++) {
- fprintf(file, "\t%.*s", n, cp);
+ fprintf(file,"\t%.*s", n, cp);
cp += n;
}
if ((cp < cp2) && (n = *cp++)) {
- fprintf(file, "\t%.*s", n, cp);
+ fprintf(file,"\t%.*s", n, cp);
cp += n;
} else if (type == T_HINFO)
fprintf(file, "\n;; *** Warning *** OS-type missing");
@@ -541,7 +544,7 @@ __p_rr(cp, msg, file)
case T_MX:
case T_AFSDB:
case T_RT:
- fprintf(file, "\t%d ", _getshort((u_char*)cp));
+ fprintf(file,"\t%d ", _getshort((u_char*)cp));
cp += INT16SZ;
if ((cp = p_fqname(cp, msg, file)) == NULL)
return (NULL);
@@ -557,7 +560,7 @@ __p_rr(cp, msg, file)
return (NULL);
break;
- case T_TXT:
+ case T_TXT:
case T_X25:
(void) fputs("\t\"", file);
cp2 = cp1 + dlen;
@@ -572,12 +575,16 @@ __p_rr(cp, msg, file)
}
}
putc('"', file);
- break;
-
- case T_NSAP:
- (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
+ break;
+
+ case T_NSAP:
+ isoa.isoa_len = dlen;
+ if (isoa.isoa_len > sizeof(isoa.isoa_genaddr))
+ isoa.isoa_len = sizeof(isoa.isoa_genaddr);
+ bcopy(cp, isoa.isoa_genaddr, isoa.isoa_len);
+ (void) fprintf(file, "\t%s", iso_ntoa(&isoa));
cp += dlen;
- break;
+ break;
case T_MINFO:
case T_RP:
@@ -598,7 +605,7 @@ __p_rr(cp, msg, file)
case T_UID:
case T_GID:
if (dlen == 4) {
- fprintf(file, "\t%u", _getlong((u_char*)cp));
+ fprintf(file,"\t%u", _getlong((u_char*)cp));
cp += INT32SZ;
}
break;
@@ -617,7 +624,7 @@ __p_rr(cp, msg, file)
while (cp < cp1 + dlen) {
c = *cp++;
do {
- if (c & 0200) {
+ if (c & 0200) {
if (lcnt == 0) {
fputs("\n\t\t\t", file);
lcnt = 5;
@@ -626,7 +633,7 @@ __p_rr(cp, msg, file)
putc(' ', file);
lcnt--;
}
- c <<= 1;
+ c <<= 1;
} while (++n & 07);
}
putc(')', file);
@@ -650,7 +657,7 @@ __p_rr(cp, msg, file)
#endif /* ALLOW_T_UNSPEC */
default:
- fprintf(file, "\t?%d?", type);
+ fprintf(file,"\t?%d?", type);
cp += dlen;
}
#if 0
@@ -659,7 +666,7 @@ __p_rr(cp, msg, file)
putc('\n', file);
#endif
if (cp - cp1 != dlen) {
- fprintf(file, ";; packet size error (found %d, dlen was %d)\n",
+ fprintf(file,";; packet size error (found %d, dlen was %d)\n",
cp - cp1, dlen);
cp = NULL;
}
diff --git a/lib/libc/net/res_init.c b/lib/libc/net/res_init.c
index c1f120d..1fff1dd 100644
--- a/lib/libc/net/res_init.c
+++ b/lib/libc/net/res_init.c
@@ -1,9 +1,7 @@
-/*
- * ++Copyright++ 1985, 1989, 1993
- * -
+/*-
* Copyright (c) 1985, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
+ * The Regents of the University of California. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -14,12 +12,12 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -33,14 +31,14 @@
* 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
@@ -55,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
-static char rcsid[] = "$Id: res_init.c,v 8.3 1995/06/29 09:26:28 vixie Exp $";
+static char rcsid[] = "$Id: res_init.c,v 1.5 1995/08/20 20:02:52 peter Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -68,46 +66,11 @@ static char rcsid[] = "$Id: res_init.c,v 8.3 1995/06/29 09:26:28 vixie Exp $";
#include <stdio.h>
#include <ctype.h>
#include <resolv.h>
-#if defined(BSD) && (BSD >= 199103)
-# include <unistd.h>
-# include <stdlib.h>
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
-
-/*-------------------------------------- info about "sortlist" --------------
- * Marc Majka 1994/04/16
- * Allan Nathanson 1994/10/29 (BIND 4.9.3.x)
- *
- * NetInfo resolver configuration directory support.
- *
- * Allow a NetInfo directory to be created in the hierarchy which
- * contains the same information as the resolver configuration file.
- *
- * - The local domain name is stored as the value of the "domain" property.
- * - The Internet address(es) of the name server(s) are stored as values
- * of the "nameserver" property.
- * - The name server addresses are stored as values of the "nameserver"
- * property.
- * - The search list for host-name lookup is stored as values of the
- * "search" property.
- * - The sortlist comprised of IP address netmask pairs are stored as
- * values of the "sortlist" property. The IP address and optional netmask
- * should be seperated by a slash (/) or ampersand (&) character.
- * - Internal resolver variables can be set from the value of the "options"
- * property.
- */
-#if defined(NeXT)
-# include <netinfo/ni.h>
-# define NI_PATH_RESCONF "/locations/resolver"
-# define NI_TIMEOUT 10
-static int netinfo_res_init __P((int *haveenv, int *havesearch));
-#endif
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
-#if defined(USE_OPTIONS_H)
-# include "../conf/options.h"
-#endif
+#include "res_config.h"
static void res_setoptions __P((char *, char *));
@@ -117,10 +80,6 @@ static const char sort_mask[] = "/&";
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.
*/
@@ -137,7 +96,7 @@ struct __res_state _res;
* 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
+ * 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.
*
@@ -249,9 +208,6 @@ res_init()
(line[sizeof(name) - 1] == ' ' || \
line[sizeof(name) - 1] == '\t'))
-#ifdef NeXT
- if (netinfo_res_init(&haveenv, &havesearch) == 0)
-#endif
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
/* read the config file */
while (fgets(buf, sizeof(buf), fp) != NULL) {
@@ -267,7 +223,8 @@ res_init()
cp++;
if ((*cp == '\0') || (*cp == '\n'))
continue;
- strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
+ (void)strncpy(_res.defdname, cp,
+ sizeof(_res.defdname) - 1);
if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
*cp = '\0';
havesearch = 0;
@@ -282,7 +239,8 @@ res_init()
cp++;
if ((*cp == '\0') || (*cp == '\n'))
continue;
- strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
+ (void)strncpy(_res.defdname, cp,
+ sizeof(_res.defdname) - 1);
if ((cp = strchr(_res.defdname, '\n')) != NULL)
*cp = '\0';
/*
@@ -311,7 +269,7 @@ res_init()
}
/* read nameservers to query */
if (MATCH(buf, "nameserver") && nserv < MAXNS) {
- struct in_addr a;
+ struct in_addr a;
cp = buf + sizeof("nameserver") - 1;
while (*cp == ' ' || *cp == '\t')
@@ -337,7 +295,7 @@ res_init()
break;
net = cp;
while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
- isascii(*cp) && !isspace(*cp))
+ isascii(*cp) && !isspace(*cp))
cp++;
n = *cp;
*cp = 0;
@@ -354,11 +312,11 @@ res_init()
if (inet_aton(net, &a)) {
_res.sort_list[nsort].mask = a.s_addr;
} else {
- _res.sort_list[nsort].mask =
+ _res.sort_list[nsort].mask =
net_mask(_res.sort_list[nsort].addr);
}
} else {
- _res.sort_list[nsort].mask =
+ _res.sort_list[nsort].mask =
net_mask(_res.sort_list[nsort].addr);
}
nsort++;
@@ -373,7 +331,7 @@ res_init()
continue;
}
}
- if (nserv > 1)
+ if (nserv > 1)
_res.nscount = nserv;
#ifdef RESOLVSORT
_res.nsort = nsort;
@@ -393,7 +351,7 @@ res_init()
#ifndef RFC1535
dots = 0;
- for (cp = _res.defdname; *cp; cp++)
+ for (cp = _res.defdname; *cp; cp++)
dots += (*cp == '.');
cp = _res.defdname;
@@ -413,7 +371,7 @@ res_init()
printf(";;\t..END..\n");
}
#endif /* DEBUG */
-#endif /* !RFC1535 */
+#endif /*!RFC1535*/
}
if ((cp = getenv("RES_OPTIONS")) != NULL)
@@ -439,7 +397,7 @@ res_setoptions(options, source)
while (*cp == ' ' || *cp == '\t')
cp++;
/* search for and process individual options */
- if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
+ if (!strncmp(cp, "ndots:", sizeof("ndots:")-1)) {
i = atoi(cp + sizeof("ndots:") - 1);
if (i <= RES_MAXNDOTS)
_res.ndots = i;
@@ -449,7 +407,7 @@ res_setoptions(options, source)
if (_res.options & RES_DEBUG)
printf(";;\tndots=%d\n", _res.ndots);
#endif
- } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
+ } else if (!strncmp(cp, "debug", sizeof("debug")-1)) {
#ifdef DEBUG
if (!(_res.options & RES_DEBUG)) {
printf(";; res_setoptions(\"%s\", \"%s\")..\n",
@@ -473,171 +431,16 @@ 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);
+ 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));
+ 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
-#ifdef NeXT
-static int
-netinfo_res_init(haveenv, havesearch)
- int *haveenv;
- int *havesearch;
-{
- register int n;
- void *domain, *parent;
- ni_id dir;
- ni_status status;
- ni_namelist nl;
- int nserv = 0;
-#ifdef RESOLVSORT
- int nsort = 0;
-#endif
-
- status = ni_open(NULL, ".", &domain);
- if (status == NI_OK) {
- ni_setreadtimeout(domain, NI_TIMEOUT);
- ni_setabort(domain, 1);
-
- /* climb the NetInfo hierarchy to find a resolver directory */
- while (status == NI_OK) {
- status = ni_pathsearch(domain, &dir, NI_PATH_RESCONF);
- if (status == NI_OK) {
- /* found a resolver directory */
-
- if (*haveenv == 0) {
- /* get the default domain name */
- status = ni_lookupprop(domain, &dir, "domain", &nl);
- if (status == NI_OK && nl.ni_namelist_len > 0) {
- (void)strncpy(_res.defdname,
- nl.ni_namelist_val[0],
- sizeof(_res.defdname) - 1);
- _res.defdname[sizeof(_res.defdname) - 1] = '\0';
- ni_namelist_free(&nl);
- *havesearch = 0;
- }
-
- /* get search list */
- status = ni_lookupprop(domain, &dir, "search", &nl);
- if (status == NI_OK && nl.ni_namelist_len > 0) {
- (void)strncpy(_res.defdname,
- nl.ni_namelist_val[0],
- sizeof(_res.defdname) - 1);
- _res.defdname[sizeof(_res.defdname) - 1] = '\0';
- /* copy */
- for (n = 0;
- n < nl.ni_namelist_len && n < MAXDNSRCH;
- n++) {
- /* duplicate up to MAXDNSRCH servers */
- char *cp = nl.ni_namelist_val[n];
- _res.dnsrch[n] =
- strcpy((char *)malloc(strlen(cp) + 1), cp);
- }
- ni_namelist_free(&nl);
- *havesearch = 1;
- }
- }
-
- /* get list of nameservers */
- status = ni_lookupprop(domain, &dir, "nameserver", &nl);
- if (status == NI_OK && nl.ni_namelist_len > 0) {
- /* copy up to MAXNS servers */
- for (n = 0;
- n < nl.ni_namelist_len && nserv < MAXNS;
- n++) {
- struct in_addr a;
-
- if (inet_aton(nl.ni_namelist_val[n], &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++;
- }
- }
- ni_namelist_free(&nl);
- }
-
- if (nserv > 1)
- _res.nscount = nserv;
-
-#ifdef RESOLVSORT
- /* get sort order */
- status = ni_lookupprop(domain, &dir, "sortlist", &nl);
- if (status == NI_OK && nl.ni_namelist_len > 0) {
-
- /* copy up to MAXRESOLVSORT address/netmask pairs */
- for (n = 0;
- n < nl.ni_namelist_len && nsort < MAXRESOLVSORT;
- n++) {
- char ch;
- char *cp;
- const char *sp;
- struct in_addr a;
-
- cp = NULL;
- for (sp = sort_mask; *sp; sp++) {
- char *cp1;
- cp1 = strchr(nl.ni_namelist_val[n], *sp);
- if (cp && cp1)
- cp = (cp < cp1)? cp : cp1;
- else if (cp1)
- cp = cp1;
- }
- if (cp != NULL) {
- ch = *cp;
- *cp = '\0';
- break;
- }
- if (inet_aton(nl.ni_namelist_val[n], &a)) {
- _res.sort_list[nsort].addr = a;
- if (*cp && ISSORTMASK(ch)) {
- *cp++ = ch;
- if (inet_aton(cp, &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++;
- }
- }
- ni_namelist_free(&nl);
- }
-
- _res.nsort = nsort;
-#endif
-
- /* get resolver options */
- status = ni_lookupprop(domain, &dir, "options", &nl);
- if (status == NI_OK && nl.ni_namelist_len > 0) {
- res_setoptions(nl.ni_namelist_val[0], "conf");
- ni_namelist_free(&nl);
- }
-
- ni_free(domain);
- return(1); /* using DNS configuration from NetInfo */
- }
-
- status = ni_open(domain, "..", &parent);
- ni_free(domain);
- if (status == NI_OK)
- domain = parent;
- }
- }
- return(0); /* if not using DNS configuration from NetInfo */
-}
-#endif /* NeXT */
-
u_int16_t
res_randomid()
{
diff --git a/lib/libc/net/res_mkquery.c b/lib/libc/net/res_mkquery.c
index 76786db..61d5825e 100644
--- a/lib/libc/net/res_mkquery.c
+++ b/lib/libc/net/res_mkquery.c
@@ -1,9 +1,7 @@
-/*
- * ++Copyright++ 1985, 1993
- * -
+/*-
* Copyright (c) 1985, 1993
- * The Regents of the University of California. All rights reserved.
- *
+ * The Regents of the University of California. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -14,12 +12,12 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -33,14 +31,14 @@
* 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
@@ -55,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_mkquery.c,v 8.3 1995/06/29 09:26:28 vixie Exp $";
+static char rcsid[] = "$Id: res_mkquery.c,v 1.5 1995/08/20 20:02:56 peter Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -63,17 +61,11 @@ static char rcsid[] = "$Id: res_mkquery.c,v 8.3 1995/06/29 09:26:28 vixie Exp $"
#include <arpa/nameser.h>
#include <stdio.h>
-#include <netdb.h>
#include <resolv.h>
-#if defined(BSD) && (BSD >= 199103)
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
+#include <string.h>
+#include <netdb.h>
-#if defined(USE_OPTIONS_H)
-# include <../conf/options.h>
-#endif
+#include "res_config.h"
/*
* Form all types of queries.
@@ -111,7 +103,7 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
* Initialize header fields.
*/
if ((buf == NULL) || (buflen < HFIXEDSZ))
- return (-1);
+ return(-1);
bzero(buf, HFIXEDSZ);
hp = (HEADER *) buf;
hp->id = htons(++_res.id);
@@ -131,7 +123,7 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
case QUERY: /*FALLTHROUGH*/
case NS_NOTIFY_OP:
if ((buflen -= QFIXEDSZ) < 0)
- return (-1);
+ return(-1);
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
return (-1);
cp += n;
@@ -205,13 +197,13 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
return (-1);
cp += n;
__putshort(type, cp);
- cp += INT16SZ;
- __putshort(class, cp);
- cp += INT16SZ;
+ cp += INT16SZ;
+ __putshort(class, cp);
+ cp += INT16SZ;
__putlong(0, cp);
cp += INT32SZ;
__putshort(datalen, cp);
- cp += INT16SZ;
+ cp += INT16SZ;
if (datalen) {
bcopy(data, cp, datalen);
cp += datalen;
@@ -228,13 +220,13 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
return (-1);
cp += n;
__putshort(newrr->r_type, cp);
- cp += INT16SZ;
- __putshort(newrr->r_class, cp);
- cp += INT16SZ;
+ cp += INT16SZ;
+ __putshort(newrr->r_class, cp);
+ cp += INT16SZ;
__putlong(0, cp);
cp += INT32SZ;
__putshort(newrr->r_size, cp);
- cp += INT16SZ;
+ cp += INT16SZ;
if (newrr->r_size) {
bcopy(newrr->r_data, cp, newrr->r_size);
cp += newrr->r_size;
diff --git a/lib/libc/net/res_query.c b/lib/libc/net/res_query.c
index 8229fbc..40c569a 100644
--- a/lib/libc/net/res_query.c
+++ b/lib/libc/net/res_query.c
@@ -1,9 +1,7 @@
-/*
- * ++Copyright++ 1988, 1993
- * -
+/*-
* Copyright (c) 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
+ * The Regents of the University of California. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -14,12 +12,12 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -33,14 +31,14 @@
* 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
@@ -55,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_query.c,v 8.6 1995/06/29 09:26:28 vixie Exp $";
+static char rcsid[] = "$Id: res_query.c,v 1.5 1995/08/20 20:03:00 peter Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -68,16 +66,10 @@ static char rcsid[] = "$Id: res_query.c,v 8.6 1995/06/29 09:26:28 vixie Exp $";
#include <resolv.h>
#include <ctype.h>
#include <errno.h>
-#if defined(BSD) && (BSD >= 199306)
-# include <stdlib.h>
-# include <string.h>
-#else
-# include "../conf/portability.h"
-#endif
+#include <stdlib.h>
+#include <string.h>
-#if defined(USE_OPTIONS_H)
-# include <../conf/options.h>
-#endif
+#include "res_config.h"
#if PACKETSZ > 1024
#define MAXPACKET PACKETSZ
@@ -147,21 +139,21 @@ res_query(name, class, type, answer, anslen)
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;
+ 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);
}
@@ -194,7 +186,7 @@ res_search(name, class, type, answer, anslen)
errno = 0;
h_errno = HOST_NOT_FOUND; /* default, if we never query */
dots = 0;
- for (cp = name; *cp; cp++)
+ for (cp = name; *cp; cp++)
dots += (*cp == '.');
trailing_dot = 0;
if (cp > name && *--cp == '.')
diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c
index 427e82a..1f7017f 100644
--- a/lib/libc/net/res_send.c
+++ b/lib/libc/net/res_send.c
@@ -1,9 +1,7 @@
-/*
- * ++Copyright++ 1985, 1989, 1993
- * -
+/*-
* Copyright (c) 1985, 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
+ * The Regents of the University of California. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -14,12 +12,12 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -33,14 +31,14 @@
* 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
@@ -55,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id: res_send.c,v 8.7 1995/12/03 08:31:17 vixie Exp $";
+static char rcsid[] = "$Id: res_send.c,v 1.5 1995/08/20 20:03:06 peter Exp $";
#endif /* LIBC_SCCS and not lint */
/* change this to "0"
@@ -63,7 +61,7 @@ static char rcsid[] = "$Id: res_send.c,v 8.7 1995/12/03 08:31:17 vixie Exp $";
* of multi-homed SunOS
* ("broken") name servers.
*/
-#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */
+#define CHECK_SRVR_ADDR 1 /* XXX - should be in res_config.h */
/*
* Send query to name server and wait for reply.
@@ -78,20 +76,14 @@ static char rcsid[] = "$Id: res_send.c,v 8.7 1995/12/03 08:31:17 vixie Exp $";
#include <arpa/inet.h>
#include <stdio.h>
-#include <netdb.h>
#include <errno.h>
#include <resolv.h>
-#if defined(BSD) && (BSD >= 199306)
-# include <stdlib.h>
-# include <string.h>
-# include <unistd.h>
-#else
-# include "../conf/portability.h"
-#endif
+#include <netdb.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
-#if defined(USE_OPTIONS_H)
-# include <../conf/options.h>
-#endif
+#include "res_config.h"
void _res_close __P((void));
@@ -99,23 +91,6 @@ 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 ciruit? */
-#ifndef FD_SET
-/* XXX - should be in portability.h */
-#define NFDBITS 32
-#define FD_SETSIZE 32
-#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
-#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
-#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
-#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
-#endif
-
-/* XXX - this should be done in portability.h */
-#if (defined(BSD) && (BSD >= 199103)) || defined(linux)
-# define CAN_RECONNECT 1
-#else
-# define CAN_RECONNECT 0
-#endif
-
#ifndef DEBUG
# define Dprint(cond, args) /*empty*/
# define DprintQ(cond, args, query, size) /*empty*/
@@ -127,38 +102,38 @@ static int vc = 0; /* is the socket a virtual ciruit? */
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) {
+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),
+ string,
+ inet_ntoa(address.sin_addr),
ntohs(address.sin_port),
- strerror(error));
- }
- errno = save;
+ strerror(error));
}
- 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;
+ 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
static res_send_qhook Qhook = NULL;
@@ -239,7 +214,7 @@ res_nameinquery(name, type, class, buf, eom)
if (n < 0)
return (-1);
cp += n;
- ttype = _getshort(cp); cp += INT16SZ;
+ ttype = _getshort(cp); cp += INT16SZ;
tclass = _getshort(cp); cp += INT16SZ;
if (ttype == type &&
tclass == class &&
@@ -288,20 +263,20 @@ res_queriesmatch(buf1, eom1, buf2, eom2)
int
res_send(buf, buflen, ans, anssiz)
- const u_char *buf;
- int buflen;
- u_char *ans;
- int anssiz;
+ const u_char *buf;
+ int buflen;
+ u_char *ans;
+ int anssiz;
{
- HEADER *hp = (HEADER *) buf;
- HEADER *anhp = (HEADER *) ans;
+ HEADER *hp = (HEADER *) buf;
+ HEADER *anhp = (HEADER *) ans;
int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
- register int n;
- u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
+ register int n;
+ u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
/* errno should have been set by res_init() in this case. */
- return (-1);
+ return (-1);
}
DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
(stdout, ";; res_send()\n"), buf, buflen);
@@ -318,7 +293,7 @@ res_send(buf, buflen, ans, anssiz)
for (ns = 0; ns < _res.nscount; ns++) {
struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
same_ns:
- if (badns & (1 << ns)) {
+ if (badns & (1<<ns)) {
_res_close();
goto next_ns;
}
@@ -355,13 +330,13 @@ res_send(buf, buflen, ans, anssiz)
Dprint(_res.options & RES_DEBUG,
(stdout, ";; Querying server (# %d) address = %s\n",
- ns + 1, inet_ntoa(nsap->sin_addr)));
+ ns+1, inet_ntoa(nsap->sin_addr)));
if (v_circuit) {
- int truncated;
- struct iovec iov[2];
- u_short len;
- u_char *cp;
+ int truncated;
+ struct iovec iov[2];
+ u_short len;
+ u_char *cp;
/*
* Use virtual circuit;
@@ -385,7 +360,7 @@ res_send(buf, buflen, ans, anssiz)
terrno = errno;
Aerror(stderr, "connect/vc",
errno, *nsap);
- badns |= (1 << ns);
+ badns |= (1<<ns);
_res_close();
goto next_ns;
}
@@ -402,7 +377,7 @@ res_send(buf, buflen, ans, anssiz)
if (writev(s, iov, 2) != (INT16SZ + buflen)) {
terrno = errno;
Perror(stderr, "write failed", errno);
- badns |= (1 << ns);
+ badns |= (1<<ns);
_res_close();
goto next_ns;
}
@@ -481,19 +456,16 @@ res_send(buf, buflen, ans, anssiz)
/*
* Use datagrams.
*/
- struct timeval timeout;
- fd_set dsmask;
+ struct timeval timeout;
+ fd_set dsmask;
struct sockaddr_in from;
- int fromlen;
+ int fromlen;
if ((s < 0) || vc) {
if (vc)
_res_close();
s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0) {
-#if !CAN_RECONNECT
- bad_dg_sock:
-#endif
terrno = errno;
Perror(stderr, "socket(dg)", errno);
return (-1);
@@ -527,7 +499,7 @@ res_send(buf, buflen, ans, anssiz)
Aerror(stderr,
"connect(dg)",
errno, *nsap);
- badns |= (1 << ns);
+ badns |= (1<<ns);
_res_close();
goto next_ns;
}
@@ -535,7 +507,7 @@ res_send(buf, buflen, ans, anssiz)
}
if (send(s, (char*)buf, buflen, 0) != buflen) {
Perror(stderr, "send", errno);
- badns |= (1 << ns);
+ badns |= (1<<ns);
_res_close();
goto next_ns;
}
@@ -545,7 +517,6 @@ res_send(buf, buflen, ans, anssiz)
* for responses from more than one server.
*/
if (connected) {
-#if CAN_RECONNECT
struct sockaddr_in no_addr;
no_addr.sin_family = AF_INET;
@@ -555,15 +526,6 @@ res_send(buf, buflen, ans, anssiz)
(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
connected = 0;
errno = 0;
}
@@ -572,7 +534,7 @@ res_send(buf, buflen, ans, anssiz)
sizeof(struct sockaddr))
!= buflen) {
Aerror(stderr, "sendto", errno, *nsap);
- badns |= (1 << ns);
+ badns |= (1<<ns);
_res_close();
goto next_ns;
}
@@ -646,7 +608,7 @@ res_send(buf, buflen, ans, anssiz)
#endif
if (!(_res.options & RES_INSECURE2) &&
!res_queriesmatch(buf, buf + buflen,
- ans, ans + anssiz)) {
+ ans, ans + anssiz)) {
/*
* response contains wrong query? ignore it.
* XXX - potential security hazard could
@@ -664,11 +626,11 @@ res_send(buf, buflen, ans, anssiz)
DprintQ(_res.options & RES_DEBUG,
(stdout, "server rejected query:\n"),
ans, resplen);
- badns |= (1 << ns);
+ badns |= (1<<ns);
_res_close();
/* don't retry if called from dig */
if (!_res.pfcode)
- goto next_ns;
+ goto next_ns;
}
if (!(_res.options & RES_IGNTC) && anhp->tc) {
/*
@@ -682,13 +644,9 @@ res_send(buf, buflen, ans, anssiz)
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, ""),
+ (stdout, ";; got answer:\n"),
ans, resplen);
/*
* If using virtual circuits, we assume that the first server
diff --git a/lib/libc/net/resolver.3 b/lib/libc/net/resolver.3
new file mode 100644
index 0000000..4014c72
--- /dev/null
+++ b/lib/libc/net/resolver.3
@@ -0,0 +1,323 @@
+.\" 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
+.\"
+.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>
+.Fo res_query
+.Fa "char *dname"
+.Fa "int class"
+.Fa "int type"
+.Fa "u_char *answer"
+.Fa "int anslen"
+.Fc
+.Fo res_search
+.Fa "char *dname"
+.Fa "int class"
+.Fa "int type"
+.Fa "u_char *answer"
+.Fa "int anslen"
+.Fc
+.Fo res_mkquery
+.Fa "int op"
+.Fa "char *dname"
+.Fa "int class"
+.Fa "int type"
+.Fa "char *data"
+.Fa "int datalen"
+.Fa "struct rrec *newrr"
+.Fa "char *buf"
+.Fa "int buflen"
+.Fc
+.Fo res_send
+.Fa "char *msg"
+.Fa "int msglen"
+.Fa "char *answer"
+.Fa "int anslen"
+.Fc
+.Fn res_init
+.Fo dn_comp
+.Fa "char *exp_dn"
+.Fa "char *comp_dn"
+.Fa "int length"
+.Fa "char **dnptrs"
+.Fa "char **lastdnptr"
+.Fc
+.Fo dn_expand
+.Fa "u_char *msg"
+.Fa "u_char *eomorig"
+.Fa "u_char *comp_dn"
+.Fa "u_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.
+.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 .
+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
+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 named 8 ,
+.Xr resolver 5 ,
+.Xr hostname 7 ,
+.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/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/nls/Makefile.inc b/lib/libc/nls/Makefile.inc
new file mode 100644
index 0000000..22c693b
--- /dev/null
+++ b/lib/libc/nls/Makefile.inc
@@ -0,0 +1,6 @@
+# $NetBSD: Makefile.inc,v 1.7 1995/02/27 13:06:20 cgd Exp $
+
+.PATH: ${.CURDIR}/nls
+
+SRCS+= catclose.c catgets.c catopen.c msgcat.c
+MAN3+= nls/catclose.3 nls/catgets.3 nls/catopen.3
diff --git a/lib/libc/nls/catclose.3 b/lib/libc/nls/catclose.3
new file mode 100644
index 0000000..f9803ff
--- /dev/null
+++ b/lib/libc/nls/catclose.3
@@ -0,0 +1,54 @@
+.\" $Id$
+.\"
+.\" 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 catopen 3 ,
+.Xr catgets 3
+.Sh STANDARDS
+The
+.Fn catclose
+function conforms to
+.St -xpg3 .
+
diff --git a/lib/libc/nls/catclose.c b/lib/libc/nls/catclose.c
new file mode 100644
index 0000000..341f664
--- /dev/null
+++ b/lib/libc/nls/catclose.c
@@ -0,0 +1,25 @@
+/* $Id$ */
+
+/*
+ * 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..3747d82
--- /dev/null
+++ b/lib/libc/nls/catgets.3
@@ -0,0 +1,67 @@
+.\" $Id$
+.\"
+.\" 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" "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 catclose 3 ,
+.Xr catopen 3
+.Sh STANDARDS
+The
+.Fn catgets
+function conforms to
+.St -xpg3 .
diff --git a/lib/libc/nls/catgets.c b/lib/libc/nls/catgets.c
new file mode 100644
index 0000000..c29cf64
--- /dev/null
+++ b/lib/libc/nls/catgets.c
@@ -0,0 +1,28 @@
+/* $Id$ */
+
+/*
+ * 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, char *));
+
+char *
+catgets(catd, set_id, msg_id, s)
+ nl_catd catd;
+ int set_id;
+ int msg_id;
+ 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..f581baf
--- /dev/null
+++ b/lib/libc/nls/catopen.3
@@ -0,0 +1,82 @@
+.\" $Id$
+.\"
+.\" 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
+The
+.Fa oflag
+argument is reserved for future use and should be set to zero.
+.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 availiable.
+.El
+.Sh SEE ALSO
+.Xr catclose 3 ,
+.Xr catgets 3
+.Sh STANDARDS
+The
+.Fn catopen
+function conforms to
+.St -xpg3 .
diff --git a/lib/libc/nls/catopen.c b/lib/libc/nls/catopen.c
new file mode 100644
index 0000000..5dfb727
--- /dev/null
+++ b/lib/libc/nls/catopen.c
@@ -0,0 +1,26 @@
+/* $Id$ */
+
+/*
+ * 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..8df18ae
--- /dev/null
+++ b/lib/libc/nls/msgcat.c
@@ -0,0 +1,394 @@
+/* $Id: msgcat.c,v 1.3 1995/06/17 03:02:21 ache Exp $ */
+
+/***********************************************************
+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 <fcntl.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 nl_catd loadSet();
+
+nl_catd _catopen( name, type)
+__const char *name;
+int type;
+{
+ char path[MAXPATHLEN];
+ __const char *catpath = NULL;
+ char *nlspath, *tmppath = NULL;
+ char *lang;
+ long len;
+ char *base, *cptr, *pathP;
+ struct stat sbuf;
+
+ if (!name || !*name) return(NLERR);
+
+ if (strchr(name, '/')) {
+ catpath = name;
+ if (stat(catpath, &sbuf)) return(0);
+ } else {
+ if ((lang = (char *) getenv("LANG")) == NULL) lang = "C";
+ if ((nlspath = (char *) getenv("NLSPATH")) == NULL) {
+ 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 = (char *) 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 (tmppath) free(tmppath);
+
+ if (!catpath) return(0);
+ }
+
+ return(loadCat(catpath, type));
+}
+
+/*
+ * 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) 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;
+char *dflt;
+{
+ MCMsgT *msg;
+ MCCatT *cat = (MCCatT *) catd;
+ char *cptr;
+
+ msg = MCGetMsg(MCGetSet(cat, setId), msgId);
+ if (msg) cptr = msg->msg.str;
+ else cptr = dflt;
+ return(cptr);
+}
+
+
+int _catclose( catd)
+nl_catd catd;
+{
+ MCCatT *cat = (MCCatT *) catd;
+ MCSetT *set;
+ int i;
+
+ if (!cat) 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); return(0);}
+#define NOSPACE() {fprintf(stderr, "%s: no more memory.\n", ERRNAME); return(NLERR);}
+
+static nl_catd loadCat( catpath, type)
+__const char *catpath;
+int type;
+{
+ MCHeaderT header;
+ MCCatT *cat;
+ MCSetT *set;
+ long i;
+ off_t nextSet;
+
+ cat = (MCCatT *) malloc(sizeof(MCCatT));
+ if (!cat) return(NLERR);
+ cat->loadType = type;
+
+ if ((cat->fd = open(catpath, O_RDONLY)) < 0) {
+ return(0);
+ }
+
+ 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) {
+ fprintf(stderr, "%s: %s is version %d, we need %d.\n", ERRNAME,
+ catpath, header.majorVer, MCMajorVer);
+ return(0);
+ }
+
+ if (header.numSets <= 0) {
+ fprintf(stderr, "%s: %s has %d sets!\n", ERRNAME, catpath,
+ header.numSets);
+ return(0);
+ }
+
+ 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) CORRUPT();
+
+ /* read in the set header */
+ set = cat->sets + i;
+ if (read(cat->fd, set, sizeof(*set)) != sizeof(*set)) CORRUPT();
+
+ /* if it's invalid, skip over it (and backup 'i') */
+
+ if (set->invalid) {
+ --i;
+ nextSet = set->nextSet;
+ continue;
+ }
+
+ if (cat->loadType == MCLoadAll) {
+ nl_catd res;
+ if ((res = loadSet(cat, set)) <= 0) {
+ if (res == -1) NOSPACE();
+ CORRUPT();
+ }
+ } else set->invalid = True;
+ nextSet = set->nextSet;
+ }
+ if (cat->loadType == MCLoadAll) {
+ close(cat->fd);
+ cat->fd = -1;
+ }
+ return((nl_catd) cat);
+}
+
+static nl_catd 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 = (char *) malloc(set->dataLen)) == NULL) return(-1);
+ if (read(cat->fd, set->data.str, set->dataLen) != set->dataLen) return(0);
+
+ /* Get the messages */
+ if (lseek(cat->fd, set->u.firstMsg, 0) == -1) return(0);
+ if ((set->u.msgs = (MCMsgT *) malloc(sizeof(MCMsgT) * set->numMsgs)) == NULL) return(-1);
+
+ for (i = 0; i < set->numMsgs; ++i) {
+ msg = set->u.msgs + i;
+ if (read(cat->fd, msg, sizeof(*msg)) != sizeof(*msg)) 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..4fabb59
--- /dev/null
+++ b/lib/libc/nls/msgcat.h
@@ -0,0 +1,170 @@
+/* $Id: msgcat.h,v 1.1 1995/03/30 12:47:27 jkh Exp $ */
+
+/* -*-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 1
+#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..617aae3
--- /dev/null
+++ b/lib/libc/quad/Makefile.inc
@@ -0,0 +1,19 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+
+# Quad support, if needed
+
+.if ${MACHINE} == "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
+
+.PATH: ${.CURDIR}/${MACHINE}/quad ${.CURDIR}/quad
diff --git a/lib/libc/quad/TESTS/Makefile b/lib/libc/quad/TESTS/Makefile
new file mode 100644
index 0000000..3d37abf
--- /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 $@
+
+DIVREM= divrem.c ../qdivrem.c
+divrem: ${DIVREM}
+ gcc -g -DSPARC_XXX ${DIVREM} -o $@
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..f31c6e8
--- /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, neg ^= 1;
+ 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..873a1f6
--- /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
+ * $Id$
+ */
+
+/*
+ * 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..48e286e
--- /dev/null
+++ b/lib/libc/regex/Makefile.inc
@@ -0,0 +1,14 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+
+# regex sources
+.PATH: ${.CURDIR}/regex
+
+CFLAGS+=-DPOSIX_MISTAKE
+
+SRCS+= regcomp.c regerror.c regexec.c regfree.c
+
+MAN3+= regex/regex.3
+MAN7+= regex/re_format.7
+
+MLINKS+=regex.3 regcomp.3 regex.3 regexec.3 regex.3 regerror.3
+MLINKS+=regexec.3 regfree.3
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..a29a92e
--- /dev/null
+++ b/lib/libc/regex/cclass.h
@@ -0,0 +1,70 @@
+/*-
+ * 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
+ */
+
+/* character-class table */
+static struct cclass {
+ char *name;
+ char *chars;
+ char *multis;
+} cclasses[] = {
+ "alnum", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+0123456789", "",
+ "alpha", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
+ "",
+ "blank", " \t", "",
+ "cntrl", "\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\
+\25\26\27\30\31\32\33\34\35\36\37\177", "",
+ "digit", "0123456789", "",
+ "graph", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
+ "",
+ "lower", "abcdefghijklmnopqrstuvwxyz",
+ "",
+ "print", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ",
+ "",
+ "punct", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
+ "",
+ "space", "\t\n\v\f\r ", "",
+ "upper", "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ "",
+ "xdigit", "0123456789ABCDEFabcdef",
+ "",
+ NULL, 0, ""
+};
diff --git a/lib/libc/regex/cname.h b/lib/libc/regex/cname.h
new file mode 100644
index 0000000..c1632eb
--- /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..8b54837
--- /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;
+ const register sopno gf = g->firststate+1; /* +1 for OEND */
+ const register 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(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..db2f634
--- /dev/null
+++ b/lib/libc/regex/re_format.7
@@ -0,0 +1,269 @@
+.\" 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
+.\"
+.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.
+`|', `+', and `?' are ordinary characters and there is no equivalent
+for their functionality.
+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..74c8d19
--- /dev/null
+++ b/lib/libc/regex/regcomp.c
@@ -0,0 +1,1696 @@
+/*-
+ * 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 "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));
+static void mcsub __P((cset *cs, char *cp));
+static int mcin __P((cset *cs, char *cp));
+static char *mcfind __P((cset *cs, char *cp));
+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);
+ 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 '(':
+ 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);
+ 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 '\\':
+ REQUIRE(MORE(), REG_EESCAPE);
+ c = GETNEXT();
+ ordinary(p, c);
+ break;
+ case '{': /* okay as ordinary except if digit follows */
+ REQUIRE(!MORE() || !isdigit(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(PEEK2())) ))
+ return; /* no repetition, we're done */
+ NEXT();
+
+ 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(PEEK())) {
+ count2 = p_count(p);
+ 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();
+ REQUIRE(MORE(), REG_EBRACE);
+ SETERROR(REG_BADBR);
+ }
+ break;
+ }
+
+ if (!MORE())
+ return;
+ c = PEEK();
+ if (!( c == '*' || c == '+' || c == '?' ||
+ (c == '{' && MORE2() && isdigit(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;
+{
+ 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++;
+ }
+
+ 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 == '\\') {
+ REQUIRE(MORE(), REG_EESCAPE);
+ c = BACKSL | (unsigned char)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);
+ 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 '*':
+ REQUIRE(starordinary, REG_BADRPT);
+ /* FALLTHROUGH */
+ default:
+ ordinary(p, c &~ BACKSL);
+ 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(PEEK())) {
+ count2 = p_count(p);
+ 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();
+ REQUIRE(MORE(), REG_EBRACE);
+ SETERROR(REG_BADBR);
+ }
+ } else if (c == (unsigned char)'$') /* $ (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(PEEK()) && count <= DUPMAX) {
+ count = count*10 + (GETNEXT() - '0');
+ ndigits++;
+ }
+
+ 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, '-');
+ 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();
+ REQUIRE(MORE(), REG_EBRACK);
+ c = PEEK();
+ REQUIRE(c != '-' && c != ']', REG_ECTYPE);
+ p_b_cclass(p, cs);
+ REQUIRE(MORE(), REG_EBRACK);
+ REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
+ break;
+ case '=': /* equivalence class */
+ NEXT2();
+ REQUIRE(MORE(), REG_EBRACK);
+ c = PEEK();
+ REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
+ p_b_eclass(p, cs);
+ REQUIRE(MORE(), REG_EBRACK);
+ 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;
+/* xxx what about signed chars here... */
+ REQUIRE(start <= finish, REG_ERANGE);
+ for (i = start; i <= finish; i++)
+ 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 char *sp = p->next;
+ register struct cclass *cp;
+ register size_t len;
+ register char *u;
+ register char c;
+
+ while (MORE() && isalpha(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;
+ }
+
+ u = cp->chars;
+ while ((c = *u++) != '\0')
+ CHadd(cs, c);
+ for (u = cp->multis; *u != '\0'; u += strlen(u) + 1)
+ MCadd(p, cs, u);
+}
+
+/*
+ - 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;
+
+ REQUIRE(MORE(), REG_EBRACK);
+ if (!EATTWO('[', '.'))
+ return(GETNEXT());
+
+ /* collating symbol */
+ value = p_b_coll_elem(p, '.');
+ 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;
+{
+ 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];
+
+ 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(ch) && othercase(ch) != ch)
+ bothcases(p, ch);
+ else {
+ EMIT(OCHAR, (unsigned char)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 *)realloc((char *)p->g->sets,
+ nc * sizeof(cset));
+ if (p->g->setbits == NULL)
+ p->g->setbits = (uch *)malloc(nbytes);
+ else {
+ p->g->setbits = (uch *)realloc((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 uch 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 = realloc(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';
+}
+
+/*
+ - 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 = realloc(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);
+}
+
+/*
+ - 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 = (unsigned char)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 = (unsigned char)c1;
+ register unsigned uc2 = (unsigned char)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..212f709
--- /dev/null
+++ b/lib/libc/regex/regerror.c
@@ -0,0 +1,178 @@
+/*-
+ * 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 <ctype.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..66a7285
--- /dev/null
+++ b/lib/libc/regex/regex.3
@@ -0,0 +1,538 @@
+.\" 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
+.\"
+.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 4.4BSD 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..64b6212
--- /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 0xf8000000
+#define OPDMASK 0x07ffffff
+#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 (1<<OPSHIFT) /* endmarker - */
+#define OCHAR (2<<OPSHIFT) /* character unsigned char */
+#define OBOL (3<<OPSHIFT) /* left anchor - */
+#define OEOL (4<<OPSHIFT) /* right anchor - */
+#define OANY (5<<OPSHIFT) /* . - */
+#define OANYOF (6<<OPSHIFT) /* [...] set number */
+#define OBACK_ (7<<OPSHIFT) /* begin \d paren number */
+#define O_BACK (8<<OPSHIFT) /* end \d paren number */
+#define OPLUS_ (9<<OPSHIFT) /* + prefix fwd to suffix */
+#define O_PLUS (10<<OPSHIFT) /* + suffix back to prefix */
+#define OQUEST_ (11<<OPSHIFT) /* ? prefix fwd to suffix */
+#define O_QUEST (12<<OPSHIFT) /* ? suffix back to prefix */
+#define OLPAREN (13<<OPSHIFT) /* ( fwd to ) */
+#define ORPAREN (14<<OPSHIFT) /* ) back to ( */
+#define OCH_ (15<<OPSHIFT) /* begin choice fwd to OOR2 */
+#define OOR1 (16<<OPSHIFT) /* | pt. 1 back to OOR1 or OCH_ */
+#define OOR2 (17<<OPSHIFT) /* | pt. 2 fwd to OOR2 or O_CH */
+#define O_CH (18<<OPSHIFT) /* end choice back to OOR1 */
+#define OBOW (19<<OPSHIFT) /* begin word - */
+#define OEOW (20<<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 */
+ uch 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 += (c))
+#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (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(c) || (c) == '_')
diff --git a/lib/libc/regex/regexec.c b/lib/libc/regex/regexec.c
new file mode 100644
index 0000000..3890b61
--- /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) &= ~(1 << (n)))
+#define SET1(v, n) ((v) |= 1 << (n))
+#define ISSET(v, n) ((v) & (1 << (n)))
+#define ASSIGN(d, s) ((d) = (s))
+#define EQ(a, b) ((a) == (b))
+#define STATEVARS int dummy /* dummy version */
+#define STATESETUP(m, n) /* nothing */
+#define STATETEARDOWN(m) /* nothing */
+#define SETUP(v) ((v) = 0)
+#define onestate int
+#define INIT(o, n) ((o) = (unsigned)1 << (n))
+#define INC(o) ((o) <<= 1)
+#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) |= ((unsigned)(src)&(here)) << (n))
+#define BACK(dst, src, n) ((dst) |= ((unsigned)(src)&(here)) >> (n))
+#define ISSETBACK(v, n) ((v) & ((unsigned)here >> (n)))
+/* 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 int 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 int
+#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..43f0f39
--- /dev/null
+++ b/lib/libc/rpc/Makefile.inc
@@ -0,0 +1,23 @@
+# @(#)Makefile 5.11 (Berkeley) 9/6/90
+
+.PATH: ${.CURDIR}/rpc ${.CURDIR}/.
+SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c \
+ clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c clnt_tcp.c \
+ clnt_udp.c rpc_dtablesize.c get_myaddress.c getrpcent.c getrpcport.c \
+ pmap_clnt.c pmap_getmaps.c pmap_getport.c pmap_prot.c \
+ pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c rpc_callmsg.c \
+ svc.c svc_auth.c svc_auth_unix.c svc_raw.c svc_run.c svc_simple.c \
+ svc_tcp.c svc_udp.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+= rpc/rstat.1
+MAN3+= rpc/bindresvport.3 rpc/getrpcent.3 rpc/getrpcport.3 rpc/rpc.3
+MAN5+= rpc/rpc.5
+MAN8+= rpc/rstat_svc.8
+
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_none.c b/lib/libc/rpc/auth_none.c
new file mode 100644
index 0000000..b04d5e6
--- /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 = "$Id: auth_none.c,v 1.2 1995/05/30 05:41:11 rgrimes Exp $";
+#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_unix.c b/lib/libc/rpc/auth_unix.c
new file mode 100644
index 0000000..b63b959
--- /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 = "$Id: auth_unix.c,v 1.4 1995/05/30 05:41:12 rgrimes Exp $";
+#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
+ bcopy(mymem, au->au_origcred.oa_base, (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 = geteuid();
+ gid = 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] = 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/authunix_prot.c b/lib/libc/rpc/authunix_prot.c
new file mode 100644
index 0000000..5a8c2a4
--- /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 = "$Id: authunix_prot.c,v 1.1 1994/08/07 18:35:40 wollman Exp $";
+#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..1fb1f9a
--- /dev/null
+++ b/lib/libc/rpc/bindresvport.3
@@ -0,0 +1,27 @@
+.\" @(#)bindresvport.3n 2.2 88/08/02 4.0 RPCSRC; from 1.7 88/03/14 SMI
+.TH BINDRESVPORT 3N "22 november 1987"
+.SH NAME
+bindresvport \- bind a socket to a privileged IP port
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <netinet/in.h>
+.LP
+.B int bindresvport(sd, sin)
+.B int sd;
+.B struct sockaddr_in \(**sin;
+.fi
+.SH DESCRIPTION
+.LP
+.B bindresvport(\|)
+is used to bind a socket descriptor to a privileged
+.SM 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
+.B errno
+set to reflect the cause of the error.
+.LP
+Only root can bind to a privileged port; this call will fail for any
+other users.
diff --git a/lib/libc/rpc/bindresvport.c b/lib/libc/rpc/bindresvport.c
new file mode 100644
index 0000000..c7f93b2
--- /dev/null
+++ b/lib/libc/rpc/bindresvport.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: @(#)bindresvport.c 1.8 88/02/08 SMI";*/
+/*static char *sccsid = "from: @(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: bindresvport.c,v 1.2 1995/05/30 05:41:13 rgrimes Exp $";
+#endif
+
+/*
+ * Copyright (c) 1987 by Sun Microsystems, Inc.
+ */
+
+#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
+ */
+bindresvport(sd, sin)
+ int sd;
+ struct sockaddr_in *sin;
+{
+ int res;
+ static short port;
+ struct sockaddr_in myaddr;
+ extern int errno;
+ int i;
+
+#define STARTPORT 600
+#define ENDPORT (IPPORT_RESERVED - 1)
+#define NPORTS (ENDPORT - STARTPORT + 1)
+
+ if (sin == (struct sockaddr_in *)0) {
+ sin = &myaddr;
+ bzero(sin, sizeof (*sin));
+ sin->sin_family = AF_INET;
+ } else if (sin->sin_family != AF_INET) {
+ errno = EPFNOSUPPORT;
+ return (-1);
+ }
+ if (port == 0) {
+ port = (getpid() % NPORTS) + STARTPORT;
+ }
+ res = -1;
+ errno = EADDRINUSE;
+ for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) {
+ sin->sin_port = htons(port++);
+ if (port > ENDPORT) {
+ port = STARTPORT;
+ }
+ res = bind(sd,
+ (struct sockaddr *)sin, sizeof(struct sockaddr_in));
+ }
+ return (res);
+}
diff --git a/lib/libc/rpc/clnt_generic.c b/lib/libc/rpc/clnt_generic.c
new file mode 100644
index 0000000..a529336
--- /dev/null
+++ b/lib/libc/rpc/clnt_generic.c
@@ -0,0 +1,114 @@
+/*
+ * 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 = "$Id: clnt_generic.c,v 1.2 1995/05/30 05:41:14 rgrimes Exp $";
+#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;
+ int sock;
+ struct timeval tv;
+ CLIENT *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);
+ }
+ sin.sin_family = h->h_addrtype;
+ sin.sin_port = 0;
+ bzero(sin.sin_zero, sizeof(sin.sin_zero));
+ bcopy(h->h_addr, (char*)&sin.sin_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);
+ }
+ tv.tv_sec = 25;
+ clnt_control(client, CLSET_TIMEOUT, &tv);
+ break;
+ case IPPROTO_TCP:
+ client = clnttcp_create(&sin, prog, vers, &sock, 0, 0);
+ if (client == NULL) {
+ return (NULL);
+ }
+ tv.tv_sec = 25;
+ tv.tv_usec = 0;
+ clnt_control(client, CLSET_TIMEOUT, &tv);
+ 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..a6ee70b
--- /dev/null
+++ b/lib/libc/rpc/clnt_perror.c
@@ -0,0 +1,304 @@
+/*
+ * 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 = "$Id: clnt_perror.c,v 1.3 1995/10/22 14:51:14 phk Exp $";
+#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();
+
+static char *buf;
+
+static char *
+_buf()
+{
+
+ if (buf == 0)
+ buf = (char *)malloc(256);
+ return (buf);
+}
+
+/*
+ * Print reply error info
+ */
+char *
+clnt_sperror(rpch, s)
+ CLIENT *rpch;
+ char *s;
+{
+ struct rpc_err e;
+ void clnt_perrno();
+ char *err;
+ char *str = _buf();
+ char *strstart = str;
+
+ if (str == 0)
+ return (0);
+ CLNT_GETERR(rpch, &e);
+
+ (void) sprintf(str, "%s: ", s);
+ str += strlen(str);
+
+ (void) strcpy(str, 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) sprintf(str, "; errno = %s",
+ strerror(e.re_errno));
+ str += strlen(str);
+ break;
+
+ case RPC_VERSMISMATCH:
+ (void) sprintf(str,
+ "; low version = %lu, high version = %lu",
+ e.re_vers.low, e.re_vers.high);
+ str += strlen(str);
+ break;
+
+ case RPC_AUTHERROR:
+ err = auth_errmsg(e.re_why);
+ (void) sprintf(str,"; why = ");
+ str += strlen(str);
+ if (err != NULL) {
+ (void) sprintf(str, "%s",err);
+ } else {
+ (void) sprintf(str,
+ "(unknown authentication error - %d)",
+ (int) e.re_why);
+ }
+ str += strlen(str);
+ break;
+
+ case RPC_PROGVERSMISMATCH:
+ (void) sprintf(str,
+ "; low version = %lu, high version = %lu",
+ e.re_vers.low, e.re_vers.high);
+ str += strlen(str);
+ break;
+
+ default: /* unknown */
+ (void) sprintf(str,
+ "; s1 = %lu, s2 = %lu",
+ e.re_lb.s1, e.re_lb.s2);
+ str += strlen(str);
+ break;
+ }
+ (void) sprintf(str, "\n");
+ return(strstart) ;
+}
+
+void
+clnt_perror(rpch, s)
+ CLIENT *rpch;
+ char *s;
+{
+ (void) fprintf(stderr,"%s\n",clnt_sperror(rpch,s));
+}
+
+
+struct rpc_errtab {
+ enum clnt_stat status;
+ char *message;
+};
+
+static struct rpc_errtab rpc_errlist[] = {
+ { RPC_SUCCESS,
+ "RPC: Success" },
+ { RPC_CANTENCODEARGS,
+ "RPC: Can't encode arguments" },
+ { RPC_CANTDECODERES,
+ "RPC: Can't decode result" },
+ { RPC_CANTSEND,
+ "RPC: Unable to send" },
+ { RPC_CANTRECV,
+ "RPC: Unable to receive" },
+ { RPC_TIMEDOUT,
+ "RPC: Timed out" },
+ { RPC_VERSMISMATCH,
+ "RPC: Incompatible versions of RPC" },
+ { RPC_AUTHERROR,
+ "RPC: Authentication error" },
+ { RPC_PROGUNAVAIL,
+ "RPC: Program unavailable" },
+ { RPC_PROGVERSMISMATCH,
+ "RPC: Program/version mismatch" },
+ { RPC_PROCUNAVAIL,
+ "RPC: Procedure unavailable" },
+ { RPC_CANTDECODEARGS,
+ "RPC: Server can't decode arguments" },
+ { RPC_SYSTEMERROR,
+ "RPC: Remote system error" },
+ { RPC_UNKNOWNHOST,
+ "RPC: Unknown host" },
+ { RPC_UNKNOWNPROTO,
+ "RPC: Unknown protocol" },
+ { RPC_PMAPFAILURE,
+ "RPC: Port mapper failure" },
+ { RPC_PROGNOTREGISTERED,
+ "RPC: Program not registered"},
+ { RPC_FAILED,
+ "RPC: Failed (unspecified error)"}
+};
+
+
+/*
+ * This interface for use by clntrpc
+ */
+char *
+clnt_sperrno(stat)
+ enum clnt_stat stat;
+{
+ int i;
+
+ for (i = 0; i < sizeof(rpc_errlist)/sizeof(struct rpc_errtab); i++) {
+ if (rpc_errlist[i].status == stat) {
+ return (rpc_errlist[i].message);
+ }
+ }
+ 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;
+{
+ extern int sys_nerr;
+ char *str = _buf();
+
+ if (str == 0)
+ return(0);
+ (void) sprintf(str, "%s: ", s);
+ (void) strcat(str, clnt_sperrno(rpc_createerr.cf_stat));
+ switch (rpc_createerr.cf_stat) {
+ case RPC_PMAPFAILURE:
+ (void) strcat(str, " - ");
+ (void) strcat(str,
+ clnt_sperrno(rpc_createerr.cf_error.re_status));
+ break;
+
+ case RPC_SYSTEMERROR:
+ (void) strcat(str, " - ");
+ if (rpc_createerr.cf_error.re_errno > 0
+ && rpc_createerr.cf_error.re_errno < sys_nerr)
+ (void) strcat(str,
+ strerror(rpc_createerr.cf_error.re_errno));
+ else
+ (void) sprintf(&str[strlen(str)], "Error %d",
+ rpc_createerr.cf_error.re_errno);
+ break;
+ }
+ (void) strcat(str, "\n");
+ return (str);
+}
+
+void
+clnt_pcreateerror(s)
+ char *s;
+{
+ (void) fprintf(stderr,"%s\n",clnt_spcreateerror(s));
+}
+
+struct auth_errtab {
+ enum auth_stat status;
+ char *message;
+};
+
+static struct auth_errtab auth_errlist[] = {
+ { AUTH_OK,
+ "Authentication OK" },
+ { AUTH_BADCRED,
+ "Invalid client credential" },
+ { AUTH_REJECTEDCRED,
+ "Server rejected credential" },
+ { AUTH_BADVERF,
+ "Invalid client verifier" },
+ { AUTH_REJECTEDVERF,
+ "Server rejected verifier" },
+ { AUTH_TOOWEAK,
+ "Client credential too weak" },
+ { AUTH_INVALIDRESP,
+ "Invalid server verifier" },
+ { AUTH_FAILED,
+ "Failed (unspecified error)" },
+};
+
+static char *
+auth_errmsg(stat)
+ enum auth_stat stat;
+{
+ int i;
+
+ for (i = 0; i < sizeof(auth_errlist)/sizeof(struct auth_errtab); i++) {
+ if (auth_errlist[i].status == stat) {
+ return(auth_errlist[i].message);
+ }
+ }
+ return(NULL);
+}
diff --git a/lib/libc/rpc/clnt_raw.c b/lib/libc/rpc/clnt_raw.c
new file mode 100644
index 0000000..b52e658
--- /dev/null
+++ b/lib/libc/rpc/clnt_raw.c
@@ -0,0 +1,241 @@
+/*
+ * 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 = "$Id: clnt_raw.c,v 1.3 1995/10/22 14:51:16 phk Exp $";
+#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>
+
+#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..2678287
--- /dev/null
+++ b/lib/libc/rpc/clnt_simple.c
@@ -0,0 +1,116 @@
+/*
+ * 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 = "$Id: clnt_simple.c,v 1.2 1995/05/30 05:41:17 rgrimes Exp $";
+#endif
+
+/*
+ * clnt_simple.c
+ * Simplified front end to 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 <netdb.h>
+
+static struct callrpc_private {
+ CLIENT *client;
+ int socket;
+ int oldprognum, oldversnum, valid;
+ char *oldhost;
+} *callrpc_private;
+
+callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
+ char *host;
+ 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(256);
+ 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;
+ (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;
+ bcopy(hp->h_addr, (char *)&server_addr.sin_addr, hp->h_length);
+ 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..ebe238d
--- /dev/null
+++ b/lib/libc/rpc/clnt_tcp.c
@@ -0,0 +1,471 @@
+/*
+ * 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 = "$Id: clnt_tcp.c,v 1.4 1995/10/27 16:56:50 adam Exp $";
+#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
+
+extern int errno;
+
+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;
+ struct timeval now;
+ struct rpc_msg call_msg;
+
+ 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;
+ (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 = 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
+ */
+ mem_free((caddr_t)ct, sizeof(struct ct_data));
+ 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_long *msg_x_id = (u_long *)(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;
+
+ switch (request) {
+ case CLSET_TIMEOUT:
+ ct->ct_wait = *(struct timeval *)info;
+ ct->ct_waitset = TRUE;
+ break;
+ case CLGET_TIMEOUT:
+ *(struct timeval *)info = ct->ct_wait;
+ break;
+ case CLGET_SERVER_ADDR:
+ *(struct sockaddr_in *)info = ct->ct_addr;
+ break;
+ 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;
+{
+#ifdef FD_SETSIZE
+ fd_set mask;
+ fd_set readfds;
+
+ if (len == 0)
+ return (0);
+ FD_ZERO(&mask);
+ FD_SET(ct->ct_sock, &mask);
+#else
+ register int mask = 1 << (ct->ct_sock);
+ int readfds;
+
+ if (len == 0)
+ return (0);
+
+#endif /* def FD_SETSIZE */
+ while (TRUE) {
+ readfds = mask;
+ switch (select(_rpc_dtablesize(), &readfds, (fd_set *)NULL,
+ (fd_set *)NULL, &(ct->ct_wait))) {
+ case 0:
+ ct->ct_error.re_status = RPC_TIMEDOUT;
+ return (-1);
+
+ case -1:
+ if (errno == EINTR)
+ continue;
+ ct->ct_error.re_status = RPC_CANTRECV;
+ ct->ct_error.re_errno = 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..d0da495
--- /dev/null
+++ b/lib/libc/rpc/clnt_udp.c
@@ -0,0 +1,447 @@
+/*
+ * 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 = "$Id: clnt_udp.c,v 1.5 1995/10/22 14:51:21 phk Exp $";
+#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>
+
+extern int errno;
+
+/*
+ * 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;
+ struct timeval now;
+ struct rpc_msg call_msg;
+
+ 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 = 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 prov 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;
+#ifdef FD_SETSIZE
+ fd_set readfds;
+ fd_set mask;
+#else
+ int readfds;
+ register int mask;
+#endif /* def FD_SETSIZE */
+ struct sockaddr_in from;
+ struct rpc_msg reply_msg;
+ XDR reply_xdrs;
+ struct timeval time_waited;
+ 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 */
+ }
+
+ time_waited.tv_sec = 0;
+ time_waited.tv_usec = 0;
+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)))
+ 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;
+ return (cu->cu_error.re_status = RPC_CANTSEND);
+ }
+
+ /*
+ * Hack to provide rpc-based message passing
+ */
+ if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
+ 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;
+#ifdef FD_SETSIZE
+ FD_ZERO(&mask);
+ FD_SET(cu->cu_sock, &mask);
+#else
+ mask = 1 << cu->cu_sock;
+#endif /* def FD_SETSIZE */
+ for (;;) {
+ readfds = mask;
+ switch (select(_rpc_dtablesize(), &readfds, (fd_set *)NULL,
+ (fd_set *)NULL, &(cu->cu_wait))) {
+
+ case 0:
+ time_waited.tv_sec += cu->cu_wait.tv_sec;
+ time_waited.tv_usec += cu->cu_wait.tv_usec;
+ while (time_waited.tv_usec >= 1000000) {
+ time_waited.tv_sec++;
+ time_waited.tv_usec -= 1000000;
+ }
+ if ((time_waited.tv_sec < timeout.tv_sec) ||
+ ((time_waited.tv_sec == timeout.tv_sec) &&
+ (time_waited.tv_usec < timeout.tv_usec)))
+ goto send_again;
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+
+ /*
+ * buggy in other cases because time_waited is not being
+ * updated.
+ */
+ case -1:
+ if (errno == EINTR)
+ continue;
+ cu->cu_error.re_errno = errno;
+ 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;
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+ if (inlen < sizeof(u_long))
+ continue;
+ /* see if reply transaction id matches sent id */
+ if (*((u_long *)(cu->cu_inbuf)) != *((u_long *)(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 {
+ cu->cu_error.re_status = RPC_CANTDECODERES;
+ }
+ 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;
+
+ switch (request) {
+ case CLSET_TIMEOUT:
+ cu->cu_total = *(struct timeval *)info;
+ break;
+ case CLGET_TIMEOUT:
+ *(struct timeval *)info = cu->cu_total;
+ break;
+ case CLSET_RETRY_TIMEOUT:
+ cu->cu_wait = *(struct timeval *)info;
+ break;
+ case CLGET_RETRY_TIMEOUT:
+ *(struct timeval *)info = cu->cu_wait;
+ break;
+ case CLGET_SERVER_ADDR:
+ *(struct sockaddr_in *)info = cu->cu_raddr;
+ break;
+ 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/get_myaddress.c b/lib/libc/rpc/get_myaddress.c
new file mode 100644
index 0000000..1565531
--- /dev/null
+++ b/lib/libc/rpc/get_myaddress.c
@@ -0,0 +1,100 @@
+/*
+ * 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 = "$Id: get_myaddress.c,v 1.2 1995/05/30 05:41:20 rgrimes Exp $";
+#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
+ */
+get_myaddress(addr)
+ struct sockaddr_in *addr;
+{
+ int s;
+ char buf[BUFSIZ];
+ struct ifconf ifc;
+ struct ifreq ifreq, *ifr;
+ int len, slop;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ perror("get_myaddress: socket");
+ exit(1);
+ }
+ ifc.ifc_len = sizeof (buf);
+ ifc.ifc_buf = buf;
+ if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+ perror("get_myaddress: ioctl (get interface configuration)");
+ exit(1);
+ }
+ ifr = ifc.ifc_req;
+ for (len = ifc.ifc_len; len; len -= sizeof ifreq) {
+ ifreq = *ifr;
+ if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+ perror("get_myaddress: ioctl");
+ exit(1);
+ }
+ if ((ifreq.ifr_flags & IFF_UP) &&
+ ifr->ifr_addr.sa_family == AF_INET) {
+ *addr = *((struct sockaddr_in *)&ifr->ifr_addr);
+ addr->sin_port = htons(PMAPPORT);
+ break;
+ }
+ /*
+ * Deal with variable length addresses
+ */
+ slop = ifr->ifr_addr.sa_len - sizeof (struct sockaddr);
+ if (slop) {
+ ifr = (struct ifreq *) ((caddr_t)ifr + slop);
+ len -= slop;
+ }
+ ifr++;
+ }
+ (void) close(s);
+}
diff --git a/lib/libc/rpc/getrpcent.3 b/lib/libc/rpc/getrpcent.3
new file mode 100644
index 0000000..edf64e4
--- /dev/null
+++ b/lib/libc/rpc/getrpcent.3
@@ -0,0 +1,109 @@
+.\" @(#)getrpcent.3n 2.2 88/08/02 4.0 RPCSRC; from 1.11 88/03/14 SMI
+.TH GETRPCENT 3N "14 December 1987"
+.SH NAME
+getrpcent, getrpcbyname, getrpcbynumber \- get RPC entry
+.SH SYNOPSIS
+.nf
+.ft B
+#include <netdb.h>
+.LP
+.ft B
+struct rpcent *getrpcent(\|)
+.LP
+.ft B
+struct rpcent *getrpcbyname(name)
+char *name;
+.LP
+.ft B
+struct rpcent *getrpcbynumber(number)
+int number;
+.LP
+.ft B
+setrpcent (stayopen)
+int stayopen
+.LP
+.ft B
+endrpcent (\|)
+.fi
+.SH DESCRIPTION
+.LP
+.BR getrpcent(\|) ,
+.BR getrpcbyname(\|) ,
+and
+.B getrpcbynumber(\|)
+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,
+.BR /etc/rpc .
+.RS
+.LP
+.nf
+.ft B
+struct rpcent {
+ char *r_name; /* name of server for this rpc program */
+ char **r_aliases; /* alias list */
+ long r_number; /* rpc program number */
+};
+.ft R
+.fi
+.RE
+.LP
+The members of this structure are:
+.RS
+.PD 0
+.TP 20
+.B r_name
+The name of the server for this rpc program.
+.TP 20
+.B r_aliases
+A zero terminated list of alternate names for the rpc program.
+.TP 20
+.B r_number
+The rpc program number for this service.
+.PD
+.RE
+.LP
+.B getrpcent(\|)
+reads the next line of the file, opening the file if necessary.
+.LP
+.B getrpcent(\|)
+opens and rewinds the file. If the
+.I stayopen
+flag is non-zero,
+the net data base will not be closed after each call to
+.B getrpcent(\|)
+(either directly, or indirectly through one of
+the other \*(lqgetrpc\*(rq calls).
+.LP
+.B endrpcent
+closes the file.
+.LP
+.B getrpcbyname(\|)
+and
+.B 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
+.PD 0
+.TP 20
+.B /etc/rpc
+.PD
+.SH "SEE ALSO"
+.BR rpc (5),
+.BR rpcinfo (8),
+.BR ypserv (8)
+.SH DIAGNOSTICS
+.LP
+A
+.SM NULL
+pointer is returned on
+.SM EOF
+or error.
+.SH BUGS
+.LP
+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..e9b919c
--- /dev/null
+++ b/lib/libc/rpc/getrpcent.c
@@ -0,0 +1,299 @@
+/*
+ * 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 = "$Id: getrpcent.c,v 1.2 1995/05/30 05:41:21 rgrimes Exp $";
+#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;
+#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;
+ char **rp;
+
+ setrpcent(0);
+ while (rpc = getrpcent()) {
+ if (strcmp(rpc->r_name, name) == 0)
+ return (rpc);
+ for (rp = rpc->r_aliases; *rp != NULL; rp++) {
+ if (strcmp(*rp, name) == 0)
+ return (rpc);
+ }
+ }
+ endrpcent();
+ return (NULL);
+}
+
+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()
+{
+ struct rpcent *hp;
+ int reason;
+ register struct rpcdata *d = _rpcdata();
+#ifdef YP
+ 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);
+ if (fgets(d->line, BUFSIZ, 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, len);
+ p = d->line;
+ d->line[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..01e7502
--- /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
+.TH GETRPCPORT 3 "6 October 1987"
+.SH NAME
+getrpcport \- get RPC port number
+.SH SYNOPSIS
+.ft B
+.nf
+int getrpcport(host, prognum, versnum, proto)
+ char *host;
+ int prognum, versnum, proto;
+.fi
+.SH DESCRIPTION
+.IX getrpcport "" "\fLgetrpcport\fR \(em get RPC port number"
+.B getrpcport(\|)
+returns the port number for version
+.I versnum
+of the RPC program
+.I prognum
+running on
+.I host
+and using protocol
+.IR proto .
+It returns 0 if it cannot contact the portmapper, or if
+.I prognum
+is not registered. If
+.I prognum
+is registered but not with version
+.IR 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..b280493
--- /dev/null
+++ b/lib/libc/rpc/getrpcport.c
@@ -0,0 +1,58 @@
+/*
+ * 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 = "$Id: getrpcport.c,v 1.2 1995/05/30 05:41:22 rgrimes Exp $";
+#endif
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+getrpcport(host, prognum, versnum, proto)
+ char *host;
+{
+ struct sockaddr_in addr;
+ struct hostent *hp;
+
+ if ((hp = gethostbyname(host)) == NULL)
+ return (0);
+ bcopy(hp->h_addr, (char *) &addr.sin_addr, hp->h_length);
+ addr.sin_family = AF_INET;
+ addr.sin_port = 0;
+ return (pmap_getport(&addr, prognum, versnum, proto));
+}
diff --git a/lib/libc/rpc/pmap_clnt.c b/lib/libc/rpc/pmap_clnt.c
new file mode 100644
index 0000000..c91682f
--- /dev/null
+++ b/lib/libc/rpc/pmap_clnt.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_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 = "$Id: pmap_clnt.c,v 1.2 1995/05/30 05:41:22 rgrimes Exp $";
+#endif
+
+/*
+ * pmap_clnt.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+
+static struct timeval timeout = { 5, 0 };
+static struct timeval tottimeout = { 60, 0 };
+
+void clnt_perror();
+
+
+/*
+ * 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;
+
+ get_myaddress(&myaddress);
+ 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);
+ (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;
+
+ get_myaddress(&myaddress);
+ 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);
+ (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..cbb1a43
--- /dev/null
+++ b/lib/libc/rpc/pmap_getmaps.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: @(#)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 = "$Id: pmap_getmaps.c,v 1.2 1995/05/30 05:41:23 rgrimes Exp $";
+#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
+
+extern int errno;
+
+/*
+ * 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);
+ }
+ (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..dd63a37
--- /dev/null
+++ b/lib/libc/rpc/pmap_getport.c
@@ -0,0 +1,90 @@
+/*
+ * 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 = "$Id: pmap_getport.c,v 1.2 1995/05/30 05:41:24 rgrimes Exp $";
+#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);
+ }
+ (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..07b5acd
--- /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 = "$Id: pmap_prot.c,v 1.1 1994/08/07 18:35:56 wollman Exp $";
+#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..5e937ed
--- /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 = "$Id: pmap_prot2.c,v 1.1 1994/08/07 18:35:57 wollman Exp $";
+#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;
+
+ 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..8511206
--- /dev/null
+++ b/lib/libc/rpc/pmap_rmt.c
@@ -0,0 +1,399 @@
+/*
+ * 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 = "$Id: pmap_rmt.c,v 1.3 1995/10/22 14:51:32 phk Exp $";
+#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 <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
+
+extern int errno;
+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;
+ }
+ (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;
+ 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) {
+ addrs[i++] =
+ inet_makeaddr(inet_netof(sin->sin_addr),
+ INADDR_ANY);
+ } else {
+ addrs[i++] = ((struct sockaddr_in*)
+ &ifreq.ifr_addr)->sin_addr;
+ }
+#else /* 4.2 BSD */
+ addrs[i++] = inet_makeaddr(inet_netof(sin->sin_addr),
+ INADDR_ANY);
+#endif
+ }
+ }
+ 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;
+#ifdef FD_SETSIZE
+ fd_set mask;
+ fd_set readfds;
+#else
+ int readfds;
+ register int mask;
+#endif /* def FD_SETSIZE */
+ 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;
+ char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
+
+ /*
+ * 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 */
+#ifdef FD_SETSIZE
+ FD_ZERO(&mask);
+ FD_SET(sock, &mask);
+#else
+ mask = (1 << sock);
+#endif /* def FD_SETSIZE */
+ nets = getbroadcastnets(addrs, sock, inbuf);
+ bzero((char *)&baddr, sizeof (baddr));
+ baddr.sin_family = AF_INET;
+ baddr.sin_port = htons(PMAPPORT);
+ baddr.sin_addr.s_addr = htonl(INADDR_ANY);
+/* baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */
+ (void)gettimeofday(&t, (struct timezone *)0);
+ msg.rm_xid = xid = 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.
+ */
+ 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;
+ readfds = mask;
+ switch (select(_rpc_dtablesize(), &readfds, (fd_set *)NULL,
+ (fd_set *)NULL, &t)) {
+
+ 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_long))
+ 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 ... */
+ } else {
+#ifdef notdef
+ /* some kind of deserialization problem ... */
+ if (msg.rm_xid == xid)
+ fprintf(stderr, "Broadcast deserialization problem");
+ /* otherwise, just random garbage */
+#endif
+ }
+ 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:
+ (void)close(sock);
+ AUTH_DESTROY(unix_auth);
+ return (stat);
+}
+
diff --git a/lib/libc/rpc/rpc.3 b/lib/libc/rpc/rpc.3
new file mode 100644
index 0000000..74501c3
--- /dev/null
+++ b/lib/libc/rpc/rpc.3
@@ -0,0 +1,1729 @@
+.\" @(#)rpc.3n 2.4 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI
+.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 (3N).
+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;
+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
+void
+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) .
+.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 failured 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 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
+.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 maximun 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 (3N),
+.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..324ecb1
--- /dev/null
+++ b/lib/libc/rpc/rpc.5
@@ -0,0 +1,71 @@
+.\" @(#)rpc.5 2.2 88/08/03 4.0 RPCSRC; from 1.4 87/11/27 SMI;
+.TH RPC 5 "26 September 1985"
+.SH NAME
+rpc \- rpc program number data base
+.SH SYNOPSIS
+.B /etc/rpc
+.SH DESCRIPTION
+The
+.I rpc
+file contains user readable names that
+can be used in place of rpc program numbers.
+Each line has the following information:
+.HP 10
+name of server for the rpc program
+.br
+.ns
+.HP 10
+rpc program number
+.br
+.ns
+.HP 10
+aliases
+.LP
+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.
+.LP
+Here is an example of the \fI/etc/rpc\fP file from the Sun RPC Source
+distribution.
+.nf
+.ta 1.5i +0.5i +1.0i +1.0i
+#
+# rpc 88/08/01 4.0 RPCSRC; from 1.12 88/02/07 SMI
+#
+portmapper 100000 portmap sunrpc
+rstatd 100001 rstat rstat_svc rup perfmeter
+rusersd 100002 rusers
+nfs 100003 nfsprog
+ypserv 100004 ypprog
+mountd 100005 mount showmount
+ypbind 100007
+walld 100008 rwall shutdown
+yppasswdd 100009 yppasswd
+etherstatd 100010 etherstat
+rquotad 100011 rquotaprog quota rquota
+sprayd 100012 spray
+3270_mapper 100013
+rje_mapper 100014
+selection_svc 100015 selnsvc
+database_svc 100016
+rexd 100017 rex
+alis 100018
+sched 100019
+llockmgr 100020
+nlockmgr 100021
+x25.inr 100022
+statmon 100023
+status 100024
+bootparam 100026
+ypupdated 100028 ypupdate
+keyserv 100029 keyserver
+tfsd 100037
+nsed 100038
+nsemntd 100039
+.fi
+.DT
+.SH FILES
+/etc/rpc
+.SH "SEE ALSO"
+getrpcent(3N)
diff --git a/lib/libc/rpc/rpc_callmsg.c b/lib/libc/rpc/rpc_callmsg.c
new file mode 100644
index 0000000..54f103b
--- /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 = "$Id: rpc_callmsg.c,v 1.2 1995/05/30 05:41:28 rgrimes Exp $";
+#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 long *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) {
+ bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length);
+ buf += RNDUP(oa->oa_length) / sizeof (long);
+ }
+ oa = &cmsg->rm_call.cb_verf;
+ IXDR_PUT_ENUM(buf, oa->oa_flavor);
+ IXDR_PUT_LONG(buf, oa->oa_length);
+ if (oa->oa_length) {
+ bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length);
+ /* no real need....
+ buf += RNDUP(oa->oa_length) / sizeof (long);
+ */
+ }
+ 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 {
+ bcopy((caddr_t)buf, oa->oa_base,
+ oa->oa_length);
+ /* no real need....
+ buf += RNDUP(oa->oa_length) /
+ sizeof (long);
+ */
+ }
+ }
+ 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 {
+ bcopy((caddr_t)buf, oa->oa_base,
+ oa->oa_length);
+ /* no real need...
+ buf += RNDUP(oa->oa_length) /
+ sizeof (long);
+ */
+ }
+ }
+ return (TRUE);
+ }
+ }
+ if (
+ xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
+ xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
+ (cmsg->rm_direction == CALL) &&
+ xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+ (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
+ xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) &&
+ xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)) &&
+ xdr_u_long(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..aa09526
--- /dev/null
+++ b/lib/libc/rpc/rpc_commondata.c
@@ -0,0 +1,46 @@
+/*
+ * 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 = "$Id: rpc_commondata.c,v 1.1 1994/08/07 18:36:01 wollman Exp $";
+#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;
+#ifdef FD_SETSIZE
+fd_set svc_fdset;
+#else
+int svc_fds;
+#endif /* def FD_SETSIZE */
+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..6ca511d
--- /dev/null
+++ b/lib/libc/rpc/rpc_dtablesize.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: @(#)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 = "rpc_dtablesize.c,v 1.1 1994/08/07 18:36:02 wollman Exp";
+#endif
+
+#include <sys/types.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).
+ * This can lead to many RPC functions getting back an EINVAL from
+ * select() and bombing all over the place.
+ *
+ * You can apparently get select() to handle values larger than 256
+ * by patching the kernel, but most people aren't likely to know
+ * that. Clamping this function at 256 is a kludge, but it'll have to
+ * do until select()'s descriptor table size can be adjusted dynamically.
+ */
+_rpc_dtablesize()
+{
+ 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..1693b67
--- /dev/null
+++ b/lib/libc/rpc/rpc_prot.c
@@ -0,0 +1,291 @@
+/*
+ * 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 = "$Id: rpc_prot.c,v 1.1 1994/08/07 18:36:03 wollman Exp $";
+#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_long(xdrs, &(ar->ar_vers.low)))
+ return (FALSE);
+ return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
+ }
+ 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_long(xdrs, &(rr->rj_vers.low)))
+ return (FALSE);
+ return (xdr_u_long(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_long(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_long(xdrs, &(cmsg->rm_xid)) &&
+ xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
+ xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+ xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
+ return (xdr_u_long(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;
+ }
+ /* 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;
+ }
+}
diff --git a/lib/libc/rpc/rstat.1 b/lib/libc/rpc/rstat.1
new file mode 100644
index 0000000..61d9999
--- /dev/null
+++ b/lib/libc/rpc/rstat.1
@@ -0,0 +1,57 @@
+.\" @(#)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(8c)
+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(8c) ),
+and cannot accomodate any RPC-based services. The host may be down.
+.SH "SEE ALSO"
+.BR portmap (8c),
+.BR rstat_svc (8c)
diff --git a/lib/libc/rpc/rstat_svc.8 b/lib/libc/rpc/rstat_svc.8
new file mode 100644
index 0000000..a10b71d
--- /dev/null
+++ b/lib/libc/rpc/rstat_svc.8
@@ -0,0 +1,21 @@
+.\" @(#)rstat_svc.8c 2.2 88/08/03 4.0 RPCSRC; from 1.10 87/09/09 SMI
+.TH RSTAT_SVC 8C "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/svc.c b/lib/libc/rpc/svc.c
new file mode 100644
index 0000000..809cbfb
--- /dev/null
+++ b/lib/libc/rpc/svc.c
@@ -0,0 +1,483 @@
+/*
+ * 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 = "$Id: svc.c,v 1.2 1995/05/30 05:41:31 rgrimes Exp $";
+#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>
+
+extern int errno;
+
+#ifdef FD_SETSIZE
+static SVCXPRT **xports;
+#else
+#define NOFILE 32
+
+static SVCXPRT *xports[NOFILE];
+#endif /* def FD_SETSIZE */
+
+#define NULL_SVC ((struct svc_callout *)0)
+#define RQCRED_SIZE 400 /* this size is excessive */
+
+/*
+ * 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();
+
+/* *************** SVCXPRT related stuff **************** */
+
+/*
+ * Activate a transport handle.
+ */
+void
+xprt_register(xprt)
+ SVCXPRT *xprt;
+{
+ register int sock = xprt->xp_sock;
+
+#ifdef FD_SETSIZE
+ if (xports == NULL) {
+ xports = (SVCXPRT **)
+ mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *));
+ }
+ if (sock < _rpc_dtablesize()) {
+ xports[sock] = xprt;
+ FD_SET(sock, &svc_fdset);
+ }
+#else
+ if (sock < NOFILE) {
+ xports[sock] = xprt;
+ svc_fds |= (1 << sock);
+ }
+#endif /* def FD_SETSIZE */
+
+}
+
+/*
+ * De-activate a transport handle.
+ */
+void
+xprt_unregister(xprt)
+ SVCXPRT *xprt;
+{
+ register int sock = xprt->xp_sock;
+
+#ifdef FD_SETSIZE
+ if ((sock < _rpc_dtablesize()) && (xports[sock] == xprt)) {
+ xports[sock] = (SVCXPRT *)0;
+ FD_CLR(sock, &svc_fdset);
+ }
+#else
+ if ((sock < NOFILE) && (xports[sock] == xprt)) {
+ xports[sock] = (SVCXPRT *)0;
+ svc_fds &= ~(1 << sock);
+ }
+#endif /* def FD_SETSIZE */
+}
+
+
+/* ********************** 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;
+{
+#ifdef FD_SETSIZE
+ fd_set readfds;
+
+ FD_ZERO(&readfds);
+ readfds.fds_bits[0] = rdfds;
+ svc_getreqset(&readfds);
+#else
+ int readfds = rdfds & svc_fds;
+
+ svc_getreqset(&readfds);
+#endif /* def FD_SETSIZE */
+}
+
+void
+svc_getreqset(readfds)
+#ifdef FD_SETSIZE
+ fd_set *readfds;
+{
+#else
+ int *readfds;
+{
+ int readfds_local = *readfds;
+#endif /* def FD_SETSIZE */
+ 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 u_long mask;
+ register int bit;
+ register u_long *maskp;
+ register int setsize;
+ register int sock;
+ 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]);
+
+
+#ifdef FD_SETSIZE
+ setsize = _rpc_dtablesize();
+ maskp = (u_long *)readfds->fds_bits;
+ for (sock = 0; sock < setsize; sock += NFDBITS) {
+ for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) {
+ /* sock has input waiting */
+ xprt = xports[sock + bit - 1];
+#else
+ for (sock = 0; readfds_local != 0; sock++, readfds_local >>= 1) {
+ if ((readfds_local & 1) != 0) {
+ /* sock has input waiting */
+ xprt = xports[sock];
+#endif /* def FD_SETSIZE */
+ /* 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 = 0 - 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..6c1e560
--- /dev/null
+++ b/lib/libc/rpc/svc_auth.c
@@ -0,0 +1,117 @@
+/*
+ * 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.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_auth.c 2.1 88/08/07 4.0 RPCSRC";*/
+static char *rcsid = "$Id: svc_auth.c,v 1.1 1994/08/07 18:36:07 wollman Exp $";
+#endif
+
+/*
+ * svc_auth_nodes.c, Server-side rpc authenticator interface,
+ * *WITHOUT* DES authentication.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.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(); /* unix style (uid, gids) */
+enum auth_stat _svcauth_short(); /* short hand unix style */
+
+static struct {
+ enum auth_stat (*authenticator)();
+} svcauthsw[] = {
+ _svcauth_null, /* AUTH_NULL */
+ _svcauth_unix, /* AUTH_UNIX */
+ _svcauth_short, /* AUTH_SHORT */
+};
+#define AUTH_MAX 2 /* HIGHEST AUTH NUMBER */
+
+
+/*
+ * 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;
+
+ 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;
+ if ((cred_flavor <= AUTH_MAX) && (cred_flavor >= AUTH_NULL)) {
+ return ((*(svcauthsw[cred_flavor].authenticator))(rqst, msg));
+ }
+
+ return (AUTH_REJECTEDCRED);
+}
+
+enum auth_stat
+_svcauth_null(/*rqst, msg*/)
+ /*struct svc_req *rqst;
+ struct rpc_msg *msg;*/
+{
+
+ return (AUTH_OK);
+}
diff --git a/lib/libc/rpc/svc_auth_unix.c b/lib/libc/rpc/svc_auth_unix.c
new file mode 100644
index 0000000..27ced54
--- /dev/null
+++ b/lib/libc/rpc/svc_auth_unix.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: @(#)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 = "$Id: svc_auth_unix.c,v 1.2 1995/05/30 05:41:33 rgrimes Exp $";
+#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 long *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;
+ }
+ bcopy((caddr_t)buf, aup->aup_machname, (u_int)str_len);
+ aup->aup_machname[str_len] = 0;
+ str_len = RNDUP(str_len);
+ buf += str_len / sizeof (long);
+ 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;
+ }
+ 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..f72a5f4
--- /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 = "$Id: svc_raw.c,v 1.2 1995/05/30 05:41:34 rgrimes Exp $";
+#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..730acd3
--- /dev/null
+++ b/lib/libc/rpc/svc_run.c
@@ -0,0 +1,73 @@
+/*
+ * 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 = "$Id: svc_run.c,v 1.1 1994/08/07 18:36:09 wollman Exp $";
+#endif
+
+/*
+ * This is the rpc server side idle loop
+ * Wait for input, call server program.
+ */
+#include <rpc/rpc.h>
+#include <sys/errno.h>
+
+void
+svc_run()
+{
+#ifdef FD_SETSIZE
+ fd_set readfds;
+#else
+ int readfds;
+#endif /* def FD_SETSIZE */
+ extern int errno;
+
+ for (;;) {
+#ifdef FD_SETSIZE
+ readfds = svc_fdset;
+#else
+ readfds = svc_fds;
+#endif /* def FD_SETSIZE */
+ switch (select(_rpc_dtablesize(), &readfds, (int *)0, (int *)0,
+ (struct timeval *)0)) {
+ case -1:
+ if (errno == EINTR) {
+ continue;
+ }
+ perror("svc_run: - select failed");
+ return;
+ case 0:
+ continue;
+ default:
+ svc_getreqset(&readfds);
+ }
+ }
+}
diff --git a/lib/libc/rpc/svc_simple.c b/lib/libc/rpc/svc_simple.c
new file mode 100644
index 0000000..8bcc306
--- /dev/null
+++ b/lib/libc/rpc/svc_simple.c
@@ -0,0 +1,147 @@
+/*
+ * 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 = "$Id: svc_simple.c,v 1.2 1995/05/30 05:41:37 rgrimes Exp $";
+#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 <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;
+
+registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
+ char *(*progname)();
+ xdrproc_t inproc, outproc;
+{
+
+ if (procnum == NULLPROC) {
+ (void) fprintf(stderr,
+ "can't reassign procedure number %d\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, (char *)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 */
+ bzero(xdrbuf, 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..e2d6733
--- /dev/null
+++ b/lib/libc/rpc/svc_tcp.c
@@ -0,0 +1,422 @@
+/*
+ * 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 = "$Id: svc_tcp.c,v 1.3 1995/10/22 14:51:38 phk Exp $";
+#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 <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,
+ abort,
+ abort,
+ 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);
+
+ 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;
+ }
+ bzero((char *)&addr, sizeof (addr));
+ 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;
+
+ 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);
+ }
+ /*
+ * 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.)
+ */
+static int
+readtcp(xprt, buf, len)
+ register SVCXPRT *xprt;
+ caddr_t buf;
+ register int len;
+{
+ register int sock = xprt->xp_sock;
+#ifdef FD_SETSIZE
+ fd_set mask;
+ fd_set readfds;
+
+ FD_ZERO(&mask);
+ FD_SET(sock, &mask);
+#else
+ register int mask = 1 << sock;
+ int readfds;
+#endif /* def FD_SETSIZE */
+ do {
+ readfds = mask;
+ if (select(_rpc_dtablesize(), &readfds, (fd_set *)NULL,
+ (fd_set *)NULL, &wait_per_try) <= 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ goto fatal_err;
+ }
+#ifdef FD_SETSIZE
+ } while (!FD_ISSET(sock, &readfds));
+#else
+ } while (readfds != mask);
+#endif /* def FD_SETSIZE */
+ if ((len = read(sock, buf, len)) > 0) {
+ return (len);
+ }
+fatal_err:
+ ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
+ 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);
+ }
+ 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..b071355
--- /dev/null
+++ b/lib/libc/rpc/svc_udp.c
@@ -0,0 +1,482 @@
+/*
+ * 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 = "$Id: svc_udp.c,v 1.3 1995/05/30 05:41:39 rgrimes Exp $";
+#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 struct xp_ops svcudp_op = {
+ svcudp_recv,
+ svcudp_stat,
+ svcudp_getargs,
+ svcudp_reply,
+ svcudp_freeargs,
+ svcudp_destroy
+};
+
+extern int errno;
+
+/*
+ * 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;
+ }
+ bzero((char *)&addr, sizeof (addr));
+ 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;
+ static int cache_get();
+
+ 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 < (int)(4*sizeof(u_long)))
+ 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;
+ static void cache_set();
+
+ 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) \
+ bzero((char *) addr, 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.
+ */
+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
+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) (bcmp((char*)&a1, (char*)&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/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc
new file mode 100644
index 0000000..5ca5016
--- /dev/null
+++ b/lib/libc/stdio/Makefile.inc
@@ -0,0 +1,40 @@
+# @(#)Makefile.inc 8.3 (Berkeley) 4/17/94
+
+# stdio sources
+.PATH: ${.CURDIR}/stdio
+
+SRCS+= 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 vfprintf.c \
+ vfscanf.c vprintf.c vscanf.c vsnprintf.c vsprintf.c vsscanf.c \
+ wbuf.c wsetup.c
+
+MAN3+= stdio/fclose.3 stdio/ferror.3 stdio/fflush.3 stdio/fgetln.3 \
+ stdio/fgets.3 stdio/fopen.3 stdio/fputs.3 stdio/fread.3 stdio/fseek.3 \
+ stdio/funopen.3 stdio/getc.3 stdio/mktemp.3 stdio/printf.3 \
+ stdio/putc.3 stdio/remove.3 stdio/scanf.3 stdio/setbuf.3 \
+ stdio/stdio.3 stdio/tmpnam.3 stdio/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 fsetpos.3 fseek.3 ftell.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 mkstemp.3
+MLINKS+=printf.3 fprintf.3 printf.3 snprintf.3 printf.3 sprintf.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
diff --git a/lib/libc/stdio/clrerr.c b/lib/libc/stdio/clrerr.c
new file mode 100644
index 0000000..de4526e
--- /dev/null
+++ b/lib/libc/stdio/clrerr.c
@@ -0,0 +1,49 @@
+/*-
+ * 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[] = "@(#)clrerr.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#undef clearerr
+
+void
+clearerr(fp)
+ FILE *fp;
+{
+ __sclearerr(fp);
+}
diff --git a/lib/libc/stdio/fclose.3 b/lib/libc/stdio/fclose.3
new file mode 100644
index 0000000..77f3316
--- /dev/null
+++ b/lib/libc/stdio/fclose.3
@@ -0,0 +1,93 @@
+.\" 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
+.\"
+.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
+.Bl -tag -width [EBADF]
+.It Bq Er EBADF
+The argument
+.Fa stream
+is not an open stream.
+.El
+.Pp
+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 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..8315c3c
--- /dev/null
+++ b/lib/libc/stdio/fclose.c
@@ -0,0 +1,67 @@
+/*-
+ * 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[] = "@(#)fclose.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+
+fclose(fp)
+ register FILE *fp;
+{
+ register int r;
+
+ if (fp->_flags == 0) { /* not open! */
+ errno = EBADF;
+ return (EOF);
+ }
+ 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);
+ fp->_flags = 0; /* Release this FILE for reuse. */
+ fp->_r = fp->_w = 0; /* Mess up if reaccessed. */
+ 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..7f58057
--- /dev/null
+++ b/lib/libc/stdio/feof.c
@@ -0,0 +1,52 @@
+/*-
+ * 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[] = "@(#)feof.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro feof.
+ */
+#undef feof
+
+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..411999d
--- /dev/null
+++ b/lib/libc/stdio/ferror.3
@@ -0,0 +1,100 @@
+.\" 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
+.\"
+.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..27ca107
--- /dev/null
+++ b/lib/libc/stdio/ferror.c
@@ -0,0 +1,52 @@
+/*-
+ * 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[] = "@(#)ferror.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro ferror.
+ */
+#undef ferror
+
+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..ce3f1b7
--- /dev/null
+++ b/lib/libc/stdio/fflush.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 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
+.\"
+.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 fopen 3 ,
+.Xr fclose 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..4a5cf0f
--- /dev/null
+++ b/lib/libc/stdio/fflush.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[] = "@(#)fflush.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stdio.h>
+#include "local.h"
+
+/* Flush a single file, or (if fp is NULL) all files. */
+fflush(fp)
+ register FILE *fp;
+{
+
+ if (fp == NULL)
+ return (_fwalk(__sflush));
+ if ((fp->_flags & (__SWR | __SRW)) == 0) {
+ errno = EBADF;
+ return (EOF);
+ }
+ return (__sflush(fp));
+}
+
+__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..800846c
--- /dev/null
+++ b/lib/libc/stdio/fgetc.c
@@ -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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fgetc.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+fgetc(fp)
+ FILE *fp;
+{
+ return (__sgetc(fp));
+}
diff --git a/lib/libc/stdio/fgetln.3 b/lib/libc/stdio/fgetln.3
new file mode 100644
index 0000000..60089ea
--- /dev/null
+++ b/lib/libc/stdio/fgetln.3
@@ -0,0 +1,123 @@
+.\" 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
+.\"
+.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 4.4BSD.
diff --git a/lib/libc/stdio/fgetln.c b/lib/libc/stdio/fgetln.c
new file mode 100644
index 0000000..ec81a2d
--- /dev/null
+++ b/lib/libc/stdio/fgetln.c
@@ -0,0 +1,160 @@
+/*-
+ * 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[] = "@(#)fgetln.c 8.2 (Berkeley) 1/2/94";
+#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
+ */
+__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', 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', 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..1f4ec1d
--- /dev/null
+++ b/lib/libc/stdio/fgetpos.c
@@ -0,0 +1,48 @@
+/*-
+ * 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[] = "@(#)fgetpos.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+fgetpos(fp, pos)
+ FILE *fp;
+ fpos_t *pos;
+{
+ return((*pos = ftell(fp)) == (fpos_t)-1);
+}
diff --git a/lib/libc/stdio/fgets.3 b/lib/libc/stdio/fgets.3
new file mode 100644
index 0000000..827de6b
--- /dev/null
+++ b/lib/libc/stdio/fgets.3
@@ -0,0 +1,151 @@
+.\" 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
+.\"
+.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" "size_t 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
+.Xr 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.
+In any case a
+.Ql \e0
+character is appended to end the string.
+.Pp
+The
+.Fn gets
+function
+is equivalent to
+.Fn fgets
+with an infinite
+.Xr 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 or an error occurs before any characters are read,
+they return
+.Dv NULL.
+The
+.Fn fgets
+and
+functions
+.Fn gets
+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..09f6877
--- /dev/null
+++ b/lib/libc/stdio/fgets.c
@@ -0,0 +1,104 @@
+/*-
+ * 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[] = "@(#)fgets.c 8.2 (Berkeley) 12/22/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.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 size_t n;
+ register FILE *fp;
+{
+ register size_t len;
+ register char *s;
+ register unsigned char *p, *t;
+
+ if (n == 0) /* sanity check */
+ return (NULL);
+
+ 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)
+ 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;
+ return (buf);
+ }
+ fp->_r -= len;
+ fp->_p += len;
+ (void)memcpy((void *)s, (void *)p, len);
+ s += len;
+ n -= len;
+ }
+ *s = 0;
+ return (buf);
+}
diff --git a/lib/libc/stdio/fileno.c b/lib/libc/stdio/fileno.c
new file mode 100644
index 0000000..91e82e8
--- /dev/null
+++ b/lib/libc/stdio/fileno.c
@@ -0,0 +1,52 @@
+/*-
+ * 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[] = "@(#)fileno.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro fileno.
+ */
+#undef fileno
+
+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..2986a2c
--- /dev/null
+++ b/lib/libc/stdio/findfp.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)
+static char sccsid[] = "@(#)findfp.c 8.2 (Berkeley) 1/4/94";
+#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 "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(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();
+ 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;
+ }
+ return (NULL);
+found:
+ fp->_flags = 1; /* reserve this slot; caller sets real flags */
+ 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..ee1a76c
--- /dev/null
+++ b/lib/libc/stdio/flags.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[] = "@(#)flags.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <errno.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.
+ */
+__sflags(mode, optr)
+ register 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..23d790c
--- /dev/null
+++ b/lib/libc/stdio/fopen.3
@@ -0,0 +1,237 @@
+.\" 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
+.\"
+.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 "char *path" "char *mode"
+.Ft FILE *
+.Fn fdopen "int fildes" "char *mode"
+.Ft FILE *
+.Fn freopen "char *path" "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.
+.No 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.
+.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
+.Xr 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..479ee24
--- /dev/null
+++ b/lib/libc/stdio/fprintf.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[] = "@(#)fprintf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#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..3bee513
--- /dev/null
+++ b/lib/libc/stdio/fpurge.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[] = "@(#)fpurge.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+
+/*
+ * fpurge: like fflush, but without writing anything: leave the
+ * given FILE's buffer empty.
+ */
+int
+fpurge(fp)
+ register FILE *fp;
+{
+ if (!fp->_flags) {
+ errno = EBADF;
+ return(EOF);
+ }
+
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_p = fp->_bf._base;
+ fp->_r = 0;
+ fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
+ return (0);
+}
diff --git a/lib/libc/stdio/fputc.c b/lib/libc/stdio/fputc.c
new file mode 100644
index 0000000..c86f711
--- /dev/null
+++ b/lib/libc/stdio/fputc.c
@@ -0,0 +1,48 @@
+/*-
+ * 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[] = "@(#)fputc.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+fputc(c, fp)
+ int c;
+ register FILE *fp;
+{
+ return (putc(c, fp));
+}
diff --git a/lib/libc/stdio/fputs.3 b/lib/libc/stdio/fputs.3
new file mode 100644
index 0000000..5578ec2
--- /dev/null
+++ b/lib/libc/stdio/fputs.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.
+.\"
+.\" @(#)fputs.3 8.1 (Berkeley) 6/4/93
+.\"
+.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 putc 3 ,
+.Xr ferror 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..9f9be2e
--- /dev/null
+++ b/lib/libc/stdio/fputs.c
@@ -0,0 +1,60 @@
+/*-
+ * 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[] = "@(#)fputs.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include "fvwrite.h"
+
+/*
+ * Write the given string to the given file.
+ */
+fputs(s, fp)
+ const char *s;
+ FILE *fp;
+{
+ 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;
+ return (__sfvwrite(fp, &uio));
+}
diff --git a/lib/libc/stdio/fread.3 b/lib/libc/stdio/fread.3
new file mode 100644
index 0000000..8dd65af
--- /dev/null
+++ b/lib/libc/stdio/fread.3
@@ -0,0 +1,106 @@
+.\" 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
+.\"
+.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 int
+.Fn fread "void *ptr" "size_t size" "size_t nmemb" "FILE *stream"
+.Ft int
+.Fn fwrite "const void *ptr" "size_t size" "size_t nmemb" "FILE *stream"
+.Sh DESCRIPTION
+The function
+.Fn fread
+reads
+.Fa nmemb
+objects, each
+.Xr 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..22436ec
--- /dev/null
+++ b/lib/libc/stdio/fread.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[] = "@(#)fread.c 8.2 (Berkeley) 12/11/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.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);
+ 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 */
+ return ((total - resid) / size);
+ }
+ }
+ (void)memcpy((void *)p, (void *)fp->_p, resid);
+ fp->_r -= resid;
+ fp->_p += resid;
+ return (count);
+}
diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c
new file mode 100644
index 0000000..7a8a3ef
--- /dev/null
+++ b/lib/libc/stdio/freopen.c
@@ -0,0 +1,155 @@
+/*-
+ * 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[] = "@(#)freopen.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 <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.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);
+ }
+
+ 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 */
+ 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;
+ return (fp);
+}
diff --git a/lib/libc/stdio/fscanf.c b/lib/libc/stdio/fscanf.c
new file mode 100644
index 0000000..f0e726a
--- /dev/null
+++ b/lib/libc/stdio/fscanf.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[] = "@(#)fscanf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#if __STDC__
+fscanf(FILE *fp, char const *fmt, ...) {
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+#else
+fscanf(fp, fmt, va_alist)
+ FILE *fp;
+ char *fmt;
+ va_dcl
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap);
+#endif
+ ret = __svfscanf(fp, fmt, ap);
+ va_end(ap);
+ return (ret);
+}
diff --git a/lib/libc/stdio/fseek.3 b/lib/libc/stdio/fseek.3
new file mode 100644
index 0000000..4d22276
--- /dev/null
+++ b/lib/libc/stdio/fseek.3
@@ -0,0 +1,188 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt FSEEK 3
+.Os
+.Sh NAME
+.Nm fgetpos ,
+.Nm fseek ,
+.Nm fsetpos ,
+.Nm ftell ,
+.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" "fpos_t *pos"
+.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 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 fsetpos
+return 0,
+and
+.Fn ftell
+returns 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 .
+.El
+.Pp
+The function
+.Fn fgetpos ,
+.Fn fseek ,
+.Fn fsetpos ,
+and
+.Fn ftell
+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 .
diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c
new file mode 100644
index 0000000..9cb04ad
--- /dev/null
+++ b/lib/libc/stdio/fseek.c
@@ -0,0 +1,246 @@
+/*-
+ * 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[] = "@(#)fseek.c 8.3 (Berkeley) 1/2/94";
+#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"
+
+#define POS_ERR (-(fpos_t)1)
+
+/*
+ * Seek the given file to the given offset.
+ * `Whence' must be one of the three SEEK_* macros.
+ */
+int
+fseek(fp, offset, whence)
+ register FILE *fp;
+ long 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();
+
+ /*
+ * Have to be able to seek.
+ */
+ if ((seekfn = fp->_seek) == NULL) {
+ errno = ESPIPE; /* historic practice */
+ 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 == -1L)
+ 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;
+ 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;
+ 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;
+ }
+ 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) {
+ 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;
+ return (0);
+}
diff --git a/lib/libc/stdio/fsetpos.c b/lib/libc/stdio/fsetpos.c
new file mode 100644
index 0000000..4dace2d
--- /dev/null
+++ b/lib/libc/stdio/fsetpos.c
@@ -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
+ * 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[] = "@(#)fsetpos.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * fsetpos: like fseek.
+ */
+fsetpos(iop, pos)
+ FILE *iop;
+ const fpos_t *pos;
+{
+ return (fseek(iop, (long)*pos, SEEK_SET));
+}
diff --git a/lib/libc/stdio/ftell.c b/lib/libc/stdio/ftell.c
new file mode 100644
index 0000000..724e543
--- /dev/null
+++ b/lib/libc/stdio/ftell.c
@@ -0,0 +1,88 @@
+/*-
+ * 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[] = "@(#)ftell.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <errno.h>
+#include "local.h"
+
+/*
+ * ftell: return current offset.
+ */
+long
+ftell(fp)
+ register const FILE *fp;
+{
+ register fpos_t pos;
+
+ if (fp->_seek == NULL) {
+ errno = ESPIPE; /* historic practice */
+ return (-1L);
+ }
+
+ /*
+ * 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 == -1L)
+ 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;
+ }
+ return (pos);
+}
diff --git a/lib/libc/stdio/funopen.3 b/lib/libc/stdio/funopen.3
new file mode 100644
index 0000000..8ed9b30
--- /dev/null
+++ b/lib/libc/stdio/funopen.3
@@ -0,0 +1,168 @@
+.\" 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
+.\"
+.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 "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 *, 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 4.4BSD.
+.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..3ab6279
--- /dev/null
+++ b/lib/libc/stdio/fvwrite.c
@@ -0,0 +1,189 @@
+/*-
+ * 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[] = "@(#)fvwrite.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.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.
+ */
+__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(;);
+ w = fp->_w;
+ if (fp->_flags & __SSTR) {
+ if (len < w)
+ w = len;
+ 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..7771c41
--- /dev/null
+++ b/lib/libc/stdio/fwalk.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[] = "@(#)fwalk.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stdio.h>
+#include "local.h"
+#include "glue.h"
+
+_fwalk(function)
+ register int (*function)();
+{
+ 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..dbc2e97
--- /dev/null
+++ b/lib/libc/stdio/fwrite.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)
+static char sccsid[] = "@(#)fwrite.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "local.h"
+#include "fvwrite.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;
+
+ /*
+ * 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)
+ return (count);
+ return ((n - uio.uio_resid) / size);
+}
diff --git a/lib/libc/stdio/getc.3 b/lib/libc/stdio/getc.3
new file mode 100644
index 0000000..de93a19
--- /dev/null
+++ b/lib/libc/stdio/getc.3
@@ -0,0 +1,136 @@
+.\" 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
+.\"
+.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 .
+.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 .
+.Sh SEE ALSO
+.Xr ferror 3 ,
+.Xr fread 3 ,
+.Xr fopen 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
+and
+.Xr ferror
+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..1e900cd
--- /dev/null
+++ b/lib/libc/stdio/getc.c
@@ -0,0 +1,52 @@
+/*-
+ * 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[] = "@(#)getc.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro getc.
+ */
+#undef getc
+
+getc(fp)
+ register FILE *fp;
+{
+ return (__sgetc(fp));
+}
diff --git a/lib/libc/stdio/getchar.c b/lib/libc/stdio/getchar.c
new file mode 100644
index 0000000..20e52b7
--- /dev/null
+++ b/lib/libc/stdio/getchar.c
@@ -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
+ * 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[] = "@(#)getchar.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * A subroutine version of the macro getchar.
+ */
+#include <stdio.h>
+
+#undef getchar
+
+getchar()
+{
+ return (getc(stdin));
+}
diff --git a/lib/libc/stdio/gets.c b/lib/libc/stdio/gets.c
new file mode 100644
index 0000000..d31aeee
--- /dev/null
+++ b/lib/libc/stdio/gets.c
@@ -0,0 +1,71 @@
+/*-
+ * 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[] = "@(#)gets.c 8.1 (Berkeley) 6/4/93";
+#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..5220290
--- /dev/null
+++ b/lib/libc/stdio/getw.c
@@ -0,0 +1,49 @@
+/*-
+ * 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[] = "@(#)getw.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+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..9021d74
--- /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.2 (Berkeley) 1/2/94
+ */
+
+/*
+ * Information local to this implementation of stdio,
+ * in particular, macros and private variables.
+ */
+
+int __sflush __P((FILE *));
+FILE *__sfp __P((void));
+int __srefill __P((FILE *));
+int __sread __P((void *, char *, int));
+int __swrite __P((void *, char const *, int));
+fpos_t __sseek __P((void *, fpos_t, int));
+int __sclose __P((void *));
+void __sinit __P((void));
+void _cleanup __P((void));
+void (*__cleanup) __P((void));
+void __smakebuf __P((FILE *));
+int __swhatbuf __P((FILE *, size_t *, int *));
+int _fwalk __P((int (*)(FILE *)));
+int __swsetup __P((FILE *));
+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..361bebf
--- /dev/null
+++ b/lib/libc/stdio/mktemp.3
@@ -0,0 +1,136 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.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"
+.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.
+.Sh RETURN VALUES
+The
+.Fn mktemp
+function
+returns a pointer to the template on success and
+.Dv NULL
+on failure.
+The
+.Fn mkstemp
+function
+returns \-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 mktemp
+and
+.Fn mkstemp
+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 mktemp
+and
+.Fn mkstemp
+functions
+may also set
+.Va errno
+to any value specified by the
+.Xr stat 2
+function.
+.Pp
+The
+.Fn mkstemp
+function
+may also set
+.Va errno
+to any value specified by the
+.Xr open 2
+function.
+.Sh SEE ALSO
+.Xr chmod 2 ,
+.Xr getpid 2 ,
+.Xr open 2 ,
+.Xr stat 2
+.Sh HISTORY
+A
+.Nm mktemp
+function appeared in
+.At v7 .
diff --git a/lib/libc/stdio/mktemp.c b/lib/libc/stdio/mktemp.c
new file mode 100644
index 0000000..3f5966e
--- /dev/null
+++ b/lib/libc/stdio/mktemp.c
@@ -0,0 +1,127 @@
+/*
+ * 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[] = "@(#)mktemp.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 <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h>
+
+static int _gettemp();
+
+mkstemp(path)
+ char *path;
+{
+ int fd;
+
+ return (_gettemp(path, &fd) ? fd : -1);
+}
+
+char *
+mktemp(path)
+ char *path;
+{
+ return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
+}
+
+static
+_gettemp(path, doopen)
+ char *path;
+ register int *doopen;
+{
+ extern int errno;
+ register char *start, *trv;
+ struct stat sbuf;
+ u_int pid;
+
+ pid = getpid();
+ for (trv = path; *trv; ++trv); /* extra X's get set to 0's */
+ while (*--trv == 'X') {
+ *trv = (pid % 10) + '0';
+ pid /= 10;
+ }
+
+ /*
+ * check the target directory; if you have six X's and it
+ * doesn't exist this runs for a *very* long time.
+ */
+ for (start = trv + 1;; --trv) {
+ if (trv <= path)
+ break;
+ if (*trv == '/') {
+ *trv = '\0';
+ if (stat(path, &sbuf))
+ return(0);
+ if (!S_ISDIR(sbuf.st_mode)) {
+ errno = ENOTDIR;
+ return(0);
+ }
+ *trv = '/';
+ 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 (stat(path, &sbuf))
+ return(errno == ENOENT ? 1 : 0);
+
+ /* tricky little algorithm for backward compatibility */
+ for (trv = start;;) {
+ if (!*trv)
+ return(0);
+ if (*trv == 'z')
+ *trv++ = 'a';
+ else {
+ if (isdigit(*trv))
+ *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..57a73fc
--- /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 && *s) {
+ 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..cf64e1e
--- /dev/null
+++ b/lib/libc/stdio/printf.3
@@ -0,0 +1,638 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt PRINTF 3
+.Os
+.Sh NAME
+.Nm printf ,
+.Nm fprintf ,
+.Nm sprintf ,
+.Nm snprintf ,
+.Nm vprintf ,
+.Nm vfprintf,
+.Nm vsprintf ,
+.Nm vsnprintf
+.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 smprintf "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" "char *format" "va_list ap"
+.Ft int
+.Fn vsnprintf "char *str" "size_t size" "const char *format" "va_list ap"
+.\" .Ft int
+.\" .Fn vsmprintf "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 .
+.\" .IR str ;
+.\" and
+.\" .I smprintf
+.\" and
+.\" .I vsmprintf
+.\" dynamically allocate a new string with
+.\" .IR malloc .
+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.
+.\" Except for
+.\" .I smprintf
+.\" and
+.\" .IR vsmprintf ,
+.\" all of these functions return
+These functions return
+the number of characters printed
+(not including the trailing
+.Ql \e0
+used to end output to strings).
+.\" .I Smprintf
+.\" and
+.\" .I vsmprintf
+.\" return a pointer to a string of an appropriate length;
+.\" this pointer should be passed to
+.\" .I free
+.\" to release the associated storage
+.\" when it is no longer needed.
+.\" If sufficient space is not avaliable,
+.\" .I smprintf
+.\" and
+.\" .I vsmprintf
+.\" will return
+.\" .SM
+.\" .BR
+.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.
+.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
+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 ( Mc 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 *
+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.
+.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 g
+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 snprintf
+and
+.Fn vsnprintf
+are new to this release.
+.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 impossible 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..eb6ae83
--- /dev/null
+++ b/lib/libc/stdio/printf.c
@@ -0,0 +1,67 @@
+/*-
+ * 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[] = "@(#)printf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#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..fc6e6a7
--- /dev/null
+++ b/lib/libc/stdio/putc.3
@@ -0,0 +1,129 @@
+.\" 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
+.\"
+.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
+.Fn Putc
+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
+.Fn Putchar
+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..c18353b
--- /dev/null
+++ b/lib/libc/stdio/putc.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)
+static char sccsid[] = "@(#)putc.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * A subroutine version of the macro putc.
+ */
+#undef putc
+
+putc(c, fp)
+ int c;
+ register FILE *fp;
+{
+ return (__sputc(c, fp));
+}
diff --git a/lib/libc/stdio/putchar.c b/lib/libc/stdio/putchar.c
new file mode 100644
index 0000000..036b897
--- /dev/null
+++ b/lib/libc/stdio/putchar.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)
+static char sccsid[] = "@(#)putchar.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+#undef putchar
+
+/*
+ * A subroutine version of the macro putchar
+ */
+putchar(c)
+ int c;
+{
+ register FILE *so = stdout;
+
+ return (__sputc(c, so));
+}
diff --git a/lib/libc/stdio/puts.c b/lib/libc/stdio/puts.c
new file mode 100644
index 0000000..96a8184
--- /dev/null
+++ b/lib/libc/stdio/puts.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)
+static char sccsid[] = "@(#)puts.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include "fvwrite.h"
+
+/*
+ * Write the given string to stdout, appending a newline.
+ */
+puts(s)
+ char const *s;
+{
+ 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;
+ return (__sfvwrite(stdout, &uio) ? EOF : '\n');
+}
diff --git a/lib/libc/stdio/putw.c b/lib/libc/stdio/putw.c
new file mode 100644
index 0000000..4ba8982
--- /dev/null
+++ b/lib/libc/stdio/putw.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)
+static char sccsid[] = "@(#)putw.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include "fvwrite.h"
+
+putw(w, fp)
+ int w;
+ FILE *fp;
+{
+ 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;
+ return (__sfvwrite(fp, &uio));
+}
diff --git a/lib/libc/stdio/refill.c b/lib/libc/stdio/refill.c
new file mode 100644
index 0000000..35af0c0
--- /dev/null
+++ b/lib/libc/stdio/refill.c
@@ -0,0 +1,128 @@
+/*-
+ * 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[] = "@(#)refill.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+
+static
+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.
+ */
+__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;
+ 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..7d6fc7d
--- /dev/null
+++ b/lib/libc/stdio/remove.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.
+.\"
+.\" @(#)remove.3 8.1 (Berkeley) 6/4/93
+.\"
+.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..216535a
--- /dev/null
+++ b/lib/libc/stdio/remove.c
@@ -0,0 +1,48 @@
+/*-
+ * 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[] = "@(#)remove.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <unistd.h>
+#include <stdio.h>
+
+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..4f8391b
--- /dev/null
+++ b/lib/libc/stdio/rewind.c
@@ -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
+ * 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[] = "@(#)rewind.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <stdio.h>
+
+void
+rewind(fp)
+ register FILE *fp;
+{
+ (void) fseek(fp, 0L, SEEK_SET);
+ clearerr(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..3299fb5
--- /dev/null
+++ b/lib/libc/stdio/rget.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)
+static char sccsid[] = "@(#)rget.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * Handle getc() when the buffer ran out:
+ * Refill, then return the first character
+ * in the newly-filled buffer.
+ */
+__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..377a602
--- /dev/null
+++ b/lib/libc/stdio/scanf.3
@@ -0,0 +1,430 @@
+.\" 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
+.\"
+.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.)
+.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
+.Xr 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
+.Xr 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 strtol 3 ,
+.Xr strtoul 3 ,
+.Xr strtod 3 ,
+.Xr getc 3 ,
+.Xr printf 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..d36b13a
--- /dev/null
+++ b/lib/libc/stdio/scanf.c
@@ -0,0 +1,67 @@
+/*-
+ * 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[] = "@(#)scanf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#if __STDC__
+scanf(char const *fmt, ...)
+#else
+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
+ ret = __svfscanf(stdin, fmt, ap);
+ 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..30e9db7
--- /dev/null
+++ b/lib/libc/stdio/setbuf.3
@@ -0,0 +1,202 @@
+.\" 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
+.\"
+.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" "size_t 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 fopen 3 ,
+.Xr fclose 3 ,
+.Xr fread 3 ,
+.Xr malloc 3 ,
+.Xr puts 3 ,
+.Xr printf 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..a6d06dd
--- /dev/null
+++ b/lib/libc/stdio/setbuffer.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)
+static char sccsid[] = "@(#)setbuffer.c 8.1 (Berkeley) 6/4/93";
+#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);
+}
+
+/*
+ * 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..867f9b4
--- /dev/null
+++ b/lib/libc/stdio/setvbuf.c
@@ -0,0 +1,160 @@
+/*-
+ * 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[] = "@(#)setvbuf.c 8.2 (Berkeley) 11/16/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "local.h"
+
+/*
+ * Set one of the three kinds of buffering, optionally including
+ * a buffer.
+ */
+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);
+
+ /*
+ * 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;
+ 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;
+
+ return (ret);
+}
diff --git a/lib/libc/stdio/snprintf.c b/lib/libc/stdio/snprintf.c
new file mode 100644
index 0000000..3c3cf7d
--- /dev/null
+++ b/lib/libc/stdio/snprintf.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)
+static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#if __STDC__
+snprintf(char *str, size_t n, char const *fmt, ...)
+#else
+snprintf(str, n, fmt, va_alist)
+ char *str;
+ size_t n;
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+ FILE f;
+
+ if ((int)n < 1)
+ return (EOF);
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = n - 1;
+ ret = vfprintf(&f, fmt, ap);
+ *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..254064f
--- /dev/null
+++ b/lib/libc/stdio/sprintf.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)
+static char sccsid[] = "@(#)sprintf.c 8.1 (Berkeley) 6/4/93";
+#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"
+
+#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._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..bb72744
--- /dev/null
+++ b/lib/libc/stdio/sscanf.c
@@ -0,0 +1,88 @@
+/*-
+ * 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[] = "@(#)sscanf.c 8.1 (Berkeley) 6/4/93";
+#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"
+
+/* ARGSUSED */
+static int
+eofread(cookie, buf, len)
+ void *cookie;
+ char *buf;
+ int len;
+{
+
+ return (0);
+}
+
+#if __STDC__
+sscanf(const char *str, char const *fmt, ...)
+#else
+sscanf(str, fmt, va_alist)
+ char *str;
+ char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+ FILE f;
+
+ 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..572df8c
--- /dev/null
+++ b/lib/libc/stdio/stdio.3
@@ -0,0 +1,287 @@
+.\" 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
+.\"
+.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 ouput 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 appended mode. If append mode
+is used, the position indicator will be placed 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 ouput takes place as if all characters were
+read by successive calls to the
+.Xr fputc 3
+function.
+.Pp
+A file is disassociated from a stream by
+.Em closing
+the file.
+Ouput 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 after a file is closed (garbage).
+.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, such as
+.Xr abort 3
+do not bother about closing files properly.
+.Pp
+This implementation needs and 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 input), 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 an 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
+.Xr libc
+and routines are automatically loaded as needed by the compilers
+.Xr cc 1
+and
+.Xr pc 1 .
+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 SEEK_END ,
+.Dv SEEK_SET ,
+.Dv SEE_CUR ,
+.Dv TMP_MAX ,
+.Dv clearerr ,
+.Dv feof ,
+.Dv ferror ,
+.Dv fileno ,
+.Dv freopen ,
+.Dv fwopen ,
+.Dv getc ,
+.Dv getchar ,
+.Dv putc ,
+.Dv putchar ,
+.Dv stderr ,
+.Dv stdin ,
+.Dv stdout .
+Function versions of the macro functions
+.Xr feof ,
+.Xr ferror ,
+.Xr clearerr ,
+.Xr fileno ,
+.Xr getc ,
+.Xr getchar ,
+.Xr putc ,
+and
+.Xr putchar
+exist and will be used if the macros
+definitions are explicitly removed.
+.Sh SEE ALSO
+.Xr open 2 ,
+.Xr close 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
+and
+.Xr abort .
+.Sh STANDARDS
+The
+.Nm stdio
+library conforms to
+.St -ansiC .
+.Sh LIST OF FUNCTIONS
+.Bl -column "Description"
+.Sy Function Description
+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
+fgetline 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
+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
+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..c2d7d87
--- /dev/null
+++ b/lib/libc/stdio/stdio.c
@@ -0,0 +1,104 @@
+/*-
+ * 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[] = "@(#)stdio.c 8.1 (Berkeley) 6/4/93";
+#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.
+ */
+__sread(cookie, buf, n)
+ void *cookie;
+ char *buf;
+ int n;
+{
+ register FILE *fp = cookie;
+ register int ret;
+
+ ret = read(fp->_file, buf, n);
+ /* if the read succeeded, update the current offset */
+ if (ret >= 0)
+ fp->_offset += ret;
+ else
+ fp->_flags &= ~__SOFF; /* paranoia */
+ return (ret);
+}
+
+__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, 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 == -1L)
+ fp->_flags &= ~__SOFF;
+ else {
+ fp->_flags |= __SOFF;
+ fp->_offset = ret;
+ }
+ return (ret);
+}
+
+__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..6644ae5
--- /dev/null
+++ b/lib/libc/stdio/tempnam.c
@@ -0,0 +1,86 @@
+/*
+ * 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[] = "@(#)tempnam.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <paths.h>
+
+char *
+tempnam(dir, pfx)
+ const char *dir, *pfx;
+{
+ int sverrno;
+ char *f, *name;
+
+ if (!(name = malloc(MAXPATHLEN)))
+ return(NULL);
+
+ if (!pfx)
+ pfx = "tmp.";
+
+ if (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..2f8abfc
--- /dev/null
+++ b/lib/libc/stdio/tmpfile.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[] = "@(#)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 <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..3b053ee
--- /dev/null
+++ b/lib/libc/stdio/tmpnam.3
@@ -0,0 +1,219 @@
+.\" 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
+.\"
+.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 )
+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..ce86482
--- /dev/null
+++ b/lib/libc/stdio/tmpnam.c
@@ -0,0 +1,58 @@
+/*-
+ * 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.
+ */
+
+#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>
+
+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..e88b64f
--- /dev/null
+++ b/lib/libc/stdio/ungetc.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.
+.\"
+.\" @(#)ungetc.3 8.1 (Berkeley) 6/4/93
+.\"
+.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 getc 3 ,
+.Xr fseek 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..deaed75
--- /dev/null
+++ b/lib/libc/stdio/ungetc.c
@@ -0,0 +1,148 @@
+/*-
+ * 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[] = "@(#)ungetc.c 8.2 (Berkeley) 11/3/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "local.h"
+
+/*
+ * 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
+__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, 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);
+}
+
+ungetc(c, fp)
+ int c;
+ register FILE *fp;
+{
+ if (c == EOF)
+ return (EOF);
+ if (!__sdidinit)
+ __sinit();
+ 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)
+ return (EOF);
+ if (fp->_flags & __SWR) {
+ if (__sflush(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))
+ return (EOF);
+ *--fp->_p = c;
+ fp->_r++;
+ 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++;
+ 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;
+ return (c);
+}
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
new file mode 100644
index 0000000..f53db61
--- /dev/null
+++ b/lib/libc/stdio/vfprintf.c
@@ -0,0 +1,867 @@
+/*-
+ * 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[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93";
+#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"
+
+/* Define FLOATING_POINT to get floating point. */
+#define FLOATING_POINT
+
+/*
+ * 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 */
+
+
+/*
+ * 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; unimplemented */
+#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; /* 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 fieldsz; /* field size expanded by sign, etc */
+ int realsz; /* field size expanded by dprec */
+ int size; /* size of converted field or string */
+ 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 */
+
+ /*
+ * 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; \
+}
+
+ /*
+ * To extend shorts properly, we need both signed and unsigned
+ * argument extraction methods.
+ */
+#define SARG() \
+ (flags&LONGINT ? va_arg(ap, long) : \
+ flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
+ (long)va_arg(ap, int))
+#define UARG() \
+ (flags&LONGINT ? va_arg(ap, u_long) : \
+ flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
+ (u_long)va_arg(ap, u_int))
+
+ /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
+ if (cantwrite(fp))
+ return (EOF);
+
+ /* optimise fprintf(stderr) (and other unbuffered Unix files) */
+ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
+ fp->_file >= 0)
+ return (__sbprintf(fp, fmt0, ap));
+
+ fmt = (char *)fmt0;
+ 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) {
+ 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.
+ */
+ if ((width = va_arg(ap, int)) >= 0)
+ goto rflag;
+ width = -width;
+ /* FALLTHROUGH */
+ case '-':
+ flags |= LADJUST;
+ goto rflag;
+ case '+':
+ sign = '+';
+ goto rflag;
+ case '.':
+ if ((ch = *fmt++) == '*') {
+ n = va_arg(ap, int);
+ 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));
+ width = n;
+ goto reswitch;
+#ifdef FLOATING_POINT
+ case 'L':
+ flags |= LONGDBL;
+ goto rflag;
+#endif
+ case 'h':
+ flags |= SHORTINT;
+ goto rflag;
+ case 'l':
+ flags |= LONGINT;
+ goto rflag;
+ case 'q':
+ flags |= QUADINT;
+ goto rflag;
+ case 'c':
+ *(cp = buf) = va_arg(ap, int);
+ size = 1;
+ sign = '\0';
+ break;
+ case 'D':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'd':
+ case 'i':
+ if (flags & QUADINT) {
+ uqval = va_arg(ap, 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)
+ _double = (double)va_arg(ap, long double);
+ else
+ _double = va_arg(ap, 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)
+ *va_arg(ap, quad_t *) = ret;
+ else if (flags & LONGINT)
+ *va_arg(ap, long *) = ret;
+ else if (flags & SHORTINT)
+ *va_arg(ap, short *) = ret;
+ else
+ *va_arg(ap, int *) = ret;
+ continue; /* no output */
+ case 'O':
+ flags |= LONGINT;
+ /*FALLTHROUGH*/
+ case 'o':
+ if (flags & QUADINT)
+ uqval = va_arg(ap, 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)va_arg(ap, void *);
+ base = 16;
+ xdigs = "0123456789abcdef";
+ flags = (flags & ~QUADINT) | HEXPREFIX;
+ ch = 'x';
+ goto nosign;
+ case 's':
+ if ((cp = va_arg(ap, 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, 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 = va_arg(ap, 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 = va_arg(ap, 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.
+ * fieldsz excludes decimal prec; realsz includes it.
+ */
+ fieldsz = size;
+ if (sign)
+ fieldsz++;
+ else if (flags & HEXPREFIX)
+ fieldsz += 2;
+ realsz = dprec > fieldsz ? dprec : fieldsz;
+
+ /* 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 - fieldsz, 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 += width > realsz ? width : realsz;
+
+ FLUSH(); /* copy out the I/O vectors */
+ }
+done:
+ FLUSH();
+error:
+ return (__sferror(fp) ? EOF : ret);
+ /* NOTREACHED */
+}
+
+#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..22ed5a0
--- /dev/null
+++ b/lib/libc/stdio/vfscanf.c
@@ -0,0 +1,748 @@
+/*-
+ * 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[] = "@(#)vfscanf.c 8.1 (Berkeley) 6/4/93";
+#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 "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; unimplemented */
+#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 */
+
+/*
+ * 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., strtol or strtoul */
+#define CT_FLOAT 4 /* floating, i.e., strtod */
+
+#define u_char unsigned char
+#define u_long unsigned long
+
+static u_char *__sccl();
+
+/*
+ * vfscanf
+ */
+__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 nread; /* number of characters consumed from fp */
+ int base; /* base argument to strtol/strtoul */
+ u_long (*ccfn)(); /* conversion function (strtol/strtoul) */
+ 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;
+ 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)) {
+ for (;;) {
+ if (fp->_r <= 0 && __srefill(fp))
+ return (nassigned);
+ if (!isspace(*fp->_p))
+ break;
+ 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 '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_long (*)())strtol;
+ base = 10;
+ break;
+
+ case 'i':
+ c = CT_INT;
+ ccfn = (u_long (*)())strtol;
+ base = 0;
+ break;
+
+ case 'O': /* compat */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'o':
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 8;
+ break;
+
+ case 'u':
+ c = CT_INT;
+ ccfn = strtoul;
+ base = 10;
+ break;
+
+ case 'X': /* compat XXX */
+ flags |= LONG;
+ /* FALLTHROUGH */
+ case 'x':
+ flags |= PFXOK; /* enable 0x prefixing */
+ c = CT_INT;
+ ccfn = strtoul;
+ 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 = strtoul;
+ base = 16;
+ break;
+
+ case 'n':
+ if (flags & SUPPRESS) /* ??? */
+ continue;
+ if (flags & SHORT)
+ *va_arg(ap, short *) = nread;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = 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_long (*)())strtol;
+ 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++;
+ }
+ break;
+
+ case CT_CCL:
+ /* scan a (nonempty) character class (sets NOSKIP) */
+ if (width == 0)
+ width = ~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;
+ break;
+
+ case CT_STRING:
+ /* like CCL, but zero-length string OK, & no NOSKIP */
+ if (width == 0)
+ width = ~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++;
+ }
+ continue;
+
+ case CT_INT:
+ /* scan an integer as if by strtol/strtoul */
+#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_long res;
+
+ *p = 0;
+ res = (*ccfn)(buf, (char **)NULL, base);
+ if (flags & POINTER)
+ *va_arg(ap, void **) = (void *)res;
+ else if (flags & SHORT)
+ *va_arg(ap, short *) = res;
+ else if (flags & LONG)
+ *va_arg(ap, long *) = res;
+ else
+ *va_arg(ap, int *) = res;
+ nassigned++;
+ }
+ nread += p - buf;
+ 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;
+ res = strtod(buf,(char **) NULL);
+ if (flags & LONG)
+ *va_arg(ap, double *) = res;
+ else
+ *va_arg(ap, float *) = res;
+ nassigned++;
+ }
+ nread += p - buf;
+ break;
+#endif /* FLOATING_POINT */
+ }
+ }
+input_failure:
+ return (nassigned ? nassigned : -1);
+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;
+
+ /* 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 */
+ /* should probably use memset here */
+ for (n = 0; n < 256; n++)
+ tab[n] = v;
+ 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 == ']' || n < c) {
+ c = '-';
+ break; /* resume the for(;;) */
+ }
+ fmt++;
+ do { /* fill in the range */
+ tab[++c] = v;
+ } while (c < n);
+#if 1 /* XXX another disgusting compatibility hack */
+ /*
+ * 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..f8184bb
--- /dev/null
+++ b/lib/libc/stdio/vprintf.c
@@ -0,0 +1,48 @@
+/*-
+ * 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[] = "@(#)vprintf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+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..5d12865
--- /dev/null
+++ b/lib/libc/stdio/vscanf.c
@@ -0,0 +1,49 @@
+/*-
+ * 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)
+static char sccsid[] = "@(#)vscanf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+vscanf(fmt, ap)
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+
+ return (__svfscanf(stdin, fmt, ap));
+}
diff --git a/lib/libc/stdio/vsnprintf.c b/lib/libc/stdio/vsnprintf.c
new file mode 100644
index 0000000..ccc8af6
--- /dev/null
+++ b/lib/libc/stdio/vsnprintf.c
@@ -0,0 +1,60 @@
+/*-
+ * 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[] = "@(#)vsnprintf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+vsnprintf(str, n, fmt, ap)
+ char *str;
+ size_t n;
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ int ret;
+ FILE f;
+
+ if ((int)n < 1)
+ return (EOF);
+ f._flags = __SWR | __SSTR;
+ f._bf._base = f._p = (unsigned char *)str;
+ f._bf._size = f._w = n - 1;
+ ret = vfprintf(&f, fmt, ap);
+ *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..c6e192a
--- /dev/null
+++ b/lib/libc/stdio/vsprintf.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[] = "@(#)vsprintf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <limits.h>
+
+vsprintf(str, fmt, ap)
+ char *str;
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ int ret;
+ FILE f;
+
+ 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..e776689
--- /dev/null
+++ b/lib/libc/stdio/vsscanf.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
+ * 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)
+static char sccsid[] = "@(#)vsscanf.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <string.h>
+
+/* ARGSUSED */
+static int
+eofread(cookie, buf, len)
+ void *cookie;
+ char *buf;
+ int len;
+{
+
+ return (0);
+}
+
+vsscanf(str, fmt, ap)
+ const char *str;
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ FILE f;
+
+ 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..36d7c8d
--- /dev/null
+++ b/lib/libc/stdio/wbuf.c
@@ -0,0 +1,88 @@
+/*-
+ * 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[] = "@(#)wbuf.c 8.1 (Berkeley) 6/4/93";
+#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.
+ */
+__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..1215edc
--- /dev/null
+++ b/lib/libc/stdio/wsetup.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)
+static char sccsid[] = "@(#)wsetup.c 8.1 (Berkeley) 6/4/93";
+#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.
+ */
+__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..81e8ed0
--- /dev/null
+++ b/lib/libc/stdlib/Makefile.inc
@@ -0,0 +1,30 @@
+# @(#)Makefile.inc 8.2 (Berkeley) 2/16/94
+
+# machine-independent stdlib sources
+.PATH: ${.CURDIR}/${MACHINE}/stdlib ${.CURDIR}/stdlib
+
+SRCS+= abort.c atexit.c atof.c atoi.c atol.c bsearch.c calloc.c div.c \
+ exit.c getenv.c getopt.c getsubopt.c strhash.c heapsort.c labs.c \
+ ldiv.c malloc.c merge.c putenv.c qsort.c radixsort.c rand.c random.c \
+ realpath.c setenv.c strtod.c strtol.c strtoq.c strtoul.c \
+ strtouq.c system.c
+
+# machine-dependent stdlib sources
+.include "${.CURDIR}/${MACHINE}/stdlib/Makefile.inc"
+
+MAN3+= stdlib/abort.3 stdlib/abs.3 stdlib/alloca.3 stdlib/atexit.3 \
+ stdlib/atof.3 stdlib/atoi.3 stdlib/atol.3 stdlib/bsearch.3 \
+ stdlib/calloc.3 stdlib/div.3 stdlib/exit.3 \
+ stdlib/getenv.3 stdlib/getopt.3 stdlib/getsubopt.3 stdlib/labs.3 \
+ stdlib/ldiv.3 stdlib/malloc.3 stdlib/memory.3 stdlib/qsort.3 \
+ stdlib/radixsort.3 stdlib/rand.3 stdlib/random.3 \
+ stdlib/realpath.3 stdlib/strtod.3 stdlib/strtol.3 stdlib/strtoul.3 \
+ stdlib/system.3
+
+MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.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
+MLINKS+=strtol.3 strtoq.3
+MLINKS+=strtoul.3 strtouq.3
+MLINKS+=malloc.3 free.3 malloc.3 realloc.3
diff --git a/lib/libc/stdlib/abort.3 b/lib/libc/stdlib/abort.3
new file mode 100644
index 0000000..83b4e04
--- /dev/null
+++ b/lib/libc/stdlib/abort.3
@@ -0,0 +1,70 @@
+.\" 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
+.\"
+.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
+No open streams are closed or flushed.
+.Sh RETURN VALUES
+The
+.Nm abort
+function
+never returns.
+.Sh SEE ALSO
+.Xr sigaction 2 ,
+.Xr exit 2
+.Sh STANDARDS
+The
+.Fn abort
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/stdlib/abort.c b/lib/libc/stdlib/abort.c
new file mode 100644
index 0000000..690bdf5
--- /dev/null
+++ b/lib/libc/stdlib/abort.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[] = "@(#)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>
+
+void
+abort()
+{
+ sigset_t mask;
+
+ 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);
+ (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+ (void)kill(getpid(), SIGABRT);
+
+ /*
+ * if SIGABRT ignored, or caught and the handler returns, do
+ * it again, only harder.
+ */
+ (void)signal(SIGABRT, SIG_DFL);
+ (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+ (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..e12f798
--- /dev/null
+++ b/lib/libc/stdlib/abs.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
+.\" 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
+.\"
+.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 floor 3 ,
+.Xr labs 3
+.Xr cabs 3
+.Xr hypot 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..ad5aaf69
--- /dev/null
+++ b/lib/libc/stdlib/alloca.3
@@ -0,0 +1,78 @@
+.\" 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
+.\"
+.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 pagesize 2
+.Xr calloc 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..d50d57c
--- /dev/null
+++ b/lib/libc/stdlib/atexit.3
@@ -0,0 +1,77 @@
+.\" 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
+.\"
+.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..9c4caed
--- /dev/null
+++ b/lib/libc/stdlib/atexit.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)
+static char sccsid[] = "@(#)atexit.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include "atexit.h"
+
+/*
+ * 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 = malloc(sizeof(*p))) == NULL)
+ 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..3067e8d
--- /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.1 (Berkeley) 6/4/93
+ */
+
+/* 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 */
+};
+
+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..978d3f4
--- /dev/null
+++ b/lib/libc/stdlib/atof.3
@@ -0,0 +1,87 @@
+.\" 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
+.\"
+.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 .
+.Sh BUGS
+This manual page represents intent instead of actual practice.
+While it is intended that
+.Fn atof
+be implemented using
+.Xr strtod 3 ,
+this has not yet happened.
+In the current system,
+.Fn atof
+translates a string in the following form to a double: a string of
+leading white space, possibly followed by a sign (``+'' or ``-''),
+followed by a digit string which may contain one decimal point (``.''),
+which may be followed by either of the exponent flags (``E'' or ``e''),
+and lastly, followed by a signed or unsigned integer.
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..a39779f
--- /dev/null
+++ b/lib/libc/stdlib/atoi.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
+.\" 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
+.\"
+.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..a13c0e2
--- /dev/null
+++ b/lib/libc/stdlib/atoi.c
@@ -0,0 +1,45 @@
+/*
+ * 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>
+
+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..6b12cc9
--- /dev/null
+++ b/lib/libc/stdlib/atol.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.
+.\"
+.\" @(#)atol.3 8.1 (Berkeley) 6/4/93
+.\"
+.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..e4cf49f
--- /dev/null
+++ b/lib/libc/stdlib/bsearch.3
@@ -0,0 +1,90 @@
+.\" 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
+.\"
+.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.3 b/lib/libc/stdlib/calloc.3
new file mode 100644
index 0000000..0ca15e5
--- /dev/null
+++ b/lib/libc/stdlib/calloc.3
@@ -0,0 +1,70 @@
+.\" 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.
+.\"
+.\" @(#)calloc.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt CALLOC 3
+.Os
+.Sh NAME
+.Nm calloc
+.Nd allocate clean memory (zero initialized space)
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft void *
+.Fn calloc "size_t nmemb" "size_t size"
+.Sh DESCRIPTION
+The
+.Fn calloc
+function allocates space for an array of
+.Fa nmemb
+objects, each of whose size is
+.Fa size .
+The space is initialized to all bits zero.
+.Sh RETURN VALUES
+The
+.Fn calloc
+function returns
+a pointer to the
+the allocated space if successful; otherwise a null pointer is returned.
+.Sh SEE ALSO
+.Xr malloc 3 ,
+.Xr realloc 3 ,
+.Xr free 3 ,
+.Sh STANDARDS
+The
+.Fn calloc
+function conforms to
+.St -ansiC .
diff --git a/lib/libc/stdlib/calloc.c b/lib/libc/stdlib/calloc.c
new file mode 100644
index 0000000..d7c8e07
--- /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..f09e818
--- /dev/null
+++ b/lib/libc/stdlib/div.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
+.\" 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
+.\"
+.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..43ee3c0
--- /dev/null
+++ b/lib/libc/stdlib/exit.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
+.\" 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
+.\"
+.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
+.Sh RETURN VALUES
+The
+.Fn exit
+function
+never returns.
+.Sh SEE ALSO
+.Xr _exit 2 ,
+.Xr atexit 3 ,
+.Xr intro 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..a8f6e24
--- /dev/null
+++ b/lib/libc/stdlib/exit.c
@@ -0,0 +1,60 @@
+/*-
+ * 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)();
+
+/*
+ * Exit, flushing stdio buffers if necessary.
+ */
+void
+exit(status)
+ int status;
+{
+ register struct atexit *p;
+ register int n;
+
+ 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..f552d3d
--- /dev/null
+++ b/lib/libc/stdlib/getenv.3
@@ -0,0 +1,151 @@
+.\" 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
+.\"
+.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..95ff6e6
--- /dev/null
+++ b/lib/libc/stdlib/getopt.3
@@ -0,0 +1,252 @@
+.\" 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.4 (Berkeley) 4/19/94
+.\"
+.Dd April 19, 1994
+.Dt GETOPT 3
+.Os BSD 4.3
+.Sh NAME
+.Nm getopt
+.Nd get option character from command line argument list
+.Sh SYNOPSIS
+.Fd #include <stdlib.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 an
+.Dv EOF
+when the argument list is exhausted, or a non-recognized
+option is encountered.
+The interpretation of options in the argument list may be cancelled
+by the option
+.Ql --
+(double dash) which causes
+.Fn getopt
+to signal the end of argument processing and return an
+.Dv EOF .
+When all options have been processed (i.e., up to the first non-option
+argument),
+.Fn getopt
+returns
+.Dv EOF .
+.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 and returns
+.Ql ?
+to the
+.Em stderr .
+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:")) != EOF)
+ 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
+.Bx 4.3 .
+.Sh BUGS
+A single dash
+.Dq Li -
+may be specified as an 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
+.Dv EOF .
+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 ((c = getopt(argc, argv, "0123456789")) != EOF)
+ switch (c) {
+ 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..994d757
--- /dev/null
+++ b/lib/libc/stdlib/getopt.c
@@ -0,0 +1,117 @@
+/*
+ * 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.2 (Berkeley) 4/2/94";
+#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 */
+
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc || *(place = nargv[optind]) != '-') {
+ place = EMSG;
+ return (EOF);
+ }
+ if (place[1] && *++place == '-') { /* found "--" */
+ ++optind;
+ place = EMSG;
+ return (EOF);
+ }
+ } /* option letter okay? */
+ if ((optopt = (int)*place++) == (int)':' ||
+ !(oli = strchr(ostr, optopt))) {
+ /*
+ * if the user didn't specify '-' as an option,
+ * assume it means EOF.
+ */
+ if (optopt == (int)'-')
+ return (EOF);
+ 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 == ':')
+ return (BADARG);
+ if (opterr)
+ (void)fprintf(stderr,
+ "%s: option requires an argument -- %c\n",
+ __progname, optopt);
+ return (BADCH);
+ }
+ 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..e1040d7
--- /dev/null
+++ b/lib/libc/stdlib/getsubopt.3
@@ -0,0 +1,145 @@
+.\" 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
+.\"
+.Dd June 9, 1993
+.Dt GETSUBOPT 3
+.Os
+.Sh NAME
+.Nm getsubopt
+.Nd get sub options from an argument
+.Sh SYNOPSIS
+.Fd #include <stdlib.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 4.4BSD.
diff --git a/lib/libc/stdlib/getsubopt.c b/lib/libc/stdlib/getsubopt.c
new file mode 100644
index 0000000..afd577a
--- /dev/null
+++ b/lib/libc/stdlib/getsubopt.c
@@ -0,0 +1,98 @@
+/*-
+ * 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;
+
+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..d800064
--- /dev/null
+++ b/lib/libc/stdlib/heapsort.c
@@ -0,0 +1,184 @@
+/*-
+ * 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 <sys/types.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stddef.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..ef9ba80
--- /dev/null
+++ b/lib/libc/stdlib/labs.3
@@ -0,0 +1,66 @@
+.\" 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
+.\"
+.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 floor 3 ,
+.Xr cabs 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..a68952f
--- /dev/null
+++ b/lib/libc/stdlib/ldiv.3
@@ -0,0 +1,70 @@
+.\" 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
+.\"
+.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 "int num" "int 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..94a3fd6
--- /dev/null
+++ b/lib/libc/stdlib/malloc.3
@@ -0,0 +1,191 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt MALLOC 3
+.Os BSD 4
+.Sh NAME
+.Nm malloc ,
+.Nd general memory allocation function
+.Pp
+.Nm free
+.Nd free up memory allocated with malloc, calloc or realloc
+.Pp
+.Nm realloc
+.Nd reallocation of memory function
+.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"
+.Sh DESCRIPTION
+The
+.Fn malloc
+function allocates uninitialized space for an object whose
+size is specified by
+.Fa size .
+The
+.Fn malloc
+function maintains multiple lists of free blocks according to size, allocating
+space from the appropriate list.
+.Pp
+The allocated space is
+suitably aligned (after possible pointer
+coercion) for storage of any type of object. If the space is of
+.Em pagesize
+or larger, the memory returned will be page-aligned.
+.Pp
+The
+.Fn free
+function causes the space pointed to by
+.Fa ptr
+to be deallocated, that is, at least made available for further allocation,
+but if possible, it will passed back to the kernel with
+.Xr sbrk 2 .
+If
+.Fa ptr
+is a null pointer, no action occurs.
+.Pp
+The
+.Fn realloc
+function changes the size of the object pointed to by
+.Fa ptr
+to the size specified by
+.Fa size .
+The contents of the object 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 object is indeterminate.
+If
+.Fa ptr
+is a null pointer, the
+.Fn realloc
+function behaves like the
+.Fn malloc
+function for the specified size.
+If the space cannot be allocated, the object
+pointed to by
+.Fa ptr
+is unchanged.
+If
+.Fa size
+is zero and
+.Fa ptr
+is not a null pointer, the object it points to is freed.
+.Pp
+
+.Sh ENVIRONMENT
+This malloc will check the environment for a variable called
+.Em MALLOC_OPTIONS
+and scan it for flags.
+Flags are single letters, uppercase means on, lowercase means off.
+.Bl -tag -width indent
+.It A
+``abort'' malloc will coredump the process, rather that tollerate failure.
+This is a very handy debugging aid, since the core file will represent the
+time of failure,
+rather than when the NULL pointer was accessed.
+
+.It D
+``dump'' malloc will dump statistics in a file called ``malloc.out'' at exit.
+
+.It J
+``junk'' fill some junk into the area allocated.
+Currently junk is bytes of 0xd0, this is pronounced ``Duh'' :-)
+
+.It R
+``realloc'' always reallocate when
+.Fn realloc
+is called, even if the initial allocation was big enough.
+This can substantially aid in compacting memory.
+
+.It Z
+``zero'' fill some junk into the area allocated (see ``J''),
+except for the exact length the user asked for, which is zerod.
+
+.El
+.Pp
+The ``J'' and ``Z'' is mostly for testing and debugging,
+if a program changes behaviour if either of these options are used,
+it is buggy.
+.Sh RETURN VALUES
+The
+.Fn malloc
+function returns
+a pointer to the allocated space if successful; otherwise
+a null pointer is returned.
+.Pp
+The
+.Fn free
+function returns no value.
+.Pp
+The
+.Fn realloc
+function returns either a null pointer or a pointer
+to the possibly moved allocated space.
+.Sh SEE ALSO
+.Xr brk 2 ,
+.Xr pagesize 2 ,
+.Xr calloc 3 ,
+.Xr alloca 3 ,
+.Xr memory 3
+.Sh STANDARDS
+The
+.Fn malloc
+function conforms to
+.St -ansiC .
+.Sh HISTORY
+The present implementation of malloc started out as a filesystem on a drum
+attached to a 20bit binary challenged computer built with discrete germanium
+transistors, and it has since graduated to handle primary storage rather than
+secondary.
+.Pp
+The main difference from other malloc implementations are belived to be that
+the free pages are not accessed until allocated.
+Most malloc implementations will store a data structure containing a,
+possibly double-, linked list in the free chunks of memory, used to tie
+all the free memory together.
+That is a quite suboptimal thing to do.
+Every time the free-list is traversed, all the otherwise unused, and very
+likely paged out, pages get faulted into primary memory, just to see what
+lies after them in the list.
+.Pp
+On systems which are paging, this can make a factor five in difference on the
+pagefaults of a process.
diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c
new file mode 100644
index 0000000..4299028
--- /dev/null
+++ b/lib/libc/stdlib/malloc.c
@@ -0,0 +1,1155 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "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
+ * ----------------------------------------------------------------------------
+ *
+ * $Id: malloc.c,v 1.8 1995/12/18 12:03:54 phk Exp $
+ *
+ */
+
+/*
+ * Defining EXTRA_SANITY will enable some checks which are related
+ * to internal conditions and consistency in malloc.c
+ */
+#undef EXTRA_SANITY
+
+/*
+ * Defining MALLOC_STATS will enable you to call malloc_dump() and set
+ * the [dD] options in the MALLOC_OPTIONS environment variable.
+ * It has no run-time performance hit.
+ */
+#define MALLOC_STATS
+
+#if defined(EXTRA_SANITY) && !defined(MALLOC_STATS)
+# define MALLOC_STATS /* required for EXTRA_SANITY */
+#endif
+
+/*
+ * What to use for Junk
+ */
+#define SOME_JUNK 0xd0 /* as in "Duh" :-) */
+
+/*
+ * If these weren't defined here, they would be calculated on the fly,
+ * at a considerable cost in performance.
+ */
+#if defined(__i386__) && defined(__FreeBSD__)
+# define malloc_pagesize 4096U
+# define malloc_pageshift 12U
+# define malloc_minsize 16U
+# define malloc_maxsize ((malloc_pagesize)>>1)
+#endif /* __i386__ && __FreeBSD__ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <memory.h>
+#include <errno.h>
+#include <err.h>
+#include <sys/types.h>
+#include <sys/mman.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_long 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 */
+ u_long size; /* number of bytes free */
+};
+
+/*
+ * How many bits per u_long in the bitmap.
+ * Change only if not 8 bits/byte
+ */
+#define MALLOC_BITS (8*sizeof(u_long))
+
+/*
+ * 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)
+
+/*
+ * The i386 architecture has some very convenient instructions.
+ * We might as well use them. There are C-language backups, but
+ * they are considerably slower.
+ */
+#ifdef __i386__
+#define ffs _ffs
+static __inline int
+_ffs(unsigned input)
+{
+ int result;
+ asm("bsfl %1,%0" : "=r" (result) : "r" (input));
+ return result+1;
+}
+
+#define fls _fls
+static __inline int
+_fls(unsigned input)
+{
+ int result;
+ asm("bsrl %1,%0" : "=r" (result) : "r" (input));
+ return result+1;
+}
+
+#define set_bit _set_bit
+static __inline void
+_set_bit(struct pginfo *pi, int bit)
+{
+ asm("btsl %0,(%1)" :
+ : "r" (bit & (MALLOC_BITS-1)), "r" (pi->bits+(bit/MALLOC_BITS)));
+}
+
+#define clr_bit _clr_bit
+static __inline void
+_clr_bit(struct pginfo *pi, int bit)
+{
+ asm("btcl %0,(%1)" :
+ : "r" (bit & (MALLOC_BITS-1)), "r" (pi->bits+(bit/MALLOC_BITS)));
+}
+
+#endif /* __i386__ */
+
+/*
+ * Set to one when malloc_init has been called
+ */
+static unsigned initialized;
+
+/*
+ * The size of a page.
+ * Must be a integral multiplum of the granularity of mmap(2).
+ * Your toes will curl if it isn't a power of two
+ */
+#ifndef malloc_pagesize
+static unsigned malloc_pagesize;
+#endif /* malloc_pagesize */
+
+/*
+ * 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)
+
+/*
+ * malloc_pagesize == 1 << malloc_pageshift
+ */
+#ifndef malloc_pageshift
+static unsigned malloc_pageshift;
+#endif /* malloc_pageshift */
+
+/*
+ * The smallest allocation we bother about.
+ * Must be power of two
+ */
+#ifndef malloc_minsize
+static unsigned malloc_minsize;
+#endif /* malloc_minsize */
+
+/*
+ * The largest chunk we care about.
+ * Must be smaller than pagesize
+ * Must be power of two
+ */
+#ifndef malloc_maxsize
+static unsigned malloc_maxsize;
+#endif /* malloc_maxsize */
+
+/*
+ * The minimum size (in bytes) of the free page cache.
+ */
+#ifndef malloc_cache
+static unsigned malloc_cache;
+#endif /* malloc_cache */
+
+/*
+ * 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() if we fail to get VM ?
+ */
+static int malloc_abort;
+
+/*
+ * Are we trying to die ?
+ */
+static int suicide;
+
+#ifdef MALLOC_STATS
+/*
+ * dump statistics
+ */
+static int malloc_stats;
+#endif /* MALLOC_STATS */
+
+/*
+ * always realloc ?
+ */
+static int malloc_realloc;
+
+/*
+ * zero fill ?
+ */
+static int malloc_zero;
+
+/*
+ * junk fill ?
+ */
+static int malloc_junk;
+
+/*
+ * my last break.
+ */
+static void *malloc_brk;
+
+/*
+ * one location cache for free-list holders
+ */
+static struct pgfree *px;
+
+/*
+ * Necessary function declarations
+ */
+static int extend_pgdir(u_long index);
+
+#ifdef MALLOC_STATS
+void
+malloc_dump(FILE *fd)
+{
+ struct pginfo **pd;
+ struct pgfree *pf;
+ int j;
+
+ pd = page_dir;
+
+ /* print out all the pages */
+ for(j=0;j<=last_index;j++) {
+ fprintf(fd,"%08lx %5d ",(j+malloc_origo) << malloc_pageshift,j);
+ if (pd[j] == MALLOC_NOT_MINE) {
+ for(j++;j<=last_index && pd[j] == MALLOC_NOT_MINE;j++)
+ ;
+ j--;
+ fprintf(fd,".. %5d not mine\n", j);
+ } else if (pd[j] == MALLOC_FREE) {
+ for(j++;j<=last_index && pd[j] == MALLOC_FREE;j++)
+ ;
+ j--;
+ fprintf(fd,".. %5d free\n", j);
+ } else if (pd[j] == MALLOC_FIRST) {
+ for(j++;j<=last_index && pd[j] == MALLOC_FOLLOW;j++)
+ ;
+ j--;
+ fprintf(fd,".. %5d in use\n", j);
+ } else if (pd[j] < MALLOC_MAGIC) {
+ fprintf(fd,"(%p)\n", pd[j]);
+ } else {
+ fprintf(fd,"%p %d (of %d) x %d @ %p --> %p\n",
+ pd[j],pd[j]->free, pd[j]->total,
+ pd[j]->size, pd[j]->page, pd[j]->next);
+ }
+ }
+
+ for(pf=free_list.next; pf; pf=pf->next) {
+ fprintf(fd,"Free: @%p [%p...%p[ %ld ->%p <-%p\n",
+ pf,pf->page,pf->end,pf->size,pf->prev,pf->next);
+ if (pf == pf->next) {
+ fprintf(fd,"Free_list loops.\n");
+ break;
+ }
+ }
+
+ /* print out various info */
+ fprintf(fd,"Minsize\t%d\n",malloc_minsize);
+ fprintf(fd,"Maxsize\t%d\n",malloc_maxsize);
+ fprintf(fd,"Pagesize\t%d\n",malloc_pagesize);
+ fprintf(fd,"Pageshift\t%d\n",malloc_pageshift);
+ fprintf(fd,"FirstPage\t%ld\n",malloc_origo);
+ fprintf(fd,"LastPage\t%ld %lx\n",last_index+malloc_pageshift,
+ (last_index + malloc_pageshift) << malloc_pageshift);
+ fprintf(fd,"Break\t%ld\n",(u_long)sbrk(0) >> malloc_pageshift);
+}
+#endif /* MALLOC_STATS */
+
+static void
+wrterror(char *p)
+{
+ char *q = "Malloc error: ";
+ suicide = 1;
+ write(2,q,strlen(q));
+ write(2,p,strlen(p));
+#ifdef MALLOC_STATS
+ if (malloc_stats)
+ malloc_dump(stderr);
+#endif /* MALLOC_STATS */
+ abort();
+}
+
+static void
+wrtwarning(char *p)
+{
+ char *q = "Malloc warning: ";
+ if (malloc_abort)
+ wrterror(p);
+ write(2,q,strlen(q));
+ write(2,p,strlen(p));
+}
+
+#ifdef EXTRA_SANITY
+static void
+malloc_exit()
+{
+ FILE *fd = fopen("malloc.out","a");
+ char *q = "malloc() warning: Couldn't dump stats.\n";
+ if (fd) {
+ malloc_dump(fd);
+ fclose(fd);
+ } else
+ write(2,q,strlen(q));
+}
+#endif /* EXTRA_SANITY */
+
+
+/*
+ * Allocate a number of pages from the OS
+ */
+static caddr_t
+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("(internal): 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;
+}
+
+/*
+ * Set a bit in the bitmap
+ */
+#ifndef set_bit
+static __inline void
+set_bit(struct pginfo *pi, int bit)
+{
+ pi->bits[bit/MALLOC_BITS] |= 1<<(bit%MALLOC_BITS);
+}
+#endif /* set_bit */
+
+/*
+ * Clear a bit in the bitmap
+ */
+#ifndef clr_bit
+static __inline void
+clr_bit(struct pginfo *pi, int bit)
+{
+ pi->bits[bit/MALLOC_BITS] &= ~(1<<(bit%MALLOC_BITS));
+}
+#endif /* clr_bit */
+
+#ifndef tst_bit
+/*
+ * Test a bit in the bitmap
+ */
+static __inline int
+tst_bit(struct pginfo *pi, int bit)
+{
+ return pi->bits[bit/MALLOC_BITS] & (1<<(bit%MALLOC_BITS));
+}
+#endif /* tst_bit */
+
+/*
+ * Find last bit
+ */
+#ifndef fls
+static __inline int
+fls(int size)
+{
+ int i = 1;
+ while (size >>= 1)
+ i++;
+ return i;
+}
+#endif /* fls */
+
+/*
+ * 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(0, i * malloc_pagesize, PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0);
+ 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((caddr_t)old, oldlen);
+ return 1;
+}
+
+/*
+ * Initialize the world
+ */
+static void
+malloc_init ()
+{
+ char *p;
+
+#ifdef EXTRA_SANITY
+ malloc_junk = 1;
+#endif /* EXTRA_SANITY */
+
+ for (p=getenv("MALLOC_OPTIONS"); p && *p; p++) {
+ switch (*p) {
+ case 'a': malloc_abort = 0; break;
+ case 'A': malloc_abort = 1; break;
+#ifdef MALLOC_STATS
+ case 'd': malloc_stats = 0; break;
+ case 'D': malloc_stats = 1; break;
+#endif /* MALLOC_STATS */
+ case 'r': malloc_realloc = 0; break;
+ case 'R': malloc_realloc = 1; break;
+ case 'j': malloc_junk = 0; break;
+ case 'J': malloc_junk = 1; break;
+ case 'z': malloc_zero = 0; break;
+ case 'Z': malloc_zero = 1; break;
+ default:
+ wrtwarning("(Init): Unknown char in MALLOC_OPTIONS\n");
+ p = 0;
+ break;
+ }
+ }
+
+ /*
+ * We want junk in the entire allocation, and zero only in the part
+ * the user asked for.
+ */
+ if (malloc_zero)
+ malloc_junk=1;
+
+#ifdef EXTRA_SANITY
+ if (malloc_stats)
+ atexit(malloc_exit);
+#endif /* EXTRA_SANITY */
+
+#ifndef malloc_pagesize
+ /* determine our pagesize */
+ malloc_pagesize = getpagesize();
+#endif /* malloc_pagesize */
+
+#ifndef malloc_maxsize
+ malloc_maxsize = malloc_pagesize >> 1;
+#endif /* malloc_maxsize */
+
+#ifndef malloc_pageshift
+ {
+ int i;
+ /* determine how much we shift by to get there */
+ for (i = malloc_pagesize; i > 1; i >>= 1)
+ malloc_pageshift++;
+ }
+#endif /* malloc_pageshift */
+
+#ifndef malloc_cache
+ malloc_cache = 100 << malloc_pageshift;
+#endif /* malloc_cache */
+
+#ifndef malloc_minsize
+ {
+ int i;
+ /*
+ * find the smallest size allocation we will bother about.
+ * this is determined as the smallest allocation that can hold
+ * it's own pginfo;
+ */
+ i = 2;
+ for(;;) {
+ int j;
+
+ /* Figure out the size of the bits */
+ j = malloc_pagesize/i;
+ j /= 8;
+ if (j < sizeof(u_long))
+ j = sizeof (u_long);
+ if (sizeof(struct pginfo) + j - sizeof (u_long) <= i)
+ break;
+ i += i;
+ }
+ malloc_minsize = i;
+ }
+#endif /* malloc_minsize */
+
+ /* Allocate one page for the page directory */
+ page_dir = (struct pginfo **) mmap(0, malloc_pagesize, PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, -1, 0);
+ if (page_dir == (struct pginfo **) -1)
+ wrterror("(Init) my first mmap 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;
+
+ /* Been here, done that */
+ initialized++;
+
+ /*
+ * 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 *) malloc (sizeof *px);
+}
+
+/*
+ * Allocate a number of complete pages
+ */
+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 += 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
+ free(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 = sizeof *bp - sizeof(u_long);
+ l += sizeof(u_long) *
+ (((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 *)malloc(l);
+ if (!bp)
+ return 0;
+ }
+
+ bp->size = (1<<bits);
+ bp->shift = bits;
+ bp->total = bp->free = malloc_pagesize >> bits;
+ bp->page = pp;
+
+ page_dir[ptr2index(pp)] = bp;
+
+ bp->next = page_dir[bits];
+ page_dir[bits] = bp;
+
+ /* set all valid bits in the bits */
+ 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++)
+ set_bit(bp,i);
+
+ if (bp == bp->page) {
+ /* Mark the ones we stole for ourselves */
+ for(i=0;l > 0;i++) {
+ clr_bit(bp,i);
+ bp->free--;
+ bp->total--;
+ l -= (1 << bits);
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Allocate a fragment
+ */
+static void *
+malloc_bytes(size_t size)
+{
+ int j;
+ struct pginfo *bp;
+ int k;
+ u_long *lp;
+
+ /* Don't bother with anything less than this */
+ if (size < malloc_minsize)
+ size = malloc_minsize;
+
+ /* Find the right bucket */
+ j = fls((size)-1);
+
+ /* 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 */
+ k = ffs(*lp) - 1;
+ *lp ^= 1<<k;
+
+ /* 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(bp->page + k, SOME_JUNK, bp->size);
+
+ return bp->page + k;
+}
+
+/*
+ * Allocate a piece of memory
+ */
+void *
+malloc(size_t size)
+{
+ void *result;
+
+ if (!initialized)
+ malloc_init();
+
+ if (suicide)
+ abort();
+
+ if (size <= malloc_maxsize)
+ result = malloc_bytes(size);
+ else
+ result = malloc_pages(size);
+
+ if (malloc_abort && !result)
+ wrterror("malloc(): returns NULL\n");
+
+ if (malloc_zero)
+ memset(result,0,size);
+
+ return result;
+}
+
+/*
+ * Change the size of an allocation.
+ */
+void *
+realloc(void *ptr, size_t size)
+{
+ void *p;
+ u_long osize,index;
+ struct pginfo **mp;
+ int i;
+
+ if (suicide)
+ return 0;
+
+ if (!ptr) /* Bounce to malloc() */
+ return malloc(size);
+
+ if (!initialized) {
+ wrtwarning("realloc(): malloc() never got called.\n");
+ return 0;
+ }
+
+ if (ptr && !size) { /* Bounce to free() */
+ free(ptr);
+ return 0;
+ }
+
+ index = ptr2index(ptr);
+
+ if (index < malloc_pageshift) {
+ wrtwarning("realloc(): junk pointer (too low)\n");
+ return 0;
+ }
+
+ if (index > last_index) {
+ wrtwarning("realloc(): junk pointer (too high)\n");
+ return 0;
+ }
+
+ mp = &page_dir[index];
+
+ if (*mp == MALLOC_FIRST) { /* Page allocation */
+
+ /* Check the pointer */
+ if ((u_long)ptr & malloc_pagemask) {
+ wrtwarning("realloc(): 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("realloc(): 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 (tst_bit(*mp,i)) {
+ wrtwarning("realloc(): already free chunk.\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("realloc(): wrong page pointer.\n");
+ return 0;
+ }
+
+ p = malloc(size);
+
+ if (p) {
+ /* copy the lesser of the two sizes, and free the old one */
+ if (osize < size)
+ memcpy(p,ptr,osize);
+ else
+ memcpy(p,ptr,size);
+ free(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;
+ u_long l;
+ void *tail;
+
+ if (info == MALLOC_FREE) {
+ wrtwarning("free(): already free page.\n");
+ return;
+ }
+
+ if (info != MALLOC_FIRST) {
+ wrtwarning("free(): freeing wrong page.\n");
+ return;
+ }
+
+ if ((u_long)ptr & malloc_pagemask) {
+ wrtwarning("free(): 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;
+
+ tail = ptr+l;
+
+ /* add to free-list */
+ if (!px)
+ px = malloc(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 = 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 += 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;
+ free(pt);
+ }
+ } 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("messed up free list");
+ }
+ }
+
+ /* 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 = 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. */
+ }
+}
+
+/*
+ * 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("free(): modified pointer.\n");
+ return;
+ }
+
+ if (tst_bit(info,i)) {
+ wrtwarning("free(): already free chunk.\n");
+ return;
+ }
+
+ set_bit(info,i);
+ 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)
+ free(info);
+ free(vp);
+}
+
+void
+free(void *ptr)
+{
+ struct pginfo *info;
+ int index;
+
+ /* This is legal */
+ if (!ptr)
+ return;
+
+ if (!initialized) {
+ wrtwarning("free(): malloc() never got 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("free(): junk pointer (too low)\n");
+ return;
+ }
+
+ if (index > last_index) {
+ wrtwarning("free(): junk pointer (too high)\n");
+ return;
+ }
+
+ info = page_dir[index];
+
+ if (info < MALLOC_MAGIC)
+ free_pages(ptr,index,info);
+ else
+ free_bytes(ptr,index,info);
+ return;
+}
diff --git a/lib/libc/stdlib/memory.3 b/lib/libc/stdlib/memory.3
new file mode 100644
index 0000000..9bc600b
--- /dev/null
+++ b/lib/libc/stdlib/memory.3
@@ -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.
+.\"
+.\" @(#)memory.3 8.1 (Berkeley) 6/4/93
+.\"
+.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 calloc 3 ,
+.Xr free 3 ,
+.Xr malloc 3 ,
+.Xr realloc 3 ,
+.Xr alloca 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..a47e300
--- /dev/null
+++ b/lib/libc/stdlib/merge.c
@@ -0,0 +1,347 @@
+/*-
+ * 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);
+ }
+
+ /*
+ * 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 */
+LINEAR: 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;
+SLOWCASE: 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/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..4f449c7
--- /dev/null
+++ b/lib/libc/stdlib/qsort.3
@@ -0,0 +1,233 @@
+.\" 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
+.\"
+.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
+function succeeds 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..66c0224
--- /dev/null
+++ b/lib/libc/stdlib/qsort.c
@@ -0,0 +1,179 @@
+/*-
+ * 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[] =
+ "$Id$";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#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 = 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 = a + (n / 2) * es;
+ if (n > 7) {
+ pl = a;
+ pn = 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 = a + es;
+
+ pc = pd = 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 = 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 = 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..ce30378
--- /dev/null
+++ b/lib/libc/stdlib/radixsort.3
@@ -0,0 +1,160 @@
+.\" 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
+.\"
+.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 "u_char **base" "int nmemb" "u_char *table" "u_int endbyte"
+.Ft int
+.Fn sradixsort "u_char **base" "int nmemb" "u_char *table" "u_int 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 4.4BSD.
diff --git a/lib/libc/stdlib/radixsort.c b/lib/libc/stdlib/radixsort.c
new file mode 100644
index 0000000..af47fb0
--- /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.1 (Berkeley) 6/4/93";
+#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. */
+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. */
+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..f2e3742
--- /dev/null
+++ b/lib/libc/stdlib/rand.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
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt RAND 3
+.Os
+.Sh NAME
+.Nm rand ,
+.Nm srand
+.Nd bad random number generator
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft void
+.Fn srand "unsigned seed"
+.Ft int
+.Fn rand void
+.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 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 seed value is provided, the functions are automatically
+seeded with a value of 1.
+.Sh SEE ALSO
+.Xr random 3
+.Sh STANDARDS
+The
+.Fn rand
+and
+.Fn srand
+functions
+conform to
+.St -ansiC .
diff --git a/lib/libc/stdlib/rand.c b/lib/libc/stdlib/rand.c
new file mode 100644
index 0000000..12846c3
--- /dev/null
+++ b/lib/libc/stdlib/rand.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[] = "@(#)rand.c 8.1 (Berkeley) 6/14/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <stdlib.h>
+
+static u_long next = 1;
+
+int
+rand()
+{
+ return ((next = next * 1103515245 + 12345) % ((u_long)RAND_MAX + 1));
+}
+
+void
+srand(seed)
+u_int seed;
+{
+ next = seed;
+}
diff --git a/lib/libc/stdlib/random.3 b/lib/libc/stdlib/random.3
new file mode 100644
index 0000000..84680e2
--- /dev/null
+++ b/lib/libc/stdlib/random.3
@@ -0,0 +1,166 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt RANDOM 3
+.Os BSD 4.2
+.Sh NAME
+.Nm random ,
+.Nm srandom ,
+.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 seed"
+.Ft char *
+.Fn initstate "unsigned seed" "char *state" "int 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 Ns / Fn srandom
+have (almost) the same calling sequence and initialization properties as
+.Xr rand 3 Ns / Xr srand 3 .
+The difference is that
+.Xr rand
+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
+Unlike
+.Xr srand ,
+.Fn srandom
+does not return the old seed; the reason for this is that the amount of
+state information used is much more than a single word. (Two other
+routines are provided to deal with restarting/changing random
+number generators). Like
+.Xr rand 3 ,
+however,
+.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 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 AUTHOR
+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
+.Sh HISTORY
+These
+functions appeared in
+.Bx 4.2 .
+.Sh BUGS
+About 2/3 the speed of
+.Xr rand 3 .
diff --git a/lib/libc/stdlib/random.c b/lib/libc/stdlib/random.c
new file mode 100644
index 0000000..fa89f82
--- /dev/null
+++ b/lib/libc/stdlib/random.c
@@ -0,0 +1,363 @@
+/*
+ * 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[] = "@(#)random.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * 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.
+ */
+
+/*
+ * 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 int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
+static int 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,
+ 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,
+};
+
+/*
+ * 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 int rand_type = TYPE_3;
+static int rand_deg = DEG_3;
+static int rand_sep = SEP_3;
+static long *end_ptr = &randtbl[DEG_3 + 1];
+
+/*
+ * 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 int x;
+{
+ register int i, j;
+
+ if (rand_type == TYPE_0)
+ state[0] = x;
+ else {
+ j = 1;
+ state[0] = x;
+ for (i = 1; i < rand_deg; i++)
+ state[i] = 1103515245 * state[i - 1] + 12345;
+ fptr = &state[rand_sep];
+ rptr = &state[0];
+ for (i = 0; i < 10 * rand_deg; i++)
+ (void)random();
+ }
+}
+
+/*
+ * 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.
+ */
+char *
+initstate(seed, arg_state, n)
+ unsigned int seed; /* seed for R.N.G. */
+ char *arg_state; /* pointer to state array */
+ int n; /* # bytes of state info */
+{
+ register char *ostate = (char *)(&state[-1]);
+
+ 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 (%d 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 *)arg_state)[1]); /* first location */
+ end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
+ srandom(seed);
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = 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.
+ */
+char *
+setstate(arg_state)
+ char *arg_state;
+{
+ register long *new_state = (long *)arg_state;
+ register int type = new_state[0] % MAX_TYPES;
+ register int 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 = &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()
+{
+ long i;
+
+ if (rand_type == TYPE_0)
+ i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
+ else {
+ *fptr += *rptr;
+ i = (*fptr >> 1) & 0x7fffffff; /* chucking least random bit */
+ if (++fptr >= end_ptr) {
+ fptr = state;
+ ++rptr;
+ } else if (++rptr >= end_ptr)
+ rptr = state;
+ }
+ return(i);
+}
diff --git a/lib/libc/stdlib/realpath.3 b/lib/libc/stdlib/realpath.3
new file mode 100644
index 0000000..83f4a43
--- /dev/null
+++ b/lib/libc/stdlib/realpath.3
@@ -0,0 +1,125 @@
+.\" 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
+.\"
+.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..28380d7
--- /dev/null
+++ b/lib/libc/stdlib/realpath.c
@@ -0,0 +1,158 @@
+/*
+ * 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];
+
+ /* 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)) {
+ n = readlink(p, resolved, MAXPATHLEN);
+ 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..4a28f25
--- /dev/null
+++ b/lib/libc/stdlib/setenv.c
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+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 **)realloc((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..9349d0a
--- /dev/null
+++ b/lib/libc/stdlib/strhash.c
@@ -0,0 +1,432 @@
+#ifndef lint
+static char *rcsid = "$Header: /home/ncvs/src/lib/libc/stdlib/strhash.c,v 1.4 1995/05/30 05:41:55 rgrimes Exp $";
+#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 1.4 1995/05/30 05:41:55 rgrimes
+ * Remove trailing whitespace.
+ *
+ * Revision 1.3 1995/03/28 08:41:02 jkh
+ * Fix a missing _hash() to prevent namespace pollution with the db/hash routines.
+ * Grrr. If the dbhash routines weren't grossly overengineered I wouldn't
+ * even need to do this! :-(
+ *
+ * Also now export the hash_stats routine. Manpage coming RSN - I promise.
+ *
+ * Revision 1.2 1995/03/26 19:32:24 ache
+ * Hash 8bit chars without sign extension
+ *
+ * Revision 1.1 1995/03/26 10:21:55 jkh
+ * Add the strhash family of routines. They provide a number of features
+ * that the db/hash functions don't, and they're much simpler to use for
+ * low-overhead string hashing.
+ *
+ * Revision 1.1 1995/02/25 02:16:34 jkh
+ * Second version of this - now support the essentials of a basic
+ * attributed file system for storing menu information and command
+ * templates. This is not finished yet, but it does compile so I can
+ * commit it to the tree now and continue working on it.
+ *
+ * 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 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..e1d4c39
--- /dev/null
+++ b/lib/libc/stdlib/strtod.3
@@ -0,0 +1,132 @@
+.\" 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
+.\"
+.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 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..0ccd6fd
--- /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..4ebf069
--- /dev/null
+++ b/lib/libc/stdlib/strtol.3
@@ -0,0 +1,168 @@
+.\" 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
+.\"
+.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 "char *nptr" "char **endptr" "int base"
+
+.Fd #include <sys/types.h>
+.Fd #include <stdlib.h>
+.Fd #include <limits.h>
+.Ft quad_t
+.Fn strtoq "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..3e6ec70
--- /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..a5720df
--- /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;
+ 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..a5720df
--- /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;
+ 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..5d6b050
--- /dev/null
+++ b/lib/libc/stdlib/strtoul.3
@@ -0,0 +1,163 @@
+.\" 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
+.\"
+.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..0bf6b82
--- /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..16dda0b
--- /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..16dda0b
--- /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..d89c79e
--- /dev/null
+++ b/lib/libc/stdlib/system.3
@@ -0,0 +1,93 @@
+.\" 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
+.\"
+.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, or \-1 if the
+.Xr wait 3
+for the shell failed.
+A return value of 127 means the execution of the shell
+failed.
+.Sh SEE ALSO
+.Xr sh 1 ,
+.Xr execve 2 ,
+.Xr wait 2 ,
+.Xr popen 3
+.Sh STANDARDS
+The
+.Fn system
+function
+conforms to
+.St -ansiC .
diff --git a/lib/libc/stdlib/system.c b/lib/libc/stdlib/system.c
new file mode 100644
index 0000000..c438f17
--- /dev/null
+++ b/lib/libc/stdlib/system.c
@@ -0,0 +1,76 @@
+/*
+ * 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>
+
+system(command)
+ const char *command;
+{
+ union wait pstat;
+ pid_t pid;
+ int omask;
+ sig_t intsave, quitsave;
+
+ if (!command) /* just checking... */
+ return(1);
+
+ omask = sigblock(sigmask(SIGCHLD));
+ switch(pid = vfork()) {
+ case -1: /* error */
+ (void)sigsetmask(omask);
+ pstat.w_status = 0;
+ pstat.w_retcode = 127;
+ return(pstat.w_status);
+ case 0: /* child */
+ (void)sigsetmask(omask);
+ execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL);
+ _exit(127);
+ }
+ intsave = signal(SIGINT, SIG_IGN);
+ quitsave = signal(SIGQUIT, SIG_IGN);
+ pid = waitpid(pid, (int *)&pstat, 0);
+ (void)sigsetmask(omask);
+ (void)signal(SIGINT, intsave);
+ (void)signal(SIGQUIT, quitsave);
+ return(pid == -1 ? -1 : pstat.w_status);
+}
diff --git a/lib/libc/stdtime/Makefile.inc b/lib/libc/stdtime/Makefile.inc
new file mode 100644
index 0000000..f72048b
--- /dev/null
+++ b/lib/libc/stdtime/Makefile.inc
@@ -0,0 +1,10 @@
+# $Id: Makefile.inc,v 1.1 1994/09/13 03:50:55 wollman Exp $
+
+.PATH: ${.CURDIR}/stdtime
+
+SRCS+= asctime.c localtime.c strftime.c difftime.c
+MAN5+= stdtime/tzfile.5
+MAN3+= stdtime/ctime.3 stdtime/strftime.3 stdtime/time2posix.3
+
+MLINKS+=ctime.3 asctime.3 ctime.3 difftime.3 ctime.3 gmtime.3 \
+ ctime.3 localtime.3 ctime.3 mktime.3
diff --git a/lib/libc/stdtime/asctime.c b/lib/libc/stdtime/asctime.c
new file mode 100644
index 0000000..6087702
--- /dev/null
+++ b/lib/libc/stdtime/asctime.c
@@ -0,0 +1,56 @@
+#ifndef lint
+#ifndef NOID
+static char elsieid[] = "@(#)asctime.c 7.5";
+#endif /* !defined NOID */
+#endif /* !defined lint */
+
+/*LINTLIBRARY*/
+
+#include "private.h"
+#include "tzfile.h"
+
+/*
+** A la X3J11, with core dump avoidance.
+*/
+
+char *
+asctime(timeptr)
+register const struct tm * timeptr;
+{
+ 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).
+ */
+ static char result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) +
+ 3 + 2 + 1 + 1];
+ 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..ff6a8ef
--- /dev/null
+++ b/lib/libc/stdtime/ctime.3
@@ -0,0 +1,258 @@
+.\" 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.
+.\"
+.\" @(#)ctime.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt CTIME 3
+.Os BSD 4.3
+.Sh NAME
+.Nm asctime ,
+.Nm ctime ,
+.Nm difftime ,
+.Nm gmtime ,
+.Nm localtime ,
+.Nm mktime
+.Nd transform binary date and time value to
+.Tn ASCII
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.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"
+.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
+environmental variable (see
+.Xr tzset 3 ) .
+The function
+.Fn localtime
+uses
+.Xr tzset
+to initialize time conversion information if
+.Xr tzset
+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
+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
+The function
+.Fn mktime
+converts the broken-down time, expressed as local 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 .
+.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.)
+.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 HISTORY
+This manual page is derived from
+the time package contributed to Berkeley by
+Arthur Olsen and which appeared in
+.Bx 4.3 .
+.Sh BUGS
+Except for
+.Fn difftime
+and
+.Fn mktime ,
+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
+.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.
+.Pp
+Avoid using out-of-range values with
+.Fn mktime
+when setting up lunch with promptness sticklers in Riyadh.
diff --git a/lib/libc/stdtime/difftime.c b/lib/libc/stdtime/difftime.c
new file mode 100644
index 0000000..68f9d7e
--- /dev/null
+++ b/lib/libc/stdtime/difftime.c
@@ -0,0 +1,74 @@
+#ifndef lint
+#ifndef NOID
+static char elsieid[] = "@(#)difftime.c 7.4";
+#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 = 1;
+ while ((hibit <<= 1) > 0)
+ continue;
+ /*
+ ** 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;
+ ** many 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.
+ */
+ 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..d6337ff
--- /dev/null
+++ b/lib/libc/stdtime/localtime.c
@@ -0,0 +1,1612 @@
+#ifndef lint
+#ifndef NOID
+static char elsieid[] = "@(#)localtime.c 7.44";
+#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 "private.h"
+#include "tzfile.h"
+#include "fcntl.h"
+
+/*
+** 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;
+
+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;
+
+ if (name == NULL && (name = TZDEFAULT) == NULL)
+ return -1;
+ {
+ register int doaccess;
+ /*
+ ** Section 4.9.1 of the C standard says that
+ ** "FILENAME_MAX expands to an integral constant expression
+ ** that is the sie 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) + 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;
+ }
+ {
+ 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_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' && !isdigit(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 || !isdigit(*strp))
+ return NULL;
+ num = 0;
+ while ((c = *strp) != '\0' && isdigit(c)) {
+ num = num * 10 + (c - '0');
+ if (num > max)
+ return NULL; /* illegal value */
+ ++strp;
+ }
+ 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;
+
+ if (*strp == '-') {
+ neg = 1;
+ ++strp;
+ } else if (isdigit(*strp) || *strp++ == '+')
+ neg = 0;
+ else return NULL; /* illegal offset */
+ 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 (isdigit(*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;
+ } 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 */
+void
+tzsetwall P((void))
+{
+ 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();
+}
+
+void
+tzset P((void))
+{
+ 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();
+}
+
+/*
+** 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(timep)
+const time_t * const timep;
+{
+ tzset();
+ localsub(timep, 0L, &tm);
+ return &tm;
+}
+
+/*
+** 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;
+{
+ 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);
+ }
+ 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;
+{
+ 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);
+ tmp->tm_sec = (int) (rem % SECSPERMIN);
+ if (hit)
+ /*
+ ** A positive leap second requires a special
+ ** representation. This uses "... ??:59:60" et seq.
+ */
+ tmp->tm_sec += hit;
+ tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
+ if (tmp->tm_wday < 0)
+ tmp->tm_wday += DAYSPERWEEK;
+ y = EPOCH_YEAR;
+ if (days >= 0)
+ for ( ; ; ) {
+ yleap = isleap(y);
+ if (days < (long) year_lengths[yleap])
+ break;
+ ++y;
+ days = days - (long) year_lengths[yleap];
+ }
+ else do {
+ --y;
+ yleap = isleap(y);
+ days = days + (long) year_lengths[yleap];
+ } while (days < 0);
+ 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));
+}
+
+/*
+** 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. (mtxinu!kridle now).
+** 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;
+ yourtm.tm_mday += year_lengths[isleap(yourtm.tm_year)];
+ }
+ while (yourtm.tm_mday > DAYSPERLYEAR) {
+ yourtm.tm_mday -= year_lengths[isleap(yourtm.tm_year)];
+ 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;
+ }
+ /*
+ ** Calculate the number of magnitude bits in a time_t
+ ** (this works regardless of whether time_t is
+ ** signed or unsigned, though lint complains if unsigned).
+ */
+ for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
+ continue;
+ /*
+ ** If time_t is signed, then 0 is the median value,
+ ** if time_t is unsigned, then 1 << bits is median.
+ */
+ t = (t < 0) ? 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;
+ 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 = 0; i < sp->typecnt; ++i) {
+ if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
+ continue;
+ for (j = 0; j < sp->typecnt; ++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 = 0; samei < sp->typecnt; ++samei) {
+ if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
+ continue;
+ for (otheri = 0; otheri < sp->typecnt; ++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;
+{
+ tzset();
+ return time1(tmp, localsub, 0L);
+}
+
+#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..3ed6e0b
--- /dev/null
+++ b/lib/libc/stdtime/private.h
@@ -0,0 +1,200 @@
+#ifndef PRIVATE_H
+
+#define PRIVATE_H
+
+/* 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 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.33";*/
+#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_SETTIMEOFDAY
+#define HAVE_SETTIMEOFDAY 3
+#endif /* !defined HAVE_SETTIMEOFDAY */
+
+#ifndef HAVE_UNISTD_H
+#define HAVE_UNISTD_H 1
+#endif /* !defined HAVE_UNISTD_H */
+
+/*
+** Nested includes
+*/
+
+#include "sys/types.h" /* for time_t */
+#include "stdio.h"
+#include "ctype.h"
+#include "errno.h"
+#include "string.h"
+#include "limits.h" /* for CHAR_BIT */
+#include "time.h"
+#include "stdlib.h"
+
+#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) */
+
+/*
+** Workarounds for compilers/systems.
+*/
+
+/*
+** SunOS 4.1.1 cc lacks const.
+*/
+
+#ifndef const
+#ifndef __STDC__
+#define const
+#endif /* !defined __STDC__ */
+#endif /* !defined const */
+
+/*
+** SunOS 4.1.1 cc lacks prototypes.
+*/
+
+#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 EXIT_SUCCESS.
+*/
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#endif /* !defined EXIT_SUCCESS */
+
+/*
+** SunOS 4.1.1 headers lack EXIT_FAILURE.
+*/
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif /* !defined EXIT_FAILURE */
+
+/*
+** 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 */
+
+/*
+** SunOS 4.1.1 libraries lack remove.
+*/
+
+#ifndef remove
+extern int unlink P((const char * filename));
+#define remove unlink
+#endif /* !defined remove */
+
+/*
+** Finally, some convenience items.
+*/
+
+#ifndef TRUE
+#define TRUE 1
+#endif /* !defined TRUE */
+
+#ifndef FALSE
+#define FALSE 0
+#endif /* !defined FALSE */
+
+#ifndef INT_STRLEN_MAXIMUM
+/*
+** 302 / 1000 is log10(2.0) rounded up.
+** Subtract one for the sign bit;
+** add one for integer division truncation;
+** add one more for a minus sign.
+*/
+#define INT_STRLEN_MAXIMUM(type) \
+ ((sizeof(type) * CHAR_BIT - 1) * 302 / 1000 + 2)
+#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 */
+
+/*
+** 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..b0647b3
--- /dev/null
+++ b/lib/libc/stdtime/strftime.3
@@ -0,0 +1,214 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt STRFTIME 3
+.Os
+.Sh NAME
+.Nm strftime
+.Nd format date and time
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <time.h>
+.Fd #include <string.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
+null character, is not more than
+.Fa maxsize ,
+.Fn strftime
+returns the number of characters in the array, not counting the
+terminating null.
+Otherwise, zero is returned.
+.Pp
+Each conversion specification is replaced by the characters as
+follows which are then copied into the buffer.
+.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*
+POSIX locale extensions.
+The sequences
+%Ec %EC %Ex %Ey %EY
+%Od %Oe %OH %OI %Om %OM
+%OS %Ou %OU %OV %Ow %OW %Oy
+are supposed to provide alternate
+representations.
+.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 \&%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 (the first
+Monday as the first day of week 1) as a
+decimal number (01-53).
+.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 with produced by
+.Xr date 1 ) .
+.It Cm %%
+is replaced by
+.Ql % .
+.El
+.Sh SEE ALSO
+.Xr date 1 ,
+.Xr ctime 3 ,
+.Xr printf 1 ,
+.Xr printf 3
+.Sh STANDARDS
+The
+.Fn strftime
+function
+conforms to
+.St -ansiC .
+The
+.Ql %s
+conversion specification is an extension.
+.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..0ad723e
--- /dev/null
+++ b/lib/libc/stdtime/strftime.c
@@ -0,0 +1,576 @@
+/*
+ * 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[] =
+ "$Id: strftime.c,v 1.5 1995/08/07 23:35:41 ache Exp $";
+#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 <locale.h>
+#include <rune.h> /* for _PATH_LOCALE */
+#include <sys/stat.h>
+
+#define LOCALE_HOME _PATH_LOCALE
+
+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;
+};
+
+static struct lc_time_T localebuf;
+static struct lc_time_T * _loc P((void));
+static int using_locale;
+
+#define Locale (using_locale ? &localebuf : &C_time_locale)
+
+static 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 %b %e %X %Y",
+
+ /* am */
+ "AM",
+
+ /* pm */
+ "PM",
+
+ /* date_fmt */
+ "%a %b %e %X %Z %Y"
+};
+
+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 *));
+static char * _secs P((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;
+{
+ for ( ; *format; ++format) {
+ if (*format == '%') {
+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) ?
+ "?" : 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':
+ case 'O':
+ /*
+ ** POSIX locale extensions, a la
+ ** Arnold Robbins' strftime version 3.0.
+ ** The sequences
+ ** %Ec %EC %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)
+ */
+ goto label;
+ case 'e':
+ pt = _conv(t->tm_mday, "%2d", 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':
+ pt = _secs(t, 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':
+ /*
+ ** 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). The method for
+ ** determining the week number is as specified
+ ** by ISO 8601 (to wit: if the week containing
+ ** January 1 has four or more days in the new
+ ** year, then it is week 1, otherwise it is
+ ** week 53 of the previous year and the next
+ ** week is week 1)."
+ ** (ado, 5/24/93)
+ */
+ /*
+ ** XXX--If January 1 falls on a Friday,
+ ** January 1-3 are part of week 53 of the
+ ** previous year. By analogy, if January
+ ** 1 falls on a Thursday, are December 29-31
+ ** of the PREVIOUS year part of week 1???
+ ** (ado 5/24/93)
+ */
+ /*
+ ** You are understood not to expect this.
+ */
+ {
+ int i;
+
+ i = (t->tm_yday + 10 - (t->tm_wday ?
+ (t->tm_wday - 1) : 6)) / 7;
+ if (i == 0) {
+ /*
+ ** What day of the week does
+ ** January 1 fall on?
+ */
+ i = t->tm_wday -
+ (t->tm_yday - 1);
+ /*
+ ** Fri Jan 1: 53
+ ** Sun Jan 1: 52
+ ** Sat Jan 1: 53 if previous
+ ** year a leap
+ ** year, else 52
+ */
+ if (i == TM_FRIDAY)
+ i = 53;
+ else if (i == TM_SUNDAY)
+ i = 52;
+ else i = isleap(t->tm_year +
+ TM_YEAR_BASE) ?
+ 53 : 52;
+#ifdef XPG4_1994_04_09
+ /*
+ ** As of 4/9/94, though,
+ ** XPG4 calls for 53
+ ** unconditionally.
+ */
+ i = 53;
+#endif /* defined XPG4_1994_04_09 */
+ }
+ pt = _conv(i, "%02d", 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 *
+_secs(t, pt, ptlim)
+ const struct tm *t;
+ char *pt;
+ const char *ptlim;
+{
+ char buf[INT_STRLEN_MAXIMUM(int) + 1];
+ register time_t s;
+ struct tm tmp;
+
+ /* Make a copy, mktime(3) modifies the tm struct. */
+ tmp = *t;
+ s = mktime(&tmp);
+ (void) sprintf(buf, "%ld", s);
+ 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;
+}
+
+extern char *_PathLocale;
+
+int
+__time_load_locale(const char *name)
+{
+ static const char lc_time[] = "LC_TIME";
+ static char * locale_buf;
+ static char locale_buf_C[] = "C";
+
+ int fd;
+ char * lbuf;
+ char * p;
+ const char ** ap;
+ const char * plim;
+ char filename[FILENAME_MAX];
+ struct stat st;
+ size_t namesize;
+ size_t bufsize;
+ int save_using_locale;
+
+ save_using_locale = using_locale;
+ using_locale = 0;
+
+ if (name == NULL)
+ goto no_locale;
+
+ if (!*name || !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) {
+ p = lbuf;
+ for (ap = (const char **) &localebuf;
+ ap < (const char **) (&localebuf + 1);
+ ++ap)
+ *ap = p += strlen(p) + 1;
+ using_locale = 1;
+ return 0;
+ }
+ /*
+ ** Slurp the locale file into the cache.
+ */
+ namesize = strlen(name) + 1;
+
+ snprintf(filename, sizeof filename,
+ "%s/%s/%s",
+ _PathLocale, name, 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) : realloc(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;
+ for (ap = (const char **) &localebuf;
+ ap < (const char **) (&localebuf + 1);
+ ++ap) {
+ if (p == plim)
+ goto reset_locale;
+ *ap = p;
+ while (*p != '\n')
+ ++p;
+ *p++ = '\0';
+ }
+ /*
+ ** Record the successful parse in the cache.
+ */
+ locale_buf = lbuf;
+
+ 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;
+ localebuf = C_time_locale;
+ save_using_locale = 0;
+bad_lbuf:
+ free(lbuf);
+bad_locale:
+ (void) close(fd);
+no_locale:
+ using_locale = save_using_locale;
+ return -1;
+}
diff --git a/lib/libc/stdtime/time2posix.3 b/lib/libc/stdtime/time2posix.3
new file mode 100644
index 0000000..846a52e
--- /dev/null
+++ b/lib/libc/stdtime/time2posix.3
@@ -0,0 +1,119 @@
+.TH TIME2POSIX 3
+.SH NAME
+time2posix, posix2time \- convert seconds since the Epoch
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <time.h>
+.PP
+.B time_t time2posix(t)
+.B time_t t
+.PP
+.B time_t posix2time(t)
+.B time_t t
+.PP
+.B cc ... -lz
+.fi
+.SH DESCRIPTION
+IEEE Standard 1003.1
+(POSIX)
+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
+.IR time(2) ,
+.IR localtime(3) ,
+.IR mktime(3) ,
+and
+.IR difftime(3) .
+However,
+POSIX 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
+.I time2posix
+and
+.I 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
+.I Time2posix
+is single-valued.
+That is,
+every local time_t
+corresponds to a single POSIX time_t.
+.I Posix2time
+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 a time
+T and it's conversion to,
+and back from,
+the POSIX representation over the leap second inserted at the end of June,
+1993.
+.nf
+.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
+.sp
+.ce
+ [Note: posix2time(B+1) => A+0 or A+1]
+.fi
+.PP
+If leap-second support is not enabled,
+local time_t's and
+POSIX time_t's are equivalent,
+and both
+.I time2posix
+and
+.I posix2time
+degenerate to the identity function.
+.SH SEE ALSO
+difftime(3),
+localtime(3),
+mktime(3),
+time(2)
+.\" @(#)time2posix.3 7.3
diff --git a/lib/libc/stdtime/tzfile.5 b/lib/libc/stdtime/tzfile.5
new file mode 100644
index 0000000..4bff7de
--- /dev/null
+++ b/lib/libc/stdtime/tzfile.5
@@ -0,0 +1,122 @@
+.Dd September 13, 1994
+.Dt TZFILE 5
+.Os FreeBSD 2.0
+.Sh NAME
+.Nm tzfile
+.Nd time zone information
+.Sh SYNOPSIS
+.Fd #include <tzfile.h>
+.Sh DESCRIPTION
+The time zone information files used by
+.Xr tzset 3
+begin with bytes reserved for future use,
+followed by four four-byte values of type
+.Fa long ,
+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 Li tzh_ttisstdcnt
+The number of standard/wall indicators stored in the file.
+.It Li tzh_leapcnt
+The number of leap seconds for which data is stored in the file.
+.It Li tzh_timecnt
+The number of ``transition times'' for which data is stored
+in the file.
+.It Li tzh_typecnt
+The number of ``local time types'' for which data is stored
+in the file (must not be zero).
+.It Li tzh_charcnt
+The number of characters of ``time zone abbreviation strings''
+stored in the file.
+.El
+.Pp
+The above header is followed by
+.Li 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 2 )
+at which the rules for computing local time change.
+Next come
+.Li 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
+.Li tt_gmtoff
+of type
+.Fa long ,
+in a standard byte order, followed by a one-byte value for
+.Li tt_isdst
+and a one-byte value for
+.Li tt_abbrind .
+In each structure,
+.Li tt_gmtoff
+gives the number of seconds to be added to GMT,
+.Li tt_isdst
+tells whether
+.Li tm_isdst
+should be set by
+.Xr localtime 3
+and
+.Li 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
+.Li 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 2 )
+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
+Finally there are
+.Li 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
+.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
diff --git a/lib/libc/stdtime/tzfile.h b/lib/libc/stdtime/tzfile.h
new file mode 100644
index 0000000..4ba0025
--- /dev/null
+++ b/lib/libc/stdtime/tzfile.h
@@ -0,0 +1,180 @@
+#ifndef TZFILE_H
+
+#define TZFILE_H
+
+/*
+** 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.6";*/
+#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. . .
+*/
+
+struct tzhead {
+ char tzh_reserved[20]; /* 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 GMT 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 GMT, 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..336476a
--- /dev/null
+++ b/lib/libc/string/Makefile.inc
@@ -0,0 +1,97 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
+
+.PATH: ${.CURDIR}/${MACHINE}/string ${.CURDIR}/string
+
+CFLAGS += -I${.CURDIR}/locale
+# machine-independent string sources
+SRCS+= memccpy.c strcasecmp.c strcoll.c strdup.c strerror.c \
+ strmode.c strtok.c strxfrm.c
+
+# machine-dependent string sources
+.include "${.CURDIR}/${MACHINE}/string/Makefile.inc"
+
+# If no machine specific bzero(3), build one out of memset(3).
+.if empty(SRCS:Mbzero.S)
+OBJS+= bzero.o
+bzero.o: memset.c
+ ${CC} -DBZERO ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -x -r ${.TARGET}
+ @mv a.out ${.TARGET}
+
+bzero.po: memset.c
+ ${CC} -DBZERO ${CFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
+ @${LD} -X -r ${.TARGET}
+ @mv a.out ${.TARGET}
+.endif
+
+# If no machine specific memmove(3), build one out of bcopy(3).
+.if empty(SRCS:Mmemmove.S)
+OBJS+= memmove.o
+memmove.o: bcopy.c
+ ${CC} -DMEMMOVE ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -x -r ${.TARGET}
+ @mv a.out ${.TARGET}
+
+memmove.po: bcopy.c
+ ${CC} -DMEMMOVE ${CFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
+ @${LD} -X -r ${.TARGET}
+ @mv a.out ${.TARGET}
+.endif
+
+# If no machine specific memcpy(3), build one out of bcopy(3).
+.if empty(SRCS:Mmemmove.S)
+OBJS+= memcpy.o
+memcpy.o: bcopy.c
+ ${CC} -DMEMCOPY ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -x -r ${.TARGET}
+ @mv a.out ${.TARGET}
+
+memcpy.po: bcopy.c
+ ${CC} -DMEMCOPY ${CFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
+ @${LD} -X -r ${.TARGET}
+ @mv a.out ${.TARGET}
+.endif
+
+# If no machine specific strchr(3), build one out of index(3).
+.if empty(SRCS:Mstrchr.S)
+OBJS+= strchr.o
+strchr.o: index.c
+ ${CC} -DSTRCHR ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -x -r ${.TARGET}
+ @mv a.out ${.TARGET}
+
+strchr.po: index.c
+ ${CC} -DSTRCHR ${CFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
+ @${LD} -X -r ${.TARGET}
+ @mv a.out ${.TARGET}
+.endif
+
+# If no machine specific strrchr(3), build one out of rindex(3).
+.if empty(SRCS:Mstrrchr.S)
+OBJS+= strrchr.o
+strrchr.o: rindex.c
+ ${CC} -DSTRRCHR ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -x -r ${.TARGET}
+ @mv a.out ${.TARGET}
+
+strrchr.po: rindex.c
+ ${CC} -DSTRRCHR ${CFLAGS} -c -p ${.ALLSRC} -o ${.TARGET}
+ @${LD} -X -r ${.TARGET}
+ @mv a.out ${.TARGET}
+.endif
+#
+MAN3+= string/bcmp.3 string/bcopy.3 string/bstring.3 string/bzero.3 \
+ string/ffs.3 string/index.3 string/memccpy.3 string/memchr.3 \
+ string/memcmp.3 string/memcpy.3 string/memmove.3 string/memset.3 \
+ string/rindex.3 string/strcasecmp.3 string/strcat.3 string/strchr.3 \
+ string/strcmp.3 string/strcoll.3 string/strcpy.3 string/strcspn.3 \
+ string/string.3 string/strlen.3 string/strmode.3 \
+ string/strdup.3 string/strerror.3 string/strpbrk.3 string/strrchr.3 \
+ string/strsep.3 string/strspn.3 string/strstr.3 string/strtok.3 \
+ string/strxfrm.3 string/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
diff --git a/lib/libc/string/bcmp.3 b/lib/libc/string/bcmp.3
new file mode 100644
index 0000000..5b02740
--- /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
+.\"
+.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 bcmp 3 ,
+.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..7f6a14c
--- /dev/null
+++ b/lib/libc/string/bcopy.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.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (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
+.\"
+.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..10d91a2
--- /dev/null
+++ b/lib/libc/string/bstring.3
@@ -0,0 +1,109 @@
+.\" 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
+.\"
+.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..46a20ab
--- /dev/null
+++ b/lib/libc/string/bzero.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.
+.\"
+.\" @(#)bzero.3 8.1 (Berkeley) 6/4/93
+.\"
+.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/ffs.3 b/lib/libc/string/ffs.3
new file mode 100644
index 0000000..451b7b9
--- /dev/null
+++ b/lib/libc/string/ffs.3
@@ -0,0 +1,61 @@
+.\" 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
+.\"
+.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..eb49c8f
--- /dev/null
+++ b/lib/libc/string/index.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.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (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
+.\"
+.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..28d6441
--- /dev/null
+++ b/lib/libc/string/memccpy.3
@@ -0,0 +1,72 @@
+.\" 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
+.\"
+.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 4.4BSD.
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..c94b086
--- /dev/null
+++ b/lib/libc/string/memchr.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 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
+.\"
+.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..a859529
--- /dev/null
+++ b/lib/libc/string/memcmp.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.
+.\"
+.\" @(#)memcmp.3 8.1 (Berkeley) 6/4/93
+.\"
+.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 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..61b6768
--- /dev/null
+++ b/lib/libc/string/memcpy.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.
+.\"
+.\" @(#)memcpy.3 8.1 (Berkeley) 6/4/93
+.\"
+.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/memmove.3 b/lib/libc/string/memmove.3
new file mode 100644
index 0000000..54c2b9b
--- /dev/null
+++ b/lib/libc/string/memmove.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
+.\" 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
+.\"
+.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/memset.3 b/lib/libc/string/memset.3
new file mode 100644
index 0000000..98e6d5f
--- /dev/null
+++ b/lib/libc/string/memset.3
@@ -0,0 +1,70 @@
+.\" 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
+.\"
+.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..99c72dc
--- /dev/null
+++ b/lib/libc/string/memset.c
@@ -0,0 +1,130 @@
+/*-
+ * 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;
+ register u_int c;
+ 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 = (int)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..78d3294
--- /dev/null
+++ b/lib/libc/string/rindex.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.
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (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
+.\"
+.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..f9d27ff
--- /dev/null
+++ b/lib/libc/string/strcasecmp.3
@@ -0,0 +1,86 @@
+.\" 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
+.\"
+.Dd June 9, 1993
+.Dt STRCASECMP 3
+.Os
+.Sh NAME
+.Nm strcasecmp
+.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 4.4BSD.
diff --git a/lib/libc/string/strcasecmp.c b/lib/libc/string/strcasecmp.c
new file mode 100644
index 0000000..f31c297
--- /dev/null
+++ b/lib/libc/string/strcasecmp.c
@@ -0,0 +1,115 @@
+/*
+ * 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>
+
+#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;
+
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison. The mappings are
+ * based upon ascii character sequences.
+ */
+static const u_char charmap[] = {
+ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+ '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+ '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+ '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+ '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+ '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+ '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+ '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+ '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+ '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
+ '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
+ '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
+ '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
+ '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+ '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+ '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+};
+
+int
+strcasecmp(s1, s2)
+ const char *s1, *s2;
+{
+ register const u_char *cm = charmap,
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ while (cm[*us1] == cm[*us2++])
+ if (*us1++ == '\0')
+ return (0);
+ return (cm[*us1] - cm[*--us2]);
+}
+
+int
+strncasecmp(s1, s2, n)
+ const char *s1, *s2;
+ register size_t n;
+{
+ if (n != 0) {
+ register const u_char *cm = charmap,
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ do {
+ if (cm[*us1] != cm[*us2++])
+ return (cm[*us1] - cm[*--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..6fe13aa
--- /dev/null
+++ b/lib/libc/string/strcat.3
@@ -0,0 +1,93 @@
+.\" 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
+.\"
+.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.
+.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
+.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..3436967
--- /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..d2676ba
--- /dev/null
+++ b/lib/libc/string/strchr.3
@@ -0,0 +1,87 @@
+.\" 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
+.\"
+.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 NULL
+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/strcmp.3 b/lib/libc/string/strcmp.3
new file mode 100644
index 0000000..49e5f14
--- /dev/null
+++ b/lib/libc/string/strcmp.3
@@ -0,0 +1,93 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt STRCMP 3
+.Os
+.Sh NAME
+.Nm strcmp
+.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 .
+.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 .
+.Pp
+The
+.Fn strncmp
+compares not more than
+.Fa len
+characters.
+.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..79cfaa8
--- /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 (*(unsigned char *)s1 - *(unsigned char *)--s2);
+}
diff --git a/lib/libc/string/strcoll.3 b/lib/libc/string/strcoll.3
new file mode 100644
index 0000000..180434f
--- /dev/null
+++ b/lib/libc/string/strcoll.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 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
+.\"
+.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, otherwith 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..915e649
--- /dev/null
+++ b/lib/libc/string/strcoll.c
@@ -0,0 +1,78 @@
+/*-
+ * 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.
+ *
+ * $Id: strcoll.c,v 1.3 1995/02/18 01:38:58 ache Exp $
+ */
+
+#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;
+ char *tt, *t, *tt2, *t2;
+
+ if (__collate_load_error)
+ return strcasecmp(s, s2);
+
+ len = len2 = 1;
+ ret = ret2 = 0;
+ tt = t = __collate_substitute(s);
+ tt2 = t2 = __collate_substitute(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..1e6f335
--- /dev/null
+++ b/lib/libc/string/strcpy.3
@@ -0,0 +1,121 @@
+.\" 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
+.\"
+.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
+.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..d1791dd
--- /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..89d20fd
--- /dev/null
+++ b/lib/libc/string/strcspn.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.
+.\"
+.\" @(#)strcspn.3 8.1 (Berkeley) 6/4/93
+.\"
+.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..2f1d5d2
--- /dev/null
+++ b/lib/libc/string/strdup.3
@@ -0,0 +1,63 @@
+.\" 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
+.\"
+.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 malloc 3
+.Xr free 3
+.Sh HISTORY
+The
+.Fn strdup
+function first appeared in 4.4BSD.
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..784c061
--- /dev/null
+++ b/lib/libc/string/strerror.3
@@ -0,0 +1,124 @@
+.\" 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
+.\"
+.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 char *sys_errlist[];
+.Vt extern 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 ,
+it is prepended to the message
+string and separated from it by
+a colon and space
+.Pq Ql \&:\ \& .
+If
+.Fa string
+is
+.Dv NULL ,
+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
+.Fa sys_errlist .
+The external value
+.Fa sys_nerr
+contains a count of the messages in
+.Fa 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 4.4BSD.
+.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.
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..c257d94
--- /dev/null
+++ b/lib/libc/string/string.3
@@ -0,0 +1,155 @@
+.\" 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
+.\"
+.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 index 3 ,
+.Xr strcat 3 ,
+.Xr strchr 3 ,
+.Xr strrchr 3 ,
+.Xr strcmp 3 ,
+.Xr strcasecmp 3 ,
+.Xr strcpy 3 ,
+.Xr strerror 3 ,
+.Xr strlen 3 ,
+.Xr strpbrk 3 ,
+.Xr strsep 3 ,
+.Xr strspn 3 ,
+.Xr strcspn 3 ,
+.Xr strstr 3 ,
+.Xr strtok 3 ,
+.Xr rindex 3
+.Xr bstring 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/strlen.3 b/lib/libc/string/strlen.3
new file mode 100644
index 0000000..04cb48e
--- /dev/null
+++ b/lib/libc/string/strlen.3
@@ -0,0 +1,70 @@
+.\" 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
+.\"
+.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..0cedd55
--- /dev/null
+++ b/lib/libc/string/strmode.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.
+.\"
+.\" @(#)strmode.3 8.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.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 NULL .
+.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 ?
+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 4.4BSD.
diff --git a/lib/libc/string/strmode.c b/lib/libc/string/strmode.c
new file mode 100644
index 0000000..651b263
--- /dev/null
+++ b/lib/libc/string/strmode.c
@@ -0,0 +1,147 @@
+/*-
+ * 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.1 (Berkeley) 6/4/93";
+#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
+ 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..805b5b0
--- /dev/null
+++ b/lib/libc/string/strncmp.c
@@ -0,0 +1,56 @@
+/*
+ * 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 (*(unsigned char *)s1 - *(unsigned char *)--s2);
+ 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..6b0edaf
--- /dev/null
+++ b/lib/libc/string/strpbrk.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.
+.\"
+.\" @(#)strpbrk.3 8.1 (Berkeley) 6/4/93
+.\"
+.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..dd551d4
--- /dev/null
+++ b/lib/libc/string/strrchr.3
@@ -0,0 +1,90 @@
+.\" 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
+.\"
+.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/strsep.3 b/lib/libc/string/strsep.3
new file mode 100644
index 0000000..938b657
--- /dev/null
+++ b/lib/libc/string/strsep.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.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (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
+.\"
+.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" "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')
+ ++ap;
+.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 4.4BSD.
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/strspn.3 b/lib/libc/string/strspn.3
new file mode 100644
index 0000000..04c4bdc
--- /dev/null
+++ b/lib/libc/string/strspn.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.
+.\"
+.\" @(#)strspn.3 8.1 (Berkeley) 6/4/93
+.\"
+.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 strcspn
+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..7d16b97
--- /dev/null
+++ b/lib/libc/string/strstr.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.
+.\"
+.\" @(#)strstr.3 8.1 (Berkeley) 6/4/93
+.\"
+.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..56db2b0
--- /dev/null
+++ b/lib/libc/string/strtok.3
@@ -0,0 +1,110 @@
+.\" 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.
+.\"
+.\" @(#)strtok.3 8.2 (Berkeley) 2/3/94
+.\"
+.Dd February 3, 1994
+.Dt STRTOK 3
+.Os BSD 3
+.Sh NAME
+.Nm strtok
+.Nd string tokens
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft char *
+.Fn strtok "char *str" "const char *sep"
+.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
+function
+returns 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 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
+There is no way to get tokens from multiple strings simultaneously.
+.Pp
+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 .
diff --git a/lib/libc/string/strtok.c b/lib/libc/string/strtok.c
new file mode 100644
index 0000000..9151cf2
--- /dev/null
+++ b/lib/libc/string/strtok.c
@@ -0,0 +1,90 @@
+/*
+ * 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[] = "@(#)strtok.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>
+#include <string.h>
+
+char *
+strtok(s, delim)
+ register char *s;
+ register const char *delim;
+{
+ register char *spanp;
+ register int c, sc;
+ char *tok;
+ static char *last;
+
+
+ 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
+ s[-1] = 0;
+ last = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
diff --git a/lib/libc/string/strxfrm.3 b/lib/libc/string/strxfrm.3
new file mode 100644
index 0000000..5602671
--- /dev/null
+++ b/lib/libc/string/strxfrm.3
@@ -0,0 +1,77 @@
+.\" 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
+.\"
+.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 transform null-terminating string pointed by
+.Fa src
+according to the current locale collation if any,
+then copied not more than
+.Fa n-1
+characters of the result string into
+.Fa dst ,
+ending it whith null character and return result length.
+Comparing two strings using
+.Fn strcmp
+after
+.Fn strxfrm
+is equal to comparing
+two original strings with
+.Fn strcoll .
+.Sh BUGS
+Sometimes biheviour of this function is unpredicatable.
+.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..eb02c13
--- /dev/null
+++ b/lib/libc/string/strxfrm.c
@@ -0,0 +1,92 @@
+/*-
+ * 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.
+ *
+ * $Id: strxfrm.c,v 1.3 1995/02/18 01:39:00 ache Exp $
+ */
+
+#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;
+ char *d = dest, *s, *ss;
+
+ if (len < 1)
+ return 0;
+
+ if (!*src) {
+ *d = '\0';
+ return 0;
+ }
+
+ if (__collate_load_error) {
+ size_t slen = strlen(src);
+
+ if (slen < len) {
+ strcpy(d, src);
+ return slen;
+ }
+ strncpy(d, src, len - 1);
+ d[len - 1] = '\0';
+ return len - 1;
+ }
+
+ ss = s = __collate_substitute(src);
+ prim = sec = 0;
+ while (*s && len > 1) {
+ while (*s && !prim) {
+ __collate_lookup(s, &l, &prim, &sec);
+ s += l;
+ }
+ if (prim) {
+ *d++ = (char)prim;
+ len--;
+ }
+ }
+#if 0
+ s = ss;
+ while (*s && len > 1) {
+ while (*s && !prim) {
+ lookup(s, &l, &prim, &sec);
+ s += l;
+ }
+ if (prim && sec) {
+ *d++ = (char)sec;
+ len--;
+ }
+ }
+#endif /* 0 */
+ *d = '\0';
+ free(ss);
+
+ return d - dest;
+}
diff --git a/lib/libc/string/swab.3 b/lib/libc/string/swab.3
new file mode 100644
index 0000000..70a9205
--- /dev/null
+++ b/lib/libc/string/swab.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.
+.\"
+.\" @(#)swab.3 8.1 (Berkeley) 6/4/93
+.\"
+.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..dc65844
--- /dev/null
+++ b/lib/libc/sys/Makefile.inc
@@ -0,0 +1,141 @@
+# @(#)Makefile.inc 8.1 (Berkeley) 6/17/93
+
+# sys sources
+.PATH: ${.CURDIR}/${MACHINE}/sys ${.CURDIR}/sys
+
+# modules with non-default implementations on at least one architecture:
+SRCS+= Ovfork.S brk.S cerror.S exect.S fork.S pipe.S ptrace.S reboot.S \
+ sbrk.S setlogin.S sigpending.S sigprocmask.S sigreturn.S \
+ sigsuspend.S syscall.S
+
+# glue to provide compatibility between GCC 1.X and 2.X
+SRCS+= ftruncate.c lseek.c mmap.c truncate.c
+
+# modules with default implementations on all architectures:
+ASM= accept.o access.o acct.o adjtime.o bind.o chdir.o chflags.o chmod.o \
+ chown.o chroot.o close.o connect.o dup.o dup2.o execve.o fchdir.o \
+ fchflags.o fchmod.o fchown.o fcntl.o flock.o fpathconf.o fstat.o \
+ fstatfs.o fsync.o getdirentries.o getdtablesize.o getegid.o \
+ geteuid.o getfh.o getfsstat.o getgid.o getgroups.o getitimer.o \
+ getpeername.o getpgrp.o getpid.o getppid.o getpriority.o \
+ getrlimit.o getrusage.o getsockname.o getsockopt.o gettimeofday.o \
+ getuid.o ioctl.o kill.o ktrace.o lfs_bmapv.o lfs_markv.o \
+ lfs_segclean.o lfs_segwait.o link.o listen.o lstat.o \
+ madvise.o mincore.o mkdir.o mkfifo.o mknod.o mlock.o mount.o \
+ mprotect.o msgsys.o msync.o munlock.o munmap.o nfssvc.o \
+ ntp_adjtime.o open.o pathconf.o profil.o quotactl.o read.o \
+ readlink.o readv.o recvfrom.o recvmsg.o rename.o revoke.o rmdir.o \
+ rtprio.o select.o semsys.o sendmsg.o sendto.o setegid.o seteuid.o setgid.o \
+ setgroups.o setitimer.o setpgid.o setpriority.o \
+ setregid.o setreuid.o setrlimit.o \
+ setsid.o setsockopt.o settimeofday.o setuid.o shmsys.o shutdown.o \
+ sigaction.o sigaltstack.o socket.o socketpair.o stat.o statfs.o \
+ swapon.o symlink.o sync.o sysarch.o umask.o unlink.o unmount.o \
+ utimes.o vadvise.o wait4.o write.o writev.o __syscall.o __sysctl.o
+
+PSEUDO= _exit.o _getlogin.o
+
+OBJS+= ${ASM} ${PSEUDO}
+
+${ASM}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h
+ @${ECHO} creating ${.PREFIX}.o
+ @printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' | \
+ ${CPP} ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -o ${.PREFIX}.o
+ @${LD} -x -r ${.PREFIX}.o
+ @mv a.out ${.PREFIX}.o
+
+PASM= ${ASM:.o=.po}
+${PASM}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h
+ @${ECHO} creating ${.PREFIX}.po
+ @printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' | \
+ ${CPP} -DPROF ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -o ${.PREFIX}.po
+ @${LD} -x -r ${.PREFIX}.po
+ @mv a.out ${.PREFIX}.po
+
+SASM= ${ASM:.o=.so}
+${SASM}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h
+ @${ECHO} creating ${.PREFIX}.so
+ @printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' | \
+ ${CPP} -DPIC ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -k -o ${.PREFIX}.so
+
+${PSEUDO}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h
+ @${ECHO} creating ${.PREFIX}.o
+ @printf '#include "SYS.h"\nPSEUDO(${.PREFIX},${.PREFIX:S/_//})\n' | \
+ ${CPP} ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -o ${.PREFIX}.o
+ @${LD} -x -r ${.PREFIX}.o
+ @mv a.out ${.PREFIX}.o
+
+PPSEUDO=${PSEUDO:.o=.po}
+${PPSEUDO}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h
+ @${ECHO} creating ${.PREFIX}.po
+ @printf '#include "SYS.h"\nPSEUDO(${.PREFIX},${.PREFIX:S/_//})\n' | \
+ ${CPP} -DPROF ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -o ${.PREFIX}.po
+ @${LD} -x -r ${.PREFIX}.po
+ @mv a.out ${.PREFIX}.po
+
+SPSEUDO=${PSEUDO:.o=.so}
+${SPSEUDO}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h
+ @${ECHO} creating ${.PREFIX}.so
+ @printf '#include "SYS.h"\nPSEUDO(${.PREFIX},${.PREFIX:S/_//})\n' | \
+ ${CPP} -DPIC ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -k -o ${.PREFIX}.so
+
+MAN2+= sys/accept.2 sys/access.2 sys/acct.2 sys/adjtime.2 sys/bind.2 \
+ sys/brk.2 sys/chdir.2 sys/chflags.2 sys/chmod.2 sys/chown.2 \
+ sys/chroot.2 sys/close.2 sys/connect.2 sys/dup.2 sys/execve.2 \
+ sys/_exit.2 sys/fcntl.2 sys/flock.2 sys/fork.2 sys/fsync.2 \
+ sys/getdirentries.2 sys/getdtablesize.2 sys/getfh.2 sys/getfsstat.2 \
+ sys/getgid.2 sys/getgroups.2 sys/getitimer.2 sys/getlogin.2 \
+ sys/getpeername.2 sys/getpgrp.2 sys/getpid.2 sys/getpriority.2 \
+ sys/getrlimit.2 sys/getrusage.2 sys/getsockname.2 sys/getsockopt.2 \
+ sys/gettimeofday.2 sys/getuid.2 sys/intro.2 sys/ioctl.2 sys/kill.2 \
+ sys/ktrace.2 sys/link.2 sys/listen.2 sys/lseek.2 sys/mkdir.2 \
+ sys/mkfifo.2 sys/mknod.2 sys/madvise.2 sys/mincore.2 sys/mlock.2 \
+ sys/mmap.2 sys/mount.2 sys/mprotect.2 sys/msync.2 sys/munmap.2 \
+ sys/nfssvc.2 sys/open.2 sys/pathconf.2 sys/pipe.2 sys/profil.2 \
+ sys/quotactl.2 sys/read.2 sys/readlink.2 sys/reboot.2 sys/recv.2 \
+ sys/rename.2 sys/revoke.2 sys/rmdir.2 sys/rtprio.2 sys/select.2 \
+ sys/semctl.2 sys/semget.2 sys/semop.2 \
+ sys/send.2 sys/setgroups.2 \
+ sys/setpgid.2 sys/setregid.2 sys/setreuid.2 \
+ sys/setsid.2 sys/setuid.2 sys/shmat.2 sys/shmctl.2 sys/shmget.2 \
+ sys/shutdown.2 \
+ sys/sigaction.2 sys/sigpending.2 sys/sigprocmask.2 sys/sigreturn.2 \
+ sys/sigaltstack.2 sys/sigstack.2 sys/sigsuspend.2 sys/socket.2 \
+ sys/socketpair.2 sys/stat.2 sys/statfs.2 sys/swapon.2 sys/symlink.2 \
+ sys/sync.2 sys/syscall.2 sys/truncate.2 sys/umask.2 sys/unlink.2 \
+ sys/utimes.2 sys/vfork.2 sys/wait.2 sys/write.2
+
+# missing: ptrace.2
+
+MLINKS+=brk.2 sbrk.2
+MLINKS+=dup.2 dup2.2
+MLINKS+=chdir.2 fchdir.2
+MLINKS+=chflags.2 fchflags.2
+MLINKS+=chmod.2 fchmod.2
+MLINKS+=chown.2 fchown.2
+MLINKS+=getgid.2 getegid.2
+MLINKS+=getitimer.2 setitimer.2
+MLINKS+=getlogin.2 setlogin.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 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+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2
+MLINKS+=write.2 writev.2
diff --git a/lib/libc/sys/_exit.2 b/lib/libc/sys/_exit.2
new file mode 100644
index 0000000..73e6062
--- /dev/null
+++ b/lib/libc/sys/_exit.2
@@ -0,0 +1,112 @@
+.\" 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
+.\"
+.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
+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 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 VALUE
+.Fn _exit
+can never return.
+.Sh SEE ALSO
+.Xr fork 2 ,
+.Xr sigvec 2 ,
+.Xr wait 2 ,
+.Xr exit 3
+.Sh STANDARDS
+The
+.Nm _exit
+function is defined by
+.St -p1003.1-88 .
diff --git a/lib/libc/sys/accept.2 b/lib/libc/sys/accept.2
new file mode 100644
index 0000000..d475e36
--- /dev/null
+++ b/lib/libc/sys/accept.2
@@ -0,0 +1,166 @@
+.\" 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
+.\"
+.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" "int *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 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 ENOTSOCK
+The descriptor references a file, not a socket.
+.It Bq Er EOPNOTSUPP
+The referenced socket is not of type
+.Dv SOCK_STREAM .
+.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 listen 2 ,
+.Xr select 2 ,
+.Xr socket 2
+.Sh HISTORY
+The
+.Nm
+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..0dc9d2e
--- /dev/null
+++ b/lib/libc/sys/access.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.
+.\"
+.\" @(#)access.2 8.2 (Berkeley) 4/1/94
+.\"
+.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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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
+.Fn Access
+conforms to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
+.Sh CAVEAT
+.Fn Access
+is a potential security hole and
+should never be used.
diff --git a/lib/libc/sys/acct.2 b/lib/libc/sys/acct.2
new file mode 100644
index 0000000..bcd45ca
--- /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
+.\"
+.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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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
+.Nm
+function call appeared in Version 7 AT&T UNIX.
diff --git a/lib/libc/sys/adjtime.2 b/lib/libc/sys/adjtime.2
new file mode 100644
index 0000000..84b9ad8
--- /dev/null
+++ b/lib/libc/sys/adjtime.2
@@ -0,0 +1,111 @@
+.\" 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
+.\"
+.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 "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
+.Nm
+function call appeared in
+.Bx 4.3 .
diff --git a/lib/libc/sys/bind.2 b/lib/libc/sys/bind.2
new file mode 100644
index 0000000..18512e2
--- /dev/null
+++ b/lib/libc/sys/bind.2
@@ -0,0 +1,126 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt BIND 2
+.Os BSD 4.2
+.Sh NAME
+.Nm bind
+.Nd bind a name to a socket
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Ft int
+.Fn bind "int s" "struct sockaddr *name" "int namelen"
+.Sh DESCRIPTION
+.Fn Bind
+assigns a name to an unnamed socket.
+When a socket is created
+with
+.Xr socket 2
+it exists in a name space (address family)
+but has no name assigned.
+.Fn Bind
+requests that
+.Fa name
+be assigned to the socket.
+.Sh NOTES
+Binding a name 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 name binding vary between communication domains.
+Consult the manual entries in section 4 for detailed information.
+.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 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 EINVAL
+The socket is already bound to an address.
+.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 name
+parameter is not in a valid part of the user
+address space.
+.El
+.Pp
+The following errors are specific to binding names 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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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 listen 2 ,
+.Xr socket 2 ,
+.Xr getsockname 2
+.Sh HISTORY
+The
+.Nm
+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..7580f38
--- /dev/null
+++ b/lib/libc/sys/brk.2
@@ -0,0 +1,146 @@
+.\" 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.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.Dt BRK 2
+.Os BSD 4
+.Sh NAME
+.Nm brk ,
+.Nm sbrk
+.Nd change data segment size
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Ft int
+.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 ,
+e.g.
+.Dq qetext + rlp\(->rlim_max.
+(see
+.Xr end 3
+for the definition of
+.Em etext ) .
+.Sh RETURN VALUES
+.Nm Brk
+returns 0 if successful;
+otherwise -1 with
+.Va errno
+set to indicate why the allocation failed.
+The
+.Nm sbrk
+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
+.Xr 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 malloc 3 ,
+.Xr end 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 .
+.Sh HISTORY
+A
+.Nm
+function call appeared in Version 7 AT&T UNIX.
diff --git a/lib/libc/sys/chdir.2 b/lib/libc/sys/chdir.2
new file mode 100644
index 0000000..0b06fa8
--- /dev/null
+++ b/lib/libc/sys/chdir.2
@@ -0,0 +1,129 @@
+.\" 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
+.\"
+.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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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
+.Fn Chdir
+is expected to conform to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
+.Sh HISTORY
+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..8481851
--- /dev/null
+++ b/lib/libc/sys/chflags.2
@@ -0,0 +1,154 @@
+.\" 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.1 (Berkeley) 6/9/93
+.\"
+.Dd June 9, 1993
+.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 ARCHIVED
+.\"File is archived.
+.It SF_IMMUTABLE
+The file may not be changed.
+.It SF_APPEND
+The file may only be appended to.
+.El
+.Pp
+The
+.Dq UF_IMMUTABLE
+and
+.Dq UF_APPEND
+flags may be set or unset by either the owner of a file or the super-user.
+.Pp
+The
+.Dq SF_IMMUTABLE
+and
+.Dq SF_APPEND
+flags may only be set or unset by the super-user.
+They 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 it:
+.Bl -tag -width Er
+.It Bq Er ENOTDIR
+A component of the path prefix is not a directory.
+.It Bq Er EINVAL
+The pathname contains a character with the high-order bit set.
+.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.
+.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.
+.El
+.Sh SEE ALSO
+.Xr chflags 1,
+.Xr init 8
+.Sh HISTORY
+The
+.Nm chflags
+and
+.Nm fchflags
+functions first appeared in 4.4BSD.
diff --git a/lib/libc/sys/chmod.2 b/lib/libc/sys/chmod.2
new file mode 100644
index 0000000..1075158
--- /dev/null
+++ b/lib/libc/sys/chmod.2
@@ -0,0 +1,182 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt CHMOD 2
+.Os BSD 4
+.Sh NAME
+.Nm chmod ,
+.Nm fchmod
+.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"
+.Sh DESCRIPTION
+The function
+.Fn chmod
+sets the file permission bits
+of the file
+specified by the pathname
+.Fa path
+to
+.Fa mode .
+.Fn Fchmod
+sets the permission bits of the specified
+file descriptor
+.Fa fd .
+.Fn Chmod
+verifies that the process owner (user) either owns
+the file specified by
+.Fa path
+(or
+.Fa fd ) ,
+or
+is the super-user.
+A mode is created from
+.Em or'd
+permission bit masks
+defined in
+.Aq Pa sys/stat.h :
+.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 /* save swapped text even after use */
+.Ed
+.Pp
+The
+.Dv ISVTX
+(the
+.Em sticky bit )
+indicates to the system which executable files are shareable (the
+default) and the system maintains the program text of the files
+in the swap area. The sticky bit may only be set by the super user
+on shareable executable files.
+.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
+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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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.
+.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 open 2 ,
+.Xr chown 2 ,
+.Xr stat 2 ,
+.Xr sticky 8
+.Sh STANDARDS
+.Fn Chmod
+is expected to conform to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
+.Sh HISTORY
+The
+.Fn fchmod
+function call
+appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/chown.2 b/lib/libc/sys/chown.2
new file mode 100644
index 0000000..11c3956
--- /dev/null
+++ b/lib/libc/sys/chown.2
@@ -0,0 +1,148 @@
+.\" 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
+.\"
+.Dd April 19, 1994
+.Dt CHOWN 2
+.Os BSD 4
+.Sh NAME
+.Nm chown ,
+.Nm fchown
+.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"
+.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.
+.Pp
+.Fn Fchown
+is particularly useful when used in conjunction
+with the file locking primitives (see
+.Xr flock 2 ) .
+.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
+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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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 chown 8 ,
+.Xr chgrp 1 ,
+.Xr chmod 2 ,
+.Xr flock 2
+.Sh STANDARDS
+.Fn Chown
+is expected to conform to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
+.Sh HISTORY
+The
+.Fn fchown
+function call
+appeared in
+.Bx 4.2 .
+.Pp
+The
+.Fn chown
+and
+.Fn fchown
+functions were changed to follow symbolic links in
+.Bx 4.4 .
diff --git a/lib/libc/sys/chroot.2 b/lib/libc/sys/chroot.2
new file mode 100644
index 0000000..d8763fe
--- /dev/null
+++ b/lib/libc/sys/chroot.2
@@ -0,0 +1,97 @@
+.\" 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
+.\"
+.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.
+.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 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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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
+.Nm
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/close.2 b/lib/libc/sys/close.2
new file mode 100644
index 0000000..885ac80
--- /dev/null
+++ b/lib/libc/sys/close.2
@@ -0,0 +1,120 @@
+.\" 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
+.\"
+.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 ) .
+.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
+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 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 flock 2 ,
+.Xr open 2 ,
+.Xr pipe 2 ,
+.Xr socket 2 ,
+.Xr socketpair 2 ,
+.Xr execve 2 ,
+.Xr fcntl 2
+.Sh STANDARDS
+.Fn Close
+conforms to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
diff --git a/lib/libc/sys/connect.2 b/lib/libc/sys/connect.2
new file mode 100644
index 0000000..eb38ab3
--- /dev/null
+++ b/lib/libc/sys/connect.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.
+.\"
+.\" @(#)connect.2 8.1 (Berkeley) 6/4/93
+.\"
+.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" "struct sockaddr *name" "int 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 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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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 select 2 ,
+.Xr socket 2 ,
+.Xr getsockname 2
+.Sh HISTORY
+The
+.Nm
+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..8989639
--- /dev/null
+++ b/lib/libc/sys/dup.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.
+.\"
+.\" @(#)dup.2 8.1 (Berkeley) 6/4/93
+.\"
+.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, the descriptor is first deallocated as if a
+.Xr close 2
+call had been done first.
+.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 open 2 ,
+.Xr close 2 ,
+.Xr fcntl 2 ,
+.Xr pipe 2 ,
+.Xr socket 2 ,
+.Xr socketpair 2 ,
+.Xr getdtablesize 2
+.Sh STANDARDS
+.Fn Dup
+and
+.Fn dup2
+are expected to conform
+to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
diff --git a/lib/libc/sys/execve.2 b/lib/libc/sys/execve.2
new file mode 100644
index 0000000..ba47e6d
--- /dev/null
+++ b/lib/libc/sys/execve.2
@@ -0,0 +1,261 @@
+.\" 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.3 (Berkeley) 1/24/94
+.\"
+.Dd January 24, 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
+.Fn execve Ap d ,
+the system
+.Fn execve Ap s
+runs 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
+.Fn execve Ap d
+file becomes the second argument;
+otherwise, the name of the originally
+.Fn 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
+.Fn 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 ) .
+.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 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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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.
+.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's argument list
+is larger than the system-imposed limit.
+The limit in the system as released is 20480 bytes
+.Pf ( Dv NCARGS
+in
+.Ao Pa sys/param.h Ac .
+.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 exit 2 ,
+.Xr fork 2 ,
+.Xr execl 3 ,
+.Xr environ 7
+.Sh HISTORY
+The
+.Nm
+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..f53c02f
--- /dev/null
+++ b/lib/libc/sys/fcntl.2
@@ -0,0 +1,481 @@
+.\" 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
+.\"
+.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" "int arg"
+.Sh DESCRIPTION
+.Fn Fcntl
+provides for control over descriptors.
+The argument
+.Fa fd
+is a descriptor to be operated on by
+.Fa cmd
+as follows:
+.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 execv 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
+call, or if a
+.Xr write
+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
+.Nm 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,
+.Nm fcntl
+returns immediately with
+.Er EACCES .
+.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
+.Nm fcntl
+is waiting for a region, the
+.Nm 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 \fIany\fP 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 getpwname 3
+to retrieve a record,
+the lock will be lost because
+.Xr getpwname 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 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 EACCES
+The argument
+.Fa arg
+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 EMFILE
+.Fa Cmd
+is
+.Dv F_DUPFD
+and the maximum allowed number of file descriptors are currently
+open.
+.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_DUPED
+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 ESRCH
+.Fa Cmd
+is
+.Dv F_SETOWN
+and
+the process ID given as argument is not in use.
+.El
+.Sh SEE ALSO
+.Xr close 2 ,
+.Xr execve 2 ,
+.Xr flock 2 ,
+.Xr getdtablesize 2 ,
+.Xr open 2 ,
+.Xr sigvec 2
+.Sh HISTORY
+The
+.Nm
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/flock.2 b/lib/libc/sys/flock.2
new file mode 100644
index 0000000..bb6abb7
--- /dev/null
+++ b/lib/libc/sys/flock.2
@@ -0,0 +1,145 @@
+.\" 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
+.\"
+.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 1 /* shared lock */
+.Fd #define LOCK_EX 2 /* exclusive lock */
+.Fd #define LOCK_NB 4 /* don't block when locking */
+.Fd #define LOCK_UN 8 /* unlock */
+.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 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.
+.El
+.Sh SEE ALSO
+.Xr open 2 ,
+.Xr close 2 ,
+.Xr dup 2 ,
+.Xr execve 2 ,
+.Xr fork 2
+.Sh HISTORY
+The
+.Nm
+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..0c290f6
--- /dev/null
+++ b/lib/libc/sys/fork.2
@@ -0,0 +1,108 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt FORK 2
+.Os BSD 4
+.Sh NAME
+.Nm fork
+.Nd create a new process
+.Sh SYNOPSIS
+.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
+or
+.Xr write
+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 processes 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.
+This limit is configuration-dependent.
+.It Bq Er EAGAIN
+The system-imposed limit
+.Dv MAXUPRC
+.Pq Aq Pa sys/param.h
+on the total number of
+processes under execution by a single user would be exceeded.
+.It Bq Er ENOMEM
+There is insufficient swap space for the new process.
+.El
+.Sh SEE ALSO
+.Xr execve 2 ,
+.Xr wait 2
+.Sh HISTORY
+A
+.Fn fork 2
+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..234ea6e
--- /dev/null
+++ b/lib/libc/sys/fsync.2
@@ -0,0 +1,81 @@
+.\" 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
+.\"
+.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 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 sync 8 ,
+.Xr update 8
+.Sh HISTORY
+The
+.Nm
+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..2f3ae6d
--- /dev/null
+++ b/lib/libc/sys/ftruncate.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[] = "@(#)ftruncate.c 8.1 (Berkeley) 6/17/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/syscall.h>
+
+/*
+ * 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;
+{
+
+ return(__syscall((quad_t)SYS_ftruncate, fd, 0, length));
+}
diff --git a/lib/libc/sys/getdirentries.2 b/lib/libc/sys/getdirentries.2
new file mode 100644
index 0000000..6df9444
--- /dev/null
+++ b/lib/libc/sys/getdirentries.2
@@ -0,0 +1,152 @@
+.\" 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.1 (Berkeley) 6/9/93
+.\"
+.Dd June 9, 1993
+.Dt GETDIRENTRIES 2
+.Os
+.Sh NAME
+.Nm getdirentries
+.Nd "get directory entries in a filesystem independent format"
+.Sh SYNOPSIS
+.Fd #include <sys/dirent.h>
+.Ft int
+.Fn getdirentries "int fd" "char *buf" "int nbytes" "long *basep"
+.Sh DESCRIPTION
+.Fn Getdirentries
+reads 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.
+.Fa Nbytes
+must be greater than or equal to the
+block size associated with the file,
+see
+.Xr stat 2 .
+Some filesystems may not support
+.Fn getdirentries
+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
+unsigned long d_fileno;
+unsigned short d_reclen;
+unsigned short 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_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 .
+A value of zero is returned when
+the end of the directory has been reached.
+.Pp
+.Fn Getdirentries
+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 ,
+or zero.
+.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 [EFAULT]
+.It EBADF
+.Fa fd
+is not a valid file descriptor open for reading.
+.It EFAULT
+Either
+.Fa buf
+or
+.Fa basep
+point outside the allocated address space.
+.It EIO
+An
+.Tn I/O
+error occurred while reading from or writing to the file system.
+.El
+.Sh SEE ALSO
+.Xr open 2 ,
+.Xr lseek 2
+.Sh HISTORY
+The
+.Nm getdirentries
+function first appeared in 4.4BSD.
diff --git a/lib/libc/sys/getdtablesize.2 b/lib/libc/sys/getdtablesize.2
new file mode 100644
index 0000000..8251fec
--- /dev/null
+++ b/lib/libc/sys/getdtablesize.2
@@ -0,0 +1,60 @@
+.\" 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
+.\"
+.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
+.Nm
+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..ab73d5a
--- /dev/null
+++ b/lib/libc/sys/getfh.2
@@ -0,0 +1,96 @@
+.\" 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
+.\"
+.Dd June 9, 1993
+.Dt GETFH 2
+.Os
+.Sh NAME
+.Nm getfh
+.Nd get file handle
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/mount.h>
+.Ft int
+.Fn getfh "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 EINVAL
+.Fa path
+contains a character with the high-order bit set.
+.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
+.Nm getfh
+function
+first appeared in 4.4BSD.
diff --git a/lib/libc/sys/getfsstat.2 b/lib/libc/sys/getfsstat.2
new file mode 100644
index 0000000..9d2a0d7
--- /dev/null
+++ b/lib/libc/sys/getfsstat.2
@@ -0,0 +1,135 @@
+.\" 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.1 (Berkeley) 6/9/93
+.\"
+.Dd June 9, 1993
+.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 quad fsid_t;
+
+#define MNAMELEN 32 /* length of buffer for returned name */
+
+struct statfs {
+ short f_type; /* type of filesystem (see below) */
+ short f_flags; /* copy of mount flags */
+ long f_bsize; /* fundamental filesystem block size */
+ long f_iosize; /* optimal transfer block size */
+ long f_blocks; /* total data blocks in filesystem */
+ long f_bfree; /* free blocks in fs */
+ long f_bavail; /* free blocks avail to non-superuser */
+ long f_files; /* total file nodes in filesystem */
+ long f_ffree; /* free file nodes in fs */
+ fsid_t f_fsid; /* filesystem id */
+ long f_spare[6]; /* spare for later */
+ char f_mntonname[MNAMELEN]; /* directory on which mounted */
+ char f_mntfromname[MNAMELEN]; /* mounted filesystem */
+};
+/*
+ * File system types.
+ */
+#define MOUNT_UFS 1
+#define MOUNT_NFS 2
+#define MOUNT_PC 3
+.Ed
+.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
+.Nm getfsstat
+function first appeared in 4.4BSD.
diff --git a/lib/libc/sys/getgid.2 b/lib/libc/sys/getgid.2
new file mode 100644
index 0000000..52519d7
--- /dev/null
+++ b/lib/libc/sys/getgid.2
@@ -0,0 +1,79 @@
+.\" 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
+.\"
+.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>
+.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 setregid 2 ,
+.Xr setgid 3
+.Sh STANDARDS
+.Fn Getgid
+and
+.Fn getegid
+conform to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
diff --git a/lib/libc/sys/getgroups.2 b/lib/libc/sys/getgroups.2
new file mode 100644
index 0000000..1428d83
--- /dev/null
+++ b/lib/libc/sys/getgroups.2
@@ -0,0 +1,90 @@
+.\" 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
+.\"
+.Dd April 16, 1994
+.Dt GETGROUPS 2
+.Os BSD 4.2
+.Sh NAME
+.Nm getgroups
+.Nd get group access list
+.Sh SYNOPSIS
+.Fd #include <sys/param.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 ,
+as defined in
+.Aq Pa sys/param.h ,
+will ever
+be returned.
+.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
+.Nm
+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..ac2e59a
--- /dev/null
+++ b/lib/libc/sys/getitimer.2
@@ -0,0 +1,166 @@
+.\" 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.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.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" "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. 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.
+.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 (beware that >= and <= do not
+work with this macro).
+.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 select 2 ,
+.Xr sigvec 2 ,
+.Xr gettimeofday 2
+.Sh HISTORY
+The
+.Nm
+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..5b351ca
--- /dev/null
+++ b/lib/libc/sys/getlogin.2
@@ -0,0 +1,126 @@
+.\" 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
+.\"
+.Dd June 9, 1993
+.Dt GETLOGIN 2
+.Os BSD 4.2
+.Sh NAME
+.Nm getlogin ,
+.Nm setlogin
+.Nd get/set login name
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Ft char *
+.Fn getlogin void
+.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 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).
+.Sh RETURN VALUES
+If a call to
+.Fn getlogin
+succeeds, it returns a pointer to a null-terminated string in a static buffer.
+If the name has not been set, it returns
+.Dv NULL .
+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 12.
+.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
+.Sh BUGS
+Login names are limited in length by
+.Fn setlogin .
+However, lower limits are placed on login names elsewhere in the system
+.Pf ( Dv UT_NAMESIZE
+in
+.Ao Pa utmp.h Ac ) .
+.Pp
+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 4.4BSD.
diff --git a/lib/libc/sys/getpeername.2 b/lib/libc/sys/getpeername.2
new file mode 100644
index 0000000..d89488c
--- /dev/null
+++ b/lib/libc/sys/getpeername.2
@@ -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.
+.\"
+.\" @(#)getpeername.2 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt GETPEERNAME 2
+.Os BSD 4.2
+.Sh NAME
+.Nm getpeername
+.Nd get name of connected peer
+.Sh SYNOPSIS
+.Ft int
+.Fn getpeername "int s" "struct sockaddr *name" "int *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 DIAGNOSTICS
+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 socket 2 ,
+.Xr getsockname 2
+.Sh HISTORY
+The
+.Nm
+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..88812b7
--- /dev/null
+++ b/lib/libc/sys/getpgrp.2
@@ -0,0 +1,101 @@
+.\" 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
+.\"
+.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"
+.Sh DESCRIPTION
+The process group of the current process is returned by
+.Fn getpgrp .
+.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 setpgid 2 ,
+.Xr termios 4
+.Sh HISTORY
+The
+.Nm
+function call appeared in
+.Bx 4.0 .
+.Sh STANDARDS
+The
+.Fn getpgrp
+function conforms to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
+.Sh COMPATABILITY
+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-88 .
+.Pp
+From the
+.St -p1003.1-88
+Rationale:
+.sp
+4.3BSD 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 System V
+.Fn getpgrp
+suffices, and the added complexity of the 4.3BSD
+.Fn getpgrp
+has been omitted from POSIX.1.
diff --git a/lib/libc/sys/getpid.2 b/lib/libc/sys/getpid.2
new file mode 100644
index 0000000..5f77706
--- /dev/null
+++ b/lib/libc/sys/getpid.2
@@ -0,0 +1,72 @@
+.\" 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
+.\"
+.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 <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 2
+.Sh STANDARDS
+.Fn Getpid
+and
+.Fn getppid
+conform to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
diff --git a/lib/libc/sys/getpriority.2 b/lib/libc/sys/getpriority.2
new file mode 100644
index 0000000..aa151a0
--- /dev/null
+++ b/lib/libc/sys/getpriority.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.
+.\"
+.\" @(#)getpriority.2 8.1 (Berkeley) 6/4/93
+.\"
+.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
+.Nm
+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..4ef3258
--- /dev/null
+++ b/lib/libc/sys/getrlimit.2
@@ -0,0 +1,182 @@
+.\" 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
+.\"
+.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" "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
+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.
+.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 {
+ quad_t rlim_cur; /* current (soft) limit */
+ quad_t rlim_max; /* hard limit */
+};
+.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 break
+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 2 ,
+.Xr sigaltstack 2 ,
+.Xr sigvec 2 ,
+.Xr sysctl 3
+.Sh HISTORY
+The
+.Nm
+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..b75bccc
--- /dev/null
+++ b/lib/libc/sys/getrusage.2
@@ -0,0 +1,165 @@
+.\" 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
+.\"
+.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; /* integral 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.
+.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 ERRORS
+.Fn Getrusage
+returns -1 on error.
+The possible errors are:
+.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
+.Sh BUGS
+There is no way to obtain information about a child process
+that has not yet terminated.
+.Sh HISTORY
+The
+.Nm
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/getsockname.2 b/lib/libc/sys/getsockname.2
new file mode 100644
index 0000000..d56e404
--- /dev/null
+++ b/lib/libc/sys/getsockname.2
@@ -0,0 +1,87 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt GETSOCKNAME 2
+.Os BSD 4.2
+.Sh NAME
+.Nm getsockname
+.Nd get socket name
+.Sh SYNOPSIS
+.Ft int
+.Fn getsockname "int s" "struct sockaddr *name" "int *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 DIAGNOSTICS
+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 socket 2
+.Sh BUGS
+Names bound to sockets in the UNIX domain are inaccessible;
+.Xr getsockname
+returns a zero length name.
+.Sh HISTORY
+The
+.Nm
+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..24ae2b8b
--- /dev/null
+++ b/lib/libc/sys/getsockopt.2
@@ -0,0 +1,354 @@
+.\" 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.3 (Berkeley) 4/19/94
+.\" $Id$
+.\"
+.Dd November 3, 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" "int *optlen"
+.Ft int
+.Fn setsockopt "int s" "int level" "int optname" "const void *optval" "int 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
+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 the
+.Fn setsockopt
+call when
+.Dv SO_LINGER
+is requested).
+If
+.Dv SO_LINGER
+is disabled and a
+.Xr close
+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
+or
+.Xr read
+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.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 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 sysctl 1 ,
+.Xr ioctl 2 ,
+.Xr socket 2 ,
+.Xr getprotoent 3 ,
+.Xr sysctl 3 ,
+.Xr protocols 5
+.Sh BUGS
+Several of the socket options should be handled at lower levels of the system.
+.Sh HISTORY
+The
+.Nm
+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..9426de6
--- /dev/null
+++ b/lib/libc/sys/gettimeofday.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.
+.\"
+.\" @(#)gettimeofday.2 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.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 "struct timeval *tp" "struct timezone *tzp"
+.Sh DESCRIPTION
+.Bf -symbolic
+Note: timezone is no longer used; this information is kept outside
+the kernel.
+.Ef
+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 ``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; /* of Greenwich */
+ int tz_dsttime; /* type of dst correction to apply */
+};
+.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.
+.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 timed 8
+.Sh HISTORY
+The
+.Nm
+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..23b1763
--- /dev/null
+++ b/lib/libc/sys/getuid.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.
+.\"
+.\" @(#)getuid.2 8.1 (Berkeley) 6/4/93
+.\"
+.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 setreuid 2
+.Sh STANDARDS
+.Fn Geteuid
+and
+.Fn getuid
+conform to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
diff --git a/lib/libc/sys/intro.2 b/lib/libc/sys/intro.2
new file mode 100644
index 0000000..bf43809
--- /dev/null
+++ b/lib/libc/sys/intro.2
@@ -0,0 +1,668 @@
+.\" Copyright (c) 1993, 1980198319861991
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (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.3 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.Dt INTRO 2
+.Os BSD 4
+.Sh NAME
+.Nm intro
+.Nd introduction to system calls and error numbers
+.Sh SYNOPSIS
+.Fd #include <sys/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 DIAGNOSTICS
+Nearly all of the system calls provide an error number in the external
+variable
+.Va errno ,
+which is defined as:
+.Pp
+.Dl extern int errno
+.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 20480 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).
+.It Er 10 ECHILD Em "\&No child processes" .
+A
+.Xr wait
+or
+.Xr waitpid
+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
+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
+or
+.Xr kill
+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
+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
+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
+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.
+.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
+request was made on an already connected socket; or,
+a
+.Xr sendto
+or
+.Xr sendmsg
+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
+or
+.Xr send
+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 8 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
+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.
+.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.
+.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 30000.
+.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 .
+.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.
+.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 ,
+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.
+.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 ,
+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). (The parity bit,
+bit 7, must be 0.)
+.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
+intro(3), perror(3)
diff --git a/lib/libc/sys/ioctl.2 b/lib/libc/sys/ioctl.2
new file mode 100644
index 0000000..36ce6ff
--- /dev/null
+++ b/lib/libc/sys/ioctl.2
@@ -0,0 +1,106 @@
+.\" 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
+.\"
+.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" "char *argp"
+.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
+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 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 tty 4 ,
+.Xr intro 4
+.Sh HISTORY
+An
+.Nm
+function call appeared in Version 7 AT&T UNIX.
diff --git a/lib/libc/sys/kill.2 b/lib/libc/sys/kill.2
new file mode 100644
index 0000000..a20afd3
--- /dev/null
+++ b/lib/libc/sys/kill.2
@@ -0,0 +1,131 @@
+.\" 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
+.\"
+.Dd April 19, 1994
+.Dt KILL 2
+.Os BSD 4
+.Sh NAME
+.Nm kill
+.Nd send signal to a process
+.Sh SYNOPSIS
+.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 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 getpid 2 ,
+.Xr getpgrp 2 ,
+.Xr killpg 2 ,
+.Xr sigaction 2
+.Sh STANDARDS
+The
+.Fn kill
+function is expected to
+conform to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
diff --git a/lib/libc/sys/ktrace.2 b/lib/libc/sys/ktrace.2
new file mode 100644
index 0000000..9fe61f8
--- /dev/null
+++ b/lib/libc/sys/ktrace.2
@@ -0,0 +1,162 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt KTRACE 2
+.Os BSD 4
+.Sh NAME
+.Nm ktrace
+.Nd process tracing
+.Sh SYNOPSIS
+.Fd #include <sys/types.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 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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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.
+.El
+.Sh SEE ALSO
+.Xr ktrace 1 ,
+.Xr kdump 1
+.Sh HISTORY
+A
+.Nm 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..d160786
--- /dev/null
+++ b/lib/libc/sys/link.2
@@ -0,0 +1,151 @@
+.\" 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
+.\"
+.Dd January 12, 1994
+.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.
+Unless the caller is the super-user,
+.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 EINVAL
+Either pathname contains a character with the high-order bit set.
+.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 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 and the effective
+user ID is not super-user.
+.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 symlink 2 ,
+.Xr unlink 2
+.Sh STANDARDS
+.Fn Link
+is expected to
+conform to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
diff --git a/lib/libc/sys/listen.2 b/lib/libc/sys/listen.2
new file mode 100644
index 0000000..eaa9522
--- /dev/null
+++ b/lib/libc/sys/listen.2
@@ -0,0 +1,120 @@
+.\" 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
+.\" $Id$
+.\"
+.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/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.somaxconn
+specifies a hard limit on
+.Fa backlog ;
+if a value greater than
+.Li kern.somaxconn
+or less than zero is specified,
+.Fa backlog
+is silently forced to
+.Li kern.somaxconn .
+.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 sysctl 1 ,
+.Xr accept 2 ,
+.Xr connect 2 ,
+.Xr socket 2 ,
+.Xr sysctl 3
+.Sh HISTORY
+The
+.Nm
+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
+.Tn FreeBSD
+2.2.
diff --git a/lib/libc/sys/lseek.2 b/lib/libc/sys/lseek.2
new file mode 100644
index 0000000..ef38451
--- /dev/null
+++ b/lib/libc/sys/lseek.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.
+.\"
+.\" @(#)lseek.2 8.3 (Berkeley) 4/19/94
+.\"
+.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 pointer
+.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 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
+conforms to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
diff --git a/lib/libc/sys/lseek.c b/lib/libc/sys/lseek.c
new file mode 100644
index 0000000..52208d1
--- /dev/null
+++ b/lib/libc/sys/lseek.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[] = "@(#)lseek.c 8.1 (Berkeley) 6/17/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/syscall.h>
+
+/*
+ * 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;
+{
+ extern off_t __syscall();
+
+ return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence));
+}
diff --git a/lib/libc/sys/madvise.2 b/lib/libc/sys/madvise.2
new file mode 100644
index 0000000..d0676ab
--- /dev/null
+++ b/lib/libc/sys/madvise.2
@@ -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.
+.\"
+.\" @(#)madvise.2 8.1 (Berkeley) 6/9/93
+.\"
+.Dd June 9, 1993
+.Dt MADVISE 2
+.Os
+.Sh NAME
+.Nm madvise
+.Nd give advise about use of memory
+.Sh SYNOPSIS
+.Fn madvise "caddr_t addr" "int 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
+.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_SPACEAVAIL 5 /* insure that resources are reserved */
+.Ed
+.Sh SEE ALSO
+.Xr msync 2 ,
+.Xr munmap 2 ,
+.Xr mprotect 2 ,
+.Xr mincore 2
+.Sh HISTORY
+The
+.Nm madvise
+function first appeared in 4.4BSD.
diff --git a/lib/libc/sys/mincore.2 b/lib/libc/sys/mincore.2
new file mode 100644
index 0000000..4e73c2a
--- /dev/null
+++ b/lib/libc/sys/mincore.2
@@ -0,0 +1,61 @@
+.\" 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
+.\"
+.Dd June 9, 1993
+.Dt MINCORE 2
+.Os
+.Sh NAME
+.Nm mincore
+.Nd get advise about use of memory
+.Sh SYNOPSIS
+.Fn mincore "caddr_t addr" "int 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 SEE ALSO
+.Xr msync 2 ,
+.Xr munmap 2 ,
+.Xr mprotect 2 ,
+.Xr madvise 2 ,
+.Sh HISTORY
+The
+.Fn mincore
+function first appeared in 4.4BSD.
diff --git a/lib/libc/sys/mkdir.2 b/lib/libc/sys/mkdir.2
new file mode 100644
index 0000000..4bf11be
--- /dev/null
+++ b/lib/libc/sys/mkdir.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.
+.\"
+.\" @(#)mkdir.2 8.2 (Berkeley) 12/11/93
+.\"
+.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/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 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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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
+.Fa path
+argument contains a byte with the high-order bit set.
+.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
+.Fn Mkdir
+conforms to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
diff --git a/lib/libc/sys/mkfifo.2 b/lib/libc/sys/mkfifo.2
new file mode 100644
index 0000000..6f7686e
--- /dev/null
+++ b/lib/libc/sys/mkfifo.2
@@ -0,0 +1,124 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt MKFIFO 2
+.Os
+.Sh NAME
+.Nm mkfifo
+.Nd make a fifo file
+.Sh SYNOPSIS
+.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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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
+.Fa path
+argument contains a byte with the high-order bit set.
+.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 stat 2 ,
+.Xr umask 2
+.Sh STANDARDS
+The
+.Nm mkfifo
+function call conforms to
+.St -p1003.1-88 .
diff --git a/lib/libc/sys/mknod.2 b/lib/libc/sys/mknod.2
new file mode 100644
index 0000000..d77ccbc
--- /dev/null
+++ b/lib/libc/sys/mknod.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.
+.\"
+.\" @(#)mknod.2 8.1 (Berkeley) 6/4/93
+.\"
+.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 device special file
+.Fa path
+is created with the major and minor
+device numbers extracted from
+.Fa mode.
+The access permissions of
+.Fa path
+are descendant from the
+.Xr umask 2
+of the parent process.
+.Pp
+If
+.Fa mode
+indicates a block or character special file,
+.Fa dev
+is a configuration dependent specification of a character or block
+I/O device and the superblock of the device. If
+.Fa mode
+does not indicate a block special or character special device,
+.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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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 EPERM
+The pathname contains a character with the high-order bit set.
+.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.
+.El
+.Sh SEE ALSO
+.Xr chmod 2 ,
+.Xr stat 2 ,
+.Xr umask 2
+.Sh HISTORY
+A
+.Nm
+function call appeared in Version 6 AT&T UNIX.
diff --git a/lib/libc/sys/mlock.2 b/lib/libc/sys/mlock.2
new file mode 100644
index 0000000..90bb7c7
--- /dev/null
+++ b/lib/libc/sys/mlock.2
@@ -0,0 +1,161 @@
+.\" 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
+.\"
+.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 "caddr_t addr" "size_t len"
+.Ft int
+.Fn munlock "caddr_t addr" "size_t len"
+.Sh DESCRIPTION
+The
+.Nm mlock
+system call
+locks into memory the physical pages associated with the virtual address
+range starting at
+.Fa addr
+for
+.Fa len
+bytes.
+The
+.Nm munlock
+call unlocks pages previously locked by one or more
+.Nm 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
+.Nm 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
+.Nm mlock
+calls on the same address range.
+Unlocking is performed explicitly by
+.Nm munlock
+or implicitly by a call to
+.Nm 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
+.Nm mlock
+the minimum of
+a system-wide ``wired pages'' limit and
+the per-process
+.Li RLIMIT_MEMLOCK
+resource limit.
+.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 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 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 mmap 2 ,
+.Xr munmap 2 ,
+.Xr setrlimit 2 ,
+.Xr getpagesize 3
+.Sh BUGS
+Unlike The Sun implementation, multiple
+.Nm mlock
+calls on the same address range require the corresponding number of
+.Nm munlock
+calls to actually unlock the pages, i.e.
+.Nm 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.
+.Sh HISTORY
+The
+.Fn mlock
+and
+.Fn munlock
+functions first appeared in 4.4BSD.
diff --git a/lib/libc/sys/mmap.2 b/lib/libc/sys/mmap.2
new file mode 100644
index 0000000..1c0d84a
--- /dev/null
+++ b/lib/libc/sys/mmap.2
@@ -0,0 +1,210 @@
+.\" 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.1 (Berkeley) 6/4/93
+.\"
+.Dd "June 4, 1993"
+.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 caddr_t
+.Fn mmap "caddr_t addr" "size_t len" "int prot" "int flags" "int fd" "off_t offset"
+.Sh DESCRIPTION
+The
+.Nm 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 offset
+or
+.Fa len
+is not a multiple of the pagesize, the mapped region may extend past the
+specified range.
+.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
+regions is used only for
+naming, and may be specified as \-1 if no name is associated with the
+region.
+.\".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,
+.Nm 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 exec 2
+system calls.
+.It Dv MAP_PRIVATE
+Modifications are private.
+.It Dv MAP_SHARED
+Modifications are shared.
+.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,
+.Nm mmap
+returns a pointer to the mapped region.
+Otherwise, a value of -1 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 PROT_WRITE ,
+.Dv MAP_SHARED
+and
+.Dv MAP_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
+.\"One of
+.\".Dv MAP_ANON
+.\"or
+.\".Dv MAP_FILE
+.\"was not specified as part of the
+.\".Fa flags
+.\"parameter.
+.Dv MAP_FIXED
+was specified and the
+.I addr
+parameter was not page aligned.
+.Fa Fd
+did not reference a regular or character special file.
+.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 getpagesize 2 ,
+.Xr msync 2 ,
+.Xr munmap 2 ,
+.Xr mprotect 2 ,
+.Xr madvise 2 ,
+.Xr mincore 2
diff --git a/lib/libc/sys/mmap.c b/lib/libc/sys/mmap.c
new file mode 100644
index 0000000..67da734
--- /dev/null
+++ b/lib/libc/sys/mmap.c
@@ -0,0 +1,58 @@
+/*
+ * 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>
+
+/*
+ * This function provides 64-bit offset padding that
+ * is not supplied by GCC 1.X but is supplied by GCC 2.X.
+ */
+caddr_t
+mmap(addr, len, prot, flags, fd, offset)
+ caddr_t addr;
+ size_t len;
+ int prot;
+ int flags;
+ int fd;
+ off_t offset;
+{
+
+ return((caddr_t)__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..6829a3e
--- /dev/null
+++ b/lib/libc/sys/mount.2
@@ -0,0 +1,314 @@
+.\" 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.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.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 "int type" "const char *dir" "int flags" "caddr_t 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.
+.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_NODEV
+Do not interpret special files on the filesystem.
+.It Dv MNT_SYNCHRONOUS
+All I/O to the filesystem should be done synchronously.
+.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,
+most filesystems will not allow a change from read-write to read-only.
+.Pp
+The
+.Fa type
+argument defines the type of the filesystem.
+The types of filesystems known to the system are defined in
+.Aq Pa sys/mount.h .
+.Fa Data
+is a pointer to a structure that contains the type
+specific arguments to mount.
+The currently supported types of filesystems and
+their type specific data are:
+.Pp
+.Dv MOUNT_UFS
+.Bd -literal -offset indent -compact
+struct ufs_args {
+ char *fspec; /* Block special file to mount */
+ int exflags; /* export related flags */
+ uid_t exroot; /* mapping for root uid */
+};
+.Ed
+.Pp
+.Dv MOUNT_NFS
+.Bd -literal -offset indent -compact
+struct nfs_args {
+ struct sockaddr_in *addr; /* file server address */
+ nfsv2fh_t *fh; /* File handle to be mounted */
+ int flags; /* flags */
+ int wsize; /* write size in bytes */
+ int rsize; /* read size in bytes */
+ int timeo; /* initial timeout 0.1 secs */
+ int retrans; /* times to retry send */
+ char *hostname; /* server's name */
+};
+.Ed
+.Pp
+.Dv MOUNT_MFS
+.Bd -literal -offset indent -compact
+struct mfs_args {
+ char *name; /* name of backing process */
+ caddr_t base; /* base address of the filesystem */
+ u_long size; /* size of the filesystem */
+};
+.Ed
+.Pp
+The
+.Fn umount
+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 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.
+.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
+.Nm Umount
+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
+.Fn Mount
+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 EINVAL
+A pathname contains a character with the high-order bit set.
+.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
+.Nm Umount
+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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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 mount 8 ,
+.Xr umount 8 ,
+.Xr mfs 8
+.Sh BUGS
+Some of the error codes need translation to more obvious messages.
+.Sh HISTORY
+.Fn Mount
+and
+.Fn umount
+function calls appeared in Version 6 AT&T UNIX.
diff --git a/lib/libc/sys/mprotect.2 b/lib/libc/sys/mprotect.2
new file mode 100644
index 0000000..bb2b9ad
--- /dev/null
+++ b/lib/libc/sys/mprotect.2
@@ -0,0 +1,58 @@
+.\" 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
+.\"
+.Dd June 9, 1993
+.Dt MPROTECT 2
+.Os
+.Sh NAME
+.Nm mprotect
+.Nd control the protection of pages
+.Sh SYNOPSIS
+.Fn mprotect "caddr_t addr" "int 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 SEE ALSO
+.Xr msync 2 ,
+.Xr munmap 2 ,
+.Xr madvise 2 ,
+.Xr mincore 2
+.Sh HISTORY
+The
+.Fn mprotect
+function first appeared in 4.4BSD.
diff --git a/lib/libc/sys/msync.2 b/lib/libc/sys/msync.2
new file mode 100644
index 0000000..d976e30
--- /dev/null
+++ b/lib/libc/sys/msync.2
@@ -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.
+.\"
+.\" @(#)msync.2 8.1 (Berkeley) 6/9/93
+.\"
+.Dd June 9, 1993
+.Dt MSYNC 2
+.Os
+.Sh NAME
+.Nm msync
+.Nd synchronize a mapped region
+.Sh SYNOPSIS
+.Fn msync "caddr_t addr" "int 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 the pages containing
+.Fa addr
+and
+.Fa len
+succeeding locations will be examined.
+The
+.Fa flags
+argument may be specified as follows:
+.Bd -literal
+MS_ASYNC Return immediately (not currently implemented)
+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.
+.Sh SEE ALSO
+.Xr madvise 2 ,
+.Xr munmap 2 ,
+.Xr mprotect 2 ,
+.Xr mincore 2
+.Sh HISTORY
+The
+.Fn msync
+function first appeared in 4.4BSD.
diff --git a/lib/libc/sys/munmap.2 b/lib/libc/sys/munmap.2
new file mode 100644
index 0000000..b9e8a1b
--- /dev/null
+++ b/lib/libc/sys/munmap.2
@@ -0,0 +1,78 @@
+.\" 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.2 (Berkeley) 4/15/94
+.\"
+.Dd April 15, 1994
+.Dt MUNMAP 2
+.Os
+.Sh NAME
+.Nm munmap
+.Nd remove a mapping
+.Sh SYNOPSIS
+.Fn munmap "caddr_t 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,
+.Nm 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 not part of the currently
+valid address space.
+.Sh "SEE ALSO"
+.Xr getpagesize 2 ,
+.Xr msync 2 ,
+.Xr munmap 2 ,
+.Xr mprotect 2 ,
+.Xr madvise 2 ,
+.Xr mincore 2
+.Sh HISTORY
+The
+.Fn munmap
+function first appeared in 4.4BSD.
diff --git a/lib/libc/sys/nfssvc.2 b/lib/libc/sys/nfssvc.2
new file mode 100644
index 0000000..0c8038f
--- /dev/null
+++ b/lib/libc/sys/nfssvc.2
@@ -0,0 +1,238 @@
+.\" 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
+.\"
+.Dd June 9, 1993
+.Dt NFSSVC 2
+.Os
+.Sh NAME
+.Nm nfssvc
+.Nd NFS services
+.Sh SYNOPSIS
+.Fd #include <unistd.h>
+.Fd #include <nfs/nfs.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 */
+ char *ncd_authstr; /* Authenticator string */
+};
+.Ed
+.sp
+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) */
+ char *nsd_authstr; /* Auth string (ret) */
+};
+.Ed
+.sp
+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
+.sp
+to pass a server side
+.Tn NFS
+socket into the kernel for servicing by the
+.Xr nfsd 8
+daemons.
+.Sh RETURN VALUES
+Normally
+.Nm 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 nfsd 8 ,
+.Xr mount_nfs 8 ,
+.Xr nfsiod 8
+.Sh HISTORY
+The
+.Nm nfssvc
+function first appeared in 4.4BSD.
+.Sh BUGS
+The
+.Nm 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
+.Nm 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..dea59fc
--- /dev/null
+++ b/lib/libc/sys/open.2
@@ -0,0 +1,257 @@
+.\" 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
+.\"
+.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" "mode_t mode"
+.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 which case 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
+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.
+.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 EINTR
+The
+.Nm
+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).
+.El
+.Sh SEE ALSO
+.Xr chmod 2 ,
+.Xr close 2 ,
+.Xr dup 2 ,
+.Xr getdtablesize 2 ,
+.Xr lseek 2 ,
+.Xr read 2 ,
+.Xr write 2 ,
+.Xr umask 2
+.Sh HISTORY
+An
+.Nm
+function call appeared in Version 6 AT&T UNIX.
diff --git a/lib/libc/sys/pathconf.2 b/lib/libc/sys/pathconf.2
new file mode 100644
index 0000000..1b4fbc4
--- /dev/null
+++ b/lib/libc/sys/pathconf.2
@@ -0,0 +1,163 @@
+.\" 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
+.\"
+.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
+.Nm pathconf ,
+the
+.Fa path
+argument is the name of a file or directory.
+For
+.Nm 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
+.Nm pathconf
+or
+.Nm 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
+.Nm pathconf
+and
+.Nm 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
+.Nm pathconf
+and
+.Nm fpathconf
+functions first appeared in 4.4BSD.
diff --git a/lib/libc/sys/pipe.2 b/lib/libc/sys/pipe.2
new file mode 100644
index 0000000..b2556a6
--- /dev/null
+++ b/lib/libc/sys/pipe.2
@@ -0,0 +1,123 @@
+.\" 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
+.\"
+.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
+Pipes are really a special case of the
+.Xr socketpair 2
+call and, in fact, are implemented as such in the system.
+.Pp
+The bidirectional nature of this implementation of pipes is not
+portable to older systems, so it is reccomended 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 read 2 ,
+.Xr write 2 ,
+.Xr fork 2 ,
+.Xr socketpair 2
+.Sh HISTORY
+A
+.Nm
+function call appeared in Version 6 AT&T UNIX.
+.Pp
+Bidirectional pipes were first used on Unix System V release 4.
diff --git a/lib/libc/sys/profil.2 b/lib/libc/sys/profil.2
new file mode 100644
index 0000000..670e343
--- /dev/null
+++ b/lib/libc/sys/profil.2
@@ -0,0 +1,129 @@
+.\" 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
+.\"
+.Dd "June 4, 1993"
+.Dt PROFIL 2
+.Os
+.Sh NAME
+.Nm profil
+.Nd control process profiling
+.Sh SYNOPSIS
+.Ft int
+.Fn profil "char *samples" "int size" "int 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 clock tick,
+the kernel updates an appropriate count in the
+.Fa samples
+buffer.
+.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 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
+.\" wish I knew... probably 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/quotactl.2 b/lib/libc/sys/quotactl.2
new file mode 100644
index 0000000..047d070
--- /dev/null
+++ b/lib/libc/sys/quotactl.2
@@ -0,0 +1,213 @@
+.\" 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.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt QUOTACTL 2
+.Os
+.Sh NAME
+.Nm quotactl
+.Nd manipulate filesystem quotas
+.Sh SYNOPSIS
+.Ft #include <ufs/ufs/quota.h> /* for ufs quotas */
+.Ft int
+.Fn quotactl "const char *path" "int cmd" "int id" "char *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 .
+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 ``ufs'' filesystem.
+For ``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
+and group identifiers.
+The ``ufs'' specific commands are:
+.Bl -tag -width Q_QUOTAON
+.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/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/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/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 EINVAL
+A pathname contains a character with the high-order bit set.
+.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
+.Nm 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..b94341a
--- /dev/null
+++ b/lib/libc/sys/read.2
@@ -0,0 +1,189 @@
+.\" 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
+.\"
+.Dd February 26, 1994
+.Dt READ 2
+.Os BSD 4
+.Sh NAME
+.Nm read ,
+.Nm readv
+.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"
+.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].
+.Pp
+For
+.Fn readv ,
+the
+.Fa iovec
+structure is defined as:
+.Pp
+.Bd -literal -offset indent -compact
+struct iovec {
+ void *iov_base;
+ size_t iov_len;
+};
+.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
+and
+.Fn readv
+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 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
+and
+.Fn readv
+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
+.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
+.Fn Read
+is expected to conform to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
+.Sh HISTORY
+The
+.Fn readv
+function call
+appeared in
+.Bx 4.2 .
+A
+.Nm read
+function call
+appeared in
+Version 6 AT&T UNIX.
diff --git a/lib/libc/sys/readlink.2 b/lib/libc/sys/readlink.2
new file mode 100644
index 0000000..4827110
--- /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
+.\"
+.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 .
+.Nm Readlink
+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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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 stat 2 ,
+.Xr lstat 2 ,
+.Xr symlink 2
+.Xr symlink 7 ,
+.Sh HISTORY
+The
+.Nm
+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..0db9ea2
--- /dev/null
+++ b/lib/libc/sys/reboot.2
@@ -0,0 +1,158 @@
+.\" 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
+.\"
+.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_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.
+.Pp
+When no options are given (i.e.,
+.Dv RB_AUTOBOOT
+is used), the system is
+rebooted from file ``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 ) .
+.El
+.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 kadb 4 ,
+.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
+.Nm
+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..9ed24a3
--- /dev/null
+++ b/lib/libc/sys/recv.2
@@ -0,0 +1,263 @@
+.\" 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
+.\"
+.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" "int *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
+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[]; */
+};
+.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
+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 read 2 ,
+.Xr select 2 ,
+.Xr getsockopt 2 ,
+.Xr socket 2
+.Sh HISTORY
+The
+.Nm
+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..be47d58
--- /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
+.\"
+.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 EINVAL
+Either pathname contains a character with the high-order bit set.
+.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
+.Fn Rename
+conforms to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
diff --git a/lib/libc/sys/revoke.2 b/lib/libc/sys/revoke.2
new file mode 100644
index 0000000..e782874
--- /dev/null
+++ b/lib/libc/sys/revoke.2
@@ -0,0 +1,105 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt REVOKE 2
+.Os
+.Sh NAME
+.Nm revoke
+.Nd revoke file access
+.Sh SYNOPSIS
+.Ft int
+.Fn revoke "char *path"
+.Sh DESCRIPTION
+The
+.Nm 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
+.Nm 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 named file is neither a character special or block
+special 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
+.Nm revoke
+function was introduced in
+.Bx 4.3 Reno .
diff --git a/lib/libc/sys/rmdir.2 b/lib/libc/sys/rmdir.2
new file mode 100644
index 0000000..29f8833
--- /dev/null
+++ b/lib/libc/sys/rmdir.2
@@ -0,0 +1,106 @@
+.\" 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
+.\"
+.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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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
+.Nm
+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..c9957fd
--- /dev/null
+++ b/lib/libc/sys/rtprio.2
@@ -0,0 +1,106 @@
+.\" 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.
+.\"
+.\" $Id: $
+.\"
+.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/resource.h>
+.Fd #include <sys/rtprio.h>
+.Ft int
+.Fn rtprio "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 AUTHOR
+The original author was Henrik Vestergaard Draboel - hvd@terry.ping.dk. This
+implementation in FreeBSD was substantially rewritten by David Greenman.
+.Sh SEE ALSO
+.Xr rtprio 1 ,
+.Xr nice 1 ,
+.Xr ps 1 ,
+.Xr nice 2 ,
+.Xr renice 8
+
diff --git a/lib/libc/sys/select.2 b/lib/libc/sys/select.2
new file mode 100644
index 0000000..e923ea4
--- /dev/null
+++ b/lib/libc/sys/select.2
@@ -0,0 +1,188 @@
+.\" 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
+.\"
+.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 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 &fdsetx
+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 affect 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.
+.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
+.Sh BUGS
+Although the provision of
+.Xr getdtablesize 2
+was intended to allow user programs to be written independent
+of the kernel limit on the number of open files, the dimension
+of a sufficiently large bit field for select remains a problem.
+The default size
+.Dv FD_SETSIZE
+(currently 256) is somewhat larger than
+the current kernel limit to the number of open files.
+However, in order to accommodate programs which might potentially
+use a larger number of open files with select, it is possible
+to increase this size within a kernel by providing
+a larger definition of
+.Dv FD_SETSIZE
+in kernel configuration file and rebuilding a kernel.
+To increase default limit user program must define its own
+.Dv FD_SETSIZE
+which is less or equal new kernel
+.Dv FD_SETSIZE
+before the inclusion of any header which includes
+.Aq Pa sys/types.h .
+.Pp
+.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
+.Nm
+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..fe60ce0
--- /dev/null
+++ b/lib/libc/sys/semctl.2
@@ -0,0 +1,173 @@
+.\"
+.\" 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.
+.\"
+.\" $Id$
+.\"
+.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" "union semun arg"
+.Sh DESCRIPTION
+.Fn Semctl
+performs the operation indicated by
+.Fa cmd
+on the semaphore set indicated by
+.Fa semid .
+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 effictive uid must equal the semaphore set's
+.Fa sem_perm.uid
+or
+.Fa sem_perm.cuid ,
+or the process must have superuser priviliges.
+.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..323aef4
--- /dev/null
+++ b/lib/libc/sys/semget.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.
+.\"
+.\" $Id$
+.\"
+.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_W
+Write access for user.
+.It Dv (SEM_R>>3)
+Read access for group.
+.It Dv (SEM_W>>3)
+Write access for group.
+.It Dv (SEM_R>>6)
+Read access for other.
+.It Dv (SEM_W>>6)
+Write 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
diff --git a/lib/libc/sys/semop.2 b/lib/libc/sys/semop.2
new file mode 100644
index 0000000..74fa01b
--- /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.
+.\"
+.\" $Id$
+.\"
+.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 specifed, 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 semget 2 ,
+.Xr semctl 2
diff --git a/lib/libc/sys/send.2 b/lib/libc/sys/send.2
new file mode 100644
index 0000000..77e2ed8
--- /dev/null
+++ b/lib/libc/sys/send.2
@@ -0,0 +1,179 @@
+.\" 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
+.\" $Id$
+.\"
+.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" "int 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 [EMSGSIZE]
+.It Bq Er EBADF
+An invalid descriptor was specified.
+.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.
+.El
+.Sh SEE ALSO
+.Xr fcntl 2 ,
+.Xr recv 2 ,
+.Xr select 2 ,
+.Xr getsockopt 2 ,
+.Xr socket 2 ,
+.Xr write 2
+.Sh HISTORY
+The
+.Nm
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/setgroups.2 b/lib/libc/sys/setgroups.2
new file mode 100644
index 0000000..e20b47e
--- /dev/null
+++ b/lib/libc/sys/setgroups.2
@@ -0,0 +1,83 @@
+.\" 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
+.\"
+.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
+.Nm
+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..141c203
--- /dev/null
+++ b/lib/libc/sys/setpgid.2
@@ -0,0 +1,89 @@
+.\" 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
+.\"
+.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_tpid pid_tpgrp
+.Ft int
+.Fn setpgrp pid_tpid pid_tpgrp
+.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
+.Fn Setpgid
+conforms to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
+.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..e890a98
--- /dev/null
+++ b/lib/libc/sys/setregid.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.
+.\"
+.\" @(#)setregid.2 8.2 (Berkeley) 4/16/94
+.\"
+.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 setegid 2 ,
+.Xr setgid 2 ,
+.Xr setuid 2
+.Sh HISTORY
+The
+.Nm
+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..12af3ca
--- /dev/null
+++ b/lib/libc/sys/setreuid.2
@@ -0,0 +1,89 @@
+.\" 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
+.\"
+.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 seteuid 2 ,
+.Xr setuid 2
+.Sh HISTORY
+The
+.Nm
+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..48ac6a0
--- /dev/null
+++ b/lib/libc/sys/setsid.2
@@ -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.
+.\"
+.\" @(#)setsid.2 8.1 (Berkeley) 6/4/93
+.\"
+.Dd "June 4, 1993"
+.Dt SETSID 2
+.Os
+.Sh NAME
+.Nm setsid
+.Nd create session and set process group ID
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Ft pid_t
+.Fn setsid "void"
+.Sh DESCRIPTION
+The
+.Nm 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.
+.Pp
+Upon successful completion, the
+.Nm 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.
+.Sh ERRORS
+If an error occurs,
+.Nm setsid
+returns -1 and the global variable
+.Va errno
+is set to indicate the error, as follows:
+.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 3 ,
+.Xr tcgetpgrp 3 ,
+.Xr tcsetpgrp 3
+.Sh STANDARDS
+The
+.Nm setsid
+function is expected to be compliant with the
+.St -p1003.1-88
+specification.
diff --git a/lib/libc/sys/setuid.2 b/lib/libc/sys/setuid.2
new file mode 100644
index 0000000..383a8f5
--- /dev/null
+++ b/lib/libc/sys/setuid.2
@@ -0,0 +1,122 @@
+.\" 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
+.\"
+.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.
+The
+.Fn setuid
+function is permitted if the specified ID is equal to the real 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.
+The
+.Fn setgid
+function is permitted if the specified ID is equal to the real 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 getuid 2 ,
+.Xr getgid 2
+.Sh STANDARDS
+The
+.Fn setuid
+and
+.Fn setgid
+functions are compliant with the
+.St -p1003.1-88
+specification with
+.Li _POSIX_SAVED_IDS
+not defined.
+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.
diff --git a/lib/libc/sys/shmat.2 b/lib/libc/sys/shmat.2
new file mode 100644
index 0000000..587eebc
--- /dev/null
+++ b/lib/libc/sys/shmat.2
@@ -0,0 +1,110 @@
+.\"
+.\" 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.
+.\"
+.\" $Id$
+.\"
+.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 <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 identifed 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 specifed 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 shmget 2 ,
+.Xr shmctl 2
diff --git a/lib/libc/sys/shmctl.2 b/lib/libc/sys/shmctl.2
new file mode 100644
index 0000000..b1c5a4b
--- /dev/null
+++ b/lib/libc/sys/shmctl.2
@@ -0,0 +1,136 @@
+.\"
+.\" 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.
+.\"
+.\" $Id$
+.\"
+.Dd July 17, 1995
+.Dt SHMCTL 2
+.Os FreeBSD
+.Sh NAME
+.Nm shmctl
+.Nd shared memory control
+.Sh SYNOPSIS
+.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 privilges.
+.\" .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 priviliges. 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 shmget 2 ,
+.Xr shmat 2 ,
+.Xr shmdt 2 ,
+.Xr ftok 3
diff --git a/lib/libc/sys/shmget.2 b/lib/libc/sys/shmget.2
new file mode 100644
index 0000000..3df3272
--- /dev/null
+++ b/lib/libc/sys/shmget.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.
+.\"
+.\" $Id$
+.\"
+.Dd July 3, 1995
+.Dt SHMGET 2
+.Os FreeBSD
+.Sh NAME
+.Nm shmget
+.Nd obtain a shared memory identifier
+.Sh SYNOPSIS
+.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 minumum, 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 shmctl 2 ,
+.Xr shmat 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..976f958
--- /dev/null
+++ b/lib/libc/sys/shutdown.2
@@ -0,0 +1,81 @@
+.\" 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
+.\"
+.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/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 0, further receives will be disallowed.
+If
+.Fa how
+is 1, further sends will be disallowed.
+If
+.Fa how
+is 2, further sends and receives will be disallowed.
+.Sh DIAGNOSTICS
+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 HISTORY
+The
+.Nm
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/sigaction.2 b/lib/libc/sys/sigaction.2
new file mode 100644
index 0000000..3f41266
--- /dev/null
+++ b/lib/libc/sys/sigaction.2
@@ -0,0 +1,370 @@
+.\" 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.
+.\"
+.\" @(#)sigaction.2 8.2 (Berkeley) 4/3/94
+.\"
+.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 {
+ void (*sa_handler)();
+ sigset_t sa_mask;
+ int sa_flags;
+};
+.Ed
+.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 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 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 specific signal.
+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 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 .
+If the
+.Dv SA_NOCLDSTOP
+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.
+Further, if the
+.Dv SA_ONSTACK
+bit is set in
+.Em sa_flags ,
+the system will deliver the signal to the process on a
+.Em "signal stack" ,
+specified with
+.Xr sigstack 2 .
+.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 2
+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" " system call given invalid argument"
+.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 mask specified in
+.Fa act
+is not allowed to block
+.Dv SIGKILL
+or
+.Dv SIGSTOP .
+This is done silently by the system.
+.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 EXAMPLE
+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.
+.Fa Code
+is a parameter that is either a constant
+or the code provided by
+the hardware.
+.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 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
+.Nm sigaction
+function is defined by
+.St -p1003.1-88 .
+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.
+.Sh SEE ALSO
+.Xr kill 1 ,
+.Xr ptrace 2 ,
+.Xr kill 2 ,
+.Xr sigaction 2 ,
+.Xr sigprocmask 2 ,
+.Xr sigsuspend 2 ,
+.Xr sigblock 2 ,
+.Xr sigsetmask 2 ,
+.Xr sigpause 2 ,
+.Xr sigstack 2 ,
+.Xr sigvec 2 ,
+.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..f1ed718
--- /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.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt SIGALTSTACK 2
+.Os BSD 4.2
+.Sh NAME
+.Nm sigaltstack
+.Nd set and/or get signal stack context
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <signal.h>
+.Bd -literal
+struct sigaltstack {
+ caddr_t ss_sp;
+ long 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 SA_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
+.Nm
+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 SA_ONSTACK
+if the process is currently on a signal stack and
+.Dv SA_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 Sigstack
+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
+.Nm 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..0c87d4f
--- /dev/null
+++ b/lib/libc/sys/sigpending.2
@@ -0,0 +1,72 @@
+.\" 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
+.\"
+.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
+.Nm 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
+.Nm sigpending
+function does not currently detect any errors.
+.Sh SEE ALSO
+.Xr sigaction 2 ,
+.Xr sigprocmask 2
+.Sh STANDARDS
+The
+.Nm sigpending
+function is defined by
+.St -p1003.1-88 .
diff --git a/lib/libc/sys/sigprocmask.2 b/lib/libc/sys/sigprocmask.2
new file mode 100644
index 0000000..73b014d
--- /dev/null
+++ b/lib/libc/sys/sigprocmask.2
@@ -0,0 +1,120 @@
+.\" 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
+.\"
+.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"
+.Fn sigmask signum
+.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 sigsetops 3 ,
+.Xr sigsuspend 2
+.Sh STANDARDS
+The
+.Nm sigprocmask
+function call is expected to
+conform to
+.St -p1003.1-88 .
diff --git a/lib/libc/sys/sigreturn.2 b/lib/libc/sys/sigreturn.2
new file mode 100644
index 0000000..f995d11
--- /dev/null
+++ b/lib/libc/sys/sigreturn.2
@@ -0,0 +1,97 @@
+.\" 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
+.\"
+.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>
+.Bd -literal
+struct sigcontext {
+ int sc_onstack;
+ int sc_mask;
+ int sc_sp;
+ int sc_fp;
+ int sc_ap;
+ int sc_pc;
+ int sc_ps;
+};
+.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
+.Nm
+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..54d1c14
--- /dev/null
+++ b/lib/libc/sys/sigstack.2
@@ -0,0 +1,51 @@
+.\" 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
+.\"
+.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
+.Nm
+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..a234454
--- /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.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.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 sigprocmask 2 ,
+.Xr sigaction 2 ,
+.Xr sigsetops 3
+.Sh STANDARDS
+The
+.Nm sigsupend
+function call
+conforms to
+.St -p1003.1-88 .
diff --git a/lib/libc/sys/socket.2 b/lib/libc/sys/socket.2
new file mode 100644
index 0000000..e048b46
--- /dev/null
+++ b/lib/libc/sys/socket.2
@@ -0,0 +1,270 @@
+.\" 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
+.\" $Id$
+.\"
+.Dd February 15, 1995
+.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_INET (ARPA Internet protocols),
+PF_ISO (ISO protocols),
+PF_CCITT (ITU-T protocols, like X.25),
+PF_NS (Xerox Network Systems protocols), and
+.\"PF_IMPLINK (IMP \*(lqhost at IMP\*(rq link layer).
+.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
+SOCK_DGRAM
+SOCK_RAW
+SOCK_SEQPACKET
+SOCK_RDM
+.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 EACCESS
+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 getprotoent 3 ,
+.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
+.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
+.Nm
+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..1e8ba24
--- /dev/null
+++ b/lib/libc/sys/socketpair.2
@@ -0,0 +1,91 @@
+.\" 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
+.\"
+.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 DIAGNOSTICS
+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 read 2 ,
+.Xr write 2 ,
+.Xr pipe 2
+.Sh BUGS
+This call is currently implemented only for the
+.Tn UNIX
+domain.
+.Sh HISTORY
+The
+.Nm
+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..8f78621
--- /dev/null
+++ b/lib/libc/sys/stat.2
@@ -0,0 +1,276 @@
+.\" 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.3 (Berkeley) 4/19/94
+.\"
+.Dd April 19, 1994
+.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.
+Unlike other filesystem objects,
+symbolic links do not have an owner, group, access mode, times, etc.
+Instead, these attributes are taken from the directory that
+contains the link.
+The only attributes returned from an
+.Fn lstat
+that refer to the symbolic link itself are the file type (S_IFLNK),
+size, blocks, and link count (always 1).
+.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; /* device inode resides on */
+ ino_t st_ino; /* inode's number */
+ mode_t st_mode; /* inode protection mode */
+ nlink_t st_nlink; /* number or hard links to the file */
+ uid_t st_uid; /* user-id of owner */
+ gid_t st_gid; /* group-id of owner */
+ dev_t st_rdev; /* device type, for special file inode */
+ 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 */
+ off_t st_size; /* file size, in bytes */
+ quad_t st_blocks; /* blocks allocated for file */
+ u_long st_blksize;/* optimal file sys I/O ops blocksize */
+ u_long st_flags; /* user defined flags for file */
+ u_long 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
+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_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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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 CAVEAT
+The fields in the stat structure currently marked
+.Fa st_spare1 ,
+.Fa st_spare2 ,
+and
+.Fa st_spare3
+are present in preparation for inode time stamps expanding
+to 64 bits. This, however, can break certain programs that
+depend on the time stamps being contiguous (in calls to
+.Xr utimes 2 ) .
+.Sh SEE ALSO
+.Xr chmod 2 ,
+.Xr chown 2 ,
+.Xr utimes 2
+.Xr symlink 7
+.Sh BUGS
+Applying
+.Xr fstat
+to a socket (and thus to a pipe)
+returns a zero'd 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 IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
+.Sh HISTORY
+A
+.Nm 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..a7a1da2
--- /dev/null
+++ b/lib/libc/sys/statfs.2
@@ -0,0 +1,161 @@
+.\" 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.3 (Berkeley) 2/11/94
+.\"
+.Dd February 11, 1994
+.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 quad fsid_t;
+
+#define MNAMELEN 90 /* length of buffer for returned name */
+
+struct statfs {
+short f_type; /* type of filesystem (see below) */
+short f_flags; /* copy of mount flags */
+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 */
+long f_spare[9]; /* spare for later */
+char f_mntonname[MNAMELEN]; /* mount point */
+char f_mntfromname[MNAMELEN]; /* mounted filesystem */
+};
+/*
+* File system types.
+*/
+#define MOUNT_UFS 1 /* Fast Filesystem */
+#define MOUNT_NFS 2 /* Sun-compatible Network Filesystem */
+#define MOUNT_MFS 3 /* Memory-based Filesystem */
+#define MOUNT_MSDOS 4 /* MS/DOS Filesystem */
+#define MOUNT_LFS 5 /* Log-based Filesystem */
+#define MOUNT_LOFS 6 /* Loopback Filesystem */
+#define MOUNT_FDESC 7 /* File Descriptor Filesystem */
+#define MOUNT_PORTAL 8 /* Portal Filesystem */
+#define MOUNT_NULL 9 /* Minimal Filesystem Layer */
+#define MOUNT_UMAP 10 /* Uid/Gid Remapping Filesystem */
+#define MOUNT_KERNFS 11 /* Kernel Information Filesystem */
+#define MOUNT_PROCFS 12 /* /proc Filesystem */
+#define MOUNT_AFS 13 /* Andrew Filesystem */
+#define MOUNT_CD9660 14 /* ISO9660 (aka CDROM) Filesystem */
+#define MOUNT_UNION 15 /* Union (translucent) Filesystem */
+.Ed
+.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 EINVAL
+.Fa path
+contains a character with the high-order bit set.
+.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
+.Nm statfs
+function first appeared in 4.4BSD.
diff --git a/lib/libc/sys/swapon.2 b/lib/libc/sys/swapon.2
new file mode 100644
index 0000000..5f152cc
--- /dev/null
+++ b/lib/libc/sys/swapon.2
@@ -0,0 +1,113 @@
+.\" 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
+.\"
+.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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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 swapon 8 ,
+.Xr config 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
+.Nm
+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..c404a3d
--- /dev/null
+++ b/lib/libc/sys/symlink.2
@@ -0,0 +1,139 @@
+.\" 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
+.\"
+.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 EINVAL
+Either
+.Fa name1
+or
+.Fa name2
+contains a character with the high-order bit set.
+.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
+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 link 2 ,
+.Xr ln 1 ,
+.Xr unlink 2
+.Sh HISTORY
+The
+.Nm
+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..5e79fef
--- /dev/null
+++ b/lib/libc/sys/sync.2
@@ -0,0 +1,73 @@
+.\" 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
+.\"
+.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 8
+(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 sync 8 ,
+.Xr update 8
+.Sh BUGS
+.Fn Sync
+may return before the buffers are completely flushed.
+.Sh HISTORY
+A
+.Nm
+function call appeared in Version 6 AT&T UNIX.
diff --git a/lib/libc/sys/syscall.2 b/lib/libc/sys/syscall.2
new file mode 100644
index 0000000..2e020ad
--- /dev/null
+++ b/lib/libc/sys/syscall.2
@@ -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.
+.\"
+.\" @(#)syscall.2 8.1 (Berkeley) 6/16/93
+.\"
+.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 int
+.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
+.Nm __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
+.Nm 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..2a5f3a6
--- /dev/null
+++ b/lib/libc/sys/truncate.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.
+.\"
+.\" @(#)truncate.2 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt TRUNCATE 2
+.Os BSD 4.2
+.Sh NAME
+.Nm truncate ,
+.Nm ftruncate
+.Nd truncate 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 to at most
+.Fa length
+bytes in size. If the file previously
+was larger than this size, the extra data
+is lost.
+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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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.
+.Sh HISTORY
+The
+.Nm
+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..0d50cd7
--- /dev/null
+++ b/lib/libc/sys/truncate.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[] = "@(#)truncate.c 8.1 (Berkeley) 6/17/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/syscall.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)
+ 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..cec3f1d
--- /dev/null
+++ b/lib/libc/sys/umask.2
@@ -0,0 +1,82 @@
+.\" 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
+.\"
+.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 IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
diff --git a/lib/libc/sys/unlink.2 b/lib/libc/sys/unlink.2
new file mode 100644
index 0000000..78221bc
--- /dev/null
+++ b/lib/libc/sys/unlink.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.
+.\"
+.\" @(#)unlink.2 8.1 (Berkeley) 6/4/93
+.\"
+.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.
+.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 EINVAL
+The pathname contains a character with the high-order bit set.
+.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 and the effective user ID
+of the process is not the super-user.
+.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
+.Nm
+function call appeared in Version 6 AT&T UNIX.
diff --git a/lib/libc/sys/utimes.2 b/lib/libc/sys/utimes.2
new file mode 100644
index 0000000..1ebeb37
--- /dev/null
+++ b/lib/libc/sys/utimes.2
@@ -0,0 +1,118 @@
+.\" 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
+.\"
+.Dd June 4, 1993
+.Dt UTIMES 2
+.Os BSD 4
+.Sh NAME
+.Nm utimes
+.Nd set file access and modification times
+.Sh SYNOPSIS
+.Fd #include <sys/time.h>
+.Ft int
+.Fn utimes "const char *file" "const struct timeval *times"
+.Sh DESCRIPTION
+The
+.Fn utimes
+function sets the access and modification times of the named file from
+the structures in the argument array
+.Fa times .
+.Pp
+The first structure is the access time, and the second is the modification
+time.
+.Pp
+If the times are specified (the
+.Fa times
+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 times
+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 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
+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
+.Xr File
+or
+.Fa times
+points outside the process's allocated address space.
+.It Bq Er EINVAL
+The pathname contains a character with the high-order bit set.
+.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 255 characters,
+or an entire path name exceeded 1023 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
+.Sh SEE ALSO
+.Xr stat 2
+.Sh HISTORY
+The
+.Nm utimes
+function call appeared in
+.Bx 4.2 .
diff --git a/lib/libc/sys/vfork.2 b/lib/libc/sys/vfork.2
new file mode 100644
index 0000000..8b6e077
--- /dev/null
+++ b/lib/libc/sys/vfork.2
@@ -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.
+.\"
+.\" @(#)vfork.2 8.1 (Berkeley) 6/4/93
+.\"
+.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 .
+.Fn Vfork
+differs from
+.Xr fork
+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 .
+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
+rather than
+.Xr exit
+if you can't
+.Xr execve ,
+since
+.Xr exit
+will flush and close standard I/O channels, and thereby mess up the
+parent processes standard I/O data structures.
+(Even with
+.Xr fork
+it is wrong to call
+.Xr exit
+since buffered data would then be flushed twice.)
+.Sh SEE ALSO
+.Xr fork 2 ,
+.Xr execve 2 ,
+.Xr sigvec 2 ,
+.Xr wait 2 ,
+.Sh DIAGNOSTICS
+Same as for
+.Xr fork .
+.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
+as it will, in that case, be made synonymous to
+.Xr fork .
+.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
+.Nm
+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..c0077b1
--- /dev/null
+++ b/lib/libc/sys/wait.2
@@ -0,0 +1,295 @@
+.\" 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
+.\"
+.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 2 .
+.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 2
+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 sigaction 2
+.Sh HISTORY
+A
+.Nm
+function call appeared in Version 6 AT&T UNIX.
diff --git a/lib/libc/sys/write.2 b/lib/libc/sys/write.2
new file mode 100644
index 0000000..de2d3ae
--- /dev/null
+++ b/lib/libc/sys/write.2
@@ -0,0 +1,205 @@
+.\" 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
+.\"
+.Dd April 2, 1994
+.Dt WRITE 2
+.Os BSD 4
+.Sh NAME
+.Nm write ,
+.Nm writev
+.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"
+.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].
+.Pp
+For
+.Fn writev ,
+the
+.Fa iovec
+structure is defined as:
+.Pp
+.Bd -literal -offset indent -compact
+struct iovec {
+ void *iov_base;
+ size_t iov_len;
+};
+.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 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
+and
+.Fn writev
+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 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.
+.El
+.Sh SEE ALSO
+.Xr fcntl 2 ,
+.Xr lseek 2 ,
+.Xr open 2 ,
+.Xr pipe 2 ,
+.Xr select 2
+.Sh STANDARDS
+.Fn Write
+is expected to conform to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
+.Sh HISTORY
+The
+.Fn writev
+function call
+appeared in
+.Bx 4.2 .
+A
+.Nm write
+function call
+appeared in
+Version 6 AT&T UNIX.
diff --git a/lib/libc/xdr/Makefile.inc b/lib/libc/xdr/Makefile.inc
new file mode 100644
index 0000000..d41fb72
--- /dev/null
+++ b/lib/libc/xdr/Makefile.inc
@@ -0,0 +1,7 @@
+# @(#)Makefile 5.11 (Berkeley) 9/6/90
+
+.PATH: ${.CURDIR}/xdr ${.CURDIR}/.
+SRCS+= xdr.c xdr_array.c xdr_float.c xdr_mem.c \
+ xdr_rec.c xdr_reference.c xdr_stdio.c
+
+MAN3+= xdr/xdr.3
diff --git a/lib/libc/xdr/xdr.3 b/lib/libc/xdr/xdr.3
new file mode 100644
index 0000000..b656ea8
--- /dev/null
+++ b/lib/libc/xdr/xdr.3
@@ -0,0 +1,823 @@
+.\" @(#)xdr.3n 2.2 88/08/03 4.0 RPCSRC; from 1.16 88/03/14 SMI
+.TH XDR 3N "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 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 (3N)
+.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..87b4f7a
--- /dev/null
+++ b/lib/libc/xdr/xdr.c
@@ -0,0 +1,579 @@
+/*
+ * 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 = "$Id: xdr.c,v 1.2 1995/05/30 05:42:03 rgrimes Exp $";
+#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 <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;
+{
+
+#ifdef lint
+ (void) (xdr_short(xdrs, (short *)ip));
+ return (xdr_long(xdrs, (long *)ip));
+#else
+ if (sizeof (int) == sizeof (long)) {
+ return (xdr_long(xdrs, (long *)ip));
+ } else {
+ return (xdr_short(xdrs, (short *)ip));
+ }
+#endif
+}
+
+/*
+ * XDR unsigned integers
+ */
+bool_t
+xdr_u_int(xdrs, up)
+ XDR *xdrs;
+ u_int *up;
+{
+
+#ifdef lint
+ (void) (xdr_short(xdrs, (short *)up));
+ return (xdr_u_long(xdrs, (u_long *)up));
+#else
+ if (sizeof (u_int) == sizeof (u_long)) {
+ return (xdr_u_long(xdrs, (u_long *)up));
+ } else {
+ return (xdr_short(xdrs, (short *)up));
+ }
+#endif
+}
+
+/*
+ * 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;
+{
+
+ if (xdrs->x_op == XDR_ENCODE)
+ return (XDR_PUTLONG(xdrs, lp));
+
+ if (xdrs->x_op == XDR_DECODE)
+ return (XDR_GETLONG(xdrs, lp));
+
+ if (xdrs->x_op == 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;
+{
+
+ if (xdrs->x_op == XDR_DECODE)
+ return (XDR_GETLONG(xdrs, (long *)ulp));
+ if (xdrs->x_op == XDR_ENCODE)
+ return (XDR_PUTLONG(xdrs, (long *)ulp));
+ if (xdrs->x_op == 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, &l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &l)) {
+ return (FALSE);
+ }
+ *usp = (u_short) 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;
+ 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 (short)) {
+ return (xdr_short(xdrs, (short *)ep));
+ } else {
+ return (FALSE);
+ }
+#else
+ (void) (xdr_short(xdrs, (short *)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, 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;
+{
+ if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
+ return (TRUE);
+ }
+ return (FALSE);
+}
diff --git a/lib/libc/xdr/xdr_array.c b/lib/libc/xdr/xdr_array.c
new file mode 100644
index 0000000..35bbb2b
--- /dev/null
+++ b/lib/libc/xdr/xdr_array.c
@@ -0,0 +1,156 @@
+/*
+ * 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 = "$Id: xdr_array.c,v 1.2 1995/05/30 05:42:04 rgrimes Exp $";
+#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);
+ }
+ bzero(target, 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..105ca43
--- /dev/null
+++ b/lib/libc/xdr/xdr_float.c
@@ -0,0 +1,283 @@
+/*
+ * 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 = "$Id: xdr_float.c,v 1.1 1994/08/07 18:39:32 wollman Exp $";
+#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 Suns (Sky / 68000's), i386's, MIPS, NS32k and Vaxen.
+ */
+
+#if defined(mc68000)||defined(sparc)||defined(i386)||defined(mips)||defined(ns32000)
+#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;
+{
+#ifndef IEEEFP
+ 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
+ return (XDR_PUTLONG(xdrs, (long *)fp));
+#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
+ return (XDR_GETLONG(xdrs, (long *)fp));
+#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);
+}
+
+/*
+ * This routine works on Suns (Sky / 68000's), i386's, MIPS and Vaxen.
+ */
+
+#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;
+{
+ register long *lp;
+#ifndef IEEEFP
+ 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
+ lp = (long *)dp;
+#if BYTE_ORDER == BIG_ENDIAN
+ return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
+#else
+ return (XDR_PUTLONG(xdrs, lp+1) && XDR_PUTLONG(xdrs, lp));
+#endif
+#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
+ lp = (long *)dp;
+#if BYTE_ORDER == BIG_ENDIAN
+ return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
+#else
+ return (XDR_GETLONG(xdrs, lp+1) && XDR_GETLONG(xdrs, lp));
+#endif
+#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..6f82f67
--- /dev/null
+++ b/lib/libc/xdr/xdr_mem.c
@@ -0,0 +1,186 @@
+/*
+ * 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 = "$Id: xdr_mem.c,v 1.2 1995/05/30 05:42:06 rgrimes Exp $";
+#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();
+static bool_t xdrmem_putlong();
+static bool_t xdrmem_getbytes();
+static bool_t xdrmem_putbytes();
+static u_int xdrmem_getpos();
+static bool_t xdrmem_setpos();
+static long * xdrmem_inline();
+static void xdrmem_destroy();
+
+static struct xdr_ops xdrmem_ops = {
+ xdrmem_getlong,
+ xdrmem_putlong,
+ xdrmem_getbytes,
+ xdrmem_putbytes,
+ xdrmem_getpos,
+ xdrmem_setpos,
+ xdrmem_inline,
+ 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 = &xdrmem_ops;
+ xdrs->x_private = xdrs->x_base = addr;
+ xdrs->x_handy = size;
+}
+
+static void
+xdrmem_destroy(/*xdrs*/)
+ /*XDR *xdrs;*/
+{
+}
+
+static bool_t
+xdrmem_getlong(xdrs, lp)
+ register XDR *xdrs;
+ long *lp;
+{
+
+ if ((xdrs->x_handy -= sizeof(long)) < 0)
+ return (FALSE);
+ *lp = (long)ntohl((u_long)(*((long *)(xdrs->x_private))));
+ xdrs->x_private += sizeof(long);
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_putlong(xdrs, lp)
+ register XDR *xdrs;
+ long *lp;
+{
+
+ if ((xdrs->x_handy -= sizeof(long)) < 0)
+ return (FALSE);
+ *(long *)xdrs->x_private = (long)htonl((u_long)(*lp));
+ xdrs->x_private += sizeof(long);
+ 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);
+ bcopy(xdrs->x_private, addr, 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);
+ bcopy(addr, xdrs->x_private, len);
+ xdrs->x_private += len;
+ return (TRUE);
+}
+
+static u_int
+xdrmem_getpos(xdrs)
+ register XDR *xdrs;
+{
+
+ return ((u_int)xdrs->x_private - (u_int)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 = (int)lastaddr - (int)newaddr;
+ return (TRUE);
+}
+
+static long *
+xdrmem_inline(xdrs, len)
+ register XDR *xdrs;
+ int len;
+{
+ long *buf = 0;
+
+ if (xdrs->x_handy >= len) {
+ xdrs->x_handy -= len;
+ buf = (long *) xdrs->x_private;
+ xdrs->x_private += len;
+ }
+ return (buf);
+}
diff --git a/lib/libc/xdr/xdr_rec.c b/lib/libc/xdr/xdr_rec.c
new file mode 100644
index 0000000..3b69f25
--- /dev/null
+++ b/lib/libc/xdr/xdr_rec.c
@@ -0,0 +1,585 @@
+/*
+ * 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 = "$Id: xdr_rec.c,v 1.3 1995/05/30 05:42:09 rgrimes Exp $";
+#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 long * 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_long)(1 << 31))
+
+typedef struct rec_strm {
+ caddr_t tcp_handle;
+ caddr_t the_buffer;
+ /*
+ * out-goung bits
+ */
+ int (*writeit)();
+ 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_long *frag_header; /* beginning of curren fragment */
+ bool_t frag_sent; /* true if buffer sent in middle of record */
+ /*
+ * in-coming bits
+ */
+ int (*readit)();
+ 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_int)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_long *)rstrm->out_base;
+ rstrm->out_finger += sizeof(u_long);
+ 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 long *buflp = (long *)(rstrm->in_finger);
+ long mylong;
+
+ /* first try the inline, fast case */
+ if ((rstrm->fbtbc >= sizeof(long)) &&
+ (((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) {
+ *lp = (long)ntohl((u_long)(*buflp));
+ rstrm->fbtbc -= sizeof(long);
+ rstrm->in_finger += sizeof(long);
+ } else {
+ if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long)))
+ return (FALSE);
+ *lp = (long)ntohl((u_long)mylong);
+ }
+ return (TRUE);
+}
+
+static bool_t
+xdrrec_putlong(xdrs, lp)
+ XDR *xdrs;
+ long *lp;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ register long *dest_lp = ((long *)(rstrm->out_finger));
+
+ if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) {
+ /*
+ * this case should almost never happen so the code is
+ * inefficient
+ */
+ rstrm->out_finger -= sizeof(long);
+ rstrm->frag_sent = TRUE;
+ if (! flush_out(rstrm, FALSE))
+ return (FALSE);
+ dest_lp = ((long *)(rstrm->out_finger));
+ rstrm->out_finger += sizeof(long);
+ }
+ *dest_lp = (long)htonl((u_long)(*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 int current;
+
+ while (len > 0) {
+ current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger;
+ current = (len < current) ? len : current;
+ bcopy(addr, rstrm->out_finger, 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)rstrm->tcp_handle, (long) 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 = (u_int) -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 long *
+xdrrec_inline(xdrs, len)
+ register XDR *xdrs;
+ int len;
+{
+ register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+ long * buf = NULL;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ if ((rstrm->out_finger + len) <= rstrm->out_boundry) {
+ buf = (long *) rstrm->out_finger;
+ rstrm->out_finger += len;
+ }
+ break;
+
+ case XDR_DECODE:
+ if ((len <= rstrm->fbtbc) &&
+ ((rstrm->in_finger + len) <= rstrm->in_boundry)) {
+ buf = (long *) 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_long) >=
+ (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_long);
+ *(rstrm->frag_header) = htonl((u_long)len | LAST_FRAG);
+ rstrm->frag_header = (u_long *)rstrm->out_finger;
+ rstrm->out_finger += sizeof(u_long);
+ 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_long len = (u_long)(rstrm->out_finger) -
+ (u_long)(rstrm->frag_header) - sizeof(u_long);
+
+ *(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_long *)rstrm->out_base;
+ rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long);
+ 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_int i;
+ register int len;
+
+ where = rstrm->in_base;
+ i = (u_int)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 int current;
+
+ while (len > 0) {
+ current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
+ if (current == 0) {
+ if (! fill_input_buf(rstrm))
+ return (FALSE);
+ continue;
+ }
+ current = (len < current) ? len : current;
+ bcopy(rstrm->in_finger, addr, 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_long 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;
+ 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 int current;
+
+ while (cnt > 0) {
+ current = (int)rstrm->in_boundry - (int)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..91ccff2
--- /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 = "$Id: xdr_reference.c,v 1.2 1995/05/30 05:42:12 rgrimes Exp $";
+#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);
+ }
+ bzero(loc, (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_stdio.c b/lib/libc/xdr/xdr_stdio.c
new file mode 100644
index 0000000..5cfdf20
--- /dev/null
+++ b/lib/libc/xdr/xdr_stdio.c
@@ -0,0 +1,191 @@
+/*
+ * 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 = "$Id: xdr_stdio.c,v 1.1 1994/08/07 18:39:35 wollman Exp $";
+#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 long * 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(long), 1, (FILE *)xdrs->x_private) != 1)
+ return (FALSE);
+#ifndef mc68000
+ *lp = ntohl(*lp);
+#endif
+ return (TRUE);
+}
+
+static bool_t
+xdrstdio_putlong(xdrs, lp)
+ XDR *xdrs;
+ long *lp;
+{
+
+#ifndef mc68000
+ long mycopy = htonl(*lp);
+ lp = &mycopy;
+#endif
+ if (fwrite((caddr_t)lp, sizeof(long), 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 long *
+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..529de75
--- /dev/null
+++ b/lib/libc/yp/Makefile.inc
@@ -0,0 +1,17 @@
+# from: @(#)Makefile.inc 5.3 (Berkeley) 2/20/91
+# $Id: Makefile.inc,v 1.1 1994/08/07 23:04:53 wollman Exp $
+
+# yp sources
+.PATH: ${.CURDIR}/yp
+
+SRCS+= xdryp.c yp_xdr.c yplib.c
+CLEANFILES+= yp_xdr.c yp.h
+
+RPCSRC= ${.DESTDIR}/usr/include/rpcsvc/yp.x
+RPCGEN= rpcgen
+
+yp_xdr.c: ${RPCSRC} yp.h
+ ${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..51a3878
--- /dev/null
+++ b/lib/libc/yp/xdryp.c
@@ -0,0 +1,115 @@
+/*
+ * 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 = "$Id: xdryp.c,v 1.3 1995/04/02 19:58:29 wpaul Exp $";
+#endif
+
+#include <rpc/rpc.h>
+#include <rpcsvc/yp.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);
+ return FALSE;
+ }
+ 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);
+ 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..9614fb0
--- /dev/null
+++ b/lib/libc/yp/yplib.c
@@ -0,0 +1,910 @@
+/*
+ * 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 = "$Id: yplib.c,v 1.13 1995/11/05 05:39:04 wpaul Exp $";
+#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.
+ */
+
+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;
+ long dom_vers;
+};
+
+#include <rpcsvc/ypclnt.h>
+
+#ifndef YPBINDLOCK
+#define YPBINDLOCK "/var/run/ypbind.lock"
+#endif
+
+#ifndef BINDINGDIR
+#define BINDINGDIR "/var/yp/binding"
+#endif
+#define YPMATCHCACHE
+#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;
+
+struct dom_binding *_ypbindlist;
+static char _yp_domain[MAXHOSTNAMELEN];
+int _yplib_timeout = 10;
+
+#ifdef YPMATCHCACHE
+int _yplib_cache = 5;
+
+static struct ypmatch_ent {
+ struct ypmatch_ent *next;
+ char *map, *key, *val;
+ int keylen, vallen;
+ time_t expire_t;
+} *ypmc;
+
+static void
+ypmatch_add(map, key, keylen, val, vallen)
+char *map;
+char *key;
+int keylen;
+char *val;
+int vallen;
+{
+ struct ypmatch_ent *ep;
+ time_t t;
+
+ time(&t);
+
+ for(ep=ypmc; ep; ep=ep->next)
+ if(ep->expire_t < t)
+ break;
+ if(ep==NULL) {
+ ep = (struct ypmatch_ent *)malloc(sizeof *ep);
+ bzero((char *)ep, sizeof *ep);
+ if(ypmc)
+ ep->next = ypmc;
+ ypmc = ep;
+ }
+
+ if(ep->key)
+ free(ep->key);
+ if(ep->val)
+ free(ep->val);
+
+ ep->key = NULL;
+ ep->val = NULL;
+
+ ep->key = (char *)malloc(keylen);
+ if(ep->key==NULL)
+ return;
+
+ ep->val = (char *)malloc(vallen);
+ if(ep->key==NULL) {
+ free(ep->key);
+ ep->key = NULL;
+ return;
+ }
+ ep->keylen = keylen;
+ ep->vallen = vallen;
+
+ bcopy(key, ep->key, ep->keylen);
+ bcopy(val, ep->val, ep->vallen);
+
+ if(ep->map) {
+ if( strcmp(ep->map, map) ) {
+ free(ep->map);
+ ep->map = strdup(map);
+ }
+ } else {
+ ep->map = strdup(map);
+ }
+
+ ep->expire_t = t + _yplib_cache;
+}
+
+static bool_t
+ypmatch_find(map, key, keylen, val, vallen)
+char *map;
+char *key;
+int keylen;
+char **val;
+int *vallen;
+{
+ struct ypmatch_ent *ep;
+ time_t t;
+
+ if(ypmc==NULL)
+ return 0;
+
+ time(&t);
+
+ for(ep=ypmc; ep; ep=ep->next) {
+ if(ep->keylen != keylen)
+ continue;
+ if(strcmp(ep->map, map))
+ continue;
+ if(bcmp(ep->key, key, keylen))
+ continue;
+ if(t > ep->expire_t)
+ continue;
+
+ *val = ep->val;
+ *vallen = ep->vallen;
+ return 1;
+ }
+ return 0;
+}
+#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 int 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, lfd, fd, gpid;
+ CLIENT *client;
+ int new = 0, r;
+ int retries = 0;
+
+ gpid = getpid();
+ if( !(pid==-1 || pid==gpid) ) {
+ ysd = _ypbindlist;
+ while(ysd) {
+ if(ysd->dom_client)
+ clnt_destroy(ysd->dom_client);
+ 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;
+ }
+
+ if ((lfd = open(YPBINDLOCK, O_RDONLY)) == -1)
+ return(YPERR_YPBIND);
+ errno = 0;
+ switch (flock(lfd, LOCK_EX|LOCK_NB) == -1 && errno == EWOULDBLOCK) {
+ case 0:
+ close(lfd);
+ return (YPERR_YPBIND);
+ break;
+ case 1:
+ default:
+ close(lfd);
+ break;
+ }
+
+again:
+ retries++;
+ if (retries > MAX_RETRIES) {
+ if (new)
+ free(ysd);
+ return(YPERR_YPBIND);
+ }
+#ifdef BINDINGDIR
+ if(ysd->dom_vers==0) {
+ sprintf(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) {
+ 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) {
+ clnt_pcreateerror("clnttcp_create");
+ 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) {
+ fprintf(stderr,
+ "YP: server for domain %s not responding, retrying\n", dom);
+ clnt_destroy(client);
+ ysd->dom_vers = -1;
+ 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;
+ ysd->dom_server_port =
+ *(u_short *)&ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port;
+gotit:
+ ysd->dom_vers = YPVERS;
+ strcpy(ysd->dom_domain, dom);
+ }
+
+ tv.tv_sec = _yplib_timeout/2;
+ tv.tv_usec = 0;
+ if(ysd->dom_client)
+ clnt_destroy(ysd->dom_client);
+ ysd->dom_socket = RPC_ANYSOCK;
+ ysd->dom_client = clntudp_create(&ysd->dom_server_addr,
+ YPPROG, YPVERS, tv, &ysd->dom_socket);
+ 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");
+
+ if(new) {
+ ysd->dom_pnext = _ypbindlist;
+ _ypbindlist = ysd;
+ }
+
+ if(ypdb!=NULL)
+ *ypdb = ysd;
+ return 0;
+}
+
+static void
+_yp_unbind(ypb)
+struct dom_binding *ypb;
+{
+ clnt_destroy(ypb->dom_client);
+ ypb->dom_client = NULL;
+ ypb->dom_socket = -1;
+}
+
+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) {
+ clnt_destroy(ypb->dom_client);
+ 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;
+
+#ifdef YPMATCHCACHE
+ 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;
+
+ yprk.domain = indomain;
+ yprk.map = inmap;
+ yprk.key.keydat_val = (char *)inkey;
+ yprk.key.keydat_len = inkeylen;
+
+ 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");
+ ysd->dom_vers = -1;
+ 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
+ if( strcmp(_yp_domain, indomain)==0 )
+ ypmatch_add(inmap, inkey, inkeylen, *outval, *outvallen);
+#endif
+ }
+ xdr_free(xdr_ypresp_val, (char *)&yprv);
+ _yp_unbind(ysd);
+ 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");
+ ysd->dom_vers = 0;
+ 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);
+ _yp_unbind(ysd);
+ 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");
+ ysd->dom_vers = -1;
+ 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);
+ _yp_unbind(ysd);
+ 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;
+ int clnt_sock;
+
+ /* Sanity check */
+
+ if (indomain == NULL || !strlen(indomain) ||
+ inmap == NULL || !strlen(inmap))
+ return YPERR_BADARGS;
+
+ if( _yp_dobind(indomain, &ysd) != 0)
+ return YPERR_DOMAIN;
+
+ tv.tv_sec = _yplib_timeout;
+ tv.tv_usec = 0;
+ 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;
+
+ (void) clnt_call(clnt, YPPROC_ALL,
+ xdr_ypreq_nokey, &yprnk, xdr_ypresp_all_seq, &status, tv);
+ clnt_destroy(clnt);
+ xdr_free(xdr_ypresp_all_seq, (char *)&status); /* not really needed... */
+ _yp_unbind(ysd);
+
+ if(status != YP_FALSE)
+ return ypprot_err(status);
+ 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);
+ if(r != RPC_SUCCESS) {
+ clnt_perror(ysd->dom_client, "yp_order: clnt_call");
+ ysd->dom_vers = -1;
+ goto again;
+ }
+
+ *outorder = ypro.ordernum;
+ xdr_free(xdr_ypresp_order, (char *)&ypro);
+ _yp_unbind(ysd);
+ return ypprot_err(ypro.stat);
+}
+
+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");
+ ysd->dom_vers = -1;
+ goto again;
+ }
+ if( !(r=ypprot_err(yprm.stat)) ) {
+ *outname = (char *)strdup(yprm.peer);
+ }
+ xdr_free(xdr_ypresp_master, (char *)&yprm);
+ _yp_unbind(ysd);
+ 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");
+ ysd->dom_vers = -1;
+ goto again;
+ }
+ *outmaplist = ypml.maps;
+ /* NO: xdr_free(xdr_ypresp_maplist, &ypml);*/
+ _yp_unbind(ysd);
+ return ypprot_err(ypml.stat);
+}
+
+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;
+}
OpenPOWER on IntegriCloud