aboutsummaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/Makefile8
-rw-r--r--lib/libc/compat-43/creat.23
-rw-r--r--lib/libc/compat-43/sigvec.22
-rw-r--r--lib/libc/db/PORT/Makefile55
-rw-r--r--lib/libc/db/PORT/README60
-rw-r--r--lib/libc/db/PORT/clib/memmove.c139
-rw-r--r--lib/libc/db/PORT/clib/realloc.c11
-rw-r--r--lib/libc/db/PORT/clib/snprintf.c54
-rw-r--r--lib/libc/db/PORT/include/cdefs.h94
-rw-r--r--lib/libc/db/PORT/include/compat.h217
-rw-r--r--lib/libc/db/PORT/include/db.h194
-rw-r--r--lib/libc/db/PORT/include/mpool.h135
l---------lib/libc/db/PORT/sys1
l---------lib/libc/db/README1
-rw-r--r--lib/libc/db/VERSION46
-rw-r--r--lib/libc/db/btree/bt_close.c19
-rw-r--r--lib/libc/db/btree/bt_delete.c10
-rw-r--r--lib/libc/db/btree/bt_get.c22
-rw-r--r--lib/libc/db/btree/bt_open.c38
-rw-r--r--lib/libc/db/btree/bt_put.c29
-rw-r--r--lib/libc/db/btree/bt_search.c152
-rw-r--r--lib/libc/db/btree/bt_seq.c21
-rw-r--r--lib/libc/db/btree/bt_utils.c23
-rw-r--r--lib/libc/db/btree/btree.h33
-rw-r--r--lib/libc/db/btree/extern.h3
-rw-r--r--lib/libc/db/db/db.c29
-rw-r--r--lib/libc/db/doc/btree.3.ps364
-rw-r--r--lib/libc/db/doc/dbopen.3.ps496
-rw-r--r--lib/libc/db/doc/hash.3.ps289
-rw-r--r--lib/libc/db/doc/hash.ps12209
-rw-r--r--lib/libc/db/doc/mpool.3.ps318
-rw-r--r--lib/libc/db/doc/recno.3.ps317
-rw-r--r--lib/libc/db/hash/hash.c21
-rw-r--r--lib/libc/db/hash/hash_page.c19
-rw-r--r--lib/libc/db/hash/hsearch.c4
-rw-r--r--lib/libc/db/hash/ndbm.c4
-rw-r--r--lib/libc/db/man/btree.350
-rw-r--r--lib/libc/db/man/dbopen.335
-rw-r--r--lib/libc/db/man/hash.346
-rw-r--r--lib/libc/db/man/recno.380
-rw-r--r--lib/libc/db/recno/rec_close.c18
-rw-r--r--lib/libc/db/recno/rec_delete.c9
-rw-r--r--lib/libc/db/recno/rec_get.c17
-rw-r--r--lib/libc/db/recno/rec_open.c22
-rw-r--r--lib/libc/db/recno/rec_put.c8
-rw-r--r--lib/libc/db/recno/rec_search.c16
-rw-r--r--lib/libc/db/recno/rec_seq.c15
-rw-r--r--lib/libc/db/recno/rec_utils.c16
-rw-r--r--lib/libc/db/test/Makefile16
-rw-r--r--lib/libc/db/test/dbtest.c56
-rw-r--r--lib/libc/db/test/run.test315
-rw-r--r--lib/libc/db/test/strerror.c67
-rw-r--r--lib/libc/gen/Makefile.inc43
-rw-r--r--lib/libc/gen/alarm.34
-rw-r--r--lib/libc/gen/crypt.c2
-rw-r--r--lib/libc/gen/ctype_.c9
-rw-r--r--lib/libc/gen/directory.32
-rw-r--r--lib/libc/gen/err.311
-rw-r--r--lib/libc/gen/fnmatch.325
-rw-r--r--lib/libc/gen/fnmatch.c85
-rw-r--r--lib/libc/gen/getcap.35
-rw-r--r--lib/libc/gen/getgrent.32
-rw-r--r--lib/libc/gen/getgrent.c87
-rw-r--r--lib/libc/gen/getpwent.c288
-rw-r--r--lib/libc/gen/isctype.c15
-rw-r--r--lib/libc/gen/isupper.32
-rw-r--r--lib/libc/gen/ldexp.32
-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/nlist.32
-rw-r--r--lib/libc/gen/regexp.3315
-rw-r--r--lib/libc/gen/regexp/COPYRIGHT22
-rw-r--r--lib/libc/gen/regexp/README84
-rw-r--r--lib/libc/gen/regexp/regerror.c18
-rw-r--r--lib/libc/gen/regexp/regexp.3315
-rw-r--r--lib/libc/gen/regexp/regexp.c1320
-rw-r--r--lib/libc/gen/regexp/regexp.h21
-rw-r--r--lib/libc/gen/regexp/regmagic.h5
-rw-r--r--lib/libc/gen/regexp/regsub.c81
-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/setmode.c8
-rw-r--r--lib/libc/gen/signal.34
-rw-r--r--lib/libc/gen/tcgetpgrp.379
-rw-r--r--lib/libc/gen/tcsetattr.3330
-rw-r--r--lib/libc/gen/tcsetpgrp.3100
-rw-r--r--lib/libc/gen/timezone.32
-rw-r--r--lib/libc/gen/timezone.c1
-rw-r--r--lib/libc/gen/ualarm.32
-rw-r--r--lib/libc/i386/DEFS.h57
-rw-r--r--lib/libc/i386/SYS.h28
-rw-r--r--lib/libc/i386/gen/_setjmp.S (renamed from lib/libc/i386/gen/_setjmp.s)0
-rw-r--r--lib/libc/i386/gen/alloca.S (renamed from lib/libc/i386/gen/alloca.s)0
-rw-r--r--lib/libc/i386/gen/divsi3.S (renamed from lib/libc/i386/gen/divsi3.s)1
-rw-r--r--lib/libc/i386/gen/fabs.S (renamed from lib/libc/i386/gen/fabs.s)0
-rw-r--r--lib/libc/i386/gen/fixdfsi.S (renamed from lib/libc/i386/gen/fixdfsi.s)1
-rw-r--r--lib/libc/i386/gen/fixunsdfsi.S82
-rw-r--r--lib/libc/i386/gen/fixunsdfsi.s50
-rw-r--r--lib/libc/i386/gen/modf.S (renamed from lib/libc/i386/gen/modf.s)1
-rw-r--r--lib/libc/i386/gen/setjmp.S (renamed from lib/libc/i386/gen/setjmp.s)5
-rw-r--r--lib/libc/i386/gen/sigsetjmp.S (renamed from lib/libc/i386/gen/sigsetjmp.s)9
-rw-r--r--lib/libc/i386/gen/udivsi3.S (renamed from lib/libc/i386/gen/udivsi3.s)1
-rw-r--r--lib/libc/i386/net/htonl.S (renamed from lib/libc/i386/net/htonl.s)0
-rw-r--r--lib/libc/i386/net/htons.S (renamed from lib/libc/i386/net/htons.s)0
-rw-r--r--lib/libc/i386/net/ntohl.S (renamed from lib/libc/i386/net/ntohl.s)0
-rw-r--r--lib/libc/i386/net/ntohs.S (renamed from lib/libc/i386/net/ntohs.s)0
-rw-r--r--lib/libc/i386/stdlib/abs.S (renamed from lib/libc/i386/stdlib/abs.s)0
-rw-r--r--lib/libc/i386/stdlib/div.S (renamed from lib/libc/i386/stdlib/div.s)4
-rw-r--r--lib/libc/i386/stdlib/labs.S (renamed from lib/libc/i386/stdlib/labs.s)0
-rw-r--r--lib/libc/i386/stdlib/ldiv.S (renamed from lib/libc/i386/stdlib/ldiv.s)4
-rw-r--r--lib/libc/i386/string/bcmp.S (renamed from lib/libc/i386/string/bcmp.s)4
-rw-r--r--lib/libc/i386/string/bcopy.S (renamed from lib/libc/i386/string/bcopy.s)4
-rw-r--r--lib/libc/i386/string/bzero.S (renamed from lib/libc/i386/string/bzero.s)4
-rw-r--r--lib/libc/i386/string/ffs.S (renamed from lib/libc/i386/string/ffs.s)4
-rw-r--r--lib/libc/i386/string/index.S (renamed from lib/libc/i386/string/index.s)4
-rw-r--r--lib/libc/i386/string/memchr.S (renamed from lib/libc/i386/string/memchr.s)4
-rw-r--r--lib/libc/i386/string/memcmp.S (renamed from lib/libc/i386/string/memcmp.s)8
-rw-r--r--lib/libc/i386/string/memmove.S (renamed from lib/libc/i386/string/memmove.s)4
-rw-r--r--lib/libc/i386/string/memset.S (renamed from lib/libc/i386/string/memset.s)4
-rw-r--r--lib/libc/i386/string/rindex.S (renamed from lib/libc/i386/string/rindex.s)4
-rw-r--r--lib/libc/i386/string/strcat.S (renamed from lib/libc/i386/string/strcat.s)4
-rw-r--r--lib/libc/i386/string/strchr.S (renamed from lib/libc/i386/string/strchr.s)4
-rw-r--r--lib/libc/i386/string/strcmp.S (renamed from lib/libc/i386/string/strcmp.s)8
-rw-r--r--lib/libc/i386/string/strcpy.S (renamed from lib/libc/i386/string/strcpy.s)4
-rw-r--r--lib/libc/i386/string/strlen.S (renamed from lib/libc/i386/string/strlen.s)4
-rw-r--r--lib/libc/i386/string/strncmp.S (renamed from lib/libc/i386/string/strncmp.s)8
-rw-r--r--lib/libc/i386/string/strrchr.S (renamed from lib/libc/i386/string/strrchr.s)4
-rw-r--r--lib/libc/i386/sys/Makefile.inc10
-rw-r--r--lib/libc/i386/sys/Ovfork.S (renamed from lib/libc/i386/sys/Ovfork.s)10
-rw-r--r--lib/libc/i386/sys/brk.S (renamed from lib/libc/i386/sys/brk.s)26
-rw-r--r--lib/libc/i386/sys/cerror.S (renamed from lib/libc/i386/sys/cerror.s)9
-rw-r--r--lib/libc/i386/sys/exect.S (renamed from lib/libc/i386/sys/exect.s)2
-rw-r--r--lib/libc/i386/sys/fork.S (renamed from lib/libc/i386/sys/fork.s)2
-rw-r--r--lib/libc/i386/sys/i386_get_ldt.298
-rw-r--r--lib/libc/i386/sys/i386_get_ldt.c50
-rw-r--r--lib/libc/i386/sys/i386_set_ldt.c50
-rw-r--r--lib/libc/i386/sys/mount.S (renamed from lib/libc/i386/sys/mount.s)2
-rw-r--r--lib/libc/i386/sys/pipe.S (renamed from lib/libc/i386/sys/pipe.s)2
-rw-r--r--lib/libc/i386/sys/ptrace.S (renamed from lib/libc/i386/sys/ptrace.s)11
-rw-r--r--lib/libc/i386/sys/reboot.S (renamed from lib/libc/i386/sys/reboot.s)2
-rw-r--r--lib/libc/i386/sys/sbrk.S (renamed from lib/libc/i386/sys/sbrk.s)24
-rw-r--r--lib/libc/i386/sys/setlogin.S (renamed from lib/libc/i386/sys/setlogin.s)11
-rw-r--r--lib/libc/i386/sys/sigpending.S (renamed from lib/libc/i386/sys/sigpending.s)2
-rw-r--r--lib/libc/i386/sys/sigprocmask.S (renamed from lib/libc/i386/sys/sigprocmask.s)2
-rw-r--r--lib/libc/i386/sys/sigreturn.S (renamed from lib/libc/i386/sys/sigreturn.s)2
-rw-r--r--lib/libc/i386/sys/sigsuspend.S (renamed from lib/libc/i386/sys/sigsuspend.s)0
-rw-r--r--lib/libc/i386/sys/syscall.S (renamed from lib/libc/i386/sys/syscall.s)2
-rw-r--r--lib/libc/net/Makefile.inc2
-rw-r--r--lib/libc/net/gethostbyname.32
-rw-r--r--lib/libc/quad/Makefile.inc10
-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.h112
-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/Makefile.inc13
-rw-r--r--lib/libc/regex/WHATSNEW72
-rw-r--r--lib/libc/regex/cclass.h70
-rw-r--r--lib/libc/regex/cname.h141
-rw-r--r--lib/libc/regex/engine.c1075
-rw-r--r--lib/libc/regex/regcomp.c1653
-rw-r--r--lib/libc/regex/regerror.c171
-rw-r--r--lib/libc/regex/regex.3502
-rw-r--r--lib/libc/regex/regex.7231
-rw-r--r--lib/libc/regex/regex.h108
-rw-r--r--lib/libc/regex/regex2.h173
-rw-r--r--lib/libc/regex/regexec.c182
-rw-r--r--lib/libc/regex/regfree.c (renamed from lib/libc/db/PORT/include/ndbm.h)71
-rw-r--r--lib/libc/regex/tests448
-rw-r--r--lib/libc/regex/utils.h50
-rw-r--r--lib/libc/rpc/DISCLAIMER28
-rw-r--r--lib/libc/rpc/Makefile.inc39
-rw-r--r--lib/libc/rpc/README233
-rw-r--r--lib/libc/rpc/auth.h178
-rw-r--r--lib/libc/rpc/auth_none.c135
-rw-r--r--lib/libc/rpc/auth_unix.c322
-rw-r--r--lib/libc/rpc/auth_unix.h82
-rw-r--r--lib/libc/rpc/authunix_prot.c68
-rw-r--r--lib/libc/rpc/bindresvport.327
-rw-r--r--lib/libc/rpc/bindresvport.c84
-rw-r--r--lib/libc/rpc/clnt.h358
-rw-r--r--lib/libc/rpc/clnt_generic.c113
-rw-r--r--lib/libc/rpc/clnt_perror.c303
-rw-r--r--lib/libc/rpc/clnt_raw.c240
-rw-r--r--lib/libc/rpc/clnt_simple.c115
-rw-r--r--lib/libc/rpc/clnt_tcp.c468
-rw-r--r--lib/libc/rpc/clnt_udp.c444
-rw-r--r--lib/libc/rpc/get_myaddress.c99
-rw-r--r--lib/libc/rpc/getrpcent.3109
-rw-r--r--lib/libc/rpc/getrpcent.c298
-rw-r--r--lib/libc/rpc/getrpcport.331
-rw-r--r--lib/libc/rpc/getrpcport.c57
-rw-r--r--lib/libc/rpc/pmap_clnt.c117
-rw-r--r--lib/libc/rpc/pmap_clnt.h84
-rw-r--r--lib/libc/rpc/pmap_getmaps.c86
-rw-r--r--lib/libc/rpc/pmap_getport.c89
-rw-r--r--lib/libc/rpc/pmap_prot.c59
-rw-r--r--lib/libc/rpc/pmap_prot.h104
-rw-r--r--lib/libc/rpc/pmap_prot2.c118
-rw-r--r--lib/libc/rpc/pmap_rmt.c397
-rw-r--r--lib/libc/rpc/pmap_rmt.h63
-rw-r--r--lib/libc/rpc/rpc.31729
-rw-r--r--lib/libc/rpc/rpc.571
-rw-r--r--lib/libc/rpc/rpc.h89
-rw-r--r--lib/libc/rpc/rpc_callmsg.c192
-rw-r--r--lib/libc/rpc/rpc_commondata.c46
-rw-r--r--lib/libc/rpc/rpc_dtablesize.c48
-rw-r--r--lib/libc/rpc/rpc_msg.h195
-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.c481
-rw-r--r--lib/libc/rpc/svc.h302
-rw-r--r--lib/libc/rpc/svc_auth.c117
-rw-r--r--lib/libc/rpc/svc_auth.h50
-rw-r--r--lib/libc/rpc/svc_auth_unix.c136
-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.c145
-rw-r--r--lib/libc/rpc/svc_tcp.c421
-rw-r--r--lib/libc/rpc/svc_udp.c480
-rw-r--r--lib/libc/rpc/types.h66
-rw-r--r--lib/libc/rpc/xdr.3823
-rw-r--r--lib/libc/rpc/xdr.c578
-rw-r--r--lib/libc/rpc/xdr.h291
-rw-r--r--lib/libc/rpc/xdr_array.c155
-rw-r--r--lib/libc/rpc/xdr_float.c283
-rw-r--r--lib/libc/rpc/xdr_mem.c186
-rw-r--r--lib/libc/rpc/xdr_rec.c586
-rw-r--r--lib/libc/rpc/xdr_reference.c134
-rw-r--r--lib/libc/rpc/xdr_stdio.c191
-rw-r--r--lib/libc/stdio/ferror.32
-rw-r--r--lib/libc/stdio/fgets.32
-rw-r--r--lib/libc/stdio/setvbuf.c5
-rw-r--r--lib/libc/stdio/stdio.32
-rw-r--r--lib/libc/stdio/strerror.34
-rw-r--r--lib/libc/stdio/tempnam.c22
-rw-r--r--lib/libc/stdio/vfprintf.c58
-rw-r--r--lib/libc/stdlib/Makefile.inc6
-rw-r--r--lib/libc/stdlib/bsearch.32
-rw-r--r--lib/libc/stdlib/exit.c2
-rw-r--r--lib/libc/stdlib/getopt.3164
-rw-r--r--lib/libc/stdlib/getopt.c44
-rw-r--r--lib/libc/stdlib/rand48.33
-rw-r--r--lib/libc/stdlib/random.32
-rw-r--r--lib/libc/stdlib/realloc.32
-rw-r--r--lib/libc/stdlib/setenv.c3
-rw-r--r--lib/libc/stdlib/strtol.c2
-rw-r--r--lib/libc/stdlib/strtoq.c136
-rw-r--r--lib/libc/stdlib/strtoul.c2
-rw-r--r--lib/libc/stdlib/strtouq.c (renamed from lib/libc/db/PORT/clib/mktemp.c)148
-rw-r--r--lib/libc/string/Makefile.inc16
-rw-r--r--lib/libc/string/bzero.32
-rw-r--r--lib/libc/string/ffs.32
-rw-r--r--lib/libc/string/strchr.32
-rw-r--r--lib/libc/string/strsep.32
-rw-r--r--lib/libc/sys/Makefile.inc68
-rw-r--r--lib/libc/sys/accept.22
-rw-r--r--lib/libc/sys/acct.23
-rw-r--r--lib/libc/sys/brk.212
-rw-r--r--lib/libc/sys/chown.22
-rw-r--r--lib/libc/sys/close.24
-rw-r--r--lib/libc/sys/execve.225
-rw-r--r--lib/libc/sys/fork.23
-rw-r--r--lib/libc/sys/getsockopt.22
-rw-r--r--lib/libc/sys/intro.24
-rw-r--r--lib/libc/sys/ioctl.23
-rw-r--r--lib/libc/sys/kill.22
-rw-r--r--lib/libc/sys/ktrace.266
-rw-r--r--lib/libc/sys/lseek.24
-rw-r--r--lib/libc/sys/mknod.23
-rw-r--r--lib/libc/sys/mount.23
-rw-r--r--lib/libc/sys/open.23
-rw-r--r--lib/libc/sys/pipe.23
-rw-r--r--lib/libc/sys/read.22
-rw-r--r--lib/libc/sys/setpgid.22
-rw-r--r--lib/libc/sys/setregid.250
-rw-r--r--lib/libc/sys/setreuid.245
-rw-r--r--lib/libc/sys/setsid.267
-rw-r--r--lib/libc/sys/sigaction.22
-rw-r--r--lib/libc/sys/sigsuspend.22
-rw-r--r--lib/libc/sys/socket.24
-rw-r--r--lib/libc/sys/stat.24
-rw-r--r--lib/libc/sys/statfs.25
-rw-r--r--lib/libc/sys/sync.23
-rw-r--r--lib/libc/sys/uname.230
-rw-r--r--lib/libc/sys/unlink.23
-rw-r--r--lib/libc/sys/wait.27
-rw-r--r--lib/libc/sys/write.22
-rw-r--r--lib/libc/yp/Makefile.inc8
-rw-r--r--lib/libc/yp/xdryp.c394
-rw-r--r--lib/libc/yp/yplib.c794
321 files changed, 25149 insertions, 18093 deletions
diff --git a/lib/libc/Makefile b/lib/libc/Makefile
index 281f23054cf2..319a528c5a54 100644
--- a/lib/libc/Makefile
+++ b/lib/libc/Makefile
@@ -6,17 +6,23 @@
# from CFLAGS below. To remove these strings from just the system call
# stubs, remove just -DSYSLIBC_SCCS from CFLAGS.
LIB=c
-CFLAGS+=-DLIBC_SCCS -DSYSLIBC_SCCS
+CFLAGS+= -DYP -DLIBC_SCCS -DSYSLIBC_SCCS
AINC= -I${.CURDIR}/${MACHINE}
+INSTALL_PIC_ARCHIVE=
.include "${.CURDIR}/compat-43/Makefile.inc"
.include "${.CURDIR}/db/Makefile.inc"
.include "${.CURDIR}/gen/Makefile.inc"
.include "${.CURDIR}/locale/Makefile.inc"
.include "${.CURDIR}/net/Makefile.inc"
+.include "${.CURDIR}/quad/Makefile.inc"
.include "${.CURDIR}/stdio/Makefile.inc"
.include "${.CURDIR}/stdlib/Makefile.inc"
.include "${.CURDIR}/string/Makefile.inc"
.include "${.CURDIR}/sys/Makefile.inc"
+.include "${.CURDIR}/rpc/Makefile.inc"
+.include "${.CURDIR}/regex/Makefile.inc"
+.include "${.CURDIR}/yp/Makefile.inc"
+.include "${.CURDIR}/${MACHINE}/sys/Makefile.inc"
.include <bsd.lib.mk>
diff --git a/lib/libc/compat-43/creat.2 b/lib/libc/compat-43/creat.2
index d1e1226bf2ef..23670785e397 100644
--- a/lib/libc/compat-43/creat.2
+++ b/lib/libc/compat-43/creat.2
@@ -55,4 +55,5 @@ open(path, O_CREAT | O_TRUNC | O_WRONLY, mode);
.Sh HISTORY
The
.Nm
-function call appeared in Version 6 AT&T UNIX.
+function call appeared in
+.At v6 .
diff --git a/lib/libc/compat-43/sigvec.2 b/lib/libc/compat-43/sigvec.2
index dc4ce5c4c58b..38c9537b09da 100644
--- a/lib/libc/compat-43/sigvec.2
+++ b/lib/libc/compat-43/sigvec.2
@@ -53,7 +53,7 @@ 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 occurence of a hardware interrupt:
+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
diff --git a/lib/libc/db/PORT/Makefile b/lib/libc/db/PORT/Makefile
deleted file mode 100644
index 9b0b56b4bf56..000000000000
--- a/lib/libc/db/PORT/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-# @(#)Makefile 8.1 (Berkeley) 6/2/93
-
-LIBDB= libdb.a
-OBJ1= bt_close.o bt_conv.o bt_debug.o bt_delete.o bt_get.o bt_open.o \
- bt_overflow.o bt_page.o bt_put.o bt_search.o bt_seq.o bt_split.o \
- bt_stack.o bt_utils.o
-OBJ2= db.o
-OBJ3= hash.o hash_bigkey.o hash_buf.o hash_func.o hash_log2.o hash_page.o \
- hsearch.o ndbm.o
-OBJ4= mpool.o
-OBJ5= rec_close.o rec_delete.o rec_get.o rec_open.o rec_put.o rec_search.o \
- rec_seq.o rec_utils.o
-
-# If you don't have memmove(3), add memmove.o to the MISC line.
-#
-# If you don't have mktemp(3) or mkstemp(3), add mktemp.o to the MISC line.
-#
-# If realloc(3) of a NULL pointer on your system isn't the same as
-# a malloc(3) call, add realloc.o to the MISC line.
-#
-# If you don't have snprintf/vsnprintf(3), add snprintf.o to the MISC line.
-# Note, this depends you your having vsprintf(3) -- if you don't, there's
-# no workaround other than changing the source code to not use the snprintf
-# calls. If you have to make that change, check to see if your vsprintf
-# returns a length or a char *; if it's the latter, set VSPRINTF_CHARSTAR
-# in the include/compat.h file.
-MISC=
-
-${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC}
- ar cq $@ \
- `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort`
- ranlib $@
-
-${OBJ1}:
- ${CC} -c -O -I. -Iinclude -I../btree ../btree/*.c
-${OBJ2}:
- ${CC} -c -O -I. -Iinclude -I../db ../db/*.c
-${OBJ3}:
- ${CC} -c -O -I. -Iinclude -I../hash ../hash/*.c
-${OBJ4}:
- ${CC} -c -O -I. -Iinclude -I../mpool ../mpool/*.c
-${OBJ5}:
- ${CC} -c -O -I. -Iinclude -I../recno ../recno/*.c
-
-memmove.o:
- ${CC} -DMEMMOVE -c -O -I. -Iinclude clib/memmove.c
-mktemp.o:
- ${CC} -c -O -I. -Iinclude clib/mktemp.c
-realloc.o:
- ${CC} -c -O -I. -Iinclude clib/realloc.c
-snprintf.o:
- ${CC} -c -O -I. -Iinclude clib/snprintf.c
-
-clean:
- rm -f ${LIBDB} ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC}
diff --git a/lib/libc/db/PORT/README b/lib/libc/db/PORT/README
deleted file mode 100644
index cbe7f1136241..000000000000
--- a/lib/libc/db/PORT/README
+++ /dev/null
@@ -1,60 +0,0 @@
-# @(#)README 8.1 (Berkeley) 6/2/93
-
-This is the directory to use for creating a library of the dbopen(3)
-routines. The Makefile builds the base system. By changing it and
-the compat.h file, you should be able to pick and choose the various
-things your system needs to make libdb run.
-
-The knobs that you may have to turn:
-
-In the Makefile:
- If you don't have mktemp(3) or mkstemp(3) on your system, add
- "mktemp.o" to the MISC list.
-
- If you don't have snprintf(3) on your system, add snprintf.o
- to the MISC list.
-
- If you don't have memmove(3), add memmove.o to the MISC list.
-
-In include/compat.h:
- Before attempting to build this library, you should skim through
- the compat.h file, and adjust it as necessary for your system.
- It's possible to use the #ifndef construct to figure out if a
- #ifdef has been set, but C provides no similar method to figure
- out if a typedef has been done. All of the typedef's are grouped
- at the top of compat.h, your compile errors will tell you which
- ones you need.
-
- Particularly subtle problems can occur if you don't have the
- BYTE_ORDER set right or if the realloc define is wrong.
-
-Some other problems:
- You may see warning messages about illegal pointer combinations.
- It's because systems prototype malloc, calloc and realloc in
- different places. If you want to stop the warnings, find out
- where your system prototypes them, and include it in compat.h,
- or, just prototype them yourself.
-
-To install:
- Programs using the dbopen(3) interface have to include db.h.
- To install the library, you'll need to put db.h (found in the
- directory PORT/include) and the library libdb.a in some place
- accesible to your program.
-
-Hints:
- SunOS 4.1.2 works with ``MISC=realloc.o snprintf.o memmove.o''
- and the include/compat.h realloc ``#if 0'' changed to ``#if 1''.
- SunOS gives a bunch of warning messages on the malloc family
- routines.
-
- Ultrix 4.2A works with ``MISC=realloc.o snprintf.o memmove.o''
- and the include/compat.h realloc ``#if 0'' changed to ``#if 1''
- and BYTE_ORDER changed from BIG_ENDIAN to LITTLE_ENDIAN.
- Ultrix does not give warning messages on the malloc family
- routines.
-
- The recno routines require the mmap(2) call. It wouldn't be
- difficult to port this package to a system without mmap. Change
- rec_open.c to do slightly different initialization and to write
- two new routines for rec_get.c that handle regular files using
- reads and writes.
diff --git a/lib/libc/db/PORT/clib/memmove.c b/lib/libc/db/PORT/clib/memmove.c
deleted file mode 100644
index f90b09c9b73f..000000000000
--- a/lib/libc/db/PORT/clib/memmove.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*-
- * 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/db/PORT/clib/realloc.c b/lib/libc/db/PORT/clib/realloc.c
deleted file mode 100644
index 11e5cd28c5da..000000000000
--- a/lib/libc/db/PORT/clib/realloc.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <sys/types.h>
-
-#include <stdlib.h>
-
-void *
-__fix_realloc(p, n)
- void *p;
- size_t n;
-{
- return (p == 0 ? malloc(n) : realloc(p, n));
-}
diff --git a/lib/libc/db/PORT/clib/snprintf.c b/lib/libc/db/PORT/clib/snprintf.c
deleted file mode 100644
index 2863fa28d62b..000000000000
--- a/lib/libc/db/PORT/clib/snprintf.c
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <sys/types.h>
-#include <sys/cdefs.h>
-
-#include <compat.h>
-
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-int
-#ifdef __STDC__
-snprintf(char *str, size_t n, const char *fmt, ...)
-#else
-snprintf(str, n, fmt, va_alist)
- char *str;
- size_t n;
- const char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
- char *rp;
- int rval;
-#ifdef __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
-#ifdef VSPRINTF_CHARSTAR
- rp = vsprintf(str, fmt, ap);
- va_end(ap);
- return (strlen(rp));
-#else
- rval = vsprintf(str, fmt, ap);
- va_end(ap);
- return (rval);
-#endif
-}
-
-int
-vsnprintf(str, n, fmt, ap)
- char *str;
- size_t n;
- const char *fmt;
- va_list ap;
-{
-#ifdef VSPRINTF_CHARSTAR
- return (strlen(vsprintf(str, fmt, ap)));
-#else
- return (vsprintf(str, fmt, ap));
-#endif
-}
diff --git a/lib/libc/db/PORT/include/cdefs.h b/lib/libc/db/PORT/include/cdefs.h
deleted file mode 100644
index a04665e30e49..000000000000
--- a/lib/libc/db/PORT/include/cdefs.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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.
- *
- * @(#)cdefs.h 8.1 (Berkeley) 6/2/93
- */
-
-#ifndef _CDEFS_H_
-#define _CDEFS_H_
-
-#if defined(__cplusplus)
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS };
-#else
-#define __BEGIN_DECLS
-#define __END_DECLS
-#endif
-
-/*
- * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
- * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
- * The __CONCAT macro is a bit tricky -- make sure you don't put spaces
- * in between its arguments. __CONCAT can also concatenate double-quoted
- * strings produced by the __STRING macro, but this only works with ANSI C.
- */
-#if defined(__STDC__) || defined(__cplusplus)
-#define __P(protos) protos /* full-blown ANSI C */
-#define __CONCAT(x,y) x ## y
-#define __STRING(x) #x
-
-#else /* !(__STDC__ || __cplusplus) */
-#define __P(protos) () /* traditional C preprocessor */
-#define __CONCAT(x,y) x/**/y
-#define __STRING(x) "x"
-
-#ifdef __GNUC__
-#define const __const /* GCC: ANSI C with -traditional */
-#define inline __inline
-#define signed __signed
-#define volatile __volatile
-
-#else /* !__GNUC__ */
-#define const /* delete ANSI C keywords */
-#define inline
-#define signed
-#define volatile
-#endif /* !__GNUC__ */
-#endif /* !(__STDC__ || __cplusplus) */
-
-/*
- * GCC has extensions for declaring functions as `pure' (always returns
- * the same value given the same inputs, i.e., has no external state and
- * no side effects) and `dead' (nonreturning). These mainly affect
- * optimization and warnings. Unfortunately, GCC complains if these are
- * used under strict ANSI mode (`gcc -ansi -pedantic'), hence we need to
- * define them only if compiling without this.
- */
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-#define __dead __volatile
-#define __pure __const
-#else
-#define __dead
-#define __pure
-#endif
-
-#endif /* !_CDEFS_H_ */
diff --git a/lib/libc/db/PORT/include/compat.h b/lib/libc/db/PORT/include/compat.h
deleted file mode 100644
index bb3f91466731..000000000000
--- a/lib/libc/db/PORT/include/compat.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*-
- * 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.
- *
- * @(#)compat.h 8.1 (Berkeley) 6/2/93
- */
-
-#ifndef _COMPAT_H_
-#define _COMPAT_H_
-
-/*
- * If your system doesn't typedef u_long, u_short, or u_char, change
- * the 0 to a 1.
- */
-#if 0
-typedef unsigned long u_long;
-typedef unsigned short u_short;
-typedef unsigned char u_char;
-#endif
-
-/* If your system doesn't typedef size_t, change the 0 to a 1. */
-#if 0
-typedef unsigned int size_t;
-#define SIZE_T_MAX UINT_MAX
-#endif
-
-/*
- * If your system doesn't specify a max size for a SIZE_T, check
- * to make sure this is the right one.
- */
-#ifndef SIZE_T_MAX
-#define SIZE_T_MAX UINT_MAX
-#endif
-
-/*
- * If your system doesn't have the POSIX type for a signal mask,
- * change the 0 to a 1.
- */
-#if 0
-typedef unsigned int sigset_t;
-#endif
-
-/*
- * If your system's vsprintf returns a char *, not an int,
- * change the 0 to a 1.
- */
-#if 0
-#define VSPRINTF_CHARSTAR
-#endif
-
-/*
- * If you don't have POSIX 1003.1 signals, the signal code surrounding the
- * temporary file creation is intended to block all of the possible signals
- * long enough to create the file and unlink it. All of this stuff is
- * intended to use old-style BSD calls to fake POSIX 1003.1 calls.
- */
-#ifdef NO_POSIX_SIGNALS
-#define sigemptyset(set) (*(set) = 0)
-#define sigfillset(set) (*(set) = ~(sigset_t)0, 0)
-#define sigaddset(set,signo) (*(set) |= sigmask(signo), 0)
-#define sigdelset(set,signo) (*(set) &= ~sigmask(signo), 0)
-#define sigismember(set,signo) ((*(set) & sigmask(signo)) != 0)
-
-#define SIG_BLOCK 1
-#define SIG_UNBLOCK 2
-#define SIG_SETMASK 3
-
-static int __sigtemp; /* For the use of sigprocmask */
-
-#define sigprocmask(how,set,oset) \
- ((__sigtemp = (((how) == SIG_BLOCK) ? \
- sigblock(0) | *(set) : (((how) == SIG_UNBLOCK) ? \
- sigblock(0) & ~(*(set)) : ((how) == SIG_SETMASK ? \
- *(set) : sigblock(0))))), ((oset) ? \
- (*(oset) = sigsetmask(__sigtemp)) : sigsetmask(__sigtemp)), 0)
-#endif
-
-/*
- * If realloc(3) of a NULL pointer on your system isn't the same as
- * a malloc(3) call, change the 0 to a 1, and add realloc.o to the
- * MISC line in your Makefile.
- */
-#if 0
-#define realloc __fix_realloc
-#endif
-
-/*
- * If your system doesn't have an include file with the appropriate
- * byte order set, make sure you specify the correct one.
- */
-#ifndef BYTE_ORDER
-#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
-#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */
-#define BYTE_ORDER BIG_ENDIAN /* Set for your system. */
-#endif
-
-#if defined(SYSV) || defined(SYSTEM5)
-#define index(a, b) strchr(a, b)
-#define rindex(a, b) strrchr(a, b)
-#define bzero(a, b) memset(a, 0, b)
-#define bcmp(a, b, n) memcmp(a, b, n)
-#define bcopy(a, b, n) memmove(b, a, n)
-#endif
-
-#if defined(BSD) || defined(BSD4_3)
-#define strchr(a, b) index(a, b)
-#define strrchr(a, b) rindex(a, b)
-#define memcmp(a, b, n) bcmp(a, b, n)
-#define memmove(a, b, n) bcopy(b, a, n)
-#endif
-
-/*
- * 32-bit machine. The db routines are theoretically independent of
- * the size of u_shorts and u_longs, but I don't know that anyone has
- * ever actually tried it. At a minimum, change the following #define's
- * if you are trying to compile on a different type of system.
- */
-#ifndef USHRT_MAX
-#define USHRT_MAX 0xFFFF
-#define ULONG_MAX 0xFFFFFFFF
-#endif
-
-/* POSIX 1003.1 access mode mask. */
-#ifndef O_ACCMODE
-#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
-#endif
-
-/* POSIX 1003.2 RE limit. */
-#ifndef _POSIX2_RE_DUP_MAX
-#define _POSIX2_RE_DUP_MAX 255
-#endif
-
-/*
- * If you can't provide lock values in the open(2) call. Note, this
- * allows races to happen.
- */
-#ifndef O_EXLOCK
-#define O_EXLOCK 0
-#endif
-
-#ifndef O_SHLOCK
-#define O_SHLOCK 0
-#endif
-
-#ifndef EFTYPE
-#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */
-#endif
-
-#ifndef WCOREDUMP /* 4.4BSD extension */
-#define WCOREDUMP(a) 0
-#endif
-
-#ifndef STDERR_FILENO
-#define STDIN_FILENO 0 /* ANSI C #defines */
-#define STDOUT_FILENO 1
-#define STDERR_FILENO 2
-#endif
-
-#ifndef SEEK_END
-#define SEEK_SET 0 /* POSIX 1003.1 seek values */
-#define SEEK_CUR 1
-#define SEEK_END 2
-#endif
-
-#ifndef S_ISLNK /* BSD POSIX 1003.1 extensions */
-#define S_ISLNK(m) ((m & 0170000) == 0120000)
-#define S_ISSOCK(m) ((m & 0170000) == 0140000)
-#endif
-
-#ifndef _POSIX2_RE_DUP_MAX
-#define _POSIX2_RE_DUP_MAX 255
-#endif
-
-#ifndef NULL /* ANSI C #defines NULL everywhere. */
-#define NULL 0
-#endif
-
-#ifndef MAX
-#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a))
-#endif
-#ifndef MIN
-#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b))
-#endif
-
-#ifndef _BSD_VA_LIST_
-#define _BSD_VA_LIST_ char *
-#endif
-
-#endif /* !_COMPAT_H_ */
diff --git a/lib/libc/db/PORT/include/db.h b/lib/libc/db/PORT/include/db.h
deleted file mode 100644
index 2b7de273a517..000000000000
--- a/lib/libc/db/PORT/include/db.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*-
- * 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.
- *
- * @(#)db.h 8.1 (Berkeley) 6/2/93
- */
-
-#ifndef _DB_H_
-#define _DB_H_
-
-#include <sys/types.h>
-#include <sys/cdefs.h>
-#include <machine/endian.h>
-
-#define RET_ERROR -1 /* Return values. */
-#define RET_SUCCESS 0
-#define RET_SPECIAL 1
-
-#define MAX_PAGE_NUMBER ULONG_MAX /* >= # of pages in a file */
-typedef u_long pgno_t;
-#define MAX_PAGE_OFFSET USHRT_MAX /* >= # of bytes in a page */
-typedef u_short indx_t;
-#define MAX_REC_NUMBER ULONG_MAX /* >= # of records in a tree */
-typedef u_long recno_t;
-
-/* Key/data structure -- a Data-Base Thang. */
-typedef struct {
- void *data; /* data */
- size_t size; /* data length */
-} DBT;
-
-/* Routine flags. */
-#define R_CURSOR 1 /* del, put, seq */
-#define __R_UNUSED 2 /* UNUSED */
-#define R_FIRST 3 /* seq */
-#define R_IAFTER 4 /* put (RECNO) */
-#define R_IBEFORE 5 /* put (RECNO) */
-#define R_LAST 6 /* seq (BTREE, RECNO) */
-#define R_NEXT 7 /* seq */
-#define R_NOOVERWRITE 8 /* put */
-#define R_PREV 9 /* seq (BTREE, RECNO) */
-#define R_SETCURSOR 10 /* put (RECNO) */
-#define R_RECNOSYNC 11 /* sync (RECNO) */
-
-typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
-
-#define __USE_OPEN_FLAGS \
- (O_CREAT|O_EXCL|O_EXLOCK|O_RDONLY|O_RDWR|O_SHLOCK|O_TRUNC)
-
-/* Access method description structure. */
-typedef struct __db {
- DBTYPE type; /* underlying db type */
- int (*close) __P((struct __db *));
- int (*del) __P((const struct __db *, const DBT *, u_int));
- int (*fd) __P((const struct __db *));
- int (*get) __P((const struct __db *, const DBT *, DBT *, u_int));
- int (*put) __P((const struct __db *, DBT *, const DBT *, u_int));
- int (*seq) __P((const struct __db *, DBT *, DBT *, u_int));
- int (*sync) __P((const struct __db *, u_int));
- void *internal; /* access method private */
-} DB;
-
-#define BTREEMAGIC 0x053162
-#define BTREEVERSION 3
-
-/* Structure used to pass parameters to the btree routines. */
-typedef struct {
-#define R_DUP 0x01 /* duplicate keys */
- u_long flags;
- int cachesize; /* bytes to cache */
- int maxkeypage; /* maximum keys per page */
- int minkeypage; /* minimum keys per page */
- int psize; /* page size */
- /* comparison, prefix functions */
- int (*compare) __P((const DBT *, const DBT *));
- int (*prefix) __P((const DBT *, const DBT *));
- int lorder; /* byte order */
-} BTREEINFO;
-
-#define HASHMAGIC 0x061561
-#define HASHVERSION 2
-
-/* Structure used to pass parameters to the hashing routines. */
-typedef struct {
- int bsize; /* bucket size */
- int ffactor; /* fill factor */
- int nelem; /* number of elements */
- int cachesize; /* bytes to cache */
- /* hash function */
- int (*hash) __P((const void *, size_t));
- int lorder; /* byte order */
-} HASHINFO;
-
-/* Structure used to pass parameters to the record routines. */
-typedef struct {
-#define R_FIXEDLEN 0x01 /* fixed-length records */
-#define R_NOKEY 0x02 /* key not required */
-#define R_SNAPSHOT 0x04 /* snapshot the input */
- u_long flags;
- int cachesize; /* bytes to cache */
- int psize; /* page size */
- int lorder; /* byte order */
- size_t reclen; /* record length (fixed-length records) */
- u_char bval; /* delimiting byte (variable-length records */
- char *bfname; /* btree file name */
-} RECNOINFO;
-
-/*
- * Little endian <==> big endian long swap macros.
- * BLSWAP swap a memory location
- * BLPSWAP swap a referenced memory location
- * BLSWAP_COPY swap from one location to another
- */
-#define BLSWAP(a) { \
- u_long _tmp = a; \
- ((char *)&a)[0] = ((char *)&_tmp)[3]; \
- ((char *)&a)[1] = ((char *)&_tmp)[2]; \
- ((char *)&a)[2] = ((char *)&_tmp)[1]; \
- ((char *)&a)[3] = ((char *)&_tmp)[0]; \
-}
-#define BLPSWAP(a) { \
- u_long _tmp = *(u_long *)a; \
- ((char *)a)[0] = ((char *)&_tmp)[3]; \
- ((char *)a)[1] = ((char *)&_tmp)[2]; \
- ((char *)a)[2] = ((char *)&_tmp)[1]; \
- ((char *)a)[3] = ((char *)&_tmp)[0]; \
-}
-#define BLSWAP_COPY(a, b) { \
- ((char *)&(b))[0] = ((char *)&(a))[3]; \
- ((char *)&(b))[1] = ((char *)&(a))[2]; \
- ((char *)&(b))[2] = ((char *)&(a))[1]; \
- ((char *)&(b))[3] = ((char *)&(a))[0]; \
-}
-
-/*
- * Little endian <==> big endian short swap macros.
- * BSSWAP swap a memory location
- * BSPSWAP swap a referenced memory location
- * BSSWAP_COPY swap from one location to another
- */
-#define BSSWAP(a) { \
- u_short _tmp = a; \
- ((char *)&a)[0] = ((char *)&_tmp)[1]; \
- ((char *)&a)[1] = ((char *)&_tmp)[0]; \
-}
-#define BSPSWAP(a) { \
- u_short _tmp = *(u_short *)a; \
- ((char *)a)[0] = ((char *)&_tmp)[1]; \
- ((char *)a)[1] = ((char *)&_tmp)[0]; \
-}
-#define BSSWAP_COPY(a, b) { \
- ((char *)&(b))[0] = ((char *)&(a))[1]; \
- ((char *)&(b))[1] = ((char *)&(a))[0]; \
-}
-
-__BEGIN_DECLS
-DB *dbopen __P((const char *, int, int, DBTYPE, const void *));
-
-#ifdef __DBINTERFACE_PRIVATE
-DB *__bt_open __P((const char *, int, int, const BTREEINFO *));
-DB *__hash_open __P((const char *, int, int, const HASHINFO *));
-DB *__rec_open __P((const char *, int, int, const RECNOINFO *));
-void __dbpanic __P((DB *dbp));
-#endif
-__END_DECLS
-#endif /* !_DB_H_ */
diff --git a/lib/libc/db/PORT/include/mpool.h b/lib/libc/db/PORT/include/mpool.h
deleted file mode 100644
index 910e0782aa9d..000000000000
--- a/lib/libc/db/PORT/include/mpool.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*-
- * 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.
- *
- * @(#)mpool.h 8.1 (Berkeley) 6/2/93
- */
-
-/*
- * The memory pool scheme is a simple one. Each in memory page is referenced
- * by a bucket which is threaded in three ways. All active pages are threaded
- * on a hash chain (hashed by the page number) and an lru chain. Inactive
- * pages are threaded on a free chain. Each reference to a memory pool is
- * handed an MPOOL which is the opaque cookie passed to all of the memory
- * routines.
- */
-#define HASHSIZE 128
-#define HASHKEY(pgno) ((pgno - 1) % HASHSIZE)
-
-/* The BKT structures are the elements of the lists. */
-typedef struct BKT {
- struct BKT *hnext; /* next hash bucket */
- struct BKT *hprev; /* previous hash bucket */
- struct BKT *cnext; /* next free/lru bucket */
- struct BKT *cprev; /* previous free/lru bucket */
- void *page; /* page */
- pgno_t pgno; /* page number */
-
-#define MPOOL_DIRTY 0x01 /* page needs to be written */
-#define MPOOL_PINNED 0x02 /* page is pinned into memory */
- unsigned long flags; /* flags */
-} BKT;
-
-/* The BKTHDR structures are the heads of the lists. */
-typedef struct BKTHDR {
- struct BKT *hnext; /* next hash bucket */
- struct BKT *hprev; /* previous hash bucket */
- struct BKT *cnext; /* next free/lru bucket */
- struct BKT *cprev; /* previous free/lru bucket */
-} BKTHDR;
-
-typedef struct MPOOL {
- BKTHDR free; /* The free list. */
- BKTHDR lru; /* The LRU list. */
- BKTHDR hashtable[HASHSIZE]; /* Hashed list by page number. */
- pgno_t curcache; /* Current number of cached pages. */
- pgno_t maxcache; /* Max number of cached pages. */
- pgno_t npages; /* Number of pages in the file. */
- u_long pagesize; /* File page size. */
- int fd; /* File descriptor. */
- /* Page in conversion routine. */
- void (*pgin) __P((void *, pgno_t, void *));
- /* Page out conversion routine. */
- void (*pgout) __P((void *, pgno_t, void *));
- void *pgcookie; /* Cookie for page in/out routines. */
-#ifdef STATISTICS
- unsigned long cachehit;
- unsigned long cachemiss;
- unsigned long pagealloc;
- unsigned long pageflush;
- unsigned long pageget;
- unsigned long pagenew;
- unsigned long pageput;
- unsigned long pageread;
- unsigned long pagewrite;
-#endif
-} MPOOL;
-
-#ifdef __MPOOLINTERFACE_PRIVATE
-/* Macros to insert/delete into/from hash chain. */
-#define rmhash(bp) { \
- (bp)->hprev->hnext = (bp)->hnext; \
- (bp)->hnext->hprev = (bp)->hprev; \
-}
-#define inshash(bp, pg) { \
- hp = &mp->hashtable[HASHKEY(pg)]; \
- (bp)->hnext = hp->hnext; \
- (bp)->hprev = (struct BKT *)hp; \
- hp->hnext->hprev = (bp); \
- hp->hnext = (bp); \
-}
-
-/* Macros to insert/delete into/from lru and free chains. */
-#define rmchain(bp) { \
- (bp)->cprev->cnext = (bp)->cnext; \
- (bp)->cnext->cprev = (bp)->cprev; \
-}
-#define inschain(bp, dp) { \
- (bp)->cnext = (dp)->cnext; \
- (bp)->cprev = (struct BKT *)(dp); \
- (dp)->cnext->cprev = (bp); \
- (dp)->cnext = (bp); \
-}
-#endif
-
-__BEGIN_DECLS
-MPOOL *mpool_open __P((DBT *, int, pgno_t, pgno_t));
-void mpool_filter __P((MPOOL *, void (*)(void *, pgno_t, void *),
- void (*)(void *, pgno_t, void *), void *));
-void *mpool_new __P((MPOOL *, pgno_t *));
-void *mpool_get __P((MPOOL *, pgno_t, u_int));
-int mpool_put __P((MPOOL *, void *, u_int));
-int mpool_sync __P((MPOOL *));
-int mpool_close __P((MPOOL *));
-#ifdef STATISTICS
-void mpool_stat __P((MPOOL *));
-#endif
-__END_DECLS
diff --git a/lib/libc/db/PORT/sys b/lib/libc/db/PORT/sys
deleted file mode 120000
index 2996fba35632..000000000000
--- a/lib/libc/db/PORT/sys
+++ /dev/null
@@ -1 +0,0 @@
-include \ No newline at end of file
diff --git a/lib/libc/db/README b/lib/libc/db/README
deleted file mode 120000
index 974cf28e0083..000000000000
--- a/lib/libc/db/README
+++ /dev/null
@@ -1 +0,0 @@
-VERSION \ No newline at end of file
diff --git a/lib/libc/db/VERSION b/lib/libc/db/VERSION
index ceca0b2061bd..972d3517311a 100644
--- a/lib/libc/db/VERSION
+++ b/lib/libc/db/VERSION
@@ -1,6 +1,6 @@
-# @(#)VERSION 8.1 (Berkeley) 6/6/93
+# @(#)VERSION 8.8 (Berkeley) 12/19/93
-This is version 1.6 of the Berkeley DB code.
+This is version 1.73 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!
@@ -8,16 +8,42 @@ 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.
============================================
-1.5 -> 1.6 06 Jun 1993
+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
+
+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.
@@ -30,16 +56,16 @@ bostic@cs.berkeley.edu.
Change sync routines to take a flag argument, recno
uses this to sync out the underlying btree.
-1.3 -> 1.4 10 May 1993
+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 1 May 1993
+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
+1.1 -> 1.2 15 Apr 1993
No bug fixes, only compatibility hacks.
============================================
@@ -50,9 +76,9 @@ Distribution contents:
VERSION This file.
btree B+tree routines.
db Dbopen(3) interface routine.
- doc USENIX papers.
+ doc USENIX papers, formatted man pages.
hash Extended linear hashing routines.
- man Man pages.
+ man Unformatted man pages.
mpool Memory pool routines.
- recno Fixed/variable length routines.
+ recno Fixed/variable length record routines.
test Test package.
diff --git a/lib/libc/db/btree/bt_close.c b/lib/libc/db/btree/bt_close.c
index 22c739b7b78b..5ff2adff9c8f 100644
--- a/lib/libc/db/btree/bt_close.c
+++ b/lib/libc/db/btree/bt_close.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_close.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)bt_close.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -69,6 +69,12 @@ __bt_close(dbp)
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.
@@ -114,13 +120,20 @@ __bt_sync(dbp, flags)
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);
}
- t = dbp->internal;
-
if (ISSET(t, B_INMEM | B_RDONLY) || !ISSET(t, B_MODIFIED))
return (RET_SUCCESS);
diff --git a/lib/libc/db/btree/bt_delete.c b/lib/libc/db/btree/bt_delete.c
index 326618b1f609..e512c8423da2 100644
--- a/lib/libc/db/btree/bt_delete.c
+++ b/lib/libc/db/btree/bt_delete.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_delete.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)bt_delete.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -70,10 +70,18 @@ __bt_delete(dbp, key, flags)
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);
diff --git a/lib/libc/db/btree/bt_get.c b/lib/libc/db/btree/bt_get.c
index 4f473bc4f110..28b2d603dfe5 100644
--- a/lib/libc/db/btree/bt_get.c
+++ b/lib/libc/db/btree/bt_get.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_get.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)bt_get.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -70,11 +70,20 @@ __bt_get(dbp, key, data, flags)
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);
}
- t = dbp->internal;
+
if ((e = __bt_search(t, key, &exact)) == NULL)
return (RET_ERROR);
if (!exact) {
@@ -99,7 +108,14 @@ __bt_get(dbp, key, data, flags)
}
status = __bt_ret(t, e, NULL, data);
- mpool_put(t->bt_mp, e->page, 0);
+ /*
+ * 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);
}
diff --git a/lib/libc/db/btree/bt_open.c b/lib/libc/db/btree/bt_open.c
index f918124042e8..feeffa4c6bf2 100644
--- a/lib/libc/db/btree/bt_open.c
+++ b/lib/libc/db/btree/bt_open.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_open.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)bt_open.c 8.3 (Berkeley) 9/16/93";
#endif /* LIBC_SCCS and not lint */
/*
@@ -83,9 +83,9 @@ static int tmp __P((void));
*
*/
DB *
-__bt_open(fname, flags, mode, openinfo)
+__bt_open(fname, flags, mode, openinfo, dflags)
const char *fname;
- int flags, mode;
+ int flags, mode, dflags;
const BTREEINFO *openinfo;
{
BTMETA m;
@@ -156,19 +156,17 @@ __bt_open(fname, flags, mode, openinfo)
/* Allocate and initialize DB and BTREE structures. */
if ((t = malloc(sizeof(BTREE))) == NULL)
goto err;
- t->bt_fd = -1; /* Don't close unopened fd on error. */
- if ((t->bt_dbp = dbp = malloc(sizeof(DB))) == NULL)
- goto err;
+ memset(t, 0, sizeof(BTREE));
t->bt_bcursor.pgno = P_INVALID;
- t->bt_bcursor.index = 0;
- t->bt_stack = NULL;
- t->bt_sp = t->bt_maxstack = 0;
- t->bt_kbuf = t->bt_dbuf = NULL;
- t->bt_kbufsz = t->bt_dbufsz = 0;
+ 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 = malloc(sizeof(DB))) == NULL)
+ goto err;
t->bt_flags = 0;
if (t->bt_lorder != machine_lorder)
SET(t, B_NEEDSWAP);
@@ -199,8 +197,7 @@ __bt_open(fname, flags, mode, openinfo)
goto einval;
}
- if ((t->bt_fd =
- open(fname, flags & __USE_OPEN_FLAGS, mode)) < 0)
+ if ((t->bt_fd = open(fname, flags, mode)) < 0)
goto err;
} else {
@@ -314,6 +311,14 @@ __bt_open(fname, flags, mode, openinfo)
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;
@@ -420,6 +425,13 @@ __bt_fd(dbp)
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);
diff --git a/lib/libc/db/btree/bt_put.c b/lib/libc/db/btree/bt_put.c
index 2e0918b8f0d8..11a211b15a63 100644
--- a/lib/libc/db/btree/bt_put.c
+++ b/lib/libc/db/btree/bt_put.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_put.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)bt_put.c 8.3 (Berkeley) 9/16/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -82,6 +82,12 @@ __bt_put(dbp, key, data, flags)
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))
@@ -260,7 +266,6 @@ bt_fast(t, key, data, exactp)
const DBT *key, *data;
int *exactp;
{
- EPG e;
PAGE *h;
size_t nbytes;
int cmp;
@@ -269,8 +274,8 @@ bt_fast(t, key, data, exactp)
t->bt_order = NOT;
return (NULL);
}
- e.page = h;
- e.index = t->bt_last.index;
+ 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
@@ -281,19 +286,19 @@ bt_fast(t, key, data, exactp)
goto miss;
if (t->bt_order == FORWARD) {
- if (e.page->nextpg != P_INVALID)
+ if (t->bt_cur.page->nextpg != P_INVALID)
goto miss;
- if (e.index != NEXTINDEX(h) - 1)
+ if (t->bt_cur.index != NEXTINDEX(h) - 1)
goto miss;
- if ((cmp = __bt_cmp(t, key, &e)) < 0)
+ if ((cmp = __bt_cmp(t, key, &t->bt_cur)) < 0)
goto miss;
- t->bt_last.index = cmp ? ++e.index : e.index;
+ t->bt_last.index = cmp ? ++t->bt_cur.index : t->bt_cur.index;
} else {
- if (e.page->prevpg != P_INVALID)
+ if (t->bt_cur.page->prevpg != P_INVALID)
goto miss;
- if (e.index != 0)
+ if (t->bt_cur.index != 0)
goto miss;
- if ((cmp = __bt_cmp(t, key, &e)) > 0)
+ if ((cmp = __bt_cmp(t, key, &t->bt_cur)) > 0)
goto miss;
t->bt_last.index = 0;
}
@@ -301,7 +306,7 @@ bt_fast(t, key, data, exactp)
#ifdef STATISTICS
++bt_cache_hit;
#endif
- return (&e);
+ return (&t->bt_cur);
miss:
#ifdef STATISTICS
diff --git a/lib/libc/db/btree/bt_search.c b/lib/libc/db/btree/bt_search.c
index 06aba1126bda..a164173d0173 100644
--- a/lib/libc/db/btree/bt_search.c
+++ b/lib/libc/db/btree/bt_search.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_search.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)bt_search.c 8.4 (Berkeley) 12/10/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -45,6 +45,9 @@ static char sccsid[] = "@(#)bt_search.c 8.1 (Berkeley) 6/4/93";
#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.
*
@@ -54,12 +57,9 @@ static char sccsid[] = "@(#)bt_search.c 8.1 (Berkeley) 6/4/93";
* exactp: pointer to exact match flag
*
* Returns:
- * EPG for matching record, if any, or the EPG for the location of the
- * key, if it were inserted into the tree.
- *
- * Warnings:
- * The EPG returned is in static memory, and will be overwritten by the
- * next search of any kind in any tree.
+ * 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)
@@ -67,11 +67,10 @@ __bt_search(t, key, exactp)
const DBT *key;
int *exactp;
{
- register indx_t index;
- register int base, cmp, lim;
- register PAGE *h;
+ PAGE *h, *n;
+ indx_t index;
pgno_t pg;
- static EPG e;
+ int base, cmp, lim;
BT_CLR(t);
for (pg = P_ROOT;;) {
@@ -79,13 +78,13 @@ __bt_search(t, key, exactp)
return (NULL);
/* Do a binary search on the current page. */
- e.page = h;
+ t->bt_cur.page = h;
for (base = 0, lim = NEXTINDEX(h); lim; lim >>= 1) {
- e.index = index = base + (lim >> 1);
- if ((cmp = __bt_cmp(t, key, &e)) == 0) {
+ 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 (&e);
+ return (&t->bt_cur);
}
goto next;
}
@@ -95,11 +94,26 @@ __bt_search(t, key, exactp)
}
}
- /* If it's a leaf page, we're done. */
+ /*
+ * 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) {
- e.index = base;
+ t->bt_cur.index = base;
*exactp = 0;
- return (&e);
+ 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);
}
/*
@@ -117,3 +131,105 @@ next: if (__bt_push(t, h->pgno, index) == RET_ERROR)
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
index 03f8f09a2837..182ef7080d5e 100644
--- a/lib/libc/db/btree/bt_seq.c
+++ b/lib/libc/db/btree/bt_seq.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_seq.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)bt_seq.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -86,12 +86,19 @@ __bt_seq(dbp, key, data, flags)
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.
*/
- t = dbp->internal;
switch(flags) {
case R_NEXT:
case R_PREV:
@@ -116,7 +123,15 @@ __bt_seq(dbp, key, data, flags)
/* Update the actual cursor. */
t->bt_bcursor.pgno = e.page->pgno;
t->bt_bcursor.index = e.index;
- mpool_put(t->bt_mp, e.page, 0);
+
+ /*
+ * 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);
diff --git a/lib/libc/db/btree/bt_utils.c b/lib/libc/db/btree/bt_utils.c
index 452eb87e4253..ad8eb97a2f22 100644
--- a/lib/libc/db/btree/bt_utils.c
+++ b/lib/libc/db/btree/bt_utils.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bt_utils.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)bt_utils.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -70,11 +70,17 @@ __bt_ret(t, e, key, data)
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);
- } else {
+ 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 = realloc(t->bt_dbuf, bl->dsize + 1)) == NULL)
@@ -84,8 +90,11 @@ __bt_ret(t, e, key, data)
}
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;
}
- data->data = t->bt_dbuf;
if (key == NULL)
return (RET_SUCCESS);
@@ -94,7 +103,8 @@ __bt_ret(t, e, key, data)
if (__ovfl_get(t, bl->bytes,
&key->size, &t->bt_kbuf, &t->bt_kbufsz))
return (RET_ERROR);
- } else {
+ key->data = t->bt_kbuf;
+ } else if (ISSET(t, B_DB_LOCK)) {
if (bl->ksize > t->bt_kbufsz) {
if ((p = realloc(t->bt_kbuf, bl->ksize)) == NULL)
return (RET_ERROR);
@@ -103,8 +113,11 @@ __bt_ret(t, e, key, data)
}
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;
}
- key->data = t->bt_kbuf;
return (RET_SUCCESS);
}
diff --git a/lib/libc/db/btree/btree.h b/lib/libc/db/btree/btree.h
index 1e393236b09c..d32e52aa1741 100644
--- a/lib/libc/db/btree/btree.h
+++ b/lib/libc/db/btree/btree.h
@@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)btree.h 8.1 (Berkeley) 6/4/93
+ * @(#)btree.h 8.4 (Berkeley) 12/18/93
*/
#include <mpool.h>
@@ -59,7 +59,7 @@
* (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 {
+typedef struct _page {
pgno_t pgno; /* this page's page number */
pgno_t prevpg; /* left sibling */
pgno_t nextpg; /* right sibling */
@@ -111,7 +111,7 @@ typedef struct PAGE {
* somewhat special and can cause duplicate internal and leaf page records and
* some minor modifications of the above rule.
*/
-typedef struct BINTERNAL {
+typedef struct _binternal {
size_t ksize; /* key size */
pgno_t pgno; /* page number stored on */
#define P_BIGDATA 0x01 /* overflow data */
@@ -142,7 +142,7 @@ typedef struct BINTERNAL {
* 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 {
+typedef struct _rinternal {
recno_t nrecs; /* number of records */
pgno_t pgno; /* page number stored below */
} RINTERNAL;
@@ -163,7 +163,7 @@ typedef struct RINTERNAL {
}
/* For the btree leaf pages, the item is a key and data pair. */
-typedef struct BLEAF {
+typedef struct _bleaf {
size_t ksize; /* size of key */
size_t dsize; /* size of data */
u_char flags; /* P_BIGDATA, P_BIGKEY */
@@ -196,7 +196,7 @@ typedef struct BLEAF {
}
/* For the recno leaf pages, the item is a data entry. */
-typedef struct RLEAF {
+typedef struct _rleaf {
size_t dsize; /* size of data */
u_char flags; /* P_BIGDATA */
char bytes[1];
@@ -238,12 +238,12 @@ typedef struct RLEAF {
* 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 {
+typedef struct _epgno {
pgno_t pgno; /* the page number */
indx_t index; /* the index on the page */
} EPGNO;
-typedef struct EPG {
+typedef struct _epg {
PAGE *page; /* the (pinned) page */
indx_t index; /* the index on the page */
} EPG;
@@ -253,7 +253,7 @@ typedef struct EPG {
* 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 {
+typedef struct _btmeta {
u_long m_magic; /* magic number */
u_long m_version; /* version */
u_long m_psize; /* page size */
@@ -265,11 +265,14 @@ typedef struct BTMETA {
} BTMETA;
/* The in-memory btree/recno data structure. */
-typedef struct BTREE {
+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) */
@@ -291,7 +294,7 @@ typedef struct BTREE {
indx_t bt_ovflsize; /* cut-off for key/data overflow */
int bt_lorder; /* byte order */
/* sorted order */
- enum { NOT, BACK, FORWARD, } bt_order;
+ enum { NOT, BACK, FORWARD } bt_order;
EPGNO bt_last; /* last insert */
/* B: key comparison function */
@@ -299,7 +302,7 @@ typedef struct BTREE {
/* B: prefix comparison function */
int (*bt_pfx) __P((const DBT *, const DBT *));
/* R: recno input function */
- int (*bt_irec) __P((struct BTREE *, recno_t));
+ int (*bt_irec) __P((struct _btree *, recno_t));
FILE *bt_rfp; /* R: record FILE pointer */
int bt_rfd; /* R: record file descriptor */
@@ -324,17 +327,21 @@ typedef struct BTREE {
#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_RECNO 0x00080 /* record oriented tree */
#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_long bt_flags; /* btree state */
} BTREE;
diff --git a/lib/libc/db/btree/extern.h b/lib/libc/db/btree/extern.h
index 99b6f31b73e8..bcb10535fccc 100644
--- a/lib/libc/db/btree/extern.h
+++ b/lib/libc/db/btree/extern.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)extern.h 8.1 (Berkeley) 6/4/93
+ * @(#)extern.h 8.2 (Berkeley) 9/7/93
*/
int __bt_close __P((DB *));
@@ -45,7 +45,6 @@ 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 *));
-DB *__bt_open __P((const char *, int, int, const BTREEINFO *));
void __bt_pgin __P((void *, pgno_t, void *));
void __bt_pgout __P((void *, pgno_t, void *));
int __bt_push __P((BTREE *, pgno_t, int));
diff --git a/lib/libc/db/db/db.c b/lib/libc/db/db/db.c
index e31d48cef418..52e8a363036f 100644
--- a/lib/libc/db/db/db.c
+++ b/lib/libc/db/db/db.c
@@ -32,12 +32,13 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)db.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)db.c 8.3 (Berkeley) 9/13/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
+#include <fcntl.h>
#include <stddef.h>
#include <stdio.h>
@@ -51,14 +52,24 @@ dbopen(fname, flags, mode, type, openinfo)
DBTYPE type;
const void *openinfo;
{
- switch (type) {
- case DB_BTREE:
- return (__bt_open(fname, flags, mode, openinfo));
- case DB_HASH:
- return (__hash_open(fname, flags, mode, openinfo));
- case DB_RECNO:
- return (__rec_open(fname, flags, mode, 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);
}
diff --git a/lib/libc/db/doc/btree.3.ps b/lib/libc/db/doc/btree.3.ps
deleted file mode 100644
index 7ae6af965b44..000000000000
--- a/lib/libc/db/doc/btree.3.ps
+++ /dev/null
@@ -1,364 +0,0 @@
-%!PS-Adobe-3.0
-%%Creator: groff version 1.08
-%%DocumentNeededResources: font Times-Roman
-%%+ font Times-Bold
-%%+ font Times-Italic
-%%DocumentSuppliedResources: procset grops 1.08 0
-%%Pages: 2
-%%PageOrder: Ascend
-%%Orientation: Portrait
-%%EndComments
-%%BeginProlog
-%%BeginResource: procset grops 1.08 0
-/setpacking where{
-pop
-currentpacking
-true setpacking
-}if
-/grops 120 dict dup begin
-/SC 32 def
-/A/show load def
-/B{0 SC 3 -1 roll widthshow}bind def
-/C{0 exch ashow}bind def
-/D{0 exch 0 SC 5 2 roll awidthshow}bind def
-/E{0 rmoveto show}bind def
-/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
-/G{0 rmoveto 0 exch ashow}bind def
-/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/I{0 exch rmoveto show}bind def
-/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
-/K{0 exch rmoveto 0 exch ashow}bind def
-/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/M{rmoveto show}bind def
-/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
-/O{rmoveto 0 exch ashow}bind def
-/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/Q{moveto show}bind def
-/R{moveto 0 SC 3 -1 roll widthshow}bind def
-/S{moveto 0 exch ashow}bind def
-/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/SF{
-findfont exch
-[exch dup 0 exch 0 exch neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/MF{
-findfont
-[5 2 roll
-0 3 1 roll
-neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/level0 0 def
-/RES 0 def
-/PL 0 def
-/LS 0 def
-/PLG{
-gsave newpath clippath pathbbox grestore
-exch pop add exch pop
-}bind def
-/BP{
-/level0 save def
-1 setlinecap
-1 setlinejoin
-72 RES div dup scale
-LS{
-90 rotate
-}{
-0 PL translate
-}ifelse
-1 -1 scale
-}bind def
-/EP{
-level0 restore
-showpage
-}bind def
-/DA{
-newpath arcn stroke
-}bind def
-/SN{
-transform
-.25 sub exch .25 sub exch
-round .25 add exch round .25 add exch
-itransform
-}bind def
-/DL{
-SN
-moveto
-SN
-lineto stroke
-}bind def
-/DC{
-newpath 0 360 arc closepath
-}bind def
-/TM matrix def
-/DE{
-TM currentmatrix pop
-translate scale newpath 0 0 .5 0 360 arc closepath
-TM setmatrix
-}bind def
-/RC/rcurveto load def
-/RL/rlineto load def
-/ST/stroke load def
-/MT/moveto load def
-/CL/closepath load def
-/FL{
-currentgray exch setgray fill setgray
-}bind def
-/BL/fill load def
-/LW/setlinewidth load def
-/RE{
-findfont
-dup maxlength 1 index/FontName known not{1 add}if dict begin
-{
-1 index/FID ne{def}{pop pop}ifelse
-}forall
-/Encoding exch def
-dup/FontName exch def
-currentdict end definefont pop
-}bind def
-/DEFS 0 def
-/EBEGIN{
-moveto
-DEFS begin
-}bind def
-/EEND/end load def
-/CNT 0 def
-/level1 0 def
-/PBEGIN{
-/level1 save def
-translate
-div 3 1 roll div exch scale
-neg exch neg exch translate
-0 setgray
-0 setlinecap
-1 setlinewidth
-0 setlinejoin
-10 setmiterlimit
-[]0 setdash
-/setstrokeadjust where{
-pop
-false setstrokeadjust
-}if
-/setoverprint where{
-pop
-false setoverprint
-}if
-newpath
-/CNT countdictstack def
-userdict begin
-/showpage{}def
-}bind def
-/PEND{
-clear
-countdictstack CNT sub{end}repeat
-level1 restore
-}bind def
-end def
-/setpacking where{
-pop
-setpacking
-}if
-%%EndResource
-%%IncludeResource: font Times-Roman
-%%IncludeResource: font Times-Bold
-%%IncludeResource: font Times-Italic
-grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
-792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
-/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
-/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
-/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
-/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/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/bracketleft/backslash
-/bracketright/circumflex/underscore/quoteleft/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/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
-/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
-/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
-/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
-/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
-/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
-/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
-/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
-/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
-/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
-/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
-/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
-/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
-/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
-/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
-/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE
-/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE
-%%EndProlog
-%%Page: 1 1
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF 378.84(BTREE\(3\) BTREE\(3\))72 48 R/F1 9/Times-Bold@0
-SF -.18(NA)72 84 S(ME).18 E F0(btree \255 btree database access method)108 96 Q
-F1(SYNOPSIS)72 112.8 Q/F2 10/Times-Bold@0 SF(#include <sys/types.h>)108 124.8 Q
-(#include <db)108 136.8 Q(.h>)-.4 E F1(DESCRIPTION)72 153.6 Q F0 .198
-(The routine)108 165.6 R/F3 10/Times-Italic@0 SF(dbopen)2.698 E F0 .198
-(is the library interf)2.698 F .198(ace to database \214les.)-.1 F .198
-(One of the supported \214le formats is btree \214les.)5.198 F .974
-(The general description of the database access methods is in)108 177.6 R F3
-(dbopen)3.475 E F0 .975(\(3\), this manual page describes only).24 F
-(the btree speci\214c information.)108 189.6 Q(The btree data structure is a s\
-orted, balanced tree structure storing associated k)108 206.4 Q -.15(ey)-.1 G
-(/data pairs.).15 E .504(The btree access method speci\214c data structure pro)
-108 223.2 R .504(vided to)-.15 F F3(dbopen)3.004 E F0 .503
-(is de\214ned in the <db)3.003 F .503(.h> include \214le as)-.4 F(follo)108
-235.2 Q(ws:)-.25 E(typedef struct {)108 252 Q(u_long \215ags;)144 264 Q
-(u_int cachesize;)144 276 Q(inde)144 288 Q(x_t psize;)-.15 E(int lorder;)144
-300 Q(int mink)144 312 Q -.15(ey)-.1 G(page;).15 E
-(int \(*compare\)\(const DBT *k)144 324 Q -.15(ey)-.1 G(1, const DBT *k).15 E
--.15(ey)-.1 G(2\);).15 E(int \(*pre\214x\)\(const DBT *k)144 336 Q -.15(ey)-.1
-G(1, const DBT *k).15 E -.15(ey)-.1 G(2\);).15 E 2.5(}B)108 348 S(TREEINFO;)
-121.97 348 Q(The elements of this structure are as follo)108 364.8 Q(ws:)-.25 E
-14.61(\215ags The)108 381.6 R(\215ag v)2.5 E(alue is speci\214ed by)-.25 E F3
-(or)2.5 E F0('ing an).73 E 2.5(yo)-.15 G 2.5(ft)313.2 381.6 S(he follo)321.81
-381.6 Q(wing v)-.25 E(alues:)-.25 E(R_DUP)144 398.4 Q 1.296(Permit duplicate k)
-180 410.4 R -.15(ey)-.1 G 3.796(si).15 G 3.796(nt)275.578 410.4 S 1.296
-(he tree, i.e. permit insertion if the k)287.154 410.4 R 1.596 -.15(ey t)-.1 H
-3.796(ob).15 G 3.796(ei)466.878 410.4 S 1.296(nserted already)477.894 410.4 R
--.15(ex)180 422.4 S 1.935(ists in the tree.).15 F 1.935(The def)6.935 F 1.935
-(ault beha)-.1 F(vior)-.2 E 4.435(,a)-.4 G 4.435(sd)358.215 422.4 S 1.935
-(escribed in)371.54 422.4 R F3(dbopen)4.435 E F0 1.935(\(3\), is to o).24 F
--.15(ve)-.15 G 1.935(rwrite a).15 F .148(matching k)180 434.4 R .448 -.15(ey w)
--.1 H .148(hen inserting a ne).15 F 2.649(wk)-.25 G .449 -.15(ey o)329.709
-434.4 T 2.649(rt).15 G 2.649(of)355.407 434.4 S .149(ail if the R_NOO)366.286
-434.4 R(VER)-.5 E .149(WRITE \215ag is speci-)-.55 F 5.972(\214ed. The)180
-446.4 R 3.472(R_DUP \215ag is o)5.972 F -.15(ve)-.15 G 3.472
-(rridden by the R_NOO).15 F(VER)-.5 E 3.471(WRITE \215ag, and if the)-.55 F
-(R_NOO)180 458.4 Q(VER)-.5 E .781
-(WRITE \215ag is speci\214ed, attempts to insert duplicate k)-.55 F -.15(ey)-.1
-G 3.282(si).15 G .782(nto the tree will)474.604 458.4 R -.1(fa)180 470.4 S(il.)
-.1 E 1.13(If the database contains duplicate k)180 487.2 R -.15(ey)-.1 G 1.129
-(s, the order of retrie).15 F -.25(va)-.25 G 3.629(lo).25 G 3.629(fk)439.644
-487.2 S -.15(ey)451.503 487.2 S 1.129(/data pairs is unde-).15 F .837
-(\214ned if the)180 499.2 R F3 -.1(ge)3.337 G(t).1 E F0 .837
-(routine is used, ho)3.337 F(we)-.25 E -.15(ve)-.25 G -.4(r,).15 G F3(seq)3.737
-E F0 .838(routine calls with the R_CURSOR \215ag set)3.337 F(will al)180 511.2
-Q -.1(wa)-.1 G(ys return the logical `).1 E(`\214rst')-.74 E 2.5('o)-.74 G 2.5
-(fa)333.85 511.2 S .3 -.15(ny g)344.12 511.2 T(roup of duplicate k).15 E -.15
-(ey)-.1 G(s.).15 E(cachesize)108 528 Q 3.056(As)144 540 S .556
-(uggested maximum size \(in bytes\) of the memory cache.)158.166 540 R .555
-(This v)5.556 F .555(alue is)-.25 F F2(only)3.055 E F0(advisory)3.055 E 3.055
-(,a)-.65 G .555(nd the)514.725 540 R .759
-(access method will allocate more memory rather than f)144 552 R 3.259
-(ail. Since)-.1 F -2.15 -.25(ev e)3.259 H .76(ry search e).25 F .76
-(xamines the root)-.15 F .055
-(page of the tree, caching the most recently used pages substantially impro)144
-564 R -.15(ve)-.15 G 2.554(sa).15 G .054(ccess time.)459.578 564 R .054
-(In addi-)5.054 F .661(tion, ph)144 576 R .662(ysical writes are delayed as lo\
-ng as possible, so a moderate cache can reduce the number)-.05 F .601
-(of I/O operations signi\214cantly)144 588 R 5.601(.O)-.65 G -.15(bv)280.744
-588 S(iously).15 E 3.101(,u)-.65 G .601(sing a cache increases \(b)324.995 588
-R .6(ut only increases\) the lik)-.2 F(eli-)-.1 E .19(hood of corruption or lo\
-st data if the system crashes while a tree is being modi\214ed.)144 600 R(If)
-5.191 E F3(cac)2.691 E(hesize)-.15 E F0(is)2.691 E 2.5(0\()144 612 S
-(no size is speci\214ed\) a def)154.83 612 Q(ault cache is used.)-.1 E 12.95
-(psize P)108 628.8 R .45
-(age size is the size \(in bytes\) of the pages used for nodes in the tree.)
--.15 F .449(The minimum page size is)5.449 F .442
-(512 bytes and the maximum page size is 64K.)144 640.8 R(If)5.442 E F3(psize)
-2.942 E F0 .442(is 0 \(no page size is speci\214ed\) a page size)2.942 F
-(is chosen based on the underlying \214le system I/O block size.)144 652.8 Q
-9.62(lorder The)108 669.6 R 1.597(byte order for inte)4.097 F 1.596
-(gers in the stored database metadata.)-.15 F 1.596
-(The number should represent the)6.596 F .688(order as an inte)144 681.6 R .689
-(ger; for e)-.15 F .689(xample, big endian order w)-.15 F .689
-(ould be the number 4,321.)-.1 F(If)5.689 E F3(lor)3.189 E(der)-.37 E F0 .689
-(is 0 \(no)3.189 F(order is speci\214ed\) the current host order is used.)144
-693.6 Q(1)535 768 Q EP
-%%Page: 2 2
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF 378.84(BTREE\(3\) BTREE\(3\))72 48 R(mink)108 84 Q -.15
-(ey)-.1 G(page).15 E 1.423(The minimum number of k)144 96 R -.15(ey)-.1 G 3.923
-(sw).15 G 1.422(hich will be stored on an)282.245 96 R 3.922(ys)-.15 G 1.422
-(ingle page.)400.618 96 R 1.422(This v)6.422 F 1.422(alue is used to)-.25 F
-.257(determine which k)144 108 R -.15(ey)-.1 G 2.757(sw).15 G .257
-(ill be stored on o)242.001 108 R -.15(ve)-.15 G(r\215o).15 E 2.757(wp)-.25 G
-.257(ages, i.e. if a k)348.006 108 R .558 -.15(ey o)-.1 H 2.758(rd).15 G .258
-(ata item is longer than the)435.11 108 R 1.102(pagesize di)144 120 R 1.102
-(vided by the mink)-.25 F -.15(ey)-.1 G 1.102(page v).15 F 1.102
-(alue, it will be stored on o)-.25 F -.15(ve)-.15 G(r\215o).15 E 3.602(wp)-.25
-G 1.102(ages instead of in the)451.164 120 R(page itself.)144 132 Q(If)5 E/F1
-10/Times-Italic@0 SF(mink)2.5 E -.3(ey)-.1 G(pa).3 E -.1(ge)-.1 G F0
-(is 0 \(no minimum number of k)2.6 E -.15(ey)-.1 G 2.5(si).15 G 2.5(ss)392.84
-132 S(peci\214ed\) a v)403.12 132 Q(alue of 2 is used.)-.25 E(compare)108 148.8
-Q .751(Compare is the k)144 160.8 R 1.051 -.15(ey c)-.1 H .751
-(omparison function.).15 F .751(It must return an inte)5.751 F .752
-(ger less than, equal to, or greater)-.15 F .913(than zero if the \214rst k)144
-172.8 R 1.213 -.15(ey a)-.1 H -.18(rg).15 G .913
-(ument is considered to be respecti).18 F -.15(ve)-.25 G .913
-(ly less than, equal to, or greater).15 F .352(than the second k)144 184.8 R
-.652 -.15(ey a)-.1 H -.18(rg).15 G 2.852(ument. The).18 F .353
-(same comparison function must be used on a gi)2.852 F -.15(ve)-.25 G 2.853(nt)
-.15 G .353(ree e)503.127 184.8 R -.15(ve)-.25 G(ry).15 E .817
-(time it is opened.)144 196.8 R(If)5.817 E F1(compar)3.317 E(e)-.37 E F0 .817
-(is NULL \(no comparison function is speci\214ed\), the k)3.317 F -.15(ey)-.1 G
-3.316(sa).15 G .816(re com-)508.364 196.8 R(pared le)144 208.8 Q(xically)-.15 E
-2.5(,w)-.65 G(ith shorter k)214.57 208.8 Q -.15(ey)-.1 G 2.5(sc).15 G
-(onsidered less than longer k)282.92 208.8 Q -.15(ey)-.1 G(s.).15 E 10.17
-(pre\214x Pre\214x)108 225.6 R .291(is the pre\214x comparison function.)2.791
-F .292(If speci\214ed, this routine must return the number of bytes)5.291 F
-.937(of the second k)144 237.6 R 1.237 -.15(ey a)-.1 H -.18(rg).15 G .937
-(ument which are necessary to determine that it is greater than the \214rst k)
-.18 F -.15(ey)-.1 G(ar)144 249.6 Q 3.477(gument. If)-.18 F .977(the k)3.477 F
--.15(ey)-.1 G 3.477(sa).15 G .977(re equal, the k)241.898 249.6 R 1.277 -.15
-(ey l)-.1 H .978(ength should be returned.).15 F .978
-(Note, the usefulness of this)5.978 F .558(routine is v)144 261.6 R .558
-(ery data dependent, b)-.15 F .558
-(ut, in some data sets can produce signi\214cantly reduced tree sizes)-.2 F
-.354(and search times.)144 273.6 R(If)5.354 E F1(pr)2.854 E(e\214x)-.37 E F0
-.354(is NULL \(no pre\214x function is speci\214ed\),)2.854 F/F2 10
-/Times-Bold@0 SF(and)2.854 E F0 .354(no comparison function)2.854 F .193
-(is speci\214ed, a def)144 285.6 R .193(ault le)-.1 F .193
-(xical comparison routine is used.)-.15 F(If)5.192 E F1(pr)2.692 E(e\214x)-.37
-E F0 .192(is NULL and a comparison rou-)2.692 F
-(tine is speci\214ed, no pre\214x comparison is done.)144 297.6 Q .79
-(If the \214le already e)108 314.4 R .79(xists \(and the O_TR)-.15 F .79
-(UNC \215ag is not speci\214ed\), the v)-.4 F .79
-(alues speci\214ed for the parameters)-.25 F
-(\215ags, lorder and psize are ignored in f)108 326.4 Q -.2(avo)-.1 G 2.5(ro).2
-G 2.5(ft)284.4 326.4 S(he v)293.01 326.4 Q(alues used when the tree w)-.25 E
-(as created.)-.1 E -.15(Fo)108 343.2 S(rw).15 E
-(ard sequential scans of a tree are from the least k)-.1 E .3 -.15(ey t)-.1 H
-2.5(ot).15 G(he greatest.)348.55 343.2 Q 1.043(Space freed up by deleting k)108
-360 R -.15(ey)-.1 G 1.043(/data pairs from the tree is ne).15 F -.15(ve)-.25 G
-3.543(rr).15 G 1.043(eclaimed, although it is normally made)378.686 360 R -.2
-(av)108 372 S 1.394(ailable for reuse.)-.05 F 1.394
-(This means that the btree storage structure is gro)6.394 F(w-only)-.25 E 6.395
-(.T)-.65 G 1.395(he only solutions are to)441.09 372 R -.2(avo)108 384 S(id e)
-.2 E(xcessi)-.15 E .3 -.15(ve d)-.25 H
-(eletions, or to create a fresh tree periodically from a scan of an e).15 E
-(xisting one.)-.15 E .344(Searches, insertions, and deletions in a btree will \
-all complete in O lg base N where base is the a)108 400.8 R -.15(ve)-.2 G .343
-(rage \214ll).15 F -.1(fa)108 412.8 S(ctor).1 E 5.798(.O)-.55 G .799
-(ften, inserting ordered data into btrees results in a lo)146.188 412.8 R 3.299
-<778c>-.25 G .799(ll f)377.505 412.8 R(actor)-.1 E 5.799(.T)-.55 G .799
-(his implementation has been)423.443 412.8 R(modi\214ed to mak)108 424.8 Q 2.5
-(eo)-.1 G(rdered insertion the best case, resulting in a much better than norm\
-al page \214ll f)185.4 424.8 Q(actor)-.1 E(.)-.55 E/F3 9/Times-Bold@0 SF
-(SEE ALSO)72 441.6 Q F1(dbopen)108 453.6 Q F0(\(3\),).24 E F1(hash)2.5 E F0
-(\(3\),).28 E F1(mpool)2.5 E F0(\(3\),).51 E F1 -.37(re)2.5 G(cno).37 E F0
-(\(3\)).18 E F1(The Ubiquitous B-tr)108 477.6 Q(ee)-.37 E F0 2.5(,D).18 G
-(ouglas Comer)209.47 477.6 Q 2.5(,A)-.4 G(CM Comput. Surv)276.72 477.6 Q 2.5
-(.1)-.65 G(1, 2 \(June 1979\), 121-138.)360.25 477.6 Q F1(Pr)108 501.6 Q 1.588
-(e\214x B-tr)-.37 F(ees)-.37 E F0 4.088(,B).27 G 1.587(ayer and Unterauer)
-177.636 501.6 R 4.087(,A)-.4 G 1.587(CM T)270.447 501.6 R 1.587
-(ransactions on Database Systems, V)-.35 F 1.587(ol. 2, 1 \(March 1977\),)-1.29
-F(11-26.)108 513.6 Q F1(The Art of Computer Pr)108 537.6 Q -.1(og)-.45 G -.15
-(ra).1 G(mming V).15 E(ol. 3: Sorting and Sear)-1.11 E -.15(ch)-.37 G(ing).15 E
-F0 2.5(,D).22 G(.E. Knuth, 1968, pp 471-480.)382 537.6 Q F3 -.09(BU)72 554.4 S
-(GS).09 E F0(Only big and little endian byte order is supported.)108 566.4 Q(2)
-535 768 Q EP
-%%Trailer
-end
-%%EOF
diff --git a/lib/libc/db/doc/dbopen.3.ps b/lib/libc/db/doc/dbopen.3.ps
deleted file mode 100644
index 872c82e771c9..000000000000
--- a/lib/libc/db/doc/dbopen.3.ps
+++ /dev/null
@@ -1,496 +0,0 @@
-%!PS-Adobe-3.0
-%%Creator: groff version 1.08
-%%DocumentNeededResources: font Times-Roman
-%%+ font Times-Bold
-%%+ font Times-Italic
-%%DocumentSuppliedResources: procset grops 1.08 0
-%%Pages: 4
-%%PageOrder: Ascend
-%%Orientation: Portrait
-%%EndComments
-%%BeginProlog
-%%BeginResource: procset grops 1.08 0
-/setpacking where{
-pop
-currentpacking
-true setpacking
-}if
-/grops 120 dict dup begin
-/SC 32 def
-/A/show load def
-/B{0 SC 3 -1 roll widthshow}bind def
-/C{0 exch ashow}bind def
-/D{0 exch 0 SC 5 2 roll awidthshow}bind def
-/E{0 rmoveto show}bind def
-/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
-/G{0 rmoveto 0 exch ashow}bind def
-/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/I{0 exch rmoveto show}bind def
-/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
-/K{0 exch rmoveto 0 exch ashow}bind def
-/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/M{rmoveto show}bind def
-/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
-/O{rmoveto 0 exch ashow}bind def
-/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/Q{moveto show}bind def
-/R{moveto 0 SC 3 -1 roll widthshow}bind def
-/S{moveto 0 exch ashow}bind def
-/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/SF{
-findfont exch
-[exch dup 0 exch 0 exch neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/MF{
-findfont
-[5 2 roll
-0 3 1 roll
-neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/level0 0 def
-/RES 0 def
-/PL 0 def
-/LS 0 def
-/PLG{
-gsave newpath clippath pathbbox grestore
-exch pop add exch pop
-}bind def
-/BP{
-/level0 save def
-1 setlinecap
-1 setlinejoin
-72 RES div dup scale
-LS{
-90 rotate
-}{
-0 PL translate
-}ifelse
-1 -1 scale
-}bind def
-/EP{
-level0 restore
-showpage
-}bind def
-/DA{
-newpath arcn stroke
-}bind def
-/SN{
-transform
-.25 sub exch .25 sub exch
-round .25 add exch round .25 add exch
-itransform
-}bind def
-/DL{
-SN
-moveto
-SN
-lineto stroke
-}bind def
-/DC{
-newpath 0 360 arc closepath
-}bind def
-/TM matrix def
-/DE{
-TM currentmatrix pop
-translate scale newpath 0 0 .5 0 360 arc closepath
-TM setmatrix
-}bind def
-/RC/rcurveto load def
-/RL/rlineto load def
-/ST/stroke load def
-/MT/moveto load def
-/CL/closepath load def
-/FL{
-currentgray exch setgray fill setgray
-}bind def
-/BL/fill load def
-/LW/setlinewidth load def
-/RE{
-findfont
-dup maxlength 1 index/FontName known not{1 add}if dict begin
-{
-1 index/FID ne{def}{pop pop}ifelse
-}forall
-/Encoding exch def
-dup/FontName exch def
-currentdict end definefont pop
-}bind def
-/DEFS 0 def
-/EBEGIN{
-moveto
-DEFS begin
-}bind def
-/EEND/end load def
-/CNT 0 def
-/level1 0 def
-/PBEGIN{
-/level1 save def
-translate
-div 3 1 roll div exch scale
-neg exch neg exch translate
-0 setgray
-0 setlinecap
-1 setlinewidth
-0 setlinejoin
-10 setmiterlimit
-[]0 setdash
-/setstrokeadjust where{
-pop
-false setstrokeadjust
-}if
-/setoverprint where{
-pop
-false setoverprint
-}if
-newpath
-/CNT countdictstack def
-userdict begin
-/showpage{}def
-}bind def
-/PEND{
-clear
-countdictstack CNT sub{end}repeat
-level1 restore
-}bind def
-end def
-/setpacking where{
-pop
-setpacking
-}if
-%%EndResource
-%%IncludeResource: font Times-Roman
-%%IncludeResource: font Times-Bold
-%%IncludeResource: font Times-Italic
-grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
-792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
-/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
-/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
-/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
-/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/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/bracketleft/backslash
-/bracketright/circumflex/underscore/quoteleft/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/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
-/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
-/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
-/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
-/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
-/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
-/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
-/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
-/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
-/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
-/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
-/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
-/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
-/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
-/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
-/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE
-/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE
-%%EndProlog
-%%Page: 1 1
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF 169.84(DBOPEN\(3\) 1993 DBOPEN\(3\))72 48 R/F1 9
-/Times-Bold@0 SF -.18(NA)72 84 S(ME).18 E F0
-(dbopen \255 database access methods)108 96 Q F1(SYNOPSIS)72 112.8 Q/F2 10
-/Times-Bold@0 SF(#include <sys/types.h>)108 124.8 Q(#include <limits.h>)108
-136.8 Q(#include <db)108 148.8 Q(.h>)-.4 E(DB *)108 172.8 Q
-(dbopen\(const char *\214le, int \215ags, int mode, DBTYPE type,)108 184.8 Q
-(const v)158 196.8 Q(oid *openinf)-.1 E(o\);)-.25 E F1(DESCRIPTION)72 213.6 Q
-/F3 10/Times-Italic@0 SF(Dbopen)108 225.6 Q F0 .032(is the library interf)2.532
-F .031(ace to database \214les.)-.1 F .031
-(The supported \214le formats are btree, hashed and UNIX \214le)5.031 F 2.82
-(oriented. The)108 237.6 R .32
-(btree format is a representation of a sorted, balanced tree structure.)2.82 F
-.321(The hashed format is an)5.321 F -.15(ex)108 249.6 S .424
-(tensible, dynamic hashing scheme.).15 F .423
-(The \215at-\214le format is a byte stream \214le with \214x)5.423 F .423
-(ed or v)-.15 F .423(ariable length)-.25 F 2.906(records. The)108 261.6 R .407
-(formats and \214le format speci\214c information are described in detail in t\
-heir respecti)2.906 F .707 -.15(ve m)-.25 H(anual).15 E(pages)108 273.6 Q F3
-(btr)2.5 E(ee)-.37 E F0(\(3\),).18 E F3(hash)2.5 E F0(\(3\) and).28 E F3 -.37
-(re)2.5 G(cno).37 E F0(\(3\).).18 E .433(Dbopen opens)108 290.4 R F3(\214le)
-2.933 E F0 .433(for reading and/or writing.)2.933 F .433(Files ne)5.433 F -.15
-(ve)-.25 G 2.933(ri).15 G .433(ntended to be preserv)346.737 290.4 R .433
-(ed on disk may be created)-.15 F(by setting the \214le parameter to NULL.)108
-302.4 Q(The)108 319.2 Q F3<8d61>4.661 E(gs)-.1 E F0(and)4.661 E F3 2.161
-(mode ar)4.661 F(guments)-.37 E F0 2.161(are as speci\214ed to the)4.661 F F3
-(open)4.661 E F0 2.162(\(2\) routine, ho).24 F(we)-.25 E -.15(ve)-.25 G 2.962
--.4(r, o).15 H 2.162(nly the O_CREA).4 F -.74(T,)-1.11 G 2.597
-(O_EXCL, O_EXLOCK, O_RDONL)108 331.2 R 5.177 -1.29(Y, O)-1 H(_RD)1.29 E 2.597
-(WR, O_SHLOCK and O_TR)-.3 F 2.596(UNC \215ags are meaningful.)-.4 F
-(\(Note, opening a database \214le O_WR)108 343.2 Q(ONL)-.4 E 2.5(Yi)-1 G 2.5
-(sn)289.62 343.2 S(ot possible.\))301.01 343.2 Q(The)108 360 Q F3(type)5.337 E
-F0(ar)5.337 E 2.837(gument is of type DBTYPE \(as de\214ned in the <db)-.18 F
-2.838(.h> include \214le\) and may be set to)-.4 F
-(DB_BTREE, DB_HASH or DB_RECNO.)108 372 Q(The)108 388.8 Q F3(openinfo)2.85 E F0
-(ar)2.85 E .349(gument is a pointer to an access method speci\214c structure d\
-escribed in the access method')-.18 F(s)-.55 E .03(manual page.)108 400.8 R(If)
-5.03 E F3(openinfo)2.53 E F0 .031(is NULL, each access method will use def)2.53
-F .031(aults appropriate for the system and the)-.1 F(access method.)108 412.8
-Q F3(Dbopen)108 429.6 Q F0 .416
-(returns a pointer to a DB structure on success and NULL on error)2.917 F 5.416
-(.T)-.55 G .416(he DB structure is de\214ned in)423.21 429.6 R(the <db)108
-441.6 Q(.h> include \214le, and contains at least the follo)-.4 E
-(wing \214elds:)-.25 E(typedef struct {)108 465.6 Q(DBTYPE type;)144 477.6 Q
-(int \(*close\)\(const DB *db\);)144 489.6 Q
-(int \(*del\)\(const DB *db, const DBT *k)144 501.6 Q -.15(ey)-.1 G 2.5(,u)-.5
-G(_int \215ags\);)318.92 501.6 Q(int \(*fd\)\(const DB *db\);)144 513.6 Q
-(int \(*get\)\(const DB *db, DBT *k)144 525.6 Q -.15(ey)-.1 G 2.5(,D)-.5 G
-(BT *data, u_int \215ags\);)297.53 525.6 Q(int \(*put\)\(const DB *db, DBT *k)
-144 537.6 Q -.15(ey)-.1 G 2.5(,c)-.5 G(onst DBT *data,)295.31 537.6 Q
-(u_int \215ags\);)194 549.6 Q(int \(*sync\)\(const DB *db, u_int \215ags\);)144
-561.6 Q(int \(*seq\)\(const DB *db, DBT *k)144 573.6 Q -.15(ey)-.1 G 2.5(,D)-.5
-G(BT *data, u_int \215ags\);)298.64 573.6 Q 2.5(}D)108 585.6 S(B;)122.52 585.6
-Q .101
-(These elements describe a database type and a set of functions performing v)
-108 602.4 R .101(arious actions.)-.25 F .101(These functions)5.101 F(tak)108
-614.4 Q 3.039(eap)-.1 G .539(ointer to a structure as returned by)140.078 614.4
-R F3(dbopen)3.038 E F0 3.038(,a).24 G .538
-(nd sometimes one or more pointers to k)323.196 614.4 R -.15(ey)-.1 G .538
-(/data struc-).15 F(tures and a \215ag v)108 626.4 Q(alue.)-.25 E 16.28
-(type The)108 643.2 R
-(type of the underlying access method \(and \214le format\).)2.5 E 12.95
-(close A)108 660 R .988(pointer to a routine to \215ush an)3.488 F 3.489(yc)
--.15 G .989(ached information to disk, free an)293.968 660 R 3.489(ya)-.15 G
-.989(llocated resources, and)446.662 660 R .112
-(close the underlying \214le\(s\).)144 672 R .111(Since k)5.112 F -.15(ey)-.1 G
-.111(/data pairs may be cached in memory).15 F 2.611(,f)-.65 G .111
-(ailing to sync the \214le)455.666 672 R .494(with a)144 684 R F3(close)2.994 E
-F0(or)2.994 E F3(sync)2.994 E F0 .495
-(function may result in inconsistent or lost information.)2.994 F F3(Close)
-5.495 E F0 .495(routines return)2.995 F(-1 on error \(setting)144 696 Q F3
-(errno)2.5 E F0 2.5(\)a).18 G(nd 0 on success.)254.43 696 Q 21.28(del A)108
-712.8 R(pointer to a routine to remo)2.5 E .3 -.15(ve k)-.15 H -.15(ey).05 G
-(/data pairs from the database.).15 E 209.835(24, May)72 768 R(1)535 768 Q EP
-%%Page: 2 2
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF 169.84(DBOPEN\(3\) 1993 DBOPEN\(3\))72 48 R
-(The parameter)144 84 Q/F1 10/Times-Italic@0 SF<8d61>2.5 E(g)-.1 E F0
-(may be set to the follo)2.5 E(wing v)-.25 E(alue:)-.25 E(R_CURSOR)144 100.8 Q
-.289(Delete the record referenced by the cursor)180 112.8 R 5.288(.T)-.55 G
-.288(he cursor must ha)363.342 112.8 R .588 -.15(ve p)-.2 H(re).15 E .288
-(viously been initial-)-.25 F(ized.)180 124.8 Q F1(Delete)144 141.6 Q F0 .03
-(routines return -1 on error \(setting)2.53 F F1(errno)2.53 E F0 .03
-(\), 0 on success, and 1 if the speci\214ed).18 F F1 -.1(ke)2.53 G(y)-.2 E F0
--.1(wa)2.53 G 2.53(sn).1 G .03(ot in)521.91 141.6 R(the \214le.)144 153.6 Q
-25.17(fd A)108 170.4 R .451
-(pointer to a routine which returns a \214le descriptor representati)2.951 F
-.75 -.15(ve o)-.25 H 2.95(ft).15 G .45(he underlying database.)431.73 170.4 R
-(A)5.45 E .942(\214le descriptor referencing the same \214le will be returned \
-to all processes which call)144 182.4 R F1(dbopen)3.442 E F0(with)3.442 E 1.629
-(the same)144 194.4 R F1(\214le)4.129 E F0 4.129(name. This)4.129 F 1.628
-(\214le descriptor may be safely used as a ar)4.128 F 1.628(gument to the)-.18
-F F1(fcntl)4.128 E F0 1.628(\(2\) and).51 F F1(\215oc)144 206.4 Q(k)-.2 E F0
-.425(\(2\) locking functions.).67 F .425
-(The \214le descriptor is not necessarily associated with an)5.425 F 2.925(yo)
--.15 G 2.925(ft)492.7 206.4 S .425(he under)501.735 206.4 R(-)-.2 E .198
-(lying \214les used by the access method.)144 218.4 R .198
-(No \214le descriptor is a)5.198 F -.25(va)-.2 G .198
-(ilable for in memory databases.).25 F F1(Fd)5.198 E F0
-(routines return -1 on error \(setting)144 230.4 Q F1(errno)2.5 E F0
-(\), and the \214le descriptor on success.).18 E 21.28(get A)108 247.2 R
-(pointer to a routine which is the interf)2.5 E .001(ace for k)-.1 F -.15(ey)
--.1 G .001(ed retrie).15 F -.25(va)-.25 G 2.501(lf).25 G .001
-(rom the database.)399.755 247.2 R .001(The address and)5.001 F .061
-(length of the data associated with the speci\214ed)144 259.2 R F1 -.1(ke)2.561
-G(y)-.2 E F0 .06(are returned in the structure referenced by)2.561 F F1(data)
-2.56 E F0(.).26 E F1(Get)144 271.2 Q F0(routines return -1 on error \(setting)
-2.5 E F1(errno)2.5 E F0(\), 0 on success, and 1 if the).18 E F1 -.1(ke)2.5 G(y)
--.2 E F0 -.1(wa)2.5 G 2.5(sn).1 G(ot in the \214le.)471.66 271.2 Q 20.72(put A)
-108 288 R(pointer to a routine to store k)2.5 E -.15(ey)-.1 G
-(/data pairs in the database.).15 E(The parameter)144 304.8 Q F1<8d61>2.5 E(g)
--.1 E F0(may be set to one of the follo)2.5 E(wing v)-.25 E(alues:)-.25 E
-(R_CURSOR)144 321.6 Q .051(Replace the k)180 333.6 R -.15(ey)-.1 G .051
-(/data pair referenced by the cursor).15 F 5.052(.T)-.55 G .052
-(he cursor must ha)393.98 333.6 R .352 -.15(ve p)-.2 H(re).15 E .052
-(viously been)-.25 F(initialized.)180 345.6 Q(R_IAFTER)144 362.4 Q 1.165
-(Append the data immediately after the data referenced by)180 374.4 R F1 -.1
-(ke)3.664 G(y)-.2 E F0 3.664(,c).32 G 1.164(reating a ne)446.758 374.4 R 3.664
-(wk)-.25 G -.15(ey)511.27 374.4 S(/data).15 E(pair)180 386.4 Q 6.065(.T)-.55 G
-1.065(he record number of the appended k)209.675 386.4 R -.15(ey)-.1 G 1.065
-(/data pair is returned in the).15 F F1 -.1(ke)3.565 G(y)-.2 E F0(structure.)
-3.565 E(\(Applicable only to the DB_RECNO access method.\))180 398.4 Q
-(R_IBEFORE)144 415.2 Q 1.293
-(Insert the data immediately before the data referenced by)180 427.2 R F1 -.1
-(ke)3.793 G(y)-.2 E F0 3.793(,c).32 G 1.293(reating a ne)446.371 427.2 R 3.793
-(wk)-.25 G -.15(ey)511.27 427.2 S(/data).15 E(pair)180 439.2 Q 6.54(.T)-.55 G
-1.54(he record number of the inserted k)210.15 439.2 R -.15(ey)-.1 G 1.541
-(/data pair is returned in the).15 F F1 -.1(ke)4.041 G(y)-.2 E F0(structure.)
-4.041 E(\(Applicable only to the DB_RECNO access method.\))180 451.2 Q(R_NOO)
-144 468 Q(VER)-.5 E(WRITE)-.55 E(Enter the ne)180 480 Q 2.5(wk)-.25 G -.15(ey)
-242.69 480 S(/data pair only if the k).15 E .3 -.15(ey d)-.1 H(oes not pre).15
-E(viously e)-.25 E(xist.)-.15 E(R_SETCURSOR)144 496.8 Q 1.36(Store the k)180
-508.8 R -.15(ey)-.1 G 1.36(/data pair).15 F 3.86(,s)-.4 G 1.359
-(etting or initializing the position of the cursor to reference it.)283.94
-508.8 R(\(Applicable only to the DB_BTREE and DB_RECNO access methods.\))180
-520.8 Q .563(R_SETCURSOR is a)144 537.6 R -.25(va)-.2 G .564
-(ilable only for the DB_BTREE and DB_RECNO access methods because).25 F
-(it implies that the k)144 549.6 Q -.15(ey)-.1 G 2.5(sh).15 G -2.25 -.2(av e)
-241.81 549.6 T(an inherent order which does not change.)2.7 E .416
-(R_IAFTER and R_IBEFORE are a)144 566.4 R -.25(va)-.2 G .416
-(ilable only for the DB_RECNO access method because the).25 F(y)-.15 E 1.221
-(each imply that the access method is able to create ne)144 578.4 R 3.722(wk)
--.25 G -.15(ey)385.644 578.4 S 3.722(s. This).15 F 1.222(is only true if the k)
-3.722 F -.15(ey)-.1 G 3.722(sa).15 G(re)532.23 578.4 Q
-(ordered and independent, record numbers for e)144 590.4 Q(xample.)-.15 E .289
-(The def)144 607.2 R .289(ault beha)-.1 F .289(vior of the)-.2 F F1(put)2.789 E
-F0 .289(routines is to enter the ne)2.789 F 2.789(wk)-.25 G -.15(ey)388.998
-607.2 S .288(/data pair).15 F 2.788(,r)-.4 G .288(eplacing an)444.284 607.2 R
-2.788(yp)-.15 G(re)503.03 607.2 Q(viously)-.25 E -.15(ex)144 619.2 S(isting k)
-.15 E -.15(ey)-.1 G(.)-.5 E F1(Put)144 636 Q F0 .37
-(routines return -1 on error \(setting)2.87 F F1(errno)2.87 E F0 .37
-(\), 0 on success, and 1 if the R_NOO).18 F(VER)-.5 E(WRITE)-.55 E F1<8d61>2.87
-E(g)-.1 E F0 -.1(wa)144 648 S 2.5(ss).1 G(et and the k)165.84 648 Q .3 -.15
-(ey a)-.1 H(lready e).15 E(xists in the \214le.)-.15 E 20.17(seq A)108 664.8 R
-.002(pointer to a routine which is the interf)2.502 F .002
-(ace for sequential retrie)-.1 F -.25(va)-.25 G 2.502(lf).25 G .002
-(rom the database.)416.694 664.8 R .001(The address)5.001 F .219
-(and length of the k)144 676.8 R .519 -.15(ey a)-.1 H .219
-(re returned in the structure referenced by).15 F F1 -.1(ke)2.72 G(y)-.2 E F0
-2.72(,a).32 G .22(nd the address and length of)426.42 676.8 R
-(the data are returned in the structure referenced by)144 688.8 Q F1(data)2.5 E
-F0(.).26 E .937(Sequential k)144 705.6 R -.15(ey)-.1 G .937(/data pair retrie)
-.15 F -.25(va)-.25 G 3.437(lm).25 G .936(ay be)289.748 705.6 R .936(gin at an)
--.15 F 3.436(yt)-.15 G .936(ime, and the position of the `)359.292 705.6 R
-(`cursor')-.74 E 3.436('i)-.74 G 3.436(sn)519.894 705.6 S(ot)532.22 705.6 Q(af)
-144 717.6 Q 1.585(fected by calls to the)-.25 F F1(del)4.085 E F0(,).51 E F1
--.1(ge)4.085 G(t).1 E F0(,).68 E F1(put)4.086 E F0 4.086(,o).68 G(r)308.452
-717.6 Q F1(sync)4.086 E F0 4.086(routines. Modi\214cations)4.086 F 1.586
-(to the database during a)4.086 F 1.404(sequential scan will be re\215ected in\
- the scan, i.e. records inserted behind the cursor will not be)144 729.6 R
-209.835(24, May)72 768 R(2)535 768 Q EP
-%%Page: 3 3
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF 169.84(DBOPEN\(3\) 1993 DBOPEN\(3\))72 48 R
-(returned while records inserted in front of the cursor will be returned.)144
-84 Q(The \215ag v)144 100.8 Q(alue)-.25 E/F1 10/Times-Bold@0 SF(must)2.5 E F0
-(be set to one of the follo)2.5 E(wing v)-.25 E(alues:)-.25 E(R_CURSOR)144
-117.6 Q .523(The data associated with the speci\214ed k)180 129.6 R .824 -.15
-(ey i)-.1 H 3.024(sr).15 G 3.024(eturned. This)367.236 129.6 R(dif)3.024 E .524
-(fers from the)-.25 F/F2 10/Times-Italic@0 SF -.1(ge)3.024 G(t).1 E F0
-(routines)3.024 E 1.143
-(in that it sets or initializes the cursor to the location of the k)180 141.6 R
-1.443 -.15(ey a)-.1 H 3.642(sw).15 G 3.642(ell. \(Note,)464.924 141.6 R 1.142
-(for the)3.642 F 1.275(DB_BTREE access method, the returned k)180 153.6 R 1.575
--.15(ey i)-.1 H 3.775(sn).15 G 1.276(ot necessarily an e)386.425 153.6 R 1.276
-(xact match for the)-.15 F .598(speci\214ed k)180 165.6 R -.15(ey)-.1 G 5.598
-(.T)-.5 G .598(he returned k)246.396 165.6 R .898 -.15(ey i)-.1 H 3.098(st).15
-G .598(he smallest k)325.188 165.6 R .898 -.15(ey g)-.1 H .598
-(reater than or equal to the speci\214ed).15 F -.1(ke)180 177.6 S 1.3 -.65
-(y, p)-.05 H(ermitting partial k).65 E .3 -.15(ey m)-.1 H
-(atches and range searches.\)).15 E(R_FIRST)144 194.4 Q 1.043(The \214rst k)180
-206.4 R -.15(ey)-.1 G 1.044(/data pair of the database is returned, and the cu\
-rsor is set or initialized to).15 F(reference it.)180 218.4 Q(R_LAST)144 235.2
-Q .085(The last k)180 247.2 R -.15(ey)-.1 G .085(/data pair of the database is\
- returned, and the cursor is set or initialized to ref-).15 F(erence it.)180
-259.2 Q(\(Applicable only to the DB_BTREE and DB_RECNO access methods.\))5 E
-(R_NEXT)144 276 Q(Retrie)180 288 Q .604 -.15(ve t)-.25 H .304(he k).15 F -.15
-(ey)-.1 G .304(/data pair immediately after the cursor).15 F 5.304(.I)-.55 G
-2.804(ft)410.622 288 S .305(he cursor is not yet set, this is)419.536 288 R
-(the same as the R_FIRST \215ag.)180 300 Q(R_PREV)144 316.8 Q(Retrie)180 328.8
-Q .755 -.15(ve t)-.25 H .455(he k).15 F -.15(ey)-.1 G .455
-(/data pair immediately before the cursor).15 F 5.455(.I)-.55 G 2.955(ft)419.05
-328.8 S .454(he cursor is not yet set, this)428.115 328.8 R .62
-(is the same as the R_LAST \215ag.)180 340.8 R .621
-(\(Applicable only to the DB_BTREE and DB_RECNO)5.621 F(access methods.\))180
-352.8 Q .911(R_LAST and R_PREV are a)144 369.6 R -.25(va)-.2 G .911
-(ilable only for the DB_BTREE and DB_RECNO access methods).25 F(because the)144
-381.6 Q 2.5(ye)-.15 G(ach imply that the k)202.16 381.6 Q -.15(ey)-.1 G 2.5(sh)
-.15 G -2.25 -.2(av e)302.18 381.6 T(an inherent order which does not change.)
-2.7 E F2(Seq)144 398.4 Q F0 .061(routines return -1 on error \(setting)2.561 F
-F2(errno)2.561 E F0 .061(\), 0 on success and 1 if there are no k).18 F -.15
-(ey)-.1 G .061(/data pairs less).15 F .35
-(than or greater than the speci\214ed or current k)144 410.4 R -.15(ey)-.1 G
-5.349(.I)-.5 G 2.849(ft)346.467 410.4 S .349
-(he DB_RECNO access method is being used,)355.426 410.4 R .025
-(and if the database \214le is a character special \214le and no complete k)144
-422.4 R -.15(ey)-.1 G .025(/data pairs are currently a).15 F -.25(va)-.2 G(il-)
-.25 E(able, the)144 434.4 Q F2(seq)2.5 E F0(routines return 2.)2.5 E 15.17
-(sync A)108 451.2 R .458(pointer to a routine to \215ush an)2.958 F 2.957(yc)
--.15 G .457(ached information to disk.)289.72 451.2 R .457
-(If the database is in memory only)5.457 F(,)-.65 E(the)144 463.2 Q F2(sync)2.5
-E F0(routine has no ef)2.5 E(fect and will al)-.25 E -.1(wa)-.1 G(ys succeed.)
-.1 E(The \215ag v)144 480 Q(alue may be set to the follo)-.25 E(wing v)-.25 E
-(alue:)-.25 E(R_RECNOSYNC)144 496.8 Q .077(If the DB_RECNO access method is be\
-ing used, this \215ag causes the sync routine to apply)180 508.8 R .75(to the \
-btree \214le which underlies the recno \214le, not the recno \214le itself.)180
-520.8 R .75(\(See the)5.75 F F2(bfname)3.25 E F0(\214eld of the)180 532.8 Q F2
--.37(re)2.5 G(cno).37 E F0(\(3\) manual page for more information.\)).18 E F2
-(Sync)144 549.6 Q F0(routines return -1 on error \(setting)2.5 E F2(errno)2.5 E
-F0 2.5(\)a).18 G(nd 0 on success.)336.91 549.6 Q/F3 9/Times-Bold@0 SF(KEY/D)72
-566.4 Q -1.35 -.855(AT A)-.315 H -.666(PA)3.105 G(IRS).666 E F0 .134
-(Access to all \214le types is based on k)108 578.4 R -.15(ey)-.1 G .134
-(/data pairs.).15 F .134(Both k)5.134 F -.15(ey)-.1 G 2.634(sa).15 G .134
-(nd data are represented by the follo)359.078 578.4 R .135(wing data)-.25 F
-(structure:)108 590.4 Q(typedef struct {)108 607.2 Q -.2(vo)144 619.2 S
-(id *data;).2 E(size_t size;)144 631.2 Q 2.5(}D)108 643.2 S(BT)122.52 643.2 Q
-(;)-.55 E(The elements of the DBT structure are de\214ned as follo)108 660 Q
-(ws:)-.25 E 16.84(data A)108 676.8 R(pointer to a byte string.)2.5 E 17.95
-(size The)108 693.6 R(length of the byte string.)2.5 E -2.15 -.25(Ke y)108
-710.4 T .829(and data byte strings may reference strings of essentially unlimi\
-ted length although an)3.579 F 3.328(yt)-.15 G 1.028 -.1(wo o)492.894 710.4 T
-3.328(ft).1 G(hem)522.78 710.4 Q 1.133(must \214t into a)108 722.4 R -.25(va)
--.2 G 1.134(ilable memory at the same time.).25 F 1.134
-(It should be noted that the access methods pro)6.134 F 1.134(vide no)-.15 F
-209.835(24, May)72 768 R(3)535 768 Q EP
-%%Page: 4 4
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF 169.84(DBOPEN\(3\) 1993 DBOPEN\(3\))72 48 R
-(guarantees about byte string alignment.)108 84 Q/F1 9/Times-Bold@0 SF(ERR)72
-100.8 Q(ORS)-.27 E F0(The)108 112.8 Q/F2 10/Times-Italic@0 SF(dbopen)3.389 E F0
-.889(routine may f)3.389 F .889(ail and set)-.1 F F2(errno)3.388 E F0 .888
-(for an)3.388 F 3.388(yo)-.15 G 3.388(ft)324.376 112.8 S .888
-(he errors speci\214ed for the library routines)333.874 112.8 R F2(open)3.388 E
-F0(\(2\)).24 E(and)108 124.8 Q F2(malloc)2.5 E F0(\(3\) or the follo).31 E
-(wing:)-.25 E([EFTYPE])108 141.6 Q 2.5<418c>144 153.6 S
-(le is incorrectly formatted.)159.28 153.6 Q([EINV)108 170.4 Q(AL])-1.35 E
-2.812(Ap)144 182.4 S .313(arameter has been speci\214ed \(hash function, pad b\
-yte etc.\) that is incompatible with the current)159.032 182.4 R .406
-(\214le speci\214cation or which is not meaningful for the function \(for e)144
-194.4 R .405(xample, use of the cursor with-)-.15 F .099
-(out prior initialization\) or there is a mismatch between the v)144 206.4 R .1
-(ersion number of \214le and the softw)-.15 F(are.)-.1 E(The)108 223.2 Q F2
-(close)3.469 E F0 .969(routines may f)3.469 F .969(ail and set)-.1 F F2(errno)
-3.469 E F0 .969(for an)3.469 F 3.469(yo)-.15 G 3.469(ft)320.18 223.2 S .969
-(he errors speci\214ed for the library routines)329.759 223.2 R F2(close)3.468
-E F0(\(2\),).18 E F2 -.37(re)108 235.2 S(ad).37 E F0(\(2\),).77 E F2(write)2.5
-E F0(\(2\),).18 E F2(fr)2.5 E(ee)-.37 E F0(\(3\), or).18 E F2(fsync)2.5 E F0
-(\(2\).).31 E(The)108 252 Q F2(del)2.969 E F0(,).51 E F2 -.1(ge)2.969 G(t).1 E
-F0(,).68 E F2(put)2.969 E F0(and)2.969 E F2(seq)2.969 E F0 .469(routines may f)
-2.969 F .469(ail and set)-.1 F F2(errno)2.97 E F0 .47(for an)2.97 F 2.97(yo)
--.15 G 2.97(ft)377.59 252 S .47(he errors speci\214ed for the library rou-)
-386.67 252 R(tines)108 264 Q F2 -.37(re)2.5 G(ad).37 E F0(\(2\),).77 E F2
-(write)2.5 E F0(\(2\),).18 E F2(fr)2.5 E(ee)-.37 E F0(\(3\) or).18 E F2(malloc)
-2.5 E F0(\(3\).).31 E(The)108 280.8 Q F2(fd)2.5 E F0(routines will f)2.5 E
-(ail and set)-.1 E F2(errno)2.5 E F0(to ENOENT for in memory databases.)2.5 E
-(The)108 297.6 Q F2(sync)2.5 E F0(routines may f)2.5 E(ail and set)-.1 E F2
-(errno)2.5 E F0(for an)2.5 E 2.5(yo)-.15 G 2.5(ft)307.71 297.6 S
-(he errors speci\214ed for the library routine)316.32 297.6 Q F2(fsync)2.5 E F0
-(\(2\).).31 E F1(SEE ALSO)72 314.4 Q F2(btr)108 326.4 Q(ee)-.37 E F0(\(3\),).18
-E F2(hash)2.5 E F0(\(3\),).28 E F2(mpool)2.5 E F0(\(3\),).51 E F2 -.37(re)2.5 G
-(cno).37 E F0(\(3\)).18 E F1 -.09(BU)72 343.2 S(GS).09 E F0 .399
-(The typedef DBT is a mnemonic for `)108 355.2 R .399(`data base thang')-.74 F
-.399(', and w)-.74 F .399(as used because noone could think of a rea-)-.1 F
-(sonable name that w)108 367.2 Q(asn')-.1 E 2.5(ta)-.18 G(lready used.)216.03
-367.2 Q(The \214le descriptor interf)108 384 Q
-(ace is a kluge and will be deleted in a future v)-.1 E(ersion of the interf)
--.15 E(ace.)-.1 E(None of the access methods pro)108 400.8 Q(vide an)-.15 E 2.5
-(yf)-.15 G(orm of concurrent access, locking, or transactions.)275.16 400.8 Q
-209.835(24, May)72 768 R(4)535 768 Q EP
-%%Trailer
-end
-%%EOF
diff --git a/lib/libc/db/doc/hash.3.ps b/lib/libc/db/doc/hash.3.ps
deleted file mode 100644
index 8551b86d8ff2..000000000000
--- a/lib/libc/db/doc/hash.3.ps
+++ /dev/null
@@ -1,289 +0,0 @@
-%!PS-Adobe-3.0
-%%Creator: groff version 1.08
-%%DocumentNeededResources: font Times-Roman
-%%+ font Times-Bold
-%%+ font Times-Italic
-%%DocumentSuppliedResources: procset grops 1.08 0
-%%Pages: 2
-%%PageOrder: Ascend
-%%Orientation: Portrait
-%%EndComments
-%%BeginProlog
-%%BeginResource: procset grops 1.08 0
-/setpacking where{
-pop
-currentpacking
-true setpacking
-}if
-/grops 120 dict dup begin
-/SC 32 def
-/A/show load def
-/B{0 SC 3 -1 roll widthshow}bind def
-/C{0 exch ashow}bind def
-/D{0 exch 0 SC 5 2 roll awidthshow}bind def
-/E{0 rmoveto show}bind def
-/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
-/G{0 rmoveto 0 exch ashow}bind def
-/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/I{0 exch rmoveto show}bind def
-/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
-/K{0 exch rmoveto 0 exch ashow}bind def
-/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/M{rmoveto show}bind def
-/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
-/O{rmoveto 0 exch ashow}bind def
-/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/Q{moveto show}bind def
-/R{moveto 0 SC 3 -1 roll widthshow}bind def
-/S{moveto 0 exch ashow}bind def
-/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/SF{
-findfont exch
-[exch dup 0 exch 0 exch neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/MF{
-findfont
-[5 2 roll
-0 3 1 roll
-neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/level0 0 def
-/RES 0 def
-/PL 0 def
-/LS 0 def
-/PLG{
-gsave newpath clippath pathbbox grestore
-exch pop add exch pop
-}bind def
-/BP{
-/level0 save def
-1 setlinecap
-1 setlinejoin
-72 RES div dup scale
-LS{
-90 rotate
-}{
-0 PL translate
-}ifelse
-1 -1 scale
-}bind def
-/EP{
-level0 restore
-showpage
-}bind def
-/DA{
-newpath arcn stroke
-}bind def
-/SN{
-transform
-.25 sub exch .25 sub exch
-round .25 add exch round .25 add exch
-itransform
-}bind def
-/DL{
-SN
-moveto
-SN
-lineto stroke
-}bind def
-/DC{
-newpath 0 360 arc closepath
-}bind def
-/TM matrix def
-/DE{
-TM currentmatrix pop
-translate scale newpath 0 0 .5 0 360 arc closepath
-TM setmatrix
-}bind def
-/RC/rcurveto load def
-/RL/rlineto load def
-/ST/stroke load def
-/MT/moveto load def
-/CL/closepath load def
-/FL{
-currentgray exch setgray fill setgray
-}bind def
-/BL/fill load def
-/LW/setlinewidth load def
-/RE{
-findfont
-dup maxlength 1 index/FontName known not{1 add}if dict begin
-{
-1 index/FID ne{def}{pop pop}ifelse
-}forall
-/Encoding exch def
-dup/FontName exch def
-currentdict end definefont pop
-}bind def
-/DEFS 0 def
-/EBEGIN{
-moveto
-DEFS begin
-}bind def
-/EEND/end load def
-/CNT 0 def
-/level1 0 def
-/PBEGIN{
-/level1 save def
-translate
-div 3 1 roll div exch scale
-neg exch neg exch translate
-0 setgray
-0 setlinecap
-1 setlinewidth
-0 setlinejoin
-10 setmiterlimit
-[]0 setdash
-/setstrokeadjust where{
-pop
-false setstrokeadjust
-}if
-/setoverprint where{
-pop
-false setoverprint
-}if
-newpath
-/CNT countdictstack def
-userdict begin
-/showpage{}def
-}bind def
-/PEND{
-clear
-countdictstack CNT sub{end}repeat
-level1 restore
-}bind def
-end def
-/setpacking where{
-pop
-setpacking
-}if
-%%EndResource
-%%IncludeResource: font Times-Roman
-%%IncludeResource: font Times-Bold
-%%IncludeResource: font Times-Italic
-grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
-792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
-/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
-/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
-/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
-/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/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/bracketleft/backslash
-/bracketright/circumflex/underscore/quoteleft/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/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
-/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
-/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
-/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
-/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
-/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
-/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
-/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
-/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
-/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
-/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
-/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
-/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
-/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
-/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
-/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE
-/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE
-%%EndProlog
-%%Page: 1 1
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF 182.62(HASH\(3\) 1993 HASH\(3\))72 48 R/F1 9
-/Times-Bold@0 SF -.18(NA)72 84 S(ME).18 E F0
-(hash \255 hash database access method)108 96 Q F1(SYNOPSIS)72 112.8 Q/F2 10
-/Times-Bold@0 SF(#include <sys/types.h>)108 124.8 Q(#include <db)108 136.8 Q
-(.h>)-.4 E F1(DESCRIPTION)72 153.6 Q F0 .29(The routine)108 165.6 R/F3 10
-/Times-Italic@0 SF(dbopen)2.79 E F0 .29(is the library interf)2.79 F .29
-(ace to database \214les.)-.1 F .29
-(One of the supported \214le formats is hash \214les.)5.29 F .974
-(The general description of the database access methods is in)108 177.6 R F3
-(dbopen)3.475 E F0 .975(\(3\), this manual page describes only).24 F
-(the hash speci\214c information.)108 189.6 Q(The hash data structure is an e)
-108 206.4 Q(xtensible, dynamic hashing scheme.)-.15 E .83
-(The access method speci\214c data structure pro)108 223.2 R .83(vided to)-.15
-F F3(dbopen)3.33 E F0 .83(is de\214ned in the <db)3.33 F .83
-(.h> include \214le as fol-)-.4 F(lo)108 235.2 Q(ws:)-.25 E(typedef struct {)
-108 259.2 Q(int bsize;)144 271.2 Q(int cachesize;)144 283.2 Q(int f)144 295.2 Q
--.1(fa)-.25 G(ctor;).1 E(u_long \(*hash\)\(const v)144 307.2 Q
-(oid *, size_t\);)-.2 E(int lorder;)144 319.2 Q(int nelem;)144 331.2 Q 2.5(}H)
-108 343.2 S(ASHINFO;)122.52 343.2 Q
-(The elements of this structure are as follo)108 360 Q(ws:)-.25 E(bsize)108
-376.8 Q F3(Bsize)144 376.8 Q F0 1.393(de\214nes the hash table b)3.893 F(uck)
--.2 E 1.393(et size, and is, by def)-.1 F 1.394(ault, 256 bytes.)-.1 F 1.394
-(It may be preferable to)6.394 F
-(increase the page size for disk-resident tables and tables with lar)144 388.8
-Q(ge data items.)-.18 E(cachesize)108 405.6 Q 3.16(As)144 417.6 S .66
-(uggested maximum size, in bytes, of the memory cache.)158.27 417.6 R .659
-(This v)5.659 F .659(alue is)-.25 F F2(only)3.159 E F0(advisory)3.159 E 3.159
-(,a)-.65 G .659(nd the)514.621 417.6 R
-(access method will allocate more memory rather than f)144 429.6 Q(ail.)-.1 E
--2.1 -.25(ff a)108 446.4 T(ctor).25 E F3(Ffactor)9.7 E F0 .482
-(indicates a desired density within the hash table.)2.981 F .482
-(It is an approximation of the number of)5.482 F -.1(ke)144 458.4 S .429
-(ys allo)-.05 F .429(wed to accumulate in an)-.25 F 2.929(yo)-.15 G .429(ne b)
-291.454 458.4 R(uck)-.2 E .429(et, determining when the hash table gro)-.1 F
-.428(ws or shrinks.)-.25 F(The def)144 470.4 Q(ault v)-.1 E(alue is 8.)-.25 E
-(hash)108 487.2 Q F3(Hash)144 487.2 Q F0 .1(is a user de\214ned hash function.)
-2.6 F .1(Since no hash function performs equally well on all possible)5.1 F
-.924(data, the user may \214nd that the b)144 499.2 R .923
-(uilt-in hash function does poorly on a particular data set.)-.2 F(User)5.923 E
-1.408(speci\214ed hash functions must tak)144 511.2 R 3.909(et)-.1 G 1.609 -.1
-(wo a)293.431 511.2 T -.18(rg).1 G 1.409
-(uments \(a pointer to a byte string and a length\) and).18 F
-(return an u_long to be used as the hash v)144 523.2 Q(alue.)-.25 E 9.62
-(lorder The)108 540 R 1.597(byte order for inte)4.097 F 1.596
-(gers in the stored database metadata.)-.15 F 1.596
-(The number should represent the)6.596 F .688(order as an inte)144 552 R .689
-(ger; for e)-.15 F .689(xample, big endian order w)-.15 F .689
-(ould be the number 4,321.)-.1 F(If)5.689 E F3(lor)3.189 E(der)-.37 E F0 .689
-(is 0 \(no)3.189 F .822(order is speci\214ed\) the current host order is used.)
-144 564 R .822(If the)5.822 F .822(\214le already e)5.822 F .821
-(xists, the speci\214ed v)-.15 F .821(alue is)-.25 F(ignored and the v)144 576
-Q(alue speci\214ed when the tree w)-.25 E(as created is used.)-.1 E(nelem)108
-592.8 Q F3(Nelem)144 592.8 Q F0 .701
-(is an estimate of the \214nal size of the hash table.)3.2 F .701
-(If not set or set too lo)5.701 F 2.001 -.65(w, h)-.25 H .701(ash tables will)
-.65 F -.15(ex)144 604.8 S .448(pand gracefully as k).15 F -.15(ey)-.1 G 2.948
-(sa).15 G .448(re entered, although a slight performance de)255.912 604.8 R
-.447(gradation may be noticed.)-.15 F(The def)144 616.8 Q(ault v)-.1 E
-(alue is 1.)-.25 E .79(If the \214le already e)108 633.6 R .79
-(xists \(and the O_TR)-.15 F .79(UNC \215ag is not speci\214ed\), the v)-.4 F
-.79(alues speci\214ed for the parameters)-.25 F(bsize, f)108 645.6 Q -.1(fa)
--.25 G(ctor).1 E 2.5(,l)-.4 G(order and nelem are ignored and the v)167.23
-645.6 Q(alues speci\214ed when the tree w)-.25 E(as created are used.)-.1 E
-1.232(If a hash function is speci\214ed,)108 662.4 R F3(hash_open)3.731 E F0
-1.231(will attempt to determine if the hash function speci\214ed is the)3.731 F
-(same as the one with which the database w)108 674.4 Q(as created, and will f)
--.1 E(ail if it is not.)-.1 E(Backw)108 691.2 Q .861(ard compatible interf)-.1
-F .861(aces to the routines described in)-.1 F F3(dbm)3.362 E F0 .862
-(\(3\), and).32 F F3(ndbm)3.362 E F0 .862(\(3\) are pro).32 F .862(vided, ho)
--.15 F(we)-.25 E -.15(ve)-.25 G -.4(r,).15 G(these interf)108 703.2 Q
-(aces are not compatible with pre)-.1 E(vious \214le formats.)-.25 E 214.835
-(6, June)72 768 R(1)535 768 Q EP
-%%Page: 2 2
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF 182.62(HASH\(3\) 1993 HASH\(3\))72 48 R/F1 9
-/Times-Bold@0 SF(SEE ALSO)72 84 Q/F2 10/Times-Italic@0 SF(btr)108 96 Q(ee)-.37
-E F0(\(3\),).18 E F2(dbopen)2.5 E F0(\(3\),).24 E F2(mpool)2.5 E F0(\(3\),).51
-E F2 -.37(re)2.5 G(cno).37 E F0(\(3\)).18 E F2(Dynamic Hash T)108 108 Q(ables)
--.92 E F0 2.5(,P).27 G(er)206.79 108 Q(-Ak)-.2 E 2.5(eL)-.1 G
-(arson, Communications of the A)242.86 108 Q(CM, April 1988.)-.4 E F2 2.5(AN)
-108 120 S .3 -.15(ew H)123.28 120 T(ash P).15 E(ac)-.8 E(ka)-.2 E .2 -.1(ge f)
--.1 H(or UNIX).1 E F0 2.5(,M).94 G(ar)248.41 120 Q(go Seltzer)-.18 E 2.5(,U)-.4
-G(SENIX Proceedings, W)308.09 120 Q(inter 1991.)-.4 E F1 -.09(BU)72 136.8 S(GS)
-.09 E F0(Only big and little endian byte order is supported.)108 148.8 Q
-214.835(6, June)72 768 R(2)535 768 Q EP
-%%Trailer
-end
-%%EOF
diff --git a/lib/libc/db/doc/hash.ps b/lib/libc/db/doc/hash.ps
deleted file mode 100644
index 601e375d6c40..000000000000
--- a/lib/libc/db/doc/hash.ps
+++ /dev/null
@@ -1,12209 +0,0 @@
-%!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: /a/cvs/386BSD/src/lib/libc/db/doc/hash.ps,v 1.1 1993/06/16 02:20:49 rgrimes Exp $
-
-% 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/mpool.3.ps b/lib/libc/db/doc/mpool.3.ps
deleted file mode 100644
index f595480d6be6..000000000000
--- a/lib/libc/db/doc/mpool.3.ps
+++ /dev/null
@@ -1,318 +0,0 @@
-%!PS-Adobe-3.0
-%%Creator: groff version 1.08
-%%DocumentNeededResources: font Times-Roman
-%%+ font Times-Bold
-%%+ font Times-Italic
-%%DocumentSuppliedResources: procset grops 1.08 0
-%%Pages: 2
-%%PageOrder: Ascend
-%%Orientation: Portrait
-%%EndComments
-%%BeginProlog
-%%BeginResource: procset grops 1.08 0
-/setpacking where{
-pop
-currentpacking
-true setpacking
-}if
-/grops 120 dict dup begin
-/SC 32 def
-/A/show load def
-/B{0 SC 3 -1 roll widthshow}bind def
-/C{0 exch ashow}bind def
-/D{0 exch 0 SC 5 2 roll awidthshow}bind def
-/E{0 rmoveto show}bind def
-/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
-/G{0 rmoveto 0 exch ashow}bind def
-/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/I{0 exch rmoveto show}bind def
-/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
-/K{0 exch rmoveto 0 exch ashow}bind def
-/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/M{rmoveto show}bind def
-/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
-/O{rmoveto 0 exch ashow}bind def
-/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/Q{moveto show}bind def
-/R{moveto 0 SC 3 -1 roll widthshow}bind def
-/S{moveto 0 exch ashow}bind def
-/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/SF{
-findfont exch
-[exch dup 0 exch 0 exch neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/MF{
-findfont
-[5 2 roll
-0 3 1 roll
-neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/level0 0 def
-/RES 0 def
-/PL 0 def
-/LS 0 def
-/PLG{
-gsave newpath clippath pathbbox grestore
-exch pop add exch pop
-}bind def
-/BP{
-/level0 save def
-1 setlinecap
-1 setlinejoin
-72 RES div dup scale
-LS{
-90 rotate
-}{
-0 PL translate
-}ifelse
-1 -1 scale
-}bind def
-/EP{
-level0 restore
-showpage
-}bind def
-/DA{
-newpath arcn stroke
-}bind def
-/SN{
-transform
-.25 sub exch .25 sub exch
-round .25 add exch round .25 add exch
-itransform
-}bind def
-/DL{
-SN
-moveto
-SN
-lineto stroke
-}bind def
-/DC{
-newpath 0 360 arc closepath
-}bind def
-/TM matrix def
-/DE{
-TM currentmatrix pop
-translate scale newpath 0 0 .5 0 360 arc closepath
-TM setmatrix
-}bind def
-/RC/rcurveto load def
-/RL/rlineto load def
-/ST/stroke load def
-/MT/moveto load def
-/CL/closepath load def
-/FL{
-currentgray exch setgray fill setgray
-}bind def
-/BL/fill load def
-/LW/setlinewidth load def
-/RE{
-findfont
-dup maxlength 1 index/FontName known not{1 add}if dict begin
-{
-1 index/FID ne{def}{pop pop}ifelse
-}forall
-/Encoding exch def
-dup/FontName exch def
-currentdict end definefont pop
-}bind def
-/DEFS 0 def
-/EBEGIN{
-moveto
-DEFS begin
-}bind def
-/EEND/end load def
-/CNT 0 def
-/level1 0 def
-/PBEGIN{
-/level1 save def
-translate
-div 3 1 roll div exch scale
-neg exch neg exch translate
-0 setgray
-0 setlinecap
-1 setlinewidth
-0 setlinejoin
-10 setmiterlimit
-[]0 setdash
-/setstrokeadjust where{
-pop
-false setstrokeadjust
-}if
-/setoverprint where{
-pop
-false setoverprint
-}if
-newpath
-/CNT countdictstack def
-userdict begin
-/showpage{}def
-}bind def
-/PEND{
-clear
-countdictstack CNT sub{end}repeat
-level1 restore
-}bind def
-end def
-/setpacking where{
-pop
-setpacking
-}if
-%%EndResource
-%%IncludeResource: font Times-Roman
-%%IncludeResource: font Times-Bold
-%%IncludeResource: font Times-Italic
-grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
-792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
-/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
-/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
-/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
-/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/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/bracketleft/backslash
-/bracketright/circumflex/underscore/quoteleft/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/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
-/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
-/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
-/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
-/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
-/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
-/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
-/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
-/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
-/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
-/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
-/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
-/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
-/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
-/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
-/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE
-/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE
-%%EndProlog
-%%Page: 1 1
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF 174.84(MPOOL\(3\) 1991 MPOOL\(3\))72 48 R/F1 9
-/Times-Bold@0 SF -.18(NA)72 84 S(ME).18 E F0(mpool \255 shared memory b)108 96
-Q(uf)-.2 E(fer pool)-.25 E F1(SYNOPSIS)72 112.8 Q/F2 10/Times-Bold@0 SF
-(#include <db)108 124.8 Q(.h>)-.4 E(#include <mpool.h>)108 136.8 Q(MPOOL *)108
-160.8 Q(mpool_open \(DBT *k)108 172.8 Q(ey)-.1 E 2.5(,i)-.55 G
-(nt fd, pgno_t pagesize, pgno_t maxcache\);)216.25 172.8 Q -.1(vo)108 196.8 S
-(id).1 E(mpool_\214lter \(MPOOL *mp, v)108 208.8 Q(oid \(*pgin\)\(v)-.1 E
-(oid *, pgno_t, v)-.1 E(oid *\),)-.1 E -.1(vo)158 220.8 S(id \(*pgout\)\(v).1 E
-(oid *, pgno_t, v)-.1 E(oid *\), v)-.1 E(oid *pgcookie\);)-.1 E -.1(vo)108
-244.8 S(id *).1 E(mpool_new \(MPOOL *mp, pgno_t *pgnoaddr\);)108 256.8 Q -.1
-(vo)108 280.8 S(id *).1 E(mpool_get \(MPOOL *mp, pgno_t pgno, u_int \215ags\);)
-108 292.8 Q(int)108 316.8 Q(mpool_put \(MPOOL *mp, v)108 328.8 Q(oid *pgaddr)
--.1 E 2.5(,u)-.92 G(_int \215ags\);)290.62 328.8 Q(int)108 352.8 Q
-(mpool_sync \(MPOOL *mp\);)108 364.8 Q(int)108 388.8 Q
-(mpool_close \(MPOOL *mp\);)108 400.8 Q F1(DESCRIPTION)72 417.6 Q/F3 10
-/Times-Italic@0 SF(Mpool)108 429.6 Q F0 1.013(is the library interf)3.513 F
-1.013(ace intended to pro)-.1 F 1.013(vide page oriented b)-.15 F(uf)-.2 E
-1.012(fer management of \214les.)-.25 F 1.012(The b)6.012 F(uf)-.2 E(fers)-.25
-E(may be shared between processes.)108 441.6 Q .416(The function)108 458.4 R F3
-(mpool_open)2.916 E F0 .417(initializes a memory pool.)2.917 F(The)5.417 E F3
--.1(ke)2.917 G(y)-.2 E F0(ar)2.917 E .417(gument is the byte string used to ne)
--.18 F(gotiate)-.15 E .697(between multiple processes wishing to share b)108
-470.4 R(uf)-.2 E 3.196(fers. If)-.25 F .696(the \214le b)3.196 F(uf)-.2 E .696
-(fers are mapped in shared memory)-.25 F 3.196(,a)-.65 G(ll)534.44 470.4 Q .894
-(processes using the same k)108 482.4 R 1.194 -.15(ey w)-.1 H .894
-(ill share the b).15 F(uf)-.2 E 3.394(fers. If)-.25 F F3 -.1(ke)3.394 G(y)-.2 E
-F0 .895(is NULL, the b)3.395 F(uf)-.2 E .895(fers are mapped into pri)-.25 F
--.25(va)-.25 G(te).25 E(memory)108 494.4 Q 5.116(.T)-.65 G(he)154.406 494.4 Q
-F3(fd)2.616 E F0(ar)2.616 E .115(gument is a \214le descriptor for the underly\
-ing \214le, which must be seekable.)-.18 F(If)5.115 E F3 -.1(ke)2.615 G(y)-.2 E
-F0 .115(is non-)2.615 F(NULL and matches a \214le already being mapped, the)108
-506.4 Q F3(fd)2.5 E F0(ar)2.5 E(gument is ignored.)-.18 E(The)108 523.2 Q F3
-(pa)3.328 E -.1(ge)-.1 G(size).1 E F0(ar)3.329 E .829
-(gument is the size, in bytes, of the pages into which the \214le is brok)-.18
-F .829(en up.)-.1 F(The)5.829 E F3(maxcac)3.329 E(he)-.15 E F0(ar)108 535.2 Q
-.153(gument is the maximum number of pages from the underlying \214le to cache\
- at an)-.18 F 2.653(yo)-.15 G .153(ne time.)451.308 535.2 R .153(This v)5.153 F
-.153(alue is)-.25 F .099(not relati)108 547.2 R .399 -.15(ve t)-.25 H 2.599(ot)
-.15 G .099(he number of processes which share a \214le')168.727 547.2 R 2.6(sb)
--.55 G(uf)350.39 547.2 Q .1(fers, b)-.25 F .1(ut will be the lar)-.2 F .1
-(gest v)-.18 F .1(alue speci\214ed by)-.25 F(an)108 559.2 Q 2.5(yo)-.15 G 2.5
-(ft)129.79 559.2 S(he processes sharing the \214le.)138.4 559.2 Q(The)108 576 Q
-F3(mpool_\214lter)3.254 E F0 .754(function is intended to mak)3.254 F 3.254(et)
--.1 G .754(ransparent input and output processing of the pages possi-)301.778
-576 R 3.095(ble. If)108 588 R(the)3.095 E F3(pgin)3.095 E F0 .596
-(function is speci\214ed, it is called each time a b)3.095 F(uf)-.2 E .596
-(fer is read into the memory pool from the)-.25 F .125(backing \214le.)108 600
-R .125(If the)5.125 F F3(pgout)2.625 E F0 .125
-(function is speci\214ed, it is called each time a b)2.625 F(uf)-.2 E .125
-(fer is written into the backing \214le.)-.25 F .276
-(Both functions are are called with the)108 612 R F3(pgcookie)2.777 E F0
-(pointer)2.777 E 2.777(,t)-.4 G .277
-(he page number and a pointer to the page to being)337.27 612 R
-(read or written.)108 624 Q .124(The function)108 640.8 R F3(mpool_ne)2.624 E
-(w)-.15 E F0(tak)2.624 E .123(es an MPOOL pointer and an address as ar)-.1 F
-2.623(guments. If)-.18 F 2.623(an)2.623 G .623 -.25(ew p)457.568 640.8 T .123
-(age can be allo-).25 F .944(cated, a pointer to the page is returned and the \
-page number is stored into the)108 652.8 R F3(pgnoaddr)3.445 E F0 3.445
-(address. Other)3.445 F(-)-.2 E(wise, NULL is returned and errno is set.)108
-664.8 Q 1.167(The function)108 681.6 R F3(mpool_g)3.667 E(et)-.1 E F0(tak)3.667
-E 1.167(es a MPOOL pointer and a page number as ar)-.1 F 3.666(guments. If)-.18
-F 1.166(the page e)3.666 F 1.166(xists, a)-.15 F .686
-(pointer to the page is returned.)108 693.6 R .687
-(Otherwise, NULL is returned and errno is set.)5.686 F .687
-(The \215ags parameter is not)5.687 F(currently used.)108 705.6 Q 1.463
-(The function)108 722.4 R F3(mpool_put)3.963 E F0 1.462
-(unpins the page referenced by)3.962 F F3(pgaddr)3.962 E F0(.).73 E F3(Pgaddr)
-6.462 E F0 1.462(must be an address pre)3.962 F(viously)-.25 E 197.615
-(12, September)72 768 R(1)535 768 Q EP
-%%Page: 2 2
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF 174.84(MPOOL\(3\) 1991 MPOOL\(3\))72 48 R(returned by)
-108 84 Q/F1 10/Times-Italic@0 SF(mpool_g)2.5 E(et)-.1 E F0(or)2.5 E F1
-(mpool_ne)2.5 E(w)-.15 E F0 5(.T).31 G(he \215ag v)271.65 84 Q
-(alue is speci\214ed by)-.25 E F1(or)2.5 E F0('ing an).73 E 2.5(yo)-.15 G 2.5
-(ft)434.74 84 S(he follo)443.35 84 Q(wing v)-.25 E(alues:)-.25 E(MPOOL_DIR)108
-100.8 Q(TY)-.6 E
-(The page has been modi\214ed and needs to be written to the backing \214le.)
-144 112.8 Q F1(Mpool_put)108 129.6 Q F0
-(returns 0 on success and -1 if an error occurs.)2.5 E .247(The function)108
-146.4 R F1(mpool_sync)2.747 E F0 .247(writes all modi\214ed pages associated w\
-ith the MPOOL pointer to the backing \214le.)2.747 F F1(Mpool_sync)108 158.4 Q
-F0(returns 0 on success and -1 if an error occurs.)2.5 E(The)108 175.2 Q F1
-(mpool_close)2.698 E F0 .198(function free')2.698 F 2.698(su)-.55 G 2.698(pa)
-245.432 175.2 S .498 -.15(ny a)257.57 175.2 T .198
-(llocated memory associated with the memory pool cookie.).15 F(Modi-)5.197 E
-(\214ed pages are)108 187.2 Q/F2 10/Times-Bold@0 SF(not)2.5 E F0
-(written to the backing \214le.)2.5 E F1(Mpool_close)5 E F0
-(returns 0 on success and -1 if an error occurs.)2.5 E/F3 9/Times-Bold@0 SF
-(ERR)72 204 Q(ORS)-.27 E F0(The)108 216 Q F1(mpool_open)2.938 E F0 .438
-(function may f)2.938 F .438(ail and set)-.1 F F1(errno)2.938 E F0 .438(for an)
-2.938 F 2.938(yo)-.15 G 2.938(ft)344.87 216 S .439
-(he errors speci\214ed for the library routine)353.918 216 R F1(mal-)2.939 E
-(loc)108 228 Q F0(\(3\).).31 E(The)108 244.8 Q F1(mpool_g)2.5 E(et)-.1 E F0
-(function may f)2.5 E(ail and set)-.1 E F1(errno)2.5 E F0(for the follo)2.5 E
-(wing:)-.25 E([EINV)108 261.6 Q 29.98(AL] The)-1.35 F(requested record doesn')
-2.5 E 2.5(te)-.18 G(xist.)305.96 261.6 Q(The)108 278.4 Q F1(mpool_ne)4.073 E(w)
--.15 E F0(and)4.073 E F1(mpool_g)4.073 E(et)-.1 E F0 1.573(functions may f)
-4.073 F 1.573(ail and set)-.1 F F1(errno)4.073 E F0 1.573(for an)4.073 F 4.073
-(yo)-.15 G 4.073(ft)421.336 278.4 S 1.573(he errors speci\214ed for the)431.519
-278.4 R(library routines)108 290.4 Q F1 -.37(re)2.5 G(ad).37 E F0(\(2\)).77 E
-F1 2.5(,w).54 G(rite)214.48 290.4 Q F0(\(2\)).18 E F1(,).54 E F0(and)2.5 E F1
-(malloc)2.5 E F0(\(3\).).31 E(The)108 307.2 Q F1(mpool_sync)4.287 E F0 1.787
-(function may f)4.287 F 1.787(ail and set)-.1 F F1(errno)4.288 E F0 1.788
-(for an)4.288 F 4.288(yo)-.15 G 4.288(ft)356.694 307.2 S 1.788
-(he errors speci\214ed for the library routine)367.092 307.2 R F1(write)108
-319.2 Q F0(\(2\).).18 E(The)108 336 Q F1(mpool_close)4.125 E F0 1.624
-(function may f)4.125 F 1.624(ail and set)-.1 F F1(errno)4.124 E F0 1.624
-(for an)4.124 F 4.124(yo)-.15 G 4.124(ft)357.842 336 S 1.624
-(he errors speci\214ed for the library routine)368.076 336 R F1(fr)108 348 Q
-(ee)-.37 E F0(\(3\).).18 E F3(SEE ALSO)72 364.8 Q F1(dbopen)108 376.8 Q F0
-(\(3\),).24 E F1(btr)2.5 E(ee)-.37 E F0(\(3\),).18 E F1(hash)2.5 E F0(\(3\),)
-.28 E F1 -.37(re)2.5 G(cno).37 E F0(\(3\)).18 E 197.615(12, September)72 768 R
-(2)535 768 Q EP
-%%Trailer
-end
-%%EOF
diff --git a/lib/libc/db/doc/recno.3.ps b/lib/libc/db/doc/recno.3.ps
deleted file mode 100644
index 6ea5344151d7..000000000000
--- a/lib/libc/db/doc/recno.3.ps
+++ /dev/null
@@ -1,317 +0,0 @@
-%!PS-Adobe-3.0
-%%Creator: groff version 1.08
-%%DocumentNeededResources: font Times-Roman
-%%+ font Times-Bold
-%%+ font Times-Italic
-%%DocumentSuppliedResources: procset grops 1.08 0
-%%Pages: 2
-%%PageOrder: Ascend
-%%Orientation: Portrait
-%%EndComments
-%%BeginProlog
-%%BeginResource: procset grops 1.08 0
-/setpacking where{
-pop
-currentpacking
-true setpacking
-}if
-/grops 120 dict dup begin
-/SC 32 def
-/A/show load def
-/B{0 SC 3 -1 roll widthshow}bind def
-/C{0 exch ashow}bind def
-/D{0 exch 0 SC 5 2 roll awidthshow}bind def
-/E{0 rmoveto show}bind def
-/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
-/G{0 rmoveto 0 exch ashow}bind def
-/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/I{0 exch rmoveto show}bind def
-/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
-/K{0 exch rmoveto 0 exch ashow}bind def
-/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/M{rmoveto show}bind def
-/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
-/O{rmoveto 0 exch ashow}bind def
-/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/Q{moveto show}bind def
-/R{moveto 0 SC 3 -1 roll widthshow}bind def
-/S{moveto 0 exch ashow}bind def
-/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
-/SF{
-findfont exch
-[exch dup 0 exch 0 exch neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/MF{
-findfont
-[5 2 roll
-0 3 1 roll
-neg 0 0]makefont
-dup setfont
-[exch/setfont cvx]cvx bind def
-}bind def
-/level0 0 def
-/RES 0 def
-/PL 0 def
-/LS 0 def
-/PLG{
-gsave newpath clippath pathbbox grestore
-exch pop add exch pop
-}bind def
-/BP{
-/level0 save def
-1 setlinecap
-1 setlinejoin
-72 RES div dup scale
-LS{
-90 rotate
-}{
-0 PL translate
-}ifelse
-1 -1 scale
-}bind def
-/EP{
-level0 restore
-showpage
-}bind def
-/DA{
-newpath arcn stroke
-}bind def
-/SN{
-transform
-.25 sub exch .25 sub exch
-round .25 add exch round .25 add exch
-itransform
-}bind def
-/DL{
-SN
-moveto
-SN
-lineto stroke
-}bind def
-/DC{
-newpath 0 360 arc closepath
-}bind def
-/TM matrix def
-/DE{
-TM currentmatrix pop
-translate scale newpath 0 0 .5 0 360 arc closepath
-TM setmatrix
-}bind def
-/RC/rcurveto load def
-/RL/rlineto load def
-/ST/stroke load def
-/MT/moveto load def
-/CL/closepath load def
-/FL{
-currentgray exch setgray fill setgray
-}bind def
-/BL/fill load def
-/LW/setlinewidth load def
-/RE{
-findfont
-dup maxlength 1 index/FontName known not{1 add}if dict begin
-{
-1 index/FID ne{def}{pop pop}ifelse
-}forall
-/Encoding exch def
-dup/FontName exch def
-currentdict end definefont pop
-}bind def
-/DEFS 0 def
-/EBEGIN{
-moveto
-DEFS begin
-}bind def
-/EEND/end load def
-/CNT 0 def
-/level1 0 def
-/PBEGIN{
-/level1 save def
-translate
-div 3 1 roll div exch scale
-neg exch neg exch translate
-0 setgray
-0 setlinecap
-1 setlinewidth
-0 setlinejoin
-10 setmiterlimit
-[]0 setdash
-/setstrokeadjust where{
-pop
-false setstrokeadjust
-}if
-/setoverprint where{
-pop
-false setoverprint
-}if
-newpath
-/CNT countdictstack def
-userdict begin
-/showpage{}def
-}bind def
-/PEND{
-clear
-countdictstack CNT sub{end}repeat
-level1 restore
-}bind def
-end def
-/setpacking where{
-pop
-setpacking
-}if
-%%EndResource
-%%IncludeResource: font Times-Roman
-%%IncludeResource: font Times-Bold
-%%IncludeResource: font Times-Italic
-grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
-792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
-/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
-/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
-/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
-/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
-/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/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/bracketleft/backslash
-/bracketright/circumflex/underscore/quoteleft/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/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
-/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
-/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
-/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
-/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
-/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
-/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
-/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
-/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
-/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
-/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
-/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
-/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
-/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
-/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
-/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE
-/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE
-%%EndProlog
-%%Page: 1 1
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF 175.95(RECNO\(3\) 1993 RECNO\(3\))72 48 R/F1 9
-/Times-Bold@0 SF -.18(NA)72 84 S(ME).18 E F0
-(recno \255 record number database access method)108 96 Q F1(SYNOPSIS)72 112.8
-Q/F2 10/Times-Bold@0 SF(#include <sys/types.h>)108 124.8 Q(#include <db)108
-136.8 Q(.h>)-.4 E F1(DESCRIPTION)72 153.6 Q F0 1.158(The routine)108 165.6 R/F3
-10/Times-Italic@0 SF(dbopen)3.658 E F0 1.158(is the library interf)3.658 F
-1.158(ace to database \214les.)-.1 F 1.157
-(One of the supported \214le formats is record)6.158 F 1.159(number \214les.)
-108 177.6 R 1.159(The general description of the database access methods is in)
-6.159 F F3(dbopen)3.66 E F0 1.16(\(3\), this manual page).24 F
-(describes only the recno speci\214c information.)108 189.6 Q 1.944
-(The record number data structure is either v)108 206.4 R 1.944
-(ariable or \214x)-.25 F 1.944
-(ed-length records stored in a \215at-\214le format,)-.15 F 2.04
-(accessed by the logical record number)108 218.4 R 7.04(.T)-.55 G 2.04(he e)
-286.31 218.4 R 2.04(xistence of record number \214v)-.15 F 4.54(ei)-.15 G 2.04
-(mplies the e)442.1 218.4 R 2.04(xistence of)-.15 F .876
-(records one through four)108 230.4 R 3.376(,a)-.4 G .875
-(nd the deletion of record number one causes record number \214v)219.684 230.4
-R 3.375(et)-.15 G 3.375(ob)489.93 230.4 S 3.375(er)503.305 230.4 S(enum-)514.45
-230.4 Q .282(bered to record number four)108 242.4 R 2.782(,a)-.4 G 2.782(sw)
-231.19 242.4 S .283(ell as the cursor)245.082 242.4 R 2.783(,i)-.4 G 2.783(fp)
-316.633 242.4 S .283(ositioned after record number one, to shift do)327.746
-242.4 R .283(wn one)-.25 F(record.)108 254.4 Q .373
-(The recno access method speci\214c data structure pro)108 271.2 R .373
-(vided to)-.15 F F3(dbopen)2.873 E F0 .373(is de\214ned in the <db)2.873 F .373
-(.h> include \214le as)-.4 F(follo)108 283.2 Q(ws:)-.25 E(typedef struct {)108
-300 Q(u_char b)144 312 Q -.25(va)-.15 G(l;).25 E(u_int cachesize;)144 324 Q
-(inde)144 336 Q(x_t psize;)-.15 E(u_long \215ags;)144 348 Q(int lorder;)144 360
-Q(size_t reclen;)144 372 Q(char *bfname;)144 384 Q 2.5(}R)108 396 S(ECNOINFO;)
-121.97 396 Q(The elements of this structure are de\214ned as follo)108 412.8 Q
-(ws:)-.25 E -.15(bv)108 429.6 S 16.68(al The)-.1 F .182
-(delimiting byte to be used to mark the end of a record for v)2.682 F .183
-(ariable-length records, and the pad)-.25 F .809(character for \214x)144 441.6
-R .809(ed-length records.)-.15 F .809(If no v)5.809 F .809
-(alue is speci\214ed, ne)-.25 F .809(wlines \(`)-.25 F(`\\n')-.74 E .808
-('\) are used to mark the)-.74 F(end of v)144 453.6 Q
-(ariable-length records and \214x)-.25 E
-(ed-length records are padded with spaces.)-.15 E(cachesize)108 470.4 Q 3.159
-(As)144 482.4 S .659(uggested maximum size, in bytes, of the memory cache.)
-158.269 482.4 R .66(This v)5.659 F .66(alue is)-.25 F F2(only)3.16 E F0
-(advisory)3.16 E 3.16(,a)-.65 G .66(nd the)514.62 482.4 R
-(access method will allocate more memory rather than f)144 494.4 Q(ail.)-.1 E
-12.95(psize The)108 511.2 R .715
-(recno access method stores the in-memory copies of its records in a btree.)
-3.216 F .715(This v)5.715 F .715(alue is the)-.25 F
-(size \(in bytes\) of the pages used for nodes in that tree.)144 523.2 Q(See)5
-E F3(btr)2.5 E(ee)-.37 E F0(\(3\) for more information.).18 E 3.51(bfname The)
-108 540 R .505
-(recno access method stores the in-memory copies of its records in a btree.)
-3.005 F .506(If bfname is non-)5.506 F .065(NULL, it speci\214es the name of t\
-he btree \214le, as if speci\214ed as the \214le name for a dbopen of a btree)
-144 552 R(\214le.)144 564 Q 14.61(\215ags The)108 580.8 R(\215ag v)2.5 E
-(alue is speci\214ed by)-.25 E F3(or)2.5 E F0('ing an).73 E 2.5(yo)-.15 G 2.5
-(ft)313.2 580.8 S(he follo)321.81 580.8 Q(wing v)-.25 E(alues:)-.25 E
-(R_FIXEDLEN)144 597.6 Q .962(The records are \214x)180 609.6 R .963
-(ed-length, not byte delimited.)-.15 F .963(The structure element)5.963 F F3
--.37(re)3.463 G(clen).37 E F0(speci\214es)3.463 E
-(the length of the record, and the structure element)180 621.6 Q F3(bval)2.5 E
-F0(is used as the pad character)2.5 E(.)-.55 E(R_NOKEY)144 638.4 Q 2.34
-(In the interf)180 650.4 R 2.34(ace speci\214ed by)-.1 F F3(dbopen)4.84 E F0
-4.84(,t).24 G 2.34(he sequential record retrie)344.98 650.4 R -.25(va)-.25 G
-4.84<6c8c>.25 G 2.34(lls in both the)478.25 650.4 R(caller')180 662.4 Q 3.556
-(sk)-.55 G 1.357 -.15(ey a)217.336 662.4 T 1.057(nd data structures.).15 F
-1.057(If the R_NOKEY \215ag is speci\214ed, the)6.057 F F3(cur)3.557 E(sor)-.1
-E F0(routines)3.557 E .029(are not required to \214ll in the k)180 674.4 R .329
--.15(ey s)-.1 H 2.529(tructure. This).15 F .028(permits applications to retrie)
-2.529 F .328 -.15(ve r)-.25 H .028(ecords at).15 F
-(the end of \214les without reading all of the interv)180 686.4 Q
-(ening records.)-.15 E(R_SN)144 703.2 Q(APSHO)-.35 E(T)-.4 E .964
-(This \215ag requires that a snapshot of the \214le be tak)180 715.2 R .965
-(en when)-.1 F F3(dbopen)3.465 E F0 .965(is called, instead of)3.465 F
-(permitting an)180 727.2 Q 2.5(yu)-.15 G
-(nmodi\214ed records to be read from the original \214le.)245.96 727.2 Q
-209.835(16, May)72 768 R(1)535 768 Q EP
-%%Page: 2 2
-%%BeginPageSetup
-BP
-%%EndPageSetup
-/F0 10/Times-Roman@0 SF 175.95(RECNO\(3\) 1993 RECNO\(3\))72 48 R 9.62
-(lorder The)108 84 R 1.597(byte order for inte)4.097 F 1.596
-(gers in the stored database metadata.)-.15 F 1.596
-(The number should represent the)6.596 F .688(order as an inte)144 96 R .689
-(ger; for e)-.15 F .689(xample, big endian order w)-.15 F .689
-(ould be the number 4,321.)-.1 F(If)5.689 E/F1 10/Times-Italic@0 SF(lor)3.189 E
-(der)-.37 E F0 .689(is 0 \(no)3.189 F
-(order is speci\214ed\) the current host order is used.)144 108 Q 9.07
-(reclen The)108 124.8 R(length of a \214x)2.5 E(ed-length record.)-.15 E .972
-(The data part of the k)108 141.6 R -.15(ey)-.1 G .971(/data pair used by the \
-recno access method is the same as other access methods.).15 F .198(The k)108
-153.6 R .498 -.15(ey i)-.1 H 2.698(sd).15 G(if)157.504 153.6 Q 2.698
-(ferent. The)-.25 F F1(data)2.698 E F0 .198(\214eld of the k)2.698 F .499 -.15
-(ey s)-.1 H .199(hould be a pointer to a memory location of type).15 F F1 -.37
-(re)2.699 G(cno_t).37 E F0 2.699(,a).68 G(s)536.11 153.6 Q .506
-(de\214ned in the <db)108 165.6 R .506(.h> include \214le.)-.4 F .506
-(This type is normally the lar)5.506 F .506(gest unsigned inte)-.18 F .506
-(gral type a)-.15 F -.25(va)-.2 G .505(ilable to the).25 F 2.5
-(implementation. The)108 177.6 R F1(size)2.5 E F0(\214eld of the k)2.5 E .3
--.15(ey s)-.1 H(hould be the size of that type.).15 E .064(In the interf)108
-194.4 R .064(ace speci\214ed by)-.1 F F1(dbopen)2.564 E F0 2.564(,u).24 G .064
-(sing the)261.544 194.4 R F1(put)2.564 E F0(interf)2.564 E .064
-(ace to create a ne)-.1 F 2.564(wr)-.25 G .065
-(ecord will cause the creation of)414.436 194.4 R .755(multiple, empty records\
- if the record number is more than one greater than the lar)108 206.4 R .754
-(gest record currently in)-.18 F(the database.)108 218.4 Q/F2 9/Times-Bold@0 SF
-(SEE ALSO)72 235.2 Q F1(dbopen)108 247.2 Q F0(\(3\),).24 E F1(hash)2.5 E F0
-(\(3\),).28 E F1(mpool)2.5 E F0(\(3\),).51 E F1 -.37(re)2.5 G(cno).37 E F0
-(\(3\)).18 E F1 2.754(Document Pr)108 271.2 R 2.754
-(ocessing in a Relational Database System)-.45 F F0 5.255(,M).32 G 2.755
-(ichael Stonebrak)362.13 271.2 R(er)-.1 E 5.255(,H)-.4 G 2.755(eidi Stettner)
-454.06 271.2 R 5.255(,J)-.4 G(oseph)516.67 271.2 Q
-(Kalash, Antonin Guttman, Nadene L)108 283.2 Q
-(ynn, Memorandum No. UCB/ERL M82/32, May 1982.)-.55 E F2 -.09(BU)72 300 S(GS)
-.09 E F0(Only big and little endian byte order is supported.)108 312 Q 209.835
-(16, May)72 768 R(2)535 768 Q EP
-%%Trailer
-end
-%%EOF
diff --git a/lib/libc/db/hash/hash.c b/lib/libc/db/hash/hash.c
index aa2e42856ebe..e9b25831d20e 100644
--- a/lib/libc/db/hash/hash.c
+++ b/lib/libc/db/hash/hash.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)hash.c 8.4 (Berkeley) 10/12/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -93,9 +93,9 @@ long hash_accesses, hash_collisions, hash_expansions, hash_overflows;
/* OPEN/CLOSE */
extern DB *
-__hash_open(file, flags, mode, info)
+__hash_open(file, flags, mode, info, dflags)
const char *file;
- int flags, mode;
+ int flags, mode, dflags;
const HASHINFO *info; /* Special directives for create */
{
HTAB *hashp;
@@ -111,13 +111,14 @@ __hash_open(file, flags, mode, info)
if (!(hashp = calloc(1, sizeof(HTAB))))
return (NULL);
hashp->fp = -1;
+
/*
- * Select flags relevant to us. 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
+ * 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 = flags & __USE_OPEN_FLAGS;
+ hashp->flags = flags;
new_table = 0;
if (!file || (flags & O_TRUNC) ||
@@ -152,7 +153,9 @@ __hash_open(file, flags, mode, info)
/* Verify file type, versions and hash function */
if (hashp->MAGIC != HASHMAGIC)
RETURN_ERROR(EFTYPE, error1);
- if (hashp->VERSION != HASHVERSION)
+#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);
@@ -865,7 +868,7 @@ hash_realloc(p_ptr, oldsize, newsize)
if (p = malloc(newsize)) {
memmove(p, *p_ptr, oldsize);
- memset(p + oldsize, 0, newsize - oldsize);
+ memset((char *)p + oldsize, 0, newsize - oldsize);
free(*p_ptr);
*p_ptr = p;
}
diff --git a/lib/libc/db/hash/hash_page.c b/lib/libc/db/hash/hash_page.c
index c2260f7b21a3..463189b15d2b 100644
--- a/lib/libc/db/hash/hash_page.c
+++ b/lib/libc/db/hash/hash_page.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hash_page.c 8.1 (Berkeley) 6/6/93";
+static char sccsid[] = "@(#)hash_page.c 8.2 (Berkeley) 9/6/93";
#endif /* LIBC_SCCS and not lint */
/*
@@ -302,12 +302,8 @@ ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
n = ino[0] - 1;
while (n < ino[0]) {
if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) {
- /*
- * Ov_addr gets set before reaching this point; there's
- * always an overflow page before a big key/data page.
- */
if (__big_split(hashp, old_bufp,
- new_bufp, bufp, ov_addr, obucket, &ret))
+ new_bufp, bufp, bufp->addr, obucket, &ret))
return (-1);
old_bufp = ret.oldp;
if (!old_bufp)
@@ -409,11 +405,14 @@ __addel(hashp, bufp, key, val)
bp = (u_short *)bufp->page;
do_expand = 0;
- while (bp[0] && (bp[bp[0]] < REAL_KEY))
+ while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY))
/* Exception case */
- if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) {
- /* This is a big-keydata pair */
- bufp = __add_ovflpage(hashp, bufp);
+ 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;
diff --git a/lib/libc/db/hash/hsearch.c b/lib/libc/db/hash/hsearch.c
index 30657b2c8ab6..8074d67945cf 100644
--- a/lib/libc/db/hash/hsearch.c
+++ b/lib/libc/db/hash/hsearch.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)hsearch.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)hsearch.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -62,7 +62,7 @@ hcreate(nel)
info.cachesize = NULL;
info.hash = NULL;
info.lorder = 0;
- dbp = (DB *)__hash_open(NULL, O_CREAT | O_RDWR, 0600, &info);
+ dbp = (DB *)__hash_open(NULL, O_CREAT | O_RDWR, 0600, &info, 0);
return ((int)dbp);
}
diff --git a/lib/libc/db/hash/ndbm.c b/lib/libc/db/hash/ndbm.c
index 2756074744c2..89b9916566b2 100644
--- a/lib/libc/db/hash/ndbm.c
+++ b/lib/libc/db/hash/ndbm.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)ndbm.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)ndbm.c 8.2 (Berkeley) 9/11/93";
#endif /* LIBC_SCCS and not lint */
/*
@@ -72,7 +72,7 @@ dbm_open(file, flags, mode)
info.lorder = 0;
(void)strcpy(path, file);
(void)strcat(path, DBM_SUFFIX);
- return ((DBM *)__hash_open(path, flags, mode, &info));
+ return ((DBM *)__hash_open(path, flags, mode, &info, 0));
}
extern void
diff --git a/lib/libc/db/man/btree.3 b/lib/libc/db/man/btree.3
index 923bc263cae2..afd3a672c884 100644
--- a/lib/libc/db/man/btree.3
+++ b/lib/libc/db/man/btree.3
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)btree.3 8.1 (Berkeley) 6/4/93
+.\" @(#)btree.3 8.2 (Berkeley) 1/2/94
.\"
-.TH BTREE 3
+.TH BTREE 3 "January 2, 1994"
.\".UC 7
.SH NAME
btree \- btree database access method
@@ -64,17 +64,17 @@ u_long flags;
.br
u_int cachesize;
.br
-index_t psize;
-.br
-int lorder;
-.\" .br
-.\" int maxkeypage;
+int maxkeypage;
.br
int minkeypage;
.br
+index_t psize;
+.br
int (*compare)(const DBT *key1, const DBT *key2);
.br
int (*prefix)(const DBT *key1, const DBT *key2);
+.br
+int lorder;
.RE
} BTREEINFO;
.PP
@@ -121,23 +121,9 @@ If
.I cachesize
is 0 (no size is specified) a default cache 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
-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
-.\" maxkeypage
+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
@@ -157,6 +143,14 @@ 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
@@ -187,6 +181,14 @@ 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
diff --git a/lib/libc/db/man/dbopen.3 b/lib/libc/db/man/dbopen.3
index a2e2bfd14b43..fbfabadc6445 100644
--- a/lib/libc/db/man/dbopen.3
+++ b/lib/libc/db/man/dbopen.3
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)dbopen.3 8.1 (Berkeley) 6/4/93
+.\" @(#)dbopen.3 8.5 (Berkeley) 1/2/94
.\"
-.TH DBOPEN 3 "June 4, 1993"
+.TH DBOPEN 3 "January 2, 1994"
.UC 7
.SH NAME
dbopen \- database access methods
@@ -51,7 +51,7 @@ const void *openinfo);
.SH DESCRIPTION
.IR Dbopen
is the library interface to database files.
-The supported file formats are btree, hashed and UNIX file oriented.
+The supported file formats are btree, hashed and flat-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
@@ -75,9 +75,29 @@ and
.I mode arguments
are as specified to the
.IR open (2)
-routine, however, only the O_CREAT, O_EXCL, O_EXLOCK, O_RDONLY, O_RDWR,
-O_SHLOCK and O_TRUNC flags are meaningful.
+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
@@ -167,7 +187,7 @@ processes which call
with the same
.I file
name.
-This file descriptor may be safely used as a argument to the
+This file descriptor may be safely used as an argument to the
.IR fcntl (2)
and
.IR flock (2)
@@ -442,6 +462,9 @@ for any of the errors specified for the library routine
.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.
diff --git a/lib/libc/db/man/hash.3 b/lib/libc/db/man/hash.3
index 698f10ca185c..57a77c1f870d 100644
--- a/lib/libc/db/man/hash.3
+++ b/lib/libc/db/man/hash.3
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)hash.3 8.1 (Berkeley) 6/6/93
+.\" @(#)hash.3 8.4 (Berkeley) 1/2/94
.\"
-.TH HASH 3 "June 6, 1993"
+.TH HASH 3 "January 2, 1994"
.UC 7
.SH NAME
hash \- hash database access method
@@ -61,15 +61,15 @@ typedef struct {
.RS
int bsize;
.br
-int cachesize;
-.br
int ffactor;
.br
+int nelem;
+.br
+int cachesize;
+.br
u_long (*hash)(const void *, size_t);
.br
int lorder;
-.br
-int nelem;
.RE
} HASHINFO;
.PP
@@ -81,13 +81,6 @@ 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
-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
ffactor
.I Ffactor
indicates a desired density within the hash table.
@@ -95,6 +88,20 @@ 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.
@@ -113,13 +120,6 @@ If
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.
-.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.
.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
@@ -134,17 +134,17 @@ Backward compatible interfaces to the routines described in
.IR dbm (3),
and
.IR ndbm (3)
-are provided, however, these interfaces are not compatible with
+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)
-.br
+.sp
.IR "Dynamic Hash Tables" ,
Per-Ake Larson, Communications of the ACM, April 1988.
-.br
+.sp
.IR "A New Hash Package for UNIX" ,
Margo Seltzer, USENIX Proceedings, Winter 1991.
.SH BUGS
diff --git a/lib/libc/db/man/recno.3 b/lib/libc/db/man/recno.3
index 476155642a2e..a6f218b2efe4 100644
--- a/lib/libc/db/man/recno.3
+++ b/lib/libc/db/man/recno.3
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)recno.3 8.1 (Berkeley) 6/4/93
+.\" @(#)recno.3 8.2 (Berkeley) 1/2/94
.\"
-.TH RECNO 3 "June 4, 1993"
+.TH RECNO 3 "January 2, 1994"
.UC 7
.SH NAME
recno \- record number database access method
@@ -66,59 +66,24 @@ is defined in the <db.h> include file as follows:
.PP
typedef struct {
.RS
-u_char bval;
+u_long flags;
.br
u_int cachesize;
.br
index_t psize;
.br
-u_long flags;
-.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
-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
-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
-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.
-.TP
flags
The flag value is specified by
.IR or 'ing
@@ -151,6 +116,27 @@ 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,
@@ -161,6 +147,20 @@ 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.
diff --git a/lib/libc/db/recno/rec_close.c b/lib/libc/db/recno/rec_close.c
index 49c5f2ca5e56..73e3690394ba 100644
--- a/lib/libc/db/recno/rec_close.c
+++ b/lib/libc/db/recno/rec_close.c
@@ -32,7 +32,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_close.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)rec_close.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -63,12 +63,18 @@ __rec_close(dbp)
BTREE *t;
int rval;
+ 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. */
- t = dbp->internal;
-
rval = RET_SUCCESS;
if (ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize))
rval = RET_ERROR;
@@ -110,6 +116,12 @@ __rec_sync(dbp, flags)
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));
diff --git a/lib/libc/db/recno/rec_delete.c b/lib/libc/db/recno/rec_delete.c
index 98d135331d55..fc4bea8a128d 100644
--- a/lib/libc/db/recno/rec_delete.c
+++ b/lib/libc/db/recno/rec_delete.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_delete.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)rec_delete.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -71,6 +71,13 @@ __rec_delete(dbp, key, flags)
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)
diff --git a/lib/libc/db/recno/rec_get.c b/lib/libc/db/recno/rec_get.c
index d02451272284..55d080bdfb5e 100644
--- a/lib/libc/db/recno/rec_get.c
+++ b/lib/libc/db/recno/rec_get.c
@@ -32,7 +32,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_get.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)rec_get.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -71,6 +71,15 @@ __rec_get(dbp, key, data, flags)
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);
@@ -80,7 +89,6 @@ __rec_get(dbp, key, data, flags)
* If we haven't seen this record yet, try to find it in the
* original file.
*/
- t = dbp->internal;
if (nrec > t->bt_nrecs) {
if (ISSET(t, R_EOF | R_INMEM))
return (RET_SPECIAL);
@@ -93,7 +101,10 @@ __rec_get(dbp, key, data, flags)
return (RET_ERROR);
status = __rec_ret(t, e, 0, NULL, data);
- mpool_put(t->bt_mp, e->page, 0);
+ 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_open.c b/lib/libc/db/recno/rec_open.c
index a0e152e476da..f05a44bb0026 100644
--- a/lib/libc/db/recno/rec_open.c
+++ b/lib/libc/db/recno/rec_open.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_open.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)rec_open.c 8.4 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -49,13 +49,14 @@ static char sccsid[] = "@(#)rec_open.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h>
#include <unistd.h>
+#define __DBINTERFACE_PRIVATE
#include <db.h>
#include "recno.h"
DB *
-__rec_open(fname, flags, mode, openinfo)
+__rec_open(fname, flags, mode, openinfo, dflags)
const char *fname;
- int flags, mode;
+ int flags, mode, dflags;
const RECNOINFO *openinfo;
{
BTREE *t;
@@ -83,9 +84,9 @@ __rec_open(fname, flags, mode, openinfo)
btopeninfo.prefix = NULL;
btopeninfo.lorder = openinfo->lorder;
dbp = __bt_open(openinfo->bfname,
- O_RDWR, S_IRUSR | S_IWUSR, &btopeninfo);
+ O_RDWR, S_IRUSR | S_IWUSR, &btopeninfo, dflags);
} else
- dbp = __bt_open(NULL, O_RDWR, S_IRUSR | S_IWUSR, NULL);
+ dbp = __bt_open(NULL, O_RDWR, S_IRUSR | S_IWUSR, NULL, dflags);
if (dbp == NULL)
goto err;
@@ -158,8 +159,8 @@ slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL)
SET(t, R_EOF);
else {
t->bt_msize = sb.st_size;
- if ((t->bt_smap =
- mmap(NULL, t->bt_msize, PROT_READ, 0, rfd,
+ 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;
@@ -213,6 +214,13 @@ __rec_fd(dbp)
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);
diff --git a/lib/libc/db/recno/rec_put.c b/lib/libc/db/recno/rec_put.c
index 9dcdc9c30bf4..515c90a46518 100644
--- a/lib/libc/db/recno/rec_put.c
+++ b/lib/libc/db/recno/rec_put.c
@@ -32,7 +32,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_put.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)rec_put.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -72,6 +72,12 @@ __rec_put(dbp, key, data, flags)
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))
diff --git a/lib/libc/db/recno/rec_search.c b/lib/libc/db/recno/rec_search.c
index 9d50b2f50ca4..ea3e06a6aee4 100644
--- a/lib/libc/db/recno/rec_search.c
+++ b/lib/libc/db/recno/rec_search.c
@@ -32,7 +32,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_search.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)rec_search.c 8.2 (Berkeley) 9/14/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -55,9 +55,10 @@ static char sccsid[] = "@(#)rec_search.c 8.1 (Berkeley) 6/4/93";
* EPG for matching record, if any, or the EPG for the location of the
* key, if it were inserted into the tree.
*
- * Warnings:
- * The EPG returned is in static memory, and will be overwritten by the
- * next search of any kind in any 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)
@@ -65,7 +66,6 @@ __rec_search(t, recno, op)
recno_t recno;
enum SRCHOP op;
{
- static EPG e;
register indx_t index;
register PAGE *h;
EPGNO *parent;
@@ -80,9 +80,9 @@ __rec_search(t, recno, op)
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
goto err;
if (h->flags & P_RLEAF) {
- e.page = h;
- e.index = recno - total;
- return (&e);
+ 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);
diff --git a/lib/libc/db/recno/rec_seq.c b/lib/libc/db/recno/rec_seq.c
index 29210a753697..bc66d1c4987e 100644
--- a/lib/libc/db/recno/rec_seq.c
+++ b/lib/libc/db/recno/rec_seq.c
@@ -32,7 +32,7 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)rec_seq.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)rec_seq.c 8.2 (Berkeley) 9/7/93";
#endif /* not lint */
#include <sys/types.h>
@@ -69,6 +69,13 @@ __rec_seq(dbp, key, data, flags)
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)
@@ -116,7 +123,9 @@ einval: errno = EINVAL;
t->bt_rcursor = nrec;
status = __rec_ret(t, e, nrec, key, data);
-
- mpool_put(t->bt_mp, e->page, 0);
+ 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
index c55f4df0f81c..ad87a4aa444e 100644
--- a/lib/libc/db/recno/rec_utils.c
+++ b/lib/libc/db/recno/rec_utils.c
@@ -32,7 +32,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rec_utils.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)rec_utils.c 8.2 (Berkeley) 9/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -70,11 +70,17 @@ __rec_ret(t, e, nrec, key, data)
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);
- } else {
+ 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 = realloc(t->bt_dbuf, rl->dsize + 1)) == NULL)
@@ -84,12 +90,16 @@ __rec_ret(t, e, nrec, key, data)
}
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;
}
- data->data = t->bt_dbuf;
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 = realloc(t->bt_kbuf, sizeof(recno_t))) == NULL)
return (RET_ERROR);
diff --git a/lib/libc/db/test/Makefile b/lib/libc/db/test/Makefile
index f04a780c74dc..a070941f8f2d 100644
--- a/lib/libc/db/test/Makefile
+++ b/lib/libc/db/test/Makefile
@@ -1,10 +1,14 @@
-# @(#)Makefile 8.1 (Berkeley) 6/4/93
+# @(#)Makefile 8.7 (Berkeley) 1/2/94
PROG= dbtest
-SRCS= dbtest.c
+OBJS= dbtest.o
-CFLAGS+= -g -DDEBUG -DSTATISTICS
-NOMAN= noman
+# Add -DSTATISTICS to CFLAGS to get btree statistical use info.
+# Note, the db library has to be compiled for statistics as well.
+CFLAGS= -O -DDEBUG
-NOINCLUDE=1
-.include <bsd.prog.mk>
+dbtest: ${OBJS} ${LIB}
+ ${CC} -o $@ ${OBJS} ${LIB}
+
+clean:
+ rm -f gmon.out ${OBJS} ${PROG} t1 t2 t3
diff --git a/lib/libc/db/test/dbtest.c b/lib/libc/db/test/dbtest.c
index 823223088dd1..41a115e9b602 100644
--- a/lib/libc/db/test/dbtest.c
+++ b/lib/libc/db/test/dbtest.c
@@ -38,7 +38,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)dbtest.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)dbtest.c 8.7 (Berkeley) 1/2/94";
#endif /* not lint */
#include <sys/param.h>
@@ -91,12 +91,13 @@ main(argc, argv)
DB *dbp;
DBT data, key, keydata;
size_t len;
- int ch;
+ int ch, oflags;
char *fname, *infoarg, *p, buf[8 * 1024];
infoarg = NULL;
fname = NULL;
- while ((ch = getopt(argc, argv, "f:i:o:")) != EOF)
+ oflags = O_CREAT | O_RDWR;
+ while ((ch = getopt(argc, argv, "f:i:lo:")) != EOF)
switch(ch) {
case 'f':
fname = optarg;
@@ -104,6 +105,9 @@ main(argc, argv)
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)
@@ -145,7 +149,7 @@ main(argc, argv)
(void)unlink(buf);
}
if ((dbp = dbopen(fname,
- O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, type, infop)) == NULL)
+ oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL)
err("dbopen: %s", strerror(errno));
XXdbp = dbp;
@@ -238,7 +242,7 @@ ldata: switch(command) {
err("line %lu: not expecting a key", lineno);
if (type == DB_RECNO) {
static recno_t recno;
- recno = strtol(p + 1, NULL, 0);
+ recno = atoi(p + 1);
key.data = &recno;
key.size = sizeof(recno);
} else {
@@ -284,6 +288,10 @@ lkey: switch(command) {
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);
@@ -502,75 +510,75 @@ setinfo(type, s)
switch(type) {
case DB_BTREE:
if (!strcmp("flags", s)) {
- ib.flags = strtoul(eq, NULL, 0);
+ ib.flags = atoi(eq);
return (&ib);
}
if (!strcmp("cachesize", s)) {
- ib.cachesize = strtoul(eq, NULL, 0);
+ ib.cachesize = atoi(eq);
return (&ib);
}
if (!strcmp("maxkeypage", s)) {
- ib.maxkeypage = strtoul(eq, NULL, 0);
+ ib.maxkeypage = atoi(eq);
return (&ib);
}
if (!strcmp("minkeypage", s)) {
- ib.minkeypage = strtoul(eq, NULL, 0);
+ ib.minkeypage = atoi(eq);
return (&ib);
}
if (!strcmp("lorder", s)) {
- ib.lorder = strtoul(eq, NULL, 0);
+ ib.lorder = atoi(eq);
return (&ib);
}
if (!strcmp("psize", s)) {
- ib.psize = strtoul(eq, NULL, 0);
+ ib.psize = atoi(eq);
return (&ib);
}
break;
case DB_HASH:
if (!strcmp("bsize", s)) {
- ih.bsize = strtoul(eq, NULL, 0);
+ ih.bsize = atoi(eq);
return (&ih);
}
if (!strcmp("ffactor", s)) {
- ih.ffactor = strtoul(eq, NULL, 0);
+ ih.ffactor = atoi(eq);
return (&ih);
}
if (!strcmp("nelem", s)) {
- ih.nelem = strtoul(eq, NULL, 0);
+ ih.nelem = atoi(eq);
return (&ih);
}
if (!strcmp("cachesize", s)) {
- ih.cachesize = strtoul(eq, NULL, 0);
+ ih.cachesize = atoi(eq);
return (&ih);
}
if (!strcmp("lorder", s)) {
- ih.lorder = strtoul(eq, NULL, 0);
+ ih.lorder = atoi(eq);
return (&ih);
}
break;
case DB_RECNO:
if (!strcmp("flags", s)) {
- rh.flags = strtoul(eq, NULL, 0);
+ rh.flags = atoi(eq);
return (&rh);
}
if (!strcmp("cachesize", s)) {
- rh.cachesize = strtoul(eq, NULL, 0);
+ rh.cachesize = atoi(eq);
return (&rh);
}
if (!strcmp("lorder", s)) {
- rh.lorder = strtoul(eq, NULL, 0);
+ rh.lorder = atoi(eq);
return (&rh);
}
if (!strcmp("reclen", s)) {
- rh.reclen = strtoul(eq, NULL, 0);
+ rh.reclen = atoi(eq);
return (&rh);
}
if (!strcmp("bval", s)) {
- rh.bval = strtoul(eq, NULL, 0);
+ rh.bval = atoi(eq);
return (&rh);
}
if (!strcmp("psize", s)) {
- rh.psize = strtoul(eq, NULL, 0);
+ rh.psize = atoi(eq);
return (&rh);
}
break;
@@ -595,8 +603,10 @@ rfile(name, lenp)
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 = malloc((u_int)sb.st_size)) == NULL)
err("%s", strerror(errno));
(void)read(fd, p, (int)sb.st_size);
@@ -622,7 +632,7 @@ void
usage()
{
(void)fprintf(stderr,
- "usage: dbtest [-f file] [-i info] [-o file] type script\n");
+ "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n");
exit(1);
}
diff --git a/lib/libc/db/test/run.test b/lib/libc/db/test/run.test
index 2e0bd8d196ff..5eeaf743dd68 100644
--- a/lib/libc/db/test/run.test
+++ b/lib/libc/db/test/run.test
@@ -1,32 +1,50 @@
#!/bin/sh -
#
-# @(#)run.test 8.1 (Berkeley) 6/4/93
+# @(#)run.test 8.7 (Berkeley) 9/16/93
#
# db regression tests
-
main()
{
- DICT=/usr/share/dict/words
- PROG=obj/dbtest
- TMP1=t1
- TMP2=t2
- TMP3=t3
- test1
- test2
- test3
- test4
- test5
- test6
- test7
- test8
- test9
- test10
- test11
- test12
- test13
- test20
+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
}
@@ -35,21 +53,25 @@ main()
# be key/data pairs.
test1()
{
- printf "Test 1: btree, hash: small key, small data pairs\n"
+ 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
- printf "p\nk%s\nd%s\ng\nk%s\n" $i $i $i
+ 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
- printf "test1: type %s: failed\n" $type
+ echo "test1: type $type: failed"
exit 1
fi
done
- printf "Test 1: recno: small key, small data pairs\n"
+ echo "Test 1: recno: small key, small data pairs"
rm -f $TMP2 $TMP3
sed 200q $DICT |
awk '{
@@ -59,7 +81,7 @@ test1()
$PROG -o $TMP3 recno $TMP2
if (cmp -s $TMP1 $TMP3) ; then :
else
- printf "test1: type recno: failed\n"
+ echo "test1: type recno: failed"
exit 1
fi
}
@@ -68,23 +90,27 @@ test1()
# each a medium size data entry.
test2()
{
- printf "Test 2: btree, hash: small key, medium data pairs\n"
+ 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
- printf "p\nk%s\nd%s\ng\nk%s\n" $i $mdata $i
+ 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
- printf "test2: type %s: failed\n" $type
+ echo "test2: type $type: failed"
exit 1
fi
done
- printf "Test 2: recno: small key, medium data pairs\n"
+ echo "Test 2: recno: small key, medium data pairs"
rm -f $TMP2 $TMP3
echo $mdata |
awk '{ for (i = 1; i < 201; ++i)
@@ -93,7 +119,7 @@ test2()
$PROG -o $TMP3 recno $TMP2
if (cmp -s $TMP1 $TMP3) ; then :
else
- printf "test2: type recno: failed\n"
+ echo "test2: type recno: failed"
exit 1
fi
}
@@ -101,40 +127,46 @@ test2()
# Insert the programs in /bin with their paths as their keys.
test3()
{
- printf "Test 3: hash: small key, big data pairs\n"
+ 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
- printf "p\nk%s\nD%s\ng\nk%s\n" $i $i $i
+ 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
- printf "test3: %s: page size %d: failed\n" \
- $type $psize
+ echo "test3: $type: failed"
exit 1
fi
done
- printf "Test 3: btree: small key, big data pairs\n"
+ echo "Test 3: btree: small key, big data pairs"
for psize in 512 16384 65536; do
- printf "\tpage size %d\n" $psize
+ echo " page size $psize"
for type in btree; do
rm -f $TMP2 $TMP3
for i in `find /bin -type f -print`; do
- printf "p\nk%s\nD%s\ng\nk%s\n" $i $i $i
+ 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
- printf "test3: %s: page size %d: failed\n" \
- $type $psize
+ echo "test3: $type: page size $psize: failed"
exit 1
fi
done
done
- printf "Test 3: recno: big data pairs\n"
+ echo "Test 3: recno: big data pairs"
rm -f $TMP2 $TMP3
find /bin -type f -print |
awk '{
@@ -142,11 +174,11 @@ test3()
printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i);
}' > $TMP2
for psize in 512 16384 65536; do
- printf "\tpage size %d\n" $psize
+ echo " page size $psize"
$PROG -i psize=$psize -o $TMP3 recno $TMP2
if (cmp -s $TMP1 $TMP3) ; then :
else
- printf "test3: recno: page size %d: failed\n" $psize
+ echo "test3: recno: page size $psize: failed"
exit 1
fi
done
@@ -155,18 +187,33 @@ test3()
# Do random recno entries.
test4()
{
- printf "Test 4: recno: random entries\n"
+ echo "Test 4: recno: random entries"
echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
awk '{
- for (i = 37; i <= 37 + 88 * 17; i += 17)
- printf("input key %d: %.*s\n", i, i % 41, $0);
- for (i = 1; i <= 15; ++i)
- printf("input key %d: %.*s\n", i, i % 41, $0);
- for (i = 19234; i <= 19234 + 61 * 27; i += 27)
- printf("input key %d: %.*s\n", i, i % 41, $0);
+ 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
+ rm -f $TMP2 $TMP3
cat $TMP1 |
awk 'BEGIN {
i = 37;
@@ -196,7 +243,7 @@ test4()
$PROG -o $TMP3 recno $TMP2
if (cmp -s $TMP1 $TMP3) ; then :
else
- printf "test4: type recno: failed\n"
+ echo "test4: type recno: failed"
exit 1
fi
}
@@ -204,14 +251,19 @@ test4()
# Do reverse order recno entries.
test5()
{
- printf "Test 5: recno: reverse order entries\n"
+ echo "Test 5: recno: reverse order entries"
echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
awk ' {
- for (i = 1500; i; --i)
- printf("input key %d: %.*s\n", i, i % 34, $0);
+ 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
+ rm -f $TMP2 $TMP3
cat $TMP1 |
awk 'BEGIN {
i = 1500;
@@ -227,7 +279,7 @@ test5()
$PROG -o $TMP3 recno $TMP2
if (cmp -s $TMP1 $TMP3) ; then :
else
- printf "test5: type recno: failed\n"
+ echo "test5: type recno: failed"
exit 1
fi
}
@@ -235,16 +287,26 @@ test5()
# Do alternating order recno entries.
test6()
{
- printf "Test 6: recno: alternating order entries\n"
+ echo "Test 6: recno: alternating order entries"
echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
awk ' {
- for (i = 1; i < 1200; i += 2)
- printf("input key %d: %.*s\n", i, i % 34, $0);
- for (i = 2; i < 1200; i += 2)
- printf("input key %d: %.*s\n", i, i % 34, $0);
+ 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
+ rm -f $TMP2 $TMP3
cat $TMP1 |
awk 'BEGIN {
i = 1;
@@ -269,7 +331,7 @@ test6()
sort -o $TMP3 $TMP3
if (cmp -s $TMP1 $TMP3) ; then :
else
- printf "test6: type recno: failed\n"
+ echo "test6: type recno: failed"
exit 1
fi
}
@@ -277,7 +339,7 @@ test6()
# Delete cursor record
test7()
{
- printf "Test 7: btree, recno: delete cursor record\n"
+ echo "Test 7: btree, recno: delete cursor record"
echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" |
awk '{
for (i = 1; i <= 120; ++i)
@@ -288,7 +350,7 @@ test7()
printf("%05d: input key %d: %s\n", 2, 2, $0);
exit;
}' > $TMP1
- rm -f TMP2 $TMP3
+ rm -f $TMP2 $TMP3
for type in btree recno; do
cat $TMP1 |
@@ -311,7 +373,7 @@ test7()
$PROG -o $TMP3 recno $TMP2
if (cmp -s $TMP1 $TMP3) ; then :
else
- printf "test7: type $type: failed\n"
+ echo "test7: type $type: failed"
exit 1
fi
done
@@ -320,8 +382,9 @@ test7()
# Make sure that overflow pages are reused.
test8()
{
- printf "Test 8: btree, hash: repeated small key, big data pairs\n"
+ 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");
@@ -338,21 +401,21 @@ test8()
printf("eend of test8 run\n");
}' > $TMP1
$PROG btree $TMP1
- $PROG hash $TMP1
+# $PROG hash $TMP1
# No explicit test for success.
}
# Test btree duplicate keys
test9()
{
- printf "Test 9: btree: duplicate keys\n"
+ 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
+ rm -f $TMP2 $TMP3
for type in btree; do
cat $TMP1 |
@@ -369,7 +432,7 @@ test9()
sort -o $TMP3 $TMP3
if (cmp -s $TMP1 $TMP3) ; then :
else
- printf "test9: type $type: failed\n"
+ echo "test9: type $type: failed"
exit 1
fi
done
@@ -378,14 +441,14 @@ test9()
# Test use of cursor flags without initialization
test10()
{
- printf "Test 10: btree, recno: test cursor flag use\n"
+ 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
+ rm -f $TMP2 $TMP3
# Test that R_CURSOR doesn't succeed before cursor initialized
for type in btree recno; do
@@ -401,7 +464,7 @@ test10()
}' > $TMP2
$PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
if [ -s $TMP3 ] ; then
- printf "Test 10: delete: R_CURSOR SHOULD HAVE FAILED\n"
+ echo "Test 10: delete: R_CURSOR SHOULD HAVE FAILED"
exit 1
fi
done
@@ -418,7 +481,7 @@ test10()
}' > $TMP2
$PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1
if [ -s $TMP3 ] ; then
- printf "Test 10: put: R_CURSOR SHOULD HAVE FAILED\n"
+ echo "Test 10: put: R_CURSOR SHOULD HAVE FAILED"
exit 1
fi
done
@@ -427,14 +490,14 @@ test10()
# Test insert in reverse order.
test11()
{
- printf "Test 11: recno: reverse order insert\n"
+ 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
+ rm -f $TMP2 $TMP3
for type in recno; do
cat $TMP1 |
@@ -452,7 +515,7 @@ test11()
$PROG -o $TMP3 $type $TMP2
if (cmp -s $TMP1 $TMP3) ; then :
else
- printf "test11: type $type: failed\n"
+ echo "test11: type $type: failed"
exit 1
fi
done
@@ -463,19 +526,23 @@ test11()
# the btree split code gets hammered.
test12()
{
- printf "Test 12: btree: lots of keys, small page size\n"
+ 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
- printf "p\nk%s\nd%s\ng\nk%s\n" $i $mdata $i
+ 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
- printf "test12: type %s: failed\n" $type
+ echo "test12: type $type: failed"
exit 1
fi
done
@@ -484,27 +551,32 @@ test12()
# Test different byte orders.
test13()
{
- printf "Test 13: btree, hash: differing byte orders\n"
+ 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
- printf "p\nk%s\nd%s\ng\nk%s\n" $i $i $i
+ 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
- printf "test13: %s/%s put failed\n" $type $order
+ echo "test13: $type/$order put failed"
exit 1
fi
for i in `sed 50q $DICT`; do
- printf "g\nk%s\n" $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
- printf "test13: %s/%s get failed\n" $type $order
+ echo "test13: $type/$order get failed"
exit 1
fi
done
@@ -515,18 +587,29 @@ test13()
# Try a variety of bucketsizes and fill factors for hashing
test20()
{
- printf\
- "Test 20: hash: bucketsize, fill factor; nelem 25000 cachesize 65536\n"
- awk 'BEGIN {
- for (i = 1; i <= 10000; ++i)
- printf("%.*s\n", i % 34,
- "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg");
+ 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 '{
- ++i;
- printf("p\nk%s\nd%.*s\n", $0, i % 34,
- "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg");
+ 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 '{
@@ -535,82 +618,82 @@ test20()
}' >> $TMP2
bsize=256
for ffactor in 11 14 21; do
- printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor
+ 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
- printf "test20: type hash:\
-bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n"
+ 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
- printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor
+ 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
- printf "test20: type hash:\
-bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n"
+ 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
- printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor
+ 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
- printf "test20: type hash:\
-bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n"
+ 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
- printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor
+ 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
- printf "test20: type hash:\
-bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n"
+ 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
- printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor
+ 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
- printf "test20: type hash:\
-bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n"
+ 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
- printf "\tbucketsize %d, fill factor %d\n" $bsize $ffactor
+ 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
- printf "test20: type hash:\
-bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed\n"
+ echo "test20: type hash:\
+bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed"
exit 1
fi
done
}
-main
+main $*
diff --git a/lib/libc/db/test/strerror.c b/lib/libc/db/test/strerror.c
new file mode 100644
index 000000000000..53f374bdf796
--- /dev/null
+++ b/lib/libc/db/test/strerror.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[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <string.h>
+
+char *
+strerror(num)
+ int num;
+{
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+#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(sys_errlist[errnum]);
+
+ /* Do this by hand, so we don't include stdio(3). */
+ t = tmp;
+ do {
+ *t++ = "0123456789"[errnum % 10];
+ } while (errnum /= 10);
+ for (p = ebuf + sizeof(UPREFIX) - 1;;) {
+ *p++ = *--t;
+ if (t <= tmp)
+ break;
+ }
+ return(ebuf);
+}
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index f7d472e667e4..0f0a66405d13 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -1,23 +1,22 @@
# @(#)Makefile.inc 5.21 (Berkeley) 5/24/91
# gen sources
-.PATH: ${.CURDIR}/${MACHINE}/gen ${.CURDIR}/gen ${.CURDIR}/gen/regexp
+.PATH: ${.CURDIR}/${MACHINE}/gen ${.CURDIR}/gen
SRCS+= alarm.c assert.c clock.c crypt.c ctermid.c ctime.c ctype_.c \
directory.c difftime.c disklabel.c err.c errlst.c exec.c \
fnmatch.c frexp.c fstab.c fts.c getcap.c getcwd.c getgrent.c \
getlogin.c getmntinfo.c getpass.c getpwent.c getsubopt.c getttyent.c \
getusershell.c glob.c infinity.c initgroups.c insque.c isatty.c \
- isctype.c isinf.c mktemp.c nice.c nlist.c pause.c popen.c psignal.c \
- raise.c setjmperr.c setmode.c setrgid.c setruid.c \
+ isctype.c isinf.c mktemp.c msgctl.c msgget.c msgsnd.c msgrcv.c \
+ nice.c nlist.c pause.c popen.c psignal.c raise.c scandir.c \
+ semconfig.c semctl.c semget.c semop.c \
+ setjmperr.c setmode.c setrgid.c setruid.c \
shmat.c shmctl.c shmdt.c shmget.c \
- siginterrupt.c \
- scandir.c siglist.c signal.c sigsetops.c sleep.c syslog.c termios.c \
- time.c times.c timezone.c ttyname.c ttyslot.c ualarm.c unvis.c \
- usleep.c utime.c valloc.c vis.c wait.c wait3.c waitpid.c
-
-# gen/regexp sources
-SRCS+= regerror.c regexp.c regsub.c
+ siginterrupt.c siglist.c signal.c sigsetops.c sleep.c syslog.c \
+ termios.c time.c times.c timezone.c ttyname.c ttyslot.c \
+ ualarm.c unvis.c usleep.c utime.c valloc.c vis.c \
+ wait.c wait3.c waitpid.c
.if (${MACHINE} == "hp300")
SRCS+= _setjmp.s alloca.s fabs.s ldexp.s modf.s setjmp.s
@@ -27,8 +26,8 @@ SRCS+= adddf3.s addsf3.s ashlsi3.s ashrsi3.s cmpdf2.s cmpsf2.s divdf3.s \
negdf2.s negsf2.s saveregs.c subdf3.s subsf3.s truncdfsf2.s udivsi3.s \
umodsi3.s umulsi3.s
.elif (${MACHINE} == "i386")
-SRCS+= _setjmp.s alloca.s fabs.s ldexp.c modf.s setjmp.s sigsetjmp.s
-SRCS+= divsi3.s fixdfsi.s fixunsdfsi.s udivsi3.s
+SRCS+= _setjmp.S alloca.S fabs.S ldexp.c modf.S setjmp.S sigsetjmp.S
+SRCS+= divsi3.S fixdfsi.S fixunsdfsi.S udivsi3.S
.elif (${MACHINE} == "tahoe")
CFLAGS+=-I/sys
SRCS+= _setjmp.s alloca.s fabs.s ldexp.s modf.s setjmp.s
@@ -48,14 +47,14 @@ MAN3+= gen/alarm.3 gen/clock.3 gen/crypt.3 gen/ctermid.3 gen/ctime.3 \
gen/islower.3 gen/isprint.3 gen/ispunct.3 gen/isspace.3 \
gen/isupper.3 gen/isxdigit.3 gen/ldexp.3 gen/modf.3 gen/nice.3 \
gen/nlist.3 gen/pause.3 gen/popen.3 gen/psignal.3 gen/raise.3 \
- gen/regexp.3 gen/scandir.3 gen/setjmp.3 gen/setmode.3 gen/setuid.3 \
+ gen/scandir.3 gen/setjmp.3 gen/setmode.3 gen/setuid.3 \
gen/siginterrupt.3 gen/signal.3 gen/sigsetops.3 gen/sleep.3 \
- gen/syslog.3 gen/tcsendbreak.3 gen/time.3 gen/times.3 \
- gen/timezone.3 gen/tolower.3 gen/toupper.3 gen/ttyname.3 \
- gen/tzset.3 gen/ualarm.3 gen/unvis.3 gen/usleep.3 gen/utime.3 \
- gen/valloc.3 gen/vis.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/tolower.3 \
+ gen/toupper.3 gen/ttyname.3 gen/tzset.3 gen/ualarm.3 gen/unvis.3 \
+ gen/usleep.3 gen/utime.3 gen/valloc.3 gen/vis.3
-MLINKS= crypt.3 encrypt.3 crypt.3 setkey.3
+MLINKS+=crypt.3 encrypt.3 crypt.3 setkey.3
MLINKS+=ctime.3 asctime.3 ctime.3 difftime.3 ctime.3 gmtime.3 \
ctime.3 localtime.3 ctime.3 mktime.3
MLINKS+=directory.3 closedir.3 directory.3 dirfd.3 directory.3 opendir.3 \
@@ -83,8 +82,6 @@ MLINKS+=insque.3 remque.3
MLINKS+=isinf.3 isnan.3
MLINKS+=popen.3 pclose.3
MLINKS+=psignal.3 sys_siglist.3
-MLINKS+=regexp.3 regcomp.3 regexp.3 regexec.3 regexp.3 regsub.3 \
- regexp.3 regerror.3
MLINKS+=scandir.3 alphasort.3
MLINKS+=setjmp.3 _longjmp.3 setjmp.3 _setjmp.3 setjmp.3 longjmp.3 \
setjmp.3 sigsetjmp.3 setjmp.3 siglongjmp.3 setjmp.3 longjmperror.3
@@ -97,8 +94,10 @@ MLINKS+=sigsetops.3 sigemptyset.3 sigsetops.3 sigfillset.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 cfgetispeed.3 tcsetattr.3 cfsetispeed.3 \
+ tcsetattr.3 cfgetospeed.3 tcsetattr.3 cfsetospeed.3 \
+ tcsetattr.3 cfsetspeed.3 tcsetattr.3 cfmakeraw.3 \
+ tcsetattr.3 tcgetattr.3
MLINKS+=ttyname.3 isatty.3 ttyname.3 ttyslot.3
MLINKS+=tzset.3 tzsetwall.3
diff --git a/lib/libc/gen/alarm.3 b/lib/libc/gen/alarm.3
index c34abc21e6af..63c338ebac1c 100644
--- a/lib/libc/gen/alarm.3
+++ b/lib/libc/gen/alarm.3
@@ -56,7 +56,7 @@ before asserting the terminating signal
When the signal has successfully been caught,
.Fn alarm
returns the amount of time left on the clock.
-The maximum mumber of
+The maximum number of
.Ar seconds
allowed
is 2147483647.
@@ -65,7 +65,7 @@ If an alarm has been set with
.Fn alarm ,
another call to
.Fn alarm
-will superceed the prior call.
+will supercede the prior call.
The request
.Fn alarm "0"
voids the current
diff --git a/lib/libc/gen/crypt.c b/lib/libc/gen/crypt.c
index be5d6873fe48..e0a96988ac01 100644
--- a/lib/libc/gen/crypt.c
+++ b/lib/libc/gen/crypt.c
@@ -36,7 +36,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/* from static char sccsid[] = "@(#)crypt.c 5.11 (Berkeley) 6/25/91"; */
-static char rcsid[] = "$Header: /a/cvs/386BSD/src/lib/libc/gen/crypt.c,v 1.6 1993/08/29 22:03:56 nate Exp $";
+static char rcsid[] = "$Header: /home/cvs/386BSD/src/lib/libc/gen/crypt.c,v 1.6 1993/08/29 22:03:56 nate Exp $";
#endif /* LIBC_SCCS and not lint */
#include <unistd.h>
diff --git a/lib/libc/gen/ctype_.c b/lib/libc/gen/ctype_.c
index b6f83051411e..d361c1617cea 100644
--- a/lib/libc/gen/ctype_.c
+++ b/lib/libc/gen/ctype_.c
@@ -1,4 +1,13 @@
/*
+ * Copyright (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.
+ *
+ * $Id: ctype_.c,v 1.1.1.1.2.1 1994/05/04 07:39:42 rgrimes Exp $
+ */
+/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
diff --git a/lib/libc/gen/directory.3 b/lib/libc/gen/directory.3
index cae5ea3dda56..6b5ea9d88301 100644
--- a/lib/libc/gen/directory.3
+++ b/lib/libc/gen/directory.3
@@ -48,7 +48,7 @@
.Fd #include <dirent.h>
.Ft DIR *
.Fn opendir "const char *filename"
-.Ft struct direct
+.Ft struct dirent *
.Fn readdir "DIR *dirp"
.Ft long
.Fn telldir "const DIR *dirp"
diff --git a/lib/libc/gen/err.3 b/lib/libc/gen/err.3
index 44ca0942c1b3..2a3f4c391fd3 100644
--- a/lib/libc/gen/err.3
+++ b/lib/libc/gen/err.3
@@ -1,5 +1,5 @@
-.\" Copyright (c) 1993 The Regents of the University of California.
-.\" All rights reserved.
+.\" 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
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)err.3 5.2 (Berkeley) 3/19/93
+.\" @(#)err.3 8.1 (Berkeley) 6/9/93
.\"
-.Dd "March 19, 1993"
+.Dd "June 9, 1993"
.Dt ERR 3
.Os BSD 4
.Sh NAME
@@ -125,5 +125,4 @@ The
.Fn err
and
.Fn warn
-functions are
-.Ud .
+functions first appeared in 4.4BSD.
diff --git a/lib/libc/gen/fnmatch.3 b/lib/libc/gen/fnmatch.3
index 2d967d2d1bd0..d3d3ccaa3b6e 100644
--- a/lib/libc/gen/fnmatch.3
+++ b/lib/libc/gen/fnmatch.3
@@ -1,5 +1,5 @@
-.\" Copyright (c) 1989, 1991 The Regents of the University of California.
-.\" All rights reserved.
+.\" 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.
@@ -31,9 +31,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)fnmatch.3 5.4 (Berkeley) 6/28/92
+.\" from: @(#)fnmatch.3 8.1 (Berkeley) 6/9/93
+.\" $Id: fnmatch.3,v 1.3 1993/11/23 00:10:08 jtc Exp $
.\"
-.Dd June 28, 1992
+.Dd June 9, 1993
.Dt FNMATCH 3
.Os
.Sh NAME
@@ -94,7 +95,6 @@ Additionally, if
.Dv FNM_PATHNAME
is set,
a period is ``leading'' if it immediately follows a slash.
-.Em "This flag is not currently implemented."
.El
.Sh RETURN VALUES
The
@@ -110,19 +110,16 @@ otherwise, it returns the value
.Xr glob 3 ,
.Xr wordexp 3 ,
.Xr regexp 3
+.Sh STANDARDS
+The
+.Fn fnmatch
+function is expected to conform to
+.St -p1003.2-92 .
.Sh HISTORY
The
.Fn fnmatch
-function is
-.Ud .
+function first appeared in 4.4BSD.
.Sh BUGS
-Quotes and slashes in range patterns are not handled correctly by
-this implementation.
-.Pp
-The
-.Dv FNM_PERIOD
-flag is not implemented.
-.Pp
The pattern
.Ql *
matches the empty string, even if
diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c
index 7b54c3b7254a..9d64cf5573ad 100644
--- a/lib/libc/gen/fnmatch.c
+++ b/lib/libc/gen/fnmatch.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * 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.
@@ -35,11 +35,12 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)fnmatch.c 5.6 (Berkeley) 6/28/92";
+/* from: static char sccsid[] = "@(#)fnmatch.c 8.1 (Berkeley) 6/4/93"; */
+static char *rcsid = "$Id: fnmatch.c,v 1.3 1993/11/23 00:10:09 jtc Exp $";
#endif /* LIBC_SCCS and not lint */
/*
- * Function fnmatch() as proposed in POSIX 1003.2 B.6 (D11.2).
+ * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
* Compares a filename or pathname to a pattern.
*/
@@ -48,12 +49,14 @@ static char sccsid[] = "@(#)fnmatch.c 5.6 (Berkeley) 6/28/92";
#define EOS '\0'
-static const char *rangematch __P((const char *, int));
+static const char *rangematch __P((const char *, int, int));
+int
fnmatch(pattern, string, flags)
register const char *pattern, *string;
int flags;
{
+ const char *stringstart = string;
register char c;
char test;
@@ -62,9 +65,14 @@ fnmatch(pattern, string, flags)
case EOS:
return (*string == EOS ? 0 : FNM_NOMATCH);
case '?':
- if ((test = *string++) == EOS ||
- test == '/' && flags & FNM_PATHNAME)
+ 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;
@@ -72,6 +80,10 @@ fnmatch(pattern, string, flags)
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)
@@ -87,7 +99,7 @@ fnmatch(pattern, string, flags)
/* General case, use recursion. */
while ((test = *string) != EOS) {
- if (!fnmatch(pattern, string, flags))
+ if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
return (0);
if (test == '/' && flags & FNM_PATHNAME)
break;
@@ -95,11 +107,13 @@ fnmatch(pattern, string, flags)
}
return (FNM_NOMATCH);
case '[':
- if ((test = *string++) == EOS ||
- test == '/' && flags & FNM_PATHNAME)
+ if (*string == EOS)
+ return (FNM_NOMATCH);
+ if (*string == '/' && flags & FNM_PATHNAME)
return (FNM_NOMATCH);
- if ((pattern = rangematch(pattern, test)) == NULL)
+ if ((pattern = rangematch(pattern, *string, flags)) == NULL)
return (FNM_NOMATCH);
+ ++string;
break;
case '\\':
if (!(flags & FNM_NOESCAPE)) {
@@ -107,9 +121,6 @@ fnmatch(pattern, string, flags)
c = '\\';
--pattern;
}
- if (c != *string++)
- return (FNM_NOMATCH);
- break;
}
/* FALLTHROUGH */
default:
@@ -121,30 +132,48 @@ fnmatch(pattern, string, flags)
}
static const char *
-rangematch(pattern, test)
+rangematch(pattern, test, flags)
register const char *pattern;
register int test;
+ int flags;
{
register char c, c2;
int negate, ok;
- if (negate = (*pattern == '!'))
- ++pattern;
-
- /*
- * XXX
- * TO DO: quoting
+ /* A bracket expression starting with an unquoted circumflex
+ * character produces unspecified results (IEEE 1003.2-1992,
+ * 3.13.2). I have chosen to treat it like '!', for
+ * consistancy with regular expression syntax.
*/
+ if (negate = (*pattern == '!' || *pattern == '^')) {
+ pattern++;
+ }
+
for (ok = 0; (c = *pattern++) != ']';) {
- if (c == EOS)
- return (NULL); /* Illegal pattern. */
- if (*pattern == '-' && (c2 = pattern[1]) != EOS && c2 != ']') {
- if (c <= test && test <= c2)
- ok = 1;
- pattern += 2;
+ if (c == '\\' && !(flags & FNM_NOESCAPE)) {
+ c = *pattern++;
+ }
+ if (c == EOS) {
+ return (NULL);
}
- else if (c == test)
+
+ 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/getcap.3 b/lib/libc/gen/getcap.3
index 4af162f1af62..d18b3797bc7e 100644
--- a/lib/libc/gen/getcap.3
+++ b/lib/libc/gen/getcap.3
@@ -32,7 +32,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)getcap.3 5.4 (Berkeley) 8/11/92
+.\" from: @(#)getcap.3 5.4 (Berkeley) 8/11/92
+.\" $Id: getcap.3,v 1.1.2.1 1994/05/01 16:05:00 jkh Exp $
.\"
.Dd "August 11, 1992"
.Dt GETCAP 3
@@ -236,7 +237,7 @@ 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 occured, and \-2
+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).
diff --git a/lib/libc/gen/getgrent.3 b/lib/libc/gen/getgrent.3
index 45d3bced27ab..fd2e2e194e76 100644
--- a/lib/libc/gen/getgrent.3
+++ b/lib/libc/gen/getgrent.3
@@ -96,7 +96,7 @@ 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 necesssary.
+All three routines will open the group file for reading, if necessary.
.Pp
The
.Fn setgroupent
diff --git a/lib/libc/gen/getgrent.c b/lib/libc/gen/getgrent.c
index 60593c2831fd..18f7079eff30 100644
--- a/lib/libc/gen/getgrent.c
+++ b/lib/libc/gen/getgrent.c
@@ -32,13 +32,20 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getgrent.c 5.9 (Berkeley) 4/1/91";
+/* static char *sccsid = "from: @(#)getgrent.c 5.9 (Berkeley) 4/1/91"; */
+static char *rcsid = "$Id: getgrent.c,v 1.3 1994/01/11 19:00:57 nate Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <grp.h>
+#ifdef YP
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
static FILE *_gr_fp;
static struct group _gr_group;
@@ -50,6 +57,11 @@ static char *members[MAXGRP];
#define MAXLINELENGTH 1024
static char line[MAXLINELENGTH];
+#ifdef YP
+static char *__ypcurrent, *__ypdomain;
+static int __ypcurrentlen, __ypmode=0;
+#endif
+
struct group *
getgrent()
{
@@ -90,7 +102,7 @@ getgrgid(gid)
return(rval ? &_gr_group : NULL);
}
-static
+static int
start_gr()
{
if (_gr_fp) {
@@ -100,10 +112,10 @@ start_gr()
return((_gr_fp = fopen(_PATH_GROUP, "r")) ? 1 : 0);
}
-int
+void
setgrent()
{
- return(setgroupent(0));
+ (void) setgroupent(0);
}
int
@@ -125,27 +137,88 @@ endgrent()
}
}
-static
+static int
grscan(search, gid, name)
register int search, gid;
register char *name;
{
register char *cp, **m;
char *bp;
- char *fgets(), *strsep(), *index();
for (;;) {
+#ifdef YP
+ if(__ypmode) {
+ char *key, *data;
+ int keylen, datalen;
+ int r;
+
+ if(!__ypdomain) {
+ if(yp_get_default_domain(&__ypdomain)) {
+ __ypmode = 0;
+ continue;
+ }
+ }
+ if(__ypcurrent) {
+ r = yp_next(__ypdomain, "group.byname",
+ __ypcurrent, __ypcurrentlen,
+ &key, &keylen, &data, &datalen);
+ free(__ypcurrent);
+ /*printf("yp_next %d\n", r);*/
+ switch(r) {
+ case 0:
+ break;
+ default:
+ __ypcurrent = NULL;
+ __ypmode = 0;
+ free(data);
+ continue;
+ }
+ __ypcurrent = key;
+ __ypcurrentlen = keylen;
+ bcopy(data, line, datalen);
+ free(data);
+ } else {
+ r = yp_first(__ypdomain, "group.byname",
+ &__ypcurrent, &__ypcurrentlen,
+ &data, &datalen);
+ /*printf("yp_first %d\n", r);*/
+ switch(r) {
+ case 0:
+ break;
+ default:
+ __ypmode = 0;
+ free(data);
+ continue;
+ }
+ bcopy(data, line, datalen);
+ free(data);
+ }
+ line[datalen] = '\0';
+ /*printf("line = %s\n", line);*/
+ bp = line;
+ goto parse;
+ }
+#endif
if (!fgets(line, sizeof(line), _gr_fp))
return(0);
bp = line;
/* skip lines that are too big */
- if (!index(line, '\n')) {
+ if (!strchr(line, '\n')) {
int ch;
while ((ch = getc(_gr_fp)) != '\n' && ch != EOF)
;
continue;
}
+#ifdef YP
+ if ((strcmp("+\n", line) == 0) || (strncmp("+:*:0:", line, 5) == 0)) {
+ if(_yp_check(NULL)) {
+ __ypmode = 1;
+ continue;
+ }
+ }
+parse:
+#endif
_gr_group.gr_name = strsep(&bp, ":\n");
if (search && name && strcmp(_gr_group.gr_name, name))
continue;
diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c
index fe1b19cc2563..93a09ee52ff6 100644
--- a/lib/libc/gen/getpwent.c
+++ b/lib/libc/gen/getpwent.c
@@ -32,7 +32,8 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getpwent.c 5.21 (Berkeley) 3/14/91";
+/*static char *sccsid = "from: @(#)getpwent.c 5.21 (Berkeley) 3/14/91";*/
+static char *rcsid = "$Id: getpwent.c,v 1.4 1994/01/11 19:00:58 nate Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -46,6 +47,12 @@ static char sccsid[] = "@(#)getpwent.c 5.21 (Berkeley) 3/14/91";
#include <stdlib.h>
#include <string.h>
#include <limits.h>
+#ifdef YP
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
static struct passwd _pw_passwd; /* password structure */
static DB *_pw_db; /* password database */
@@ -53,21 +60,142 @@ static int _pw_keynum; /* key counter */
static int _pw_stayopen; /* keep fd's open */
static int __hashpw(), __initdb();
+#ifdef YP
+static char *__ypcurrent, *__ypdomain;
+static int __ypcurrentlen, __ypmode=0;
+static char line[1024];
+
+static int
+__ypparse(pw, s)
+struct passwd *pw;
+char *s;
+{
+ char *bp, *cp;
+
+ bp = s;
+ pw->pw_name = strsep(&bp, ":\n");
+ pw->pw_passwd = strsep(&bp, ":\n");
+ if (!(cp = strsep(&bp, ":\n")))
+ return 1;
+ pw->pw_uid = atoi(cp);
+ if (!(cp = strsep(&bp, ":\n")))
+ return 0;
+ pw->pw_gid = atoi(cp);
+ pw->pw_change = 0;
+ pw->pw_class = "";
+ pw->pw_gecos = strsep(&bp, ":\n");
+ pw->pw_dir = strsep(&bp, ":\n");
+ pw->pw_shell = strsep(&bp, ":\n");
+ pw->pw_expire = 0;
+ return 0;
+}
+#endif
+
struct passwd *
getpwent()
{
DBT key;
char bf[sizeof(_pw_keynum) + 1];
+#ifdef YP
+ char *bp, *cp;
+#endif
if (!_pw_db && !__initdb())
return((struct passwd *)NULL);
+#ifdef YP
+again:
+ if(__ypmode) {
+ char *key, *data;
+ int keylen, datalen;
+ int r;
+
+ if(!__ypdomain) {
+ if( _yp_check(&__ypdomain) == 0) {
+ __ypmode = 0;
+ goto again;
+ }
+ }
+ if(__ypcurrent) {
+ r = yp_next(__ypdomain, "passwd.byname",
+ __ypcurrent, __ypcurrentlen,
+ &key, &keylen, &data, &datalen);
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+ /*printf("yp_next %d\n", r);*/
+ switch(r) {
+ case 0:
+ break;
+ default:
+ __ypcurrent = NULL;
+ __ypmode = 0;
+ free(data);
+ data = NULL;
+ goto again;
+ }
+ __ypcurrent = key;
+ __ypcurrentlen = keylen;
+ bcopy(data, line, datalen);
+ free(data);
+ data = NULL;
+ } else {
+ r = yp_first(__ypdomain, "passwd.byname",
+ &__ypcurrent, &__ypcurrentlen,
+ &data, &datalen);
+ /*printf("yp_first %d\n", r);*/
+ switch(r) {
+ case 0:
+ break;
+ default:
+ __ypmode = 0;
+ free(data);
+ goto again;
+ }
+ bcopy(data, line, datalen);
+ free(data);
+ data = NULL;
+ }
+ line[datalen] = '\0';
+ /*printf("line = %s\n", line);*/
+ bp = line;
+ goto parse;
+ }
+#endif
+
++_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;
- return(__hashpw(&key) ? &_pw_passwd : (struct passwd *)NULL);
+ if(__hashpw(&key)) {
+#ifdef YP
+ if(strcmp(_pw_passwd.pw_name, "+") == 0) {
+ __ypmode = 1;
+ goto again;
+ }
+#endif
+ return &_pw_passwd;
+ }
+ return (struct passwd *)NULL;
+
+#ifdef YP
+parse:
+ _pw_passwd.pw_name = strsep(&bp, ":\n");
+ _pw_passwd.pw_passwd = strsep(&bp, ":\n");
+ if (!(cp = strsep(&bp, ":\n")))
+ goto again;
+ _pw_passwd.pw_uid = atoi(cp);
+ if (!(cp = strsep(&bp, ":\n")))
+ goto again;
+ _pw_passwd.pw_gid = atoi(cp);
+ _pw_passwd.pw_change = 0;
+ _pw_passwd.pw_class = "";
+ _pw_passwd.pw_gecos = strsep(&bp, ":\n");
+ _pw_passwd.pw_dir = strsep(&bp, ":\n");
+ _pw_passwd.pw_shell = strsep(&bp, ":\n");
+ _pw_passwd.pw_expire = 0;
+ return &_pw_passwd;
+#endif
}
struct passwd *
@@ -81,6 +209,70 @@ getpwnam(name)
if (!_pw_db && !__initdb())
return((struct passwd *)NULL);
+#ifdef YP
+ bf[0] = _PW_KEYBYNAME;
+ len = strlen("+");
+ bcopy("+", bf + 1, MIN(len, UT_NAMESIZE));
+ key.data = (u_char *)bf;
+ key.size = len + 1;
+
+ /*
+ * If there is a user called "+", then YP is active. In that
+ * case we must sequence through the passwd file in sequence.
+ */
+ if ( __hashpw(&key)) {
+ int r;
+
+ for(_pw_keynum=1; _pw_keynum; _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;
+ if(__hashpw(&key) == 0)
+ break;
+ if(strcmp(_pw_passwd.pw_name, "+") == 0) {
+ if(!__ypdomain) {
+ if(_yp_check(&__ypdomain) == 0) {
+ continue;
+ }
+ }
+ if(__ypcurrent) {
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+ }
+ r = yp_match(__ypdomain, "passwd.byname",
+ name, strlen(name),
+ &__ypcurrent, &__ypcurrentlen);
+ switch(r) {
+ case 0:
+ break;
+ default:
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+ continue;
+ }
+ bcopy(__ypcurrent, line, __ypcurrentlen);
+ line[__ypcurrentlen] = '\0';
+ if(__ypparse(&_pw_passwd, line))
+ continue;
+ }
+ if( strcmp(_pw_passwd.pw_name, name) == 0) {
+ if (!_pw_stayopen) {
+ (void)(_pw_db->close)(_pw_db);
+ _pw_db = (DB *)NULL;
+ }
+ return &_pw_passwd;
+ }
+ continue;
+ }
+ if (!_pw_stayopen) {
+ (void)(_pw_db->close)(_pw_db);
+ _pw_db = (DB *)NULL;
+ }
+ return (struct passwd *)NULL;
+ }
+#endif /* YP */
+
bf[0] = _PW_KEYBYNAME;
len = strlen(name);
bcopy(name, bf + 1, MIN(len, UT_NAMESIZE));
@@ -104,12 +296,78 @@ getpwuid(uid)
#endif
{
DBT key;
- int keyuid, rval;
- char bf[sizeof(keyuid) + 1];
+ char bf[sizeof(_pw_keynum) + 1];
+ int keyuid, rval, len;
if (!_pw_db && !__initdb())
return((struct passwd *)NULL);
+#ifdef YP
+ bf[0] = _PW_KEYBYNAME;
+ len = strlen("+");
+ bcopy("+", bf + 1, MIN(len, UT_NAMESIZE));
+ key.data = (u_char *)bf;
+ key.size = len + 1;
+
+ /*
+ * If there is a user called "+", then YP is active. In that
+ * case we must sequence through the passwd file in sequence.
+ */
+ if ( __hashpw(&key)) {
+ char uidbuf[20];
+ int r;
+
+ for(_pw_keynum=1; _pw_keynum; _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;
+ if(__hashpw(&key) == 0)
+ break;
+ if(strcmp(_pw_passwd.pw_name, "+") == 0) {
+ if(!__ypdomain) {
+ if(_yp_check(&__ypdomain) == 0) {
+ continue;
+ }
+ }
+ if(__ypcurrent) {
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+ }
+ sprintf(uidbuf, "%d", uid);
+ r = yp_match(__ypdomain, "passwd.byuid",
+ uidbuf, strlen(uidbuf),
+ &__ypcurrent, &__ypcurrentlen);
+ switch(r) {
+ case 0:
+ break;
+ default:
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+ continue;
+ }
+ bcopy(__ypcurrent, line, __ypcurrentlen);
+ line[__ypcurrentlen] = '\0';
+ if(__ypparse(&_pw_passwd, line))
+ continue;
+ }
+ if( _pw_passwd.pw_uid == uid) {
+ if (!_pw_stayopen) {
+ (void)(_pw_db->close)(_pw_db);
+ _pw_db = (DB *)NULL;
+ }
+ return &_pw_passwd;
+ }
+ continue;
+ }
+ if (!_pw_stayopen) {
+ (void)(_pw_db->close)(_pw_db);
+ _pw_db = (DB *)NULL;
+ }
+ return (struct passwd *)NULL;
+ }
+#endif /* YP */
+
bf[0] = _PW_KEYBYUID;
keyuid = uid;
bcopy(&keyuid, bf + 1, sizeof(keyuid));
@@ -130,15 +388,19 @@ setpassent(stayopen)
{
_pw_keynum = 0;
_pw_stayopen = stayopen;
+#ifdef YP
+ __ypmode = 0;
+ if(__ypcurrent)
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+#endif
return(1);
}
-int
+void
setpwent()
{
- _pw_keynum = 0;
- _pw_stayopen = 0;
- return(1);
+ (void) setpassent(0);
}
void
@@ -149,9 +411,15 @@ endpwent()
(void)(_pw_db->close)(_pw_db);
_pw_db = (DB *)NULL;
}
+#ifdef YP
+ __ypmode = 0;
+ if(__ypcurrent)
+ free(__ypcurrent);
+ __ypcurrent = NULL;
+#endif
}
-static
+static int
__initdb()
{
static int warned;
@@ -166,7 +434,7 @@ __initdb()
return(0);
}
-static
+static int
__hashpw(key)
DBT *key;
{
diff --git a/lib/libc/gen/isctype.c b/lib/libc/gen/isctype.c
index e598f1069d12..d8dd5bc33e9f 100644
--- a/lib/libc/gen/isctype.c
+++ b/lib/libc/gen/isctype.c
@@ -1,4 +1,13 @@
/*
+ * Copyright (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.
+ *
+ * $Id: isctype.c,v 1.1.1.1.2.1 1994/05/04 07:39:44 rgrimes Exp $
+ */
+/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
@@ -30,12 +39,6 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
- * -------------------- ----- ----------------------
- * CURRENT PATCH LEVEL: 1 00027
- * -------------------- ----- ----------------------
- *
- * 02 Aug 92 Wiljo Heinen Fixed toupper()/tolower() range check
*/
#if defined(LIBC_SCCS) && !defined(lint)
diff --git a/lib/libc/gen/isupper.3 b/lib/libc/gen/isupper.3
index a9ac34b089a5..22d39e2114fe 100644
--- a/lib/libc/gen/isupper.3
+++ b/lib/libc/gen/isupper.3
@@ -44,7 +44,7 @@
.Sh SYNOPSIS
.Fd #include <ctype.h>
.Ft int
-.Fn supper "int c"
+.Fn isupper "int c"
.Sh DESCRIPTION
The
.Fn isupper
diff --git a/lib/libc/gen/ldexp.3 b/lib/libc/gen/ldexp.3
index 7b96ef4871fa..9920fc45a2f2 100644
--- a/lib/libc/gen/ldexp.3
+++ b/lib/libc/gen/ldexp.3
@@ -40,7 +40,7 @@
.Os
.Sh NAME
.Nm ldexp
-.Nd mutliply floating-point number by integral power of 2
+.Nd multiply floating-point number by integral power of 2
.Sh SYNOPSIS
.Fd #include <math.h>
.Ft double
diff --git a/lib/libc/gen/msgctl.c b/lib/libc/gen/msgctl.c
new file mode 100644
index 000000000000..7b74c51e2466
--- /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 000000000000..3e146b05cbe6
--- /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 000000000000..5c1e387d1439
--- /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 000000000000..a6209159ff50
--- /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/nlist.3 b/lib/libc/gen/nlist.3
index 4e4fe24c1c90..4d0bdf302139 100644
--- a/lib/libc/gen/nlist.3
+++ b/lib/libc/gen/nlist.3
@@ -46,7 +46,7 @@ The
.Fn nlist
function
retrieves name list entries from the symbol table of an
-exectutable file. (See
+executable file. (See
.Xr a.out 5 . )
The argument
.Fa \&nl
diff --git a/lib/libc/gen/regexp.3 b/lib/libc/gen/regexp.3
deleted file mode 100644
index c78082bb8b0d..000000000000
--- a/lib/libc/gen/regexp.3
+++ /dev/null
@@ -1,315 +0,0 @@
-.\" Copyright 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.
-.\"
-.\" @(#)regexp.3 5.2 (Berkeley) 4/19/91
-.\"
-.Dd April 19, 1991
-.Dt REGEXP 3
-.Os
-.Sh NAME
-.Nm regcomp ,
-.Nm regexec ,
-.Nm regsub ,
-.Nm regerror
-.Nd regular expression handlers
-.Sh SYNOPSIS
-.Fd #include <regexp.h>
-.Ft regexp *
-.Fn regcomp "const char *exp"
-.Ft int
-.Fn regexec "const regexp *prog" "const char *string"
-.Ft void
-.Fn regsub "const regexp *prog" "const char *source" "char *dest"
-.Sh DESCRIPTION
-The
-.Fn regcomp ,
-.Fn regexec ,
-.Fn regsub ,
-and
-.Fn regerror
-functions
-implement
-.Xr egrep 1 Ns -style
-regular expressions and supporting facilities.
-.Pp
-The
-.Fn regcomp
-function
-compiles a regular expression into a structure of type
-.Xr regexp ,
-and returns a pointer to it.
-The space has been allocated using
-.Xr malloc 3
-and may be released by
-.Xr free .
-.Pp
-The
-.Fn regexec
-function
-matches a
-.Dv NUL Ns -terminated
-.Fa string
-against the compiled regular expression
-in
-.Fa prog .
-It returns 1 for success and 0 for failure, and adjusts the contents of
-.Fa prog Ns 's
-.Em startp
-and
-.Em endp
-(see below) accordingly.
-.Pp
-The members of a
-.Xr regexp
-structure include at least the following (not necessarily in order):
-.Bd -literal -offset indent
-char *startp[NSUBEXP];
-char *endp[NSUBEXP];
-.Ed
-.Pp
-where
-.Dv NSUBEXP
-is defined (as 10) in the header file.
-Once a successful
-.Fn regexec
-has been done using the
-.Fn regexp ,
-each
-.Em startp Ns - Em endp
-pair describes one substring
-within the
-.Fa string ,
-with the
-.Em startp
-pointing to the first character of the substring and
-the
-.Em endp
-pointing to the first character following the substring.
-The 0th substring is the substring of
-.Fa string
-that matched the whole
-regular expression.
-The others are those substrings that matched parenthesized expressions
-within the regular expression, with parenthesized expressions numbered
-in left-to-right order of their opening parentheses.
-.Pp
-The
-.Fn regsub
-function
-copies
-.Fa source
-to
-.Fa dest ,
-making substitutions according to the
-most recent
-.Fn regexec
-performed using
-.Fa prog .
-Each instance of `&' in
-.Fa source
-is replaced by the substring
-indicated by
-.Em startp Ns Bq
-and
-.Em endp Ns Bq .
-Each instance of
-.Sq \e Ns Em n ,
-where
-.Em n
-is a digit, is replaced by
-the substring indicated by
-.Em startp Ns Bq Em n
-and
-.Em endp Ns Bq Em n .
-To get a literal `&' or
-.Sq \e Ns Em n
-into
-.Fa dest ,
-prefix it with `\e';
-to get a literal `\e' preceding `&' or
-.Sq \e Ns Em n ,
-prefix it with
-another `\e'.
-.Pp
-The
-.Fn regerror
-function
-is called whenever an error is detected in
-.Fn regcomp ,
-.Fn regexec ,
-or
-.Fn regsub .
-The default
-.Fn regerror
-writes the string
-.Fa msg ,
-with a suitable indicator of origin,
-on the standard
-error output
-and invokes
-.Xr exit 2 .
-The
-.Fn regerror
-function
-can be replaced by the user if other actions are desirable.
-.Sh REGULAR EXPRESSION SYNTAX
-A regular expression is zero or more
-.Em branches ,
-separated by `|'.
-It matches anything that matches one of the branches.
-.Pp
-A branch is zero or more
-.Em pieces ,
-concatenated.
-It matches a match for the first, followed by a match for the second, etc.
-.Pp
-A piece is an
-.Em atom
-possibly followed by `*', `+', or `?'.
-An atom followed by `*' matches a sequence of 0 or more matches of the atom.
-An atom followed by `+' matches a sequence of 1 or more matches of the atom.
-An atom followed by `?' matches a match of the atom, or the null string.
-.Pp
-An atom is a regular expression in parentheses (matching a match for the
-regular expression), a
-.Em range
-(see below), `.'
-(matching any single character), `^' (matching the null string at the
-beginning of the input string), `$' (matching the null string at the
-end of the input string), a `\e' followed by a single character (matching
-that character), or a single character with no other significance
-(matching that character).
-.Pp
-A
-.Em range
-is a sequence of characters enclosed in `[]'.
-It normally matches any single character from the sequence.
-If the sequence begins with `^',
-it matches any single character
-.Em not
-from the rest of the sequence.
-If two characters in the sequence are separated by `\-', this is shorthand
-for the full list of
-.Tn ASCII
-characters between them
-(e.g. `[0-9]' matches any decimal digit).
-To include a literal `]' in the sequence, make it the first character
-(following a possible `^').
-To include a literal `\-', make it the first or last character.
-.Sh AMBIGUITY
-If a regular expression could match two different parts of the input string,
-it will match the one which begins earliest.
-If both begin in the same place but match different lengths, or match
-the same length in different ways, life gets messier, as follows.
-.Pp
-In general, the possibilities in a list of branches are considered in
-left-to-right order, the possibilities for `*', `+', and `?' are
-considered longest-first, nested constructs are considered from the
-outermost in, and concatenated constructs are considered leftmost-first.
-The match that will be chosen is the one that uses the earliest
-possibility in the first choice that has to be made.
-If there is more than one choice, the next will be made in the same manner
-(earliest possibility) subject to the decision on the first choice.
-And so forth.
-.Pp
-For example,
-.Sq Li (ab|a)b*c
-could match
-`abc' in one of two ways.
-The first choice is between `ab' and `a'; since `ab' is earlier, and does
-lead to a successful overall match, it is chosen.
-Since the `b' is already spoken for,
-the `b*' must match its last possibility\(emthe empty string\(emsince
-it must respect the earlier choice.
-.Pp
-In the particular case where no `|'s are present and there is only one
-`*', `+', or `?', the net effect is that the longest possible
-match will be chosen.
-So
-.Sq Li ab* ,
-presented with `xabbbby', will match `abbbb'.
-Note that if
-.Sq Li ab* ,
-is tried against `xabyabbbz', it
-will match `ab' just after `x', due to the begins-earliest rule.
-(In effect, the decision on where to start the match is the first choice
-to be made, hence subsequent choices must respect it even if this leads them
-to less-preferred alternatives.)
-.Sh RETURN VALUES
-The
-.Fn regcomp
-function
-returns
-.Dv NULL
-for a failure
-.Pf ( Fn regerror
-permitting),
-where failures are syntax errors, exceeding implementation limits,
-or applying `+' or `*' to a possibly-null operand.
-.Sh SEE ALSO
-.Xr ed 1 ,
-.Xr ex 1 ,
-.Xr expr 1 ,
-.Xr egrep 1 ,
-.Xr fgrep 1 ,
-.Xr grep 1 ,
-.Xr regex 3
-.Sh HISTORY
-Both code and manual page for
-.Fn regcomp ,
-.Fn regexec ,
-.Fn regsub ,
-and
-.Fn regerror
-were written at the University of Toronto
-and appeared in
-.Bx 4.3 tahoe .
-They are intended to be compatible with the Bell V8
-.Xr regexp 3 ,
-but are not derived from Bell code.
-.Sh BUGS
-Empty branches and empty regular expressions are not portable to V8.
-.Pp
-The restriction against
-applying `*' or `+' to a possibly-null operand is an artifact of the
-simplistic implementation.
-.Pp
-Does not support
-.Xr egrep Ns 's
-newline-separated branches;
-neither does the V8
-.Xr regexp 3 ,
-though.
-.Pp
-Due to emphasis on
-compactness and simplicity,
-it's not strikingly fast.
-It does give special attention to handling simple cases quickly.
diff --git a/lib/libc/gen/regexp/COPYRIGHT b/lib/libc/gen/regexp/COPYRIGHT
deleted file mode 100644
index 48b3f4339171..000000000000
--- a/lib/libc/gen/regexp/COPYRIGHT
+++ /dev/null
@@ -1,22 +0,0 @@
-This entire subtree is copyright the University of Toronto.
-The following copyright notice applies to all files found here. None of
-these files contain AT&T proprietary source code.
-_____________________________________________________________________________
-
- Copyright (c) 1986 by University of Toronto.
- Written by Henry Spencer. Not derived from licensed software.
-
- Permission is granted to anyone to use this software for any
- purpose on any computer system, and to redistribute it freely,
- subject to the following restrictions:
-
- 1. The author is not responsible for the consequences of use of
- this software, no matter how awful, even if they arise
- from defects in it.
-
- 2. The origin of this software must not be misrepresented, either
- by explicit claim or by omission.
-
- 3. Altered versions must be plainly marked as such, and must not
- be misrepresented as being the original software.
-
diff --git a/lib/libc/gen/regexp/README b/lib/libc/gen/regexp/README
deleted file mode 100644
index 37d6f51c7119..000000000000
--- a/lib/libc/gen/regexp/README
+++ /dev/null
@@ -1,84 +0,0 @@
-This is a nearly-public-domain reimplementation of the V8 regexp(3) package.
-It gives C programs the ability to use egrep-style regular expressions, and
-does it in a much cleaner fashion than the analogous routines in SysV.
-
- Copyright (c) 1986 by University of Toronto.
- Written by Henry Spencer. Not derived from licensed software.
-
- Permission is granted to anyone to use this software for any
- purpose on any computer system, and to redistribute it freely,
- subject to the following restrictions:
-
- 1. The author is not responsible for the consequences of use of
- this software, no matter how awful, even if they arise
- from defects in it.
-
- 2. The origin of this software must not be misrepresented, either
- by explicit claim or by omission.
-
- 3. Altered versions must be plainly marked as such, and must not
- be misrepresented as being the original software.
-
-Barring a couple of small items in the BUGS list, this implementation is
-believed 100% compatible with V8. It should even be binary-compatible,
-sort of, since the only fields in a "struct regexp" that other people have
-any business touching are declared in exactly the same way at the same
-location in the struct (the beginning).
-
-This implementation is *NOT* AT&T/Bell code, and is not derived from licensed
-software. Even though U of T is a V8 licensee. This software is based on
-a V8 manual page sent to me by Dennis Ritchie (the manual page enclosed
-here is a complete rewrite and hence is not covered by AT&T copyright).
-The software was nearly complete at the time of arrival of our V8 tape.
-I haven't even looked at V8 yet, although a friend elsewhere at U of T has
-been kind enough to run a few test programs using the V8 regexp(3) to resolve
-a few fine points. I admit to some familiarity with regular-expression
-implementations of the past, but the only one that this code traces any
-ancestry to is the one published in Kernighan & Plauger (from which this
-one draws ideas but not code).
-
-Simplistically: put this stuff into a source directory, copy regexp.h into
-/usr/include, inspect Makefile for compilation options that need changing
-to suit your local environment, and then do "make r". This compiles the
-regexp(3) functions, compiles a test program, and runs a large set of
-regression tests. If there are no complaints, then put regexp.o, regsub.o,
-and regerror.o into your C library, and regexp.3 into your manual-pages
-directory.
-
-Note that if you don't put regexp.h into /usr/include *before* compiling,
-you'll have to add "-I." to CFLAGS before compiling.
-
-The files are:
-
-Makefile instructions to make everything
-regexp.3 manual page
-regexp.h header file, for /usr/include
-regexp.c source for regcomp() and regexec()
-regsub.c source for regsub()
-regerror.c source for default regerror()
-regmagic.h internal header file
-try.c source for test program
-timer.c source for timing program
-tests test list for try and timer
-
-This implementation uses nondeterministic automata rather than the
-deterministic ones found in some other implementations, which makes it
-simpler, smaller, and faster at compiling regular expressions, but slower
-at executing them. In theory, anyway. This implementation does employ
-some special-case optimizations to make the simpler cases (which do make
-up the bulk of regular expressions actually used) run quickly. In general,
-if you want blazing speed you're in the wrong place. Replacing the insides
-of egrep with this stuff is probably a mistake; if you want your own egrep
-you're going to have to do a lot more work. But if you want to use regular
-expressions a little bit in something else, you're in luck. Note that many
-existing text editors use nondeterministic regular-expression implementations,
-so you're in good company.
-
-This stuff should be pretty portable, given appropriate option settings.
-If your chars have less than 8 bits, you're going to have to change the
-internal representation of the automaton, although knowledge of the details
-of this is fairly localized. There are no "reserved" char values except for
-NUL, and no special significance is attached to the top bit of chars.
-The string(3) functions are used a fair bit, on the grounds that they are
-probably faster than coding the operations in line. Some attempts at code
-tuning have been made, but this is invariably a bit machine-specific.
diff --git a/lib/libc/gen/regexp/regerror.c b/lib/libc/gen/regexp/regerror.c
deleted file mode 100644
index 6d0077d63429..000000000000
--- a/lib/libc/gen/regexp/regerror.c
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <regexp.h>
-#include <stdio.h>
-
-void
-regerror(s)
-const char *s;
-{
-#ifdef ERRAVAIL
- error("regexp: %s", s);
-#else
-/*
- fprintf(stderr, "regexp(3): %s\n", s);
- exit(1);
-*/
- return; /* let std. egrep handle errors */
-#endif
- /* NOTREACHED */
-}
diff --git a/lib/libc/gen/regexp/regexp.3 b/lib/libc/gen/regexp/regexp.3
deleted file mode 100644
index b25fb4b498c6..000000000000
--- a/lib/libc/gen/regexp/regexp.3
+++ /dev/null
@@ -1,315 +0,0 @@
-.\" Copyright 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.
-.\"
-.\" @(#)regexp.3 5.2 (Berkeley) 4/20/91
-.\"
-.Dd April 20, 1991
-.Dt REGEXP 3
-.Os
-.Sh NAME
-.Nm regcomp ,
-.Nm regexec ,
-.Nm regsub ,
-.Nm regerror
-.Nd regular expression handlers
-.Sh SYNOPSIS
-.Fd #include <regexp.h>
-.Ft regexp *
-.Fn regcomp "const char *exp"
-.Ft int
-.Fn regexec "const regexp *prog" "const char *string"
-.Ft void
-.Fn regsub "const regexp *prog" "const char *source" "char *dest"
-.Sh DESCRIPTION
-The
-.Fn regcomp ,
-.Fn regexec ,
-.Fn regsub ,
-and
-.Fn regerror
-functions
-implement
-.Xr egrep 1 Ns -style
-regular expressions and supporting facilities.
-.Pp
-The
-.Fn regcomp
-function
-compiles a regular expression into a structure of type
-.Xr regexp ,
-and returns a pointer to it.
-The space has been allocated using
-.Xr malloc 3
-and may be released by
-.Xr free .
-.Pp
-The
-.Fn regexec
-function
-matches a
-.Dv NUL Ns -terminated
-.Fa string
-against the compiled regular expression
-in
-.Fa prog .
-It returns 1 for success and 0 for failure, and adjusts the contents of
-.Fa prog Ns 's
-.Em startp
-and
-.Em endp
-(see below) accordingly.
-.Pp
-The members of a
-.Xr regexp
-structure include at least the following (not necessarily in order):
-.Bd -literal -offset indent
-char *startp[NSUBEXP];
-char *endp[NSUBEXP];
-.Ed
-.Pp
-where
-.Dv NSUBEXP
-is defined (as 10) in the header file.
-Once a successful
-.Fn regexec
-has been done using the
-.Fn regexp ,
-each
-.Em startp Ns - Em endp
-pair describes one substring
-within the
-.Fa string ,
-with the
-.Em startp
-pointing to the first character of the substring and
-the
-.Em endp
-pointing to the first character following the substring.
-The 0th substring is the substring of
-.Fa string
-that matched the whole
-regular expression.
-The others are those substrings that matched parenthesized expressions
-within the regular expression, with parenthesized expressions numbered
-in left-to-right order of their opening parentheses.
-.Pp
-The
-.Fn regsub
-function
-copies
-.Fa source
-to
-.Fa dest ,
-making substitutions according to the
-most recent
-.Fn regexec
-performed using
-.Fa prog .
-Each instance of `&' in
-.Fa source
-is replaced by the substring
-indicated by
-.Em startp Ns Bq
-and
-.Em endp Ns Bq .
-Each instance of
-.Sq \e Ns Em n ,
-where
-.Em n
-is a digit, is replaced by
-the substring indicated by
-.Em startp Ns Bq Em n
-and
-.Em endp Ns Bq Em n .
-To get a literal `&' or
-.Sq \e Ns Em n
-into
-.Fa dest ,
-prefix it with `\e';
-to get a literal `\e' preceding `&' or
-.Sq \e Ns Em n ,
-prefix it with
-another `\e'.
-.Pp
-The
-.Fn regerror
-function
-is called whenever an error is detected in
-.Fn regcomp ,
-.Fn regexec ,
-or
-.Fn regsub .
-The default
-.Fn regerror
-writes the string
-.Fa msg ,
-with a suitable indicator of origin,
-on the standard
-error output
-and invokes
-.Xr exit 2 .
-The
-.Fn regerror
-function
-can be replaced by the user if other actions are desirable.
-.Sh REGULAR EXPRESSION SYNTAX
-A regular expression is zero or more
-.Em branches ,
-separated by `|'.
-It matches anything that matches one of the branches.
-.Pp
-A branch is zero or more
-.Em pieces ,
-concatenated.
-It matches a match for the first, followed by a match for the second, etc.
-.Pp
-A piece is an
-.Em atom
-possibly followed by `*', `+', or `?'.
-An atom followed by `*' matches a sequence of 0 or more matches of the atom.
-An atom followed by `+' matches a sequence of 1 or more matches of the atom.
-An atom followed by `?' matches a match of the atom, or the null string.
-.Pp
-An atom is a regular expression in parentheses (matching a match for the
-regular expression), a
-.Em range
-(see below), `.'
-(matching any single character), `^' (matching the null string at the
-beginning of the input string), `$' (matching the null string at the
-end of the input string), a `\e' followed by a single character (matching
-that character), or a single character with no other significance
-(matching that character).
-.Pp
-A
-.Em range
-is a sequence of characters enclosed in `[]'.
-It normally matches any single character from the sequence.
-If the sequence begins with `^',
-it matches any single character
-.Em not
-from the rest of the sequence.
-If two characters in the sequence are separated by `\-', this is shorthand
-for the full list of
-.Tn ASCII
-characters between them
-(e.g. `[0-9]' matches any decimal digit).
-To include a literal `]' in the sequence, make it the first character
-(following a possible `^').
-To include a literal `\-', make it the first or last character.
-.Sh AMBIGUITY
-If a regular expression could match two different parts of the input string,
-it will match the one which begins earliest.
-If both begin in the same place but match different lengths, or match
-the same length in different ways, life gets messier, as follows.
-.Pp
-In general, the possibilities in a list of branches are considered in
-left-to-right order, the possibilities for `*', `+', and `?' are
-considered longest-first, nested constructs are considered from the
-outermost in, and concatenated constructs are considered leftmost-first.
-The match that will be chosen is the one that uses the earliest
-possibility in the first choice that has to be made.
-If there is more than one choice, the next will be made in the same manner
-(earliest possibility) subject to the decision on the first choice.
-And so forth.
-.Pp
-For example,
-.Sq Li (ab|a)b*c
-could match
-`abc' in one of two ways.
-The first choice is between `ab' and `a'; since `ab' is earlier, and does
-lead to a successful overall match, it is chosen.
-Since the `b' is already spoken for,
-the `b*' must match its last possibility\(emthe empty string\(emsince
-it must respect the earlier choice.
-.Pp
-In the particular case where no `|'s are present and there is only one
-`*', `+', or `?', the net effect is that the longest possible
-match will be chosen.
-So
-.Sq Li ab* ,
-presented with `xabbbby', will match `abbbb'.
-Note that if
-.Sq Li ab* ,
-is tried against `xabyabbbz', it
-will match `ab' just after `x', due to the begins-earliest rule.
-(In effect, the decision on where to start the match is the first choice
-to be made, hence subsequent choices must respect it even if this leads them
-to less-preferred alternatives.)
-.Sh RETURN VALUES
-The
-.Fn regcomp
-function
-returns
-.Dv NULL
-for a failure
-.Pf ( Fn regerror
-permitting),
-where failures are syntax errors, exceeding implementation limits,
-or applying `+' or `*' to a possibly-null operand.
-.Sh SEE ALSO
-.Xr ed 1 ,
-.Xr ex 1 ,
-.Xr expr 1 ,
-.Xr egrep 1 ,
-.Xr fgrep 1 ,
-.Xr grep 1 ,
-.Xr regex 3
-.Sh HISTORY
-Both code and manual page for
-.Fn regcomp ,
-.Fn regexec ,
-.Fn regsub ,
-and
-.Fn regerror
-were written at the University of Toronto
-and appeared in
-.Bx 4.3 tahoe .
-They are intended to be compatible with the Bell V8
-.Xr regexp 3 ,
-but are not derived from Bell code.
-.Sh BUGS
-Empty branches and empty regular expressions are not portable to V8.
-.Pp
-The restriction against
-applying `*' or `+' to a possibly-null operand is an artifact of the
-simplistic implementation.
-.Pp
-Does not support
-.Xr egrep Ns 's
-newline-separated branches;
-neither does the V8
-.Xr regexp 3 ,
-though.
-.Pp
-Due to emphasis on
-compactness and simplicity,
-it's not strikingly fast.
-It does give special attention to handling simple cases quickly.
diff --git a/lib/libc/gen/regexp/regexp.c b/lib/libc/gen/regexp/regexp.c
deleted file mode 100644
index 0084295bfb37..000000000000
--- a/lib/libc/gen/regexp/regexp.c
+++ /dev/null
@@ -1,1320 +0,0 @@
-/*
- * regcomp and regexec -- regsub and regerror are elsewhere
- *
- * Copyright (c) 1986 by University of Toronto.
- * Written by Henry Spencer. Not derived from licensed software.
- *
- * Permission is granted to anyone to use this software for any
- * purpose on any computer system, and to redistribute it freely,
- * subject to the following restrictions:
- *
- * 1. The author is not responsible for the consequences of use of
- * this software, no matter how awful, even if they arise
- * from defects in it.
- *
- * 2. The origin of this software must not be misrepresented, either
- * by explicit claim or by omission.
- *
- * 3. Altered versions must be plainly marked as such, and must not
- * be misrepresented as being the original software.
- *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
- *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to |
- *** to assist in implementing egrep.
- *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
- *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching
- *** as in BSD grep and ex.
- *** THIS IS AN ALTERED VERSION. It was altered by John Gilmore,
- *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \.
- *** THIS IS AN ALTERED VERSION. It was altered by James A. Woods,
- *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy.
- *
- * Beware that some of this code is subtly aware of the way operator
- * precedence is structured in regular expressions. Serious changes in
- * regular-expression syntax might require a total rethink.
- */
-#include <regexp.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include "regmagic.h"
-
-/*
- * The "internal use only" fields in regexp.h are present to pass info from
- * compile to execute that permits the execute phase to run lots faster on
- * simple cases. They are:
- *
- * regstart char that must begin a match; '\0' if none obvious
- * reganch is the match anchored (at beginning-of-line only)?
- * regmust string (pointer into program) that match must include, or NULL
- * regmlen length of regmust string
- *
- * Regstart and reganch permit very fast decisions on suitable starting points
- * for a match, cutting down the work a lot. Regmust permits fast rejection
- * of lines that cannot possibly match. The regmust tests are costly enough
- * that regcomp() supplies a regmust only if the r.e. contains something
- * potentially expensive (at present, the only such thing detected is * or +
- * at the start of the r.e., which can involve a lot of backup). Regmlen is
- * supplied because the test in regexec() needs it and regcomp() is computing
- * it anyway.
- */
-
-/*
- * Structure for regexp "program". This is essentially a linear encoding
- * of a nondeterministic finite-state machine (aka syntax charts or
- * "railroad normal form" in parsing technology). Each node is an opcode
- * plus a "next" pointer, possibly plus an operand. "Next" pointers of
- * all nodes except BRANCH implement concatenation; a "next" pointer with
- * a BRANCH on both ends of it is connecting two alternatives. (Here we
- * have one of the subtle syntax dependencies: an individual BRANCH (as
- * opposed to a collection of them) is never concatenated with anything
- * because of operator precedence.) The operand of some types of node is
- * a literal string; for others, it is a node leading into a sub-FSM. In
- * particular, the operand of a BRANCH node is the first node of the branch.
- * (NB this is *not* a tree structure: the tail of the branch connects
- * to the thing following the set of BRANCHes.) The opcodes are:
- */
-
-/* definition number opnd? meaning */
-#define END 0 /* no End of program. */
-#define BOL 1 /* no Match "" at beginning of line. */
-#define EOL 2 /* no Match "" at end of line. */
-#define ANY 3 /* no Match any one character. */
-#define ANYOF 4 /* str Match any character in this string. */
-#define ANYBUT 5 /* str Match any character not in this string. */
-#define BRANCH 6 /* node Match this alternative, or the next... */
-#define BACK 7 /* no Match "", "next" ptr points backward. */
-#define EXACTLY 8 /* str Match this string. */
-#define NOTHING 9 /* no Match empty string. */
-#define STAR 10 /* node Match this (simple) thing 0 or more times. */
-#define PLUS 11 /* node Match this (simple) thing 1 or more times. */
-#define WORDA 12 /* no Match "" at wordchar, where prev is nonword */
-#define WORDZ 13 /* no Match "" at nonwordchar, where prev is word */
-#define OPEN 20 /* no Mark this point in input as start of #n. */
- /* OPEN+1 is number 1, etc. */
-#define CLOSE 30 /* no Analogous to OPEN. */
-
-/*
- * Opcode notes:
- *
- * BRANCH The set of branches constituting a single choice are hooked
- * together with their "next" pointers, since precedence prevents
- * anything being concatenated to any individual branch. The
- * "next" pointer of the last BRANCH in a choice points to the
- * thing following the whole choice. This is also where the
- * final "next" pointer of each individual branch points; each
- * branch starts with the operand node of a BRANCH node.
- *
- * BACK Normal "next" pointers all implicitly point forward; BACK
- * exists to make loop structures possible.
- *
- * STAR,PLUS '?', and complex '*' and '+', are implemented as circular
- * BRANCH structures using BACK. Simple cases (one character
- * per match) are implemented with STAR and PLUS for speed
- * and to minimize recursive plunges.
- *
- * OPEN,CLOSE ...are numbered at compile time.
- */
-
-/*
- * A node is one char of opcode followed by two chars of "next" pointer.
- * "Next" pointers are stored as two 8-bit pieces, high order first. The
- * value is a positive offset from the opcode of the node containing it.
- * An operand, if any, simply follows the node. (Note that much of the
- * code generation knows about this implicit relationship.)
- *
- * Using two bytes for the "next" pointer is vast overkill for most things,
- * but allows patterns to get big without disasters.
- */
-#define OP(p) (*(p))
-#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
-#define OPERAND(p) ((p) + 3)
-
-/*
- * See regmagic.h for one further detail of program structure.
- */
-
-
-/*
- * Utility definitions.
- */
-#ifndef CHARBITS
-#define UCHARAT(p) ((int)*(unsigned char *)(p))
-#else
-#define UCHARAT(p) ((int)*(p)&CHARBITS)
-#endif
-
-#define FAIL(m) { regerror(m); return(NULL); }
-#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
-
-/*
- * Flags to be passed up and down.
- */
-#define HASWIDTH 01 /* Known never to match null string. */
-#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */
-#define SPSTART 04 /* Starts with * or +. */
-#define WORST 0 /* Worst case. */
-
-/*
- * Global work variables for regcomp().
- */
-static char *regparse; /* Input-scan pointer. */
-static int regnpar; /* () count. */
-static char regdummy;
-static char *regcode; /* Code-emit pointer; &regdummy = don't. */
-static long regsize; /* Code size. */
-
-/*
- * Forward declarations for regcomp()'s friends.
- */
-#ifndef STATIC
-#define STATIC static
-#endif
-STATIC char *reg();
-STATIC char *regbranch();
-STATIC char *regpiece();
-STATIC char *regatom();
-STATIC char *regnode();
-STATIC char *regnext();
-STATIC void regc();
-STATIC void reginsert();
-STATIC void regtail();
-STATIC void regoptail();
-#ifdef STRCSPN
-STATIC int strcspn();
-#endif
-
-/*
- - regcomp - compile a regular expression into internal code
- *
- * We can't allocate space until we know how big the compiled form will be,
- * but we can't compile it (and thus know how big it is) until we've got a
- * place to put the code. So we cheat: we compile it twice, once with code
- * generation turned off and size counting turned on, and once "for real".
- * This also means that we don't allocate space until we are sure that the
- * thing really will compile successfully, and we never have to move the
- * code and thus invalidate pointers into it. (Note that it has to be in
- * one piece because free() must be able to free it all.)
- *
- * Beware that the optimization-preparation code in here knows about some
- * of the structure of the compiled regexp.
- */
-regexp *
-regcomp(exp)
-const char *exp;
-{
- register regexp *r;
- register char *scan;
- register char *longest;
- register int len;
- int flags;
-
- if (exp == NULL)
- FAIL("NULL argument");
-
- /* First pass: determine size, legality. */
-#ifdef notdef
- if (exp[0] == '.' && exp[1] == '*') exp += 2; /* aid grep */
-#endif
- regparse = (char *)exp;
- regnpar = 1;
- regsize = 0L;
- regcode = &regdummy;
- regc(MAGIC);
- if (reg(0, &flags) == NULL)
- return(NULL);
-
- /* Small enough for pointer-storage convention? */
- if (regsize >= 32767L) /* Probably could be 65535L. */
- FAIL("regexp too big");
-
- /* Allocate space. */
- r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize);
- if (r == NULL)
- FAIL("out of space");
-
- /* Second pass: emit code. */
- regparse = (char *)exp;
- regnpar = 1;
- regcode = r->program;
- regc(MAGIC);
- if (reg(0, &flags) == NULL)
- return(NULL);
-
- /* Dig out information for optimizations. */
- r->regstart = '\0'; /* Worst-case defaults. */
- r->reganch = 0;
- r->regmust = NULL;
- r->regmlen = 0;
- scan = r->program+1; /* First BRANCH. */
- if (OP(regnext(scan)) == END) { /* Only one top-level choice. */
- scan = OPERAND(scan);
-
- /* Starting-point info. */
- if (OP(scan) == EXACTLY)
- r->regstart = *OPERAND(scan);
- else if (OP(scan) == BOL)
- r->reganch++;
-
- /*
- * If there's something expensive in the r.e., find the
- * longest literal string that must appear and make it the
- * regmust. Resolve ties in favor of later strings, since
- * the regstart check works with the beginning of the r.e.
- * and avoiding duplication strengthens checking. Not a
- * strong reason, but sufficient in the absence of others.
- */
- if (flags&SPSTART) {
- longest = NULL;
- len = 0;
- for (; scan != NULL; scan = regnext(scan))
- if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
- longest = OPERAND(scan);
- len = strlen(OPERAND(scan));
- }
- r->regmust = longest;
- r->regmlen = len;
- }
- }
-
- return(r);
-}
-
-/*
- - reg - regular expression, i.e. main body or parenthesized thing
- *
- * Caller must absorb opening parenthesis.
- *
- * Combining parenthesis handling with the base level of regular expression
- * is a trifle forced, but the need to tie the tails of the branches to what
- * follows makes it hard to avoid.
- */
-static char *
-reg(paren, flagp)
-int paren; /* Parenthesized? */
-int *flagp;
-{
- register char *ret;
- register char *br;
- register char *ender;
- register int parno;
- int flags;
-
- *flagp = HASWIDTH; /* Tentatively. */
-
- /* Make an OPEN node, if parenthesized. */
- if (paren) {
- if (regnpar >= NSUBEXP)
- FAIL("too many ()");
- parno = regnpar;
- regnpar++;
- ret = regnode(OPEN+parno);
- } else
- ret = NULL;
-
- /* Pick up the branches, linking them together. */
- br = regbranch(&flags);
- if (br == NULL)
- return(NULL);
- if (ret != NULL)
- regtail(ret, br); /* OPEN -> first. */
- else
- ret = br;
- if (!(flags&HASWIDTH))
- *flagp &= ~HASWIDTH;
- *flagp |= flags&SPSTART;
- while (*regparse == '|' || *regparse == '\n') {
- regparse++;
- br = regbranch(&flags);
- if (br == NULL)
- return(NULL);
- regtail(ret, br); /* BRANCH -> BRANCH. */
- if (!(flags&HASWIDTH))
- *flagp &= ~HASWIDTH;
- *flagp |= flags&SPSTART;
- }
-
- /* Make a closing node, and hook it on the end. */
- ender = regnode((paren) ? CLOSE+parno : END);
- regtail(ret, ender);
-
- /* Hook the tails of the branches to the closing node. */
- for (br = ret; br != NULL; br = regnext(br))
- regoptail(br, ender);
-
- /* Check for proper termination. */
- if (paren && *regparse++ != ')') {
- FAIL("unmatched ()");
- } else if (!paren && *regparse != '\0') {
- if (*regparse == ')') {
- FAIL("unmatched ()");
- } else
- FAIL("junk on end"); /* "Can't happen". */
- /* NOTREACHED */
- }
-
- return(ret);
-}
-
-/*
- - regbranch - one alternative of an | operator
- *
- * Implements the concatenation operator.
- */
-static char *
-regbranch(flagp)
-int *flagp;
-{
- register char *ret;
- register char *chain;
- register char *latest;
- int flags;
-
- *flagp = WORST; /* Tentatively. */
-
- ret = regnode(BRANCH);
- chain = NULL;
- while (*regparse != '\0' && *regparse != ')' &&
- *regparse != '\n' && *regparse != '|') {
- latest = regpiece(&flags);
- if (latest == NULL)
- return(NULL);
- *flagp |= flags&HASWIDTH;
- if (chain == NULL) /* First piece. */
- *flagp |= flags&SPSTART;
- else
- regtail(chain, latest);
- chain = latest;
- }
- if (chain == NULL) /* Loop ran zero times. */
- (void) regnode(NOTHING);
-
- return(ret);
-}
-
-/*
- - regpiece - something followed by possible [*+?]
- *
- * Note that the branching code sequences used for ? and the general cases
- * of * and + are somewhat optimized: they use the same NOTHING node as
- * both the endmarker for their branch list and the body of the last branch.
- * It might seem that this node could be dispensed with entirely, but the
- * endmarker role is not redundant.
- */
-static char *
-regpiece(flagp)
-int *flagp;
-{
- register char *ret;
- register char op;
- register char *next;
- int flags;
-
- ret = regatom(&flags);
- if (ret == NULL)
- return(NULL);
-
- op = *regparse;
- if (!ISMULT(op)) {
- *flagp = flags;
- return(ret);
- }
-
- if (!(flags&HASWIDTH) && op != '?')
- FAIL("*+ operand could be empty");
- *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
-
- if (op == '*' && (flags&SIMPLE))
- reginsert(STAR, ret);
- else if (op == '*') {
- /* Emit x* as (x&|), where & means "self". */
- reginsert(BRANCH, ret); /* Either x */
- regoptail(ret, regnode(BACK)); /* and loop */
- regoptail(ret, ret); /* back */
- regtail(ret, regnode(BRANCH)); /* or */
- regtail(ret, regnode(NOTHING)); /* null. */
- } else if (op == '+' && (flags&SIMPLE))
- reginsert(PLUS, ret);
- else if (op == '+') {
- /* Emit x+ as x(&|), where & means "self". */
- next = regnode(BRANCH); /* Either */
- regtail(ret, next);
- regtail(regnode(BACK), ret); /* loop back */
- regtail(next, regnode(BRANCH)); /* or */
- regtail(ret, regnode(NOTHING)); /* null. */
- } else if (op == '?') {
- /* Emit x? as (x|) */
- reginsert(BRANCH, ret); /* Either x */
- regtail(ret, regnode(BRANCH)); /* or */
- next = regnode(NOTHING); /* null. */
- regtail(ret, next);
- regoptail(ret, next);
- }
- regparse++;
- if (ISMULT(*regparse))
- FAIL("nested *?+");
-
- return(ret);
-}
-
-/*
- - regatom - the lowest level
- *
- * Optimization: gobbles an entire sequence of ordinary characters so that
- * it can turn them into a single node, which is smaller to store and
- * faster to run. Backslashed characters are exceptions, each becoming a
- * separate node; the code is simpler that way and it's not worth fixing.
- */
-static char *
-regatom(flagp)
-int *flagp;
-{
- register char *ret;
- int flags;
-
- *flagp = WORST; /* Tentatively. */
-
- switch (*regparse++) {
- /* FIXME: these chars only have meaning at beg/end of pat? */
- case '^':
- ret = regnode(BOL);
- break;
- case '$':
- ret = regnode(EOL);
- break;
- case '.':
- ret = regnode(ANY);
- *flagp |= HASWIDTH|SIMPLE;
- break;
- case '[': {
- register int class;
- register int classend;
-
- if (*regparse == '^') { /* Complement of range. */
- ret = regnode(ANYBUT);
- regparse++;
- } else
- ret = regnode(ANYOF);
- if (*regparse == ']' || *regparse == '-')
- regc(*regparse++);
- while (*regparse != '\0' && *regparse != ']') {
- if (*regparse == '-') {
- regparse++;
- if (*regparse == ']' || *regparse == '\0')
- regc('-');
- else {
- class = UCHARAT(regparse-2)+1;
- classend = UCHARAT(regparse);
- if (class > classend+1)
- FAIL("invalid [] range");
- for (; class <= classend; class++)
- regc(class);
- regparse++;
- }
- } else
- regc(*regparse++);
- }
- regc('\0');
- if (*regparse != ']')
- FAIL("unmatched []");
- regparse++;
- *flagp |= HASWIDTH|SIMPLE;
- }
- break;
- case '(':
- ret = reg(1, &flags);
- if (ret == NULL)
- return(NULL);
- *flagp |= flags&(HASWIDTH|SPSTART);
- break;
- case '\0':
- case '|':
- case '\n':
- case ')':
- FAIL("internal urp"); /* Supposed to be caught earlier. */
- break;
- case '?':
- case '+':
- case '*':
- FAIL("?+* follows nothing");
- break;
- case '\\':
- switch (*regparse++) {
- case '\0':
- FAIL("trailing \\");
- break;
- case '<':
- ret = regnode(WORDA);
- break;
- case '>':
- ret = regnode(WORDZ);
- break;
- /* FIXME: Someday handle \1, \2, ... */
- default:
- /* Handle general quoted chars in exact-match routine */
- goto de_fault;
- }
- break;
- de_fault:
- default:
- /*
- * Encode a string of characters to be matched exactly.
- *
- * This is a bit tricky due to quoted chars and due to
- * '*', '+', and '?' taking the SINGLE char previous
- * as their operand.
- *
- * On entry, the char at regparse[-1] is going to go
- * into the string, no matter what it is. (It could be
- * following a \ if we are entered from the '\' case.)
- *
- * Basic idea is to pick up a good char in ch and
- * examine the next char. If it's *+? then we twiddle.
- * If it's \ then we frozzle. If it's other magic char
- * we push ch and terminate the string. If none of the
- * above, we push ch on the string and go around again.
- *
- * regprev is used to remember where "the current char"
- * starts in the string, if due to a *+? we need to back
- * up and put the current char in a separate, 1-char, string.
- * When regprev is NULL, ch is the only char in the
- * string; this is used in *+? handling, and in setting
- * flags |= SIMPLE at the end.
- */
- {
- char *regprev;
- register char ch;
-
- regparse--; /* Look at cur char */
- ret = regnode(EXACTLY);
- for ( regprev = 0 ; ; ) {
- ch = *regparse++; /* Get current char */
- switch (*regparse) { /* look at next one */
-
- default:
- regc(ch); /* Add cur to string */
- break;
-
- case '.': case '[': case '(':
- case ')': case '|': case '\n':
- case '$': case '^':
- case '\0':
- /* FIXME, $ and ^ should not always be magic */
- magic:
- regc(ch); /* dump cur char */
- goto done; /* and we are done */
-
- case '?': case '+': case '*':
- if (!regprev) /* If just ch in str, */
- goto magic; /* use it */
- /* End mult-char string one early */
- regparse = regprev; /* Back up parse */
- goto done;
-
- case '\\':
- regc(ch); /* Cur char OK */
- switch (regparse[1]){ /* Look after \ */
- case '\0':
- case '<':
- case '>':
- /* FIXME: Someday handle \1, \2, ... */
- goto done; /* Not quoted */
- default:
- /* Backup point is \, scan * point is after it. */
- regprev = regparse;
- regparse++;
- continue; /* NOT break; */
- }
- }
- regprev = regparse; /* Set backup point */
- }
- done:
- regc('\0');
- *flagp |= HASWIDTH;
- if (!regprev) /* One char? */
- *flagp |= SIMPLE;
- }
- break;
- }
-
- return(ret);
-}
-
-/*
- - regnode - emit a node
- */
-static char * /* Location. */
-regnode(op)
-char op;
-{
- register char *ret;
- register char *ptr;
-
- ret = regcode;
- if (ret == &regdummy) {
- regsize += 3;
- return(ret);
- }
-
- ptr = ret;
- *ptr++ = op;
- *ptr++ = '\0'; /* Null "next" pointer. */
- *ptr++ = '\0';
- regcode = ptr;
-
- return(ret);
-}
-
-/*
- - regc - emit (if appropriate) a byte of code
- */
-static void
-regc(b)
-char b;
-{
- if (regcode != &regdummy)
- *regcode++ = b;
- else
- regsize++;
-}
-
-/*
- - reginsert - insert an operator in front of already-emitted operand
- *
- * Means relocating the operand.
- */
-static void
-reginsert(op, opnd)
-char op;
-char *opnd;
-{
- register char *src;
- register char *dst;
- register char *place;
-
- if (regcode == &regdummy) {
- regsize += 3;
- return;
- }
-
- src = regcode;
- regcode += 3;
- dst = regcode;
- while (src > opnd)
- *--dst = *--src;
-
- place = opnd; /* Op node, where operand used to be. */
- *place++ = op;
- *place++ = '\0';
- *place++ = '\0';
-}
-
-/*
- - regtail - set the next-pointer at the end of a node chain
- */
-static void
-regtail(p, val)
-char *p;
-char *val;
-{
- register char *scan;
- register char *temp;
- register int offset;
-
- if (p == &regdummy)
- return;
-
- /* Find last node. */
- scan = p;
- for (;;) {
- temp = regnext(scan);
- if (temp == NULL)
- break;
- scan = temp;
- }
-
- if (OP(scan) == BACK)
- offset = scan - val;
- else
- offset = val - scan;
- *(scan+1) = (offset>>8)&0377;
- *(scan+2) = offset&0377;
-}
-
-/*
- - regoptail - regtail on operand of first argument; nop if operandless
- */
-static void
-regoptail(p, val)
-char *p;
-char *val;
-{
- /* "Operandless" and "op != BRANCH" are synonymous in practice. */
- if (p == NULL || p == &regdummy || OP(p) != BRANCH)
- return;
- regtail(OPERAND(p), val);
-}
-
-/*
- * regexec and friends
- */
-
-/*
- * Global work variables for regexec().
- */
-static char *reginput; /* String-input pointer. */
-static char *regbol; /* Beginning of input, for ^ check. */
-static char **regstartp; /* Pointer to startp array. */
-static char **regendp; /* Ditto for endp. */
-
-/*
- * Forwards.
- */
-STATIC int regtry();
-STATIC int regmatch();
-STATIC int regrepeat();
-
-#ifdef DEBUG
-int regnarrate = 0;
-void regdump();
-STATIC char *regprop();
-#endif
-
-/*
- - regexec - match a regexp against a string
- */
-int
-regexec(prog, string)
-register const regexp *prog;
-register const char *string;
-{
- register char *s;
- extern char *strchr();
-
- /* Be paranoid... */
- if (prog == NULL || string == NULL) {
- regerror("NULL parameter");
- return(0);
- }
-
- /* Check validity of program. */
- if (UCHARAT(prog->program) != MAGIC) {
- regerror("corrupted program");
- return(0);
- }
-
- /* If there is a "must appear" string, look for it. */
- if (prog->regmust != NULL) {
- s = (char *)string;
- while ((s = strchr(s, prog->regmust[0])) != NULL) {
- if (strncmp(s, prog->regmust, prog->regmlen) == 0)
- break; /* Found it. */
- s++;
- }
- if (s == NULL) /* Not present. */
- return(0);
- }
-
- /* Mark beginning of line for ^ . */
- regbol = (char *)string;
-
- /* Simplest case: anchored match need be tried only once. */
- if (prog->reganch)
- return(regtry(prog, string));
-
- /* Messy cases: unanchored match. */
- s = (char *)string;
- if (prog->regstart != '\0')
- /* We know what char it must start with. */
- while ((s = strchr(s, prog->regstart)) != NULL) {
- if (regtry(prog, s))
- return(1);
- s++;
- }
- else
- /* We don't -- general case. */
- do {
- if (regtry(prog, s))
- return(1);
- } while (*s++ != '\0');
-
- /* Failure. */
- return(0);
-}
-
-/*
- - regtry - try match at specific point
- */
-static int /* 0 failure, 1 success */
-regtry(prog, string)
-regexp *prog;
-char *string;
-{
- register int i;
- register char **sp;
- register char **ep;
-
- reginput = string;
- regstartp = prog->startp;
- regendp = prog->endp;
-
- sp = prog->startp;
- ep = prog->endp;
- for (i = NSUBEXP; i > 0; i--) {
- *sp++ = NULL;
- *ep++ = NULL;
- }
- if (regmatch(prog->program + 1)) {
- prog->startp[0] = string;
- prog->endp[0] = reginput;
- return(1);
- } else
- return(0);
-}
-
-/*
- - regmatch - main matching routine
- *
- * Conceptually the strategy is simple: check to see whether the current
- * node matches, call self recursively to see whether the rest matches,
- * and then act accordingly. In practice we make some effort to avoid
- * recursion, in particular by going through "ordinary" nodes (that don't
- * need to know whether the rest of the match failed) by a loop instead of
- * by recursion.
- */
-static int /* 0 failure, 1 success */
-regmatch(prog)
-char *prog;
-{
- register char *scan; /* Current node. */
- char *next; /* Next node. */
- extern char *strchr();
-
- scan = prog;
-#ifdef DEBUG
- if (scan != NULL && regnarrate)
- fprintf(stderr, "%s(\n", regprop(scan));
-#endif
- while (scan != NULL) {
-#ifdef DEBUG
- if (regnarrate)
- fprintf(stderr, "%s...\n", regprop(scan));
-#endif
- next = regnext(scan);
-
- switch (OP(scan)) {
- case BOL:
- if (reginput != regbol)
- return(0);
- break;
- case EOL:
- if (*reginput != '\0')
- return(0);
- break;
- case WORDA:
- /* Must be looking at a letter, digit, or _ */
- if ((!isalnum(*reginput)) && *reginput != '_')
- return(0);
- /* Prev must be BOL or nonword */
- if (reginput > regbol &&
- (isalnum(reginput[-1]) || reginput[-1] == '_'))
- return(0);
- break;
- case WORDZ:
- /* Must be looking at non letter, digit, or _ */
- if (isalnum(*reginput) || *reginput == '_')
- return(0);
- /* We don't care what the previous char was */
- break;
- case ANY:
- if (*reginput == '\0')
- return(0);
- reginput++;
- break;
- case EXACTLY: {
- register int len;
- register char *opnd;
-
- opnd = OPERAND(scan);
- /* Inline the first character, for speed. */
- if (*opnd != *reginput)
- return(0);
- len = strlen(opnd);
- if (len > 1 && strncmp(opnd, reginput, len) != 0)
- return(0);
- reginput += len;
- }
- break;
- case ANYOF:
- if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
- return(0);
- reginput++;
- break;
- case ANYBUT:
- if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
- return(0);
- reginput++;
- break;
- case NOTHING:
- break;
- case BACK:
- break;
- case OPEN+1:
- case OPEN+2:
- case OPEN+3:
- case OPEN+4:
- case OPEN+5:
- case OPEN+6:
- case OPEN+7:
- case OPEN+8:
- case OPEN+9: {
- register int no;
- register char *save;
-
- no = OP(scan) - OPEN;
- save = reginput;
-
- if (regmatch(next)) {
- /*
- * Don't set startp if some later
- * invocation of the same parentheses
- * already has.
- */
- if (regstartp[no] == NULL)
- regstartp[no] = save;
- return(1);
- } else
- return(0);
- }
- break;
- case CLOSE+1:
- case CLOSE+2:
- case CLOSE+3:
- case CLOSE+4:
- case CLOSE+5:
- case CLOSE+6:
- case CLOSE+7:
- case CLOSE+8:
- case CLOSE+9: {
- register int no;
- register char *save;
-
- no = OP(scan) - CLOSE;
- save = reginput;
-
- if (regmatch(next)) {
- /*
- * Don't set endp if some later
- * invocation of the same parentheses
- * already has.
- */
- if (regendp[no] == NULL)
- regendp[no] = save;
- return(1);
- } else
- return(0);
- }
- break;
- case BRANCH: {
- register char *save;
-
- if (OP(next) != BRANCH) /* No choice. */
- next = OPERAND(scan); /* Avoid recursion. */
- else {
- do {
- save = reginput;
- if (regmatch(OPERAND(scan)))
- return(1);
- reginput = save;
- scan = regnext(scan);
- } while (scan != NULL && OP(scan) == BRANCH);
- return(0);
- /* NOTREACHED */
- }
- }
- break;
- case STAR:
- case PLUS: {
- register char nextch;
- register int no;
- register char *save;
- register int min;
-
- /*
- * Lookahead to avoid useless match attempts
- * when we know what character comes next.
- */
- nextch = '\0';
- if (OP(next) == EXACTLY)
- nextch = *OPERAND(next);
- min = (OP(scan) == STAR) ? 0 : 1;
- save = reginput;
- no = regrepeat(OPERAND(scan));
- while (no >= min) {
- /* If it could work, try it. */
- if (nextch == '\0' || *reginput == nextch)
- if (regmatch(next))
- return(1);
- /* Couldn't or didn't -- back up. */
- no--;
- reginput = save + no;
- }
- return(0);
- }
- break;
- case END:
- return(1); /* Success! */
- break;
- default:
- regerror("memory corruption");
- return(0);
- break;
- }
-
- scan = next;
- }
-
- /*
- * We get here only if there's trouble -- normally "case END" is
- * the terminating point.
- */
- regerror("corrupted pointers");
- return(0);
-}
-
-/*
- - regrepeat - repeatedly match something simple, report how many
- */
-static int
-regrepeat(p)
-char *p;
-{
- register int count = 0;
- register char *scan;
- register char *opnd;
-
- scan = reginput;
- opnd = OPERAND(p);
- switch (OP(p)) {
- case ANY:
- count = strlen(scan);
- scan += count;
- break;
- case EXACTLY:
- while (*opnd == *scan) {
- count++;
- scan++;
- }
- break;
- case ANYOF:
- while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
- count++;
- scan++;
- }
- break;
- case ANYBUT:
- while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
- count++;
- scan++;
- }
- break;
- default: /* Oh dear. Called inappropriately. */
- regerror("internal foulup");
- count = 0; /* Best compromise. */
- break;
- }
- reginput = scan;
-
- return(count);
-}
-
-/*
- - regnext - dig the "next" pointer out of a node
- */
-static char *
-regnext(p)
-register char *p;
-{
- register int offset;
-
- if (p == &regdummy)
- return(NULL);
-
- offset = NEXT(p);
- if (offset == 0)
- return(NULL);
-
- if (OP(p) == BACK)
- return(p-offset);
- else
- return(p+offset);
-}
-
-#ifdef DEBUG
-
-STATIC char *regprop();
-
-/*
- - regdump - dump a regexp onto stdout in vaguely comprehensible form
- */
-void
-regdump(r)
-regexp *r;
-{
- register char *s;
- register char op = EXACTLY; /* Arbitrary non-END op. */
- register char *next;
- extern char *strchr();
-
-
- s = r->program + 1;
- while (op != END) { /* While that wasn't END last time... */
- op = OP(s);
- printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */
- next = regnext(s);
- if (next == NULL) /* Next ptr. */
- printf("(0)");
- else
- printf("(%d)", (s-r->program)+(next-s));
- s += 3;
- if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
- /* Literal string, where present. */
- while (*s != '\0') {
- putchar(*s);
- s++;
- }
- s++;
- }
- putchar('\n');
- }
-
- /* Header fields of interest. */
- if (r->regstart != '\0')
- printf("start `%c' ", r->regstart);
- if (r->reganch)
- printf("anchored ");
- if (r->regmust != NULL)
- printf("must have \"%s\"", r->regmust);
- printf("\n");
-}
-
-/*
- - regprop - printable representation of opcode
- */
-static char *
-regprop(op)
-char *op;
-{
- register char *p;
- static char buf[50];
-
- (void) strcpy(buf, ":");
-
- switch (OP(op)) {
- case BOL:
- p = "BOL";
- break;
- case EOL:
- p = "EOL";
- break;
- case ANY:
- p = "ANY";
- break;
- case ANYOF:
- p = "ANYOF";
- break;
- case ANYBUT:
- p = "ANYBUT";
- break;
- case BRANCH:
- p = "BRANCH";
- break;
- case EXACTLY:
- p = "EXACTLY";
- break;
- case NOTHING:
- p = "NOTHING";
- break;
- case BACK:
- p = "BACK";
- break;
- case END:
- p = "END";
- break;
- case OPEN+1:
- case OPEN+2:
- case OPEN+3:
- case OPEN+4:
- case OPEN+5:
- case OPEN+6:
- case OPEN+7:
- case OPEN+8:
- case OPEN+9:
- sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
- p = NULL;
- break;
- case CLOSE+1:
- case CLOSE+2:
- case CLOSE+3:
- case CLOSE+4:
- case CLOSE+5:
- case CLOSE+6:
- case CLOSE+7:
- case CLOSE+8:
- case CLOSE+9:
- sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
- p = NULL;
- break;
- case STAR:
- p = "STAR";
- break;
- case PLUS:
- p = "PLUS";
- break;
- case WORDA:
- p = "WORDA";
- break;
- case WORDZ:
- p = "WORDZ";
- break;
- default:
- regerror("corrupted opcode");
- break;
- }
- if (p != NULL)
- (void) strcat(buf, p);
- return(buf);
-}
-#endif
-
-/*
- * The following is provided for those people who do not have strcspn() in
- * their C libraries. They should get off their butts and do something
- * about it; at least one public-domain implementation of those (highly
- * useful) string routines has been published on Usenet.
- */
-#ifdef STRCSPN
-/*
- * strcspn - find length of initial segment of s1 consisting entirely
- * of characters not from s2
- */
-
-static int
-strcspn(s1, s2)
-char *s1;
-char *s2;
-{
- register char *scan1;
- register char *scan2;
- register int count;
-
- count = 0;
- for (scan1 = s1; *scan1 != '\0'; scan1++) {
- for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */
- if (*scan1 == *scan2++)
- return(count);
- count++;
- }
- return(count);
-}
-#endif
diff --git a/lib/libc/gen/regexp/regexp.h b/lib/libc/gen/regexp/regexp.h
deleted file mode 100644
index 73d6bf412424..000000000000
--- a/lib/libc/gen/regexp/regexp.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Definitions etc. for regexp(3) routines.
- *
- * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof],
- * not the System V one.
- */
-#define NSUBEXP 10
-typedef struct regexp {
- char *startp[NSUBEXP];
- char *endp[NSUBEXP];
- char regstart; /* Internal use only. */
- char reganch; /* Internal use only. */
- char *regmust; /* Internal use only. */
- int regmlen; /* Internal use only. */
- char program[1]; /* Unwarranted chumminess with compiler. */
-} regexp;
-
-extern regexp *regcomp();
-extern int regexec();
-extern void regsub();
-extern void regerror();
diff --git a/lib/libc/gen/regexp/regmagic.h b/lib/libc/gen/regexp/regmagic.h
deleted file mode 100644
index 5acf4478ff71..000000000000
--- a/lib/libc/gen/regexp/regmagic.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * The first byte of the regexp internal "program" is actually this magic
- * number; the start node begins in the second byte.
- */
-#define MAGIC 0234
diff --git a/lib/libc/gen/regexp/regsub.c b/lib/libc/gen/regexp/regsub.c
deleted file mode 100644
index e55b9b624d1d..000000000000
--- a/lib/libc/gen/regexp/regsub.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * regsub
- *
- * Copyright (c) 1986 by University of Toronto.
- * Written by Henry Spencer. Not derived from licensed software.
- *
- * Permission is granted to anyone to use this software for any
- * purpose on any computer system, and to redistribute it freely,
- * subject to the following restrictions:
- *
- * 1. The author is not responsible for the consequences of use of
- * this software, no matter how awful, even if they arise
- * from defects in it.
- *
- * 2. The origin of this software must not be misrepresented, either
- * by explicit claim or by omission.
- *
- * 3. Altered versions must be plainly marked as such, and must not
- * be misrepresented as being the original software.
- */
-#include <regexp.h>
-#include <stdio.h>
-#include <string.h>
-#include "regmagic.h"
-
-#ifndef CHARBITS
-#define UCHARAT(p) ((int)*(unsigned char *)(p))
-#else
-#define UCHARAT(p) ((int)*(p)&CHARBITS)
-#endif
-
-/*
- - regsub - perform substitutions after a regexp match
- */
-void
-regsub(prog, source, dest)
-const regexp *prog;
-const char *source;
-char *dest;
-{
- register char *src;
- register char *dst;
- register char c;
- register int no;
- register int len;
- extern char *strncpy();
-
- if (prog == NULL || source == NULL || dest == NULL) {
- regerror("NULL parm to regsub");
- return;
- }
- if (UCHARAT(prog->program) != MAGIC) {
- regerror("damaged regexp fed to regsub");
- return;
- }
-
- src = (char *)source;
- dst = dest;
- while ((c = *src++) != '\0') {
- if (c == '&')
- no = 0;
- else if (c == '\\' && '0' <= *src && *src <= '9')
- no = *src++ - '0';
- else
- no = -1;
- if (no < 0) { /* Ordinary character. */
- if (c == '\\' && (*src == '\\' || *src == '&'))
- c = *src++;
- *dst++ = c;
- } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) {
- len = prog->endp[no] - prog->startp[no];
- (void) strncpy(dst, prog->startp[no], len);
- dst += len;
- if (len != 0 && *(dst-1) == '\0') { /* strncpy hit NUL. */
- regerror("damaged match string");
- return;
- }
- }
- }
- *dst++ = '\0';
-}
diff --git a/lib/libc/gen/semconfig.c b/lib/libc/gen/semconfig.c
new file mode 100644
index 000000000000..66fbb2d93398
--- /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 semctl(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 000000000000..313a1dbeda8f
--- /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 000000000000..81c6a86e438c
--- /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 000000000000..0b97c6aacb2f
--- /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/setmode.c b/lib/libc/gen/setmode.c
index fa688a77b264..12f7c1ab1ca7 100644
--- a/lib/libc/gen/setmode.c
+++ b/lib/libc/gen/setmode.c
@@ -215,7 +215,7 @@ setmode(p)
mode_t mask;
struct bitcmd *set, *saveset, *endset;
int permXbits, setlen;
- static int compress_mode();
+ static void compress_mode();
/*
* Get a copy of the mask for the permissions that are mask relative.
@@ -321,7 +321,7 @@ setmode(p)
* to flush out any partial mode that we have,
* and then do the copying of the mode bits.
*/
- if (perm) {
+ if (perm || op == '=') {
ADDCMD(op, who, perm, mask);
perm = 0;
}
@@ -337,7 +337,7 @@ setmode(p)
* Add any permissions that we haven't already
* done.
*/
- if (perm) {
+ if (perm || op == '=') {
ADDCMD(op, who, perm, mask);
perm = 0;
}
@@ -389,7 +389,7 @@ dumpmode(set)
* 'g' and 'o' commands continue to be separate. They could probably be
* compacted, but it's not worth the effort.
*/
-static
+static void
compress_mode(set)
register struct bitcmd *set;
{
diff --git a/lib/libc/gen/signal.3 b/lib/libc/gen/signal.3
index 7f6570625824..b78797c572bd 100644
--- a/lib/libc/gen/signal.3
+++ b/lib/libc/gen/signal.3
@@ -79,7 +79,7 @@ and
signals, the
.Fn signal
function allows for a signal to be caught, to be ignored, or to generate
-an interupt.
+an interrupt.
These signals are defined in the file
.Aq Pa signal.h :
.Bl -column SIGVTALARMXX "create core imagexxx"
@@ -150,7 +150,7 @@ is called.
.Pp
The handled signal is unblocked with the
function returns and
-the process continues from where it left off when the signal occured.
+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.
diff --git a/lib/libc/gen/tcgetpgrp.3 b/lib/libc/gen/tcgetpgrp.3
new file mode 100644
index 000000000000..03396104caf6
--- /dev/null
+++ b/lib/libc/gen/tcgetpgrp.3
@@ -0,0 +1,79 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tcgetpgrp.3 5.3 (Berkeley) 3/29/92
+.\"
+.Dd "March 29, 1992"
+.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/tcsetattr.3 b/lib/libc/gen/tcsetattr.3
new file mode 100644
index 000000000000..b206beec6b91
--- /dev/null
+++ b/lib/libc/gen/tcsetattr.3
@@ -0,0 +1,330 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tcsetattr.3 5.2 (Berkeley) 3/4/92
+.\"
+.Dd "March 4, 1992"
+.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 void
+.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 able 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 000000000000..ff881cb437d8
--- /dev/null
+++ b/lib/libc/gen/tcsetpgrp.3
@@ -0,0 +1,100 @@
+.\" Copyright (c) 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tcsetpgrp.3 5.3 (Berkeley) 3/29/92
+.\"
+.Dd "March 29, 1992"
+.Dt TCSETPGRP
+.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/timezone.3 b/lib/libc/gen/timezone.3
index bfd460eda664..bafa0154427e 100644
--- a/lib/libc/gen/timezone.3
+++ b/lib/libc/gen/timezone.3
@@ -49,7 +49,7 @@ See ctime(3).
.Pp
The
.Fn timezone
-function returns a pointer to a time zone abbreviation for the specifed
+function returns a pointer to a time zone abbreviation for the specified
.Ar zone
and
.Ar dst
diff --git a/lib/libc/gen/timezone.c b/lib/libc/gen/timezone.c
index de12f8ff9e5c..9339d5e151a2 100644
--- a/lib/libc/gen/timezone.c
+++ b/lib/libc/gen/timezone.c
@@ -84,6 +84,7 @@ static struct zone {
} zonetab[] = {
-1*60, "MET", "MET DST", /* Middle European */
-2*60, "EET", "EET DST", /* Eastern European */
+ -3*60, "MSK", "MSD", /* Moscow */
4*60, "AST", "ADT", /* Atlantic */
5*60, "EST", "EDT", /* Eastern */
6*60, "CST", "CDT", /* Central */
diff --git a/lib/libc/gen/ualarm.3 b/lib/libc/gen/ualarm.3
index 19fd216fd8b5..dbdc1344a82f 100644
--- a/lib/libc/gen/ualarm.3
+++ b/lib/libc/gen/ualarm.3
@@ -70,7 +70,7 @@ microseconds have passed).
When the signal has successfully been caught,
.Fn alarm
returns the amount of time left on the clock.
-The maximum mumber of
+The maximum number of
.Ar microseconds
allowed
is 2147483647.
diff --git a/lib/libc/i386/DEFS.h b/lib/libc/i386/DEFS.h
index a07b090d90f0..4b4df3e68ccb 100644
--- a/lib/libc/i386/DEFS.h
+++ b/lib/libc/i386/DEFS.h
@@ -35,28 +35,49 @@
*
* from: @(#)DEFS.h 5.1 (Berkeley) 4/23/90
*
- * $Id: DEFS.h,v 1.2 1993/10/09 08:30:43 davidg Exp $
+ * $Id: DEFS.h,v 1.3.2.1 1994/05/04 08:44:15 rgrimes 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) .align 2,0x90; .globl _/**/x; _/**/x:; \
- .data; .align 2; 1:; .long 0; \
- .text; lea 1b,%eax; call mcount; jmp 2f
-#define ENTRY(x) .align 2,0x90; .globl _/**/x; _/**/x:; \
- .data; .align 2; 1:; .long 0; \
- .text; lea 1b,%eax ; call mcount; 2:
+#define ALTENTRY(x) _START_ENTRY \
+ .globl _/**/x; .type _/**/x,@function; _/**/x:; \
+ _MID_ENTRY \
+ call mcount; jmp 9f
-#define ALTASENTRY(x) .align 2,0x90; .globl x; x:; \
- .data; .align 2; 1:; .long 0; \
- .text; lea 1b,%eax; call mcount; jmp 2f
+#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)
-#define ASENTRY(x) .align 2,0x90; .globl x; x:; \
- .data; .align 2; 1:; .long 0; \
- .text; lea 1b,%eax; call mcount; 2:
-#else
-#define ALTENTRY(x) .align 2,0x90; .globl _/**/x; _/**/x:
-#define ENTRY(x) .align 2,0x90; .globl _/**/x; _/**/x:
-#define ALTASENTRY(x) .align 2,0x90; .globl x; x:
-#define ASENTRY(x) .align 2,0x90; .globl x; x:
#endif
diff --git a/lib/libc/i386/SYS.h b/lib/libc/i386/SYS.h
index 1c7f3994049f..51d828141c7d 100644
--- a/lib/libc/i386/SYS.h
+++ b/lib/libc/i386/SYS.h
@@ -35,18 +35,32 @@
*
* from: @(#)SYS.h 5.5 (Berkeley) 5/7/91
*
- * $Id: SYS.h,v 1.2 1993/10/09 08:30:48 davidg Exp $
+ * $Id: SYS.h,v 1.3 1993/11/04 00:01:17 paul Exp $
*/
#include <syscall.h>
+#include "DEFS.h"
-#ifdef PROF
-#define ENTRY(x) .globl _/**/x; \
- .data; 1:; .long 0; .text; .align 2,0x90; _/**/x: \
- movl $1b,%eax; call mcount
+#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 ENTRY(x) .globl _/**/x; .text; .align 2,0x90; _/**/x:
-#endif PROF
+#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
diff --git a/lib/libc/i386/gen/_setjmp.s b/lib/libc/i386/gen/_setjmp.S
index 7aa3e69f84fb..7aa3e69f84fb 100644
--- a/lib/libc/i386/gen/_setjmp.s
+++ b/lib/libc/i386/gen/_setjmp.S
diff --git a/lib/libc/i386/gen/alloca.s b/lib/libc/i386/gen/alloca.S
index 65378f5ff22b..65378f5ff22b 100644
--- a/lib/libc/i386/gen/alloca.s
+++ b/lib/libc/i386/gen/alloca.S
diff --git a/lib/libc/i386/gen/divsi3.s b/lib/libc/i386/gen/divsi3.S
index a3731eca0247..b08319eaa659 100644
--- a/lib/libc/i386/gen/divsi3.s
+++ b/lib/libc/i386/gen/divsi3.S
@@ -39,6 +39,7 @@
#endif /* LIBC_SCCS and not lint */
.globl ___divsi3
+ .type ___divsi3,@function
___divsi3:
movl 4(%esp),%eax
cltd
diff --git a/lib/libc/i386/gen/fabs.s b/lib/libc/i386/gen/fabs.S
index 2519e8b8abcf..2519e8b8abcf 100644
--- a/lib/libc/i386/gen/fabs.s
+++ b/lib/libc/i386/gen/fabs.S
diff --git a/lib/libc/i386/gen/fixdfsi.s b/lib/libc/i386/gen/fixdfsi.S
index a264e83a37f2..a61c667c482c 100644
--- a/lib/libc/i386/gen/fixdfsi.s
+++ b/lib/libc/i386/gen/fixdfsi.S
@@ -2,6 +2,7 @@
.text
.align 2
.globl ___fixdfsi
+.type ___fixdfsi,@function
___fixdfsi:
pushl %ebp
movl %esp,%ebp
diff --git a/lib/libc/i386/gen/fixunsdfsi.S b/lib/libc/i386/gen/fixunsdfsi.S
new file mode 100644
index 000000000000..f61daeeea27c
--- /dev/null
+++ b/lib/libc/i386/gen/fixunsdfsi.S
@@ -0,0 +1,82 @@
+/*-
+ * 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: @(#)fixunsdfsi.s 5.1 12/17/90
+ * $Id: fixunsdfsi.S,v 1.1 1993/12/05 13:01:03 ats Exp $
+ */
+
+#if defined(LIBC_SCCS)
+ .text
+ .asciz "$Id: fixunsdfsi.S,v 1.1 1993/12/05 13:01:03 ats Exp $"
+#endif
+
+#include "DEFS.h"
+#include "SYS.h"
+
+ENTRY(__fixunsdfsi)
+ fldl 4(%esp) /* argument double to accum stack */
+ frndint /* create integer */
+#ifdef PIC
+ PIC_PROLOGUE
+ leal PIC_GOTOFF(fbiggestsigned),%eax
+ PIC_EPILOGUE
+ fcoml (%eax)
+#else
+ fcoml PIC_GOTOFF(fbiggestsigned) /* bigger than biggest signed? */
+#endif
+ fstsw %ax
+ sahf
+ jnb 1f
+
+ fistpl 4(%esp)
+ movl 4(%esp),%eax
+ ret
+
+1:
+#ifdef PIC
+ PIC_PROLOGUE
+ leal PIC_GOTOFF(fbiggestsigned),%eax
+ PIC_EPILOGUE
+ fsubl (%eax)
+#else
+ fsubl PIC_GOTOFF(fbiggestsigned) /* reduce for proper conversion */
+#endif
+ fistpl 4(%esp) /* convert */
+ movl 4(%esp),%eax
+ orl $0x80000000,%eax /* restore bias */
+ PIC_EPILOGUE
+ ret
+
+fbiggestsigned: .double 0r2147483648.0
diff --git a/lib/libc/i386/gen/fixunsdfsi.s b/lib/libc/i386/gen/fixunsdfsi.s
deleted file mode 100644
index 9f31df35d290..000000000000
--- a/lib/libc/i386/gen/fixunsdfsi.s
+++ /dev/null
@@ -1,50 +0,0 @@
- .file "__fixdfsi.s"
-.text
- .align 2
-.globl ___fixunsdfsi
-___fixunsdfsi:
- pushl %ebp
- movl %esp,%ebp
- subl $12,%esp
- fstcw -4(%ebp)
- movw -4(%ebp),%ax
- orw $0x0c00,%ax
- movw %ax,-2(%ebp)
- fldcw -2(%ebp)
- fldl 8(%ebp)
-
- fcoml fbiggestsigned /* bigger than biggest signed? */
- fstsw %ax
- sahf
- jnb 1f
-
- fistpl -12(%ebp)
- movl -12(%ebp),%eax
- jmp 2f
-
-1: fsubl fbiggestsigned /* reduce for proper conversion */
- fistpl -12(%ebp) /* convert */
- movl -12(%ebp),%eax
- orl $0x80000000,%eax /* restore bias */
-
-2: fldcw -4(%ebp)
- leave
- ret
-
- fcoml fbiggestsigned /* bigger than biggest signed? */
- fstsw %ax
- sahf
- jnb 1f
-
- fistpl 4(%esp)
- movl 4(%esp),%eax
- ret
-
-1: fsubl fbiggestsigned /* reduce for proper conversion */
- fistpl 4(%esp) /* convert */
- movl 4(%esp),%eax
- orl $0x80000000,%eax /* restore bias */
- ret
-
- .data
-fbiggestsigned: .double 0r2147483648.0
diff --git a/lib/libc/i386/gen/modf.s b/lib/libc/i386/gen/modf.S
index 978782a50d03..246729f13e95 100644
--- a/lib/libc/i386/gen/modf.s
+++ b/lib/libc/i386/gen/modf.S
@@ -49,6 +49,7 @@
/* With CHOP mode on, frndint behaves as TRUNC does. Useful. */
.text
.globl _modf
+.type _modf,@function
_modf:
pushl %ebp
movl %esp,%ebp
diff --git a/lib/libc/i386/gen/setjmp.s b/lib/libc/i386/gen/setjmp.S
index 5482caa24541..d9fc66e6f991 100644
--- a/lib/libc/i386/gen/setjmp.s
+++ b/lib/libc/i386/gen/setjmp.S
@@ -50,10 +50,11 @@
*/
#include "DEFS.h"
+#include "SYS.h"
ENTRY(setjmp)
pushl $0
- call _sigblock
+ call PIC_PLT(_sigblock)
popl %edx
movl 4(%esp),%ecx
movl 0(%esp),%edx
@@ -71,7 +72,7 @@ ENTRY(setjmp)
ENTRY(longjmp)
movl 4(%esp),%edx
pushl 24(%edx)
- call _sigsetmask /* XXX this is not reentrant */
+ call PIC_PLT(_sigsetmask) /* XXX this is not reentrant */
popl %eax
movl 4(%esp),%edx
movl 8(%esp),%eax
diff --git a/lib/libc/i386/gen/sigsetjmp.s b/lib/libc/i386/gen/sigsetjmp.S
index a2f8d4269214..6c243869daad 100644
--- a/lib/libc/i386/gen/sigsetjmp.s
+++ b/lib/libc/i386/gen/sigsetjmp.S
@@ -35,15 +35,16 @@
*
*
* from: @(#)setjmp.s 5.1 (Berkeley) 4/23/90"
- * $Id: sigsetjmp.s,v 1.2 1993/10/20 17:37:41 jtc Exp $
+ * $Id: sigsetjmp.S,v 1.1 1993/12/05 13:01:05 ats Exp $
*/
#if defined(LIBC_SCCS) && !defined(lint)
.text
- .asciz "$Id: sigsetjmp.s,v 1.2 1993/10/20 17:37:41 jtc Exp $"
+ .asciz "$Id: sigsetjmp.S,v 1.1 1993/12/05 13:01:05 ats Exp $"
#endif /* LIBC_SCCS and not lint */
#include "DEFS.h"
+#include "SYS.h"
ENTRY(sigsetjmp)
movl 8(%esp),%eax
@@ -52,7 +53,7 @@ ENTRY(sigsetjmp)
testl %eax,%eax
jz 1f
pushl $0
- call _sigblock
+ call PIC_PLT(_sigblock)
addl $4,%esp
movl 4(%esp),%ecx
movl %eax,28(%ecx)
@@ -71,7 +72,7 @@ ENTRY(siglongjmp)
cmpl $0,24(%edx)
jz 1f
pushl 28(%edx)
- call _sigsetmask
+ call PIC_PLT(_sigsetmask)
addl $4,%esp
1: movl 4(%esp),%edx
movl 8(%esp),%eax
diff --git a/lib/libc/i386/gen/udivsi3.s b/lib/libc/i386/gen/udivsi3.S
index da395d34490e..f05e004b10c6 100644
--- a/lib/libc/i386/gen/udivsi3.s
+++ b/lib/libc/i386/gen/udivsi3.S
@@ -39,6 +39,7 @@
#endif /* LIBC_SCCS and not lint */
.globl ___udivsi3
+ .type ___udivsi3,@function
___udivsi3:
movl 4(%esp),%eax
xorl %edx,%edx
diff --git a/lib/libc/i386/net/htonl.s b/lib/libc/i386/net/htonl.S
index a65e3f086412..a65e3f086412 100644
--- a/lib/libc/i386/net/htonl.s
+++ b/lib/libc/i386/net/htonl.S
diff --git a/lib/libc/i386/net/htons.s b/lib/libc/i386/net/htons.S
index 6b3fbb05a6e5..6b3fbb05a6e5 100644
--- a/lib/libc/i386/net/htons.s
+++ b/lib/libc/i386/net/htons.S
diff --git a/lib/libc/i386/net/ntohl.s b/lib/libc/i386/net/ntohl.S
index 5748f9ec8e97..5748f9ec8e97 100644
--- a/lib/libc/i386/net/ntohl.s
+++ b/lib/libc/i386/net/ntohl.S
diff --git a/lib/libc/i386/net/ntohs.s b/lib/libc/i386/net/ntohs.S
index 084c8620bd87..084c8620bd87 100644
--- a/lib/libc/i386/net/ntohs.s
+++ b/lib/libc/i386/net/ntohs.S
diff --git a/lib/libc/i386/stdlib/abs.s b/lib/libc/i386/stdlib/abs.S
index 3122fcb84f6f..3122fcb84f6f 100644
--- a/lib/libc/i386/stdlib/abs.s
+++ b/lib/libc/i386/stdlib/abs.S
diff --git a/lib/libc/i386/stdlib/div.s b/lib/libc/i386/stdlib/div.S
index 9b90e768de2d..b4f89d280955 100644
--- a/lib/libc/i386/stdlib/div.s
+++ b/lib/libc/i386/stdlib/div.S
@@ -27,12 +27,12 @@
* (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/10/08 20:13:38 jtc Exp $
+ * $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/10/08 20:13:38 jtc Exp $"
+ .asciz "$Id: div.S,v 1.1 1993/12/04 21:46:15 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/stdlib/labs.s b/lib/libc/i386/stdlib/labs.S
index b7a1c5dceebb..b7a1c5dceebb 100644
--- a/lib/libc/i386/stdlib/labs.s
+++ b/lib/libc/i386/stdlib/labs.S
diff --git a/lib/libc/i386/stdlib/ldiv.s b/lib/libc/i386/stdlib/ldiv.S
index f203b41a1787..de7bb948ab4c 100644
--- a/lib/libc/i386/stdlib/ldiv.s
+++ b/lib/libc/i386/stdlib/ldiv.S
@@ -27,12 +27,12 @@
* (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/10/08 20:13:41 jtc Exp $
+ * $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/10/08 20:13:41 jtc Exp $"
+ .asciz "$Id: ldiv.S,v 1.1 1993/12/04 21:46:17 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/bcmp.s b/lib/libc/i386/string/bcmp.S
index 4bf83346b46c..21027dadd8b4 100644
--- a/lib/libc/i386/string/bcmp.s
+++ b/lib/libc/i386/string/bcmp.S
@@ -27,11 +27,11 @@
* (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.2 1993/10/09 08:31:09 davidg Exp $
+ * $Id: bcmp.S,v 1.1 1993/12/05 13:01:40 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: bcmp.s,v 1.2 1993/10/09 08:31:09 davidg Exp $"
+ .asciz "$Id: bcmp.S,v 1.1 1993/12/05 13:01:40 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/bcopy.s b/lib/libc/i386/string/bcopy.S
index 7958d3f40972..b68cdf3c4805 100644
--- a/lib/libc/i386/string/bcopy.s
+++ b/lib/libc/i386/string/bcopy.S
@@ -32,11 +32,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: bcopy.s,v 1.3 1993/10/09 08:31:14 davidg Exp $
+ * $Id: bcopy.S,v 1.1 1993/12/05 13:01:41 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: bcopy.s,v 1.3 1993/10/09 08:31:14 davidg Exp $"
+ .asciz "$Id: bcopy.S,v 1.1 1993/12/05 13:01:41 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/bzero.s b/lib/libc/i386/string/bzero.S
index 9349954fe80c..7e0dcdc3c785 100644
--- a/lib/libc/i386/string/bzero.s
+++ b/lib/libc/i386/string/bzero.S
@@ -27,11 +27,11 @@
* (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.2 1993/08/16 18:40:26 jtc Exp $
+ * $Id: bzero.S,v 1.1 1993/12/05 13:01:42 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: bzero.s,v 1.2 1993/08/16 18:40:26 jtc Exp $"
+ .asciz "$Id: bzero.S,v 1.1 1993/12/05 13:01:42 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/ffs.s b/lib/libc/i386/string/ffs.S
index 5be6f3b988d6..42b635768bec 100644
--- a/lib/libc/i386/string/ffs.s
+++ b/lib/libc/i386/string/ffs.S
@@ -27,11 +27,11 @@
* (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 1993/08/16 18:40:28 jtc Exp $
+ * $Id: ffs.S,v 1.1 1993/12/05 13:01:43 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: ffs.s,v 1.1 1993/08/16 18:40:28 jtc Exp $"
+ .asciz "$Id: ffs.S,v 1.1 1993/12/05 13:01:43 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/index.s b/lib/libc/i386/string/index.S
index 8fb3ec016d1d..1ac847341fe6 100644
--- a/lib/libc/i386/string/index.s
+++ b/lib/libc/i386/string/index.S
@@ -27,11 +27,11 @@
* (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 1993/08/16 18:40:30 jtc Exp $
+ * $Id: index.S,v 1.1 1993/12/05 13:01:46 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: index.s,v 1.1 1993/08/16 18:40:30 jtc Exp $"
+ .asciz "$Id: index.S,v 1.1 1993/12/05 13:01:46 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/memchr.s b/lib/libc/i386/string/memchr.S
index 6b519d9033fd..5ff0a34dc1ee 100644
--- a/lib/libc/i386/string/memchr.s
+++ b/lib/libc/i386/string/memchr.S
@@ -27,11 +27,11 @@
* (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.1 1993/08/16 18:40:32 jtc Exp $
+ * $Id: memchr.S,v 1.1 1993/12/05 13:01:47 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: memchr.s,v 1.1 1993/08/16 18:40:32 jtc Exp $"
+ .asciz "$Id: memchr.S,v 1.1 1993/12/05 13:01:47 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/memcmp.s b/lib/libc/i386/string/memcmp.S
index 8e285651e4af..e1fdaaa31f6e 100644
--- a/lib/libc/i386/string/memcmp.s
+++ b/lib/libc/i386/string/memcmp.S
@@ -27,11 +27,11 @@
* (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.2 1993/10/09 08:31:18 davidg Exp $
+ * $Id: memcmp.S,v 1.1.2.1 1994/03/07 02:19:34 rgrimes Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: memcmp.s,v 1.2 1993/10/09 08:31:18 davidg Exp $"
+ .asciz "$Id: memcmp.S,v 1.1.2.1 1994/03/07 02:19:34 rgrimes Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
@@ -73,8 +73,8 @@ L5: movl $4,%ecx /* We know that one of the next */
subl %ecx,%esi /* match. */
repe
cmpsb
-L6: movsbl -1(%edi),%eax /* Perform unsigned comparison */
- movsbl -1(%esi),%edx
+L6: movzbl -1(%edi),%eax /* Perform unsigned comparison */
+ movzbl -1(%esi),%edx
subl %edx,%eax
popl %esi
popl %edi
diff --git a/lib/libc/i386/string/memmove.s b/lib/libc/i386/string/memmove.S
index 8ca0e300d262..57e52ad04295 100644
--- a/lib/libc/i386/string/memmove.s
+++ b/lib/libc/i386/string/memmove.S
@@ -32,11 +32,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: memmove.s,v 1.2 1993/10/09 08:31:22 davidg Exp $
+ * $Id: memmove.S,v 1.1 1993/12/05 13:01:50 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: memmove.s,v 1.2 1993/10/09 08:31:22 davidg Exp $"
+ .asciz "$Id: memmove.S,v 1.1 1993/12/05 13:01:50 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/memset.s b/lib/libc/i386/string/memset.S
index 8c1a8c8b722d..47e763781932 100644
--- a/lib/libc/i386/string/memset.s
+++ b/lib/libc/i386/string/memset.S
@@ -27,11 +27,11 @@
* (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 1993/08/16 18:40:38 jtc Exp $
+ * $Id: memset.S,v 1.1 1993/12/05 13:01:53 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: memset.s,v 1.1 1993/08/16 18:40:38 jtc Exp $"
+ .asciz "$Id: memset.S,v 1.1 1993/12/05 13:01:53 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/rindex.s b/lib/libc/i386/string/rindex.S
index 4fe028c36f2f..3e95f5f0b853 100644
--- a/lib/libc/i386/string/rindex.s
+++ b/lib/libc/i386/string/rindex.S
@@ -27,11 +27,11 @@
* (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 1993/08/16 18:40:39 jtc Exp $
+ * $Id: rindex.S,v 1.1 1993/12/05 13:01:55 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: rindex.s,v 1.1 1993/08/16 18:40:39 jtc Exp $"
+ .asciz "$Id: rindex.S,v 1.1 1993/12/05 13:01:55 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/strcat.s b/lib/libc/i386/string/strcat.S
index 0e4a3e27adf4..5bb6fc4074c2 100644
--- a/lib/libc/i386/string/strcat.s
+++ b/lib/libc/i386/string/strcat.S
@@ -27,11 +27,11 @@
* (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 1993/08/16 18:40:41 jtc Exp $
+ * $Id: strcat.S,v 1.1 1993/12/05 13:01:56 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: strcat.s,v 1.1 1993/08/16 18:40:41 jtc Exp $"
+ .asciz "$Id: strcat.S,v 1.1 1993/12/05 13:01:56 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/strchr.s b/lib/libc/i386/string/strchr.S
index aa35dfb4c50a..1b44b2824395 100644
--- a/lib/libc/i386/string/strchr.s
+++ b/lib/libc/i386/string/strchr.S
@@ -27,11 +27,11 @@
* (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 1993/08/16 18:40:42 jtc Exp $
+ * $Id: strchr.S,v 1.1 1993/12/05 13:01:56 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: strchr.s,v 1.1 1993/08/16 18:40:42 jtc Exp $"
+ .asciz "$Id: strchr.S,v 1.1 1993/12/05 13:01:56 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/strcmp.s b/lib/libc/i386/string/strcmp.S
index 8050234aaca4..015c21aa7fa3 100644
--- a/lib/libc/i386/string/strcmp.s
+++ b/lib/libc/i386/string/strcmp.S
@@ -27,11 +27,11 @@
* (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.2 1993/10/08 20:42:24 jtc Exp $
+ * $Id: strcmp.S,v 1.1.2.1 1994/03/07 02:19:31 rgrimes Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: strcmp.s,v 1.2 1993/10/08 20:42:24 jtc Exp $"
+ .asciz "$Id: strcmp.S,v 1.1.2.1 1994/03/07 02:19:31 rgrimes Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
@@ -118,7 +118,7 @@ L2: movb (%eax),%cl
cmpb %cl,(%edx)
je L1
.align 2, 0x90
-L3: movsbl (%eax),%eax /* unsigned comparison */
- movsbl (%edx),%edx
+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
index 6f2596a4d593..07983f9c2539 100644
--- a/lib/libc/i386/string/strcpy.s
+++ b/lib/libc/i386/string/strcpy.S
@@ -27,11 +27,11 @@
* (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 1993/08/16 18:40:44 jtc Exp $
+ * $Id: strcpy.S,v 1.1 1993/12/05 13:01:58 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: strcpy.s,v 1.1 1993/08/16 18:40:44 jtc Exp $"
+ .asciz "$Id: strcpy.S,v 1.1 1993/12/05 13:01:58 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/strlen.s b/lib/libc/i386/string/strlen.S
index 877ab6440934..3729fa52fefd 100644
--- a/lib/libc/i386/string/strlen.s
+++ b/lib/libc/i386/string/strlen.S
@@ -27,11 +27,11 @@
* (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.2 1993/10/09 08:31:25 davidg Exp $
+ * $Id: strlen.S,v 1.1 1993/12/05 13:01:59 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: strlen.s,v 1.2 1993/10/09 08:31:25 davidg Exp $"
+ .asciz "$Id: strlen.S,v 1.1 1993/12/05 13:01:59 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/string/strncmp.s b/lib/libc/i386/string/strncmp.S
index ada9a80cbc13..72922fb30fec 100644
--- a/lib/libc/i386/string/strncmp.s
+++ b/lib/libc/i386/string/strncmp.S
@@ -27,11 +27,11 @@
* (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 1993/10/08 20:42:25 jtc Exp $
+ * $Id: strncmp.S,v 1.1.2.1 1994/03/07 02:19:33 rgrimes Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: strncmp.s,v 1.2 1993/10/08 20:42:25 jtc Exp $"
+ .asciz "$Id: strncmp.S,v 1.1.2.1 1994/03/07 02:19:33 rgrimes Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
@@ -145,8 +145,8 @@ L2: testl %edx,%edx /* Have we compared n chars yet? */
cmpb %bl,(%ecx)
je L1
.align 2,0x90
-L3: movsbl (%eax),%eax /* unsigned comparision */
- movsbl (%ecx),%ecx
+L3: movzbl (%eax),%eax /* unsigned comparision */
+ movzbl (%ecx),%ecx
subl %ecx,%eax
popl %ebx
ret
diff --git a/lib/libc/i386/string/strrchr.s b/lib/libc/i386/string/strrchr.S
index c3728602e7b7..ef4d776ea471 100644
--- a/lib/libc/i386/string/strrchr.s
+++ b/lib/libc/i386/string/strrchr.S
@@ -27,11 +27,11 @@
* (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 1993/08/16 18:40:50 jtc Exp $
+ * $Id: strrchr.S,v 1.1 1993/12/05 13:02:01 ats Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
- .asciz "$Id: strrchr.s,v 1.1 1993/08/16 18:40:50 jtc Exp $"
+ .asciz "$Id: strrchr.S,v 1.1 1993/12/05 13:02:01 ats Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
diff --git a/lib/libc/i386/sys/Makefile.inc b/lib/libc/i386/sys/Makefile.inc
new file mode 100644
index 000000000000..4bbec8b7a7b6
--- /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: Makefile.inc,v 1.2 1994/02/21 05:19:06 rgrimes Exp $
+
+.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
index bb44ee899eb3..181dae564286 100644
--- a/lib/libc/i386/sys/Ovfork.s
+++ b/lib/libc/i386/sys/Ovfork.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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.3 1994/02/21 05:19:08 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
@@ -49,6 +51,7 @@
*/
.set vfork,66
.globl _vfork
+.type _vfork,@function
_vfork:
popl %ecx /* my rta into ecx */
@@ -61,7 +64,14 @@ vforkok:
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:
diff --git a/lib/libc/i386/sys/brk.s b/lib/libc/i386/sys/brk.S
index ce4717409f84..e884ac267514 100644
--- a/lib/libc/i386/sys/brk.s
+++ b/lib/libc/i386/sys/brk.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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.3 1994/02/21 05:13:26 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
@@ -48,6 +50,29 @@ 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
@@ -63,3 +88,4 @@ ok:
ret
err:
jmp cerror
+#endif
diff --git a/lib/libc/i386/sys/cerror.s b/lib/libc/i386/sys/cerror.S
index 6021fe2dd0f2..27fec0aecbb9 100644
--- a/lib/libc/i386/sys/cerror.s
+++ b/lib/libc/i386/sys/cerror.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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/02/21 05:19:09 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
@@ -42,6 +44,13 @@
.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
ret
diff --git a/lib/libc/i386/sys/exect.s b/lib/libc/i386/sys/exect.S
index 3a17aacbbe2d..1739760f887a 100644
--- a/lib/libc/i386/sys/exect.s
+++ b/lib/libc/i386/sys/exect.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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.2 1994/02/21 05:19:10 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
diff --git a/lib/libc/i386/sys/fork.s b/lib/libc/i386/sys/fork.S
index 0bfa6627edfe..15b7c46dfe96 100644
--- a/lib/libc/i386/sys/fork.s
+++ b/lib/libc/i386/sys/fork.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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.2 1994/02/21 05:19:11 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
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 000000000000..8d131c9628a3
--- /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.1 1994/01/31 12:05:30 davidg 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 000000000000..989c6b6bb4f4
--- /dev/null
+++ b/lib/libc/i386/sys/i386_get_ldt.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1993 John Brezak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <sys/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 000000000000..377437eaf9ce
--- /dev/null
+++ b/lib/libc/i386/sys/i386_set_ldt.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1993 John Brezak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <sys/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
index 2a719f9a9fbb..e0366db6b750 100644
--- a/lib/libc/i386/sys/mount.s
+++ b/lib/libc/i386/sys/mount.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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.2 1994/02/21 05:19:12 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
diff --git a/lib/libc/i386/sys/pipe.s b/lib/libc/i386/sys/pipe.S
index 60d6cd402cad..2aeae5813958 100644
--- a/lib/libc/i386/sys/pipe.s
+++ b/lib/libc/i386/sys/pipe.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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.2 1994/02/21 05:19:13 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
diff --git a/lib/libc/i386/sys/ptrace.s b/lib/libc/i386/sys/ptrace.S
index 703c4249f7c8..6137098fcdf5 100644
--- a/lib/libc/i386/sys/ptrace.s
+++ b/lib/libc/i386/sys/ptrace.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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.2 1994/02/21 05:19:14 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
@@ -42,7 +44,14 @@
ENTRY(ptrace)
xorl %eax,%eax
- movl %eax,_errno
+#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
diff --git a/lib/libc/i386/sys/reboot.s b/lib/libc/i386/sys/reboot.S
index 74c3633d2e1a..47e2f0a4b15a 100644
--- a/lib/libc/i386/sys/reboot.s
+++ b/lib/libc/i386/sys/reboot.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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.2 1994/02/21 05:19:15 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
diff --git a/lib/libc/i386/sys/sbrk.s b/lib/libc/i386/sys/sbrk.S
index ccafa2936acc..fef35cb529c8 100644
--- a/lib/libc/i386/sys/sbrk.s
+++ b/lib/libc/i386/sys/sbrk.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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 1994/02/21 05:19:16 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
@@ -52,6 +54,27 @@ curbrk: .long _end
.text
ENTRY(sbrk)
+#ifdef PIC
+ movl 4(%esp),%ecx
+ PIC_PROLOGUE
+ movl PIC_GOT(curbrk),%edx
+ movl (%edx),%eax
+ PIC_EPILOGUE
+ 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
+ ret
+err:
+ jmp PIC_PLT(cerror)
+
+#else
+
movl 4(%esp),%ecx
movl curbrk,%eax
addl %eax,4(%esp)
@@ -63,3 +86,4 @@ ENTRY(sbrk)
ret
err:
jmp cerror
+#endif
diff --git a/lib/libc/i386/sys/setlogin.s b/lib/libc/i386/sys/setlogin.S
index 227e40382889..92d761a53577 100644
--- a/lib/libc/i386/sys/setlogin.s
+++ b/lib/libc/i386/sys/setlogin.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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.2 1994/02/21 05:19:17 rgrimes Exp $
*/
#if defined(LIBC_SCCS) && !defined(lint)
@@ -43,5 +45,14 @@
.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
index a0b643536f86..4318b6d9aabd 100644
--- a/lib/libc/i386/sys/sigpending.s
+++ b/lib/libc/i386/sys/sigpending.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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.2 1994/02/21 05:19:19 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
diff --git a/lib/libc/i386/sys/sigprocmask.s b/lib/libc/i386/sys/sigprocmask.S
index 2872c1faef11..ce929a03b081 100644
--- a/lib/libc/i386/sys/sigprocmask.s
+++ b/lib/libc/i386/sys/sigprocmask.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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.2 1994/02/21 05:19:20 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
diff --git a/lib/libc/i386/sys/sigreturn.s b/lib/libc/i386/sys/sigreturn.S
index f64d5e6e6da9..b98c9508e8d8 100644
--- a/lib/libc/i386/sys/sigreturn.s
+++ b/lib/libc/i386/sys/sigreturn.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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.2 1994/02/21 05:19:21 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
diff --git a/lib/libc/i386/sys/sigsuspend.s b/lib/libc/i386/sys/sigsuspend.S
index 1db4c1a3543c..1db4c1a3543c 100644
--- a/lib/libc/i386/sys/sigsuspend.s
+++ b/lib/libc/i386/sys/sigsuspend.S
diff --git a/lib/libc/i386/sys/syscall.s b/lib/libc/i386/sys/syscall.S
index 32274930a022..37d180410e0c 100644
--- a/lib/libc/i386/sys/syscall.s
+++ b/lib/libc/i386/sys/syscall.S
@@ -32,6 +32,8 @@
* LIABILITY, OR TORT (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.2 1994/02/21 05:19:22 rgrimes Exp $
*/
#if defined(SYSLIBC_SCCS) && !defined(lint)
diff --git a/lib/libc/net/Makefile.inc b/lib/libc/net/Makefile.inc
index 23b89e27eb7b..55ca82824e52 100644
--- a/lib/libc/net/Makefile.inc
+++ b/lib/libc/net/Makefile.inc
@@ -14,7 +14,7 @@ SRCS+= gethostnamadr.c getnetbyaddr.c getnetbyname.c getnetent.c \
.if (${MACHINE} == "hp300")
SRCS+= htonl.s htons.s ntohl.s ntohs.s
.elif (${MACHINE} == "i386")
-SRCS+= htonl.s htons.s ntohl.s ntohs.s
+SRCS+= htonl.S htons.S ntohl.S ntohs.S
.elif (${MACHINE} == "tahoe")
SRCS+= htonl.s htons.s ntohl.s ntohs.s
.elif (${MACHINE} == "vax")
diff --git a/lib/libc/net/gethostbyname.3 b/lib/libc/net/gethostbyname.3
index 61d1017166b5..df0a9c9f9cc6 100644
--- a/lib/libc/net/gethostbyname.3
+++ b/lib/libc/net/gethostbyname.3
@@ -97,7 +97,7 @@ Host addresses are returned in network byte order.
.It Fa h_addr
The first address in
.Fa h_addr_list ;
-this is for backward compatiblity.
+this is for backward compatibility.
.Pp
When using the nameserver,
.Fn gethostbyname
diff --git a/lib/libc/quad/Makefile.inc b/lib/libc/quad/Makefile.inc
new file mode 100644
index 000000000000..ef690dc4a0bf
--- /dev/null
+++ b/lib/libc/quad/Makefile.inc
@@ -0,0 +1,10 @@
+# @(#)Makefile.inc 5.3 (Berkeley) 7/7/92
+
+# Quad support
+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
+
+.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 000000000000..f5e3d6e215c7
--- /dev/null
+++ b/lib/libc/quad/TESTS/Makefile
@@ -0,0 +1,11 @@
+# @(#)Makefile 5.1 (Berkeley) 6/2/92
+
+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 000000000000..903eecb4c246
--- /dev/null
+++ b/lib/libc/quad/TESTS/divrem.c
@@ -0,0 +1,78 @@
+/*-
+ * 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.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1992 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)divrem.c 5.1 (Berkeley) 6/2/92";
+#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 000000000000..07eff09dac95
--- /dev/null
+++ b/lib/libc/quad/TESTS/mul.c
@@ -0,0 +1,74 @@
+/*-
+ * 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.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1992 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)mul.c 5.1 (Berkeley) 6/2/92";
+#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 000000000000..dd5e7d19a2b8
--- /dev/null
+++ b/lib/libc/quad/adddi3.c
@@ -0,0 +1,60 @@
+/*-
+ * 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[] = "@(#)adddi3.c 5.5 (Berkeley) 6/25/92";
+#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 000000000000..c2c6cbf5ab39
--- /dev/null
+++ b/lib/libc/quad/anddi3.c
@@ -0,0 +1,58 @@
+/*-
+ * 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[] = "@(#)anddi3.c 5.4 (Berkeley) 6/25/92";
+#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 000000000000..2566aef0835e
--- /dev/null
+++ b/lib/libc/quad/ashldi3.c
@@ -0,0 +1,66 @@
+/*-
+ * 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[] = "@(#)ashldi3.c 5.7 (Berkeley) 6/25/92";
+#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 000000000000..29c2e95af273
--- /dev/null
+++ b/lib/libc/quad/ashrdi3.c
@@ -0,0 +1,75 @@
+/*-
+ * 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[] = "@(#)ashrdi3.c 5.7 (Berkeley) 6/25/92";
+#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 000000000000..b33b9a542e18
--- /dev/null
+++ b/lib/libc/quad/cmpdi2.c
@@ -0,0 +1,59 @@
+/*-
+ * 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[] = "@(#)cmpdi2.c 5.5 (Berkeley) 6/25/92";
+#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 000000000000..3529d18a0534
--- /dev/null
+++ b/lib/libc/quad/divdi3.c
@@ -0,0 +1,65 @@
+/*-
+ * 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[] = "@(#)divdi3.c 5.4 (Berkeley) 6/25/92";
+#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 000000000000..1e9930cdf8cb
--- /dev/null
+++ b/lib/libc/quad/fixdfdi.c
@@ -0,0 +1,62 @@
+/*-
+ * 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[] = "@(#)fixdfdi.c 5.4 (Berkeley) 6/25/92";
+#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 000000000000..448109fae8fb
--- /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 000000000000..84a2f7336177
--- /dev/null
+++ b/lib/libc/quad/fixunsdfdi.c
@@ -0,0 +1,96 @@
+/*-
+ * 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[] = "@(#)fixunsdfdi.c 5.5 (Berkeley) 7/13/92";
+#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 000000000000..85798adb61de
--- /dev/null
+++ b/lib/libc/quad/fixunssfdi.c
@@ -0,0 +1,100 @@
+/*-
+ * 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[] = "@(#)fixunssfdi.c 5.2 (Berkeley) 7/13/92";
+#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 000000000000..a0cd536fd50e
--- /dev/null
+++ b/lib/libc/quad/floatdidf.c
@@ -0,0 +1,74 @@
+/*-
+ * 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[] = "@(#)floatdidf.c 5.4 (Berkeley) 6/25/92";
+#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 000000000000..c359e4ce60cc
--- /dev/null
+++ b/lib/libc/quad/floatdisf.c
@@ -0,0 +1,76 @@
+/*-
+ * 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[] = "@(#)floatdisf.c 5.1 (Berkeley) 7/7/92";
+#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 000000000000..814cccaf9767
--- /dev/null
+++ b/lib/libc/quad/floatunsdidf.c
@@ -0,0 +1,59 @@
+/*-
+ * 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[] = "@(#)floatunsdidf.c 5.2 (Berkeley) 6/25/92";
+#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 000000000000..84064b767a87
--- /dev/null
+++ b/lib/libc/quad/iordi3.c
@@ -0,0 +1,58 @@
+/*-
+ * 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[] = "@(#)iordi3.c 5.4 (Berkeley) 6/25/92";
+#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 000000000000..64587068f0db
--- /dev/null
+++ b/lib/libc/quad/lshldi3.c
@@ -0,0 +1,66 @@
+/*-
+ * 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[] = "@(#)lshldi3.c 5.7 (Berkeley) 6/25/92";
+#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 000000000000..f09268cd3e8d
--- /dev/null
+++ b/lib/libc/quad/lshrdi3.c
@@ -0,0 +1,65 @@
+/*-
+ * 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[] = "@(#)lshrdi3.c 5.7 (Berkeley) 6/25/92";
+#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 000000000000..961d6a62c2a3
--- /dev/null
+++ b/lib/libc/quad/moddi3.c
@@ -0,0 +1,67 @@
+/*-
+ * 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[] = "@(#)moddi3.c 5.5 (Berkeley) 6/25/92";
+#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 000000000000..6b0d10be4f93
--- /dev/null
+++ b/lib/libc/quad/muldi3.c
@@ -0,0 +1,246 @@
+/*-
+ * 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[] = "@(#)muldi3.c 5.8 (Berkeley) 6/25/92";
+#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 000000000000..75ea1f7005b6
--- /dev/null
+++ b/lib/libc/quad/negdi2.c
@@ -0,0 +1,57 @@
+/*-
+ * 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[] = "@(#)negdi2.c 5.5 (Berkeley) 6/25/92";
+#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 000000000000..f0bc258141f6
--- /dev/null
+++ b/lib/libc/quad/notdi2.c
@@ -0,0 +1,58 @@
+/*-
+ * 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[] = "@(#)notdi2.c 5.4 (Berkeley) 6/25/92";
+#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 000000000000..c61b5e2be535
--- /dev/null
+++ b/lib/libc/quad/qdivrem.c
@@ -0,0 +1,279 @@
+/*-
+ * 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[] = "@(#)qdivrem.c 5.7 (Berkeley) 6/25/92";
+#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 000000000000..8f1ee163b959
--- /dev/null
+++ b/lib/libc/quad/quad.h
@@ -0,0 +1,112 @@
+/*-
+ * 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.
+ *
+ * @(#)quad.h 5.9 (Berkeley) 7/28/92
+ */
+
+/*
+ * 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 <machine/endian.h>
+#include <sys/types.h>
+#include <sys/cdefs.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)
+
+extern u_quad_t __qdivrem __P((u_quad_t u, u_quad_t v, u_quad_t *rem));
+
+/*
+ * 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 000000000000..3f9a83becb46
--- /dev/null
+++ b/lib/libc/quad/subdi3.c
@@ -0,0 +1,59 @@
+/*-
+ * 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[] = "@(#)subdi3.c 5.5 (Berkeley) 6/25/92";
+#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 000000000000..fbfc57533ab8
--- /dev/null
+++ b/lib/libc/quad/ucmpdi2.c
@@ -0,0 +1,58 @@
+/*-
+ * 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[] = "@(#)ucmpdi2.c 5.5 (Berkeley) 6/25/92";
+#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 000000000000..7c860e70d8a9
--- /dev/null
+++ b/lib/libc/quad/udivdi3.c
@@ -0,0 +1,53 @@
+/*-
+ * 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[] = "@(#)udivdi3.c 5.4 (Berkeley) 6/25/92";
+#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 000000000000..a4f918eab4b2
--- /dev/null
+++ b/lib/libc/quad/umoddi3.c
@@ -0,0 +1,55 @@
+/*-
+ * 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[] = "@(#)umoddi3.c 5.5 (Berkeley) 6/25/92";
+#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 000000000000..07ed29fdd322
--- /dev/null
+++ b/lib/libc/quad/xordi3.c
@@ -0,0 +1,58 @@
+/*-
+ * 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[] = "@(#)xordi3.c 5.4 (Berkeley) 6/25/92";
+#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/Makefile.inc b/lib/libc/regex/Makefile.inc
new file mode 100644
index 000000000000..673f4749a657
--- /dev/null
+++ b/lib/libc/regex/Makefile.inc
@@ -0,0 +1,13 @@
+# @(#)Makefile 5.11 (Berkeley) 9/6/90
+
+# regex sources
+.PATH: ${.CURDIR}/regex
+
+SRCS+= regfree.c regcomp.c regerror.c regexec.c
+CFLAGS+=-I${.CURDIR}/regex -DPOSIX_MISTAKE
+
+MAN3+= regex/regex.3
+MAN7+= regex/regex.7
+
+MLINKS+=regex.3 regcomp.3 regex.3 regexec.3 regex.3 regerror.3
+MLINK+= regex.3 regfree.3
diff --git a/lib/libc/regex/WHATSNEW b/lib/libc/regex/WHATSNEW
new file mode 100644
index 000000000000..0bc7589c32e1
--- /dev/null
+++ b/lib/libc/regex/WHATSNEW
@@ -0,0 +1,72 @@
+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 000000000000..04cf4b1c27b9
--- /dev/null
+++ b/lib/libc/regex/cclass.h
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 1992 Henry Spencer.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer of the University of Toronto.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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.1 (Berkeley) 6/4/93
+ */
+
+/* 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 000000000000..7f22903b1c05
--- /dev/null
+++ b/lib/libc/regex/cname.h
@@ -0,0 +1,141 @@
+/*-
+ * Copyright (c) 1992 Henry Spencer.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer of the University of Toronto.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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.1 (Berkeley) 6/4/93
+ */
+
+/* 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 000000000000..e1296db582cc
--- /dev/null
+++ b/lib/libc/regex/engine.c
@@ -0,0 +1,1075 @@
+/*-
+ * Copyright (c) 1992 Henry Spencer.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer of the University of Toronto.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * 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 */
+};
+
+static int matcher(/*register struct re_guts *g, char *string, size_t nmatch, regmatch_t pmatch[], int eflags*/);
+static char *dissect(/*register struct match *m, char *start, char *stop, sopno startst, sopno stopst*/);
+static char *backref(/*register struct match *m, char *start, char *stop, sopno startst, sopno stopst, sopno lev*/);
+static char *fast(/*register struct match *m, char *start, char *stop, sopno startst, sopno stopst*/);
+static char *slow(/*register struct match *m, char *start, char *stop, sopno startst, sopno stopst*/);
+static states step(/*register struct re_guts *g, int start, int 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)
+#ifdef REDEBUG
+static void print(/*struct match *m, char *caption, states st, int ch, FILE *d*/);
+#endif
+#ifdef REDEBUG
+static void at(/*struct match *m, char *title, char *start, char *stop, sopno startst, stopno stopst*/);
+#endif
+#ifdef REDEBUG
+static char *pchar(/*int ch*/);
+#endif
+
+#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]);
+ m->pmatch[i].rm_so = sp - m->offp;
+ break;
+ case ORPAREN:
+ i = OPND(m->g->strip[ss]);
+ 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);
+ 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);
+ 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);
+ 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 */
+}
+
+/*
+ - 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, int start, int 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;
+int start; /* start state within strip */
+int 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, stopno 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/regcomp.c b/lib/libc/regex/regcomp.c
new file mode 100644
index 000000000000..5ca038ebb108
--- /dev/null
+++ b/lib/libc/regex/regcomp.c
@@ -0,0 +1,1653 @@
+/*-
+ * Copyright (c) 1992 Henry Spencer.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer of the University of Toronto.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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.1 (Berkeley) 6/4/93
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)regcomp.c 8.1 (Berkeley) 6/4/93";
+#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) */
+};
+
+
+static void p_ere(/*register struct parse *p, int stop*/);
+static void p_ere_exp(/*register struct parse *p*/);
+static void p_str(/*register struct parse *p*/);
+static void p_bre(/*register struct parse *p, register int end1, register int end2*/);
+static int p_simp_re(/*register struct parse *p, int starordinary*/);
+static int p_count(/*register struct parse *p*/);
+static void p_bracket(/*register struct parse *p*/);
+static void p_b_term(/*register struct parse *p, register cset *cs*/);
+static void p_b_cclass(/*register struct parse *p, register cset *cs*/);
+static void p_b_eclass(/*register struct parse *p, register cset *cs*/);
+static char p_b_symbol(/*register struct parse *p*/);
+static char p_b_coll_elem(/*register struct parse *p, int endc*/);
+static char othercase(/*int ch*/);
+static void bothcases(/*register struct parse *p, int ch*/);
+static void ordinary(/*register struct parse *p, register int ch*/);
+static void nonnewline(/*register struct parse *p*/);
+static void repeat(/*register struct parse *p, sopno start, int from, int to*/);
+static int seterr(/*register struct parse *p, int e*/);
+static cset *allocset(/*register struct parse *p*/);
+static void freeset(/*register struct parse *p, register cset *cs*/);
+static int freezeset(/*register struct parse *p, register cset *cs*/);
+static int firstch(/*register struct parse *p, register cset *cs*/);
+static int nch(/*register struct parse *p, register cset *cs*/);
+static void mcadd(/*register struct parse *p, register cset *cs, register char *cp*/);
+static void mcsub(/*register cset *cs, register char *cp*/);
+static int mcin(/*register cset *cs, register char *cp*/);
+static char *mcfind(/*register cset *cs, register char *cp*/);
+static void mcinvert(/*register cset *cs*/);
+static void mccase(/*register cset *cs*/);
+static int isinsets(/*register struct re_guts *g, int c*/);
+static int samesets(/*register struct re_guts *g, int c1, int c2*/);
+static void categorize(/*struct parse *p, register struct re_guts *g*/);
+static sopno dupl(/*register struct parse *p, sopno start, sopno finish*/);
+static void doemit(/*register struct parse *p, sop op, size_t opnd*/);
+static void doinsert(/*register struct parse *p, sop op, size_t opnd, sopno pos*/);
+static void dofwd(/*register struct parse *p, sopno pos, sop value*/);
+static void enlarge(/*register struct parse *p, sopno size*/);
+static void stripsnug(/*register struct parse *p, register struct re_guts *g*/);
+static void findmust(/*register struct parse *p, register struct re_guts *g*/);
+static sopno pluscount(/*register struct parse *p, register struct re_guts *g*/);
+
+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(sop, sopnd) doemit(p, sop, (size_t)(sopnd))
+#define INSERT(sop, pos) doinsert(p, sop, 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 DROP(n) (p->slen -= (n))
+
+static int never = 0; /* for use in asserts; shuts lint up */
+
+/*
+ - regcomp - interface for parser and compilation
+ = extern int regcomp(regex_t *preg, const char *pattern, int cflags);
+ = #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;
+
+ 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 +? */
+ 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 '?':
+ INSERT(OQUEST_, pos);
+ ASTERN(O_QUEST, pos);
+ 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 +? */
+ 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 char c;
+ 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(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;
+ register char c;
+
+ 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,}? */
+ INSERT(OQUEST_, start); /* offset is wrong... */
+ repeat(p, start+1, 1, to);
+ AHEAD(start); /* ... fix it */
+ ASTERN(O_QUEST, start);
+ break;
+ case REP(1, 1): /* trivial case */
+ /* done */
+ break;
+ case REP(1, N): /* as x?x{1,n-1} */
+ INSERT(OQUEST_, start);
+ ASTERN(O_QUEST, start);
+ copy = dupl(p, start+1, finish+1);
+ assert(copy == finish+2);
+ 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;
+
+ 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 = (unsigned char *)malloc(nbytes);
+ else
+ p->g->setbits =
+ (unsigned char *)realloc((char *)p->g->setbits,
+ nbytes);
+ 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 unsigned char 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 cset *cs);
+ *
+ * This would have to know the set of possibilities. Implementation
+ * is deferred.
+ */
+static void
+mcinvert(cs)
+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 cset *cs);
+ *
+ * This would have to know the set of possibilities. Implementation
+ * is deferred.
+ */
+static void
+mccase(cs)
+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 unsigned char *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 unsigned char *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((sop *)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;
+ *cp++ = (char)OPND(s);
+ }
+ *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 000000000000..c1b71eec8c8d
--- /dev/null
+++ b/lib/libc/regex/regerror.c
@@ -0,0 +1,171 @@
+/*-
+ * Copyright (c) 1992 Henry Spencer.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer of the University of Toronto.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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.1 (Berkeley) 6/4/93
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)regerror.c 8.1 (Berkeley) 6/4/93";
+#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"
+
+static char *regatoi __P((const regex_t *, char *));
+
+/*
+ = #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 errcode, const regex_t *preg, char *errbuf, \
+ = size_t errbuf_size);
+ */
+/* 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;
+ register size_t siz;
+ register char *p;
+
+ 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 000000000000..100c8a7f71c7
--- /dev/null
+++ b/lib/libc/regex/regex.3
@@ -0,0 +1,502 @@
+.TH REGEX 3 "17 May 1993"
+.BY "Henry Spencer"
+.de ZR
+.\" one other place knows this name: the SEE ALSO section
+.IR regex (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), regex(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
+Written by Henry Spencer at University of Toronto,
+henry@zoo.toronto.edu.
+.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/regex.7 b/lib/libc/regex/regex.7
new file mode 100644
index 000000000000..ca9092ff217f
--- /dev/null
+++ b/lib/libc/regex/regex.7
@@ -0,0 +1,231 @@
+.TH REGEX 7 "6 Nov 1993"
+.BY "Henry Spencer"
+.SH NAME
+regex \- 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
+.I alnum
+characters (as defined by
+.IR ctype (3))
+which is neither preceded nor followed by
+.I alnum
+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
+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/regex.h b/lib/libc/regex/regex.h
new file mode 100644
index 000000000000..81cf1700f7e4
--- /dev/null
+++ b/lib/libc/regex/regex.h
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 1992 Henry Spencer.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer of the University of Toronto.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _REGEX_H_
+#define _REGEX_H_
+
+#include <sys/cdefs.h>
+
+#include <machine/endian.h>
+
+/* types */
+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;
+
+/* regcomp() flags */
+#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
+
+/* regerror() flags */
+#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 (!) */
+
+/* regexec() flags */
+#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 */
+
+__BEGIN_DECLS
+int regcomp __P((regex_t *, const char *, int));
+size_t regerror __P((int, const regex_t *, char *, size_t));
+int regexec __P((const regex_t *,
+ const char *, size_t, regmatch_t [], int));
+void regfree __P((regex_t *));
+__END_DECLS
+
+#endif /* !_REGEX_H_ */
diff --git a/lib/libc/regex/regex2.h b/lib/libc/regex/regex2.h
new file mode 100644
index 000000000000..2bbb04529438
--- /dev/null
+++ b/lib/libc/regex/regex2.h
@@ -0,0 +1,173 @@
+/*-
+ * Copyright (c) 1992 Henry Spencer.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer of the University of Toronto.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * 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 {
+ unsigned char *ptr; /* -> uchar [csetsize] */
+ unsigned char mask; /* bit within array */
+ unsigned char 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[(unsigned char)(c)] |= (cs)->mask, (cs)->hash += (c))
+#define CHsub(cs, c) ((cs)->ptr[(unsigned char)(c)] &= ~(cs)->mask, (cs)->hash -= (c))
+#define CHIN(cs, c) ((cs)->ptr[(unsigned char)(c)] & (cs)->mask)
+#define MCadd(cs, cp) mcadd(cs, cp) /* regcomp() internal fns */
+#define MCsub(cs, cp) mcsub(cs, cp)
+#define MCin(cs, cp) mcin(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] */
+ unsigned char *setbits; /* -> uchar[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 000000000000..c1b9075df4a3
--- /dev/null
+++ b/lib/libc/regex/regexec.c
@@ -0,0 +1,182 @@
+/*-
+ * Copyright (c) 1992 Henry Spencer.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer of the University of Toronto.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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.1 (Berkeley) 6/4/93
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)regexec.c 8.1 (Berkeley) 6/4/93";
+#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 *preg, const char *string, size_t nmatch, \
+ = regmatch_t pmatch[], int eflags);
+ = #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);
+ if (eflags != GOODFLAGS(eflags))
+ return(REG_INVARG);
+
+ 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/db/PORT/include/ndbm.h b/lib/libc/regex/regfree.c
index a545bca1326e..4bd618d9b473 100644
--- a/lib/libc/db/PORT/include/ndbm.h
+++ b/lib/libc/regex/regfree.c
@@ -1,9 +1,10 @@
/*-
- * Copyright (c) 1990, 1993
+ * Copyright (c) 1992 Henry Spencer.
+ * Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
+ * Henry Spencer of the University of Toronto.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,45 +34,47 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)ndbm.h 8.1 (Berkeley) 6/2/93
+ * @(#)regfree.c 8.1 (Berkeley) 6/4/93
*/
-#ifndef _NDBM_H_
-#define _NDBM_H_
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)regfree.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
-#include <db.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <regex.h>
-/* Map dbm interface onto db(3). */
-#define DBM_RDONLY O_RDONLY
-
-/* Flags to dbm_store(). */
-#define DBM_INSERT 0
-#define DBM_REPLACE 1
+#include "utils.h"
+#include "regex2.h"
/*
- * The db(3) support for ndbm(3) always appends this suffix to the
- * file name to avoid overwriting the user's original database.
+ - regfree - free everything
+ = extern void regfree(regex_t *preg);
*/
-#define DBM_SUFFIX ".db"
-
-typedef struct {
- char *dptr;
- int dsize;
-} datum;
+void
+regfree(preg)
+regex_t *preg;
+{
+ register struct re_guts *g;
-typedef DB DBM;
-#define dbm_pagfno(a) DBM_PAGFNO_NOT_AVAILABLE
+ if (preg->re_magic != MAGIC1) /* oops */
+ return; /* nice to complain, but hard */
-__BEGIN_DECLS
-void dbm_close __P((DBM *));
-int dbm_delete __P((DBM *, datum));
-datum dbm_fetch __P((DBM *, datum));
-datum dbm_firstkey __P((DBM *));
-long dbm_forder __P((DBM *, datum));
-datum dbm_nextkey __P((DBM *));
-DBM *dbm_open __P((const char *, int, int));
-int dbm_store __P((DBM *, datum, datum, int));
-int dbm_dirfno __P((DBM *));
-__END_DECLS
+ 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 */
-#endif /* !_NDBM_H_ */
+ 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/tests b/lib/libc/regex/tests
new file mode 100644
index 000000000000..5412bfcbd69f
--- /dev/null
+++ b/lib/libc/regex/tests
@@ -0,0 +1,448 @@
+# regular expression test set
+# Lines are at least three fields, separated by one or more tabs. "" stands
+# for an empty field. First field is an RE. Second field is flags. If
+# C flag given, regcomp() is expected to fail, and the third field is the
+# error name (minus the leading REG_).
+#
+# Otherwise it is expected to succeed, and the third field is the string to
+# try matching it against. If there is no fourth field, the match is
+# expected to fail. If there is a fourth field, it is the substring that
+# the RE is expected to match. If there is a fifth field, it is a comma-
+# separated list of what the subexpressions should match, with - indicating
+# no match for that one. In both the fourth and fifth fields, a (sub)field
+# starting with @ indicates that the (sub)expression is expected to match
+# a null string followed by the stuff after the @; this provides a way to
+# test where null strings match. The character `N' in REs and strings
+# is newline, `S' is space, `T' is tab, `Z' is NUL.
+#
+# The full list of flags:
+# - placeholder, does nothing
+# b RE is a BRE, not an ERE
+# & try it as both an ERE and a BRE
+# C regcomp() error expected, third field is error name
+# i REG_ICASE
+# m ("mundane") REG_NOSPEC
+# s REG_NOSUB (not really testable)
+# n REG_NEWLINE
+# ^ REG_NOTBOL
+# $ REG_NOTEOL
+# # REG_STARTEND (see below)
+# p REG_PEND
+#
+# For REG_STARTEND, the start/end offsets are those of the substring
+# enclosed in ().
+
+# basics
+a & a a
+abc & abc abc
+abc|de - abc abc
+a|b|c - abc a
+
+# parentheses and perversions thereof
+a(b)c - abc abc
+a\(b\)c b abc abc
+a( C EPAREN
+a( b a( a(
+a\( - a( a(
+a\( bC EPAREN
+a\(b bC EPAREN
+a(b C EPAREN
+a(b b a(b a(b
+# gag me with a right parenthesis -- 1003.2 goofed here (my fault, partly)
+a) - a) a)
+) - ) )
+# end gagging (in a just world, those *should* give EPAREN)
+a) b a) a)
+a\) bC EPAREN
+\) bC EPAREN
+a()b - ab ab
+a\(\)b b ab ab
+
+# anchoring and REG_NEWLINE
+^abc$ & abc abc
+a^b - a^b
+a^b b a^b a^b
+a$b - a$b
+a$b b a$b a$b
+^ & abc @abc
+$ & abc @
+^$ & "" @
+$^ - "" @
+\($\)\(^\) b "" @
+# stop retching, those are legitimate (although disgusting)
+^^ - "" @
+$$ - "" @
+b$ & abNc
+b$ &n abNc b
+^b$ & aNbNc
+^b$ &n aNbNc b
+^$ &n aNNb @Nb
+^$ n abc
+^$ n abcN @
+$^ n aNNb @Nb
+\($\)\(^\) bn aNNb @Nb
+^^ n^ aNNb @Nb
+$$ n aNNb @NN
+^a ^ a
+a$ $ a
+^a ^n aNb
+^b ^n aNb b
+a$ $n bNa
+b$ $n bNa b
+a*(^b$)c* - b b
+a*\(^b$\)c* b b b
+
+# certain syntax errors and non-errors
+| C EMPTY
+| b | |
+* C BADRPT
+* b * *
++ C BADRPT
+? C BADRPT
+"" &C EMPTY
+() - abc @abc
+\(\) b abc @abc
+a||b C EMPTY
+|ab C EMPTY
+ab| C EMPTY
+(|a)b C EMPTY
+(a|)b C EMPTY
+(*a) C BADRPT
+(+a) C BADRPT
+(?a) C BADRPT
+({1}a) C BADRPT
+\(\{1\}a\) bC BADRPT
+(a|*b) C BADRPT
+(a|+b) C BADRPT
+(a|?b) C BADRPT
+(a|{1}b) C BADRPT
+^* C BADRPT
+^* b * *
+^+ C BADRPT
+^? C BADRPT
+^{1} C BADRPT
+^\{1\} bC BADRPT
+
+# metacharacters, backslashes
+a.c & abc abc
+a[bc]d & abd abd
+a\*c & a*c a*c
+a\\b & a\b a\b
+a\\\*b & a\*b a\*b
+a\bc & abc abc
+a\ &C EESCAPE
+a\\bc & a\bc a\bc
+\{ bC BADRPT
+# trailing $ is a peculiar special case for the BRE code
+a$ & a a
+a$ & a$
+a\$ & a
+a\$ & a$ a$
+a\\$ & a
+a\\$ & a$
+a\\$ & a\$
+a\\$ & a\ a\
+
+# back references, ugh
+a\(b\)\2c bC ESUBREG
+a\(b\1\)c bC ESUBREG
+a\(b*\)c\1d b abbcbbd abbcbbd bb
+a\(b*\)c\1d b abbcbd
+a\(b*\)c\1d b abbcbbbd
+^\(.\)\1 b abc
+a\([bc]\)\1d b abcdabbd abbd b
+a\(\([bc]\)\2\)*d b abbccd abbccd
+a\(\([bc]\)\2\)*d b abbcbd
+# actually, this next one probably ought to fail, but the spec is unclear
+a\(\(b\)*\2\)*d b abbbd abbbd
+# here is a case that no NFA implementation does right
+\(ab*\)[ab]*\1 b ababaaa ababaaa a
+# check out normal matching in the presence of back refs
+\(a\)\1bcd b aabcd aabcd
+\(a\)\1bc*d b aabcd aabcd
+\(a\)\1bc*d b aabd aabd
+\(a\)\1bc*d b aabcccd aabcccd
+\(a\)\1bc*[ce]d b aabcccd aabcccd
+^\(a\)\1b\(c\)*cd$ b aabcccd aabcccd
+
+# ordinary repetitions
+ab*c & abc abc
+ab+c - abc abc
+ab?c - abc abc
+a\(*\)b b a*b a*b
+a\(**\)b b ab ab
+a\(***\)b bC BADRPT
+*a b *a *a
+**a b a a
+***a bC BADRPT
+
+# the dreaded bounded repetitions
+{ & { {
+{abc & {abc {abc
+{1 C BADRPT
+{1} C BADRPT
+a{b & a{b a{b
+a{1}b - ab ab
+a\{1\}b b ab ab
+a{1,}b - ab ab
+a\{1,\}b b ab ab
+a{1,2}b - aab aab
+a\{1,2\}b b aab aab
+a{1 C EBRACE
+a\{1 bC EBRACE
+a{1a C EBRACE
+a\{1a bC EBRACE
+a{1a} C BADBR
+a\{1a\} bC BADBR
+a{,2} - a{,2} a{,2}
+a\{,2\} bC BADBR
+a{,} - a{,} a{,}
+a\{,\} bC BADBR
+a{1,x} C BADBR
+a\{1,x\} bC BADBR
+a{1,x C EBRACE
+a\{1,x bC EBRACE
+a{300} C BADBR
+a\{300\} bC BADBR
+a{1,0} C BADBR
+a\{1,0\} bC BADBR
+ab{0,0}c - abcac ac
+ab\{0,0\}c b abcac ac
+ab{0,1}c - abcac abc
+ab\{0,1\}c b abcac abc
+ab{0,3}c - abbcac abbc
+ab\{0,3\}c b abbcac abbc
+ab{1,1}c - acabc abc
+ab\{1,1\}c b acabc abc
+ab{1,3}c - acabc abc
+ab\{1,3\}c b acabc abc
+ab{2,2}c - abcabbc abbc
+ab\{2,2\}c b abcabbc abbc
+ab{2,4}c - abcabbc abbc
+ab\{2,4\}c b abcabbc abbc
+((a{1,10}){1,10}){1,10} - a a a,a
+
+# multiple repetitions
+a** &C BADRPT
+a++ C BADRPT
+a?? C BADRPT
+a*+ C BADRPT
+a*? C BADRPT
+a+* C BADRPT
+a+? C BADRPT
+a?* C BADRPT
+a?+ C BADRPT
+a{1}{1} C BADRPT
+a*{1} C BADRPT
+a+{1} C BADRPT
+a?{1} C BADRPT
+a{1}* C BADRPT
+a{1}+ C BADRPT
+a{1}? C BADRPT
+a*{b} - a{b} a{b}
+a\{1\}\{1\} bC BADRPT
+a*\{1\} bC BADRPT
+a\{1\}* bC BADRPT
+
+# brackets, and numerous perversions thereof
+a[b]c & abc abc
+a[ab]c & abc abc
+a[^ab]c & adc adc
+a[]b]c & a]c a]c
+a[[b]c & a[c a[c
+a[-b]c & a-c a-c
+a[^]b]c & adc adc
+a[^-b]c & adc adc
+a[b-]c & a-c a-c
+a[b &C EBRACK
+a[] &C EBRACK
+a[1-3]c & a2c a2c
+a[3-1]c &C ERANGE
+a[1-3-5]c &C ERANGE
+a[[.-.]--]c & a-c a-c
+a[1- &C ERANGE
+a[[. &C EBRACK
+a[[.x &C EBRACK
+a[[.x. &C EBRACK
+a[[.x.] &C EBRACK
+a[[.x.]] & ax ax
+a[[.x,.]] &C ECOLLATE
+a[[.one.]]b & a1b a1b
+a[[.notdef.]]b &C ECOLLATE
+a[[.].]]b & a]b a]b
+a[[:alpha:]]c & abc abc
+a[[:notdef:]]c &C ECTYPE
+a[[: &C EBRACK
+a[[:alpha &C EBRACK
+a[[:alpha:] &C EBRACK
+a[[:alpha,:] &C ECTYPE
+a[[:]:]]b &C ECTYPE
+a[[:-:]]b &C ECTYPE
+a[[:alph:]] &C ECTYPE
+a[[:alphabet:]] &C ECTYPE
+[[:alnum:]]+ - -%@a0X- a0X
+[[:alpha:]]+ - -%@aX0- aX
+[[:blank:]]+ - aSSTb SST
+[[:cntrl:]]+ - aNTb NT
+[[:digit:]]+ - a019b 019
+[[:graph:]]+ - Sa%bS a%b
+[[:lower:]]+ - AabC ab
+[[:print:]]+ - NaSbN aSb
+[[:punct:]]+ - S%-&T %-&
+[[:space:]]+ - aSNTb SNT
+[[:upper:]]+ - aBCd BC
+[[:xdigit:]]+ - p0f3Cq 0f3C
+a[[=b=]]c & abc abc
+a[[= &C EBRACK
+a[[=b &C EBRACK
+a[[=b= &C EBRACK
+a[[=b=] &C EBRACK
+a[[=b,=]] &C ECOLLATE
+a[[=one=]]b & a1b a1b
+
+# complexities
+a(((b)))c - abc abc
+a(b|(c))d - abd abd
+a(b*|c)d - abbd abbd
+# just gotta have one DFA-buster, of course
+a[ab]{20} - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab
+# and an inline expansion in case somebody gets tricky
+a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab] - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab
+# and in case somebody just slips in an NFA...
+a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night) - aaaaabaaaabaaaabaaaabweeknights aaaaabaaaabaaaabaaaabweeknights
+# fish for anomalies as the number of states passes 32
+12345678901234567890123456789 - a12345678901234567890123456789b 12345678901234567890123456789
+123456789012345678901234567890 - a123456789012345678901234567890b 123456789012345678901234567890
+1234567890123456789012345678901 - a1234567890123456789012345678901b 1234567890123456789012345678901
+12345678901234567890123456789012 - a12345678901234567890123456789012b 12345678901234567890123456789012
+123456789012345678901234567890123 - a123456789012345678901234567890123b 123456789012345678901234567890123
+# and one really big one, beyond any plausible word width
+1234567890123456789012345678901234567890123456789012345678901234567890 - a1234567890123456789012345678901234567890123456789012345678901234567890b 1234567890123456789012345678901234567890123456789012345678901234567890
+# fish for problems as brackets go past 8
+[ab][cd][ef][gh][ij][kl][mn] - xacegikmoq acegikm
+[ab][cd][ef][gh][ij][kl][mn][op] - xacegikmoq acegikmo
+[ab][cd][ef][gh][ij][kl][mn][op][qr] - xacegikmoqy acegikmoq
+[ab][cd][ef][gh][ij][kl][mn][op][q] - xacegikmoqy acegikmoq
+
+# subtleties of matching
+abc & xabcy abc
+a\(b\)?c\1d b acd
+aBc i Abc Abc
+a[Bc]*d i abBCcd abBCcd
+0[[:upper:]]1 &i 0a1 0a1
+0[[:lower:]]1 &i 0A1 0A1
+a[^b]c &i abc
+a[^b]c &i aBc
+a[^b]c &i adc adc
+[a]b[c] - abc abc
+[a]b[a] - aba aba
+[abc]b[abc] - abc abc
+[abc]b[abd] - abd abd
+a(b?c)+d - accd accd
+(wee|week)(knights|night) - weeknights weeknights
+(we|wee|week|frob)(knights|night|day) - weeknights weeknights
+a[bc]d - xyzaaabcaababdacd abd
+a[ab]c - aaabc abc
+abc s abc abc
+
+# subexpressions
+a(b)(c)d - abcd abcd b,c
+a(((b)))c - abc abc b,b,b
+a(b|(c))d - abd abd b,-
+a(b*|c|e)d - abbd abbd bb
+a(b*|c|e)d - acd acd c
+a(b*|c|e)d - ad ad @d
+a(b?)c - abc abc b
+a(b?)c - ac ac @c
+a(b+)c - abc abc b
+a(b+)c - abbbc abbbc bbb
+a(b*)c - ac ac @c
+(a|ab)(bc([de]+)f|cde) - abcdef abcdef a,bcdef,de
+# the regression tester only asks for 9 subexpressions
+a(b)(c)(d)(e)(f)(g)(h)(i)(j)k - abcdefghijk abcdefghijk b,c,d,e,f,g,h,i,j
+a(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)l - abcdefghijkl abcdefghijkl b,c,d,e,f,g,h,i,j,k
+a([bc]?)c - abc abc b
+a([bc]?)c - ac ac @c
+a([bc]+)c - abc abc b
+a([bc]+)c - abcc abcc bc
+a([bc]+)bc - abcbc abcbc bc
+a(bb+|b)b - abb abb b
+a(bbb+|bb+|b)b - abb abb b
+a(bbb+|bb+|b)b - abbb abbb bb
+a(bbb+|bb+|b)bb - abbb abbb b
+(.*).* - abcdef abcdef abcdef
+(a*)* - bc @b @b
+
+# do we get the right subexpression when it is used more than once?
+a(b|c)*d - ad ad -
+a(b|c)*d - abcd abcd c
+a(b|c)+d - abd abd b
+a(b|c)+d - abcd abcd c
+a(b|c?)+d - ad ad @d
+a(b|c?)+d - abcd abcd @d
+a(b|c){0,0}d - ad ad -
+a(b|c){0,1}d - ad ad -
+a(b|c){0,1}d - abd abd b
+a(b|c){0,2}d - ad ad -
+a(b|c){0,2}d - abcd abcd c
+a(b|c){0,}d - ad ad -
+a(b|c){0,}d - abcd abcd c
+a(b|c){1,1}d - abd abd b
+a(b|c){1,1}d - acd acd c
+a(b|c){1,2}d - abd abd b
+a(b|c){1,2}d - abcd abcd c
+a(b|c){1,}d - abd abd b
+a(b|c){1,}d - abcd abcd c
+a(b|c){2,2}d - acbd acbd b
+a(b|c){2,2}d - abcd abcd c
+a(b|c){2,4}d - abcd abcd c
+a(b|c){2,4}d - abcbd abcbd b
+a(b|c){2,4}d - abcbcd abcbcd c
+a(b|c){2,}d - abcd abcd c
+a(b|c){2,}d - abcbd abcbd b
+a(b+|((c)*))+d - abd abd @d,@d,-
+a(b+|((c)*))+d - abcd abcd @d,@d,-
+
+# check out the STARTEND option
+[abc] &# a(b)c b
+[abc] &# a(d)c
+[abc] &# a(bc)d b
+[abc] &# a(dc)d c
+. &# a()c
+b.*c &# b(bc)c bc
+b.* &# b(bc)c bc
+.*c &# b(bc)c bc
+
+# plain strings, with the NOSPEC flag
+abc m abc abc
+abc m xabcy abc
+abc m xyz
+a*b m aba*b a*b
+a*b m ab
+"" mC EMPTY
+
+# cases involving NULs
+aZb & a a
+aZb &p a
+aZb &p# (aZb) aZb
+aZ*b &p# (ab) ab
+a.b &# (aZb) aZb
+a.* &# (aZb)c aZb
+
+# word boundaries (ick)
+[[:<:]]a & a a
+[[:<:]]a & ba
+[[:<:]]a & -a a
+a[[:>:]] & a a
+a[[:>:]] & ab
+a[[:>:]] & a- a
+[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc abc
+[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc-q abc
+[[:<:]]a.c[[:>:]] & axc-dayc-dazce-abc axc
+
+# past problems
+(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A]) - A1 A1
+abcdefghijklmnop i abcdefghijklmnop abcdefghijklmnop
+abcdefghijklmnopqrstuv i abcdefghijklmnopqrstuv abcdefghijklmnopqrstuv
+(ALAK)|(ALT[AB])|(CC[123]1)|(CM[123]1)|(GAMC)|(LC[23][EO ])|(SEM[1234])|(SL[ES][12])|(SLWW)|(SLF )|(SLDT)|(VWH[12])|(WH[34][EW])|(WP1[ESN]) - CC11 CC11
+CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a - CC11 CC11
diff --git a/lib/libc/regex/utils.h b/lib/libc/regex/utils.h
new file mode 100644
index 000000000000..2e1fce210519
--- /dev/null
+++ b/lib/libc/regex/utils.h
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 1992 Henry Spencer.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Henry Spencer of the University of Toronto.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (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.1 (Berkeley) 6/4/93
+ */
+
+/* utility definitions */
+#define DUPMAX _POSIX2_RE_DUP_MAX /* xxx is this right? */
+#define INFINITY (DUPMAX+1)
+#define NC ((CHAR_MAX)-(CHAR_MIN)+1)
+
+#ifndef REDEBUG
+#ifndef NDEBUG
+#define NDEBUG /* no assertions please */
+#endif
+#endif
+#include <assert.h>
diff --git a/lib/libc/rpc/DISCLAIMER b/lib/libc/rpc/DISCLAIMER
new file mode 100644
index 000000000000..1a66d5f4c9cd
--- /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 000000000000..8776d9d8eee9
--- /dev/null
+++ b/lib/libc/rpc/Makefile.inc
@@ -0,0 +1,39 @@
+# @(#)Makefile 5.11 (Berkeley) 9/6/90
+
+.PATH: ${.CURDIR}/rpc ${.CURDIR}/.
+CFLAGS+=-I${.CURDIR} -I${.CURDIR}/rpc
+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 xdr.c xdr_array.c xdr_mem.c \
+ xdr_rec.c xdr_reference.c xdr_stdio.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 rpc/xdr.3
+MAN5+= rpc/rpc.5
+MAN8+= rpc/rstat_svc.8
+
+
+UNSUPPORTED+= xdr_float.c
+
+HDRS+= auth.h auth_unix.h clnt.h pmap_clnt.h \
+ pmap_prot.h pmap_rmt.h rpc.h rpc_msg.h svc.h svc_auth.h types.h xdr.h
+
+beforeinstall: ${HDRS}
+ @-if [ ! -d ${DESTDIR}/usr/include/rpc ]; then \
+ mkdir ${DESTDIR}/usr/include/rpc; \
+ chown ${BINOWN}.${BINGRP} ${DESTDIR}/usr/include/rpc; \
+ chmod 755 ${DESTDIR}/usr/include/rpc; \
+ fi
+ cd ${.CURDIR}/rpc; install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${HDRS} \
+ ${DESTDIR}/usr/include/rpc
diff --git a/lib/libc/rpc/README b/lib/libc/rpc/README
new file mode 100644
index 000000000000..ad9d70f99056
--- /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.h b/lib/libc/rpc/auth.h
new file mode 100644
index 000000000000..e7db1d01fcb4
--- /dev/null
+++ b/lib/libc/rpc/auth.h
@@ -0,0 +1,178 @@
+/*
+ * 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
+ *
+ * from: @(#)auth.h 1.17 88/02/08 SMI
+ * from: @(#)auth.h 2.3 88/08/07 4.0 RPCSRC
+ * $Id: auth.h,v 1.1 1993/10/27 05:40:09 paul Exp $
+ */
+
+/*
+ * auth.h, Authentication interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The data structures are completely opaque to the client. The client
+ * is required to pass a AUTH * to routines that create rpc
+ * "sessions".
+ */
+
+#ifndef _RPC_AUTH_H
+#define _RPC_AUTH_H
+#include <sys/cdefs.h>
+
+#define MAX_AUTH_BYTES 400
+#define MAXNETNAMELEN 255 /* maximum length of network user's name */
+
+/*
+ * Status returned from authentication check
+ */
+enum auth_stat {
+ AUTH_OK=0,
+ /*
+ * failed at remote end
+ */
+ AUTH_BADCRED=1, /* bogus credentials (seal broken) */
+ AUTH_REJECTEDCRED=2, /* client should begin new session */
+ AUTH_BADVERF=3, /* bogus verifier (seal broken) */
+ AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */
+ AUTH_TOOWEAK=5, /* rejected due to security reasons */
+ /*
+ * failed locally
+ */
+ AUTH_INVALIDRESP=6, /* bogus response verifier */
+ AUTH_FAILED=7 /* some unknown reason */
+};
+
+#if (mc68000 || sparc || vax || i386 || tahoe || hp300)
+typedef u_long u_int32; /* 32-bit unsigned integers */
+#endif
+
+union des_block {
+ struct {
+ u_int32 high;
+ u_int32 low;
+ } key;
+ char c[8];
+};
+typedef union des_block des_block;
+__BEGIN_DECLS
+extern bool_t xdr_des_block __P((XDR *, des_block *));
+__END_DECLS
+
+/*
+ * Authentication info. Opaque to client.
+ */
+struct opaque_auth {
+ enum_t oa_flavor; /* flavor of auth */
+ caddr_t oa_base; /* address of more auth stuff */
+ u_int oa_length; /* not to exceed MAX_AUTH_BYTES */
+};
+
+
+/*
+ * Auth handle, interface to client side authenticators.
+ */
+typedef struct {
+ struct opaque_auth ah_cred;
+ struct opaque_auth ah_verf;
+ union des_block ah_key;
+ struct auth_ops {
+ void (*ah_nextverf)();
+ int (*ah_marshal)(); /* nextverf & serialize */
+ int (*ah_validate)(); /* validate varifier */
+ int (*ah_refresh)(); /* refresh credentials */
+ void (*ah_destroy)(); /* destroy this structure */
+ } *ah_ops;
+ caddr_t ah_private;
+} AUTH;
+
+
+/*
+ * Authentication ops.
+ * The ops and the auth handle provide the interface to the authenticators.
+ *
+ * AUTH *auth;
+ * XDR *xdrs;
+ * struct opaque_auth verf;
+ */
+#define AUTH_NEXTVERF(auth) \
+ ((*((auth)->ah_ops->ah_nextverf))(auth))
+#define auth_nextverf(auth) \
+ ((*((auth)->ah_ops->ah_nextverf))(auth))
+
+#define AUTH_MARSHALL(auth, xdrs) \
+ ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+#define auth_marshall(auth, xdrs) \
+ ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+
+#define AUTH_VALIDATE(auth, verfp) \
+ ((*((auth)->ah_ops->ah_validate))((auth), verfp))
+#define auth_validate(auth, verfp) \
+ ((*((auth)->ah_ops->ah_validate))((auth), verfp))
+
+#define AUTH_REFRESH(auth) \
+ ((*((auth)->ah_ops->ah_refresh))(auth))
+#define auth_refresh(auth) \
+ ((*((auth)->ah_ops->ah_refresh))(auth))
+
+#define AUTH_DESTROY(auth) \
+ ((*((auth)->ah_ops->ah_destroy))(auth))
+#define auth_destroy(auth) \
+ ((*((auth)->ah_ops->ah_destroy))(auth))
+
+
+extern struct opaque_auth _null_auth;
+
+
+/*
+ * These are the various implementations of client side authenticators.
+ */
+
+/*
+ * Unix style authentication
+ * AUTH *authunix_create(machname, uid, gid, len, aup_gids)
+ * char *machname;
+ * int uid;
+ * int gid;
+ * int len;
+ * int *aup_gids;
+ */
+__BEGIN_DECLS
+extern AUTH *authunix_create __P((char *, int, int, int, int *));
+extern AUTH *authunix_create_default __P((void));
+extern AUTH *authnone_create __P((void));
+extern AUTH *authdes_create();
+__END_DECLS
+
+#define AUTH_NONE 0 /* no authentication */
+#define AUTH_NULL 0 /* backward compatibility */
+#define AUTH_UNIX 1 /* unix style (uid, gids) */
+#define AUTH_SHORT 2 /* short hand unix style */
+#define AUTH_DES 3 /* des style (encrypted timestamps) */
+
+#endif /* !_RPC_AUTH_H */
diff --git a/lib/libc/rpc/auth_none.c b/lib/libc/rpc/auth_none.c
new file mode 100644
index 000000000000..9c5a664795f6
--- /dev/null
+++ b/lib/libc/rpc/auth_none.c
@@ -0,0 +1,135 @@
+/*
+ * 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.1 1993/10/27 05:40:10 paul 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 <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 000000000000..334dc56c265a
--- /dev/null
+++ b/lib/libc/rpc/auth_unix.c
@@ -0,0 +1,322 @@
+/*
+ * 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.1 1993/10/27 05:40:11 paul 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 <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 bool_t marshal_new_auth();
+
+
+/*
+ * 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;
+ 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];
+
+ if (gethostname(machname, MAX_MACHINE_NAME) == -1)
+ abort();
+ machname[MAX_MACHINE_NAME] = 0;
+ uid = geteuid();
+ gid = getegid();
+ if ((len = getgroups(NGRPS, gids)) < 0)
+ abort();
+ 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 bool_t
+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/auth_unix.h b/lib/libc/rpc/auth_unix.h
new file mode 100644
index 000000000000..e9da2644c7d8
--- /dev/null
+++ b/lib/libc/rpc/auth_unix.h
@@ -0,0 +1,82 @@
+/*
+ * 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
+ *
+ * from: @(#)auth_unix.h 1.8 88/02/08 SMI
+ * from: @(#)auth_unix.h 2.2 88/07/29 4.0 RPCSRC
+ * $Id: auth_unix.h,v 1.1 1993/10/27 05:40:12 paul Exp $
+ */
+
+/*
+ * auth_unix.h, Protocol for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * The system is very weak. The client uses no encryption for it
+ * 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.
+ */
+
+#ifndef _RPC_AUTH_UNIX_H
+#define _RPC_AUTH_UNIX_H
+#include <sys/cdefs.h>
+
+/* The machine name is part of a credential; it may not exceed 255 bytes */
+#define MAX_MACHINE_NAME 255
+
+/* gids compose part of a credential; there may not be more than 16 of them */
+#define NGRPS 16
+
+/*
+ * Unix style credentials.
+ */
+struct authunix_parms {
+ u_long aup_time;
+ char *aup_machname;
+ int aup_uid;
+ int aup_gid;
+ u_int aup_len;
+ int *aup_gids;
+};
+
+__BEGIN_DECLS
+extern bool_t xdr_authunix_parms __P((XDR *, struct authunix_parms *));
+__END_DECLS
+
+/*
+ * If a response verifier has flavor AUTH_SHORT,
+ * then the body of the response verifier encapsulates the following structure;
+ * again it is serialized in the obvious fashion.
+ */
+struct short_hand_verf {
+ struct opaque_auth new_cred;
+};
+
+#endif /* !_RPC_AUTH_UNIX_H */
diff --git a/lib/libc/rpc/authunix_prot.c b/lib/libc/rpc/authunix_prot.c
new file mode 100644
index 000000000000..15faf184cfb5
--- /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 1993/10/27 05:40:15 paul 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 000000000000..1fb1f9a30600
--- /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 000000000000..a085c910c3c3
--- /dev/null
+++ b/lib/libc/rpc/bindresvport.c
@@ -0,0 +1,84 @@
+/*
+ * 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.1 1993/10/27 05:40:17 paul 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>
+
+/*
+ * 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.h b/lib/libc/rpc/clnt.h
new file mode 100644
index 000000000000..71d36bc97fdb
--- /dev/null
+++ b/lib/libc/rpc/clnt.h
@@ -0,0 +1,358 @@
+/*
+ * 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
+ *
+ * from: @(#)clnt.h 1.31 88/02/08 SMI
+ * from: @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC
+ * $Id: clnt.h,v 1.1 1993/10/27 05:40:18 paul Exp $
+ */
+
+/*
+ * clnt.h - Client side remote procedure call interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_CLNT_H_
+#define _RPC_CLNT_H_
+#include <sys/cdefs.h>
+
+/*
+ * Rpc calls return an enum clnt_stat. This should be looked at more,
+ * since each implementation is required to live with this (implementation
+ * independent) list of errors.
+ */
+enum clnt_stat {
+ RPC_SUCCESS=0, /* call succeeded */
+ /*
+ * local errors
+ */
+ RPC_CANTENCODEARGS=1, /* can't encode arguments */
+ RPC_CANTDECODERES=2, /* can't decode results */
+ RPC_CANTSEND=3, /* failure in sending call */
+ RPC_CANTRECV=4, /* failure in receiving result */
+ RPC_TIMEDOUT=5, /* call timed out */
+ /*
+ * remote errors
+ */
+ RPC_VERSMISMATCH=6, /* rpc versions not compatible */
+ RPC_AUTHERROR=7, /* authentication error */
+ RPC_PROGUNAVAIL=8, /* program not available */
+ RPC_PROGVERSMISMATCH=9, /* program version mismatched */
+ RPC_PROCUNAVAIL=10, /* procedure unavailable */
+ RPC_CANTDECODEARGS=11, /* decode arguments error */
+ RPC_SYSTEMERROR=12, /* generic "other problem" */
+
+ /*
+ * callrpc & clnt_create errors
+ */
+ RPC_UNKNOWNHOST=13, /* unknown host name */
+ RPC_UNKNOWNPROTO=17, /* unkown protocol */
+
+ /*
+ * _ create errors
+ */
+ RPC_PMAPFAILURE=14, /* the pmapper failed in its call */
+ RPC_PROGNOTREGISTERED=15, /* remote program is not registered */
+ /*
+ * unspecified error
+ */
+ RPC_FAILED=16
+};
+
+
+/*
+ * Error info.
+ */
+struct rpc_err {
+ enum clnt_stat re_status;
+ union {
+ int RE_errno; /* realated system error */
+ enum auth_stat RE_why; /* why the auth error occurred */
+ struct {
+ u_long low; /* lowest verion supported */
+ u_long high; /* highest verion supported */
+ } RE_vers;
+ struct { /* maybe meaningful if RPC_FAILED */
+ long s1;
+ long s2;
+ } RE_lb; /* life boot & debugging only */
+ } ru;
+#define re_errno ru.RE_errno
+#define re_why ru.RE_why
+#define re_vers ru.RE_vers
+#define re_lb ru.RE_lb
+};
+
+
+/*
+ * Client rpc handle.
+ * Created by individual implementations, see e.g. rpc_udp.c.
+ * Client is responsible for initializing auth, see e.g. auth_none.c.
+ */
+typedef struct {
+ AUTH *cl_auth; /* authenticator */
+ struct clnt_ops {
+ enum clnt_stat (*cl_call)(); /* call remote procedure */
+ void (*cl_abort)(); /* abort a call */
+ void (*cl_geterr)(); /* get specific error code */
+ bool_t (*cl_freeres)(); /* frees results */
+ void (*cl_destroy)();/* destroy this structure */
+ bool_t (*cl_control)();/* the ioctl() of rpc */
+ } *cl_ops;
+ caddr_t cl_private; /* private stuff */
+} CLIENT;
+
+
+/*
+ * client side rpc interface ops
+ *
+ * Parameter types are:
+ *
+ */
+
+/*
+ * enum clnt_stat
+ * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
+ * CLIENT *rh;
+ * u_long proc;
+ * xdrproc_t xargs;
+ * caddr_t argsp;
+ * xdrproc_t xres;
+ * caddr_t resp;
+ * struct timeval timeout;
+ */
+#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \
+ ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \
+ ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+
+/*
+ * void
+ * CLNT_ABORT(rh);
+ * CLIENT *rh;
+ */
+#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh))
+#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh))
+
+/*
+ * struct rpc_err
+ * CLNT_GETERR(rh);
+ * CLIENT *rh;
+ */
+#define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp))
+#define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp))
+
+
+/*
+ * bool_t
+ * CLNT_FREERES(rh, xres, resp);
+ * CLIENT *rh;
+ * xdrproc_t xres;
+ * caddr_t resp;
+ */
+#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+
+/*
+ * bool_t
+ * CLNT_CONTROL(cl, request, info)
+ * CLIENT *cl;
+ * u_int request;
+ * char *info;
+ */
+#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+
+/*
+ * control operations that apply to both udp and tcp transports
+ */
+#define CLSET_TIMEOUT 1 /* set timeout (timeval) */
+#define CLGET_TIMEOUT 2 /* get timeout (timeval) */
+#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */
+/*
+ * udp only control operations
+ */
+#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */
+#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */
+
+/*
+ * void
+ * CLNT_DESTROY(rh);
+ * CLIENT *rh;
+ */
+#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh))
+#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh))
+
+
+/*
+ * RPCTEST is a test program which is accessable on every rpc
+ * transport/port. It is used for testing, performance evaluation,
+ * and network administration.
+ */
+
+#define RPCTEST_PROGRAM ((u_long)1)
+#define RPCTEST_VERSION ((u_long)1)
+#define RPCTEST_NULL_PROC ((u_long)2)
+#define RPCTEST_NULL_BATCH_PROC ((u_long)3)
+
+/*
+ * By convention, procedure 0 takes null arguments and returns them
+ */
+
+#define NULLPROC ((u_long)0)
+
+/*
+ * Below are the client handle creation routines for the various
+ * implementations of client side rpc. They can return NULL if a
+ * creation failure occurs.
+ */
+
+/*
+ * Memory based rpc (for speed check and testing)
+ * CLIENT *
+ * clntraw_create(prog, vers)
+ * u_long prog;
+ * u_long vers;
+ */
+__BEGIN_DECLS
+extern CLIENT *clntraw_create __P((u_long, u_long));
+__END_DECLS
+
+
+/*
+ * Generic client creation routine. Supported protocols are "udp" and "tcp"
+ * CLIENT *
+ * clnt_create(host, prog, vers, prot);
+ * char *host; -- hostname
+ * u_long prog; -- program number
+ * u_long vers; -- version number
+ * char *prot; -- protocol
+ */
+__BEGIN_DECLS
+extern CLIENT *clnt_create __P((char *, u_long, u_long, char *));
+__END_DECLS
+
+
+/*
+ * TCP based rpc
+ * CLIENT *
+ * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
+ * struct sockaddr_in *raddr;
+ * u_long prog;
+ * u_long version;
+ * register int *sockp;
+ * u_int sendsz;
+ * u_int recvsz;
+ */
+__BEGIN_DECLS
+extern CLIENT *clnttcp_create __P((struct sockaddr_in *,
+ u_long,
+ u_long,
+ int *,
+ u_int,
+ u_int));
+__END_DECLS
+
+
+/*
+ * UDP based rpc.
+ * CLIENT *
+ * clntudp_create(raddr, program, version, wait, sockp)
+ * struct sockaddr_in *raddr;
+ * u_long program;
+ * u_long version;
+ * struct timeval wait;
+ * int *sockp;
+ *
+ * Same as above, but you specify max packet sizes.
+ * CLIENT *
+ * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+ * struct sockaddr_in *raddr;
+ * u_long program;
+ * u_long version;
+ * struct timeval wait;
+ * int *sockp;
+ * u_int sendsz;
+ * u_int recvsz;
+ */
+__BEGIN_DECLS
+extern CLIENT *clntudp_create __P((struct sockaddr_in *,
+ u_long,
+ u_long,
+ struct timeval,
+ int *));
+extern CLIENT *clntudp_bufcreate __P((struct sockaddr_in *,
+ u_long,
+ u_long,
+ struct timeval,
+ int *,
+ u_int,
+ u_int));
+__END_DECLS
+
+
+/*
+ * Print why creation failed
+ */
+__BEGIN_DECLS
+extern void clnt_pcreateerror __P((char *)); /* stderr */
+extern char *clnt_spcreateerror __P((char *)); /* string */
+__END_DECLS
+
+/*
+ * Like clnt_perror(), but is more verbose in its output
+ */
+__BEGIN_DECLS
+extern void clnt_perrno __P((enum clnt_stat)); /* stderr */
+extern char *clnt_sperrno __P((enum clnt_stat)); /* string */
+__END_DECLS
+
+/*
+ * Print an English error message, given the client error code
+ */
+__BEGIN_DECLS
+extern void clnt_perror __P((CLIENT *, char *)); /* stderr */
+extern char *clnt_sperror __P((CLIENT *, char *)); /* string */
+__END_DECLS
+
+
+/*
+ * If a creation fails, the following allows the user to figure out why.
+ */
+struct rpc_createerr {
+ enum clnt_stat cf_stat;
+ struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
+};
+
+extern struct rpc_createerr rpc_createerr;
+
+
+#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */
+#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */
+
+#endif /* !_RPC_CLNT_H */
diff --git a/lib/libc/rpc/clnt_generic.c b/lib/libc/rpc/clnt_generic.c
new file mode 100644
index 000000000000..ad9c22bb7191
--- /dev/null
+++ b/lib/libc/rpc/clnt_generic.c
@@ -0,0 +1,113 @@
+/*
+ * 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.1 1993/10/27 05:40:19 paul Exp $";
+#endif
+
+/*
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ */
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <netdb.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 000000000000..9a7d76cbc200
--- /dev/null
+++ b/lib/libc/rpc/clnt_perror.c
@@ -0,0 +1,303 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * 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.1 1993/10/27 05:40:20 paul Exp $";
+#endif
+
+/*
+ * clnt_perror.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+#include <stdio.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",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",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",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 000000000000..9ee87b225701
--- /dev/null
+++ b/lib/libc/rpc/clnt_raw.c
@@ -0,0 +1,240 @@
+/*
+ * 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.1 1993/10/27 05:40:22 paul 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>
+
+#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 staic 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 000000000000..671e2eb61a93
--- /dev/null
+++ b/lib/libc/rpc/clnt_simple.c
@@ -0,0 +1,115 @@
+/*
+ * 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.1 1993/10/27 05:40:23 paul Exp $";
+#endif
+
+/*
+ * clnt_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 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 000000000000..efc041ab8db3
--- /dev/null
+++ b/lib/libc/rpc/clnt_tcp.c
@@ -0,0 +1,468 @@
+/*
+ * 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.1 1993/10/27 05:40:24 paul 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 <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 staic 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, (int*)NULL, (int*)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 000000000000..4df4631079a7
--- /dev/null
+++ b/lib/libc/rpc/clnt_udp.c
@@ -0,0 +1,444 @@
+/*
+ * 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.1 1993/10/27 05:40:25 paul Exp $";
+#endif
+
+/*
+ * clnt_udp.c, Implements a UDP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.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, (int *)NULL,
+ (int *)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 000000000000..2b0b20d96f0e
--- /dev/null
+++ b/lib/libc/rpc/get_myaddress.c
@@ -0,0 +1,99 @@
+/*
+ * 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.1 1993/10/27 05:40:27 paul 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 <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 000000000000..f500c01b075f
--- /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 (8C),
+.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 000000000000..a495278f8d27
--- /dev/null
+++ b/lib/libc/rpc/getrpcent.c
@@ -0,0 +1,298 @@
+/*
+ * 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.1 1993/10/27 05:40:29 paul Exp $";
+#endif
+
+/*
+ * Copyright (c) 1984 by Sun Microsystems, Inc.
+ */
+
+#include <stdio.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 *key = NULL, *val = NULL;
+ int keylen, 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 000000000000..0323d34a07c8
--- /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 3R "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 000000000000..f1d58f9eb718
--- /dev/null
+++ b/lib/libc/rpc/getrpcport.c
@@ -0,0 +1,57 @@
+/*
+ * 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.1 1993/10/27 05:40:31 paul Exp $";
+#endif
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#include <stdio.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 000000000000..4ef44ec3144c
--- /dev/null
+++ b/lib/libc/rpc/pmap_clnt.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: @(#)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.1 1993/10/27 05:40:32 paul Exp $";
+#endif
+
+/*
+ * pmap_clnt.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>
+
+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_clnt.h b/lib/libc/rpc/pmap_clnt.h
new file mode 100644
index 000000000000..f080ec50956f
--- /dev/null
+++ b/lib/libc/rpc/pmap_clnt.h
@@ -0,0 +1,84 @@
+/*
+ * 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
+ *
+ * from: @(#)pmap_clnt.h 1.11 88/02/08 SMI
+ * from: @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC
+ * $Id: pmap_clnt.h,v 1.1 1993/10/27 05:40:33 paul Exp $
+ */
+
+/*
+ * pmap_clnt.h
+ * Supplies C routines to get to portmap services.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * Usage:
+ * success = pmap_set(program, version, protocol, port);
+ * success = pmap_unset(program, version);
+ * port = pmap_getport(address, program, version, protocol);
+ * head = pmap_getmaps(address);
+ * clnt_stat = pmap_rmtcall(address, program, version, procedure,
+ * xdrargs, argsp, xdrres, resp, tout, port_ptr)
+ * (works for udp only.)
+ * clnt_stat = clnt_broadcast(program, version, procedure,
+ * xdrargs, argsp, xdrres, resp, eachresult)
+ * (like pmap_rmtcall, except the call is broadcasted to all
+ * locally connected nets. For each valid response received,
+ * the procedure eachresult is called. Its form is:
+ * done = eachresult(resp, raddr)
+ * bool_t done;
+ * caddr_t resp;
+ * struct sockaddr_in raddr;
+ * where resp points to the results of the call and raddr is the
+ * address if the responder to the broadcast.
+ */
+
+#ifndef _RPC_PMAPCLNT_H
+#define _RPC_PMAPCLNT_H
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern bool_t pmap_set __P((u_long, u_long, int, int));
+extern bool_t pmap_unset __P((u_long, u_long));
+extern struct pmaplist *pmap_getmaps __P((struct sockaddr_in *));
+extern enum clnt_stat pmap_rmtcall __P((struct sockaddr_in *,
+ u_long, u_long, u_long,
+ xdrproc_t, caddr_t,
+ xdrproc_t, caddr_t,
+ struct timeval, u_long *));
+extern enum clnt_stat clnt_broadcast __P((u_long, u_long, u_long,
+ xdrproc_t, char *,
+ xdrproc_t, char *,
+ bool_t (*)()));
+extern u_short pmap_getport __P((struct sockaddr_in *,
+ u_long, u_long, u_int));
+__END_DECLS
+
+#endif /* !_RPC_PMAPCLNT_H */
diff --git a/lib/libc/rpc/pmap_getmaps.c b/lib/libc/rpc/pmap_getmaps.c
new file mode 100644
index 000000000000..5af52106454b
--- /dev/null
+++ b/lib/libc/rpc/pmap_getmaps.c
@@ -0,0 +1,86 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: pmap_getmaps.c,v 1.1 1993/10/27 05:40:35 paul 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 <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 000000000000..06ed4d409fbb
--- /dev/null
+++ b/lib/libc/rpc/pmap_getport.c
@@ -0,0 +1,89 @@
+/*
+ * 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.1 1993/10/27 05:40:36 paul 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>
+
+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 000000000000..ea0a20dfb144
--- /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 1993/10/27 05:40:37 paul 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_prot.h b/lib/libc/rpc/pmap_prot.h
new file mode 100644
index 000000000000..1c10c368d187
--- /dev/null
+++ b/lib/libc/rpc/pmap_prot.h
@@ -0,0 +1,104 @@
+/*
+ * 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
+ *
+ * from: @(#)pmap_prot.h 1.14 88/02/08 SMI
+ * from: @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC
+ * $Id: pmap_prot.h,v 1.1 1993/10/27 05:40:38 paul Exp $
+ */
+
+/*
+ * pmap_prot.h
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The following procedures are supported by the protocol:
+ *
+ * PMAPPROC_NULL() returns ()
+ * takes nothing, returns nothing
+ *
+ * PMAPPROC_SET(struct pmap) returns (bool_t)
+ * TRUE is success, FALSE is failure. Registers the tuple
+ * [prog, vers, prot, port].
+ *
+ * PMAPPROC_UNSET(struct pmap) returns (bool_t)
+ * TRUE is success, FALSE is failure. Un-registers pair
+ * [prog, vers]. prot and port are ignored.
+ *
+ * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
+ * 0 is failure. Otherwise returns the port number where the pair
+ * [prog, vers] is registered. It may lie!
+ *
+ * PMAPPROC_DUMP() RETURNS (struct pmaplist *)
+ *
+ * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
+ * RETURNS (port, string<>);
+ * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
+ * Calls the procedure on the local machine. If it is not registered,
+ * this procedure is quite; ie it does not return error information!!!
+ * This procedure only is supported on rpc/udp and calls via
+ * rpc/udp. This routine only passes null authentication parameters.
+ * This file has no interface to xdr routines for PMAPPROC_CALLIT.
+ *
+ * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
+ */
+
+#ifndef _RPC_PMAPPROT_H
+#define _RPC_PMAPPROT_H
+#include <sys/cdefs.h>
+
+#define PMAPPORT ((u_short)111)
+#define PMAPPROG ((u_long)100000)
+#define PMAPVERS ((u_long)2)
+#define PMAPVERS_PROTO ((u_long)2)
+#define PMAPVERS_ORIG ((u_long)1)
+#define PMAPPROC_NULL ((u_long)0)
+#define PMAPPROC_SET ((u_long)1)
+#define PMAPPROC_UNSET ((u_long)2)
+#define PMAPPROC_GETPORT ((u_long)3)
+#define PMAPPROC_DUMP ((u_long)4)
+#define PMAPPROC_CALLIT ((u_long)5)
+
+struct pmap {
+ long unsigned pm_prog;
+ long unsigned pm_vers;
+ long unsigned pm_prot;
+ long unsigned pm_port;
+};
+
+struct pmaplist {
+ struct pmap pml_map;
+ struct pmaplist *pml_next;
+};
+
+__BEGIN_DECLS
+extern bool_t xdr_pmap __P((XDR *, struct pmap *));
+extern bool_t xdr_pmaplist __P((XDR *, struct pmaplist **));
+__END_DECLS
+
+#endif /* !_RPC_PMAPPROT_H */
diff --git a/lib/libc/rpc/pmap_prot2.c b/lib/libc/rpc/pmap_prot2.c
new file mode 100644
index 000000000000..71ab21a7103b
--- /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 1993/10/27 05:40:39 paul 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 000000000000..339860c2c153
--- /dev/null
+++ b/lib/libc/rpc/pmap_rmt.c
@@ -0,0 +1,397 @@
+/*
+ * 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.1 1993/10/27 05:40:40 paul 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 <errno.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, (int *)NULL,
+ (int *)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/pmap_rmt.h b/lib/libc/rpc/pmap_rmt.h
new file mode 100644
index 000000000000..c8c06ecb584d
--- /dev/null
+++ b/lib/libc/rpc/pmap_rmt.h
@@ -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
+ *
+ * from: @(#)pmap_rmt.h 1.2 88/02/08 SMI
+ * from: @(#)pmap_rmt.h 2.1 88/07/29 4.0 RPCSRC
+ * $Id: pmap_rmt.h,v 1.1 1993/10/27 05:40:41 paul Exp $
+ */
+
+/*
+ * Structures and XDR routines for parameters to and replies from
+ * the portmapper remote-call-service.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_PMAPRMT_H
+#define _RPC_PMAPRMT_H
+#include <sys/cdefs.h>
+
+struct rmtcallargs {
+ u_long prog, vers, proc, arglen;
+ caddr_t args_ptr;
+ xdrproc_t xdr_args;
+};
+
+struct rmtcallres {
+ u_long *port_ptr;
+ u_long resultslen;
+ caddr_t results_ptr;
+ xdrproc_t xdr_results;
+};
+
+__BEGIN_DECLS
+extern bool_t xdr_rmtcall_args __P((XDR *, struct rmtcallargs *));
+extern bool_t xdr_rmtcallres __P((XDR *, struct rmtcallres *));
+__END_DECLS
+
+#endif /* !_RPC_PMAPRMT_H */
diff --git a/lib/libc/rpc/rpc.3 b/lib/libc/rpc/rpc.3
new file mode 100644
index 000000000000..b5a2b92fce76
--- /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 3N "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 use
+.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 use
+.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 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
+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 (3N)
+.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 000000000000..324ecb153a83
--- /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.h b/lib/libc/rpc/rpc.h
new file mode 100644
index 000000000000..5f8d23ea3d6e
--- /dev/null
+++ b/lib/libc/rpc/rpc.h
@@ -0,0 +1,89 @@
+/*
+ * 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
+ *
+ * from: @(#)rpc.h 1.9 88/02/08 SMI
+ * from: @(#)rpc.h 2.4 89/07/11 4.0 RPCSRC
+ * $Id: rpc.h,v 1.1 1993/10/27 05:40:45 paul Exp $
+ */
+
+/*
+ * rpc.h, Just includes the billions of rpc header files necessary to
+ * do remote procedure calling.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+#ifndef _RPC_RPC_H
+#define _RPC_RPC_H
+
+#include <rpc/types.h> /* some typedefs */
+#include <netinet/in.h>
+
+/* external data representation interfaces */
+#include <rpc/xdr.h> /* generic (de)serializer */
+
+/* Client side only authentication */
+#include <rpc/auth.h> /* generic authenticator (client side) */
+
+/* Client side (mostly) remote procedure call */
+#include <rpc/clnt.h> /* generic rpc stuff */
+
+/* semi-private protocol headers */
+#include <rpc/rpc_msg.h> /* protocol for rpc messages */
+#include <rpc/auth_unix.h> /* protocol for unix style cred */
+/*
+ * Uncomment-out the next line if you are building the rpc library with
+ * DES Authentication (see the README file in the secure_rpc/ directory).
+ */
+/*#include <rpc/auth_des.h> /* protocol for des style cred */
+
+/* Server side only remote procedure callee */
+#include <rpc/svc.h> /* service manager and multiplexer */
+#include <rpc/svc_auth.h> /* service side authenticator */
+
+/*
+ * COMMENT OUT THE NEXT INCLUDE (or add to the #ifndef) IF RUNNING ON
+ * A VERSION OF UNIX THAT USES SUN'S NFS SOURCE. These systems will
+ * already have the structures defined by <rpc/netdb.h> included in <netdb.h>.
+ */
+/* routines for parsing /etc/rpc */
+
+struct rpcent {
+ char *r_name; /* name of server for this rpc program */
+ char **r_aliases; /* alias list */
+ int r_number; /* rpc program number */
+};
+
+__BEGIN_DECLS
+extern struct rpcent *getrpcbyname __P((char *));
+extern struct rpcent *getrpcbynumber __P((int));
+extern struct rpcent *getrpcent __P((void));
+extern void setrpcent __P((int));
+extern void endrpcent __P((void));
+__END_DECLS
+
+#endif /* !_RPC_RPC_H */
diff --git a/lib/libc/rpc/rpc_callmsg.c b/lib/libc/rpc/rpc_callmsg.c
new file mode 100644
index 000000000000..4ec59dbc7855
--- /dev/null
+++ b/lib/libc/rpc/rpc_callmsg.c
@@ -0,0 +1,192 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#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.1 1993/10/27 05:40:46 paul Exp $";
+#endif
+
+/*
+ * rpc_callmsg.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+
+#include <sys/param.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 000000000000..e870ab8dde7c
--- /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 1993/10/27 05:40:47 paul 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 000000000000..c4a2ac411b33
--- /dev/null
+++ b/lib/libc/rpc/rpc_dtablesize.c
@@ -0,0 +1,48 @@
+/*
+ * 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 = "$Id: rpc_dtablesize.c,v 1.1 1993/10/27 05:40:48 paul Exp $";
+#endif
+
+/*
+ * Cache the result of getdtablesize(), so we don't have to do an
+ * expensive system call every time.
+ */
+_rpc_dtablesize()
+{
+ static int size;
+
+ if (size == 0) {
+ size = getdtablesize();
+ }
+ return (size);
+}
diff --git a/lib/libc/rpc/rpc_msg.h b/lib/libc/rpc/rpc_msg.h
new file mode 100644
index 000000000000..f3697fa8a02f
--- /dev/null
+++ b/lib/libc/rpc/rpc_msg.h
@@ -0,0 +1,195 @@
+/*
+ * 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
+ *
+ * from: @(#)rpc_msg.h 1.7 86/07/16 SMI
+ * from: @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC
+ * $Id: rpc_msg.h,v 1.1 1993/10/27 05:40:49 paul Exp $
+ */
+
+/*
+ * rpc_msg.h
+ * rpc message definition
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_RPCMSG_H
+#define _RPC_RPCMSG_H
+
+#define RPC_MSG_VERSION ((u_long) 2)
+#define RPC_SERVICE_PORT ((u_short) 2048)
+
+/*
+ * Bottom up definition of an rpc message.
+ * NOTE: call and reply use the same overall stuct but
+ * different parts of unions within it.
+ */
+
+enum msg_type {
+ CALL=0,
+ REPLY=1
+};
+
+enum reply_stat {
+ MSG_ACCEPTED=0,
+ MSG_DENIED=1
+};
+
+enum accept_stat {
+ SUCCESS=0,
+ PROG_UNAVAIL=1,
+ PROG_MISMATCH=2,
+ PROC_UNAVAIL=3,
+ GARBAGE_ARGS=4,
+ SYSTEM_ERR=5
+};
+
+enum reject_stat {
+ RPC_MISMATCH=0,
+ AUTH_ERROR=1
+};
+
+/*
+ * Reply part of an rpc exchange
+ */
+
+/*
+ * Reply to an rpc request that was accepted by the server.
+ * Note: there could be an error even though the request was
+ * accepted.
+ */
+struct accepted_reply {
+ struct opaque_auth ar_verf;
+ enum accept_stat ar_stat;
+ union {
+ struct {
+ u_long low;
+ u_long high;
+ } AR_versions;
+ struct {
+ caddr_t where;
+ xdrproc_t proc;
+ } AR_results;
+ /* and many other null cases */
+ } ru;
+#define ar_results ru.AR_results
+#define ar_vers ru.AR_versions
+};
+
+/*
+ * Reply to an rpc request that was rejected by the server.
+ */
+struct rejected_reply {
+ enum reject_stat rj_stat;
+ union {
+ struct {
+ u_long low;
+ u_long high;
+ } RJ_versions;
+ enum auth_stat RJ_why; /* why authentication did not work */
+ } ru;
+#define rj_vers ru.RJ_versions
+#define rj_why ru.RJ_why
+};
+
+/*
+ * Body of a reply to an rpc request.
+ */
+struct reply_body {
+ enum reply_stat rp_stat;
+ union {
+ struct accepted_reply RP_ar;
+ struct rejected_reply RP_dr;
+ } ru;
+#define rp_acpt ru.RP_ar
+#define rp_rjct ru.RP_dr
+};
+
+/*
+ * Body of an rpc request call.
+ */
+struct call_body {
+ u_long cb_rpcvers; /* must be equal to two */
+ u_long cb_prog;
+ u_long cb_vers;
+ u_long cb_proc;
+ struct opaque_auth cb_cred;
+ struct opaque_auth cb_verf; /* protocol specific - provided by client */
+};
+
+/*
+ * The rpc message
+ */
+struct rpc_msg {
+ u_long rm_xid;
+ enum msg_type rm_direction;
+ union {
+ struct call_body RM_cmb;
+ struct reply_body RM_rmb;
+ } ru;
+#define rm_call ru.RM_cmb
+#define rm_reply ru.RM_rmb
+};
+#define acpted_rply ru.RM_rmb.ru.RP_ar
+#define rjcted_rply ru.RM_rmb.ru.RP_dr
+
+__BEGIN_DECLS
+/*
+ * XDR routine to handle a rpc message.
+ * xdr_callmsg(xdrs, cmsg)
+ * XDR *xdrs;
+ * struct rpc_msg *cmsg;
+ */
+extern bool_t xdr_callmsg __P((XDR *, struct rpc_msg *));
+
+/*
+ * XDR routine to pre-serialize the static part of a rpc message.
+ * xdr_callhdr(xdrs, cmsg)
+ * XDR *xdrs;
+ * struct rpc_msg *cmsg;
+ */
+extern bool_t xdr_callhdr __P((XDR *, struct rpc_msg *));
+
+/*
+ * XDR routine to handle a rpc reply.
+ * xdr_replymsg(xdrs, rmsg)
+ * XDR *xdrs;
+ * struct rpc_msg *rmsg;
+ */
+extern bool_t xdr_replymsg __P((XDR *, struct rpc_msg *));
+
+/*
+ * Fills in the error part of a reply message.
+ * _seterr_reply(msg, error)
+ * struct rpc_msg *msg;
+ * struct rpc_err *error;
+ */
+extern void _seterr_reply __P((struct rpc_msg *, struct rpc_err *));
+__END_DECLS
+
+#endif /* !_RPC_RPCMSG_H */
diff --git a/lib/libc/rpc/rpc_prot.c b/lib/libc/rpc/rpc_prot.c
new file mode 100644
index 000000000000..7fbb36fd7557
--- /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 1993/10/27 05:40:50 paul 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 000000000000..61d9999116f8
--- /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 000000000000..a10b71dbacad
--- /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 000000000000..55ad25e92ad0
--- /dev/null
+++ b/lib/libc/rpc/svc.c
@@ -0,0 +1,481 @@
+/*
+ * 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.1 1993/10/27 05:40:54 paul 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 <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.h b/lib/libc/rpc/svc.h
new file mode 100644
index 000000000000..b525d8232dea
--- /dev/null
+++ b/lib/libc/rpc/svc.h
@@ -0,0 +1,302 @@
+/*
+ * 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
+ *
+ * from: @(#)svc.h 1.20 88/02/08 SMI
+ * from: @(#)svc.h 2.2 88/07/29 4.0 RPCSRC
+ * $Id: svc.h,v 1.1 1993/10/27 05:40:55 paul Exp $
+ */
+
+/*
+ * svc.h, Server-side remote procedure call interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_SVC_H
+#define _RPC_SVC_H
+#include <sys/cdefs.h>
+
+/*
+ * This interface must manage two items concerning remote procedure calling:
+ *
+ * 1) An arbitrary number of transport connections upon which rpc requests
+ * are received. The two most notable transports are TCP and UDP; they are
+ * created and registered by routines in svc_tcp.c and svc_udp.c, respectively;
+ * they in turn call xprt_register and xprt_unregister.
+ *
+ * 2) An arbitrary number of locally registered services. Services are
+ * described by the following four data: program number, version number,
+ * "service dispatch" function, a transport handle, and a boolean that
+ * indicates whether or not the exported program should be registered with a
+ * local binder service; if true the program's number and version and the
+ * port number from the transport handle are registered with the binder.
+ * These data are registered with the rpc svc system via svc_register.
+ *
+ * A service's dispatch function is called whenever an rpc request comes in
+ * on a transport. The request's program and version numbers must match
+ * those of the registered service. The dispatch function is passed two
+ * parameters, struct svc_req * and SVCXPRT *, defined below.
+ */
+
+enum xprt_stat {
+ XPRT_DIED,
+ XPRT_MOREREQS,
+ XPRT_IDLE
+};
+
+/*
+ * Server side transport handle
+ */
+typedef struct {
+ int xp_sock;
+ u_short xp_port; /* associated port number */
+ struct xp_ops {
+ bool_t (*xp_recv)(); /* receive incomming requests */
+ enum xprt_stat (*xp_stat)(); /* get transport status */
+ bool_t (*xp_getargs)(); /* get arguments */
+ bool_t (*xp_reply)(); /* send reply */
+ bool_t (*xp_freeargs)();/* free mem allocated for args */
+ void (*xp_destroy)(); /* destroy this struct */
+ } *xp_ops;
+ int xp_addrlen; /* length of remote address */
+ struct sockaddr_in xp_raddr; /* remote address */
+ struct opaque_auth xp_verf; /* raw response verifier */
+ caddr_t xp_p1; /* private */
+ caddr_t xp_p2; /* private */
+} SVCXPRT;
+
+/*
+ * Approved way of getting address of caller
+ */
+#define svc_getcaller(x) (&(x)->xp_raddr)
+
+/*
+ * Operations defined on an SVCXPRT handle
+ *
+ * SVCXPRT *xprt;
+ * struct rpc_msg *msg;
+ * xdrproc_t xargs;
+ * caddr_t argsp;
+ */
+#define SVC_RECV(xprt, msg) \
+ (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+#define svc_recv(xprt, msg) \
+ (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+
+#define SVC_STAT(xprt) \
+ (*(xprt)->xp_ops->xp_stat)(xprt)
+#define svc_stat(xprt) \
+ (*(xprt)->xp_ops->xp_stat)(xprt)
+
+#define SVC_GETARGS(xprt, xargs, argsp) \
+ (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+#define svc_getargs(xprt, xargs, argsp) \
+ (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+
+#define SVC_REPLY(xprt, msg) \
+ (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+#define svc_reply(xprt, msg) \
+ (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+
+#define SVC_FREEARGS(xprt, xargs, argsp) \
+ (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+#define svc_freeargs(xprt, xargs, argsp) \
+ (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+
+#define SVC_DESTROY(xprt) \
+ (*(xprt)->xp_ops->xp_destroy)(xprt)
+#define svc_destroy(xprt) \
+ (*(xprt)->xp_ops->xp_destroy)(xprt)
+
+
+/*
+ * Service request
+ */
+struct svc_req {
+ u_long rq_prog; /* service program number */
+ u_long rq_vers; /* service protocol version */
+ u_long rq_proc; /* the desired procedure */
+ struct opaque_auth rq_cred; /* raw creds from the wire */
+ caddr_t rq_clntcred; /* read only cooked cred */
+ SVCXPRT *rq_xprt; /* associated transport */
+};
+
+
+/*
+ * Service registration
+ *
+ * svc_register(xprt, prog, vers, dispatch, protocol)
+ * SVCXPRT *xprt;
+ * u_long prog;
+ * u_long vers;
+ * void (*dispatch)();
+ * int protocol; /* like TCP or UDP, zero means do not register
+ */
+__BEGIN_DECLS
+extern bool_t svc_register __P((SVCXPRT *, u_long, u_long, void (*)(), int));
+__END_DECLS
+
+/*
+ * Service un-registration
+ *
+ * svc_unregister(prog, vers)
+ * u_long prog;
+ * u_long vers;
+ */
+__BEGIN_DECLS
+extern void svc_unregister __P((u_long, u_long));
+__END_DECLS
+
+/*
+ * Transport registration.
+ *
+ * xprt_register(xprt)
+ * SVCXPRT *xprt;
+ */
+__BEGIN_DECLS
+extern void xprt_register __P((SVCXPRT *));
+__END_DECLS
+
+/*
+ * Transport un-register
+ *
+ * xprt_unregister(xprt)
+ * SVCXPRT *xprt;
+ */
+__BEGIN_DECLS
+extern void xprt_unregister __P((SVCXPRT *));
+__END_DECLS
+
+
+
+
+/*
+ * When the service routine is called, it must first check to see if it
+ * knows about the procedure; if not, it should call svcerr_noproc
+ * and return. If so, it should deserialize its arguments via
+ * SVC_GETARGS (defined above). If the deserialization does not work,
+ * svcerr_decode should be called followed by a return. Successful
+ * decoding of the arguments should be followed the execution of the
+ * procedure's code and a call to svc_sendreply.
+ *
+ * Also, if the service refuses to execute the procedure due to too-
+ * weak authentication parameters, svcerr_weakauth should be called.
+ * Note: do not confuse access-control failure with weak authentication!
+ *
+ * NB: In pure implementations of rpc, the caller always waits for a reply
+ * msg. This message is sent when svc_sendreply is called.
+ * Therefore pure service implementations should always call
+ * svc_sendreply even if the function logically returns void; use
+ * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows
+ * for the abuse of pure rpc via batched calling or pipelining. In the
+ * case of a batched call, svc_sendreply should NOT be called since
+ * this would send a return message, which is what batching tries to avoid.
+ * It is the service/protocol writer's responsibility to know which calls are
+ * batched and which are not. Warning: responding to batch calls may
+ * deadlock the caller and server processes!
+ */
+
+__BEGIN_DECLS
+extern bool_t svc_sendreply __P((SVCXPRT *, xdrproc_t, char *));
+extern void svcerr_decode __P((SVCXPRT *));
+extern void svcerr_weakauth __P((SVCXPRT *));
+extern void svcerr_noproc __P((SVCXPRT *));
+extern void svcerr_progvers __P((SVCXPRT *, u_long, u_long));
+extern void svcerr_auth __P((SVCXPRT *, enum auth_stat));
+extern void svcerr_noprog __P((SVCXPRT *));
+extern void svcerr_systemerr __P((SVCXPRT *));
+__END_DECLS
+
+/*
+ * Lowest level dispatching -OR- who owns this process anyway.
+ * Somebody has to wait for incoming requests and then call the correct
+ * service routine. The routine svc_run does infinite waiting; i.e.,
+ * svc_run never returns.
+ * Since another (co-existant) package may wish to selectively wait for
+ * incoming calls or other events outside of the rpc architecture, the
+ * routine svc_getreq is provided. It must be passed readfds, the
+ * "in-place" results of a select system call (see select, section 2).
+ */
+
+/*
+ * Global keeper of rpc service descriptors in use
+ * dynamic; must be inspected before each call to select
+ */
+#ifdef FD_SETSIZE
+extern fd_set svc_fdset;
+#define svc_fds svc_fdset.fds_bits[0] /* compatibility */
+#else
+extern int svc_fds;
+#endif /* def FD_SETSIZE */
+
+/*
+ * a small program implemented by the svc_rpc implementation itself;
+ * also see clnt.h for protocol numbers.
+ */
+extern void rpctest_service();
+
+__BEGIN_DECLS
+extern void svc_getreq __P((int));
+extern void svc_getreqset __P((fd_set *));
+extern void svc_run __P((void));
+__END_DECLS
+
+/*
+ * Socket to use on svcxxx_create call to get default socket
+ */
+#define RPC_ANYSOCK -1
+
+/*
+ * These are the existing service side transport implementations
+ */
+
+/*
+ * Memory based rpc for testing and timing.
+ */
+__BEGIN_DECLS
+extern SVCXPRT *svcraw_create __P((void));
+__END_DECLS
+
+
+/*
+ * Udp based rpc.
+ */
+__BEGIN_DECLS
+extern SVCXPRT *svcudp_create __P((int));
+extern SVCXPRT *svcudp_bufcreate __P((int, u_int, u_int));
+__END_DECLS
+
+
+/*
+ * Tcp based rpc.
+ */
+__BEGIN_DECLS
+extern SVCXPRT *svctcp_create __P((int, u_int, u_int));
+__END_DECLS
+
+#endif /* !_RPC_SVC_H */
diff --git a/lib/libc/rpc/svc_auth.c b/lib/libc/rpc/svc_auth.c
new file mode 100644
index 000000000000..0a9f2765bf6a
--- /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 1993/10/27 05:40:56 paul 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.h b/lib/libc/rpc/svc_auth.h
new file mode 100644
index 000000000000..c6db4404e25d
--- /dev/null
+++ b/lib/libc/rpc/svc_auth.h
@@ -0,0 +1,50 @@
+/*
+ * 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
+ *
+ * from: @(#)svc_auth.h 1.6 86/07/16 SMI
+ * from: @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC
+ * $Id: svc_auth.h,v 1.1 1993/10/27 05:40:57 paul Exp $
+ */
+
+/*
+ * svc_auth.h, Service side of rpc authentication.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_SVCAUTH_H
+#define _RPC_SVCAUTH_H
+
+/*
+ * Server side authenticator
+ */
+__BEGIN_DECLS
+extern enum auth_stat _authenticate __P((struct svc_req *, struct rpc_msg *));
+__END_DECLS
+
+#endif /* !_RPC_SVCAUTH_H */
diff --git a/lib/libc/rpc/svc_auth_unix.c b/lib/libc/rpc/svc_auth_unix.c
new file mode 100644
index 000000000000..5cf825f6f8ab
--- /dev/null
+++ b/lib/libc/rpc/svc_auth_unix.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: @(#)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.1 1993/10/27 05:40:58 paul 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 <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 000000000000..e34ea9e32608
--- /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.1 1993/10/27 05:40:59 paul 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>
+
+
+/*
+ * 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 000000000000..52fddf226382
--- /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 1993/10/27 05:41:00 paul 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 000000000000..eacf859f5ca9
--- /dev/null
+++ b/lib/libc/rpc/svc_simple.c
@@ -0,0 +1,145 @@
+/*
+ * 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.1 1993/10/27 05:41:01 paul Exp $";
+#endif
+
+/*
+ * svc_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.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 000000000000..9d19504858fb
--- /dev/null
+++ b/lib/libc/rpc/svc_tcp.c
@@ -0,0 +1,421 @@
+/*
+ * 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.1 1993/10/27 05:41:02 paul 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 <rpc/rpc.h>
+#include <sys/socket.h>
+#include <errno.h>
+extern bool_t abort();
+extern errno;
+
+/*
+ * 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, (int*)NULL, (int*)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 000000000000..d7c7bb2dd825
--- /dev/null
+++ b/lib/libc/rpc/svc_udp.c
@@ -0,0 +1,480 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_udp.c 2.2 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: svc_udp.c,v 1.1 1993/10/27 05:41:03 paul 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 <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 < 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/rpc/types.h b/lib/libc/rpc/types.h
new file mode 100644
index 000000000000..b12221d0d3b2
--- /dev/null
+++ b/lib/libc/rpc/types.h
@@ -0,0 +1,66 @@
+/*
+ * 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
+ *
+ * from: @(#)types.h 1.18 87/07/24 SMI
+ * from: @(#)types.h 2.3 88/08/15 4.0 RPCSRC
+ * $Id: types.h,v 1.1 1993/10/27 05:41:04 paul Exp $
+ */
+
+/*
+ * Rpc additions to <sys/types.h>
+ */
+#ifndef _RPC_TYPES_H
+#define _RPC_TYPES_H
+
+#define bool_t int
+#define enum_t int
+#define __dontcare__ -1
+
+#ifndef FALSE
+# define FALSE (0)
+#endif
+#ifndef TRUE
+# define TRUE (1)
+#endif
+#ifndef NULL
+# define NULL 0
+#endif
+
+#define mem_alloc(bsize) malloc(bsize)
+#define mem_free(ptr, bsize) free(ptr)
+
+#ifndef makedev /* ie, we haven't already included it */
+#include <sys/types.h>
+#endif
+#include <sys/time.h>
+
+#ifndef INADDR_LOOPBACK
+#define INADDR_LOOPBACK (u_long)0x7F000001
+#endif
+
+#endif /* !_RPC_TYPES_H */
diff --git a/lib/libc/rpc/xdr.3 b/lib/libc/rpc/xdr.3
new file mode 100644
index 000000000000..b656ea804da8
--- /dev/null
+++ b/lib/libc/rpc/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/rpc/xdr.c b/lib/libc/rpc/xdr.c
new file mode 100644
index 000000000000..9f402047aa5a
--- /dev/null
+++ b/lib/libc/rpc/xdr.c
@@ -0,0 +1,578 @@
+/*
+ * 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.1 1993/10/27 05:41:06 paul 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 <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/rpc/xdr.h b/lib/libc/rpc/xdr.h
new file mode 100644
index 000000000000..c29cc4816c22
--- /dev/null
+++ b/lib/libc/rpc/xdr.h
@@ -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
+ *
+ * from: @(#)xdr.h 1.19 87/04/22 SMI
+ * from: @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC
+ * $Id: xdr.h,v 1.1 1993/10/27 05:41:07 paul Exp $
+ */
+
+/*
+ * xdr.h, External Data Representation Serialization Routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_XDR_H
+#define _RPC_XDR_H
+#include <sys/cdefs.h>
+
+/*
+ * XDR provides a conventional way for converting between C data
+ * types and an external bit-string representation. Library supplied
+ * routines provide for the conversion on built-in C data types. These
+ * routines and utility routines defined here are used to help implement
+ * a type encode/decode routine for each user-defined type.
+ *
+ * Each data type provides a single procedure which takes two arguments:
+ *
+ * bool_t
+ * xdrproc(xdrs, argresp)
+ * XDR *xdrs;
+ * <type> *argresp;
+ *
+ * xdrs is an instance of a XDR handle, to which or from which the data
+ * type is to be converted. argresp is a pointer to the structure to be
+ * converted. The XDR handle contains an operation field which indicates
+ * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
+ *
+ * XDR_DECODE may allocate space if the pointer argresp is null. This
+ * data can be freed with the XDR_FREE operation.
+ *
+ * We write only one procedure per data type to make it easy
+ * to keep the encode and decode procedures for a data type consistent.
+ * In many cases the same code performs all operations on a user defined type,
+ * because all the hard work is done in the component type routines.
+ * decode as a series of calls on the nested data types.
+ */
+
+/*
+ * Xdr operations. XDR_ENCODE causes the type to be encoded into the
+ * stream. XDR_DECODE causes the type to be extracted from the stream.
+ * XDR_FREE can be used to release the space allocated by an XDR_DECODE
+ * request.
+ */
+enum xdr_op {
+ XDR_ENCODE=0,
+ XDR_DECODE=1,
+ XDR_FREE=2
+};
+
+/*
+ * This is the number of bytes per unit of external data.
+ */
+#define BYTES_PER_XDR_UNIT (4)
+#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
+ * BYTES_PER_XDR_UNIT)
+
+/*
+ * A xdrproc_t exists for each data type which is to be encoded or decoded.
+ *
+ * The second argument to the xdrproc_t is a pointer to an opaque pointer.
+ * The opaque pointer generally points to a structure of the data type
+ * to be decoded. If this pointer is 0, then the type routines should
+ * allocate dynamic storage of the appropriate size and return it.
+ * bool_t (*xdrproc_t)(XDR *, caddr_t *);
+ */
+typedef bool_t (*xdrproc_t)();
+
+/*
+ * The XDR handle.
+ * Contains operation which is being applied to the stream,
+ * an operations vector for the paticular implementation (e.g. see xdr_mem.c),
+ * and two private fields for the use of the particular impelementation.
+ */
+typedef struct {
+ enum xdr_op x_op; /* operation; fast additional param */
+ struct xdr_ops {
+ bool_t (*x_getlong)(); /* get a long from underlying stream */
+ bool_t (*x_putlong)(); /* put a long to " */
+ bool_t (*x_getbytes)();/* get some bytes from " */
+ bool_t (*x_putbytes)();/* put some bytes to " */
+ u_int (*x_getpostn)();/* returns bytes off from beginning */
+ bool_t (*x_setpostn)();/* lets you reposition the stream */
+ long * (*x_inline)(); /* buf quick ptr to buffered data */
+ void (*x_destroy)(); /* free privates of this xdr_stream */
+ } *x_ops;
+ caddr_t x_public; /* users' data */
+ caddr_t x_private; /* pointer to private data */
+ caddr_t x_base; /* private used for position info */
+ int x_handy; /* extra private word */
+} XDR;
+
+/*
+ * Operations defined on a XDR handle
+ *
+ * XDR *xdrs;
+ * long *longp;
+ * caddr_t addr;
+ * u_int len;
+ * u_int pos;
+ */
+#define XDR_GETLONG(xdrs, longp) \
+ (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+#define xdr_getlong(xdrs, longp) \
+ (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+
+#define XDR_PUTLONG(xdrs, longp) \
+ (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+#define xdr_putlong(xdrs, longp) \
+ (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+
+#define XDR_GETBYTES(xdrs, addr, len) \
+ (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+#define xdr_getbytes(xdrs, addr, len) \
+ (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+
+#define XDR_PUTBYTES(xdrs, addr, len) \
+ (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+#define xdr_putbytes(xdrs, addr, len) \
+ (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+
+#define XDR_GETPOS(xdrs) \
+ (*(xdrs)->x_ops->x_getpostn)(xdrs)
+#define xdr_getpos(xdrs) \
+ (*(xdrs)->x_ops->x_getpostn)(xdrs)
+
+#define XDR_SETPOS(xdrs, pos) \
+ (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+#define xdr_setpos(xdrs, pos) \
+ (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+
+#define XDR_INLINE(xdrs, len) \
+ (*(xdrs)->x_ops->x_inline)(xdrs, len)
+#define xdr_inline(xdrs, len) \
+ (*(xdrs)->x_ops->x_inline)(xdrs, len)
+
+#define XDR_DESTROY(xdrs) \
+ if ((xdrs)->x_ops->x_destroy) \
+ (*(xdrs)->x_ops->x_destroy)(xdrs)
+#define xdr_destroy(xdrs) \
+ if ((xdrs)->x_ops->x_destroy) \
+ (*(xdrs)->x_ops->x_destroy)(xdrs)
+
+/*
+ * Support struct for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * a entry with a null procedure pointer. The xdr_union routine gets
+ * the discriminant value and then searches the array of structures
+ * for a matching value. If a match is found the associated xdr routine
+ * is called to handle that part of the union. If there is
+ * no match, then a default routine may be called.
+ * If there is no match and no default routine it is an error.
+ */
+#define NULL_xdrproc_t ((xdrproc_t)0)
+struct xdr_discrim {
+ int value;
+ xdrproc_t proc;
+};
+
+/*
+ * In-line routines for fast encode/decode of primitve data types.
+ * Caveat emptor: these use single memory cycles to get the
+ * data from the underlying buffer, and will fail to operate
+ * properly if the data is not aligned. The standard way to use these
+ * is to say:
+ * if ((buf = XDR_INLINE(xdrs, count)) == NULL)
+ * return (FALSE);
+ * <<< macro calls >>>
+ * where ``count'' is the number of bytes of data occupied
+ * by the primitive data types.
+ *
+ * N.B. and frozen for all time: each data type here uses 4 bytes
+ * of external representation.
+ */
+#define IXDR_GET_LONG(buf) ((long)ntohl((u_long)*(buf)++))
+#define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((u_long)v))
+
+#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf))
+#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf))
+#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf))
+
+#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
+
+/*
+ * These are the "generic" xdr routines.
+ */
+__BEGIN_DECLS
+extern bool_t xdr_void __P((void));
+extern bool_t xdr_int __P((XDR *, int *));
+extern bool_t xdr_u_int __P((XDR *, u_int *));
+extern bool_t xdr_long __P((XDR *, long *));
+extern bool_t xdr_u_long __P((XDR *, u_long *));
+extern bool_t xdr_short __P((XDR *, short *));
+extern bool_t xdr_u_short __P((XDR *, u_short *));
+extern bool_t xdr_bool __P((XDR *, bool_t *));
+extern bool_t xdr_enum __P((XDR *, enum_t *));
+extern bool_t xdr_array __P((XDR *, char **, u_int *, u_int, u_int, xdrproc_t));
+extern bool_t xdr_bytes __P((XDR *, char **, u_int *, u_int));
+extern bool_t xdr_opaque __P((XDR *, caddr_t, u_int));
+extern bool_t xdr_string __P((XDR *, char **, u_int));
+extern bool_t xdr_union __P((XDR *, enum_t *, char *, struct xdr_discrim *, xdrproc_t));
+extern bool_t xdr_char __P((XDR *, char *));
+extern bool_t xdr_u_char __P((XDR *, char *));
+extern bool_t xdr_vector __P((XDR *, char *, u_int, u_int, xdrproc_t));
+extern bool_t xdr_float __P((XDR *, float *));
+extern bool_t xdr_double __P((XDR *, double *));
+extern bool_t xdr_reference __P((XDR *, caddr_t *, u_int, xdrproc_t));
+extern bool_t xdr_pointer __P((XDR *, caddr_t *, u_int, xdrproc_t));
+extern bool_t xdr_wrapstring __P((XDR *, char **));
+extern void xdr_free __P((xdrproc_t, char *));
+__END_DECLS
+
+/*
+ * Common opaque bytes objects used by many rpc protocols;
+ * declared here due to commonality.
+ */
+#define MAX_NETOBJ_SZ 1024
+struct netobj {
+ u_int n_len;
+ char *n_bytes;
+};
+typedef struct netobj netobj;
+extern bool_t xdr_netobj();
+
+/*
+ * These are the public routines for the various implementations of
+ * xdr streams.
+ */
+__BEGIN_DECLS
+/* XDR using memory buffers */
+extern void xdrmem_create __P((XDR *, char *, u_int, enum xdr_op));
+
+#ifdef _STDIO_H_
+/* XDR using stdio library */
+extern void xdrstdio_create __P((XDR *, FILE *, enum xdr_op));
+#endif
+
+/* XDR pseudo records for tcp */
+extern void xdrrec_create __P((XDR *, u_int, u_int, char *, int (*)(), int (*)()));
+
+/* make end of xdr record */
+extern bool_t xdrrec_endofrecord __P((XDR *, int));
+
+/* move to beginning of next record */
+extern bool_t xdrrec_skiprecord __P((XDR *));
+
+/* true if no more input */
+extern bool_t xdrrec_eof __P((XDR *));
+__END_DECLS
+
+#endif /* !_RPC_XDR_H */
diff --git a/lib/libc/rpc/xdr_array.c b/lib/libc/rpc/xdr_array.c
new file mode 100644
index 000000000000..a17b534a92e7
--- /dev/null
+++ b/lib/libc/rpc/xdr_array.c
@@ -0,0 +1,155 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_array.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: xdr_array.c,v 1.1 1993/10/27 05:41:09 paul 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 <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/rpc/xdr_float.c b/lib/libc/rpc/xdr_float.c
new file mode 100644
index 000000000000..fae0c8b7f8e3
--- /dev/null
+++ b/lib/libc/rpc/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 1993/10/27 05:41:10 paul 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/rpc/xdr_mem.c b/lib/libc/rpc/xdr_mem.c
new file mode 100644
index 000000000000..3909edda4ee8
--- /dev/null
+++ b/lib/libc/rpc/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.1 1993/10/27 05:41:11 paul 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 <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/rpc/xdr_rec.c b/lib/libc/rpc/xdr_rec.c
new file mode 100644
index 000000000000..f2559d4b4f6b
--- /dev/null
+++ b/lib/libc/rpc/xdr_rec.c
@@ -0,0 +1,586 @@
+/*
+ * 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.1 1993/10/27 05:41:12 paul 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 <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+extern long lseek();
+
+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/rpc/xdr_reference.c b/lib/libc/rpc/xdr_reference.c
new file mode 100644
index 000000000000..c955f8820256
--- /dev/null
+++ b/lib/libc/rpc/xdr_reference.c
@@ -0,0 +1,134 @@
+/*
+ * 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.1 1993/10/27 05:41:13 paul 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 <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/rpc/xdr_stdio.c b/lib/libc/rpc/xdr_stdio.c
new file mode 100644
index 000000000000..9761b13d5f2a
--- /dev/null
+++ b/lib/libc/rpc/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 1993/10/27 05:41:14 paul 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/stdio/ferror.3 b/lib/libc/stdio/ferror.3
index e90af8fc7167..a4e367835201 100644
--- a/lib/libc/stdio/ferror.3
+++ b/lib/libc/stdio/ferror.3
@@ -82,7 +82,7 @@ The function
.Fn fileno
examines the argument
.Fa stream
-and returns its integer desciptor.
+and returns its integer descriptor.
.Sh ERRORS
These functions should not fail and do not set the external
variable
diff --git a/lib/libc/stdio/fgets.3 b/lib/libc/stdio/fgets.3
index 8676aee498ab..89a5cdbe8c62 100644
--- a/lib/libc/stdio/fgets.3
+++ b/lib/libc/stdio/fgets.3
@@ -93,8 +93,8 @@ they return
The
.Fn fgets
and
-functions
.Fn gets
+functions
do not distinguish between end-of-file and error, and callers must use
.Xr feof 3
and
diff --git a/lib/libc/stdio/setvbuf.c b/lib/libc/stdio/setvbuf.c
index 1928ae14160b..78e616387269 100644
--- a/lib/libc/stdio/setvbuf.c
+++ b/lib/libc/stdio/setvbuf.c
@@ -137,11 +137,14 @@ nbf:
flags |= __SLBF;
if (flags & __SRW)
flags &= ~(__SRD | __SWR);
- fp->_w = 0;
fp->_flags = flags;
fp->_bf._base = fp->_p = (unsigned char *)buf;
fp->_bf._size = size;
fp->_lbfsize = 0;
+ if (flags & __SWR)
+ __swsetup(fp);
+ else
+ fp->_w = 0;
__cleanup = _cleanup;
return (ret);
diff --git a/lib/libc/stdio/stdio.3 b/lib/libc/stdio/stdio.3
index 60fcb2e57173..98143dc62928 100644
--- a/lib/libc/stdio/stdio.3
+++ b/lib/libc/stdio/stdio.3
@@ -77,7 +77,7 @@ function.
A file is disassociated from a stream by
.Em closing
the file.
-Ouput streams are flushed (any unwritten buffer contents are transfered
+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
diff --git a/lib/libc/stdio/strerror.3 b/lib/libc/stdio/strerror.3
index 3f590e5d35b2..7989ea798e7d 100644
--- a/lib/libc/stdio/strerror.3
+++ b/lib/libc/stdio/strerror.3
@@ -47,7 +47,7 @@
.Sh SYNOPSIS
.Vt extern int errno;
.Vt extern char *sys_errlist[];
-.Fd #include <stdio.h>
+.Fd #include <string.h>
.Ft void
.Fn perror "const char *string"
.Ft char *
@@ -61,7 +61,7 @@ functions lookup the error message string affiliated with an
error number.
.Pp
The
-.Fn sterror
+.Fn strerror
function accepts an error number argument
.Fa errnum
and
diff --git a/lib/libc/stdio/tempnam.c b/lib/libc/stdio/tempnam.c
index 988763aac5b8..e3ee6c072f05 100644
--- a/lib/libc/stdio/tempnam.c
+++ b/lib/libc/stdio/tempnam.c
@@ -48,6 +48,8 @@ tempnam(dir, pfx)
{
int sverrno;
char *f, *name;
+ static char unique[] = "@AA";
+ int idx;
if (!(name = malloc(MAXPATHLEN)))
return(NULL);
@@ -55,27 +57,35 @@ tempnam(dir, pfx)
if (!pfx)
pfx = "tmp.";
+ /* Bump up the unique counter. The following is also a gross abuse
+ * of C, but I don't really care. This whole function is superceeded
+ * by mkstemp() anyway.
+ */
+ idx = unique[0] < 'Z' ? 0 : unique[1] < 'Z' ? 1 : unique[2] < 'Z' ?
+ 2 : (int)strcpy(unique, "AAA"), 0;
+ ++unique[idx];
+
if (f = getenv("TMPDIR")) {
- (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
- *(f + strlen(f) - 1) == '/'? "": "/", pfx);
+ (void)snprintf(name, MAXPATHLEN, "%s%s%s%sXXXXXX", f,
+ *(f + strlen(f) - 1) == '/'? "": "/", pfx, unique);
if (f = mktemp(name))
return(f);
}
if (f = (char *)dir) {
- (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
- *(f + strlen(f) - 1) == '/'? "": "/", pfx);
+ (void)snprintf(name, MAXPATHLEN, "%s%s%s%sXXXXXX", f,
+ *(f + strlen(f) - 1) == '/'? "": "/", pfx, unique);
if (f = mktemp(name))
return(f);
}
f = P_tmpdir;
- (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
+ (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, pfx, unique);
if (f = mktemp(name))
return(f);
f = _PATH_TMP;
- (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
+ (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f, pfx, unique);
if (f = mktemp(name))
return(f);
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index 8d064c696c2e..dea8a5620da6 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -35,7 +35,8 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)vfprintf.c 5.50 (Berkeley) 12/16/92";
+/*static char *sccsid = "from: @(#)vfprintf.c 5.50 (Berkeley) 12/16/92";*/
+static char *rcsid = "$Id: vfprintf.c,v 1.5 1994/02/06 07:35:02 wollman Exp $";
#endif /* LIBC_SCCS and not lint */
/*
@@ -120,6 +121,7 @@ __sbprintf(fp, fmt, ap)
#ifdef FLOATING_POINT
+#include <locale.h>
#include <math.h>
#include "floatio.h"
@@ -159,7 +161,7 @@ int
vfprintf(fp, fmt0, ap)
FILE *fp;
const char *fmt0;
- va_list ap;
+ _VA_LIST_ ap;
{
register char *fmt; /* format string */
register int ch; /* character from fmt */
@@ -382,20 +384,23 @@ reswitch: switch (ch) {
base = DEC;
goto number;
#ifdef FLOATING_POINT
- case 'e': /* anomalous precision */
+ case 'e':
case 'E':
- prec = (prec == -1) ?
- DEFPREC + 1 : prec + 1;
- /* FALLTHROUGH */
- goto fp_begin;
- case 'f': /* always print trailing zeroes */
- if (prec != 0)
- flags |= ALT;
+ case 'f':
case 'g':
case 'G':
- if (prec == -1)
+ if (prec == -1) {
prec = DEFPREC;
-fp_begin: _double = va_arg(ap, double);
+ } else if ((ch == 'g' || ch == 'G') && prec == 0) {
+ prec = 1;
+ }
+
+ 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)
@@ -409,6 +414,7 @@ fp_begin: _double = va_arg(ap, double);
size = 3;
break;
}
+
flags |= FPT;
cp = cvt(_double, prec, flags, &softsign,
&expt, ch, &ndig);
@@ -469,7 +475,12 @@ fp_begin: _double = va_arg(ap, double);
* -- ANSI X3J11
*/
/* NOSTRICT */
+ /* no easy way to tell in cpp how big a type is */
+#if defined(__i386)
+ _uquad = (u_quad_t)(u_long)va_arg(ap, void *);
+#else
_uquad = (u_quad_t)va_arg(ap, void *);
+#endif
base = HEX;
xdigs = "0123456789abcdef";
flags |= HEXPREFIX;
@@ -631,9 +642,8 @@ number: if ((dprec = prec) >= 0)
} else { /* glue together f_p fragments */
if (ch >= 'f') { /* 'f' or 'g' */
if (_double == 0) {
- /* kludge for __dtoa irregularity */
- if (prec == 0 ||
- (flags & ALT) == 0) {
+ /* kludge for __dtoa irregularity */
+ if (expt >= ndig && (flags & ALT) == 0) {
PRINT("0", 1);
} else {
PRINT("0.", 2);
@@ -701,18 +711,26 @@ cvt(value, ndigits, flags, sign, decpt, ch, length)
int mode, dsgn;
char *digits, *bp, *rve;
- if (ch == 'f')
- mode = 3;
- else {
- mode = 2;
+ 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 (flags & ALT) { /* Print trailing zeros */
+ if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */
bp = digits + ndigits;
if (ch == 'f') {
if (*digits == '0' && value)
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index 972887fbd82a..0bd1a90ab56a 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -3,17 +3,17 @@
# stdlib sources
.PATH: ${.CURDIR}/${MACHINE}/stdlib ${.CURDIR}/stdlib
-SRCS+= abort.c atexit.c atoi.c atol.c bsearch.c calloc.c div.c exit.c \
+SRCS+= abort.c atexit.c atoi.c atol.c bsearch.c calloc.c exit.c \
getenv.c getopt.c heapsort.c malloc.c multibyte.c \
putenv.c qsort.c radixsort.c rand.c random.c setenv.c strtod.c \
strtol.c strtoul.c system.c \
_rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \
- mrand48.c nrand48.c seed48.c srand48.c
+ mrand48.c nrand48.c seed48.c srand48.c strtoq.c strtouq.c
.if (${MACHINE} == "hp300")
SRCS+= abs.s div.c labs.c ldiv.c atof.c
.elif (${MACHINE} == "i386")
-SRCS+= abs.s div.s labs.s ldiv.s atof.c
+SRCS+= abs.S div.S labs.S ldiv.S atof.c
.elif (${MACHINE} == "tahoe")
SRCS+= abs.s div.c labs.c ldiv.c atof.c
.elif (${MACHINE} == "vax")
diff --git a/lib/libc/stdlib/bsearch.3 b/lib/libc/stdlib/bsearch.3
index 35c5a426f522..b1de330f2429 100644
--- a/lib/libc/stdlib/bsearch.3
+++ b/lib/libc/stdlib/bsearch.3
@@ -50,7 +50,7 @@ The
.Fn bsearch
function searches an array of
.Fa nmemb
-objects, the inital member of which is
+objects, the initial member of which is
pointed to by
.Fa base ,
for a member that matches the object pointed to by
diff --git a/lib/libc/stdlib/exit.c b/lib/libc/stdlib/exit.c
index 0d3c72520f46..50c872afe529 100644
--- a/lib/libc/stdlib/exit.c
+++ b/lib/libc/stdlib/exit.c
@@ -57,4 +57,6 @@ exit(status)
if (__cleanup)
(*__cleanup)();
_exit(status);
+ /* We'll never get here; this just surpresses a warning. */
+ while(1) { ; }
}
diff --git a/lib/libc/stdlib/getopt.3 b/lib/libc/stdlib/getopt.3
index c21a0a725faf..c028465b992f 100644
--- a/lib/libc/stdlib/getopt.3
+++ b/lib/libc/stdlib/getopt.3
@@ -29,7 +29,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)getopt.3 6.16 (Berkeley) 4/19/91
+.\" from: @(#)getopt.3 6.16 (Berkeley) 4/19/91
+.\" $Id: getopt.3,v 1.2 1993/11/23 00:08:36 jtc Exp $
.\"
.Dd April 19, 1991
.Dt GETOPT 3
@@ -38,12 +39,13 @@
.Nm getopt
.Nd get option letter from argv
.Sh SYNOPSIS
-.Fd #include <stdlib.h>
-.Vt extern char *optarg
-.Vt extern int optind
-.Vt extern int opterr
+.Fd #include <unistd.h>
.Ft int
.Fn getopt "int argc" "char * const *argv" "const char *optstring"
+.Vt extern char *optarg;
+.Vt extern int optind;
+.Vt extern int opterr;
+.Vt extern int optopt;
.Sh DESCRIPTION
The
.Fn getopt
@@ -93,68 +95,137 @@ evaluation.
The
.Fn getopt
function
-returns an
-.Dv EOF
-when the argument list is exhausted, or a non-recognized
-option is encountered.
+returns \-1
+when the argument list is exhausted.
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 .
+to signal the end of argument processing and return \-1.
When all options have been processed (i.e., up to the first non-option
argument),
.Fn getopt
-returns
-.Dv EOF .
+returns \-1.
.Sh DIAGNOSTICS
-If the
+If the
.Fn getopt
-function encounters a character not found in the string
-.Va optarg
-or detects
-a missing option argument
-it writes error message
-.Ql ?
-to the
-.Em stderr .
-Setting
+function encounters an option character that is not contained in
+.Fa optstring ,
+it returns a question mark
+.Pq ?
+character.
+If it detects a missing option argument, it returns a colon
+.Pq \:
+character if the first character of
+.Fa optstring
+is a colon, otherwise it returns a question mark.
+In either case, a diagnostic message is written to
+.Em stderr
+unless the application has set
.Va opterr
-to a zero will disable these error messages.
+to zero or the first character of
+.Fa optstring
+is a colon.
.Sh EXAMPLE
+.\" The following example comes from section E.9.7 of the IEEE 1003.2-90
+.\" standard (POSIX.2).
+The following code fragment shows how one might process the arguments for
+a utility that can take the mutually exclusive options
+.Em a
+and
+.Em b
+and the options
+.Em f
+and
+.Em o ,
+both of which require arguments:
+.Pp
.Bd -literal -compact
-extern char *optarg;
-extern int optind;
-int bflag, ch, fd;
+#include <unistd.h>
-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: unable to read file %s.\en", optarg);
- exit(1) ;
+int
+main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ int c, bflg, aflg, errflg = 0;
+ char *ifile, *ofile;
+ extern char *optarg;
+ extern int optind, optopt;
+
+ . . .
+
+ while ((c = getopt(argc, argv, ":abf:o:")) != -1) {
+ switch(ch) {
+ case 'a':
+ if (bflg)
+ errflg = 1;
+ else
+ aflg = 1;
+ break;
+ case 'b':
+ if (aflg)
+ errflg = 1;
+ else
+ bflg = 1;
+ break;
+ case 'f':
+ ifile = optarg;
+ break;
+ case 'o':
+ ofile = optarg;
+ break;
+ case ':': /* -f or -o without option-arg */
+ fprintf (stderr,
+ "Option -%c requires an option-argument\\n",
+ optopt);
+ errflg = 1;
+ break;
+ case '?':
+ fprintf (stderr,
+ "Unrecognized option: -%c\\n",
+ optopt);
+ errflg = 1;
+ break;
}
- break;
- case '?':
- default:
- usage();
+ }
+
+ if (errflg) {
+ fprintf (stderr, "usage: . . .\\n");
+ exit (2);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ . . .
+
}
-argc -= optind;
-argv += optind;
.Ed
+.Sh STANDARDS
+The
+.Fn getopt
+function conforms to
+.St -p1003.2-92 .
.Sh HISTORY
The
.Fn getopt
function appeared
.Bx 4.3 .
.Sh BUGS
+The
+.Fn getopt
+function was once specified to return
+.Dv EOF
+instead of \-1.
+This was changed by
+.St -p1003.2-92
+to decouple
+.Fn getopt
+from
+.Pa <stdio.h> .
+.Pp
Option arguments are allowed to begin with
.Dq Li \- ;
this is reasonable but
@@ -177,8 +248,7 @@ It is provided for backward compatibility
.Em only .
By default, a single dash causes
.Fn getopt
-to return
-.Dv EOF .
+to returns \-1.
This is, we believe, compatible with System V.
.Pp
It is also possible to handle digits as option letters.
@@ -195,7 +265,7 @@ The following code fragment works fairly well.
int length;
char *p;
-while ((c = getopt(argc, argv, "0123456789")) != EOF)
+while ((c = getopt(argc, argv, "0123456789")) != -1)
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
diff --git a/lib/libc/stdlib/getopt.c b/lib/libc/stdlib/getopt.c
index 7126cc1da95a..7d1d9802156f 100644
--- a/lib/libc/stdlib/getopt.c
+++ b/lib/libc/stdlib/getopt.c
@@ -32,7 +32,8 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getopt.c 4.13 (Berkeley) 2/23/91";
+/*static char *sccsid = "from: @(#)getopt.c 4.13 (Berkeley) 2/23/91";*/
+static char *rcsid = "$Id: getopt.c,v 1.2 1993/11/23 00:08:37 jtc Exp $";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
@@ -42,11 +43,12 @@ static char sccsid[] = "@(#)getopt.c 4.13 (Berkeley) 2/23/91";
/*
* get option letter from argument vector
*/
-int opterr = 1, /* if error message should be printed */
- optind = 1, /* index into parent argv vector */
- optopt; /* character checked for validity */
+int opterr = 1; /* if error message should be printed */
+int optind = 1; /* index into parent argv vector */
+int optopt; /* character checked for validity */
char *optarg; /* argument associated with option */
+#define NOOPT (int)':' /* No option */
#define BADCH (int)'?'
#define EMSG ""
@@ -63,26 +65,27 @@ getopt(nargc, nargv, ostr)
if (!*place) { /* update scanning pointer */
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = EMSG;
- return(EOF);
+ return(-1);
}
if (place[1] && *++place == '-') { /* found "--" */
++optind;
place = EMSG;
- return(EOF);
+ return(-1);
}
- } /* option letter okay? */
+ }
+ /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' ||
- !(oli = index(ostr, optopt))) {
+ !(oli = strchr(ostr, optopt))) {
/*
* if the user didn't specify '-' as an option,
- * assume it means EOF.
+ * assume it means -1.
*/
if (optopt == (int)'-')
- return(EOF);
+ return(-1);
if (!*place)
++optind;
- if (opterr) {
- if (!(p = rindex(*nargv, '/')))
+ if (opterr && *ostr != ':') {
+ if (!(p = strrchr(*nargv, '/')))
p = *nargv;
else
++p;
@@ -91,25 +94,26 @@ getopt(nargc, nargv, ostr)
}
return(BADCH);
}
+
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
- }
- else { /* need an argument */
+ } else { /* need an argument */
if (*place) /* no white space */
optarg = place;
else if (nargc <= ++optind) { /* no arg */
place = EMSG;
- if (!(p = rindex(*nargv, '/')))
- p = *nargv;
- else
- ++p;
- if (opterr)
+ if (opterr && *ostr != ':') {
+ if (!(p = strrchr(*nargv, '/')))
+ p = *nargv;
+ else
+ ++p;
(void)fprintf(stderr,
"%s: option requires an argument -- %c\n",
p, optopt);
- return(BADCH);
+ }
+ return((*ostr == ':') ? NOOPT : BADCH);
}
else /* white space */
optarg = nargv[optind];
diff --git a/lib/libc/stdlib/rand48.3 b/lib/libc/stdlib/rand48.3
index fead60db46e2..176303dcf795 100644
--- a/lib/libc/stdlib/rand48.3
+++ b/lib/libc/stdlib/rand48.3
@@ -158,6 +158,3 @@ Martin Birgmeier
.Sh SEE ALSO
.Xr rand 3 ,
.Xr random 3 .
-============================== cut here ==============================
-
-
diff --git a/lib/libc/stdlib/random.3 b/lib/libc/stdlib/random.3
index 872983cd9e86..17a31b2aae45 100644
--- a/lib/libc/stdlib/random.3
+++ b/lib/libc/stdlib/random.3
@@ -41,7 +41,7 @@
.Nm setstate
.Nd better random number generator; routines for changing generators
.Sh SYNOPSIS
-.Fd #include <stdlib>
+.Fd #include <stdlib.h>
.Ft long
.Fn random void
.Ft void
diff --git a/lib/libc/stdlib/realloc.3 b/lib/libc/stdlib/realloc.3
index ee3e64018fc7..ba2ccc9180fb 100644
--- a/lib/libc/stdlib/realloc.3
+++ b/lib/libc/stdlib/realloc.3
@@ -72,7 +72,7 @@ by a call to the
or
.Fn realloc
function, unpredictable and usually detrimental
-behaviour will occur.
+behavior will occur.
If the space cannot be allocated, the object
pointed to by
.Fa ptr
diff --git a/lib/libc/stdlib/setenv.c b/lib/libc/stdlib/setenv.c
index 14efac37b37c..9cade228c687 100644
--- a/lib/libc/stdlib/setenv.c
+++ b/lib/libc/stdlib/setenv.c
@@ -39,6 +39,8 @@ static char sccsid[] = "@(#)setenv.c 5.6 (Berkeley) 6/4/91";
#include <stdlib.h>
#include <string.h>
+extern char *_findenv();
+
/*
* setenv --
* Set the value of the environmental variable "name" to be
@@ -53,7 +55,6 @@ setenv(name, value, rewrite)
static int alloced; /* if allocated space before */
register char *C;
int l_value, offset;
- char *_findenv();
if (*value == '=') /* no `=' in value */
++value;
diff --git a/lib/libc/stdlib/strtol.c b/lib/libc/stdlib/strtol.c
index 000d87647af6..1c1d5c96ee9a 100644
--- a/lib/libc/stdlib/strtol.c
+++ b/lib/libc/stdlib/strtol.c
@@ -124,6 +124,6 @@ strtol(nptr, endptr, base)
} else if (neg)
acc = -acc;
if (endptr != 0)
- *endptr = any ? s - 1 : (char *)nptr;
+ *endptr = any ? (char *)s - 1 : (char *)nptr;
return (acc);
}
diff --git a/lib/libc/stdlib/strtoq.c b/lib/libc/stdlib/strtoq.c
new file mode 100644
index 000000000000..af02765d6c98
--- /dev/null
+++ b/lib/libc/stdlib/strtoq.c
@@ -0,0 +1,136 @@
+/*-
+ * Copyright (c) 1992 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT 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 5.1 (Berkeley) 6/26/92";
+#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 int 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 (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 = any ? (char *)s - 1 : (char *)nptr;
+ return (acc);
+}
diff --git a/lib/libc/stdlib/strtoul.c b/lib/libc/stdlib/strtoul.c
index ed8c1080ba6e..284c182ef71c 100644
--- a/lib/libc/stdlib/strtoul.c
+++ b/lib/libc/stdlib/strtoul.c
@@ -102,6 +102,6 @@ strtoul(nptr, endptr, base)
} else if (neg)
acc = -acc;
if (endptr != 0)
- *endptr = any ? s - 1 : (char *)nptr;
+ *endptr = any ? (char *)s - 1 : (char *)nptr;
return (acc);
}
diff --git a/lib/libc/db/PORT/clib/mktemp.c b/lib/libc/stdlib/strtouq.c
index 6cedd6a6be43..14e37e07f324 100644
--- a/lib/libc/db/PORT/clib/mktemp.c
+++ b/lib/libc/stdlib/strtouq.c
@@ -1,6 +1,6 @@
-/*
- * Copyright (c) 1987, 1993
- * The Regents of the University of California. All rights reserved.
+/*-
+ * Copyright (c) 1992 The Regents of the University of California.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,95 +32,83 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)strtouq.c 5.1 (Berkeley) 6/26/92";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
+
+#include <limits.h>
#include <errno.h>
-#include <stdio.h>
#include <ctype.h>
+#include <stdlib.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;
+/*
+ * 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;
{
- 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;
- }
+ register const char *s = nptr;
+ register u_quad_t acc;
+ register int c;
+ register u_quad_t qbase, cutoff;
+ register int neg, any, cutlim;
/*
- * check the target directory; if you have six X's and it
- * doesn't exist this runs for a *very* long time.
+ * See strtoq for comments as to the logic used.
*/
- for (start = trv + 1;; --trv) {
- if (trv <= path)
+ 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 (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
break;
- if (*trv == '/') {
- *trv = '\0';
- if (stat(path, &sbuf))
- return(0);
- if (!S_ISDIR(sbuf.st_mode)) {
- errno = ENOTDIR;
- return(0);
- }
- *trv = '/';
+ if (c >= base)
break;
+ if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
+ any = -1;
+ else {
+ any = 1;
+ acc *= qbase;
+ acc += c;
}
}
-
- 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*/
+ if (any < 0) {
+ acc = UQUAD_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = any ? (char *)s - 1 : (char *)nptr;
+ return (acc);
}
diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc
index edd26209a1e2..bb5f703b6573 100644
--- a/lib/libc/string/Makefile.inc
+++ b/lib/libc/string/Makefile.inc
@@ -12,11 +12,11 @@ SRCS+= bcmp.s bcopy.s bzero.s ffs.s index.s memchr.c memcmp.c memset.c \
strncat.c strncmp.s strncpy.s strpbrk.c strsep.c \
strspn.c strstr.c
.elif (${MACHINE} == "i386")
-SRCS+= bcmp.s bcopy.s bzero.s ffs.s index.s memchr.s memcmp.s memset.s \
- rindex.s strcat.s strcmp.s strcpy.s strcspn.c strlen.s \
- strncat.c strncmp.s strncpy.c strpbrk.c strsep.c \
+SRCS+= bcmp.S bcopy.S bzero.S ffs.S index.S memchr.S memcmp.S memset.S \
+ rindex.S strcat.S strcmp.S strcpy.S strcspn.c strlen.S \
+ strncat.c strncmp.S strncpy.c strpbrk.c strsep.c \
strspn.c strstr.c
-SRCS+= memmove.s strchr.s strrchr.s
+SRCS+= memmove.S strchr.S strrchr.S
.elif (${MACHINE} == "tahoe")
SRCS+= bcmp.s bcopy.s bzero.s ffs.s index.c memchr.c memcmp.s memset.c \
rindex.c strcat.s strcmp.s strcpy.s strcspn.c strlen.s \
@@ -33,7 +33,9 @@ SRCS+= memmove.s strchr.s strrchr.s
# if no machine specific memmove(3), build one out of bcopy(3).
.if empty(SRCS:Mmemcpy.s)
+.if empty(SRCS:Mmemcpy.S)
.if empty(SRCS:Mmemmove.s)
+.if empty(SRCS:Mmemmove.S)
OBJS+= memmove.o
memmove.o: bcopy.c
${CC} -DMEMMOVE ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET}
@@ -46,9 +48,12 @@ memmove.po: bcopy.c
@mv a.out ${.TARGET}
.endif
.endif
+.endif
+.endif
# if no machine specific strchr(3), build one out of index(3).
.if empty(SRCS:Mstrchr.s)
+.if empty(SRCS:Mstrchr.S)
OBJS+= strchr.o
strchr.o: index.c
${CC} -DSTRCHR ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET}
@@ -60,9 +65,11 @@ strchr.po: index.c
@${LD} -X -r ${.TARGET}
@mv a.out ${.TARGET}
.endif
+.endif
# if no machine specific strrchr(3), build one out of rindex(3).
.if empty(SRCS:Mstrrchr.s)
+.if empty(SRCS:Mstrrchr.S)
OBJS+= strrchr.o
strrchr.o: rindex.c
${CC} -DSTRRCHR ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET}
@@ -74,6 +81,7 @@ strrchr.po: rindex.c
@${LD} -X -r ${.TARGET}
@mv a.out ${.TARGET}
.endif
+.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 \
diff --git a/lib/libc/string/bzero.3 b/lib/libc/string/bzero.3
index f3fadba8d929..6f6acb65b1f0 100644
--- a/lib/libc/string/bzero.3
+++ b/lib/libc/string/bzero.3
@@ -35,7 +35,7 @@
.\"
.Dd April 19, 1991
.Dt BZERO 3
-.Os BDS 4.3
+.Os BSD 4.3
.Sh NAME
.Nm bzero
.Nd write zeroes to a byte string
diff --git a/lib/libc/string/ffs.3 b/lib/libc/string/ffs.3
index 53ed88af0b3c..482b13b77fad 100644
--- a/lib/libc/string/ffs.3
+++ b/lib/libc/string/ffs.3
@@ -46,7 +46,7 @@
.Sh DESCRIPTION
The
.Fn ffs
-fucntion
+function
finds the first bit set in
.Fa value
and returns the index of that bit.
diff --git a/lib/libc/string/strchr.3 b/lib/libc/string/strchr.3
index 1e53b530c1d4..34744d94882b 100644
--- a/lib/libc/string/strchr.3
+++ b/lib/libc/string/strchr.3
@@ -48,7 +48,7 @@
.Sh DESCRIPTION
The
.Fn strchr
-function locates the first occurence of
+function locates the first occurrence of
.Ar c
in the string pointed to by
.Ar s .
diff --git a/lib/libc/string/strsep.3 b/lib/libc/string/strsep.3
index 0901722d49f2..a4283ff849c0 100644
--- a/lib/libc/string/strsep.3
+++ b/lib/libc/string/strsep.3
@@ -48,7 +48,7 @@ The
.Fn strsep
locates in the null-terminated string at
.Fa *stringp
-the first occurence of any character in
+the first occurrence of any character in
.Fa delim
and replaces this with a
.Ql \e0 ,
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index e138dce490e9..3deb3bbcc702 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -4,9 +4,9 @@
.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
+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
# modules with default implementations on all architectures:
ASM= accept.o access.o acct.o adjtime.o async_daemon.o bind.o chdir.o \
@@ -19,51 +19,66 @@ ASM= accept.o access.o acct.o adjtime.o async_daemon.o bind.o chdir.o \
getpriority.o getrlimit.o getrusage.o getsockname.o getsockopt.o \
gettimeofday.o getuid.o ioctl.o kill.o ktrace.o link.o listen.o \
lseek.o lstat.o madvise.o mincore.o mkdir.o mkfifo.o mknod.o \
- mmap.o mount.o mprotect.o msync.o munmap.o nfssvc.o open.o \
+ mmap.o mount.o mprotect.o msgsys.o msync.o munmap.o nfssvc.o open.o \
profil.o quotactl.o read.o readlink.o readv.o recvfrom.o recvmsg.o \
- rename.o revoke.o rmdir.o select.o sendmsg.o sendto.o setdomainname.o \
- setegid.o seteuid.o setgid.o setgroups.o sethostid.o sethostname.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 sigstack.o socket.o socketpair.o stat.o \
- statfs.o swapon.o symlink.o sync.o truncate.o umask.o uname.o unlink.o \
- unmount.o utimes.o vadvise.o wait4.o write.o writev.o
+ rename.o revoke.o rmdir.o select.o semsys.o sendmsg.o sendto.o \
+ setdomainname.o setegid.o seteuid.o setgid.o setgroups.o sethostid.o \
+ sethostname.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 sigstack.o socket.o socketpair.o \
+ stat.o statfs.o swapon.o symlink.o sync.o sysarch.o truncate.o \
+ umask.o uname.o unlink.o unmount.o utimes.o vadvise.o vm_allocate.o \
+ vm_deallocate.o vm_inherit.o vm_protect.o wait4.o write.o writev.o
-PSEUDO= _exit.o _getlogin.o
PASM= ${ASM:.o=.po}
+SASM= ${ASM:.o=.so}
+
+PSEUDO= _exit.o _getlogin.o
PPSEUDO= ${PSEUDO:.o=.po}
+SPSEUDO= ${PSEUDO:.o=.so}
OBJS+= ${ASM} ${PSEUDO}
POBJS+= ${PASM} ${PPSEUDO}
+SOBJS+= ${SASM} ${SPSEUDO}
${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
+# @${LD} -x -r ${.PREFIX}.o
+# @mv a.out ${.PREFIX}.o
${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
+# @${LD} -x -r ${.PREFIX}.po
+# @mv a.out ${.PREFIX}.po
+
+${SASM}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h
+ @echo creating ${.TARGET}
+ @printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' | \
+ ${CPP} -DPIC ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -k -o ${.TARGET}
${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
+# @${LD} -x -r ${.PREFIX}.o
+# @mv a.out ${.PREFIX}.o
${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
+# @${LD} -x -r ${.PREFIX}.po
+# @mv a.out ${.PREFIX}.po
+
+${SPSEUDO}: ${.CURDIR}/${MACHINE}/SYS.h /usr/include/sys/syscall.h
+ @echo creating ${.TARGET}
+ @printf '#include "SYS.h"\nPSEUDO(${.PREFIX},${.PREFIX:S/_//})\n' | \
+ ${CPP} -DPIC ${CFLAGS:M-[ID]*} ${AINC} | ${AS} -k -o ${.TARGET}
MAN2+= sys/accept.2 sys/access.2 sys/acct.2 sys/adjtime.2 sys/async_daemon.2 \
sys/bind.2 sys/brk.2 sys/chdir.2 sys/chflags.2 sys/chmod.2 sys/chown.2 \
@@ -81,12 +96,12 @@ MAN2+= sys/accept.2 sys/access.2 sys/acct.2 sys/adjtime.2 sys/async_daemon.2 \
sys/msync.2 sys/munmap.2 sys/nfssvc.2 sys/open.2 sys/pipe.2 \
sys/quotactl.2 sys/read.2 sys/readlink.2 sys/reboot.2 sys/recv.2 \
sys/rename.2 sys/rmdir.2 sys/select.2 sys/send.2 sys/setgroups.2 \
- sys/setpgid.2 sys/setregid.2 sys/setreuid.2 sys/shutdown.2 \
- sys/sigaction.2 sys/sigprocmask.2 sys/sigreturn.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/uname.2 sys/unlink.2 sys/utimes.2 \
- sys/vfork.2 sys/wait.2 sys/write.2
+ sys/setpgid.2 sys/setregid.2 sys/setreuid.2 sys/setsid.2 \
+ sys/shutdown.2 sys/sigaction.2 sys/sigprocmask.2 sys/sigreturn.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/uname.2 sys/unlink.2 \
+ sys/utimes.2 sys/vfork.2 sys/wait.2 sys/write.2
MLINKS+=brk.2 sbrk.2
MLINKS+=dup.2 dup2.2
@@ -112,6 +127,7 @@ MLINKS+=mount.2 unmount.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+=stat.2 fstat.2 stat.2 lstat.2
MLINKS+=statfs.2 fstatfs.2
MLINKS+=truncate.2 ftruncate.2
diff --git a/lib/libc/sys/accept.2 b/lib/libc/sys/accept.2
index 6a0feb356069..5f257776166d 100644
--- a/lib/libc/sys/accept.2
+++ b/lib/libc/sys/accept.2
@@ -110,7 +110,7 @@ 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 desciptor, and rejection can be implied by closing the
+file descriptor, and rejection can be implied by closing the
new socket.
.Pp
One can obtain user connection request data without confirming
diff --git a/lib/libc/sys/acct.2 b/lib/libc/sys/acct.2
index 0a36e7be149c..42cb1eb7c83c 100644
--- a/lib/libc/sys/acct.2
+++ b/lib/libc/sys/acct.2
@@ -112,4 +112,5 @@ An I/O error occurred while reading from or writing to the file system.
.Sh HISTORY
An
.Nm
-function call appeared in Version 7 AT&T UNIX.
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/brk.2 b/lib/libc/sys/brk.2
index 79cf8cd74c51..d580b6aea757 100644
--- a/lib/libc/sys/brk.2
+++ b/lib/libc/sys/brk.2
@@ -40,10 +40,10 @@
.Nd change data segment size
.Sh SYNOPSIS
.Fd #include <sys/types.h>
-.Ft char
-.Fn *brk "const char *addr"
+.Ft int
+.Fn brk "const char *addr"
.Ft char *
-.Fn *sbrk "int incr"
+.Fn sbrk "int incr"
.Sh DESCRIPTION
.Bf -symbolic
The brk and sbrk functions are historical curiosities
@@ -107,8 +107,7 @@ returns 0 if successful; -1 if the process requests more memory than
than allowed by the system limit.
The
.Nm sbrk
-function returns 0 if successful, otherwise the error
-.Er EOPNOTSUPP
+function returns the old break value if successful, otherwise a -1
is returned.
.\" .Sh ERRORS
.\" .Xr Sbrk
@@ -141,4 +140,5 @@ the data segment without consulting
.Sh HISTORY
A
.Nm
-function call appeared in Version 7 AT&T UNIX.
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/chown.2 b/lib/libc/sys/chown.2
index 257e1d09b2ba..4eca4f5248f9 100644
--- a/lib/libc/sys/chown.2
+++ b/lib/libc/sys/chown.2
@@ -65,7 +65,7 @@ capability is restricted to the super-user.
.Fn Chown
clears the set-user-id and set-group-id bits
on the file
-to prevent accidental or mischievious creation of
+to prevent accidental or mischievous creation of
set-user-id and set-group-id programs.
.Pp
.Fn Fchown
diff --git a/lib/libc/sys/close.2 b/lib/libc/sys/close.2
index 8400214dbac3..16ca1dc3725d 100644
--- a/lib/libc/sys/close.2
+++ b/lib/libc/sys/close.2
@@ -64,7 +64,7 @@ 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 quanitity of file descriptors are being handled.
+is useful when a large quantity of file descriptors are being handled.
.Pp
When a process forks (see
.Xr fork 2 ) ,
@@ -103,7 +103,7 @@ will fail if:
.Fa D
is not an active descriptor.
.It Bq Er EINTR
-An interupt was received.
+An interrupt was received.
.El
.Sh SEE ALSO
.Xr accept 2 ,
diff --git a/lib/libc/sys/execve.2 b/lib/libc/sys/execve.2
index 63cda1443b46..726de1f88448 100644
--- a/lib/libc/sys/execve.2
+++ b/lib/libc/sys/execve.2
@@ -29,18 +29,19 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)execve.2 6.9 (Berkeley) 3/10/91
+.\" From: @(#)execve.2 6.9 (Berkeley) 3/10/91
+.\" $Id: execve.2,v 1.2.2.1 1994/05/01 16:06:05 jkh Exp $
.\"
-.Dd March 10, 1991
+.Dd March 16, 1994
.Dt EXECVE 2
-.Os BSD 4
+.Os
.Sh NAME
.Nm execve
.Nd execute a file
.Sh SYNOPSIS
.Fd #include <unistd.h>
.Ft int
-.Fn execve "const char *path" "const * char *argv" "const * char *envp"
+.Fn execve "const char *path" "char *const *argv" "char *const *envp"
.Sh DESCRIPTION
.Fn Execve
transforms the calling process into a new process.
@@ -134,6 +135,15 @@ of the new process image file.
The real user ID, real group ID and
supplementary group IDs of the new process image remain the same as the calling
process image.
+In either case, the
+.Dv SUGID
+process flag bit is set, and remains set until
+cleared by another call to
+.Nm
+which does not execute a set-id executable. This flag can be inspected
+by the
+.Xr ps 1
+utility.
.Pp
The new process also inherits the following attributes from
the calling process:
@@ -224,10 +234,10 @@ is allowed by the imposed maximum
.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
+The limit in the system as released is 32768 bytes
+.Pf ( Dv ARG_MAX
in
-.Ao Pa sys/param.h Ac ) .
+.Ao Pa limits.h Ac ) .
.It Bq Er EFAULT
The new process file is not as long as indicated by
the size values in its header.
@@ -250,6 +260,7 @@ the real
is ``root'', then the program has some of the powers
of a super-user as well.
.Sh SEE ALSO
+.Xr ps 1 ,
.Xr exit 2 ,
.Xr fork 2 ,
.Xr execl 3 ,
diff --git a/lib/libc/sys/fork.2 b/lib/libc/sys/fork.2
index 8c16ae7eda11..8b4419a4612c 100644
--- a/lib/libc/sys/fork.2
+++ b/lib/libc/sys/fork.2
@@ -104,4 +104,5 @@ There is insufficient swap space for the new process.
.Sh HISTORY
A
.Nm
-function call appeared in Version 6 AT&T UNIX.
+function call appeared in
+.At v6 .
diff --git a/lib/libc/sys/getsockopt.2 b/lib/libc/sys/getsockopt.2
index ceab2b6abe11..8f075a80af2f 100644
--- a/lib/libc/sys/getsockopt.2
+++ b/lib/libc/sys/getsockopt.2
@@ -207,7 +207,7 @@ to the appropriate network interface according to the network portion
of the destination address.
.Pp
.Dv SO_LINGER
-controls the action taken when unsent messags
+controls the action taken when unsent messages
are queued on socket and a
.Xr close 2
is performed.
diff --git a/lib/libc/sys/intro.2 b/lib/libc/sys/intro.2
index a05db39f4bc3..ca29ec5333b8 100644
--- a/lib/libc/sys/intro.2
+++ b/lib/libc/sys/intro.2
@@ -93,7 +93,7 @@ or
.Dv SIGQUIT )
was caught by the process during the execution of an interruptible
function. If the signal handler performs a normal return, the
-interupted function call will seem to have returned the error condition.
+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 not be reported until a subsequent operation on the same file
@@ -376,7 +376,7 @@ 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 occured.
+other catastrophic event occurred.
.It Er 72 EBADRPC Em "RPC struct is bad" .
Exchange of
.Tn RPC
diff --git a/lib/libc/sys/ioctl.2 b/lib/libc/sys/ioctl.2
index a90d0b8e9380..9e16641afe89 100644
--- a/lib/libc/sys/ioctl.2
+++ b/lib/libc/sys/ioctl.2
@@ -103,4 +103,5 @@ is not valid.
.Sh HISTORY
An
.Nm
-function call appeared in Version 7 AT&T UNIX.
+function call appeared in
+.At v7 .
diff --git a/lib/libc/sys/kill.2 b/lib/libc/sys/kill.2
index bdb553d96eb6..4f16c45c226d 100644
--- a/lib/libc/sys/kill.2
+++ b/lib/libc/sys/kill.2
@@ -62,7 +62,7 @@ This can be used to check the validity of
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 receving process must match
+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
diff --git a/lib/libc/sys/ktrace.2 b/lib/libc/sys/ktrace.2
new file mode 100644
index 000000000000..81d5b95f3bf2
--- /dev/null
+++ b/lib/libc/sys/ktrace.2
@@ -0,0 +1,66 @@
+.\" Copyright (c) 1983 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (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 1.0 (Berkeley) 1/4/94
+.\"
+.Dd Jan 4, 1994
+.Dt KTRACE 2
+.Os BSD 4.3
+.Sh NAME
+.Nm ktrace
+.Nd kernel call trace
+.Sh SYNOPSIS
+.Fd #include <sys/ktrace.h>
+.Ft int
+.Fn ktrace "const char *file" "int op" "int flag" "pid_t pid"
+.Sh DESCRIPTION
+.Fn Ktrace
+enables kernel trace logging for the specified processes.
+Kernel trace data is logged to the file
+.Pa file .
+The kernel operations that are traced include system calls, namei
+translations, signal processing, and
+.Tn I/O .
+
+needs to be written.
+.Sh RETURN VALUES
+needs to be written.
+.Sh ERRORS
+.Fn Ktrace
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EACCESS
+.It Bq Er EPERM
+.It Bq Er EINVAL
+.It Bq Er ESRCH
+The pid doesn't exist.
+.Sh SEE ALSO
+.Xr ktrace 1
diff --git a/lib/libc/sys/lseek.2 b/lib/libc/sys/lseek.2
index f6d8e88425c1..53db4c32da4a 100644
--- a/lib/libc/sys/lseek.2
+++ b/lib/libc/sys/lseek.2
@@ -92,7 +92,7 @@ The
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 actualy written into the gap).
+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.
@@ -100,7 +100,7 @@ associated with such a device is undefined.
Upon successful completion,
.Fn lseek
returns the resulting offset location as measured in bytes from the
-begining of the file.
+beginning of the file.
Otherwise,
a value of -1 is returned and
.Va errno
diff --git a/lib/libc/sys/mknod.2 b/lib/libc/sys/mknod.2
index edd5926863ce..da8e870ea188 100644
--- a/lib/libc/sys/mknod.2
+++ b/lib/libc/sys/mknod.2
@@ -124,4 +124,5 @@ points outside the process's allocated address space.
.Sh HISTORY
A
.Nm
-function call appeared in Version 6 AT&T UNIX.
+function call appeared in
+.At v6 .
diff --git a/lib/libc/sys/mount.2 b/lib/libc/sys/mount.2
index d830f5f8b924..1c32a25957cf 100644
--- a/lib/libc/sys/mount.2
+++ b/lib/libc/sys/mount.2
@@ -314,4 +314,5 @@ Some of the error codes need translation to more obvious messages.
.Fn Mount
and
.Fn umount
-function calls appeared in Version 6 AT&T UNIX.
+function calls appeared in
+.At v6 .
diff --git a/lib/libc/sys/open.2 b/lib/libc/sys/open.2
index 21160c688b1a..b2234a37cc2d 100644
--- a/lib/libc/sys/open.2
+++ b/lib/libc/sys/open.2
@@ -251,4 +251,5 @@ An attempt was made to open a socket (not currently implemented).
.Sh HISTORY
An
.Nm
-function call appeared in Version 6 AT&T UNIX.
+function call appeared in
+.At v6 .
diff --git a/lib/libc/sys/pipe.2 b/lib/libc/sys/pipe.2
index a34cd34ee817..8844fe5caf90 100644
--- a/lib/libc/sys/pipe.2
+++ b/lib/libc/sys/pipe.2
@@ -112,4 +112,5 @@ space.
.Sh HISTORY
A
.Nm
-function call appeared in Version 6 AT&T UNIX.
+function call appeared in
+.At v6 .
diff --git a/lib/libc/sys/read.2 b/lib/libc/sys/read.2
index e96a27329242..9bea77c73f76 100644
--- a/lib/libc/sys/read.2
+++ b/lib/libc/sys/read.2
@@ -185,4 +185,4 @@ A
.Nm read
function call
appeared in
-Version 6 AT&T UNIX.
+.At v6 .
diff --git a/lib/libc/sys/setpgid.2 b/lib/libc/sys/setpgid.2
index cdf4fcca418c..8d2592de1025 100644
--- a/lib/libc/sys/setpgid.2
+++ b/lib/libc/sys/setpgid.2
@@ -32,7 +32,7 @@
.\" @(#)setpgid.2 6.3 (Berkeley) 3/10/91
.\"
.Dd March 10, 1991
-.Dt SETPGRP 2
+.Dt SETPGID 2
.Os BSD 4
.Sh NAME
.Nm setpgid ,
diff --git a/lib/libc/sys/setregid.2 b/lib/libc/sys/setregid.2
index 70a368ee5172..86b0aa7949be 100644
--- a/lib/libc/sys/setregid.2
+++ b/lib/libc/sys/setregid.2
@@ -29,11 +29,12 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)setregid.2 6.4 (Berkeley) 3/10/91
+.\" From: @(#)setregid.2 6.4 (Berkeley) 3/10/91
+.\" $Id: setregid.2,v 1.1.1.1.2.1 1994/05/01 16:06:13 jkh Exp $
.\"
-.Dd March 10, 1991
+.Dd March 16, 1994
.Dt SETREGID 2
-.Os BSD 4.2
+.Os
.Sh NAME
.Nm setregid
.Nd set real and effective group ID
@@ -42,15 +43,42 @@
.Ft int
.Fn setregid "int rgid" "int 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.
+NB: In
+.Fx 1.0.2
+and earlier versions, this function would set the real and effective
+group ID's of the current process according to the arguments. In
+.Fx 1.1 ,
+we have adopted the behavior of
+.Bx 4.4 .
.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.
+The
+.Nm
+function is normally used by programs which wish to temporarily
+renounce special privileges they have gained (usually as a result of
+being set-gid executables), by swapping real and effective
+group ID's, so that the renunciation is reversible.
+This can result in a security hole, and does not integrate well with
+the
+.Tn POSIX
+saved group ID. In
+.Fx 1.1 ,
+the
+.Nm
+function will never actually set the real group ID; however, it will
+check its value to ensure that a future
+.Xr setegid 2
+call with the
+.Fa rgid
+argument will succeed.
+.Pp
+If
+.Fa rgid
+or
+.Fa egid
+is -1, the current ID is filled in by the system.
+The effective group ID is set, if requested, as if
+.Xr setegid 2
+had been called.
.Sh RETURN VALUES
Upon successful completion, a value of 0 is returned. Otherwise,
a value of -1 is returned and
diff --git a/lib/libc/sys/setreuid.2 b/lib/libc/sys/setreuid.2
index 061141ef278a..de34b029ab57 100644
--- a/lib/libc/sys/setreuid.2
+++ b/lib/libc/sys/setreuid.2
@@ -29,11 +29,12 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)setreuid.2 6.4 (Berkeley) 3/10/91
+.\" From: @(#)setreuid.2 6.4 (Berkeley) 3/10/91
+.\" $Id: setreuid.2,v 1.1.1.1.2.1 1994/05/01 16:06:14 jkh Exp $
.\"
-.Dd March 10, 1991
+.Dd March 16, 1994
.Dt SETREUID 2
-.Os BSD 4
+.Os
.Sh NAME
.Nm setreuid
.Nd set real and effective user ID's
@@ -42,16 +43,42 @@
.Ft int
.Fn setreuid "int ruid" "int euid"
.Sh DESCRIPTION
-The real and effective user ID's of the
-current process are set according to the arguments.
+Note: In
+.Fx 1.0.2
+and earlier versions, this function would set the real and effective
+user ID's of the current process according to the arguments. In
+.Fx 1.1
+we have adopted the behavior of
+.Bx 4.4 .
+.Pp
+The
+.Nm
+function is normally used by programs which wish to temporarily
+renounce special privileges they have gained (usually as a result of
+being set-uid executables), by swapping real and effective
+user ID's, so that the renunciation is reversible.
+This can result in a security hole, and does not integrate well with
+the
+.Tn POSIX
+saved user ID. In
+.Fx 1.1 ,
+the
+.Nm
+function will never actually set the real user ID; however, it will
+check its value to ensure that a future
+.Xr seteuid 2
+call with the
+.Fa ruid
+argument will succeed.
+.Pp
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.
+is -1, the current ID is filled in by the system.
+The effective user ID is set, if requested, as if
+.Xr seteuid 2
+had been called.
.Sh RETURN VALUES
Upon successful completion, a value of 0 is returned. Otherwise,
a value of -1 is returned and
diff --git a/lib/libc/sys/setsid.2 b/lib/libc/sys/setsid.2
new file mode 100644
index 000000000000..b4ff4db9a961
--- /dev/null
+++ b/lib/libc/sys/setsid.2
@@ -0,0 +1,67 @@
+.\" Copyright (c) 1994 Christoph M. Robitschko
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Christoph M. Robitschko
+.\" 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.
+.Dd January 28, 1994
+.Dt SETSID 2
+.Os FreeBSD
+.Sh NAME
+.Nm setsid
+.Nd create session and set process group ID
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Ft pid_t
+.Fn setsid
+.Sh DESCRIPTION
+If the calling process is not a process group leader, the
+.Fn setsid
+function creates a new session and a new process group.
+The calling process is the session leader and process group leader, and
+has no controlling terminal.
+The ID of the process group is set to the process ID of the calling process.
+The calling process is the only member of the new session and of the new
+process group.
+.Sh RETURN VALUES
+.Fn Setsid
+returns the value of the new process group ID when the operation was successful.
+If the request failed, -1 is returned and the global variable
+.Va errno
+indicates the reason.
+.Sh ERRORS
+.Fn Setsid
+will fail if:
+.Bl -tag -width indent
+.It Bq Er EPERM
+The calling process is already a process group leader, or the process group ID
+of another process matches the process ID of the calling process.
+.El
+.Sh SEE ALSO
+.Xr getpid 2 ,
+.Xr setpgid 2
+.Sh STANDARDS
+.Fn Setpgid
+conforms to IEEE Std 1003.1-1988
+.Pq Dq Tn POSIX .
diff --git a/lib/libc/sys/sigaction.2 b/lib/libc/sys/sigaction.2
index 13c2c5020e58..635512126614 100644
--- a/lib/libc/sys/sigaction.2
+++ b/lib/libc/sys/sigaction.2
@@ -49,7 +49,7 @@ struct sigaction {
.Fn sigaction "int sig" "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 occurence of a hardware interrupt:
+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
diff --git a/lib/libc/sys/sigsuspend.2 b/lib/libc/sys/sigsuspend.2
index f4167dc9784b..8e0c73001c10 100644
--- a/lib/libc/sys/sigsuspend.2
+++ b/lib/libc/sys/sigsuspend.2
@@ -36,7 +36,7 @@
.Os
.Sh NAME
.Nm sigsuspend
-.Nd atomically release blocked signals and wait for interrupt
+.Nd automatically release blocked signals and wait for interrupt
.Sh SYNOPSIS
.Fd #include <sys/signal.h>
.Ft int
diff --git a/lib/libc/sys/socket.2 b/lib/libc/sys/socket.2
index 48427b4a9459..6738badd82d1 100644
--- a/lib/libc/sys/socket.2
+++ b/lib/libc/sys/socket.2
@@ -56,11 +56,11 @@ These families are defined in the include file
The currently understood formats are
.Pp
.Bd -literal -offset indent -compact
-AF_UNIX (UNIX internal protocols),
+AF_UNIX (operating-system internal protocols),
AF_INET (ARPA Internet protocols),
AF_ISO (ISO protocols),
AF_NS (Xerox Network Systems protocols), and
-AF_IMPLINK (IMP \*(lqhost at IMP\*(rq link layer).
+AF_CCITT (ITU-T X.25 protocols).
.Ed
.Pp
The socket has the indicated
diff --git a/lib/libc/sys/stat.2 b/lib/libc/sys/stat.2
index 8509716aef41..b99b79e46123 100644
--- a/lib/libc/sys/stat.2
+++ b/lib/libc/sys/stat.2
@@ -55,7 +55,7 @@ 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 seachable.
+listed in the path name leading to the file must be searchable.
.Pp
.Fn Lstat
is like
@@ -91,7 +91,7 @@ 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 */
+ nlink_t st_nlink; /* number of 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 */
diff --git a/lib/libc/sys/statfs.2 b/lib/libc/sys/statfs.2
index 8a870878e250..4433e56152f9 100644
--- a/lib/libc/sys/statfs.2
+++ b/lib/libc/sys/statfs.2
@@ -79,7 +79,10 @@ char f_mntfromname[MNAMELEN]; /* mounted filesystem */
#define MOUNT_UFS 1
#define MOUNT_NFS 2
#define MOUNT_MFS 3
-#define MOUNT_PC 4
+#define MOUNT_MSDOS 4
+#define MOUNT_ISOFS 5
+#define MOUNT_PROCFS 6
+#define MOUNT_DEVFS 7
.Ed
.Pp
Fields that are undefined for a particular file system are set to -1.
diff --git a/lib/libc/sys/sync.2 b/lib/libc/sys/sync.2
index dd945e528415..02be22148dbd 100644
--- a/lib/libc/sys/sync.2
+++ b/lib/libc/sys/sync.2
@@ -70,4 +70,5 @@ may return before the buffers are completely flushed.
.Sh HISTORY
A
.Nm
-function call appeared in Version 6 AT&T UNIX.
+function call appeared in
+.At v6 .
diff --git a/lib/libc/sys/uname.2 b/lib/libc/sys/uname.2
index 4097375188ed..bb4c7edcd41f 100644
--- a/lib/libc/sys/uname.2
+++ b/lib/libc/sys/uname.2
@@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" from: @(#)uname.2 6.6 (Berkeley) 3/10/91
-.\" $Id: uname.2,v 1.1 1993/10/08 01:06:55 jkh Exp $
+.\" $Id: uname.2,v 1.2 1994/02/03 00:51:14 wollman Exp $
.\"
.Dd March 29, 1993
.Dt UNAME 2
@@ -43,8 +43,10 @@
.Ft int
.Fn uname "struct utsname *name"
.Sh DESCRIPTION
-.Fn Uname
-returns the information identifying the current UNIX system
+The
+.Fn uname
+function
+returns the information identifying the current operating system
in the structure pointed to by
.Fa name.
.Pp
@@ -62,25 +64,33 @@ struct utsname {
};
.Ed
.Pp
-.Fn Uname
+The
+.Fn uname
+function
returns a null-terminated character string naming the
-current UNIX system in the character array
+current operating system in the character array
.Fa sysname .
Similarly,
.Fa nodename
contains the name that the system is known by on a
communication network.
-.Fa Release
+The
+.Fa release
and
.Fa version
+fields
further identify the operating system.
-.Fa Machine
+The
+.Fa machine
+field
contains the standard name that identifies the hardware
-that the UNIX system is running on.
+that the operating system is running on.
.Sn ERRORS
.Bl -tag -width ENAMETOOLONGAA
.It Bq Er EFAULT
-.Fn Uname
+The
+.Fn uname
+function
will fail if
.Fa name
points to an invalid address.
@@ -97,4 +107,4 @@ is set to indicate the error.
The
.Nm uname
function call appeared in
-System V.2 AT&T UNIX.
+.At V.2 .
diff --git a/lib/libc/sys/unlink.2 b/lib/libc/sys/unlink.2
index 304b284c1935..668c2814086b 100644
--- a/lib/libc/sys/unlink.2
+++ b/lib/libc/sys/unlink.2
@@ -108,4 +108,5 @@ points outside the process's allocated address space.
.Sh HISTORY
An
.Nm
-function call appeared in Version 6 AT&T UNIX.
+function call appeared in
+.At v6 .
diff --git a/lib/libc/sys/wait.2 b/lib/libc/sys/wait.2
index b5a2a7cd11c5..004872f9b2ab 100644
--- a/lib/libc/sys/wait.2
+++ b/lib/libc/sys/wait.2
@@ -39,7 +39,7 @@
.Nm waitpid ,
.Nm wait4 ,
.Nm wait3
-.Nd wait for process terminatation
+.Nd wait for process termination
.Sh SYNOPSIS
.Fd #include <sys/types.h>
.Fd #include <sys/wait.h>
@@ -72,7 +72,7 @@ The
.Fn wait4
call provides a more general interface for programs
that need to wait for certain child processes,
-that need resource utilization statistics accummulated by child processes,
+that need resource utilization statistics accumulated by child processes,
or that require options.
The other wait functions are implemented using
.Fn wait4 .
@@ -292,4 +292,5 @@ call are extensions to the POSIX interface.
.Sh HISTORY
A
.Nm
-function call appeared in Version 6 AT&T UNIX.
+function call appeared in
+.At v6 .
diff --git a/lib/libc/sys/write.2 b/lib/libc/sys/write.2
index f7d1f0533917..4b00e3d21079 100644
--- a/lib/libc/sys/write.2
+++ b/lib/libc/sys/write.2
@@ -200,4 +200,4 @@ A
.Nm write
function call
appeared in
-Version 6 AT&T UNIX.
+.At v6 .
diff --git a/lib/libc/yp/Makefile.inc b/lib/libc/yp/Makefile.inc
new file mode 100644
index 000000000000..c3d565f5a35f
--- /dev/null
+++ b/lib/libc/yp/Makefile.inc
@@ -0,0 +1,8 @@
+# from: @(#)Makefile.inc 5.3 (Berkeley) 2/20/91
+# $Id: Makefile.inc,v 1.1 1993/11/01 23:56:27 paul Exp $
+
+# yp sources
+.PATH: ${.CURDIR}/arch/${MACHINE}/yp ${.CURDIR}/yp
+
+SRCS+= xdryp.c yplib.c
+
diff --git a/lib/libc/yp/xdryp.c b/lib/libc/yp/xdryp.c
new file mode 100644
index 000000000000..ba2d8d0749c0
--- /dev/null
+++ b/lib/libc/yp/xdryp.c
@@ -0,0 +1,394 @@
+/*
+ * 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.1 1993/11/01 23:56:28 paul Exp $";
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+
+extern int (*ypresp_allfn)();
+extern void *ypresp_data;
+
+struct ypresp_all {
+ bool_t more;
+ union {
+ struct ypresp_key_val val;
+ } ypresp_all_u;
+};
+
+bool_t
+xdr_domainname(xdrs, objp)
+XDR *xdrs;
+char *objp;
+{
+ if (!xdr_string(xdrs, &objp, YPMAXDOMAIN)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_peername(xdrs, objp)
+XDR *xdrs;
+char *objp;
+{
+ if (!xdr_string(xdrs, &objp, YPMAXPEER)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+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_mapname(xdrs, objp)
+XDR *xdrs;
+char *objp;
+{
+ if (!xdr_string(xdrs, &objp, YPMAXMAP)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypreq_key(xdrs, objp)
+XDR *xdrs;
+struct ypreq_key *objp;
+{
+ if (!xdr_domainname(xdrs, objp->domain)) {
+ return (FALSE);
+ }
+ if (!xdr_mapname(xdrs, objp->map)) {
+ return (FALSE);
+ }
+ if (!xdr_datum(xdrs, &objp->keydat)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypreq_nokey(xdrs, objp)
+XDR *xdrs;
+struct ypreq_nokey *objp;
+{
+ if (!xdr_domainname(xdrs, objp->domain)) {
+ return (FALSE);
+ }
+ if (!xdr_mapname(xdrs, objp->map)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_yp_inaddr(xdrs, objp)
+XDR *xdrs;
+struct in_addr *objp;
+{
+ if (!xdr_opaque(xdrs, (caddr_t)&objp->s_addr, sizeof objp->s_addr)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypbind_binding(xdrs, objp)
+XDR *xdrs;
+struct ypbind_binding *objp;
+{
+ if (!xdr_yp_inaddr(xdrs, &objp->ypbind_binding_addr)) {
+ return (FALSE);
+ }
+ if (!xdr_opaque(xdrs, (void *)&objp->ypbind_binding_port,
+ sizeof objp->ypbind_binding_port)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypbind_resptype(xdrs, objp)
+XDR *xdrs;
+enum ypbind_resptype *objp;
+{
+ if (!xdr_enum(xdrs, (enum_t *)objp)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypstat(xdrs, objp)
+XDR *xdrs;
+enum ypbind_resptype *objp;
+{
+ if (!xdr_enum(xdrs, (enum_t *)objp)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypbind_resp(xdrs, objp)
+XDR *xdrs;
+struct ypbind_resp *objp;
+{
+ if (!xdr_ypbind_resptype(xdrs, &objp->ypbind_status)) {
+ return (FALSE);
+ }
+ switch (objp->ypbind_status) {
+ case YPBIND_FAIL_VAL:
+ if (!xdr_u_int(xdrs, (u_int *)&objp->ypbind_respbody.ypbind_error)) {
+ return (FALSE);
+ }
+ break;
+ case YPBIND_SUCC_VAL:
+ if (!xdr_ypbind_binding(xdrs, &objp->ypbind_respbody.ypbind_bindinfo)) {
+ return (FALSE);
+ }
+ break;
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypresp_val(xdrs, objp)
+XDR *xdrs;
+struct ypresp_val *objp;
+{
+ if (!xdr_ypstat(xdrs, &objp->status)) {
+ return (FALSE);
+ }
+ if (!xdr_datum(xdrs, &objp->valdat)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypbind_setdom(xdrs, objp)
+XDR *xdrs;
+struct ypbind_setdom *objp;
+{
+ if (!xdr_domainname(xdrs, objp->ypsetdom_domain)) {
+ return (FALSE);
+ }
+ if (!xdr_ypbind_binding(xdrs, &objp->ypsetdom_binding)) {
+ return (FALSE);
+ }
+ if (!xdr_u_short(xdrs, &objp->ypsetdom_vers)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypresp_key_val(xdrs, objp)
+XDR *xdrs;
+struct ypresp_key_val *objp;
+{
+ if (!xdr_ypstat(xdrs, &objp->status)) {
+ return (FALSE);
+ }
+ if (!xdr_datum(xdrs, &objp->valdat)) {
+ return (FALSE);
+ }
+ if (!xdr_datum(xdrs, &objp->keydat)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypresp_all(xdrs, objp)
+XDR *xdrs;
+struct ypresp_all *objp;
+{
+ if (!xdr_bool(xdrs, &objp->more)) {
+ return (FALSE);
+ }
+ switch (objp->more) {
+ case TRUE:
+ if (!xdr_ypresp_key_val(xdrs, &objp->ypresp_all_u.val)) {
+ return (FALSE);
+ }
+ break;
+ case FALSE:
+ break;
+ default:
+ 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.status;
+ switch(status) {
+ case YP_TRUE:
+ key = (char *)malloc(out.ypresp_all_u.val.keydat.dsize + 1);
+ bcopy(out.ypresp_all_u.val.keydat.dptr, key,
+ out.ypresp_all_u.val.keydat.dsize);
+ key[out.ypresp_all_u.val.keydat.dsize] = '\0';
+ val = (char *)malloc(out.ypresp_all_u.val.valdat.dsize + 1);
+ bcopy(out.ypresp_all_u.val.valdat.dptr, val,
+ out.ypresp_all_u.val.valdat.dsize);
+ val[out.ypresp_all_u.val.valdat.dsize] = '\0';
+ xdr_free(xdr_ypresp_all, (char *)&out);
+
+ r = (*ypresp_allfn)(status,
+ key, out.ypresp_all_u.val.keydat.dsize,
+ val, out.ypresp_all_u.val.valdat.dsize,
+ 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;
+ }
+ }
+}
+
+bool_t
+xdr_ypresp_master(xdrs, objp)
+XDR *xdrs;
+struct ypresp_master *objp;
+{
+ if (!xdr_ypstat(xdrs, &objp->status)) {
+ return (FALSE);
+ }
+ if (!xdr_string(xdrs, &objp->master, YPMAXPEER)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypmaplist_str(xdrs, objp)
+XDR *xdrs;
+char *objp;
+{
+ if (!xdr_string(xdrs, &objp, YPMAXMAP+1)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypmaplist(xdrs, objp)
+XDR *xdrs;
+struct ypmaplist *objp;
+{
+ if (!xdr_ypmaplist_str(xdrs, objp->ypml_name)) {
+ return (FALSE);
+ }
+ if (!xdr_pointer(xdrs, (caddr_t *)&objp->ypml_next,
+ sizeof(struct ypmaplist), xdr_ypmaplist)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypresp_maplist(xdrs, objp)
+XDR *xdrs;
+struct ypresp_maplist *objp;
+{
+ if (!xdr_ypstat(xdrs, &objp->status)) {
+ return (FALSE);
+ }
+ if (!xdr_pointer(xdrs, (caddr_t *)&objp->list,
+ sizeof(struct ypmaplist), xdr_ypmaplist)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+bool_t
+xdr_ypresp_order(xdrs, objp)
+XDR *xdrs;
+struct ypresp_order *objp;
+{
+ if (!xdr_ypstat(xdrs, &objp->status)) {
+ return (FALSE);
+ }
+ if (!xdr_u_long(xdrs, &objp->ordernum)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
diff --git a/lib/libc/yp/yplib.c b/lib/libc/yp/yplib.c
new file mode 100644
index 000000000000..57f1df09cc96
--- /dev/null
+++ b/lib/libc/yp/yplib.c
@@ -0,0 +1,794 @@
+/*
+ * 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.2 1994/01/11 19:01:09 nate 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 <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+
+#ifndef BINDINGDIR
+#define BINDINGDIR "/var/yp/binding"
+#endif
+#define YPMATCHCACHE
+
+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
+
+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, fd, gpid;
+ CLIENT *client;
+ int new=0, r;
+
+ 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;
+ }
+again:
+#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. */
+ if(new)
+ free(ysd);
+ return YPERR_YPBIND;
+ }
+ 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 =
+ ybr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr;
+ ysd->dom_server_addr.sin_port =
+ ybr.ypbind_respbody.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. */
+ close(fd);
+ if(new)
+ free(ysd);
+ return YPERR_YPBIND;
+ }
+ }
+#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;
+ tv.tv_usec = 0;
+ r = clnt_call(client, YPBINDPROC_DOMAIN,
+ xdr_domainname, dom, xdr_ypbind_resp, &ypbr, tv);
+ if(r != RPC_SUCCESS) {
+ fprintf(stderr,
+ "YP: server for domain %s not responding, still trying\n", dom);
+ clnt_destroy(client);
+ ysd->dom_vers = -1;
+ 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 =
+ ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_port;
+ ysd->dom_server_addr.sin_addr.s_addr =
+ ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr.s_addr;
+ ysd->dom_server_port =
+ ypbr.ypbind_respbody.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;
+
+again:
+ if( _yp_dobind(indomain, &ysd) != 0)
+ return YPERR_DOMAIN;
+
+#ifdef YPMATCHCACHE
+ if( !strcmp(_yp_domain, indomain) && ypmatch_find(inmap, inkey,
+ inkeylen, &yprv.valdat.dptr, &yprv.valdat.dsize)) {
+ *outvallen = yprv.valdat.dsize;
+ *outval = (char *)malloc(*outvallen+1);
+ bcopy(yprv.valdat.dptr, *outval, *outvallen);
+ (*outval)[*outvallen] = '\0';
+ return 0;
+ }
+#endif
+
+ tv.tv_sec = _yplib_timeout;
+ tv.tv_usec = 0;
+
+ yprk.domain = indomain;
+ yprk.map = inmap;
+ yprk.keydat.dptr = (char *)inkey;
+ yprk.keydat.dsize = 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.status)) ) {
+ *outvallen = yprv.valdat.dsize;
+ *outval = (char *)malloc(*outvallen+1);
+ bcopy(yprv.valdat.dptr, *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;
+
+ *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 = -1;
+ goto again;
+ }
+ if( !(r=ypprot_err(yprkv.status)) ) {
+ *outkeylen = yprkv.keydat.dsize;
+ *outkey = (char *)malloc(*outkeylen+1);
+ bcopy(yprkv.keydat.dptr, *outkey, *outkeylen);
+ (*outkey)[*outkeylen] = '\0';
+ *outvallen = yprkv.valdat.dsize;
+ *outval = (char *)malloc(*outvallen+1);
+ bcopy(yprkv.valdat.dptr, *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;
+
+ *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.keydat.dptr = inkey;
+ yprk.keydat.dsize = 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.status)) ) {
+ *outkeylen = yprkv.keydat.dsize;
+ *outkey = (char *)malloc(*outkeylen+1);
+ bcopy(yprkv.keydat.dptr, *outkey, *outkeylen);
+ (*outkey)[*outkeylen] = '\0';
+ *outvallen = yprkv.valdat.dsize;
+ *outval = (char *)malloc(*outvallen+1);
+ bcopy(yprkv.valdat.dptr, *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;
+
+ 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;
+
+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.status);
+}
+
+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;
+
+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.status)) ) {
+ *outname = (char *)strdup(yprm.master);
+ }
+ xdr_free(xdr_ypresp_master, (char *)&yprm);
+ _yp_unbind(ysd);
+ return r;
+}
+
+yp_maplist(indomain, outmaplist)
+char *indomain;
+struct ypmaplist **outmaplist;
+{
+ struct dom_binding *ysd;
+ struct ypresp_maplist ypml;
+ struct timeval tv;
+ int r;
+
+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, 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.list;
+ /* NO: xdr_free(xdr_ypresp_maplist, &ypml);*/
+ _yp_unbind(ysd);
+ return ypprot_err(ypml.status);
+}
+
+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_NODOM;
+ 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;
+{
+ int use_yp = 0;
+ 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 )
+ return 1;
+ return 0;
+}