My initial commit message
authormcc <mcc@duce.noddleisland.org>
Thu, 19 Oct 2017 16:18:32 +0000 (16:18 +0000)
committermcc <mcc@duce.noddleisland.org>
Thu, 19 Oct 2017 16:18:32 +0000 (16:18 +0000)
791 files changed:
DISCLAIMER [new file with mode: 0644]
Make.defines.in [new file with mode: 0644]
Makefile.in [new file with mode: 0644]
README.md [new file with mode: 0644]
VERSION [new file with mode: 0644]
aclocal.m4 [new file with mode: 0644]
advio/Makefile [new file with mode: 0644]
advio/daytimetcpcli.c [new file with mode: 0644]
advio/daytimeudpcli3.c [new file with mode: 0644]
advio/daytimeudpcli4.c [new file with mode: 0644]
advio/dgclitimeo.c [new file with mode: 0644]
advio/dgclitimeo1.c [new file with mode: 0644]
advio/dgclitimeo2.c [new file with mode: 0644]
advio/dgclitimeo2.lc [new file with mode: 0644]
advio/dgclitimeo3.c [new file with mode: 0644]
advio/dgclitimeo3.lc [new file with mode: 0644]
advio/dgechoaddr.c [new file with mode: 0644]
advio/dgechoaddr.lc [new file with mode: 0644]
advio/old/dgechoaddr.c [new file with mode: 0644]
advio/old/recvfromflags.c [new file with mode: 0644]
advio/old/test01.c [new file with mode: 0644]
advio/recvfromflags.c [new file with mode: 0644]
advio/recvfromflags.lc [new file with mode: 0644]
advio/script.1 [new file with mode: 0644]
advio/sig_chld_waitpid.c [new file with mode: 0644]
advio/str_cli_kqueue04.c [new file with mode: 0644]
advio/str_cli_poll03.c [new file with mode: 0644]
advio/str_cli_select02.c [new file with mode: 0644]
advio/str_echo_stdio02.c [new file with mode: 0644]
advio/str_echo_stdio02.lc [new file with mode: 0644]
advio/tcpcli01.c [new file with mode: 0644]
advio/tcpcli02.c [new file with mode: 0644]
advio/tcpcli03.c [new file with mode: 0644]
advio/tcpcli04.c [new file with mode: 0644]
advio/tcpserv02.c [new file with mode: 0644]
advio/udpcli01.c [new file with mode: 0644]
advio/udpcli02.c [new file with mode: 0644]
advio/udpcli03.c [new file with mode: 0644]
advio/udpserv01.c [new file with mode: 0644]
advio/udpserv03.c [new file with mode: 0644]
advio/udpserv03.lc [new file with mode: 0644]
advio/udpserv04.c [new file with mode: 0644]
advio/udpserv04.lc [new file with mode: 0644]
bcast/Makefile [new file with mode: 0644]
bcast/dgclibcast1.c [new file with mode: 0644]
bcast/dgclibcast1.lc [new file with mode: 0644]
bcast/dgclibcast2.c [new file with mode: 0644]
bcast/dgclibcast3.c [new file with mode: 0644]
bcast/dgclibcast3.lc [new file with mode: 0644]
bcast/dgclibcast4.c [new file with mode: 0644]
bcast/dgclibcast4.lc [new file with mode: 0644]
bcast/dgclibcast5.c [new file with mode: 0644]
bcast/dgclibcast5.lc [new file with mode: 0644]
bcast/dgclibcast6.c [new file with mode: 0644]
bcast/dgclibcast6.lc [new file with mode: 0644]
bcast/udpcli01.c [new file with mode: 0644]
bcast/udpcli02.c [new file with mode: 0644]
bcast/udpcli03.c [new file with mode: 0644]
bcast/udpcli04.c [new file with mode: 0644]
bcast/udpcli05.c [new file with mode: 0644]
bcast/udpcli06.c [new file with mode: 0644]
config.guess [new file with mode: 0755]
config.h.in [new file with mode: 0644]
config.sub [new file with mode: 0755]
configure [new file with mode: 0755]
configure.in [new file with mode: 0644]
debug/Makefile [new file with mode: 0644]
debug/backlog.c [new file with mode: 0644]
debug/backlog.lc [new file with mode: 0644]
debug/qlen.c [new file with mode: 0644]
debug/qlen.lc [new file with mode: 0644]
debug/test01.c [new file with mode: 0644]
debug/test01.lc [new file with mode: 0644]
debug/test02.c [new file with mode: 0644]
debug/test03.c [new file with mode: 0644]
debug/test04.c [new file with mode: 0644]
debug/test05.c [new file with mode: 0644]
debug/test06.c [new file with mode: 0644]
debug/unpxti.h [new file with mode: 0644]
icmpd/Makefile [new file with mode: 0644]
icmpd/dgcli01.c [new file with mode: 0644]
icmpd/dgcli01.lc [new file with mode: 0644]
icmpd/icmpd.c [new file with mode: 0644]
icmpd/icmpd.h [new file with mode: 0644]
icmpd/icmpd.lc [new file with mode: 0644]
icmpd/readable_conn.c [new file with mode: 0644]
icmpd/readable_conn.lc [new file with mode: 0644]
icmpd/readable_listen.c [new file with mode: 0644]
icmpd/readable_listen.lc [new file with mode: 0644]
icmpd/readable_v4.c [new file with mode: 0644]
icmpd/readable_v4.lc [new file with mode: 0644]
icmpd/readable_v6.c [new file with mode: 0644]
icmpd/readable_v6.lc [new file with mode: 0644]
icmpd/script.1 [new file with mode: 0644]
icmpd/script.2 [new file with mode: 0644]
icmpd/script.3 [new file with mode: 0644]
icmpd/script.4 [new file with mode: 0644]
icmpd/udpcli01.c [new file with mode: 0644]
icmpd/unpicmpd.h [new file with mode: 0644]
inetd/Makefile [new file with mode: 0644]
inetd/daytimetcpsrv2.c [new file with mode: 0644]
inetd/daytimetcpsrv3.c [new file with mode: 0644]
inetd/daytimetcpsrv3.lc [new file with mode: 0644]
install-sh [new file with mode: 0755]
intro/Makefile [new file with mode: 0644]
intro/byteorder.c [new file with mode: 0644]
intro/daytimetcpcli.c [new file with mode: 0644]
intro/daytimetcpcli1.c [new file with mode: 0644]
intro/daytimetcpcli2.c [new file with mode: 0644]
intro/daytimetcpcli3.c [new file with mode: 0644]
intro/daytimetcpcliv6.c [new file with mode: 0644]
intro/daytimetcpsrv.c [new file with mode: 0644]
intro/daytimetcpsrv.lc [new file with mode: 0644]
intro/daytimetcpsrv1.c [new file with mode: 0644]
intro/daytimetcpsrv2.c [new file with mode: 0644]
intro/daytimetcpsrv3.c [new file with mode: 0644]
intro/daytimetcpsrvv6.c [new file with mode: 0644]
intro/truss.solaris.2.6 [new file with mode: 0644]
intro/truss.unixware.2.1 [new file with mode: 0644]
ioctl/Makefile [new file with mode: 0644]
ioctl/Progs.siocgifconf [new file with mode: 0644]
ioctl/Script.solaris [new file with mode: 0644]
ioctl/lsif01.c [new file with mode: 0644]
ioctl/lsif02.c [new file with mode: 0644]
ioctl/prifinfo.c [new file with mode: 0644]
ioctl/prifinfo.lc [new file with mode: 0644]
ioctl/prmac.c [new file with mode: 0644]
ioctl/test1.c [new file with mode: 0644]
ipopts/Makefile [new file with mode: 0644]
ipopts/dgechoprintroute.c [new file with mode: 0644]
ipopts/sigchldwaitpid.c [new file with mode: 0644]
ipopts/sourceroute.c [new file with mode: 0644]
ipopts/sourceroute.lc [new file with mode: 0644]
ipopts/sourceroute6.c [new file with mode: 0644]
ipopts/tcpcli01.c [new file with mode: 0644]
ipopts/tcpserv01.c [new file with mode: 0644]
ipopts/udpcli01.c [new file with mode: 0644]
ipopts/udpserv01.c [new file with mode: 0644]
key/Makefile [new file with mode: 0644]
key/add.c [new file with mode: 0644]
key/dump.c [new file with mode: 0644]
key/name.c [new file with mode: 0644]
key/printsadbmsg.c [new file with mode: 0644]
key/register.c [new file with mode: 0644]
key/unp.h [new file with mode: 0644]
lib/Makefile [new file with mode: 0644]
lib/addrinfo.h [new file with mode: 0644]
lib/connect_nonb.c [new file with mode: 0644]
lib/connect_nonb.lc [new file with mode: 0644]
lib/connect_timeo.c [new file with mode: 0644]
lib/connect_timeo.lc [new file with mode: 0644]
lib/daemon_inetd.c [new file with mode: 0644]
lib/daemon_inetd.lc [new file with mode: 0644]
lib/daemon_init.c [new file with mode: 0644]
lib/dg_cli.c [new file with mode: 0644]
lib/dg_echo.c [new file with mode: 0644]
lib/error.c [new file with mode: 0644]
lib/family_to_level.c [new file with mode: 0644]
lib/get_ifi_info.c [new file with mode: 0644]
lib/get_ifi_info.lc [new file with mode: 0644]
lib/gf_time.c [new file with mode: 0644]
lib/host_serv.c [new file with mode: 0644]
lib/host_serv.lc [new file with mode: 0644]
lib/hstrerror.c [new file with mode: 0644]
lib/if_indextoname.c [new file with mode: 0644]
lib/if_nameindex.c [new file with mode: 0644]
lib/if_nametoindex.c [new file with mode: 0644]
lib/in6addr_any.c [new file with mode: 0644]
lib/mcast_get_if.c [new file with mode: 0644]
lib/mcast_get_loop.c [new file with mode: 0644]
lib/mcast_get_ttl.c [new file with mode: 0644]
lib/mcast_join.c [new file with mode: 0644]
lib/mcast_join.lc [new file with mode: 0644]
lib/mcast_leave.c [new file with mode: 0644]
lib/mcast_set_if.c [new file with mode: 0644]
lib/mcast_set_loop.c [new file with mode: 0644]
lib/mcast_set_loop.lc [new file with mode: 0644]
lib/mcast_set_ttl.c [new file with mode: 0644]
lib/my_addrs.c [new file with mode: 0644]
lib/my_addrs.lc [new file with mode: 0644]
lib/pselect.c [new file with mode: 0644]
lib/pselect.lc [new file with mode: 0644]
lib/read_fd.c [new file with mode: 0644]
lib/read_fd.lc [new file with mode: 0644]
lib/readable_timeo.c [new file with mode: 0644]
lib/readable_timeo.lc [new file with mode: 0644]
lib/readline.c [new file with mode: 0644]
lib/readline.lc [new file with mode: 0644]
lib/readn.c [new file with mode: 0644]
lib/readn.lc [new file with mode: 0644]
lib/rtt.c [new file with mode: 0644]
lib/rtt.lc [new file with mode: 0644]
lib/signal.c [new file with mode: 0644]
lib/signal.lc [new file with mode: 0644]
lib/signal_intr.c [new file with mode: 0644]
lib/snprintf.c [new file with mode: 0644]
lib/sock_bind_wild.c [new file with mode: 0644]
lib/sock_cmp_addr.c [new file with mode: 0644]
lib/sock_cmp_port.c [new file with mode: 0644]
lib/sock_get_port.c [new file with mode: 0644]
lib/sock_ntop.c [new file with mode: 0644]
lib/sock_ntop.lc [new file with mode: 0644]
lib/sock_ntop_host.c [new file with mode: 0644]
lib/sock_set_addr.c [new file with mode: 0644]
lib/sock_set_port.c [new file with mode: 0644]
lib/sock_set_wild.c [new file with mode: 0644]
lib/sockatmark.c [new file with mode: 0644]
lib/sockfd_to_family.c [new file with mode: 0644]
lib/sockfd_to_family.lc [new file with mode: 0644]
lib/str_cli.c [new file with mode: 0644]
lib/str_cli.lc [new file with mode: 0644]
lib/str_echo.c [new file with mode: 0644]
lib/str_echo.lc [new file with mode: 0644]
lib/tcp_connect.c [new file with mode: 0644]
lib/tcp_connect.lc [new file with mode: 0644]
lib/tcp_listen.c [new file with mode: 0644]
lib/tcp_listen.lc [new file with mode: 0644]
lib/tv_sub.c [new file with mode: 0644]
lib/udp_client.c [new file with mode: 0644]
lib/udp_client.lc [new file with mode: 0644]
lib/udp_connect.c [new file with mode: 0644]
lib/udp_connect.lc [new file with mode: 0644]
lib/udp_server.c [new file with mode: 0644]
lib/udp_server.lc [new file with mode: 0644]
lib/unp.h [new file with mode: 0644]
lib/unp.lh [new file with mode: 0644]
lib/unpifi.h [new file with mode: 0644]
lib/unprtt.h [new file with mode: 0644]
lib/unprtt.lh [new file with mode: 0644]
lib/unpthread.h [new file with mode: 0644]
lib/wraplib.c [new file with mode: 0644]
lib/wrappthread.c [new file with mode: 0644]
lib/wrappthread.lc [new file with mode: 0644]
lib/wrapsock.c [new file with mode: 0644]
lib/wrapsock.lc [new file with mode: 0644]
lib/wrapstdio.c [new file with mode: 0644]
lib/wrapunix.c [new file with mode: 0644]
lib/writable_timeo.c [new file with mode: 0644]
lib/write_fd.c [new file with mode: 0644]
lib/write_fd.lc [new file with mode: 0644]
lib/writen.c [new file with mode: 0644]
lib/writen.lc [new file with mode: 0644]
libfree/Make.tar [new file with mode: 0755]
libfree/Makefile [new file with mode: 0644]
libfree/README [new file with mode: 0644]
libfree/README.getaddrinfo [new file with mode: 0644]
libfree/addrinfo.h [new file with mode: 0644]
libfree/getaddrinfo.c [new file with mode: 0644]
libfree/getnameinfo.c [new file with mode: 0644]
libfree/in_cksum.c [new file with mode: 0644]
libfree/inet_aton.c [new file with mode: 0644]
libfree/inet_ntop.c [new file with mode: 0644]
libfree/inet_ntop_ipv4.c [new file with mode: 0644]
libfree/inet_ntop_ipv4.lc [new file with mode: 0644]
libfree/inet_pton.c [new file with mode: 0644]
libfree/inet_pton_ipv4.c [new file with mode: 0644]
libfree/inet_pton_ipv4.lc [new file with mode: 0644]
libfree/test_ascii2addr.c [new file with mode: 0644]
libfree/test_getservbyname_r.c [new file with mode: 0644]
libfree/test_inet_pton.c [new file with mode: 0644]
libgai/Makefile [new file with mode: 0644]
libgai/addrinfo.h [new file with mode: 0644]
libgai/freeaddrinfo.c [new file with mode: 0644]
libgai/ga_aistruct.c [new file with mode: 0644]
libgai/ga_aistruct.lc [new file with mode: 0644]
libgai/ga_clone.c [new file with mode: 0644]
libgai/ga_clone.lc [new file with mode: 0644]
libgai/ga_echeck.c [new file with mode: 0644]
libgai/ga_echeck.lc [new file with mode: 0644]
libgai/ga_nsearch.c [new file with mode: 0644]
libgai/ga_nsearch.lc [new file with mode: 0644]
libgai/ga_port.c [new file with mode: 0644]
libgai/ga_port.lc [new file with mode: 0644]
libgai/ga_serv.c [new file with mode: 0644]
libgai/ga_serv.lc [new file with mode: 0644]
libgai/ga_unix.c [new file with mode: 0644]
libgai/ga_unix.lc [new file with mode: 0644]
libgai/gai_hdr.h [new file with mode: 0644]
libgai/gai_hdr.lh [new file with mode: 0644]
libgai/gai_strerror.c [new file with mode: 0644]
libgai/getaddrinfo.c [new file with mode: 0644]
libgai/getaddrinfo.lc [new file with mode: 0644]
libgai/getnameinfo.c [new file with mode: 0644]
libgai/getnameinfo.lc [new file with mode: 0644]
libgai/gn_ipv46.c [new file with mode: 0644]
libgai/gn_ipv46.lc [new file with mode: 0644]
libgai/old/ga_unixstruct.c [new file with mode: 0644]
libgai/old/savecopy.c [new file with mode: 0644]
libgai/test1.c [new file with mode: 0644]
libgai/testga.c [new file with mode: 0644]
libroute/Makefile [new file with mode: 0644]
libroute/get_rtaddrs.c [new file with mode: 0644]
libroute/get_rtaddrs.lc [new file with mode: 0644]
libroute/if_indextoname.c [new file with mode: 0644]
libroute/if_indextoname.lc [new file with mode: 0644]
libroute/if_nameindex.c [new file with mode: 0644]
libroute/if_nameindex.lc [new file with mode: 0644]
libroute/if_nametoindex.c [new file with mode: 0644]
libroute/if_nametoindex.lc [new file with mode: 0644]
libroute/net_rt_dump.c [new file with mode: 0644]
libroute/net_rt_iflist.c [new file with mode: 0644]
libroute/net_rt_iflist.lc [new file with mode: 0644]
libroute/sock_masktop.c [new file with mode: 0644]
libroute/unproute.h [new file with mode: 0644]
mcast/Makefile [new file with mode: 0644]
mcast/dgclibcast1.c [new file with mode: 0644]
mcast/dgclimcast5.c [new file with mode: 0644]
mcast/dgclimcast6.c [new file with mode: 0644]
mcast/main.c [new file with mode: 0644]
mcast/recv.c [new file with mode: 0644]
mcast/send.c [new file with mode: 0644]
mcast/udpcli01.c [new file with mode: 0644]
mcast/udpcli05.c [new file with mode: 0644]
mcast/udpcli06.c [new file with mode: 0644]
mcast/udpserv01.c [new file with mode: 0644]
mysdr/Makefile [new file with mode: 0644]
mysdr/loop.c [new file with mode: 0644]
mysdr/loop.lc [new file with mode: 0644]
mysdr/main.c [new file with mode: 0644]
mysdr/main.lc [new file with mode: 0644]
mysdr/mysdr.h [new file with mode: 0644]
mysdr/script.1 [new file with mode: 0644]
mysdr/script.2 [new file with mode: 0644]
names/Makefile [new file with mode: 0644]
names/daytimetcpcli.c [new file with mode: 0644]
names/daytimetcpcli1.c [new file with mode: 0644]
names/daytimetcpcli1.lc [new file with mode: 0644]
names/daytimetcpcli2.c [new file with mode: 0644]
names/daytimetcpcli2.lc [new file with mode: 0644]
names/daytimetcpcli3.c [new file with mode: 0644]
names/daytimetcpcli3.lc [new file with mode: 0644]
names/daytimetcpsrv1.c [new file with mode: 0644]
names/daytimetcpsrv2.c [new file with mode: 0644]
names/daytimetcpsrv3.c [new file with mode: 0644]
names/daytimetcpsrv4.c [new file with mode: 0644]
names/daytimeudpcli1.c [new file with mode: 0644]
names/daytimeudpcli1.lc [new file with mode: 0644]
names/daytimeudpcli2.c [new file with mode: 0644]
names/daytimeudpsrv2.c [new file with mode: 0644]
names/daytimeudpsrv3.c [new file with mode: 0644]
names/hostent.c [new file with mode: 0644]
names/hostent.lc [new file with mode: 0644]
names/hostent2.c [new file with mode: 0644]
names/hostent2.lc [new file with mode: 0644]
names/hostent3.c [new file with mode: 0644]
names/myaddrs1.c [new file with mode: 0644]
names/myaddrs1.lc [new file with mode: 0644]
names/netent.c [new file with mode: 0644]
names/prmyaddrs.c [new file with mode: 0644]
names/prmyaddrs1.c [new file with mode: 0644]
names/prmyaddrs1.lc [new file with mode: 0644]
names/test1.c [new file with mode: 0644]
names/test2.c [new file with mode: 0644]
names/udp_server_reuseaddr.c [new file with mode: 0644]
nonblock/Makefile [new file with mode: 0644]
nonblock/daytimetcpcli.c [new file with mode: 0644]
nonblock/doit.1 [new file with mode: 0755]
nonblock/home_page.c [new file with mode: 0644]
nonblock/script.1.sh [new file with mode: 0644]
nonblock/script.1.tcpd [new file with mode: 0644]
nonblock/start_connect.c [new file with mode: 0644]
nonblock/strclifork.c [new file with mode: 0644]
nonblock/strclinonb.c [new file with mode: 0644]
nonblock/strclinonb.lc [new file with mode: 0644]
nonblock/tcpcli01.c [new file with mode: 0644]
nonblock/tcpcli02.c [new file with mode: 0644]
nonblock/tcpcli03.c [new file with mode: 0644]
nonblock/tcpcli03.lc [new file with mode: 0644]
nonblock/tcpcli04.c [new file with mode: 0644]
nonblock/tcpservselect03.c [new file with mode: 0644]
nonblock/web.c [new file with mode: 0644]
nonblock/web.h [new file with mode: 0644]
nonblock/web.lc [new file with mode: 0644]
nonblock/write_get_cmd.c [new file with mode: 0644]
oob/Makefile [new file with mode: 0644]
oob/heartbeatcli.c [new file with mode: 0644]
oob/heartbeatserv.c [new file with mode: 0644]
oob/sigchldwaitpid.c [new file with mode: 0644]
oob/strcliselect02.c [new file with mode: 0644]
oob/strecho02.c [new file with mode: 0644]
oob/tcpcli02.c [new file with mode: 0644]
oob/tcprecv01.c [new file with mode: 0644]
oob/tcprecv01.lc [new file with mode: 0644]
oob/tcprecv02.c [new file with mode: 0644]
oob/tcprecv02.lc [new file with mode: 0644]
oob/tcprecv03.c [new file with mode: 0644]
oob/tcprecv03p.c [new file with mode: 0644]
oob/tcprecv03p.lc [new file with mode: 0644]
oob/tcprecv04.c [new file with mode: 0644]
oob/tcprecv04.lc [new file with mode: 0644]
oob/tcprecv05.c [new file with mode: 0644]
oob/tcprecv06.c [new file with mode: 0644]
oob/tcpsend01.c [new file with mode: 0644]
oob/tcpsend01.lc [new file with mode: 0644]
oob/tcpsend02.c [new file with mode: 0644]
oob/tcpsend03.c [new file with mode: 0644]
oob/tcpsend04.c [new file with mode: 0644]
oob/tcpsend04.lc [new file with mode: 0644]
oob/tcpsend05.c [new file with mode: 0644]
oob/tcpsend05.lc [new file with mode: 0644]
oob/tcpsend06.c [new file with mode: 0644]
oob/tcpsend06.lc [new file with mode: 0644]
oob/tcpserv02.c [new file with mode: 0644]
ping/Makefile [new file with mode: 0644]
ping/bsdping.c [new file with mode: 0644]
ping/init_v6.c [new file with mode: 0644]
ping/main.c [new file with mode: 0644]
ping/main.lc [new file with mode: 0644]
ping/old/icmp6.h [new file with mode: 0644]
ping/old/ip6.h [new file with mode: 0644]
ping/ping.h [new file with mode: 0644]
ping/ping_v4.c [new file with mode: 0644]
ping/proc_v4.c [new file with mode: 0644]
ping/proc_v4.lc [new file with mode: 0644]
ping/proc_v6.c [new file with mode: 0644]
ping/proc_v6.lc [new file with mode: 0644]
ping/readloop.c [new file with mode: 0644]
ping/send_v4.c [new file with mode: 0644]
ping/send_v6.c [new file with mode: 0644]
ping/sig_alrm.c [new file with mode: 0644]
ping/sig_alrm.lc [new file with mode: 0644]
ping/tv_sub.c [new file with mode: 0644]
route/Makefile [new file with mode: 0644]
route/checkudpsum.c [new file with mode: 0644]
route/get_ifi_info.c [new file with mode: 0644]
route/get_ifi_info.lc [new file with mode: 0644]
route/getrt.c [new file with mode: 0644]
route/getrt.lc [new file with mode: 0644]
route/mynetstat.c [new file with mode: 0644]
route/prifindex.c [new file with mode: 0644]
route/prifinfo.c [new file with mode: 0644]
route/prifname.c [new file with mode: 0644]
route/prifnameindex.c [new file with mode: 0644]
route/unproute.h [new file with mode: 0644]
rtt/Makefile [new file with mode: 0644]
rtt/dg_cli.c [new file with mode: 0644]
rtt/dg_cli.lc [new file with mode: 0644]
rtt/dg_echo.c [new file with mode: 0644]
rtt/dg_send_recv.c [new file with mode: 0644]
rtt/dg_send_recv.lc [new file with mode: 0644]
rtt/rtt.out.kumba.1 [new file with mode: 0644]
rtt/rtt.out.kumba.2 [new file with mode: 0644]
rtt/rtt.out.vangogh.1 [new file with mode: 0644]
rtt/rtt.out.vangogh.2 [new file with mode: 0644]
rtt/rtt.vals.kumba.1 [new file with mode: 0644]
rtt/rtt.vals.vangogh.1 [new file with mode: 0644]
rtt/udpcli01.c [new file with mode: 0644]
rtt/unprtt.h [new file with mode: 0644]
sctp/Makefile [new file with mode: 0644]
sctp/sctp_addr_to_associd.c [new file with mode: 0644]
sctp/sctp_addr_to_associd.lc [new file with mode: 0644]
sctp/sctp_bindargs.c [new file with mode: 0644]
sctp/sctp_bindargs.lc [new file with mode: 0644]
sctp/sctp_check_notify.c [new file with mode: 0644]
sctp/sctp_check_notify.lc [new file with mode: 0644]
sctp/sctp_displayevents.c [new file with mode: 0644]
sctp/sctp_displayevents.lc [new file with mode: 0644]
sctp/sctp_getnostrm.c [new file with mode: 0644]
sctp/sctp_modify_hb.c [new file with mode: 0644]
sctp/sctp_modify_hb.lc [new file with mode: 0644]
sctp/sctp_pdapircv.c [new file with mode: 0644]
sctp/sctp_pdapircv.lc [new file with mode: 0644]
sctp/sctp_print_addrs.c [new file with mode: 0644]
sctp/sctp_print_addrs.lc [new file with mode: 0644]
sctp/sctp_strcli.c [new file with mode: 0644]
sctp/sctp_strcli.lc [new file with mode: 0644]
sctp/sctp_strcli1.c [new file with mode: 0644]
sctp/sctp_strcli1.lc [new file with mode: 0644]
sctp/sctp_strcli_un.c [new file with mode: 0644]
sctp/sctp_strcli_un.lc [new file with mode: 0644]
sctp/sctp_strcliecho.c [new file with mode: 0644]
sctp/sctp_strcliecho.lc [new file with mode: 0644]
sctp/sctp_strcliecho2.c [new file with mode: 0644]
sctp/sctp_strcliecho2.lc [new file with mode: 0644]
sctp/sctp_wrapper.c [new file with mode: 0644]
sctp/sctpclient01.c [new file with mode: 0644]
sctp/sctpclient01.lc [new file with mode: 0644]
sctp/sctpclient02.c [new file with mode: 0644]
sctp/sctpclient02.lc [new file with mode: 0644]
sctp/sctpclient04.c [new file with mode: 0644]
sctp/sctpclient04.lc [new file with mode: 0644]
sctp/sctpserv01.c [new file with mode: 0644]
sctp/sctpserv01.lc [new file with mode: 0644]
sctp/sctpserv02.c [new file with mode: 0644]
sctp/sctpserv02.lc [new file with mode: 0644]
sctp/sctpserv03.c [new file with mode: 0644]
sctp/sctpserv03.lc [new file with mode: 0644]
sctp/sctpserv04.c [new file with mode: 0644]
sctp/sctpserv04.lc [new file with mode: 0644]
sctp/sctpserv05.c [new file with mode: 0644]
sctp/sctpserv05.lc [new file with mode: 0644]
sctp/sctpserv06.c [new file with mode: 0644]
sctp/sctpserv06.lc [new file with mode: 0644]
sctp/sctpserv07.c [new file with mode: 0644]
sctp/sctpserv07.lc [new file with mode: 0644]
sctp/sctpserv_fork.c [new file with mode: 0644]
sctp/sctpserv_fork.lc [new file with mode: 0644]
sctp/unp.h [new file with mode: 0644]
select/Makefile [new file with mode: 0644]
select/strcliselect01.c [new file with mode: 0644]
select/strcliselect02.c [new file with mode: 0644]
select/strcliselect02.lc [new file with mode: 0644]
select/tcpcli01.c [new file with mode: 0644]
select/tcpcli02.c [new file with mode: 0644]
select/tcpcli03.c [new file with mode: 0644]
server/Makefile [new file with mode: 0644]
server/child.h [new file with mode: 0644]
server/child.lh [new file with mode: 0644]
server/child02.c [new file with mode: 0644]
server/child02.lc [new file with mode: 0644]
server/child02l.c [new file with mode: 0644]
server/child02m.c [new file with mode: 0644]
server/child03.c [new file with mode: 0644]
server/child03m.c [new file with mode: 0644]
server/child04.c [new file with mode: 0644]
server/child05.c [new file with mode: 0644]
server/child05.lc [new file with mode: 0644]
server/client.c [new file with mode: 0644]
server/clientrst.c [new file with mode: 0644]
server/lock_fcntl.c [new file with mode: 0644]
server/lock_fcntl.lc [new file with mode: 0644]
server/lock_pthread.c [new file with mode: 0644]
server/lock_pthread.lc [new file with mode: 0644]
server/meter.c [new file with mode: 0644]
server/pr_cpu_time.c [new file with mode: 0644]
server/pthread07.c [new file with mode: 0644]
server/pthread07.h [new file with mode: 0644]
server/pthread07.lc [new file with mode: 0644]
server/pthread08.c [new file with mode: 0644]
server/pthread08.h [new file with mode: 0644]
server/pthread08.lc [new file with mode: 0644]
server/pthread09.c [new file with mode: 0644]
server/pthread09.h [new file with mode: 0644]
server/readline.c [new file with mode: 0644]
server/readline_r.c [new file with mode: 0644]
server/readline_r.h [new file with mode: 0644]
server/serv00.c [new file with mode: 0644]
server/serv01.c [new file with mode: 0644]
server/serv01.lc [new file with mode: 0644]
server/serv02.c [new file with mode: 0644]
server/serv02.lc [new file with mode: 0644]
server/serv02m.c [new file with mode: 0644]
server/serv03.c [new file with mode: 0644]
server/serv03m.c [new file with mode: 0644]
server/serv04.c [new file with mode: 0644]
server/serv05.c [new file with mode: 0644]
server/serv05.lc [new file with mode: 0644]
server/serv06.c [new file with mode: 0644]
server/serv06.lc [new file with mode: 0644]
server/serv07.c [new file with mode: 0644]
server/serv07.lc [new file with mode: 0644]
server/serv08.c [new file with mode: 0644]
server/serv08.lc [new file with mode: 0644]
server/serv09.c [new file with mode: 0644]
server/sig_chld_waitpid.c [new file with mode: 0644]
server/unpthread.h [new file with mode: 0644]
server/web_child.c [new file with mode: 0644]
server/web_child_r.c [new file with mode: 0644]
sigio/Makefile [new file with mode: 0644]
sigio/dgcli01.c [new file with mode: 0644]
sigio/dgecho01.c [new file with mode: 0644]
sigio/dgecho01.lc [new file with mode: 0644]
sigio/script.1 [new file with mode: 0755]
sigio/script.2 [new file with mode: 0755]
sigio/udpcli01.c [new file with mode: 0644]
sigio/udpserv01.c [new file with mode: 0644]
sock/Makefile [new file with mode: 0644]
sock/README [new file with mode: 0644]
sock/TODO [new file with mode: 0644]
sock/buffers.c [new file with mode: 0644]
sock/cliopen.c [new file with mode: 0644]
sock/crlf.c [new file with mode: 0644]
sock/error.c [new file with mode: 0644]
sock/loop.c [new file with mode: 0644]
sock/looptcp.c [new file with mode: 0644]
sock/loopudp.c [new file with mode: 0644]
sock/main.c [new file with mode: 0644]
sock/multicast.c [new file with mode: 0644]
sock/ourhdr.h [new file with mode: 0644]
sock/pattern.c [new file with mode: 0644]
sock/servopen.c [new file with mode: 0644]
sock/sinktcp.c [new file with mode: 0644]
sock/sinkudp.c [new file with mode: 0644]
sock/sleepus.c [new file with mode: 0644]
sock/sock.h [new file with mode: 0644]
sock/sock.in [new file with mode: 0644]
sock/sockopts.c [new file with mode: 0644]
sock/sourceroute.c [new file with mode: 0644]
sock/sourcesink.c [new file with mode: 0644]
sock/sourcetcp.c [new file with mode: 0644]
sock/sourceudp.c [new file with mode: 0644]
sock/strerror.c [new file with mode: 0644]
sock/tellwait.c [new file with mode: 0644]
sock/write.c [new file with mode: 0644]
sock/writen.c [new file with mode: 0644]
sockopt/Makefile [new file with mode: 0644]
sockopt/checkopts.c [new file with mode: 0644]
sockopt/checkopts.lc [new file with mode: 0644]
sockopt/prdefaults.c [new file with mode: 0644]
sockopt/rcvbuf.c [new file with mode: 0644]
sockopt/rcvbufset.c [new file with mode: 0644]
sockopt/sockopt.c [new file with mode: 0644]
sparc64-unknown-freebsd5.1/config.h [new file with mode: 0644]
ssntp/Makefile [new file with mode: 0644]
ssntp/main.c [new file with mode: 0644]
ssntp/main.lc [new file with mode: 0644]
ssntp/ntp.h [new file with mode: 0644]
ssntp/sntp.h [new file with mode: 0644]
ssntp/sntp_proc.c [new file with mode: 0644]
streams/Makefile [new file with mode: 0644]
streams/stream_dg/Makefile [new file with mode: 0644]
streams/stream_dg/client.c [new file with mode: 0644]
streams/stream_dg/net_stream.c [new file with mode: 0644]
streams/stream_dg/server.c [new file with mode: 0644]
streams/strlist_sock.c [new file with mode: 0644]
streams/strlist_xti.c [new file with mode: 0644]
streams/tpi_bind.c [new file with mode: 0644]
streams/tpi_close.c [new file with mode: 0644]
streams/tpi_close.lc [new file with mode: 0644]
streams/tpi_connect.c [new file with mode: 0644]
streams/tpi_connect.lc [new file with mode: 0644]
streams/tpi_daytime.c [new file with mode: 0644]
streams/tpi_daytime.h [new file with mode: 0644]
streams/tpi_read.c [new file with mode: 0644]
streams/tpi_read.lc [new file with mode: 0644]
streams/unpxti.h [new file with mode: 0644]
tcpcliserv/Makefile [new file with mode: 0644]
tcpcliserv/sigchldwait.c [new file with mode: 0644]
tcpcliserv/sigchldwait.lc [new file with mode: 0644]
tcpcliserv/sigchldwaitpid.c [new file with mode: 0644]
tcpcliserv/sigchldwaitpid.lc [new file with mode: 0644]
tcpcliserv/str_cli08.c [new file with mode: 0644]
tcpcliserv/str_cli09.c [new file with mode: 0644]
tcpcliserv/str_cli11.c [new file with mode: 0644]
tcpcliserv/str_cli11.lc [new file with mode: 0644]
tcpcliserv/str_echo08.c [new file with mode: 0644]
tcpcliserv/str_echo08.lc [new file with mode: 0644]
tcpcliserv/str_echo09.c [new file with mode: 0644]
tcpcliserv/sum.h [new file with mode: 0644]
tcpcliserv/tcpcli01.c [new file with mode: 0644]
tcpcliserv/tcpcli01.lc [new file with mode: 0644]
tcpcliserv/tcpcli04.c [new file with mode: 0644]
tcpcliserv/tcpcli05.c [new file with mode: 0644]
tcpcliserv/tcpcli06.c [new file with mode: 0644]
tcpcliserv/tcpcli07.c [new file with mode: 0644]
tcpcliserv/tcpcli08.c [new file with mode: 0644]
tcpcliserv/tcpcli09.c [new file with mode: 0644]
tcpcliserv/tcpcli10.c [new file with mode: 0644]
tcpcliserv/tcpcli11.c [new file with mode: 0644]
tcpcliserv/tcpserv01.c [new file with mode: 0644]
tcpcliserv/tcpserv01.lc [new file with mode: 0644]
tcpcliserv/tcpserv02.c [new file with mode: 0644]
tcpcliserv/tcpserv03.c [new file with mode: 0644]
tcpcliserv/tcpserv04.c [new file with mode: 0644]
tcpcliserv/tcpserv04.lc [new file with mode: 0644]
tcpcliserv/tcpserv08.c [new file with mode: 0644]
tcpcliserv/tcpserv09.c [new file with mode: 0644]
tcpcliserv/tcpservpoll01.c [new file with mode: 0644]
tcpcliserv/tcpservpoll01.lc [new file with mode: 0644]
tcpcliserv/tcpservselect01.c [new file with mode: 0644]
tcpcliserv/tcpservselect01.lc [new file with mode: 0644]
tcpcliserv/tsigpipe.c [new file with mode: 0644]
test/Makefile [new file with mode: 0644]
test/accept_eintr.c [new file with mode: 0644]
test/funcs.c [new file with mode: 0644]
test/readline.h [new file with mode: 0644]
test/readline1.c [new file with mode: 0644]
test/readline1.lc [new file with mode: 0644]
test/readline2.c [new file with mode: 0644]
test/readline3.c [new file with mode: 0644]
test/test.h [new file with mode: 0644]
test/test1.c [new file with mode: 0644]
test/test2.c [new file with mode: 0644]
test/tisfdtype.c [new file with mode: 0644]
test/treadline1.c [new file with mode: 0644]
test/treadline2.c [new file with mode: 0644]
test/treadline3.c [new file with mode: 0644]
test/tshutdown.c [new file with mode: 0644]
test/tsnprintf.c [new file with mode: 0644]
threads/Makefile [new file with mode: 0644]
threads/doit.1 [new file with mode: 0755]
threads/doit.2 [new file with mode: 0755]
threads/example01.c [new file with mode: 0644]
threads/example01.lc [new file with mode: 0644]
threads/example02.c [new file with mode: 0644]
threads/example02.lc [new file with mode: 0644]
threads/example03.c [new file with mode: 0644]
threads/readline.c [new file with mode: 0644]
threads/readline.lc [new file with mode: 0644]
threads/script.example01 [new file with mode: 0644]
threads/script.example02 [new file with mode: 0644]
threads/strclithread.c [new file with mode: 0644]
threads/strclithread.lc [new file with mode: 0644]
threads/strclithread2.c [new file with mode: 0644]
threads/tcpcli01.c [new file with mode: 0644]
threads/tcpcli02.c [new file with mode: 0644]
threads/tcpserv01.c [new file with mode: 0644]
threads/tcpserv02.c [new file with mode: 0644]
threads/test01.c [new file with mode: 0644]
threads/test02.c [new file with mode: 0644]
threads/test03.c [new file with mode: 0644]
threads/test04.c [new file with mode: 0644]
threads/test05.c [new file with mode: 0644]
threads/unpthread.h [new file with mode: 0644]
threads/web01.c [new file with mode: 0644]
threads/web01.lc [new file with mode: 0644]
threads/web02.c [new file with mode: 0644]
threads/web03.c [new file with mode: 0644]
threads/web03.lc [new file with mode: 0644]
traceroute/Makefile [new file with mode: 0644]
traceroute/icmpcode_v4.c [new file with mode: 0644]
traceroute/icmpcode_v6.c [new file with mode: 0644]
traceroute/main.c [new file with mode: 0644]
traceroute/main.lc [new file with mode: 0644]
traceroute/recv_v4.c [new file with mode: 0644]
traceroute/recv_v4.lc [new file with mode: 0644]
traceroute/recv_v6.c [new file with mode: 0644]
traceroute/recv_v6.lc [new file with mode: 0644]
traceroute/sig_alrm.c [new file with mode: 0644]
traceroute/trace.h [new file with mode: 0644]
traceroute/trace.lh [new file with mode: 0644]
traceroute/traceloop.c [new file with mode: 0644]
traceroute/traceloop.lc [new file with mode: 0644]
traceroute/tv_sub.c [new file with mode: 0644]
udpcksum/Makefile [new file with mode: 0644]
udpcksum/cleanup.c [new file with mode: 0644]
udpcksum/cleanup.lc [new file with mode: 0644]
udpcksum/main.c [new file with mode: 0644]
udpcksum/main.lc [new file with mode: 0644]
udpcksum/pcap.c [new file with mode: 0644]
udpcksum/pcap.lc [new file with mode: 0644]
udpcksum/senddnsquery-libnet.c [new file with mode: 0644]
udpcksum/senddnsquery-libnet.lc [new file with mode: 0644]
udpcksum/senddnsquery-raw.c [new file with mode: 0644]
udpcksum/senddnsquery-raw.lc [new file with mode: 0644]
udpcksum/udpcksum.c [new file with mode: 0644]
udpcksum/udpcksum.h [new file with mode: 0644]
udpcksum/udpcksum.lc [new file with mode: 0644]
udpcksum/udpread.c [new file with mode: 0644]
udpcksum/udpread.c.bad [new file with mode: 0644]
udpcksum/udpread.lc [new file with mode: 0644]
udpcksum/udpwrite.c [new file with mode: 0644]
udpcksum/udpwrite.lc [new file with mode: 0644]
udpcliserv/Makefile [new file with mode: 0644]
udpcliserv/dgcliaddr.c [new file with mode: 0644]
udpcliserv/dgclibig.c [new file with mode: 0644]
udpcliserv/dgclibig.lc [new file with mode: 0644]
udpcliserv/dgcliconnect.c [new file with mode: 0644]
udpcliserv/dgcliconnect.lc [new file with mode: 0644]
udpcliserv/dgcliinetaddr.c [new file with mode: 0644]
udpcliserv/dgcliloop1.c [new file with mode: 0644]
udpcliserv/dgcliloop3.c [new file with mode: 0644]
udpcliserv/dgecholoop1.c [new file with mode: 0644]
udpcliserv/dgecholoop2.c [new file with mode: 0644]
udpcliserv/dgecholoop2.lc [new file with mode: 0644]
udpcliserv/sigchldwaitpid.c [new file with mode: 0644]
udpcliserv/udpcli01.c [new file with mode: 0644]
udpcliserv/udpcli02.c [new file with mode: 0644]
udpcliserv/udpcli03.c [new file with mode: 0644]
udpcliserv/udpcli04.c [new file with mode: 0644]
udpcliserv/udpcli05.c [new file with mode: 0644]
udpcliserv/udpcli06.c [new file with mode: 0644]
udpcliserv/udpcli08.c [new file with mode: 0644]
udpcliserv/udpcli09.c [new file with mode: 0644]
udpcliserv/udpcli10.c [new file with mode: 0644]
udpcliserv/udpserv01.c [new file with mode: 0644]
udpcliserv/udpserv06.c [new file with mode: 0644]
udpcliserv/udpserv07.c [new file with mode: 0644]
udpcliserv/udpservselect01.c [new file with mode: 0644]
udpcliserv/udpservselect01.lc [new file with mode: 0644]
unixdomain/Makefile [new file with mode: 0644]
unixdomain/daytimetcpcli.c [new file with mode: 0644]
unixdomain/daytimetcpsrv2.c [new file with mode: 0644]
unixdomain/mycat.c [new file with mode: 0644]
unixdomain/mycat.lc [new file with mode: 0644]
unixdomain/myopen.c [new file with mode: 0644]
unixdomain/openfile.c [new file with mode: 0644]
unixdomain/readcred.c [new file with mode: 0644]
unixdomain/sigchldwaitpid.c [new file with mode: 0644]
unixdomain/strecho.c [new file with mode: 0644]
unixdomain/testfcred.c [new file with mode: 0644]
unixdomain/tfcred01.c [new file with mode: 0644]
unixdomain/unixbind.c [new file with mode: 0644]
unixdomain/unixbind.lc [new file with mode: 0644]
unixdomain/unixdgcli01.c [new file with mode: 0644]
unixdomain/unixdgcli01.lc [new file with mode: 0644]
unixdomain/unixdgserv01.c [new file with mode: 0644]
unixdomain/unixstrcli01.c [new file with mode: 0644]
unixdomain/unixstrserv01.c [new file with mode: 0644]
unixdomain/unixstrserv01.lc [new file with mode: 0644]
unixdomain/unixstrserv02.c [new file with mode: 0644]

diff --git a/DISCLAIMER b/DISCLAIMER
new file mode 100644 (file)
index 0000000..e24e4a8
--- /dev/null
@@ -0,0 +1,11 @@
+       LIMITS OF LIABILITY AND DISCLAIMER OF WARRANTY
+
+The authors and publisher of the book "UNIX Network Programming" have
+used their best efforts in preparing this software.  These efforts
+include the development, research, and testing of the theories and
+programs to determine their effectiveness.  The authors and publisher
+make no warranty of any kind, express or implied, with regard to
+these programs or the documentation contained in the book.  The authors
+and publisher shall not be liable in any event for incidental or
+consequential damages in connection with, or arising out of, the
+furnishing, performance, or use of these programs.
diff --git a/Make.defines.in b/Make.defines.in
new file mode 100644 (file)
index 0000000..ce542a9
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# This file is generated by autoconf from "Make.defines.in".
+#
+# This is the "Make.defines" file that almost every "Makefile" in the
+# source directories below this directory include.
+# The "../" in the pathnames actually refer to this directory, since
+# "make" is executed in all the subdirectories of this directory.
+#
+# System = @host@
+
+CC = @CC@
+CFLAGS = -I../lib @CFLAGS@
+LIBS = @LIBUNP@ @LIBS@
+LIBS_XTI = @LIBUNPXTI@ @LIBUNP@ @LIBS_XTI@
+RANLIB = @RANLIB@
+
+# Following is the main library, built from all the object files
+# in the lib/ and libfree/ directories.
+LIBUNP_NAME = @LIBUNP_NAME@
+
+# Following is the XTI library, built from all the object files
+# in the libxti/ directory.
+LIBUNPXTI_NAME = @LIBUNPXTI_NAME@
+
+# Following are all the object files to create in the lib/ directory.
+LIB_OBJS = @LIB_OBJS@
+
+# Following are all the object files to create in the libfree/ directory.
+LIBFREE_OBJS = @LIBFREE_OBJS@
+
+# Following are all the object files to create in the libgai/ directory.
+LIBGAI_OBJS = @LIBGAI_OBJS@
+
+# Following are all the object files to create in the libroute/ directory.
+LIBROUTE_OBJS = @LIBROUTE_OBJS@
+
+# Following are all the object files to create in the libxti/ directory.
+LIBXTI_OBJS = @LIBXTI_OBJS@
+
+CLEANFILES = core core.* *.core *.o temp.* *.out typescript* \
+               *.lc *.lh *.bsdi *.sparc *.uw
diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..452f73e
--- /dev/null
@@ -0,0 +1,11 @@
+include ./Make.defines
+
+all:
+       @echo "Nothing to make in this directory"
+       @echo "Please read the README file"
+
+clean:
+       rm -f $(CLEANFILES)
+distclean:
+       rm -f $(CLEANFILES) config.cache config.log config.status config.h Make.defines Makefile
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..b760854
--- /dev/null
+++ b/README.md
@@ -0,0 +1,115 @@
+QUICK AND DIRTY
+===============
+
+Execute the following from the src/ directory:
+
+    ./configure    # try to figure out all implementation differences
+
+    cd lib         # build the basic library that all programs need
+    make           # use "gmake" everywhere on BSD/OS systems
+
+    cd ../libfree  # continue building the basic library
+    make
+
+    cd ../libroute # only if your system supports 4.4BSD style routing sockets
+    make           # only if your system supports 4.4BSD style routing sockets
+
+    cd ../libxti   # only if your system supports XTI
+    make           # only if your system supports XTI
+
+    cd ../intro    # build and test a basic client program
+    make daytimetcpcli
+    ./daytimetcpcli 127.0.0.1
+
+If all that works, you're all set to start compiling individual programs.
+
+Notice that all the source code assumes tabs every 4 columns, not 8.
+
+MORE DETAILS
+============
+
+5.  If you need to make any changes to the "unp.h" header, notice that it
+    is a hard link in each directory, so you only need to change it once.
+
+6.  Go into the "lib/" directory and type "make".  This builds the library
+    "libunp.a" that is required by almost all of the programs.  There may
+    be compiler warnings (see NOTES below).  This step is where you'll find
+    all of your system's dependencies, and you must just update your cf/
+    files from step 1, rerun "config" and do this step again.
+
+6.  Go into the "libfree/" directory and type "make".  This adds to the
+    "libunp.a" library.  The files in this directory do not #include
+    the "unp.h" header, as people may want to use these functions
+    independent of the book's examples.
+
+8.  Once the library is made from steps 5 and 6, you can then go into any
+    of the source code directories and make whatever program you are
+    interested in.  Note that the horizontal rules at the beginning and
+    end of each program listing in the book contain the directory name and
+    filename.
+
+    BEWARE: Not all programs in each directory will compile on all systems
+    (e.g., the file src/advio/recvfromflags.c will not compile unless your
+    system supports the IP_RECVDSTADDR socket option).  Also, not all files
+    in each directory are included in the book.  Beware of any files with
+    "test" in the filename: they are probably a quick test program that I
+    wrote to check something, and may or may not work.
+
+NOTES
+-----
+
+- Many systems do not have correct function prototypes for the socket
+  functions, and this can cause many warnings during compilation.
+  For example, Solaris 2.5 omits the "const" from the 2nd argument
+  to connect().  Lots of systems use "int" for the length of socket
+  address structures, while Posix.1g specifies "size_t".  Lots of
+  systems still have the pointer argument to [sg]etsockopt() as a
+  "char *" instead of a "void *", and this also causes warnings.
+
+- SunOS 4.1.x: If you are using Sun's acc compiler, you need to run
+  the configure program as
+
+        CC=acc CFLAGS=-w CPPFLAGS=-w ./configure
+
+  Failure to do this results in numerous system headers (<sys/sockio.h>)
+  not being found during configuration, causing compile errors later.
+
+- If your system supports IPv6 and you want to run the examples in the
+  book using hostnames, you must install the latest BIND release.  You
+  can get it from ftp://ftp.vix.com/pub/bind/release.  All you need from
+  this release is a resolver library that you should then add to the
+  LDLIBS and LDLIBS_THREADS lines.
+
+- IPv6 support is still in its infancy.  There may be differences
+  between the IPv6 sockets API specifications and what the vendor
+  provides.  This may require hand tweaking, but should get better
+  over time.
+
+- If your system supports an older draft of the Posix pthreads standard,
+  but configure detects the support of pthreads, you will have to disable
+  this by hand.  Digital Unix V3.2C has this problem, for example, as it
+  supports draft 4, not the final draft.
+
+  To fix this, remove wrappthread.o from LIB_OBJS in "Make.defines" and
+  don't try to build and run any of the threads programs.
+
+COMMON DIFFERENCES
+------------------
+
+These are the common differences that I see in various headers that are
+not "yet" at the level of Posix.1g or X/Open XNS Issue 5.
+
+- getsockopt() and setsockopt(): 5th argument is not correct type.
+
+- t_bind(): second argument is missing "const".
+
+- t_connect(): second argument is missing "const".
+
+- t_open(): first argument is missing "const".
+
+- t_optmsmg(): second argument is missing "const".
+
+- If your <xti.h> defines the members of the t_opthdr{} as longs,
+  instead of t_uscalar_t, some of the printf formats of these value
+  might generate warnings from your compiler, since you are printing
+  a long without a corresponding long format specifier.
diff --git a/VERSION b/VERSION
new file mode 100644 (file)
index 0000000..021f875
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+2004/12/12
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644 (file)
index 0000000..2a62037
--- /dev/null
@@ -0,0 +1,213 @@
+dnl ##################################################################
+dnl Our macro to check for a function prototype in a given header.
+dnl
+AC_DEFUN(AC_CHECK_FUNC_PROTO,
+       [AC_CACHE_CHECK(for $1 function prototype in $2, ac_cv_have_$1_proto,
+               AC_EGREP_HEADER($1, $2,
+                       ac_cv_have_$1_proto=yes,
+                       ac_cv_have_$1_proto=no))
+       if test $ac_cv_have_$1_proto = yes ; then
+               ac_tr_func=HAVE_`echo $1 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO
+               AC_DEFINE_UNQUOTED($ac_tr_func)
+       fi
+])
+
+dnl ##################################################################
+dnl We cannot use the AC_CHECK_TYPE macros because AC_CHECK_TYPE
+dnl #includes only <sys/types.h>, <stdlib.h>, and <stddef.h>.
+dnl Unfortunately, many implementations today hide typedefs in wierd
+dnl locations: Solaris 2.5.1 has uint8_t and uint32_t in <pthread.h>.
+dnl SunOS 4.1.x has int8_t in <sys/bitypes.h>.
+dnl So we define our own macro AC_UNP_CHECK_TYPE that does the same
+dnl #includes as "unp.h", and then looks for the typedef.
+dnl
+dnl This macro should be invoked after all the header checks have been
+dnl performed, since we #include "confdefs.h" below, and then use the
+dnl HAVE_foo_H values that it can #define.
+dnl
+AC_DEFUN(AC_UNP_CHECK_TYPE,
+       [AC_MSG_CHECKING(if $1 defined)
+       AC_CACHE_VAL(ac_cv_type_$1,
+               AC_TRY_COMPILE(
+[
+#include       "confdefs.h"    /* the header built by configure so far */
+#ifdef HAVE_SYS_TYPES_H
+#  include     <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include     <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include    <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include    <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include    <arpa/inet.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#  include    <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#  include    <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include     <netdb.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#  include     <signal.h>
+#endif
+#ifdef HAVE_STDIO_H
+#  include     <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include     <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#  include     <string.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include     <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include     <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include     <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#  include     <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include     <sys/un.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include   <sys/select.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include   <strings.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include   <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include   <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include   <sys/sockio.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#  include     <pthread.h>
+#endif],
+               [ $1 foo ],
+               ac_cv_type_$1=yes,
+               ac_cv_type_$1=no))
+       AC_MSG_RESULT($ac_cv_type_$1)
+       if test $ac_cv_type_$1 = no ; then
+               AC_DEFINE($1, $2, $3)
+       fi
+])
+
+dnl ##################################################################
+dnl The following checks for any typedefs for XTI programs.
+dnl We perform all the #includes that "libxti/unpxti.h" performs.
+dnl
+AC_DEFUN(AC_UNPXTI_CHECK_TYPE,
+       [AC_MSG_CHECKING(if $1 defined)
+       AC_CACHE_VAL(ac_cv_type_$1,
+               AC_TRY_COMPILE(
+[
+#include       "confdefs.h"    /* the header built by configure so far */
+#ifdef HAVE_SYS_TYPES_H
+#  include     <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include     <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include    <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include    <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include    <arpa/inet.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#  include    <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#  include    <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include     <netdb.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#  include     <signal.h>
+#endif
+#ifdef HAVE_STDIO_H
+#  include     <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include     <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#  include     <string.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include     <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include     <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include     <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#  include     <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include     <sys/un.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include   <sys/select.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include   <strings.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include   <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include   <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include   <sys/sockio.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#  include     <pthread.h>
+#endif
+#ifdef HAVE_POLL_H
+#  include     <poll.h>
+#endif
+#ifdef HAVE_XTI_H
+#  include     <xti.h>
+#endif
+#ifdef HAVE_NETCONFIG_H
+#  include     <netconfig.h>
+#endif
+#ifdef HAVE_NETDIR_H
+#  include     <netdir.h>
+#endif
+#ifdef HAVE_STROPTS_H
+#  include     <stropts.h>
+#endif],
+               [ $1 foo ],
+               ac_cv_type_$1=yes,
+               ac_cv_type_$1=no))
+       AC_MSG_RESULT($ac_cv_type_$1)
+       if test $ac_cv_type_$1 = no ; then
+               AC_DEFINE($1, $2, $3)
+       fi
+])
diff --git a/advio/Makefile b/advio/Makefile
new file mode 100644 (file)
index 0000000..54a9ba6
--- /dev/null
@@ -0,0 +1,54 @@
+include ../Make.defines
+
+PROGS =        tcpcli01 tcpcli02 tcpserv02 \
+               udpcli01 udpcli02 udpcli03 \
+               udpserv01 udpserv03 udpserv04 \
+               daytimetcpcli daytimeudpcli3 daytimeudpcli4
+
+all:   ${PROGS}
+
+tcpcli01:      tcpcli01.o
+               ${CC} ${CFLAGS} -o $@ tcpcli01.o ${LIBS}
+
+tcpcli02:      tcpcli02.o str_cli_select02.o
+               ${CC} ${CFLAGS} -o $@ tcpcli02.o str_cli_select02.o ${LIBS}
+
+tcpcli03:      tcpcli03.o str_cli_poll03.o
+               ${CC} ${CFLAGS} -o $@ tcpcli03.o str_cli_poll03.o ${LIBS}
+
+tcpcli04:      tcpcli04.o str_cli_kqueue04.o
+               ${CC} ${CFLAGS} -o $@ tcpcli04.o str_cli_kqueue04.o ${LIBS}
+
+tcpserv02:     tcpserv02.o str_echo_stdio02.o sig_chld_waitpid.o
+               ${CC} ${CFLAGS} -o $@ tcpserv02.o str_echo_stdio02.o \
+                       sig_chld_waitpid.o ${LIBS}
+
+udpcli01:      udpcli01.o dgclitimeo1.o
+               ${CC} ${CFLAGS} -o $@ udpcli01.o dgclitimeo1.o ${LIBS}
+
+udpcli02:      udpcli02.o dgclitimeo2.o
+               ${CC} ${CFLAGS} -o $@ udpcli02.o dgclitimeo2.o ${LIBS}
+
+udpcli03:      udpcli03.o dgclitimeo3.o
+               ${CC} ${CFLAGS} -o $@ udpcli03.o dgclitimeo3.o ${LIBS}
+
+udpserv01:     udpserv01.o dgechoaddr.o recvfromflags.o
+               ${CC} ${CFLAGS} -o $@ udpserv01.o dgechoaddr.o recvfromflags.o ${LIBS}
+
+udpserv03:     udpserv03.o
+               ${CC} ${CFLAGS} -o $@ udpserv03.o ${LIBS}
+
+udpserv04:     udpserv04.o
+               ${CC} ${CFLAGS} -o $@ udpserv04.o ${LIBS}
+
+daytimetcpcli: daytimetcpcli.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpcli.o ${LIBS}
+
+daytimeudpcli3:        daytimeudpcli3.o
+               ${CC} ${CFLAGS} -o $@ daytimeudpcli3.o ${LIBS}
+
+daytimeudpcli4:        daytimeudpcli4.o
+               ${CC} ${CFLAGS} -o $@ daytimeudpcli4.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/advio/daytimetcpcli.c b/advio/daytimetcpcli.c
new file mode 100644 (file)
index 0000000..7b4dcab
--- /dev/null
@@ -0,0 +1,32 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             sockfd, n, npend;
+       char    recvline[MAXLINE + 1];
+       socklen_t       len;
+       struct sockaddr_storage ss;
+
+       if (argc != 3)
+               err_quit("usage: a.out <hostname or IPaddress> <service or port#>");
+
+       sockfd = Tcp_connect(argv[1], argv[2]);
+
+       len = sizeof(ss);
+       Getpeername(sockfd, (SA *)&ss, &len);
+       printf("connected to %s\n", Sock_ntop_host((SA *)&ss, len));
+
+       for ( ; ; ) {
+               if ( (n = Recv(sockfd, recvline, MAXLINE, MSG_PEEK)) == 0)
+                       break;          /* server closed connection */
+
+               Ioctl(sockfd, FIONREAD, &npend);        /* check FIONREAD support */
+               printf("%d bytes from PEEK, %d bytes pending\n", n, npend);
+
+               n = Read(sockfd, recvline, MAXLINE);
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+       exit(0);
+}
diff --git a/advio/daytimeudpcli3.c b/advio/daytimeudpcli3.c
new file mode 100644 (file)
index 0000000..29da552
--- /dev/null
@@ -0,0 +1,30 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             sockfd, n, nq;
+       char    recvline[MAXLINE + 1];
+       socklen_t       salen;
+       struct sockaddr *sa;
+
+       if (argc != 3)
+               err_quit("usage: a.out <hostname or IPaddress> <service or port#>");
+
+       sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);
+
+       printf("sending to %s\n", Sock_ntop_host(sa, salen));
+
+       Sendto(sockfd, "", 1, 0, sa, salen);    /* send 1-byte datagram */
+
+       n = Recvfrom(sockfd, recvline, MAXLINE, MSG_PEEK, NULL, NULL);
+
+       Ioctl(sockfd, FIONREAD, &nq);   /* check FIONREAD support */
+       printf("%d bytes from PEEK, %d bytes pending\n", n, nq);
+
+       n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
+       recvline[n] = 0;        /* null terminate */
+       Fputs(recvline, stdout);
+
+       exit(0);
+}
diff --git a/advio/daytimeudpcli4.c b/advio/daytimeudpcli4.c
new file mode 100644 (file)
index 0000000..3e47bd1
--- /dev/null
@@ -0,0 +1,32 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             sockfd, n, nq;
+       char    recvline[MAXLINE + 1];
+       socklen_t       len;
+       struct sockaddr_storage ss;
+
+       if (argc != 3)
+               err_quit("usage: a.out <hostname or IPaddress> <service or port#>");
+
+       sockfd = Udp_connect(argv[1], argv[2]);
+
+       len = sizeof(ss);
+       Getpeername(sockfd, (SA *)&ss, &len);
+       printf("connected to %s\n", Sock_ntop_host((SA *)&ss, len));
+
+       Write(sockfd, "", 2);   /* send 1-byte datagram */
+
+       n = Recv(sockfd, recvline, MAXLINE, MSG_PEEK);
+
+       Ioctl(sockfd, FIONREAD, &nq);   /* check FIONREAD support */
+       printf("%d bytes from PEEK, %d bytes pending\n", n, nq);
+
+       n = Read(sockfd, recvline, MAXLINE);
+       recvline[n] = 0;        /* null terminate */
+       Fputs(recvline, stdout);
+
+       exit(0);
+}
diff --git a/advio/dgclitimeo.c b/advio/dgclitimeo.c
new file mode 100644 (file)
index 0000000..48702ba
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int     n;
+       char    sendline[MAXLINE], recvline[MAXLINE + 1];
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               if (Readable_timeo(sockfd, 5) == 0) {
+                       fprintf(stderr, "socket timeout\n");
+                       continue;
+               }
+               n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
+
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+}
diff --git a/advio/dgclitimeo1.c b/advio/dgclitimeo1.c
new file mode 100644 (file)
index 0000000..9cf1622
--- /dev/null
@@ -0,0 +1,21 @@
+#include       "unp.h"
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int     n;
+       char    sendline[MAXLINE], recvline[MAXLINE + 1];
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               if (Readable_timeo(sockfd, 5) == 0) {
+                       fprintf(stderr, "socket timeout\n");
+               } else {
+                       n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
+                       recvline[n] = 0;        /* null terminate */
+                       Fputs(recvline, stdout);
+               }
+       }
+}
diff --git a/advio/dgclitimeo2.c b/advio/dgclitimeo2.c
new file mode 100644 (file)
index 0000000..8f258a3
--- /dev/null
@@ -0,0 +1,30 @@
+#include       "unp.h"
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                             n;
+       char                    sendline[MAXLINE], recvline[MAXLINE + 1];
+       struct timeval  tv;
+
+       tv.tv_sec = 5;
+       tv.tv_usec = 0;
+       Setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
+               if (n < 0) {
+                       if (errno == EWOULDBLOCK) {
+                               fprintf(stderr, "socket timeout\n");
+                               continue;
+                       } else
+                               err_sys("recvfrom error");
+               }
+
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+}
diff --git a/advio/dgclitimeo2.lc b/advio/dgclitimeo2.lc
new file mode 100644 (file)
index 0000000..cd6002e
--- /dev/null
@@ -0,0 +1,30 @@
+#include    "unp.h"##  1 ##src/advio/dgclitimeo2.c##
+
+void##  2 ##src/advio/dgclitimeo2.c##
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)##  3 ##src/advio/dgclitimeo2.c##
+{##  4 ##src/advio/dgclitimeo2.c##
+    int     n;##  5 ##src/advio/dgclitimeo2.c##
+    char    sendline[MAXLINE], recvline[MAXLINE + 1];##  6 ##src/advio/dgclitimeo2.c##
+    struct timeval tv;##  7 ##src/advio/dgclitimeo2.c##
+
+    tv.tv_sec = 5;##  8 ##src/advio/dgclitimeo2.c##
+    tv.tv_usec = 0;##  9 ##src/advio/dgclitimeo2.c##
+    Setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));## 10 ##src/advio/dgclitimeo2.c##
+
+    while (Fgets(sendline, MAXLINE, fp) != NULL) {## 11 ##src/advio/dgclitimeo2.c##
+
+        Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 12 ##src/advio/dgclitimeo2.c##
+
+        n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);## 13 ##src/advio/dgclitimeo2.c##
+        if (n < 0) {## 14 ##src/advio/dgclitimeo2.c##
+            if (errno == EWOULDBLOCK) {## 15 ##src/advio/dgclitimeo2.c##
+                fprintf(stderr, "socket timeout\n");## 16 ##src/advio/dgclitimeo2.c##
+                continue;## 17 ##src/advio/dgclitimeo2.c##
+            } else## 18 ##src/advio/dgclitimeo2.c##
+                err_sys("recvfrom error");## 19 ##src/advio/dgclitimeo2.c##
+        }## 20 ##src/advio/dgclitimeo2.c##
+
+        recvline[n] = 0;        /* null terminate */## 21 ##src/advio/dgclitimeo2.c##
+        Fputs(recvline, stdout);## 22 ##src/advio/dgclitimeo2.c##
+    }## 23 ##src/advio/dgclitimeo2.c##
+}## 24 ##src/advio/dgclitimeo2.c##
diff --git a/advio/dgclitimeo3.c b/advio/dgclitimeo3.c
new file mode 100644 (file)
index 0000000..ff32f18
--- /dev/null
@@ -0,0 +1,35 @@
+#include       "unp.h"
+
+static void    sig_alrm(int);
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int     n;
+       char    sendline[MAXLINE], recvline[MAXLINE + 1];
+
+       Signal(SIGALRM, sig_alrm);
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               alarm(5);
+               if ( (n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL)) < 0) {
+                       if (errno == EINTR)
+                               fprintf(stderr, "socket timeout\n");
+                       else
+                               err_sys("recvfrom error");
+               } else {
+                       alarm(0);
+                       recvline[n] = 0;        /* null terminate */
+                       Fputs(recvline, stdout);
+               }
+       }
+}
+
+static void
+sig_alrm(int signo)
+{
+       return;                 /* just interrupt the recvfrom() */
+}
diff --git a/advio/dgclitimeo3.lc b/advio/dgclitimeo3.lc
new file mode 100644 (file)
index 0000000..5fd7153
--- /dev/null
@@ -0,0 +1,35 @@
+#include    "unp.h"##  1 ##src/advio/dgclitimeo3.c##
+
+static void sig_alrm(int);##  2 ##src/advio/dgclitimeo3.c##
+
+void##  3 ##src/advio/dgclitimeo3.c##
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)##  4 ##src/advio/dgclitimeo3.c##
+{##  5 ##src/advio/dgclitimeo3.c##
+    int     n;##  6 ##src/advio/dgclitimeo3.c##
+    char    sendline[MAXLINE], recvline[MAXLINE + 1];##  7 ##src/advio/dgclitimeo3.c##
+
+    Signal(SIGALRM, sig_alrm);##  8 ##src/advio/dgclitimeo3.c##
+
+    while (Fgets(sendline, MAXLINE, fp) != NULL) {##  9 ##src/advio/dgclitimeo3.c##
+
+        Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 10 ##src/advio/dgclitimeo3.c##
+
+        alarm(5);## 11 ##src/advio/dgclitimeo3.c##
+        if ((n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL)) < 0) {## 12 ##src/advio/dgclitimeo3.c##
+            if (errno == EINTR)## 13 ##src/advio/dgclitimeo3.c##
+                fprintf(stderr, "socket timeout\n");## 14 ##src/advio/dgclitimeo3.c##
+            else## 15 ##src/advio/dgclitimeo3.c##
+                err_sys("recvfrom error");## 16 ##src/advio/dgclitimeo3.c##
+        } else {## 17 ##src/advio/dgclitimeo3.c##
+            alarm(0);## 18 ##src/advio/dgclitimeo3.c##
+            recvline[n] = 0;    /* null terminate */## 19 ##src/advio/dgclitimeo3.c##
+            Fputs(recvline, stdout);## 20 ##src/advio/dgclitimeo3.c##
+        }## 21 ##src/advio/dgclitimeo3.c##
+    }## 22 ##src/advio/dgclitimeo3.c##
+}## 23 ##src/advio/dgclitimeo3.c##
+
+static void## 24 ##src/advio/dgclitimeo3.c##
+sig_alrm(int signo)## 25 ##src/advio/dgclitimeo3.c##
+{## 26 ##src/advio/dgclitimeo3.c##
+    return;                     /* just interrupt the recvfrom() */## 27 ##src/advio/dgclitimeo3.c##
+}## 28 ##src/advio/dgclitimeo3.c##
diff --git a/advio/dgechoaddr.c b/advio/dgechoaddr.c
new file mode 100644 (file)
index 0000000..b8ab892
--- /dev/null
@@ -0,0 +1,56 @@
+#include       "unpifi.h"
+
+#undef MAXLINE
+#define        MAXLINE 20              /* to see datagram truncation */
+
+void
+dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
+{
+       int                                             flags;
+       const int                               on = 1;
+       socklen_t                               len;
+       ssize_t                                 n;
+       char                                    mesg[MAXLINE], str[INET6_ADDRSTRLEN],
+                                                       ifname[IFNAMSIZ];
+       struct in_addr                  in_zero;
+       struct unp_in_pktinfo   pktinfo;
+
+#ifdef IP_RECVDSTADDR
+       if (setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)) < 0)
+               err_ret("setsockopt of IP_RECVDSTADDR");
+#endif
+#ifdef IP_RECVIF
+       if (setsockopt(sockfd, IPPROTO_IP, IP_RECVIF, &on, sizeof(on)) < 0)
+               err_ret("setsockopt of IP_RECVIF");
+#endif
+       bzero(&in_zero, sizeof(struct in_addr));        /* all 0 IPv4 address */
+
+       for ( ; ; ) {
+               len = clilen;
+               flags = 0;
+               n = Recvfrom_flags(sockfd, mesg, MAXLINE, &flags,
+                                                  pcliaddr, &len, &pktinfo);
+               printf("%d-byte datagram from %s", n, Sock_ntop(pcliaddr, len));
+               if (memcmp(&pktinfo.ipi_addr, &in_zero, sizeof(in_zero)) != 0)
+                       printf(", to %s", Inet_ntop(AF_INET, &pktinfo.ipi_addr,
+                                                                               str, sizeof(str)));
+               if (pktinfo.ipi_ifindex > 0)
+                       printf(", recv i/f = %s",
+                                  If_indextoname(pktinfo.ipi_ifindex, ifname));
+#ifdef MSG_TRUNC
+               if (flags & MSG_TRUNC)  printf(" (datagram truncated)");
+#endif
+#ifdef MSG_CTRUNC
+               if (flags & MSG_CTRUNC) printf(" (control info truncated)");
+#endif
+#ifdef MSG_BCAST
+               if (flags & MSG_BCAST)  printf(" (broadcast)");
+#endif
+#ifdef MSG_MCAST
+               if (flags & MSG_MCAST)  printf(" (multicast)");
+#endif
+               printf("\n");
+
+               Sendto(sockfd, mesg, n, 0, pcliaddr, len);
+       }
+}
diff --git a/advio/dgechoaddr.lc b/advio/dgechoaddr.lc
new file mode 100644 (file)
index 0000000..2e445a3
--- /dev/null
@@ -0,0 +1,59 @@
+#include    "unpifi.h"##  1 ##src/advio/dgechoaddr.c##
+
+#undef  MAXLINE##  2 ##src/advio/dgechoaddr.c##
+#define MAXLINE 20              /* to see datagram truncation */##  3 ##src/advio/dgechoaddr.c##
+
+void##  4 ##src/advio/dgechoaddr.c##
+dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)##  5 ##src/advio/dgechoaddr.c##
+{##  6 ##src/advio/dgechoaddr.c##
+    int     flags;##  7 ##src/advio/dgechoaddr.c##
+    const int on = 1;##  8 ##src/advio/dgechoaddr.c##
+    socklen_t len;##  9 ##src/advio/dgechoaddr.c##
+    ssize_t n;## 10 ##src/advio/dgechoaddr.c##
+    char    mesg[MAXLINE], str[INET6_ADDRSTRLEN], ifname[IFNAMSIZ];## 11 ##src/advio/dgechoaddr.c##
+    struct in_addr in_zero;## 12 ##src/advio/dgechoaddr.c##
+    struct in_pktinfo pktinfo;## 13 ##src/advio/dgechoaddr.c##
+
+#ifdef  IP_RECVDSTADDR## 14 ##src/advio/dgechoaddr.c##
+    if (setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)) < 0)## 15 ##src/advio/dgechoaddr.c##
+        err_ret("setsockopt of IP_RECVDSTADDR");## 16 ##src/advio/dgechoaddr.c##
+#endif## 17 ##src/advio/dgechoaddr.c##
+#ifdef  IP_RECVIF## 18 ##src/advio/dgechoaddr.c##
+    if (setsockopt(sockfd, IPPROTO_IP, IP_RECVIF, &on, sizeof(on)) < 0)## 19 ##src/advio/dgechoaddr.c##
+        err_ret("setsockopt of IP_RECVIF");## 20 ##src/advio/dgechoaddr.c##
+#endif## 21 ##src/advio/dgechoaddr.c##
+    bzero(&in_zero, sizeof(struct in_addr));    /* all 0 IPv4 address */## 22 ##src/advio/dgechoaddr.c##
+
+    for (;;) {## 23 ##src/advio/dgechoaddr.c##
+        len = clilen;## 24 ##src/advio/dgechoaddr.c##
+        flags = 0;## 25 ##src/advio/dgechoaddr.c##
+        n = Recvfrom_flags(sockfd, mesg, MAXLINE, &flags,## 26 ##src/advio/dgechoaddr.c##
+                           pcliaddr, &len, &pktinfo);## 27 ##src/advio/dgechoaddr.c##
+        printf("%d-byte datagram from %s", n, Sock_ntop(pcliaddr, len));## 28 ##src/advio/dgechoaddr.c##
+        if (memcmp(&pktinfo.ipi_addr, &in_zero, sizeof(in_zero)) != 0)## 29 ##src/advio/dgechoaddr.c##
+            printf(", to %s", Inet_ntop(AF_INET, &pktinfo.ipi_addr,## 30 ##src/advio/dgechoaddr.c##
+                                        str, sizeof(str)));## 31 ##src/advio/dgechoaddr.c##
+        if (pktinfo.ipi_ifindex > 0)## 32 ##src/advio/dgechoaddr.c##
+            printf(", recv i/f = %s",## 33 ##src/advio/dgechoaddr.c##
+                   If_indextoname(pktinfo.ipi_ifindex, ifname));## 34 ##src/advio/dgechoaddr.c##
+#ifdef  MSG_TRUNC## 35 ##src/advio/dgechoaddr.c##
+        if (flags & MSG_TRUNC)## 36 ##src/advio/dgechoaddr.c##
+            printf(" (datagram truncated)");## 37 ##src/advio/dgechoaddr.c##
+#endif## 38 ##src/advio/dgechoaddr.c##
+#ifdef  MSG_CTRUNC## 39 ##src/advio/dgechoaddr.c##
+        if (flags & MSG_CTRUNC)## 40 ##src/advio/dgechoaddr.c##
+            printf(" (control info truncated)");## 41 ##src/advio/dgechoaddr.c##
+#endif## 42 ##src/advio/dgechoaddr.c##
+#ifdef  MSG_BCAST## 43 ##src/advio/dgechoaddr.c##
+        if (flags & MSG_BCAST)## 44 ##src/advio/dgechoaddr.c##
+            printf(" (broadcast)");## 45 ##src/advio/dgechoaddr.c##
+#endif## 46 ##src/advio/dgechoaddr.c##
+#ifdef  MSG_MCAST## 47 ##src/advio/dgechoaddr.c##
+        if (flags & MSG_MCAST)## 48 ##src/advio/dgechoaddr.c##
+            printf(" (multicast)");## 49 ##src/advio/dgechoaddr.c##
+#endif## 50 ##src/advio/dgechoaddr.c##
+        printf("\n");## 51 ##src/advio/dgechoaddr.c##
+
+        Sendto(sockfd, mesg, n, 0, pcliaddr, len);## 52 ##src/advio/dgechoaddr.c##
+    }## 53 ##src/advio/dgechoaddr.c##
+}## 54 ##src/advio/dgechoaddr.c##
diff --git a/advio/old/dgechoaddr.c b/advio/old/dgechoaddr.c
new file mode 100644 (file)
index 0000000..e31c268
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unp.h"
+
+#undef MAXLINE
+#define        MAXLINE 20              /* to see datagram truncation */
+
+void
+dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
+{
+       int                             flags;
+       const int               on = 1;
+       socklen_t               len;
+       ssize_t                 n;
+       char                    mesg[MAXLINE], str[INET6_ADDRSTRLEN];
+       struct in_addr  dstaddr;
+
+#ifdef IP_RECVDSTADDR
+       Setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on));
+#endif
+
+       for ( ; ; ) {
+               len = clilen;
+               flags = 0;
+               n = Recvfrom_flags(sockfd, mesg, MAXLINE, &flags,
+                                                  pcliaddr, &len, &dstaddr);
+               printf("%d-byte datagram from %s", n, Sock_ntop(pcliaddr, len));
+               if ((flags & MSG_CTRUNC) == 0)
+                       printf(", to %s", Inet_ntop(AF_INET, &dstaddr, str, sizeof(str)));
+#ifdef MSG_TRUNC
+               if (flags & MSG_TRUNC)  printf(" (datagram truncated)");
+#endif
+#ifdef MSG_BCAST
+               if (flags & MSG_BCAST)  printf(" (broadcast)");
+#endif
+#ifdef MSG_MCAST
+               if (flags & MSG_MCAST)  printf(" (multicast)");
+#endif
+               printf("\n");
+
+               Sendto(sockfd, mesg, n, 0, pcliaddr, clilen);
+       }
+}
diff --git a/advio/old/recvfromflags.c b/advio/old/recvfromflags.c
new file mode 100644 (file)
index 0000000..bb74e0d
--- /dev/null
@@ -0,0 +1,77 @@
+#include       "unp.h"
+
+ssize_t
+recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
+                          SA *sa, socklen_t *salenptr, void *dstaddrp)
+{
+       struct msghdr   msg;
+       struct iovec    iov[1];
+       ssize_t                 n;
+
+#ifdef HAVE_MSGHDR_MSG_CONTROL
+#define        CONTROL_LEN     (sizeof(struct cmsghdr) + sizeof(struct in_addr))
+       char            control[CONTROL_LEN];
+
+       msg.msg_control = control;
+       msg.msg_controllen = sizeof(control);
+       msg.msg_flags = 0;
+#else
+       bzero(&msg, sizeof(msg));       /* make certain msg_accrightslen = 0 */
+#endif
+
+       msg.msg_name = sa;
+       msg.msg_namelen = *salenptr;
+       iov[0].iov_base = ptr;
+       iov[0].iov_len = nbytes;
+       msg.msg_iov = iov;
+       msg.msg_iovlen = 1;
+
+       if ( (n = recvmsg(fd, &msg, *flagsp)) < 0)
+               return(n);
+
+       *salenptr = msg.msg_namelen;    /* pass back results */
+#ifdef HAVE_MSGHDR_MSG_CONTROL
+       *flagsp = msg.msg_flags;                /* pass back results */
+
+       /*
+        * We need someway to indicate to the caller that nothing was
+        * returned through dstaddrp (since all 32-bit values are valid
+        * IP destination addresses).  To avoid having to add yet another
+        * pointer argument, we return MSG_CTRUNC (which unp.h always
+        * defines, even if the implementation does not).
+        */
+
+#ifdef IP_RECVDSTADDR
+       if (dstaddrp && msg.msg_controllen > 0 &&
+               (msg.msg_flags & MSG_CTRUNC) == 0) {
+               struct cmsghdr  *cmptr = CMSG_FIRSTHDR(&msg);
+
+               if (cmptr->cmsg_len != CONTROL_LEN)
+                       err_quit("control length = %d", cmptr->cmsg_len);
+               if (cmptr->cmsg_level != IPPROTO_IP)
+                       err_quit("control level != IPPROTO_IP");
+               if (cmptr->cmsg_type != IP_RECVDSTADDR)
+                       err_quit("control type != IP_RECVDSTADDR");
+               memcpy(dstaddrp, CMSG_DATA(cmptr), sizeof(struct in_addr));
+       } else
+#endif
+               *flagsp |= MSG_CTRUNC;          /* dest IP addr not returned */
+#else
+       *flagsp |= MSG_CTRUNC;                  /* dest IP addr not returned */
+#endif /* HAVE_MSGHDR_MSG_CONTROL */
+
+       return(n);
+}
+
+ssize_t
+Recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
+                          SA *sa, socklen_t *salenptr, void *dstaddrp)
+{
+       ssize_t         n;
+
+       n = recvfrom_flags(fd, ptr, nbytes, flagsp, sa, salenptr, dstaddrp);
+       if (n < 0)
+               err_quit("recvfrom_flags error");
+
+       return(n);
+}
diff --git a/advio/old/test01.c b/advio/old/test01.c
new file mode 100644 (file)
index 0000000..b09c318
--- /dev/null
@@ -0,0 +1,72 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                             sockfd, flag;
+       ssize_t                 n;
+       char                    buff[MAXLINE];
+       const int               on = 1;
+       socklen_t               addrlen, len;
+       struct sockaddr *cliaddr;
+
+       if (argc == 2)
+               sockfd = Udp_server(NULL, argv[1], &addrlen);
+       else if (argc == 3)
+               sockfd = Udp_server(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: test01 <hostname> <service>");
+
+       cliaddr = Malloc(addrlen);
+
+#ifdef IP_RECVDSTADDR
+       Setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on));
+
+       len = sizeof(flag);
+       Getsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR, &flag, &len);
+       printf("IP_RECVDSTADDR option = %d, size = %d\n", flag, len);
+#else
+       printf("IP_RECVDSTADDR not defined\n");
+#endif
+
+#ifdef IP_RECVIF
+       Setsockopt(sockfd, IPPROTO_IP, IP_RECVIF, &on, sizeof(on));
+
+       len = sizeof(flag);
+       Getsockopt(sockfd, IPPROTO_IP, IP_RECVIF, &flag, &len);
+       printf("IP_RECVIF option = %d, size = %d\n", flag, len);
+#else
+       printf("IP_RECVIF not defined\n");
+#endif
+
+       for ( ; ; ) {
+#define        CONTROL_LEN     (sizeof(struct cmsghdr) + sizeof(struct in_addr))
+               char            control[CONTROL_LEN];
+
+               msg.msg_control = control;
+               msg.msg_controllen = sizeof(control);
+               msg.msg_flags = 0;
+#else
+               bzero(&msg, sizeof(msg));       /* make certain msg_accrightslen = 0 */
+#endif
+
+               msg.msg_name = sa;
+               msg.msg_namelen = *salenptr;
+               iov[0].iov_base = ptr;
+               iov[0].iov_len = nbytes;
+               msg.msg_iov = iov;
+               msg.msg_iovlen = 1;
+
+               if ( (n = recvmsg(fd, &msg, *flagsp)) < 0)
+                       return(n);
+
+               len = addrlen;
+               n = Recvfrom(sockfd, buff, MAXLINE, 0, cliaddr, &len);
+               printf("datagram from %s\n", Sock_ntop(cliaddr, len));
+
+        ticks = time(NULL);
+        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+        Sendto(sockfd, buff, strlen(buff), 0, cliaddr, len);
+       }
+       exit(0);
+}
diff --git a/advio/recvfromflags.c b/advio/recvfromflags.c
new file mode 100644 (file)
index 0000000..a3a316c
--- /dev/null
@@ -0,0 +1,96 @@
+/* include recvfrom_flags1 */
+#include       "unp.h"
+#include       <sys/param.h>           /* ALIGN macro for CMSG_NXTHDR() macro */
+
+ssize_t
+recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
+                          SA *sa, socklen_t *salenptr, struct unp_in_pktinfo *pktp)
+{
+       struct msghdr   msg;
+       struct iovec    iov[1];
+       ssize_t                 n;
+
+#ifdef HAVE_MSGHDR_MSG_CONTROL
+       struct cmsghdr  *cmptr;
+       union {
+         struct cmsghdr        cm;
+         char                          control[CMSG_SPACE(sizeof(struct in_addr)) +
+                                                               CMSG_SPACE(sizeof(struct unp_in_pktinfo))];
+       } control_un;
+
+       msg.msg_control = control_un.control;
+       msg.msg_controllen = sizeof(control_un.control);
+       msg.msg_flags = 0;
+#else
+       bzero(&msg, sizeof(msg));       /* make certain msg_accrightslen = 0 */
+#endif
+
+       msg.msg_name = sa;
+       msg.msg_namelen = *salenptr;
+       iov[0].iov_base = ptr;
+       iov[0].iov_len = nbytes;
+       msg.msg_iov = iov;
+       msg.msg_iovlen = 1;
+
+       if ( (n = recvmsg(fd, &msg, *flagsp)) < 0)
+               return(n);
+
+       *salenptr = msg.msg_namelen;    /* pass back results */
+       if (pktp)
+               bzero(pktp, sizeof(struct unp_in_pktinfo));     /* 0.0.0.0, i/f = 0 */
+/* end recvfrom_flags1 */
+
+/* include recvfrom_flags2 */
+#ifndef        HAVE_MSGHDR_MSG_CONTROL
+       *flagsp = 0;                                    /* pass back results */
+       return(n);
+#else
+
+       *flagsp = msg.msg_flags;                /* pass back results */
+       if (msg.msg_controllen < sizeof(struct cmsghdr) ||
+               (msg.msg_flags & MSG_CTRUNC) || pktp == NULL)
+               return(n);
+
+       for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;
+                cmptr = CMSG_NXTHDR(&msg, cmptr)) {
+
+#ifdef IP_RECVDSTADDR
+               if (cmptr->cmsg_level == IPPROTO_IP &&
+                       cmptr->cmsg_type == IP_RECVDSTADDR) {
+
+                       memcpy(&pktp->ipi_addr, CMSG_DATA(cmptr),
+                                  sizeof(struct in_addr));
+                       continue;
+               }
+#endif
+
+#ifdef IP_RECVIF
+               if (cmptr->cmsg_level == IPPROTO_IP &&
+                       cmptr->cmsg_type == IP_RECVIF) {
+                       struct sockaddr_dl      *sdl;
+
+                       sdl = (struct sockaddr_dl *) CMSG_DATA(cmptr);
+                       pktp->ipi_ifindex = sdl->sdl_index;
+                       continue;
+               }
+#endif
+               err_quit("unknown ancillary data, len = %d, level = %d, type = %d",
+                                cmptr->cmsg_len, cmptr->cmsg_level, cmptr->cmsg_type);
+       }
+       return(n);
+#endif /* HAVE_MSGHDR_MSG_CONTROL */
+}
+/* end recvfrom_flags2 */
+
+ssize_t
+Recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
+                          SA *sa, socklen_t *salenptr, struct unp_in_pktinfo *pktp)
+{
+       ssize_t         n;
+
+       n = recvfrom_flags(fd, ptr, nbytes, flagsp, sa, salenptr, pktp);
+       if (n < 0)
+               err_quit("recvfrom_flags error");
+
+       return(n);
+}
diff --git a/advio/recvfromflags.lc b/advio/recvfromflags.lc
new file mode 100644 (file)
index 0000000..439702e
--- /dev/null
@@ -0,0 +1,99 @@
+/* include recvfrom_flags1 */
+#include    "unp.h"##  1 ##src/advio/recvfromflags.c##
+#include    <sys/param.h>       /* ALIGN macro for CMSG_NXTHDR() macro */##  2 ##src/advio/recvfromflags.c##
+
+#ifdef  HAVE_SOCKADDR_DL_STRUCT##  3 ##src/advio/recvfromflags.c##
+# include   <net/if_dl.h>##  4 ##src/advio/recvfromflags.c##
+#endif##  5 ##src/advio/recvfromflags.c##
+
+ssize_t##  6 ##src/advio/recvfromflags.c##
+recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,##  7 ##src/advio/recvfromflags.c##
+               SA *sa, socklen_t *salenptr, struct in_pktinfo *pktp)##  8 ##src/advio/recvfromflags.c##
+{##  9 ##src/advio/recvfromflags.c##
+    struct msghdr msg;## 10 ##src/advio/recvfromflags.c##
+    struct iovec iov[1];## 11 ##src/advio/recvfromflags.c##
+    ssize_t n;## 12 ##src/advio/recvfromflags.c##
+
+#ifdef  HAVE_MSGHDR_MSG_CONTROL## 13 ##src/advio/recvfromflags.c##
+    struct cmsghdr *cmptr;## 14 ##src/advio/recvfromflags.c##
+    union {## 15 ##src/advio/recvfromflags.c##
+        struct cmsghdr cm;## 16 ##src/advio/recvfromflags.c##
+        char    control[CMSG_SPACE(sizeof(struct in_addr)) +## 17 ##src/advio/recvfromflags.c##
+                        CMSG_SPACE(sizeof(struct in_pktinfo))];## 18 ##src/advio/recvfromflags.c##
+    } control_un;## 19 ##src/advio/recvfromflags.c##
+
+    msg.msg_control = control_un.control;## 20 ##src/advio/recvfromflags.c##
+    msg.msg_controllen = sizeof(control_un.control);## 21 ##src/advio/recvfromflags.c##
+    msg.msg_flags = 0;## 22 ##src/advio/recvfromflags.c##
+#else## 23 ##src/advio/recvfromflags.c##
+    bzero(&msg, sizeof(msg));   /* make certain msg_accrightslen = 0 */## 24 ##src/advio/recvfromflags.c##
+#endif## 25 ##src/advio/recvfromflags.c##
+
+    msg.msg_name = sa;## 26 ##src/advio/recvfromflags.c##
+    msg.msg_namelen = *salenptr;## 27 ##src/advio/recvfromflags.c##
+    iov[0].iov_base = ptr;## 28 ##src/advio/recvfromflags.c##
+    iov[0].iov_len = nbytes;## 29 ##src/advio/recvfromflags.c##
+    msg.msg_iov = iov;## 30 ##src/advio/recvfromflags.c##
+    msg.msg_iovlen = 1;## 31 ##src/advio/recvfromflags.c##
+
+    if ((n = recvmsg(fd, &msg, *flagsp)) < 0)## 32 ##src/advio/recvfromflags.c##
+        return (n);## 33 ##src/advio/recvfromflags.c##
+
+    *salenptr = msg.msg_namelen;    /* pass back results */## 34 ##src/advio/recvfromflags.c##
+    if (pktp)## 35 ##src/advio/recvfromflags.c##
+        bzero(pktp, sizeof(struct in_pktinfo)); /* 0.0.0.0, i/f = 0 */## 36 ##src/advio/recvfromflags.c##
+/* end recvfrom_flags1 */
+
+/* include recvfrom_flags2 */
+#ifndef HAVE_MSGHDR_MSG_CONTROL## 37 ##src/advio/recvfromflags.c##
+    *flagsp = 0;                /* pass back results */## 38 ##src/advio/recvfromflags.c##
+    return (n);## 39 ##src/advio/recvfromflags.c##
+#else## 40 ##src/advio/recvfromflags.c##
+
+    *flagsp = msg.msg_flags;    /* pass back results */## 41 ##src/advio/recvfromflags.c##
+    if (msg.msg_controllen < sizeof(struct cmsghdr) ||## 42 ##src/advio/recvfromflags.c##
+        (msg.msg_flags & MSG_CTRUNC) || pktp == NULL)## 43 ##src/advio/recvfromflags.c##
+        return (n);## 44 ##src/advio/recvfromflags.c##
+
+    for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;## 45 ##src/advio/recvfromflags.c##
+         cmptr = CMSG_NXTHDR(&msg, cmptr)) {## 46 ##src/advio/recvfromflags.c##
+
+#ifdef  IP_RECVDSTADDR## 47 ##src/advio/recvfromflags.c##
+        if (cmptr->cmsg_level == IPPROTO_IP &&## 48 ##src/advio/recvfromflags.c##
+            cmptr->cmsg_type == IP_RECVDSTADDR) {## 49 ##src/advio/recvfromflags.c##
+
+            memcpy(&pktp->ipi_addr, CMSG_DATA(cmptr),## 50 ##src/advio/recvfromflags.c##
+                   sizeof(struct in_addr));## 51 ##src/advio/recvfromflags.c##
+            continue;## 52 ##src/advio/recvfromflags.c##
+        }## 53 ##src/advio/recvfromflags.c##
+#endif## 54 ##src/advio/recvfromflags.c##
+
+#ifdef  IP_RECVIF## 55 ##src/advio/recvfromflags.c##
+        if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF) {## 56 ##src/advio/recvfromflags.c##
+            struct sockaddr_dl *sdl;## 57 ##src/advio/recvfromflags.c##
+
+            sdl = (struct sockaddr_dl *) CMSG_DATA(cmptr);## 58 ##src/advio/recvfromflags.c##
+            pktp->ipi_ifindex = sdl->sdl_index;## 59 ##src/advio/recvfromflags.c##
+            continue;## 60 ##src/advio/recvfromflags.c##
+        }## 61 ##src/advio/recvfromflags.c##
+#endif## 62 ##src/advio/recvfromflags.c##
+        err_quit("unknown ancillary data, len = %d, level = %d, type = %d",## 63 ##src/advio/recvfromflags.c##
+                 cmptr->cmsg_len, cmptr->cmsg_level, cmptr->cmsg_type);## 64 ##src/advio/recvfromflags.c##
+    }## 65 ##src/advio/recvfromflags.c##
+    return (n);## 66 ##src/advio/recvfromflags.c##
+#endif  /* HAVE_MSGHDR_MSG_CONTROL */## 67 ##src/advio/recvfromflags.c##
+}## 68 ##src/advio/recvfromflags.c##
+/* end recvfrom_flags2 */
+
+ssize_t## 69 ##src/advio/recvfromflags.c##
+Recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,## 70 ##src/advio/recvfromflags.c##
+               SA *sa, socklen_t *salenptr, struct in_pktinfo *pktp)## 71 ##src/advio/recvfromflags.c##
+{## 72 ##src/advio/recvfromflags.c##
+    ssize_t n;## 73 ##src/advio/recvfromflags.c##
+
+    n = recvfrom_flags(fd, ptr, nbytes, flagsp, sa, salenptr, pktp);## 74 ##src/advio/recvfromflags.c##
+    if (n < 0)## 75 ##src/advio/recvfromflags.c##
+        err_quit("recvfrom_flags error");## 76 ##src/advio/recvfromflags.c##
+
+    return (n);## 77 ##src/advio/recvfromflags.c##
+}## 78 ##src/advio/recvfromflags.c##
diff --git a/advio/script.1 b/advio/script.1
new file mode 100644 (file)
index 0000000..7df1561
--- /dev/null
@@ -0,0 +1,6 @@
+kalae % ./udpserv01
+9-byte datagram from 206.62.226.33.41164, to 206.62.226.35, recv i/f = ef0
+13-byte datagram from 206.62.226.65.1057, to 206.62.226.95, recv i/f = we0 (broadcast)
+4-byte datagram from 206.62.226.33.41176, to 224.0.0.1, recv i/f = ef0 (multicast)
+20-byte datagram from 127.0.0.1.4632, to 127.0.0.1, recv i/f = lo0 (datagram truncated)
+9-byte datagram from 206.62.226.33.41178, to 206.62.226.66, recv i/f = ef0
diff --git a/advio/sig_chld_waitpid.c b/advio/sig_chld_waitpid.c
new file mode 100644 (file)
index 0000000..5fa9cbf
--- /dev/null
@@ -0,0 +1,13 @@
+#include       "unp.h"
+
+void
+sig_chld(int signo)
+{
+       pid_t   pid;
+       int             stat;
+
+       while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) {
+               printf("child %d terminated\n", pid);
+       }
+       return;
+}
diff --git a/advio/str_cli_kqueue04.c b/advio/str_cli_kqueue04.c
new file mode 100644 (file)
index 0000000..00550a7
--- /dev/null
@@ -0,0 +1,52 @@
+#include       "unp.h"
+
+void
+str_cli(FILE *fp, int sockfd)
+{
+       int                             kq, i, n, nev, stdineof = 0, isfile;
+       char                    buf[MAXLINE];
+       struct kevent   kev[2];
+       struct timespec ts;
+       struct stat             st;
+
+       isfile = ((fstat(fileno(fp), &st) == 0) &&
+                         (st.st_mode & S_IFMT) == S_IFREG);
+
+       EV_SET(&kev[0], fileno(fp), EVFILT_READ, EV_ADD, 0, 0, NULL);
+       EV_SET(&kev[1], sockfd, EVFILT_READ, EV_ADD, 0, 0, NULL);
+
+       kq = Kqueue();
+       ts.tv_sec = ts.tv_nsec = 0;
+       Kevent(kq, kev, 2, NULL, 0, &ts);
+
+       for ( ; ; ) {
+               nev = Kevent(kq, NULL, 0, kev, 2, NULL);
+
+               for (i = 0; i < nev; i++) {
+                       if (kev[i].ident == sockfd) {   /* socket is readable */
+                               if ( (n = Read(sockfd, buf, MAXLINE)) == 0) {
+                                       if (stdineof == 1)
+                                               return;         /* normal termination */
+                                       else
+                                               err_quit("str_cli: server terminated prematurely");
+                               }
+
+                               Write(fileno(stdout), buf, n);
+                       }
+
+                       if (kev[i].ident == fileno(fp)) {  /* input is readable */
+                               n = Read(fileno(fp), buf, MAXLINE);
+                               if (n > 0)
+                                       Writen(sockfd, buf, n);
+
+                               if (n == 0 || (isfile && n == kev[i].data)) {
+                                       stdineof = 1;
+                                       Shutdown(sockfd, SHUT_WR);      /* send FIN */
+                                       kev[i].flags = EV_DELETE;
+                                       Kevent(kq, &kev[i], 1, NULL, 0, &ts);   /* remove kevent */
+                                       continue;
+                               }
+                       }
+               }
+       }
+}
diff --git a/advio/str_cli_poll03.c b/advio/str_cli_poll03.c
new file mode 100644 (file)
index 0000000..c4748b8
--- /dev/null
@@ -0,0 +1,60 @@
+#include       "unp.h"
+#include       <sys/devpoll.h>
+
+void
+str_cli(FILE *fp, int sockfd)
+{
+       int             stdineof;
+       char            buf[MAXLINE];
+       int             n;
+       int             wfd;
+       struct pollfd   pollfd[2];
+       struct dvpoll   dopoll;
+       int             i;
+       int             result;
+
+       wfd = Open("/dev/poll", O_RDWR, 0);
+
+       pollfd[0].fd = fileno(fp);
+       pollfd[0].events = POLLIN;
+       pollfd[0].revents = 0;
+
+       pollfd[1].fd = sockfd;
+       pollfd[1].events = POLLIN;
+       pollfd[1].revents = 0;
+
+       Write(wfd, pollfd, sizeof(struct pollfd) * 2);
+
+       stdineof = 0;
+       for ( ; ; ) {
+               /* block until /dev/poll says something is ready */
+               dopoll.dp_timeout = -1;
+               dopoll.dp_nfds = 2;
+               dopoll.dp_fds = pollfd;
+               result = Ioctl(wfd, DP_POLL, &dopoll);
+
+               /* loop through ready file descriptors */
+               for (i = 0; i < result; i++) {
+                       if (dopoll.dp_fds[i].fd == sockfd) {
+                               /* socket is readable */
+                               if ( (n = Read(sockfd, buf, MAXLINE)) == 0) {
+                                       if (stdineof == 1)
+                                               return;         /* normal termination */
+                                       else
+                                               err_quit("str_cli: server terminated prematurely");
+                               }
+
+                               Write(fileno(stdout), buf, n);
+                       } else {
+                               /* input is readable */
+                               if ( (n = Read(fileno(fp), buf, MAXLINE)) == 0) {
+                                       stdineof = 1;
+                                       Shutdown(sockfd, SHUT_WR);      /* send FIN */
+                                       continue;
+                               }
+
+                               Writen(sockfd, buf, n);
+                       }
+               }
+       }
+}
diff --git a/advio/str_cli_select02.c b/advio/str_cli_select02.c
new file mode 100644 (file)
index 0000000..9a01462
--- /dev/null
@@ -0,0 +1,40 @@
+#include       "unp.h"
+
+void
+str_cli(FILE *fp, int sockfd)
+{
+       int                     maxfdp1, stdineof = 0;
+       fd_set          rset;
+       char            sendline[MAXLINE], recvline[MAXLINE];
+
+       FD_ZERO(&rset);
+       for ( ; ; ) {
+               if (stdineof == 0)
+                       FD_SET(fileno(fp), &rset);
+               FD_SET(sockfd, &rset);
+               maxfdp1 = max(fileno(fp), sockfd) + 1;
+               Select(maxfdp1, &rset, NULL, NULL, NULL);
+
+               if (FD_ISSET(sockfd, &rset)) {  /* socket is readable */
+                       if (Readline(sockfd, recvline, MAXLINE) == 0) {
+                               if (stdineof == 1)
+                                       return;         /* normal termination */
+                               else
+                                       err_quit("str_cli: server terminated prematurely");
+                       }
+
+                       Fputs(recvline, stdout);
+               }
+
+               if (FD_ISSET(fileno(fp), &rset)) {  /* input is readable */
+                       if (Fgets(sendline, MAXLINE, fp) == NULL) {
+                               stdineof = 1;
+                               Shutdown(sockfd, SHUT_WR);      /* send FIN */
+                               FD_CLR(fileno(fp), &rset);
+                               continue;
+                       }
+
+                       Writen(sockfd, sendline, strlen(sendline));
+               }
+       }
+}
diff --git a/advio/str_echo_stdio02.c b/advio/str_echo_stdio02.c
new file mode 100644 (file)
index 0000000..538137f
--- /dev/null
@@ -0,0 +1,14 @@
+#include       "unp.h"
+
+void
+str_echo(int sockfd)
+{
+       char            line[MAXLINE];
+       FILE            *fpin, *fpout;
+
+       fpin = Fdopen(sockfd, "r");
+       fpout = Fdopen(sockfd, "w");
+
+       while (Fgets(line, MAXLINE, fpin) != NULL)
+               Fputs(line, fpout);
+}
diff --git a/advio/str_echo_stdio02.lc b/advio/str_echo_stdio02.lc
new file mode 100644 (file)
index 0000000..32e4819
--- /dev/null
@@ -0,0 +1,14 @@
+#include    "unp.h"##  1 ##src/advio/str_echo_stdio02.c##
+
+void##  2 ##src/advio/str_echo_stdio02.c##
+str_echo(int sockfd)##  3 ##src/advio/str_echo_stdio02.c##
+{##  4 ##src/advio/str_echo_stdio02.c##
+    char    line[MAXLINE];##  5 ##src/advio/str_echo_stdio02.c##
+    FILE   *fpin, *fpout;##  6 ##src/advio/str_echo_stdio02.c##
+
+    fpin = Fdopen(sockfd, "r");##  7 ##src/advio/str_echo_stdio02.c##
+    fpout = Fdopen(sockfd, "w");##  8 ##src/advio/str_echo_stdio02.c##
+
+    while (Fgets(line, MAXLINE, fpin) != NULL)##  9 ##src/advio/str_echo_stdio02.c##
+        Fputs(line, fpout);## 10 ##src/advio/str_echo_stdio02.c##
+}## 11 ##src/advio/str_echo_stdio02.c##
diff --git a/advio/tcpcli01.c b/advio/tcpcli01.c
new file mode 100644 (file)
index 0000000..66ce515
--- /dev/null
@@ -0,0 +1,25 @@
+/* Use standard echo server; baseline measurements for nonblocking version */
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(7);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect_timeo(sockfd, (SA *) &servaddr, sizeof(servaddr), 10);
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/advio/tcpcli02.c b/advio/tcpcli02.c
new file mode 100644 (file)
index 0000000..af1f1bf
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/advio/tcpcli03.c b/advio/tcpcli03.c
new file mode 100644 (file)
index 0000000..af1f1bf
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/advio/tcpcli04.c b/advio/tcpcli04.c
new file mode 100644 (file)
index 0000000..af1f1bf
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/advio/tcpserv02.c b/advio/tcpserv02.c
new file mode 100644 (file)
index 0000000..a964276
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       pid_t                           childpid;
+       socklen_t                       clilen;
+       struct sockaddr_in      cliaddr, servaddr;
+       void                            sig_chld(int);
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       Signal(SIGCHLD, sig_chld);
+
+       for ( ; ; ) {
+               clilen = sizeof(cliaddr);
+               if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
+                       if (errno == EINTR)
+                               continue;               /* back to for() */
+                       else
+                               err_sys("accept error");
+               }
+
+               if ( (childpid = Fork()) == 0) {        /* child process */
+                       Close(listenfd);        /* close listening socket */
+                       str_echo(connfd);       /* process the request */
+                       exit(0);
+               }
+               Close(connfd);                  /* parent closes connected socket */
+       }
+}
diff --git a/advio/udpcli01.c b/advio/udpcli01.c
new file mode 100644 (file)
index 0000000..01beb88
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(7);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/advio/udpcli02.c b/advio/udpcli02.c
new file mode 100644 (file)
index 0000000..01beb88
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(7);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/advio/udpcli03.c b/advio/udpcli03.c
new file mode 100644 (file)
index 0000000..01beb88
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(7);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/advio/udpserv01.c b/advio/udpserv01.c
new file mode 100644 (file)
index 0000000..a21a857
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr, cliaddr;
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
+}
diff --git a/advio/udpserv03.c b/advio/udpserv03.c
new file mode 100644 (file)
index 0000000..02e5b60
--- /dev/null
@@ -0,0 +1,101 @@
+/* include udpserv1 */
+#include       "unpifi.h"
+
+void   mydg_echo(int, SA *, socklen_t, SA *);
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       const int                       on = 1;
+       pid_t                           pid;
+       struct ifi_info         *ifi, *ifihead;
+       struct sockaddr_in      *sa, cliaddr, wildaddr;
+
+       for (ifihead = ifi = Get_ifi_info(AF_INET, 1);
+                ifi != NULL; ifi = ifi->ifi_next) {
+
+                       /*4bind unicast address */
+               sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+               Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+               sa = (struct sockaddr_in *) ifi->ifi_addr;
+               sa->sin_family = AF_INET;
+               sa->sin_port = htons(SERV_PORT);
+               Bind(sockfd, (SA *) sa, sizeof(*sa));
+               printf("bound %s\n", Sock_ntop((SA *) sa, sizeof(*sa)));
+
+               if ( (pid = Fork()) == 0) {             /* child */
+                       mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr), (SA *) sa);
+                       exit(0);                /* never executed */
+               }
+/* end udpserv1 */
+/* include udpserv2 */
+               if (ifi->ifi_flags & IFF_BROADCAST) {
+                               /* 4try to bind broadcast address */
+                       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+                       Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+                       sa = (struct sockaddr_in *) ifi->ifi_brdaddr;
+                       sa->sin_family = AF_INET;
+                       sa->sin_port = htons(SERV_PORT);
+                       if (bind(sockfd, (SA *) sa, sizeof(*sa)) < 0) {
+                               if (errno == EADDRINUSE) {
+                                       printf("EADDRINUSE: %s\n",
+                                                  Sock_ntop((SA *) sa, sizeof(*sa)));
+                                       Close(sockfd);
+                                       continue;
+                               } else
+                                       err_sys("bind error for %s",
+                                                       Sock_ntop((SA *) sa, sizeof(*sa)));
+                       }
+                       printf("bound %s\n", Sock_ntop((SA *) sa, sizeof(*sa)));
+
+                       if ( (pid = Fork()) == 0) {             /* child */
+                               mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr),
+                                                 (SA *) sa);
+                               exit(0);                /* never executed */
+                       }
+               }
+       }
+/* end udpserv2 */
+/* include udpserv3 */
+               /* 4bind wildcard address */
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+       Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+       bzero(&wildaddr, sizeof(wildaddr));
+       wildaddr.sin_family = AF_INET;
+       wildaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       wildaddr.sin_port = htons(SERV_PORT);
+       Bind(sockfd, (SA *) &wildaddr, sizeof(wildaddr));
+       printf("bound %s\n", Sock_ntop((SA *) &wildaddr, sizeof(wildaddr)));
+
+       if ( (pid = Fork()) == 0) {             /* child */
+               mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr), (SA *) sa);
+               exit(0);                /* never executed */
+       }
+       exit(0);
+}
+/* end udpserv3 */
+
+/* include mydg_echo */
+void
+mydg_echo(int sockfd, SA *pcliaddr, socklen_t clilen, SA *myaddr)
+{
+       int                     n;
+       char            mesg[MAXLINE];
+       socklen_t       len;
+
+       for ( ; ; ) {
+               len = clilen;
+               n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
+               printf("child %d, datagram from %s", getpid(),
+                          Sock_ntop(pcliaddr, len));
+               printf(", to %s\n", Sock_ntop(myaddr, clilen));
+
+               Sendto(sockfd, mesg, n, 0, pcliaddr, len);
+       }
+}
+/* end mydg_echo */
diff --git a/advio/udpserv03.lc b/advio/udpserv03.lc
new file mode 100644 (file)
index 0000000..f342f38
--- /dev/null
@@ -0,0 +1,101 @@
+/* include udpserv1 */
+#include    "unpifi.h"##  1 ##src/advio/udpserv03.c##
+
+void    mydg_echo(int, SA *, socklen_t, SA *);##  2 ##src/advio/udpserv03.c##
+
+int##  3 ##src/advio/udpserv03.c##
+main(int argc, char **argv)##  4 ##src/advio/udpserv03.c##
+{##  5 ##src/advio/udpserv03.c##
+    int     sockfd;##  6 ##src/advio/udpserv03.c##
+    const int on = 1;##  7 ##src/advio/udpserv03.c##
+    pid_t   pid;##  8 ##src/advio/udpserv03.c##
+    struct ifi_info *ifi, *ifihead;##  9 ##src/advio/udpserv03.c##
+    struct sockaddr_in *sa, cliaddr, wildaddr;## 10 ##src/advio/udpserv03.c##
+
+    for (ifihead = ifi = Get_ifi_info(AF_INET, 1);## 11 ##src/advio/udpserv03.c##
+         ifi != NULL; ifi = ifi->ifi_next) {## 12 ##src/advio/udpserv03.c##
+
+        /* 4bind unicast address */## 13 ##src/advio/udpserv03.c##
+        sockfd = Socket(AF_INET, SOCK_DGRAM, 0);## 14 ##src/advio/udpserv03.c##
+
+        Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 15 ##src/advio/udpserv03.c##
+
+        sa = (struct sockaddr_in *) ifi->ifi_addr;## 16 ##src/advio/udpserv03.c##
+        sa->sin_family = AF_INET;## 17 ##src/advio/udpserv03.c##
+        sa->sin_port = htons(SERV_PORT);## 18 ##src/advio/udpserv03.c##
+        Bind(sockfd, (SA *) sa, sizeof(*sa));## 19 ##src/advio/udpserv03.c##
+        printf("bound %s\n", Sock_ntop((SA *) sa, sizeof(*sa)));## 20 ##src/advio/udpserv03.c##
+
+        if ((pid = Fork()) == 0) {  /* child */## 21 ##src/advio/udpserv03.c##
+            mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr), (SA *) sa);## 22 ##src/advio/udpserv03.c##
+            exit(0);            /* never executed */## 23 ##src/advio/udpserv03.c##
+        }## 24 ##src/advio/udpserv03.c##
+/* end udpserv1 */
+/* include udpserv2 */
+        if (ifi->ifi_flags & IFF_BROADCAST) {## 25 ##src/advio/udpserv03.c##
+            /* 4try to bind broadcast address */## 26 ##src/advio/udpserv03.c##
+            sockfd = Socket(AF_INET, SOCK_DGRAM, 0);## 27 ##src/advio/udpserv03.c##
+            Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 28 ##src/advio/udpserv03.c##
+
+            sa = (struct sockaddr_in *) ifi->ifi_brdaddr;## 29 ##src/advio/udpserv03.c##
+            sa->sin_family = AF_INET;## 30 ##src/advio/udpserv03.c##
+            sa->sin_port = htons(SERV_PORT);## 31 ##src/advio/udpserv03.c##
+            if (bind(sockfd, (SA *) sa, sizeof(*sa)) < 0) {## 32 ##src/advio/udpserv03.c##
+                if (errno == EADDRINUSE) {## 33 ##src/advio/udpserv03.c##
+                    printf("EADDRINUSE: %s\n",## 34 ##src/advio/udpserv03.c##
+                           Sock_ntop((SA *) sa, sizeof(*sa)));## 35 ##src/advio/udpserv03.c##
+                    Close(sockfd);## 36 ##src/advio/udpserv03.c##
+                    continue;## 37 ##src/advio/udpserv03.c##
+                } else## 38 ##src/advio/udpserv03.c##
+                    err_sys("bind error for %s",## 39 ##src/advio/udpserv03.c##
+                            Sock_ntop((SA *) sa, sizeof(*sa)));## 40 ##src/advio/udpserv03.c##
+            }## 41 ##src/advio/udpserv03.c##
+            printf("bound %s\n", Sock_ntop((SA *) sa, sizeof(*sa)));## 42 ##src/advio/udpserv03.c##
+
+            if ((pid = Fork()) == 0) {  /* child */## 43 ##src/advio/udpserv03.c##
+                mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr),## 44 ##src/advio/udpserv03.c##
+                          (SA *) sa);## 45 ##src/advio/udpserv03.c##
+                exit(0);        /* never executed */## 46 ##src/advio/udpserv03.c##
+            }## 47 ##src/advio/udpserv03.c##
+        }## 48 ##src/advio/udpserv03.c##
+    }## 49 ##src/advio/udpserv03.c##
+/* end udpserv2 */
+/* include udpserv3 */
+    /* 4bind wildcard address */## 50 ##src/advio/udpserv03.c##
+    sockfd = Socket(AF_INET, SOCK_DGRAM, 0);## 51 ##src/advio/udpserv03.c##
+    Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 52 ##src/advio/udpserv03.c##
+
+    bzero(&wildaddr, sizeof(wildaddr));## 53 ##src/advio/udpserv03.c##
+    wildaddr.sin_family = AF_INET;## 54 ##src/advio/udpserv03.c##
+    wildaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 55 ##src/advio/udpserv03.c##
+    wildaddr.sin_port = htons(SERV_PORT);## 56 ##src/advio/udpserv03.c##
+    Bind(sockfd, (SA *) &wildaddr, sizeof(wildaddr));## 57 ##src/advio/udpserv03.c##
+    printf("bound %s\n", Sock_ntop((SA *) &wildaddr, sizeof(wildaddr)));## 58 ##src/advio/udpserv03.c##
+
+    if ((pid = Fork()) == 0) {  /* child */## 59 ##src/advio/udpserv03.c##
+        mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr), (SA *) sa);## 60 ##src/advio/udpserv03.c##
+        exit(0);                /* never executed */## 61 ##src/advio/udpserv03.c##
+    }## 62 ##src/advio/udpserv03.c##
+    exit(0);## 63 ##src/advio/udpserv03.c##
+}## 64 ##src/advio/udpserv03.c##
+/* end udpserv3 */
+
+/* include mydg_echo */
+void## 65 ##src/advio/udpserv03.c##
+mydg_echo(int sockfd, SA *pcliaddr, socklen_t clilen, SA *myaddr)## 66 ##src/advio/udpserv03.c##
+{## 67 ##src/advio/udpserv03.c##
+    int     n;## 68 ##src/advio/udpserv03.c##
+    char    mesg[MAXLINE];## 69 ##src/advio/udpserv03.c##
+    socklen_t len;## 70 ##src/advio/udpserv03.c##
+
+    for (;;) {## 71 ##src/advio/udpserv03.c##
+        len = clilen;## 72 ##src/advio/udpserv03.c##
+        n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);## 73 ##src/advio/udpserv03.c##
+        printf("child %d, datagram from %s", getpid(),## 74 ##src/advio/udpserv03.c##
+               Sock_ntop(pcliaddr, len));## 75 ##src/advio/udpserv03.c##
+        printf(", to %s\n", Sock_ntop(myaddr, clilen));## 76 ##src/advio/udpserv03.c##
+
+        Sendto(sockfd, mesg, n, 0, pcliaddr, len);## 77 ##src/advio/udpserv03.c##
+    }## 78 ##src/advio/udpserv03.c##
+}## 79 ##src/advio/udpserv03.c##
+/* end mydg_echo */
diff --git a/advio/udpserv04.c b/advio/udpserv04.c
new file mode 100644 (file)
index 0000000..e4f37ce
--- /dev/null
@@ -0,0 +1,103 @@
+#include       "unpifi.h"
+
+void   mydg_echo(int, SA *, socklen_t);
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, family, port;
+       const int                       on = 1;
+       pid_t                           pid;
+       socklen_t                       salen;
+       struct sockaddr         *sa, *wild;
+       struct ifi_info         *ifi, *ifihead;
+
+       if (argc == 2)
+               sockfd = Udp_client(NULL, argv[1], (void **) &sa, &salen);
+       else if (argc == 3)
+               sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);
+       else
+               err_quit("usage: udpserv04 [ <host> ] <service or port>");
+       family = sa->sa_family;
+       port = sock_get_port(sa, salen);
+       Close(sockfd);          /* we just want family, port, salen */
+
+       for (ifihead = ifi = Get_ifi_info(family, 1);
+                ifi != NULL; ifi = ifi->ifi_next) {
+
+                       /*4bind unicast address */
+               sockfd = Socket(family, SOCK_DGRAM, 0);
+               Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+               sock_set_port(ifi->ifi_addr, salen, port);
+               Bind(sockfd, ifi->ifi_addr, salen);
+               printf("bound %s\n", Sock_ntop(ifi->ifi_addr, salen));
+
+               if ( (pid = Fork()) == 0) {             /* child */
+                       mydg_echo(sockfd, ifi->ifi_addr, salen);
+                       exit(0);                /* never executed */
+               }
+
+               if (ifi->ifi_flags & IFF_BROADCAST) {
+                               /* 4try to bind broadcast address */
+                       sockfd = Socket(family, SOCK_DGRAM, 0);
+                       Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+                       sock_set_port(ifi->ifi_brdaddr, salen, port);
+                       if (bind(sockfd, ifi->ifi_brdaddr, salen) < 0) {
+                               if (errno == EADDRINUSE) {
+                                       printf("EADDRINUSE: %s\n",
+                                                  Sock_ntop(ifi->ifi_brdaddr, salen));
+                                       Close(sockfd);
+                                       continue;
+                               } else
+                                       err_sys("bind error for %s",
+                                                       Sock_ntop(ifi->ifi_brdaddr, salen));
+                       }
+                       printf("bound %s\n", Sock_ntop(ifi->ifi_brdaddr, salen));
+
+                       if ( (pid = Fork()) == 0) {             /* child */
+                               mydg_echo(sockfd, ifi->ifi_brdaddr, salen);
+                               exit(0);                /* never executed */
+                       }
+               }
+       }
+
+               /* 4bind wildcard address */
+       sockfd = Socket(family, SOCK_DGRAM, 0);
+       Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+       wild = Malloc(salen);
+       memcpy(wild, sa, salen);        /* copy family and port */
+       sock_set_wild(wild, salen);
+
+       Bind(sockfd, wild, salen);
+       printf("bound %s\n", Sock_ntop(wild, salen));
+
+       if ( (pid = Fork()) == 0) {             /* child */
+               mydg_echo(sockfd, wild, salen);
+               exit(0);                /* never executed */
+       }
+       exit(0);
+}
+
+void
+mydg_echo(int sockfd, SA *myaddr, socklen_t salen)
+{
+       int                     n;
+       char            mesg[MAXLINE];
+       socklen_t       len;
+       struct sockaddr *cli;
+
+       cli = Malloc(salen);
+
+       for ( ; ; ) {
+               len = salen;
+               n = Recvfrom(sockfd, mesg, MAXLINE, 0, cli, &len);
+               printf("child %d, datagram from %s",
+                          getpid(), Sock_ntop(cli, len));
+               printf(", to %s\n", Sock_ntop(myaddr, salen));
+
+               Sendto(sockfd, mesg, n, 0, cli, len);
+       }
+}
diff --git a/advio/udpserv04.lc b/advio/udpserv04.lc
new file mode 100644 (file)
index 0000000..b20a60b
--- /dev/null
@@ -0,0 +1,102 @@
+#include    "unpifi.h"##  1 ##src/advio/udpserv04.c##
+
+void    mydg_echo(int, SA *, socklen_t);##  2 ##src/advio/udpserv04.c##
+
+int##  3 ##src/advio/udpserv04.c##
+main(int argc, char **argv)##  4 ##src/advio/udpserv04.c##
+{##  5 ##src/advio/udpserv04.c##
+    int     sockfd, family, port;##  6 ##src/advio/udpserv04.c##
+    const int on = 1;##  7 ##src/advio/udpserv04.c##
+    pid_t   pid;##  8 ##src/advio/udpserv04.c##
+    socklen_t salen;##  9 ##src/advio/udpserv04.c##
+    struct sockaddr *sa, *wild;## 10 ##src/advio/udpserv04.c##
+    struct ifi_info *ifi, *ifihead;## 11 ##src/advio/udpserv04.c##
+
+    if (argc == 2)## 12 ##src/advio/udpserv04.c##
+        sockfd = Udp_client(NULL, argv[1], (void **) &sa, &salen);## 13 ##src/advio/udpserv04.c##
+    else if (argc == 3)## 14 ##src/advio/udpserv04.c##
+        sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);## 15 ##src/advio/udpserv04.c##
+    else## 16 ##src/advio/udpserv04.c##
+        err_quit("usage: udpserv04 [ <host> ] <service or port>");## 17 ##src/advio/udpserv04.c##
+    family = sa->sa_family;## 18 ##src/advio/udpserv04.c##
+    port = sock_get_port(sa, salen);## 19 ##src/advio/udpserv04.c##
+    Close(sockfd);              /* we just want family, port, salen */## 20 ##src/advio/udpserv04.c##
+
+    for (ifihead = ifi = Get_ifi_info(family, 1);## 21 ##src/advio/udpserv04.c##
+         ifi != NULL; ifi = ifi->ifi_next) {## 22 ##src/advio/udpserv04.c##
+
+        /* 4bind unicast address */## 23 ##src/advio/udpserv04.c##
+        sockfd = Socket(family, SOCK_DGRAM, 0);## 24 ##src/advio/udpserv04.c##
+        Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 25 ##src/advio/udpserv04.c##
+
+        sock_set_port(ifi->ifi_addr, salen, port);## 26 ##src/advio/udpserv04.c##
+        Bind(sockfd, ifi->ifi_addr, salen);## 27 ##src/advio/udpserv04.c##
+        printf("bound %s\n", Sock_ntop(ifi->ifi_addr, salen));## 28 ##src/advio/udpserv04.c##
+
+        if ((pid = Fork()) == 0) {  /* child */## 29 ##src/advio/udpserv04.c##
+            mydg_echo(sockfd, ifi->ifi_addr, salen);## 30 ##src/advio/udpserv04.c##
+            exit(0);            /* never executed */## 31 ##src/advio/udpserv04.c##
+        }## 32 ##src/advio/udpserv04.c##
+
+        if (ifi->ifi_flags & IFF_BROADCAST) {## 33 ##src/advio/udpserv04.c##
+            /* 4try to bind broadcast address */## 34 ##src/advio/udpserv04.c##
+            sockfd = Socket(family, SOCK_DGRAM, 0);## 35 ##src/advio/udpserv04.c##
+            Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 36 ##src/advio/udpserv04.c##
+
+            sock_set_port(ifi->ifi_brdaddr, salen, port);## 37 ##src/advio/udpserv04.c##
+            if (bind(sockfd, ifi->ifi_brdaddr, salen) < 0) {## 38 ##src/advio/udpserv04.c##
+                if (errno == EADDRINUSE) {## 39 ##src/advio/udpserv04.c##
+                    printf("EADDRINUSE: %s\n",## 40 ##src/advio/udpserv04.c##
+                           Sock_ntop(ifi->ifi_brdaddr, salen));## 41 ##src/advio/udpserv04.c##
+                    Close(sockfd);## 42 ##src/advio/udpserv04.c##
+                    continue;## 43 ##src/advio/udpserv04.c##
+                } else## 44 ##src/advio/udpserv04.c##
+                    err_sys("bind error for %s",## 45 ##src/advio/udpserv04.c##
+                            Sock_ntop(ifi->ifi_brdaddr, salen));## 46 ##src/advio/udpserv04.c##
+            }## 47 ##src/advio/udpserv04.c##
+            printf("bound %s\n", Sock_ntop(ifi->ifi_brdaddr, salen));## 48 ##src/advio/udpserv04.c##
+
+            if ((pid = Fork()) == 0) {  /* child */## 49 ##src/advio/udpserv04.c##
+                mydg_echo(sockfd, ifi->ifi_brdaddr, salen);## 50 ##src/advio/udpserv04.c##
+                exit(0);        /* never executed */## 51 ##src/advio/udpserv04.c##
+            }## 52 ##src/advio/udpserv04.c##
+        }## 53 ##src/advio/udpserv04.c##
+    }## 54 ##src/advio/udpserv04.c##
+
+    /* 4bind wildcard address */## 55 ##src/advio/udpserv04.c##
+    sockfd = Socket(family, SOCK_DGRAM, 0);## 56 ##src/advio/udpserv04.c##
+    Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 57 ##src/advio/udpserv04.c##
+
+    wild = Malloc(salen);## 58 ##src/advio/udpserv04.c##
+    memcpy(wild, sa, salen);    /* copy family and port */## 59 ##src/advio/udpserv04.c##
+    sock_set_wild(wild, salen);## 60 ##src/advio/udpserv04.c##
+
+    Bind(sockfd, wild, salen);## 61 ##src/advio/udpserv04.c##
+    printf("bound %s\n", Sock_ntop(wild, salen));## 62 ##src/advio/udpserv04.c##
+
+    if ((pid = Fork()) == 0) {  /* child */## 63 ##src/advio/udpserv04.c##
+        mydg_echo(sockfd, wild, salen);## 64 ##src/advio/udpserv04.c##
+        exit(0);                /* never executed */## 65 ##src/advio/udpserv04.c##
+    }## 66 ##src/advio/udpserv04.c##
+    exit(0);## 67 ##src/advio/udpserv04.c##
+}## 68 ##src/advio/udpserv04.c##
+
+void## 69 ##src/advio/udpserv04.c##
+mydg_echo(int sockfd, SA *myaddr, socklen_t salen)## 70 ##src/advio/udpserv04.c##
+{## 71 ##src/advio/udpserv04.c##
+    int     n;## 72 ##src/advio/udpserv04.c##
+    char    mesg[MAXLINE];## 73 ##src/advio/udpserv04.c##
+    socklen_t len;## 74 ##src/advio/udpserv04.c##
+    struct sockaddr *cli;## 75 ##src/advio/udpserv04.c##
+
+    cli = Malloc(salen);## 76 ##src/advio/udpserv04.c##
+
+    for (;;) {## 77 ##src/advio/udpserv04.c##
+        len = salen;## 78 ##src/advio/udpserv04.c##
+        n = Recvfrom(sockfd, mesg, MAXLINE, 0, cli, &len);## 79 ##src/advio/udpserv04.c##
+        printf("child %d, datagram from %s", getpid(), Sock_ntop(cli, len));## 80 ##src/advio/udpserv04.c##
+        printf(", to %s\n", Sock_ntop(myaddr, salen));## 81 ##src/advio/udpserv04.c##
+
+        Sendto(sockfd, mesg, n, 0, cli, len);## 82 ##src/advio/udpserv04.c##
+    }## 83 ##src/advio/udpserv04.c##
+}## 84 ##src/advio/udpserv04.c##
diff --git a/bcast/Makefile b/bcast/Makefile
new file mode 100644 (file)
index 0000000..022ce69
--- /dev/null
@@ -0,0 +1,32 @@
+include ../Make.defines
+
+PROGS =        udpcli01 udpcli02 udpcli03 udpcli04 udpcli05 udpcli06
+
+all:   ${PROGS}
+
+# Version in book.
+udpcli01:      udpcli01.o dgclibcast1.o
+               ${CC} ${CFLAGS} -o $@ udpcli01.o dgclibcast1.o ${LIBS}
+
+# Incorrect version with alarm(1) and sleep(1) to tickle race condition.
+udpcli02:      udpcli02.o dgclibcast2.o
+               ${CC} ${CFLAGS} -o $@ udpcli02.o dgclibcast2.o ${LIBS}
+
+# Incorrect version that blocks signals, but still has a race condition.
+udpcli03:      udpcli03.o dgclibcast3.o
+               ${CC} ${CFLAGS} -o $@ udpcli03.o dgclibcast3.o ${LIBS}
+
+# Correct version using pselect().
+udpcli04:      udpcli04.o dgclibcast4.o
+               ${CC} ${CFLAGS} -o $@ udpcli04.o dgclibcast4.o ${LIBS}
+
+# Correct version using sigsetjmp()/siglongjmp().
+udpcli05:      udpcli05.o dgclibcast5.o
+               ${CC} ${CFLAGS} -o $@ udpcli05.o dgclibcast5.o ${LIBS}
+
+# Correct version using a pipe from signal handler to select().
+udpcli06:      udpcli06.o dgclibcast6.o
+               ${CC} ${CFLAGS} -o $@ udpcli06.o dgclibcast6.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/bcast/dgclibcast1.c b/bcast/dgclibcast1.c
new file mode 100644 (file)
index 0000000..2889f0a
--- /dev/null
@@ -0,0 +1,47 @@
+#include       "unp.h"
+
+static void    recvfrom_alarm(int);
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                             n;
+       const int               on = 1;
+       char                    sendline[MAXLINE], recvline[MAXLINE + 1];
+       socklen_t               len;
+       struct sockaddr *preply_addr;
+       preply_addr = Malloc(servlen);
+
+       Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+
+       Signal(SIGALRM, recvfrom_alarm);
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               alarm(5);
+               for ( ; ; ) {
+                       len = servlen;
+                       n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
+                       if (n < 0) {
+                               if (errno == EINTR)
+                                       break;          /* waited long enough for replies */
+                               else
+                                       err_sys("recvfrom error");
+                       } else {
+                               recvline[n] = 0;        /* null terminate */
+                               printf("from %s: %s",
+                                               Sock_ntop_host(preply_addr, len), recvline);
+                       }
+               }
+       }
+       free(preply_addr);
+}
+
+static void
+recvfrom_alarm(int signo)
+{
+       return;         /* just interrupt the recvfrom() */
+}
diff --git a/bcast/dgclibcast1.lc b/bcast/dgclibcast1.lc
new file mode 100644 (file)
index 0000000..5680acc
--- /dev/null
@@ -0,0 +1,46 @@
+#include    "unp.h"##  1 ##src/bcast/dgclibcast1.c##
+
+static void recvfrom_alarm(int);##  2 ##src/bcast/dgclibcast1.c##
+
+void##  3 ##src/bcast/dgclibcast1.c##
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)##  4 ##src/bcast/dgclibcast1.c##
+{##  5 ##src/bcast/dgclibcast1.c##
+    int     n;##  6 ##src/bcast/dgclibcast1.c##
+    const int on = 1;##  7 ##src/bcast/dgclibcast1.c##
+    char    sendline[MAXLINE], recvline[MAXLINE + 1];##  8 ##src/bcast/dgclibcast1.c##
+    socklen_t len;##  9 ##src/bcast/dgclibcast1.c##
+    struct sockaddr *preply_addr;## 10 ##src/bcast/dgclibcast1.c##
+
+    preply_addr = Malloc(servlen);## 11 ##src/bcast/dgclibcast1.c##
+
+    Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));## 12 ##src/bcast/dgclibcast1.c##
+
+    Signal(SIGALRM, recvfrom_alarm);## 13 ##src/bcast/dgclibcast1.c##
+
+    while (Fgets(sendline, MAXLINE, fp) != NULL) {## 14 ##src/bcast/dgclibcast1.c##
+
+        Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 15 ##src/bcast/dgclibcast1.c##
+
+        alarm(5);## 16 ##src/bcast/dgclibcast1.c##
+        for (;;) {## 17 ##src/bcast/dgclibcast1.c##
+            len = servlen;## 18 ##src/bcast/dgclibcast1.c##
+            n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);## 19 ##src/bcast/dgclibcast1.c##
+            if (n < 0) {## 20 ##src/bcast/dgclibcast1.c##
+                if (errno == EINTR)## 21 ##src/bcast/dgclibcast1.c##
+                    break;      /* waited long enough for replies */## 22 ##src/bcast/dgclibcast1.c##
+                else## 23 ##src/bcast/dgclibcast1.c##
+                    err_sys("recvfrom error");## 24 ##src/bcast/dgclibcast1.c##
+            } else {## 25 ##src/bcast/dgclibcast1.c##
+                recvline[n] = 0;    /* null terminate */## 26 ##src/bcast/dgclibcast1.c##
+                printf("from %s: %s",## 27 ##src/bcast/dgclibcast1.c##
+                       Sock_ntop_host(preply_addr, len), recvline);## 28 ##src/bcast/dgclibcast1.c##
+            }## 29 ##src/bcast/dgclibcast1.c##
+        }## 30 ##src/bcast/dgclibcast1.c##
+    }## 31 ##src/bcast/dgclibcast1.c##
+}## 32 ##src/bcast/dgclibcast1.c##
+
+static void## 33 ##src/bcast/dgclibcast1.c##
+recvfrom_alarm(int signo)## 34 ##src/bcast/dgclibcast1.c##
+{## 35 ##src/bcast/dgclibcast1.c##
+    return;                     /* just interrupt the recvfrom() */## 36 ##src/bcast/dgclibcast1.c##
+}## 37 ##src/bcast/dgclibcast1.c##
diff --git a/bcast/dgclibcast2.c b/bcast/dgclibcast2.c
new file mode 100644 (file)
index 0000000..8a75094
--- /dev/null
@@ -0,0 +1,48 @@
+#include       "unp.h"
+
+static void    recvfrom_alarm(int);
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                             n;
+       const int               on = 1;
+       char                    sendline[MAXLINE], recvline[MAXLINE + 1];
+       socklen_t               len;
+       struct sockaddr *preply_addr;
+       preply_addr = Malloc(servlen);
+
+       Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+
+       Signal(SIGALRM, recvfrom_alarm);
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               alarm(1);
+               for ( ; ; ) {
+                       len = servlen;
+                       n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
+                       if (n == -1) {
+                               if (errno == EINTR)
+                                       break;          /* waited long enough for replies */
+                               else
+                                       err_sys("recvfrom error");
+                       } else {
+                               recvline[n] = 0;        /* null terminate */
+                               sleep(1);
+                               printf("from %s: %s",
+                                               Sock_ntop_host(preply_addr, len), recvline);
+                       }
+               }
+       }
+       free(preply_addr);
+}
+
+static void
+recvfrom_alarm(int signo)
+{
+       return;         /* just interrupt the recvfrom() */
+}
diff --git a/bcast/dgclibcast3.c b/bcast/dgclibcast3.c
new file mode 100644 (file)
index 0000000..ef1354f
--- /dev/null
@@ -0,0 +1,53 @@
+#include       "unp.h"
+
+static void    recvfrom_alarm(int);
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                             n;
+       const int               on = 1;
+       char                    sendline[MAXLINE], recvline[MAXLINE + 1];
+       sigset_t                sigset_alrm;
+       socklen_t               len;
+       struct sockaddr *preply_addr;
+       preply_addr = Malloc(servlen);
+
+       Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+
+       Sigemptyset(&sigset_alrm);
+       Sigaddset(&sigset_alrm, SIGALRM);
+
+       Signal(SIGALRM, recvfrom_alarm);
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               alarm(5);
+               for ( ; ; ) {
+                       len = servlen;
+                       Sigprocmask(SIG_UNBLOCK, &sigset_alrm, NULL);
+                       n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
+                       Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);
+                       if (n < 0) {
+                               if (errno == EINTR)
+                                       break;          /* waited long enough for replies */
+                               else
+                                       err_sys("recvfrom error");
+                       } else {
+                               recvline[n] = 0;        /* null terminate */
+                               printf("from %s: %s",
+                                               Sock_ntop_host(preply_addr, len), recvline);
+                       }
+               }
+       }
+       free(preply_addr);
+}
+
+static void
+recvfrom_alarm(int signo)
+{
+       return;         /* just interrupt the recvfrom() */
+}
diff --git a/bcast/dgclibcast3.lc b/bcast/dgclibcast3.lc
new file mode 100644 (file)
index 0000000..711841e
--- /dev/null
@@ -0,0 +1,52 @@
+#include    "unp.h"##  1 ##src/bcast/dgclibcast3.c##
+
+static void recvfrom_alarm(int);##  2 ##src/bcast/dgclibcast3.c##
+
+void##  3 ##src/bcast/dgclibcast3.c##
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)##  4 ##src/bcast/dgclibcast3.c##
+{##  5 ##src/bcast/dgclibcast3.c##
+    int     n;##  6 ##src/bcast/dgclibcast3.c##
+    const int on = 1;##  7 ##src/bcast/dgclibcast3.c##
+    char    sendline[MAXLINE], recvline[MAXLINE + 1];##  8 ##src/bcast/dgclibcast3.c##
+    sigset_t sigset_alrm;##  9 ##src/bcast/dgclibcast3.c##
+    socklen_t len;## 10 ##src/bcast/dgclibcast3.c##
+    struct sockaddr *preply_addr;## 11 ##src/bcast/dgclibcast3.c##
+
+    preply_addr = Malloc(servlen);## 12 ##src/bcast/dgclibcast3.c##
+
+    Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));## 13 ##src/bcast/dgclibcast3.c##
+
+    Sigemptyset(&sigset_alrm);## 14 ##src/bcast/dgclibcast3.c##
+    Sigaddset(&sigset_alrm, SIGALRM);## 15 ##src/bcast/dgclibcast3.c##
+
+    Signal(SIGALRM, recvfrom_alarm);## 16 ##src/bcast/dgclibcast3.c##
+
+    while (Fgets(sendline, MAXLINE, fp) != NULL) {## 17 ##src/bcast/dgclibcast3.c##
+
+        Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 18 ##src/bcast/dgclibcast3.c##
+
+        alarm(5);## 19 ##src/bcast/dgclibcast3.c##
+        for (;;) {## 20 ##src/bcast/dgclibcast3.c##
+            len = servlen;## 21 ##src/bcast/dgclibcast3.c##
+            Sigprocmask(SIG_UNBLOCK, &sigset_alrm, NULL);## 22 ##src/bcast/dgclibcast3.c##
+            n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);## 23 ##src/bcast/dgclibcast3.c##
+            Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);## 24 ##src/bcast/dgclibcast3.c##
+            if (n < 0) {## 25 ##src/bcast/dgclibcast3.c##
+                if (errno == EINTR)## 26 ##src/bcast/dgclibcast3.c##
+                    break;      /* waited long enough for replies */## 27 ##src/bcast/dgclibcast3.c##
+                else## 28 ##src/bcast/dgclibcast3.c##
+                    err_sys("recvfrom error");## 29 ##src/bcast/dgclibcast3.c##
+            } else {## 30 ##src/bcast/dgclibcast3.c##
+                recvline[n] = 0;    /* null terminate */## 31 ##src/bcast/dgclibcast3.c##
+                printf("from %s: %s",## 32 ##src/bcast/dgclibcast3.c##
+                       Sock_ntop_host(preply_addr, len), recvline);## 33 ##src/bcast/dgclibcast3.c##
+            }## 34 ##src/bcast/dgclibcast3.c##
+        }## 35 ##src/bcast/dgclibcast3.c##
+    }## 36 ##src/bcast/dgclibcast3.c##
+}## 37 ##src/bcast/dgclibcast3.c##
+
+static void## 38 ##src/bcast/dgclibcast3.c##
+recvfrom_alarm(int signo)## 39 ##src/bcast/dgclibcast3.c##
+{## 40 ##src/bcast/dgclibcast3.c##
+    return;                     /* just interrupt the recvfrom() */## 41 ##src/bcast/dgclibcast3.c##
+}## 42 ##src/bcast/dgclibcast3.c##
diff --git a/bcast/dgclibcast4.c b/bcast/dgclibcast4.c
new file mode 100644 (file)
index 0000000..85656b9
--- /dev/null
@@ -0,0 +1,58 @@
+#include       "unp.h"
+
+static void    recvfrom_alarm(int);
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                             n;
+       const int               on = 1;
+       char                    sendline[MAXLINE], recvline[MAXLINE + 1];
+       fd_set                  rset;
+       sigset_t                sigset_alrm, sigset_empty;
+       socklen_t               len;
+       struct sockaddr *preply_addr;
+       preply_addr = Malloc(servlen);
+
+       Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+
+       FD_ZERO(&rset);
+
+       Sigemptyset(&sigset_empty);
+       Sigemptyset(&sigset_alrm);
+       Sigaddset(&sigset_alrm, SIGALRM);
+
+       Signal(SIGALRM, recvfrom_alarm);
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);
+               alarm(5);
+               for ( ; ; ) {
+                       FD_SET(sockfd, &rset);
+                       n = pselect(sockfd+1, &rset, NULL, NULL, NULL, &sigset_empty);
+                       if (n < 0) {
+                               if (errno == EINTR)
+                                       break;
+                               else
+                                       err_sys("pselect error");
+                       } else if (n != 1)
+                               err_sys("pselect error: returned %d", n);
+
+                       len = servlen;
+                       n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
+                       recvline[n] = 0;        /* null terminate */
+                       printf("from %s: %s",
+                                       Sock_ntop_host(preply_addr, len), recvline);
+               }
+       }
+       free(preply_addr);
+}
+
+static void
+recvfrom_alarm(int signo)
+{
+       return;         /* just interrupt the recvfrom() */
+}
diff --git a/bcast/dgclibcast4.lc b/bcast/dgclibcast4.lc
new file mode 100644 (file)
index 0000000..09f1d9f
--- /dev/null
@@ -0,0 +1,57 @@
+#include    "unp.h"##  1 ##src/bcast/dgclibcast4.c##
+
+static void recvfrom_alarm(int);##  2 ##src/bcast/dgclibcast4.c##
+
+void##  3 ##src/bcast/dgclibcast4.c##
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)##  4 ##src/bcast/dgclibcast4.c##
+{##  5 ##src/bcast/dgclibcast4.c##
+    int     n;##  6 ##src/bcast/dgclibcast4.c##
+    const int on = 1;##  7 ##src/bcast/dgclibcast4.c##
+    char    sendline[MAXLINE], recvline[MAXLINE + 1];##  8 ##src/bcast/dgclibcast4.c##
+    fd_set  rset;##  9 ##src/bcast/dgclibcast4.c##
+    sigset_t sigset_alrm, sigset_empty;## 10 ##src/bcast/dgclibcast4.c##
+    socklen_t len;## 11 ##src/bcast/dgclibcast4.c##
+    struct sockaddr *preply_addr;## 12 ##src/bcast/dgclibcast4.c##
+
+    preply_addr = Malloc(servlen);## 13 ##src/bcast/dgclibcast4.c##
+
+    Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));## 14 ##src/bcast/dgclibcast4.c##
+
+    FD_ZERO(&rset);## 15 ##src/bcast/dgclibcast4.c##
+
+    Sigemptyset(&sigset_empty);## 16 ##src/bcast/dgclibcast4.c##
+    Sigemptyset(&sigset_alrm);## 17 ##src/bcast/dgclibcast4.c##
+    Sigaddset(&sigset_alrm, SIGALRM);## 18 ##src/bcast/dgclibcast4.c##
+
+    Signal(SIGALRM, recvfrom_alarm);## 19 ##src/bcast/dgclibcast4.c##
+
+    while (Fgets(sendline, MAXLINE, fp) != NULL) {## 20 ##src/bcast/dgclibcast4.c##
+        Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 21 ##src/bcast/dgclibcast4.c##
+
+        Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);## 22 ##src/bcast/dgclibcast4.c##
+        alarm(5);## 23 ##src/bcast/dgclibcast4.c##
+        for (;;) {## 24 ##src/bcast/dgclibcast4.c##
+            FD_SET(sockfd, &rset);## 25 ##src/bcast/dgclibcast4.c##
+            n = pselect(sockfd + 1, &rset, NULL, NULL, NULL, &sigset_empty);## 26 ##src/bcast/dgclibcast4.c##
+            if (n < 0) {## 27 ##src/bcast/dgclibcast4.c##
+                if (errno == EINTR)## 28 ##src/bcast/dgclibcast4.c##
+                    break;## 29 ##src/bcast/dgclibcast4.c##
+                else## 30 ##src/bcast/dgclibcast4.c##
+                    err_sys("pselect error");## 31 ##src/bcast/dgclibcast4.c##
+            } else if (n != 1)## 32 ##src/bcast/dgclibcast4.c##
+                err_sys("pselect error: returned %d", n);## 33 ##src/bcast/dgclibcast4.c##
+
+            len = servlen;## 34 ##src/bcast/dgclibcast4.c##
+            n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);## 35 ##src/bcast/dgclibcast4.c##
+            recvline[n] = 0;    /* null terminate */## 36 ##src/bcast/dgclibcast4.c##
+            printf("from %s: %s",## 37 ##src/bcast/dgclibcast4.c##
+                   Sock_ntop_host(preply_addr, len), recvline);## 38 ##src/bcast/dgclibcast4.c##
+        }## 39 ##src/bcast/dgclibcast4.c##
+    }## 40 ##src/bcast/dgclibcast4.c##
+}## 41 ##src/bcast/dgclibcast4.c##
+
+static void## 42 ##src/bcast/dgclibcast4.c##
+recvfrom_alarm(int signo)## 43 ##src/bcast/dgclibcast4.c##
+{## 44 ##src/bcast/dgclibcast4.c##
+    return;                     /* just interrupt the recvfrom() */## 45 ##src/bcast/dgclibcast4.c##
+}## 46 ##src/bcast/dgclibcast4.c##
diff --git a/bcast/dgclibcast5.c b/bcast/dgclibcast5.c
new file mode 100644 (file)
index 0000000..edfe12c
--- /dev/null
@@ -0,0 +1,44 @@
+#include       "unp.h"
+#include       <setjmp.h>
+
+static void                    recvfrom_alarm(int);
+static sigjmp_buf      jmpbuf;
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                             n;
+       const int               on = 1;
+       char                    sendline[MAXLINE], recvline[MAXLINE + 1];
+       socklen_t               len;
+       struct sockaddr *preply_addr;
+       preply_addr = Malloc(servlen);
+
+       Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+
+       Signal(SIGALRM, recvfrom_alarm);
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               alarm(5);
+               for ( ; ; ) {
+                       if (sigsetjmp(jmpbuf, 1) != 0)
+                               break;
+                       len = servlen;
+                       n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
+                       recvline[n] = 0;        /* null terminate */
+                       printf("from %s: %s",
+                                       Sock_ntop_host(preply_addr, len), recvline);
+               }
+       }
+       free(preply_addr);
+}
+
+static void
+recvfrom_alarm(int signo)
+{
+       siglongjmp(jmpbuf, 1);
+}
diff --git a/bcast/dgclibcast5.lc b/bcast/dgclibcast5.lc
new file mode 100644 (file)
index 0000000..dfac0b2
--- /dev/null
@@ -0,0 +1,43 @@
+#include    "unp.h"##  1 ##src/bcast/dgclibcast5.c##
+#include    <setjmp.h>##  2 ##src/bcast/dgclibcast5.c##
+
+static void recvfrom_alarm(int);##  3 ##src/bcast/dgclibcast5.c##
+static sigjmp_buf jmpbuf;##  4 ##src/bcast/dgclibcast5.c##
+
+void##  5 ##src/bcast/dgclibcast5.c##
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)##  6 ##src/bcast/dgclibcast5.c##
+{##  7 ##src/bcast/dgclibcast5.c##
+    int     n;##  8 ##src/bcast/dgclibcast5.c##
+    const int on = 1;##  9 ##src/bcast/dgclibcast5.c##
+    char    sendline[MAXLINE], recvline[MAXLINE + 1];## 10 ##src/bcast/dgclibcast5.c##
+    socklen_t len;## 11 ##src/bcast/dgclibcast5.c##
+    struct sockaddr *preply_addr;## 12 ##src/bcast/dgclibcast5.c##
+
+    preply_addr = Malloc(servlen);## 13 ##src/bcast/dgclibcast5.c##
+
+    Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));## 14 ##src/bcast/dgclibcast5.c##
+
+    Signal(SIGALRM, recvfrom_alarm);## 15 ##src/bcast/dgclibcast5.c##
+
+    while (Fgets(sendline, MAXLINE, fp) != NULL) {## 16 ##src/bcast/dgclibcast5.c##
+
+        Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 17 ##src/bcast/dgclibcast5.c##
+
+        alarm(5);## 18 ##src/bcast/dgclibcast5.c##
+        for (;;) {## 19 ##src/bcast/dgclibcast5.c##
+            if (sigsetjmp(jmpbuf, 1) != 0)## 20 ##src/bcast/dgclibcast5.c##
+                break;## 21 ##src/bcast/dgclibcast5.c##
+            len = servlen;## 22 ##src/bcast/dgclibcast5.c##
+            n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);## 23 ##src/bcast/dgclibcast5.c##
+            recvline[n] = 0;    /* null terminate */## 24 ##src/bcast/dgclibcast5.c##
+            printf("from %s: %s",## 25 ##src/bcast/dgclibcast5.c##
+                   Sock_ntop_host(preply_addr, len), recvline);## 26 ##src/bcast/dgclibcast5.c##
+        }## 27 ##src/bcast/dgclibcast5.c##
+    }## 28 ##src/bcast/dgclibcast5.c##
+}## 29 ##src/bcast/dgclibcast5.c##
+
+static void## 30 ##src/bcast/dgclibcast5.c##
+recvfrom_alarm(int signo)## 31 ##src/bcast/dgclibcast5.c##
+{## 32 ##src/bcast/dgclibcast5.c##
+    siglongjmp(jmpbuf, 1);## 33 ##src/bcast/dgclibcast5.c##
+}## 34 ##src/bcast/dgclibcast5.c##
diff --git a/bcast/dgclibcast6.c b/bcast/dgclibcast6.c
new file mode 100644 (file)
index 0000000..1e6e1ed
--- /dev/null
@@ -0,0 +1,63 @@
+#include       "unp.h"
+
+static void    recvfrom_alarm(int);
+static int     pipefd[2];
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                             n, maxfdp1;
+       const int               on = 1;
+       char                    sendline[MAXLINE], recvline[MAXLINE + 1];
+       fd_set                  rset;
+       socklen_t               len;
+       struct sockaddr *preply_addr;
+       preply_addr = Malloc(servlen);
+
+       Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+
+       Pipe(pipefd);
+       maxfdp1 = max(sockfd, pipefd[0]) + 1;
+
+       FD_ZERO(&rset);
+
+       Signal(SIGALRM, recvfrom_alarm);
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               alarm(5);
+               for ( ; ; ) {
+                       FD_SET(sockfd, &rset);
+                       FD_SET(pipefd[0], &rset);
+                       if ( (n = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {
+                               if (errno == EINTR)
+                                       continue;
+                               else
+                                       err_sys("select error");
+                       }
+
+                       if (FD_ISSET(sockfd, &rset)) {
+                               len = servlen;
+                               n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
+                               recvline[n] = 0;        /* null terminate */
+                               printf("from %s: %s",
+                                               Sock_ntop_host(preply_addr, len), recvline);
+                       }
+
+                       if (FD_ISSET(pipefd[0], &rset)) {
+                               Read(pipefd[0], &n, 1);         /* timer expired */
+                               break;
+                       }
+               }
+       }
+       free(preply_addr);
+}
+
+static void
+recvfrom_alarm(int signo)
+{
+       Write(pipefd[1], "", 1);        /* write one null byte to pipe */
+       return;
+}
diff --git a/bcast/dgclibcast6.lc b/bcast/dgclibcast6.lc
new file mode 100644 (file)
index 0000000..cbd1ac1
--- /dev/null
@@ -0,0 +1,63 @@
+#include    "unp.h"##  1 ##src/bcast/dgclibcast6.c##
+
+static void recvfrom_alarm(int);##  2 ##src/bcast/dgclibcast6.c##
+static int pipefd[2];##  3 ##src/bcast/dgclibcast6.c##
+
+void##  4 ##src/bcast/dgclibcast6.c##
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)##  5 ##src/bcast/dgclibcast6.c##
+{##  6 ##src/bcast/dgclibcast6.c##
+    int     n, maxfdp1;##  7 ##src/bcast/dgclibcast6.c##
+    const int on = 1;##  8 ##src/bcast/dgclibcast6.c##
+    char    sendline[MAXLINE], recvline[MAXLINE + 1];##  9 ##src/bcast/dgclibcast6.c##
+    fd_set  rset;## 10 ##src/bcast/dgclibcast6.c##
+    socklen_t len;## 11 ##src/bcast/dgclibcast6.c##
+    struct sockaddr *preply_addr;## 12 ##src/bcast/dgclibcast6.c##
+
+    preply_addr = Malloc(servlen);## 13 ##src/bcast/dgclibcast6.c##
+
+    Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));## 14 ##src/bcast/dgclibcast6.c##
+
+    Pipe(pipefd);## 15 ##src/bcast/dgclibcast6.c##
+    maxfdp1 = max(sockfd, pipefd[0]) + 1;## 16 ##src/bcast/dgclibcast6.c##
+
+    FD_ZERO(&rset);## 17 ##src/bcast/dgclibcast6.c##
+
+    Signal(SIGALRM, recvfrom_alarm);## 18 ##src/bcast/dgclibcast6.c##
+
+    while (Fgets(sendline, MAXLINE, fp) != NULL) {## 19 ##src/bcast/dgclibcast6.c##
+        Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 20 ##src/bcast/dgclibcast6.c##
+
+        alarm(5);## 21 ##src/bcast/dgclibcast6.c##
+        for (;;) {## 22 ##src/bcast/dgclibcast6.c##
+            FD_SET(sockfd, &rset);## 23 ##src/bcast/dgclibcast6.c##
+            FD_SET(pipefd[0], &rset);## 24 ##src/bcast/dgclibcast6.c##
+            if ((n = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {## 25 ##src/bcast/dgclibcast6.c##
+                if (errno == EINTR)## 26 ##src/bcast/dgclibcast6.c##
+                    continue;## 27 ##src/bcast/dgclibcast6.c##
+                else## 28 ##src/bcast/dgclibcast6.c##
+                    err_sys("select error");## 29 ##src/bcast/dgclibcast6.c##
+            }## 30 ##src/bcast/dgclibcast6.c##
+
+            if (FD_ISSET(sockfd, &rset)) {## 31 ##src/bcast/dgclibcast6.c##
+                len = servlen;## 32 ##src/bcast/dgclibcast6.c##
+                n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr,## 33 ##src/bcast/dgclibcast6.c##
+                             &len);## 34 ##src/bcast/dgclibcast6.c##
+                recvline[n] = 0;    /* null terminate */## 35 ##src/bcast/dgclibcast6.c##
+                printf("from %s: %s",## 36 ##src/bcast/dgclibcast6.c##
+                       Sock_ntop_host(preply_addr, len), recvline);## 37 ##src/bcast/dgclibcast6.c##
+            }## 38 ##src/bcast/dgclibcast6.c##
+
+            if (FD_ISSET(pipefd[0], &rset)) {## 39 ##src/bcast/dgclibcast6.c##
+                Read(pipefd[0], &n, 1); /* timer expired */## 40 ##src/bcast/dgclibcast6.c##
+                break;## 41 ##src/bcast/dgclibcast6.c##
+            }## 42 ##src/bcast/dgclibcast6.c##
+        }## 43 ##src/bcast/dgclibcast6.c##
+    }## 44 ##src/bcast/dgclibcast6.c##
+}## 45 ##src/bcast/dgclibcast6.c##
+
+static void## 46 ##src/bcast/dgclibcast6.c##
+recvfrom_alarm(int signo)## 47 ##src/bcast/dgclibcast6.c##
+{## 48 ##src/bcast/dgclibcast6.c##
+    Write(pipefd[1], "", 1);    /* write 1 null byte to pipe */## 49 ##src/bcast/dgclibcast6.c##
+    return;## 50 ##src/bcast/dgclibcast6.c##
+}## 51 ##src/bcast/dgclibcast6.c##
diff --git a/bcast/udpcli01.c b/bcast/udpcli01.c
new file mode 100644 (file)
index 0000000..24a3e48
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli01 <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(13);          /* standard daytime server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/bcast/udpcli02.c b/bcast/udpcli02.c
new file mode 100644 (file)
index 0000000..b2d1d75
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli02 <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(13);          /* standard daytime server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/bcast/udpcli03.c b/bcast/udpcli03.c
new file mode 100644 (file)
index 0000000..93d26fd
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli03 <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(13);          /* standard daytime server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/bcast/udpcli04.c b/bcast/udpcli04.c
new file mode 100644 (file)
index 0000000..29dbbee
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli04 <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(13);          /* standard daytime server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/bcast/udpcli05.c b/bcast/udpcli05.c
new file mode 100644 (file)
index 0000000..dd0cad3
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli05 <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(13);          /* standard daytime server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/bcast/udpcli06.c b/bcast/udpcli06.c
new file mode 100644 (file)
index 0000000..b2d1d75
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli02 <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(13);          /* standard daytime server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/config.guess b/config.guess
new file mode 100755 (executable)
index 0000000..ed2e03b
--- /dev/null
@@ -0,0 +1,1321 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-03-20'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int dummy(){}" > $dummy.c ;
+       for c in cc gcc c89 c99 ; do
+         ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
+         if test $? = 0 ; then
+            CC_FOR_BUILD="$c"; break ;
+         fi ;
+       done ;
+       rm -f $dummy.c $dummy.o $dummy.rel ;
+       if test x"$CC_FOR_BUILD" = x ; then
+         CC_FOR_BUILD=no_compiler_found ;
+       fi
+       ;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+       # NetBSD (nbsd) targets should (where applicable) match one or
+       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+       # switched to ELF, *-*-netbsd* would select the old
+       # object file format.  This provides both forward
+       # compatibility and a consistent mechanism for selecting the
+       # object file format.
+       #
+       # Note: NetBSD doesn't particularly care about the vendor
+       # portion of the name.  We always set it to "unknown".
+       sysctl="sysctl -n hw.machine_arch"
+       UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+           /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+       case "${UNAME_MACHINE_ARCH}" in
+           arm*) machine=arm-unknown ;;
+           sh3el) machine=shl-unknown ;;
+           sh3eb) machine=sh-unknown ;;
+           *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+       esac
+       # The Operating System including object format, if it has switched
+       # to ELF recently, or will in the future.
+       case "${UNAME_MACHINE_ARCH}" in
+           arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+               eval $set_cc_for_build
+               if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+                       | grep __ELF__ >/dev/null
+               then
+                   # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+                   # Return netbsd for either.  FIX?
+                   os=netbsd
+               else
+                   os=netbsdelf
+               fi
+               ;;
+           *)
+               os=netbsd
+               ;;
+       esac
+       # The OS release
+       release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+       # contains redundant information, the shorter form:
+       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+       echo "${machine}-${os}${release}"
+       exit 0 ;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    macppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mipseb-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       cat <<EOF >$dummy.s
+       .data
+\$Lformat:
+       .byte 37,100,45,37,120,10,0     # "%d-%x\n"
+
+       .text
+       .globl main
+       .align 4
+       .ent main
+main:
+       .frame \$30,16,\$26,0
+       ldgp \$29,0(\$27)
+       .prologue 1
+       .long 0x47e03d80 # implver \$0
+       lda \$2,-1
+       .long 0x47e20c21 # amask \$2,\$1
+       lda \$16,\$Lformat
+       mov \$0,\$17
+       not \$1,\$18
+       jsr \$26,printf
+       ldgp \$29,0(\$26)
+       mov 0,\$16
+       jsr \$26,exit
+       .end main
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+       if test "$?" = 0 ; then
+               case `./$dummy` in
+                       0-0)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       1-0)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       1-1)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       1-101)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       2-303)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+                       2-307)
+                               UNAME_MACHINE="alphaev67"
+                               ;;
+                       2-1307)
+                               UNAME_MACHINE="alphaev68"
+                               ;;
+               esac
+       fi
+       rm -f $dummy.s $dummy
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # Should we change UNAME_MACHINE based on the output of uname instead
+       # of the specific Alpha model?
+       echo alpha-pc-interix
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-unknown-sysv4
+       exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-morphos
+       exit 0 ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       $CC_FOR_BUILD $dummy.c -o $dummy \
+         && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+       echo powerpc-motorola-powermax
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       then
+           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+           else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+           fi
+       else
+           echo i586-dg-dgux${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    ia64:AIX:*:*)
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               eval $set_cc_for_build
+               sed 's/^                //' << EOF >$dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+               rm -f $dummy.c $dummy
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:[45])
+       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/[678][0-9][0-9])
+               if [ -x /usr/bin/getconf ]; then
+                   sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+                         '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+               fi
+               if [ "${HP_ARCH}" = "" ]; then
+                   eval $set_cc_for_build
+                   sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+               {
+               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+               case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+                   switch (bits)
+                       {
+                       case 64: puts ("hppa2.0w"); break;
+                       case 32: puts ("hppa2.0n"); break;
+                       default: puts ("hppa2.0"); break;
+                       } break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+                   puts ("hppa2.0"); break;
+              #endif
+               default: puts ("hppa1.0"); break;
+               }
+                  exit (0);
+              }
+EOF
+                   (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy`
+                   if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+                   rm -f $dummy.c $dummy
+               fi ;;
+       esac
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    ia64:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i*86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+             -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3D:*:*:*)
+       echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3E:*:*:*)
+       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*SV1:*:*:*)
+       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit 0 ;;
+    i*:PW*:*)
+       echo ${UNAME_MACHINE}-pc-pw32
+       exit 0 ;;
+    x86:Interix*:3*)
+       echo i386-pc-interix3
+       exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+       # UNAME_MACHINE based on the output of uname instead of i386?
+       echo i386-pc-interix
+       exit 0 ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    i*86:Minix:*:*)
+       echo ${UNAME_MACHINE}-pc-minix
+       exit 0 ;;
+    arm*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    ia64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    m68*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    mips:Linux:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #undef CPU
+       #undef mips
+       #undef mipsel
+       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+       CPU=mipsel
+       #else
+       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+       CPU=mips
+       #else
+       CPU=
+       #endif
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+       rm -f $dummy.c
+       test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0
+       ;;
+    ppc:Linux:*:*)
+       echo powerpc-unknown-linux-gnu
+       exit 0 ;;
+    ppc64:Linux:*:*)
+       echo powerpc64-unknown-linux-gnu
+       exit 0 ;;
+    alpha:Linux:*:*)
+       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+         EV5)   UNAME_MACHINE=alphaev5 ;;
+         EV56)  UNAME_MACHINE=alphaev56 ;;
+         PCA56) UNAME_MACHINE=alphapca56 ;;
+         PCA57) UNAME_MACHINE=alphapca56 ;;
+         EV6)   UNAME_MACHINE=alphaev6 ;;
+         EV67)  UNAME_MACHINE=alphaev67 ;;
+         EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+       objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+       exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+       # Look for CPU level
+       case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+         PA7*) echo hppa1.1-unknown-linux-gnu ;;
+         PA8*) echo hppa2.0-unknown-linux-gnu ;;
+         *)    echo hppa-unknown-linux-gnu ;;
+       esac
+       exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+       echo hppa64-unknown-linux-gnu
+       exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+       echo ${UNAME_MACHINE}-ibm-linux
+       exit 0 ;;
+    sh*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    x86_64:Linux:*:*)
+       echo x86_64-unknown-linux-gnu
+       exit 0 ;;
+    i*86:Linux:*:*)
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us. cd to the root directory to prevent
+       # problems with other programs or directories called `ld' in the path.
+       # Set LC_ALL=C to ensure ld outputs messages in English.
+       ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+                        | sed -ne '/supported targets:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported targets: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_targets" in
+         elf32-i386)
+               TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+               ;;
+         a.out-i386-linux)
+               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+               exit 0 ;;               
+         coff-i386)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit 0 ;;
+         "")
+               # Either a pre-BFD a.out linker (linux-gnuoldld) or
+               # one that does not give us useful --help.
+               echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+               exit 0 ;;
+       esac
+       # Determine whether the default compiler is a.out or elf
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <features.h>
+       #ifdef __ELF__
+       # ifdef __GLIBC__
+       #  if __GLIBC__ >= 2
+       LIBC=gnu
+       #  else
+       LIBC=gnulibc1
+       #  endif
+       # else
+       LIBC=gnulibc1
+       # endif
+       #else
+       #ifdef __INTEL_COMPILER
+       LIBC=gnu
+       #else
+       LIBC=gnuaout
+       #endif
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       rm -f $dummy.c
+       test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+       test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+       ;;
+    i*86:DYNIX/ptx:4*:*)
+       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+       # earlier versions are messed up and put the nodename in both
+       # sysname and nodename.
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+       fi
+       exit 0 ;;
+    i*86:*:5:[78]*)
+       case `/bin/uname -X | grep "^Machine"` in
+           *486*)           UNAME_MACHINE=i486 ;;
+           *Pentium)        UNAME_MACHINE=i586 ;;
+           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+       esac
+       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    i*86:*DOS:*:*)
+       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       exit 0 ;;
+    pc:*:*:*)
+       # Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    *:VOS:*:*)
+       # From Paul.Green@stratus.com.
+       echo hppa1.1-stratus-vos
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:6*:*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit 0 ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit 0 ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Darwin:*:*)
+       echo `uname -p`-apple-darwin${UNAME_RELEASE}
+       exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+       UNAME_PROCESSOR=`uname -p`
+       if test "$UNAME_PROCESSOR" = "x86"; then
+               UNAME_PROCESSOR=i386
+               UNAME_MACHINE=pc
+       fi
+       echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+       exit 0 ;;
+    *:QNX:*:4*)
+       echo i386-pc-qnx
+       exit 0 ;;
+    NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk${UNAME_RELEASE}
+       exit 0 ;;
+    *:NonStop-UX:*:*)
+       echo mips-compaq-nonstopux
+       exit 0 ;;
+    BS2000:POSIX*:*:*)
+       echo bs2000-siemens-sysv
+       exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       exit 0 ;;
+    *:Plan9:*:*)
+       # "uname -m" is not consistent, so use $cputype instead. 386
+       # is converted to i386 for consistency with other x86
+       # operating systems.
+       if test "$cputype" = "386"; then
+           UNAME_MACHINE=i386
+       else
+           UNAME_MACHINE="$cputype"
+       fi
+       echo ${UNAME_MACHINE}-unknown-plan9
+       exit 0 ;;
+    i*86:OS/2:*:*)
+       # If we were able to find `uname', then EMX Unix compatibility
+       # is probably installed.
+       echo ${UNAME_MACHINE}-pc-os2-emx
+       exit 0 ;;
+    *:TOPS-10:*:*)
+       echo pdp10-unknown-tops10
+       exit 0 ;;
+    *:TENEX:*:*)
+       echo pdp10-unknown-tenex
+       exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+       echo pdp10-dec-tops20
+       exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+       echo pdp10-xkl-tops20
+       exit 0 ;;
+    *:TOPS-20:*:*)
+       echo pdp10-unknown-tops20
+       exit 0 ;;
+    *:ITS:*:*)
+       echo pdp10-unknown-its
+       exit 0 ;;
+    i*86:XTS-300:*:STOP)
+       echo ${UNAME_MACHINE}-unknown-stop
+       exit 0 ;;
+    i*86:atheos:*:*)
+       echo ${UNAME_MACHINE}-unknown-atheos
+       exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.h.in b/config.h.in
new file mode 100644 (file)
index 0000000..7bef959
--- /dev/null
@@ -0,0 +1,325 @@
+/* config.h.in.  Generated from configure.in by autoheader.  */
+
+/* CPU, vendor, and operating system */
+#undef CPU_VENDOR_OS
+
+/* Define to 1 if <netdb.h> defines struct addrinfo */
+#undef HAVE_ADDRINFO_STRUCT
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define to 1 if you have the `bzero' function. */
+#undef HAVE_BZERO
+
+/* Define to 1 if the /dev/streams/xtiso/tcp device exists */
+#undef HAVE_DEV_STREAMS_XTISO_TCP
+
+/* Define to 1 if the /dev/tcp device exists */
+#undef HAVE_DEV_TCP
+
+/* Define to 1 if the /dev/xti/tcp device exists */
+#undef HAVE_DEV_XTI_TCP
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `getaddrinfo' function. */
+#undef HAVE_GETADDRINFO
+
+/* define if getaddrinfo prototype is in <netdb.h> */
+#undef HAVE_GETADDRINFO_PROTO
+
+/* Define to 1 if you have the `gethostbyname2' function. */
+#undef HAVE_GETHOSTBYNAME2
+
+/* Define to 1 if you have the `gethostbyname_r' function. */
+#undef HAVE_GETHOSTBYNAME_R
+
+/* Define to 1 if you have the `gethostname' function. */
+#undef HAVE_GETHOSTNAME
+
+/* define if gethostname prototype is in <unistd.h> */
+#undef HAVE_GETHOSTNAME_PROTO
+
+/* Define to 1 if you have the `getnameinfo' function. */
+#undef HAVE_GETNAMEINFO
+
+/* define if getnameinfo prototype is in <netdb.h> */
+#undef HAVE_GETNAMEINFO_PROTO
+
+/* define if getrusage prototype is in <sys/resource.h> */
+#undef HAVE_GETRUSAGE_PROTO
+
+/* Define to 1 if you have the `hstrerror' function. */
+#undef HAVE_HSTRERROR
+
+/* define if hstrerror prototype is in <netdb.h> */
+#undef HAVE_HSTRERROR_PROTO
+
+/* Define to 1 if <net/if.h> defines struct if_nameindex */
+#undef HAVE_IF_NAMEINDEX_STRUCT
+
+/* Define to 1 if you have the `if_nametoindex' function. */
+#undef HAVE_IF_NAMETOINDEX
+
+/* define if if_nametoindex prototype is in <net/if.h> */
+#undef HAVE_IF_NAMETOINDEX_PROTO
+
+/* Define to 1 if you have the `inet6_rth_init' function. */
+#undef HAVE_INET6_RTH_INIT
+
+/* Define to 1 if you have the `inet_aton' function. */
+#undef HAVE_INET_ATON
+
+/* define if inet_aton prototype is in <arpa/inet.h> */
+#undef HAVE_INET_ATON_PROTO
+
+/* Define to 1 if you have the `inet_pton' function. */
+#undef HAVE_INET_PTON
+
+/* define if inet_pton prototype is in <arpa/inet.h> */
+#undef HAVE_INET_PTON_PROTO
+
+/* Define to 1 if you have the `kevent' function. */
+#undef HAVE_KEVENT
+
+/* Define to 1 if you have the `kqueue' function. */
+#undef HAVE_KQUEUE
+
+/* Define to 1 if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#undef HAVE_LIBPTHREAD
+
+/* Define to 1 if you have the `pthreads' library (-lpthreads). */
+#undef HAVE_LIBPTHREADS
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define to 1 if you have the `xti' library (-lxti). */
+#undef HAVE_LIBXTI
+
+/* Define to 1 if you have the `mkstemp' function. */
+#undef HAVE_MKSTEMP
+
+/* define if struct msghdr contains the msg_control member */
+#undef HAVE_MSGHDR_MSG_CONTROL
+
+/* Define to 1 if you have the <netconfig.h> header file. */
+#undef HAVE_NETCONFIG_H
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define to 1 if you have the <netdir.h> header file. */
+#undef HAVE_NETDIR_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the <net/if_dl.h> header file. */
+#undef HAVE_NET_IF_DL_H
+
+/* Define to 1 if you have the `poll' function. */
+#undef HAVE_POLL
+
+/* Define to 1 if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
+
+/* Define to 1 if you have the `pselect' function. */
+#undef HAVE_PSELECT
+
+/* define if pselect prototype is in <sys/stat.h> */
+#undef HAVE_PSELECT_PROTO
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
+/* Define to 1 if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* define if snprintf prototype is in <stdio.h> */
+#undef HAVE_SNPRINTF_PROTO
+
+/* Define to 1 if <net/if_dl.h> defines struct sockaddr_dl */
+#undef HAVE_SOCKADDR_DL_STRUCT
+
+/* define if socket address structures have length fields */
+#undef HAVE_SOCKADDR_SA_LEN
+
+/* Define to 1 if you have the `sockatmark' function. */
+#undef HAVE_SOCKATMARK
+
+/* define if sockatmark prototype is in <sys/socket.h> */
+#undef HAVE_SOCKATMARK_PROTO
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <stropts.h> header file. */
+#undef HAVE_STROPTS_H
+
+/* Define to 1 if `ifr_mtu' is member of `struct ifreq'. */
+#undef HAVE_STRUCT_IFREQ_IFR_MTU
+
+/* Define to 1 if the system has the type `struct sockaddr_storage'. */
+#undef HAVE_STRUCT_SOCKADDR_STORAGE
+
+/* Define to 1 if you have the <sys/event.h> header file. */
+#undef HAVE_SYS_EVENT_H
+
+/* Define to 1 if you have the <sys/filio.h> header file. */
+#undef HAVE_SYS_FILIO_H
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+#undef HAVE_SYS_SOCKIO_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/sysctl.h> header file. */
+#undef HAVE_SYS_SYSCTL_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#undef HAVE_SYS_UIO_H
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if <time.h> or <sys/time.h> defines struct timespec */
+#undef HAVE_TIMESPEC_STRUCT
+
+/* Define to 1 if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define to 1 if you have the <xti.h> header file. */
+#undef HAVE_XTI_H
+
+/* Define to 1 if you have the <xti_inet.h> header file. */
+#undef HAVE_XTI_INET_H
+
+/* Define to 1 if the system supports IPv4 */
+#undef IPV4
+
+/* Define to 1 if the system supports IPv6 */
+#undef IPV6
+
+/* Define to 1 if the system supports IPv4 */
+#undef IPv4
+
+/* Define to 1 if the system supports IPv6 */
+#undef IPv6
+
+/* Define to 1 if the system supports IP Multicast */
+#undef MCAST
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* the size of the sa_family field in a socket address structure */
+#undef SA_FAMILY_T
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if the system supports UNIX domain sockets */
+#undef UNIXDOMAIN
+
+/* Define to 1 if the system supports UNIX domain sockets */
+#undef UNIXdomain
+
+/* 16 bit signed type */
+#undef int16_t
+
+/* 32 bit signed type */
+#undef int32_t
+
+/* the type of the sa_family struct member */
+#undef sa_family_t
+
+/* unsigned integer type of the result of the sizeof operator */
+#undef size_t
+
+/* a type appropriate for address */
+#undef socklen_t
+
+/* define to __ss_family if sockaddr_storage has that instead of ss_family */
+#undef ss_family
+
+/* a signed type appropriate for a count of bytes or an error indication */
+#undef ssize_t
+
+/* scalar type */
+#undef t_scalar_t
+
+/* unsigned scalar type */
+#undef t_uscalar_t
+
+/* 16 bit unsigned type */
+#undef uint16_t
+
+/* 32 bit unsigned type */
+#undef uint32_t
+
+/* 8-bit unsigned type */
+#undef uint8_t
diff --git a/config.sub b/config.sub
new file mode 100755 (executable)
index 0000000..f365797
--- /dev/null
@@ -0,0 +1,1443 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-03-07'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple | -axis)
+               os=
+               basic_machine=$1
+               ;;
+       -sim | -cisco | -oki | -wec | -winbond)
+               os=
+               basic_machine=$1
+               ;;
+       -scout)
+               ;;
+       -wrs)
+               os=-vxworks
+               basic_machine=$1
+               ;;
+       -chorusos*)
+               os=-chorusos
+               basic_machine=$1
+               ;;
+       -chorusrdb)
+               os=-chorusrdb
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=-sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -udk*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+       -mint | -mint[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       1750a | 580 \
+       | a29k \
+       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+       | c4x | clipper \
+       | d10v | d30v | dsp16xx \
+       | fr30 \
+       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | i370 | i860 | i960 | ia64 \
+       | m32r | m68000 | m68k | m88k | mcore \
+       | mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
+       | mips64vr4100 | mips64vr4100el | mips64vr4300 \
+       | mips64vr4300el | mips64vr5000 | mips64vr5000el \
+       | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
+       | mipsisa32 | mipsisa64 \
+       | mn10200 | mn10300 \
+       | ns16k | ns32k \
+       | openrisc | or32 \
+       | pdp10 | pdp11 | pj | pjl \
+       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+       | pyramid \
+       | sh | sh[34] | sh[34]eb | shbe | shle | sh64 \
+       | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+       | strongarm \
+       | tahoe | thumb | tic80 | tron \
+       | v850 | v850e \
+       | we32k \
+       | x86 | xscale | xstormy16 | xtensa \
+       | z8k)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m6811 | m68hc11 | m6812 | m68hc12)
+               # Motorola 68HC11/12.
+               basic_machine=$basic_machine-unknown
+               os=-none
+               ;;
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+               ;;
+
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i*86 | x86_64)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       580-* \
+       | a29k-* \
+       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+       | arm-*  | armbe-* | armle-* | armv*-* \
+       | avr-* \
+       | bs2000-* \
+       | c[123]* | c30-* | [cjt]90-* | c54x-* \
+       | clipper-* | cydra-* \
+       | d10v-* | d30v-* \
+       | elxsi-* \
+       | f30[01]-* | f700-* | fr30-* | fx80-* \
+       | h8300-* | h8500-* \
+       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+       | i*86-* | i860-* | i960-* | ia64-* \
+       | m32r-* \
+       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+       | m88110-* | m88k-* | mcore-* \
+       | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
+       | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
+       | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
+       | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
+       | none-* | np1-* | ns16k-* | ns32k-* \
+       | orion-* \
+       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+       | pyramid-* \
+       | romp-* | rs6000-* \
+       | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \
+       | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+       | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+       | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
+       | v850-* | v850e-* | vax-* \
+       | we32k-* \
+       | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+       | xtensa-* \
+       | ymp-* \
+       | z8k-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       386bsd)
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       a29khif)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       adobe68k)
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-unknown
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-unknown
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-unknown
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       apollo68bsd)
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       c90)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | j90)
+               basic_machine=j90-cray
+               os=-unicos
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       cris | cris-* | etrax*)
+               basic_machine=cris-axis
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       decsystem10* | dec10*)
+               basic_machine=pdp10-dec
+               os=-tops10
+               ;;
+       decsystem20* | dec20*)
+               basic_machine=pdp10-dec
+               os=-tops20
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       es1800 | OSE68k | ose68k | ose | OSE)
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       go32)
+               basic_machine=i386-pc
+               os=-go32
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       h8300xray)
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp3k9[0-9][0-9] | hp9[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k6[0-9][0-9] | hp6[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k7[0-79][0-9] | hp7[0-79][0-9])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k78[0-9] | hp78[0-9])
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][13679] | hp8[0-9][13679])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       hppaosf)
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
+       hppro)
+               basic_machine=hppa1.1-hp
+               os=-proelf
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i*86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i*86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i*86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i*86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       i386mach)
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       mingw32)
+               basic_machine=i386-pc
+               os=-mingw32
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       mmix*)
+               basic_machine=mmix-knuth
+               os=-mmixware
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       morphos)
+               basic_machine=powerpc-unknown
+               os=-morphos
+               ;;
+       msdos)
+               basic_machine=i386-pc
+               os=-msdos
+               ;;
+       mvs)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       netbsd386)
+               basic_machine=i386-unknown
+               os=-netbsd
+               ;;
+       netwinder)
+               basic_machine=armv4l-rebel
+               os=-linux
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       necv70)
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
+       nonstopux)
+               basic_machine=mips-compaq
+               os=-nonstopux
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       nsr-tandem)
+               basic_machine=nsr-tandem
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       or32 | or32-*)
+               basic_machine=or32-unknown
+               os=-coff
+               ;;
+       OSE68000 | ose68000)
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+        pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5 | k5 | k6 | nexgen | viac3)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86 | athlon)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2)
+               basic_machine=i686-pc
+               ;;
+       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | 6x86-* | athlon-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=power-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64)  basic_machine=powerpc64-unknown
+               ;;
+       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+               basic_machine=powerpc64le-unknown
+               ;;
+       ppc64le-* | powerpc64little-*)
+               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       pw32)
+               basic_machine=i586-unknown
+               os=-pw32
+               ;;
+       rom68k)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       s390 | s390-*)
+               basic_machine=s390-ibm
+               ;;
+       s390x | s390x-*)
+               basic_machine=s390x-ibm
+               ;;
+       sa29200)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sparclite-wrs | simso-wrs)
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       st2000)
+               basic_machine=m68k-tandem
+               ;;
+       stratus)
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+        sv1)
+               basic_machine=sv1-cray
+               os=-unicos
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       t3d)
+               basic_machine=alpha-cray
+               os=-unicos
+               ;;
+       t3e)
+               basic_machine=alphaev5-cray
+               os=-unicos
+               ;;
+       t90)
+               basic_machine=t90-cray
+               os=-unicos
+               ;;
+       tic54x | c54x*)
+               basic_machine=tic54x-unknown
+               os=-coff
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       toad1)
+               basic_machine=pdp10-xkl
+               os=-tops20
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       v810 | necv810)
+               basic_machine=v810-nec
+               os=-none
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       w65*)
+               basic_machine=w65-wdc
+               os=-none
+               ;;
+       w89k-*)
+               basic_machine=hppa1.1-winbond
+               os=-proelf
+               ;;
+       windows32)
+               basic_machine=i386-pc
+               os=-windows32-msvcrt
+               ;;
+        xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       z8k-*-coff)
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)
+               basic_machine=hppa1.1-oki
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp10)
+               # there are many clones, so DEC is not a safe bet
+               basic_machine=pdp10-unknown
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sh3 | sh4 | sh3eb | sh4eb)
+               basic_machine=sh-unknown
+               ;;
+       sh64)
+               basic_machine=sh64-unknown
+               ;;
+       sparc | sparcv9 | sparcv9b)
+               basic_machine=sparc-sun
+               ;;
+        cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       mac | mpw | mac-mpw)
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)
+               basic_machine=powerpc-apple
+               ;;
+       c4x*)
+               basic_machine=c4x-none
+               os=-coff
+               ;;
+       *-unknown)
+               # Make sure to match an already-canonicalized machine name.
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+             | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -chorusos* | -chorusrdb* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+             | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+             | -morphos* | -superux* | -rtmk* | -rtmk-nova*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -qnx*)
+               case $basic_machine in
+                   x86-* | i*86-*)
+                       ;;
+                   *)
+                       os=-nto$os
+                       ;;
+               esac
+               ;;
+       -nto*)
+               os=-nto-qnx
+               ;;
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -opened*)
+               os=-openedition
+               ;;
+       -wince*)
+               os=-wince
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -atheos*)
+               os=-atheos
+               ;;
+       -386bsd)
+               os=-bsd
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -nova*)
+               os=-rtmk-nova
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       -nsk*)
+               os=-nsk
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -ose*)
+               os=-ose
+               ;;
+       -es1800*)
+               os=-ose
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+        -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+               os=-mint
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-rebel)
+               os=-linux
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+       # This must come before the *-dec entry.
+       pdp10-*)
+               os=-tops20
+               ;;
+        pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       m68*-cisco)
+               os=-aout
+               ;;
+       mips*-cisco)
+               os=-elf
+               ;;
+       mips*-*)
+               os=-elf
+               ;;
+       or32-*)
+               os=-coff
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-be)
+               os=-beos
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-wec)
+               os=-proelf
+               ;;
+       *-winbond)
+               os=-proelf
+               ;;
+       *-oki)
+               os=-proelf
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+        *-gould)
+               os=-sysv
+               ;;
+        *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+        *-sgi)
+               os=-irix
+               ;;
+        *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f30[01]-fujitsu | f700-fujitsu)
+               os=-uxpv
+               ;;
+       *-rom68k)
+               os=-coff
+               ;;
+       *-*bug)
+               os=-coff
+               ;;
+       *-apple)
+               os=-macos
+               ;;
+       *-atari*)
+               os=-mint
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -beos*)
+                               vendor=be
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -mpeix*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs* | -opened*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -vxsim* | -vxworks*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)
+                               vendor=apple
+                               ;;
+                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+                               vendor=atari
+                               ;;
+                       -vos*)
+                               vendor=stratus
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/configure b/configure
new file mode 100755 (executable)
index 0000000..87004a5
--- /dev/null
+++ b/configure
@@ -0,0 +1,9025 @@
+#! /bin/sh
+# From configure.in Revision: 1.13 .
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.57.
+#
+# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="lib/unp.h"
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT RANLIB ac_ct_RANLIB CPP EGREP LIB_OBJS LIBFREE_OBJS LIBGAI_OBJS LIBROUTE_OBJS LIBXTI_OBJS LIBS_XTI LIBUNP LIBUNPXTI LIBUNP_NAME LIBUNPXTI_NAME LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+              localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$0" : 'X\(//\)[^/]' \| \
+         X"$0" : 'X\(//\)$' \| \
+         X"$0" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+           test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.57.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+        ac_must_keep_next=false # Got value, back to normal.
+      else
+        case $ac_arg in
+          *=* | --config-cache | -C | -disable-* | --disable-* \
+          | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+          | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+          | -with-* | --with-* | -without-* | --without-* | --x)
+            case "$ac_configure_args0 " in
+              "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+            esac
+            ;;
+          -* ) ac_must_keep_next=true ;;
+        esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+        "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=$`echo $ac_var`
+        echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core core.* *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+               sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+        { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+        { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+        { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+        ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+          ac_config_headers="$ac_config_headers config.h"
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define CPU_VENDOR_OS "$host"
+_ACEOF
+
+
+
+case "$host_os" in
+*aix*)         CPPFLAGS="$CPPFLAGS -D_ALL_SOURCE" ;;
+*osf*)         CPPFLAGS="$CPPFLAGS -D_SOCKADDR_LEN" ;;
+esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output" >&5
+echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+        ;;
+    conftest.$ac_ext )
+        # This is the source file.
+        ;;
+    [ab].out )
+        # We found the default executable, but exeext='' is most
+        # certainly right.
+        break;;
+    *.* )
+        ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+        # FIXME: I believe we export ac_cv_exeext for Libtool,
+        # but it would be cool to find out if it's true.  Does anybody
+        # maintain Libtool? --akim.
+        export ac_cv_exeext
+        break;;
+    * )
+        break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+          export ac_cv_exeext
+          break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   ''\
+   '#include <stdlib.h>' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+
+
+echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5
+echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6
+if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_create ();
+int
+main ()
+{
+pthread_create ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthread_pthread_create=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthread_pthread_create=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_create" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6
+if test $ac_cv_lib_pthread_pthread_create = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPTHREAD 1
+_ACEOF
+
+  LIBS="-lpthread $LIBS"
+
+fi
+
+if test "$ac_cv_lib_pthread_pthread_create" = yes ; then
+   CFLAGS="$CFLAGS -D_REENTRANT"
+else
+
+echo "$as_me:$LINENO: checking for pthread_create in -lpthreads" >&5
+echo $ECHO_N "checking for pthread_create in -lpthreads... $ECHO_C" >&6
+if test "${ac_cv_lib_pthreads_pthread_create+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreads  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pthread_create ();
+int
+main ()
+{
+pthread_create ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pthreads_pthread_create=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthreads_pthread_create=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_create" >&5
+echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_create" >&6
+if test $ac_cv_lib_pthreads_pthread_create = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPTHREADS 1
+_ACEOF
+
+  LIBS="-lpthreads $LIBS"
+
+fi
+
+   if test "$ac_cv_lib_pthreads_pthread_create" = yes ; then
+      CFLAGS="$CFLAGS -D_REENTRANT"
+   fi
+fi
+
+
+echo "$as_me:$LINENO: checking for t_open in -lnsl" >&5
+echo $ECHO_N "checking for t_open in -lnsl... $ECHO_C" >&6
+if test "${ac_cv_lib_nsl_t_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char t_open ();
+int
+main ()
+{
+t_open ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_nsl_t_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_nsl_t_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_t_open" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_t_open" >&6
+if test $ac_cv_lib_nsl_t_open = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNSL 1
+_ACEOF
+
+  LIBS="-lnsl $LIBS"
+
+fi
+
+echo "$as_me:$LINENO: checking for library containing socket" >&5
+echo $ECHO_N "checking for library containing socket... $ECHO_C" >&6
+if test "${ac_cv_search_socket+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_socket=no
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char socket ();
+int
+main ()
+{
+socket ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_socket="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_socket" = no; then
+  for ac_lib in socket; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char socket ();
+int
+main ()
+{
+socket ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_socket="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_socket" >&5
+echo "${ECHO_T}$ac_cv_search_socket" >&6
+if test "$ac_cv_search_socket" != no; then
+  test "$ac_cv_search_socket" = "none required" || LIBS="$ac_cv_search_socket $LIBS"
+
+fi
+
+
+echo "$as_me:$LINENO: checking for /usr/local/bind/lib/libbind.a" >&5
+echo $ECHO_N "checking for /usr/local/bind/lib/libbind.a... $ECHO_C" >&6
+if test -f /usr/local/bind/lib/libbind.a ; then
+       echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       LIBS="/usr/local/bind/lib/libbind.a  $LIBS"
+else
+       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+       echo "$as_me:$LINENO: checking for $HOME/libbind.a" >&5
+echo $ECHO_N "checking for $HOME/libbind.a... $ECHO_C" >&6
+       if test -f $HOME/libbind.a ; then
+               echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               LIBS="$HOME/libbind.a  $LIBS"
+       else
+               echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+               echo "$as_me:$LINENO: checking for $HOME/libresolv.a" >&5
+echo $ECHO_N "checking for $HOME/libresolv.a... $ECHO_C" >&6
+               if test -f $HOME/libresolv.a ; then
+                       echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+                       LIBS="$HOME/libresolv.a  $LIBS"
+               else
+                       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+echo "$as_me:$LINENO: checking for res_init in -lresolv" >&5
+echo $ECHO_N "checking for res_init in -lresolv... $ECHO_C" >&6
+if test "${ac_cv_lib_resolv_res_init+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lresolv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char res_init ();
+int
+main ()
+{
+res_init ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_resolv_res_init=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_resolv_res_init=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_res_init" >&5
+echo "${ECHO_T}$ac_cv_lib_resolv_res_init" >&6
+if test $ac_cv_lib_resolv_res_init = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBRESOLV 1
+_ACEOF
+
+  LIBS="-lresolv $LIBS"
+
+fi
+
+               fi
+       fi
+fi
+
+
+echo "$as_me:$LINENO: checking for t_open in -lxti" >&5
+echo $ECHO_N "checking for t_open in -lxti... $ECHO_C" >&6
+if test "${ac_cv_lib_xti_t_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lxti  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char t_open ();
+int
+main ()
+{
+t_open ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_xti_t_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_xti_t_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_xti_t_open" >&5
+echo "${ECHO_T}$ac_cv_lib_xti_t_open" >&6
+if test $ac_cv_lib_xti_t_open = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBXTI 1
+_ACEOF
+
+  LIBS="-lxti $LIBS"
+
+fi
+
+
+echo "$as_me:$LINENO: checking for $HOME/libunp.a" >&5
+echo $ECHO_N "checking for $HOME/libunp.a... $ECHO_C" >&6
+if test -f $HOME/libunp.a ; then
+       echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       LIBUNP="$HOME/libunp.a"
+       LIBUNP_NAME=$HOME/libunp.a
+else
+       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+       LIBUNP="../libunp.a"
+       LIBUNP_NAME=../libunp.a
+fi
+
+echo "$as_me:$LINENO: checking for $HOME/libunpxti.a" >&5
+echo $ECHO_N "checking for $HOME/libunpxti.a... $ECHO_C" >&6
+if test -f $HOME/libunpxti.a ; then
+       echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       LIBUNPXTI="$HOME/libunpxti.a"
+       LIBUNPXTI_NAME=$HOME/libunpxti.a
+else
+       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+       LIBUNPXTI="../libunpxti.a"
+       LIBUNPXTI_NAME=../libunpxti.a
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                   (('a' <= (c) && (c) <= 'i') \
+                     || ('j' <= (c) && (c) <= 'r') \
+                     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+        || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/socket.h sys/time.h time.h netinet/in.h arpa/inet.h errno.h fcntl.h netdb.h signal.h stdio.h stdlib.h string.h sys/stat.h sys/uio.h unistd.h sys/wait.h sys/un.h sys/param.h sys/select.h sys/sysctl.h poll.h sys/event.h strings.h sys/ioctl.h sys/filio.h sys/sockio.h pthread.h net/if_dl.h xti.h xti_inet.h netconfig.h netdir.h stropts.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
+if test "${ac_cv_header_time+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_time=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_time=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6
+if test $ac_cv_header_time = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TIME_WITH_SYS_TIME 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking if uint8_t defined" >&5
+echo $ECHO_N "checking if uint8_t defined... $ECHO_C" >&6
+       if test "${ac_cv_type_uint8_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include       "confdefs.h"    /* the header built by configure so far */
+#ifdef HAVE_SYS_TYPES_H
+#  include     <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include     <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include    <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include    <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include    <arpa/inet.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#  include    <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#  include    <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include     <netdb.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#  include     <signal.h>
+#endif
+#ifdef HAVE_STDIO_H
+#  include     <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include     <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#  include     <string.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include     <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include     <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include     <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#  include     <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include     <sys/un.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include   <sys/select.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include   <strings.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include   <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include   <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include   <sys/sockio.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#  include     <pthread.h>
+#endif
+int
+main ()
+{
+ uint8_t foo
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_uint8_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uint8_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+       echo "$as_me:$LINENO: result: $ac_cv_type_uint8_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint8_t" >&6
+       if test $ac_cv_type_uint8_t = no ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define uint8_t unsigned char
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking if int16_t defined" >&5
+echo $ECHO_N "checking if int16_t defined... $ECHO_C" >&6
+       if test "${ac_cv_type_int16_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include       "confdefs.h"    /* the header built by configure so far */
+#ifdef HAVE_SYS_TYPES_H
+#  include     <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include     <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include    <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include    <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include    <arpa/inet.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#  include    <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#  include    <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include     <netdb.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#  include     <signal.h>
+#endif
+#ifdef HAVE_STDIO_H
+#  include     <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include     <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#  include     <string.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include     <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include     <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include     <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#  include     <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include     <sys/un.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include   <sys/select.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include   <strings.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include   <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include   <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include   <sys/sockio.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#  include     <pthread.h>
+#endif
+int
+main ()
+{
+ int16_t foo
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_int16_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_int16_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+       echo "$as_me:$LINENO: result: $ac_cv_type_int16_t" >&5
+echo "${ECHO_T}$ac_cv_type_int16_t" >&6
+       if test $ac_cv_type_int16_t = no ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define int16_t short
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking if uint16_t defined" >&5
+echo $ECHO_N "checking if uint16_t defined... $ECHO_C" >&6
+       if test "${ac_cv_type_uint16_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include       "confdefs.h"    /* the header built by configure so far */
+#ifdef HAVE_SYS_TYPES_H
+#  include     <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include     <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include    <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include    <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include    <arpa/inet.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#  include    <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#  include    <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include     <netdb.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#  include     <signal.h>
+#endif
+#ifdef HAVE_STDIO_H
+#  include     <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include     <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#  include     <string.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include     <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include     <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include     <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#  include     <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include     <sys/un.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include   <sys/select.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include   <strings.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include   <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include   <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include   <sys/sockio.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#  include     <pthread.h>
+#endif
+int
+main ()
+{
+ uint16_t foo
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_uint16_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uint16_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+       echo "$as_me:$LINENO: result: $ac_cv_type_uint16_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint16_t" >&6
+       if test $ac_cv_type_uint16_t = no ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define uint16_t unsigned short
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking if int32_t defined" >&5
+echo $ECHO_N "checking if int32_t defined... $ECHO_C" >&6
+       if test "${ac_cv_type_int32_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include       "confdefs.h"    /* the header built by configure so far */
+#ifdef HAVE_SYS_TYPES_H
+#  include     <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include     <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include    <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include    <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include    <arpa/inet.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#  include    <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#  include    <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include     <netdb.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#  include     <signal.h>
+#endif
+#ifdef HAVE_STDIO_H
+#  include     <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include     <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#  include     <string.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include     <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include     <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include     <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#  include     <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include     <sys/un.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include   <sys/select.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include   <strings.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include   <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include   <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include   <sys/sockio.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#  include     <pthread.h>
+#endif
+int
+main ()
+{
+ int32_t foo
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_int32_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_int32_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+       echo "$as_me:$LINENO: result: $ac_cv_type_int32_t" >&5
+echo "${ECHO_T}$ac_cv_type_int32_t" >&6
+       if test $ac_cv_type_int32_t = no ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define int32_t int
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking if uint32_t defined" >&5
+echo $ECHO_N "checking if uint32_t defined... $ECHO_C" >&6
+       if test "${ac_cv_type_uint32_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include       "confdefs.h"    /* the header built by configure so far */
+#ifdef HAVE_SYS_TYPES_H
+#  include     <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include     <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include    <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include    <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include    <arpa/inet.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#  include    <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#  include    <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include     <netdb.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#  include     <signal.h>
+#endif
+#ifdef HAVE_STDIO_H
+#  include     <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include     <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#  include     <string.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include     <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include     <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include     <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#  include     <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include     <sys/un.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include   <sys/select.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include   <strings.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include   <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include   <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include   <sys/sockio.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#  include     <pthread.h>
+#endif
+int
+main ()
+{
+ uint32_t foo
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_uint32_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uint32_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+       echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint32_t" >&6
+       if test $ac_cv_type_uint32_t = no ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define uint32_t unsigned int
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking if size_t defined" >&5
+echo $ECHO_N "checking if size_t defined... $ECHO_C" >&6
+       if test "${ac_cv_type_size_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include       "confdefs.h"    /* the header built by configure so far */
+#ifdef HAVE_SYS_TYPES_H
+#  include     <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include     <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include    <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include    <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include    <arpa/inet.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#  include    <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#  include    <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include     <netdb.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#  include     <signal.h>
+#endif
+#ifdef HAVE_STDIO_H
+#  include     <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include     <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#  include     <string.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include     <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include     <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include     <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#  include     <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include     <sys/un.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include   <sys/select.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include   <strings.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include   <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include   <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include   <sys/sockio.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#  include     <pthread.h>
+#endif
+int
+main ()
+{
+ size_t foo
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_size_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_size_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+       echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
+       if test $ac_cv_type_size_t = no ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking if ssize_t defined" >&5
+echo $ECHO_N "checking if ssize_t defined... $ECHO_C" >&6
+       if test "${ac_cv_type_ssize_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include       "confdefs.h"    /* the header built by configure so far */
+#ifdef HAVE_SYS_TYPES_H
+#  include     <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include     <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include    <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include    <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include    <arpa/inet.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#  include    <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#  include    <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include     <netdb.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#  include     <signal.h>
+#endif
+#ifdef HAVE_STDIO_H
+#  include     <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include     <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#  include     <string.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include     <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include     <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include     <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#  include     <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include     <sys/un.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include   <sys/select.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include   <strings.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include   <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include   <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include   <sys/sockio.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#  include     <pthread.h>
+#endif
+int
+main ()
+{
+ ssize_t foo
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_ssize_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_ssize_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+       echo "$as_me:$LINENO: result: $ac_cv_type_ssize_t" >&5
+echo "${ECHO_T}$ac_cv_type_ssize_t" >&6
+       if test $ac_cv_type_ssize_t = no ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define ssize_t int
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking if socklen_t defined" >&5
+echo $ECHO_N "checking if socklen_t defined... $ECHO_C" >&6
+       if test "${ac_cv_type_socklen_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include       "confdefs.h"    /* the header built by configure so far */
+#ifdef HAVE_SYS_TYPES_H
+#  include     <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include     <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include    <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include    <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include    <arpa/inet.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#  include    <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#  include    <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include     <netdb.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#  include     <signal.h>
+#endif
+#ifdef HAVE_STDIO_H
+#  include     <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include     <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#  include     <string.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include     <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include     <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include     <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#  include     <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include     <sys/un.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include   <sys/select.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include   <strings.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include   <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include   <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include   <sys/sockio.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#  include     <pthread.h>
+#endif
+int
+main ()
+{
+ socklen_t foo
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_socklen_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_socklen_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+       echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5
+echo "${ECHO_T}$ac_cv_type_socklen_t" >&6
+       if test $ac_cv_type_socklen_t = no ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define socklen_t unsigned int
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking if sa_family_t defined" >&5
+echo $ECHO_N "checking if sa_family_t defined... $ECHO_C" >&6
+       if test "${ac_cv_type_sa_family_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include       "confdefs.h"    /* the header built by configure so far */
+#ifdef HAVE_SYS_TYPES_H
+#  include     <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include     <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include    <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include    <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include    <arpa/inet.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#  include    <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#  include    <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include     <netdb.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#  include     <signal.h>
+#endif
+#ifdef HAVE_STDIO_H
+#  include     <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include     <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#  include     <string.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include     <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include     <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include     <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#  include     <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include     <sys/un.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include   <sys/select.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include   <strings.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include   <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include   <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include   <sys/sockio.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#  include     <pthread.h>
+#endif
+int
+main ()
+{
+ sa_family_t foo
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_sa_family_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_sa_family_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+       echo "$as_me:$LINENO: result: $ac_cv_type_sa_family_t" >&5
+echo "${ECHO_T}$ac_cv_type_sa_family_t" >&6
+       if test $ac_cv_type_sa_family_t = no ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define sa_family_t SA_FAMILY_T
+_ACEOF
+
+       fi
+
+
+echo "$as_me:$LINENO: checking if t_scalar_t defined" >&5
+echo $ECHO_N "checking if t_scalar_t defined... $ECHO_C" >&6
+       if test "${ac_cv_type_t_scalar_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include       "confdefs.h"    /* the header built by configure so far */
+#ifdef HAVE_SYS_TYPES_H
+#  include     <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include     <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include    <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include    <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include    <arpa/inet.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#  include    <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#  include    <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include     <netdb.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#  include     <signal.h>
+#endif
+#ifdef HAVE_STDIO_H
+#  include     <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include     <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#  include     <string.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include     <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include     <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include     <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#  include     <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include     <sys/un.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include   <sys/select.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include   <strings.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include   <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include   <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include   <sys/sockio.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#  include     <pthread.h>
+#endif
+#ifdef HAVE_POLL_H
+#  include     <poll.h>
+#endif
+#ifdef HAVE_XTI_H
+#  include     <xti.h>
+#endif
+#ifdef HAVE_NETCONFIG_H
+#  include     <netconfig.h>
+#endif
+#ifdef HAVE_NETDIR_H
+#  include     <netdir.h>
+#endif
+#ifdef HAVE_STROPTS_H
+#  include     <stropts.h>
+#endif
+int
+main ()
+{
+ t_scalar_t foo
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_t_scalar_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_t_scalar_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+       echo "$as_me:$LINENO: result: $ac_cv_type_t_scalar_t" >&5
+echo "${ECHO_T}$ac_cv_type_t_scalar_t" >&6
+       if test $ac_cv_type_t_scalar_t = no ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define t_scalar_t int32_t
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking if t_uscalar_t defined" >&5
+echo $ECHO_N "checking if t_uscalar_t defined... $ECHO_C" >&6
+       if test "${ac_cv_type_t_uscalar_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include       "confdefs.h"    /* the header built by configure so far */
+#ifdef HAVE_SYS_TYPES_H
+#  include     <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include     <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#  include    <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#  include    <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include    <arpa/inet.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#  include    <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#  include    <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include     <netdb.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#  include     <signal.h>
+#endif
+#ifdef HAVE_STDIO_H
+#  include     <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include     <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#  include     <string.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#  include     <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#  include     <sys/uio.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#  include     <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#  include     <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include     <sys/un.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+# include   <sys/select.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include   <strings.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include   <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include   <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include   <sys/sockio.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#  include     <pthread.h>
+#endif
+#ifdef HAVE_POLL_H
+#  include     <poll.h>
+#endif
+#ifdef HAVE_XTI_H
+#  include     <xti.h>
+#endif
+#ifdef HAVE_NETCONFIG_H
+#  include     <netconfig.h>
+#endif
+#ifdef HAVE_NETDIR_H
+#  include     <netdir.h>
+#endif
+#ifdef HAVE_STROPTS_H
+#  include     <stropts.h>
+#endif
+int
+main ()
+{
+ t_uscalar_t foo
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_t_uscalar_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_t_uscalar_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+       echo "$as_me:$LINENO: result: $ac_cv_type_t_uscalar_t" >&5
+echo "${ECHO_T}$ac_cv_type_t_uscalar_t" >&6
+       if test $ac_cv_type_t_uscalar_t = no ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define t_uscalar_t uint32_t
+_ACEOF
+
+       fi
+
+
+echo "$as_me:$LINENO: checking for struct sockaddr.sa_len" >&5
+echo $ECHO_N "checking for struct sockaddr.sa_len... $ECHO_C" >&6
+if test "${ac_cv_member_struct_sockaddr_sa_len+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+main ()
+{
+static struct sockaddr ac_aggr;
+if (ac_aggr.sa_len)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_sockaddr_sa_len=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+main ()
+{
+static struct sockaddr ac_aggr;
+if (sizeof ac_aggr.sa_len)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_sockaddr_sa_len=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_sockaddr_sa_len=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_sa_len" >&5
+echo "${ECHO_T}$ac_cv_member_struct_sockaddr_sa_len" >&6
+if test $ac_cv_member_struct_sockaddr_sa_len = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SOCKADDR_SA_LEN 1
+_ACEOF
+
+fi
+
+
+if test $ac_cv_type_sa_family_t = no ; then
+   if test $ac_cv_member_struct_sockaddr_sa_len = yes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define SA_FAMILY_T uint8_t
+_ACEOF
+
+   else
+      cat >>confdefs.h <<\_ACEOF
+#define SA_FAMILY_T uint16_t
+_ACEOF
+
+   fi
+fi
+
+echo "$as_me:$LINENO: checking for struct sockaddr_storage" >&5
+echo $ECHO_N "checking for struct sockaddr_storage... $ECHO_C" >&6
+if test "${ac_cv_type_struct_sockaddr_storage+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+main ()
+{
+if ((struct sockaddr_storage *) 0)
+  return 0;
+if (sizeof (struct sockaddr_storage))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_struct_sockaddr_storage=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_struct_sockaddr_storage=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_storage" >&5
+echo "${ECHO_T}$ac_cv_type_struct_sockaddr_storage" >&6
+if test $ac_cv_type_struct_sockaddr_storage = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+_ACEOF
+
+echo "$as_me:$LINENO: checking for struct sockaddr_storage.ss_family" >&5
+echo $ECHO_N "checking for struct sockaddr_storage.ss_family... $ECHO_C" >&6
+if test "${ac_cv_member_struct_sockaddr_storage_ss_family+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+main ()
+{
+static struct sockaddr_storage ac_aggr;
+if (ac_aggr.ss_family)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_sockaddr_storage_ss_family=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+main ()
+{
+static struct sockaddr_storage ac_aggr;
+if (sizeof ac_aggr.ss_family)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_sockaddr_storage_ss_family=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_sockaddr_storage_ss_family=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_storage_ss_family" >&5
+echo "${ECHO_T}$ac_cv_member_struct_sockaddr_storage_ss_family" >&6
+if test $ac_cv_member_struct_sockaddr_storage_ss_family = yes; then
+  :
+else
+  echo "$as_me:$LINENO: checking for struct sockaddr_storage.__ss_family" >&5
+echo $ECHO_N "checking for struct sockaddr_storage.__ss_family... $ECHO_C" >&6
+if test "${ac_cv_member_struct_sockaddr_storage___ss_family+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+main ()
+{
+static struct sockaddr_storage ac_aggr;
+if (ac_aggr.__ss_family)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_sockaddr_storage___ss_family=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+main ()
+{
+static struct sockaddr_storage ac_aggr;
+if (sizeof ac_aggr.__ss_family)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_sockaddr_storage___ss_family=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_sockaddr_storage___ss_family=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_storage___ss_family" >&5
+echo "${ECHO_T}$ac_cv_member_struct_sockaddr_storage___ss_family" >&6
+if test $ac_cv_member_struct_sockaddr_storage___ss_family = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define ss_family __ss_family
+_ACEOF
+
+else
+  { { echo "$as_me:$LINENO: error: cannot find ss_family in sockaddr_storage" >&5
+echo "$as_me: error: cannot find ss_family in sockaddr_storage" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+fi
+
+fi
+
+
+echo "$as_me:$LINENO: checking for struct msghdr.msg_control" >&5
+echo $ECHO_N "checking for struct msghdr.msg_control... $ECHO_C" >&6
+if test "${ac_cv_member_struct_msghdr_msg_control+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+main ()
+{
+static struct msghdr ac_aggr;
+if (ac_aggr.msg_control)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_msghdr_msg_control=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+main ()
+{
+static struct msghdr ac_aggr;
+if (sizeof ac_aggr.msg_control)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_msghdr_msg_control=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_msghdr_msg_control=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_msghdr_msg_control" >&5
+echo "${ECHO_T}$ac_cv_member_struct_msghdr_msg_control" >&6
+if test $ac_cv_member_struct_msghdr_msg_control = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MSGHDR_MSG_CONTROL 1
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking for struct ifreq.ifr_mtu" >&5
+echo $ECHO_N "checking for struct ifreq.ifr_mtu... $ECHO_C" >&6
+if test "${ac_cv_member_struct_ifreq_ifr_mtu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+int
+main ()
+{
+static struct ifreq ac_aggr;
+if (ac_aggr.ifr_mtu)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_ifreq_ifr_mtu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+int
+main ()
+{
+static struct ifreq ac_aggr;
+if (sizeof ac_aggr.ifr_mtu)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_ifreq_ifr_mtu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_ifreq_ifr_mtu=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_ifreq_ifr_mtu" >&5
+echo "${ECHO_T}$ac_cv_member_struct_ifreq_ifr_mtu" >&6
+if test $ac_cv_member_struct_ifreq_ifr_mtu = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_IFREQ_IFR_MTU 1
+_ACEOF
+
+
+fi
+
+
+echo "$as_me:$LINENO: checking for getaddrinfo function prototype in netdb.h" >&5
+echo $ECHO_N "checking for getaddrinfo function prototype in netdb.h... $ECHO_C" >&6
+if test "${ac_cv_have_getaddrinfo_proto+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netdb.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "getaddrinfo" >/dev/null 2>&1; then
+  ac_cv_have_getaddrinfo_proto=yes
+else
+  ac_cv_have_getaddrinfo_proto=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_getaddrinfo_proto" >&5
+echo "${ECHO_T}$ac_cv_have_getaddrinfo_proto" >&6
+       if test $ac_cv_have_getaddrinfo_proto = yes ; then
+               ac_tr_func=HAVE_`echo getaddrinfo | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO
+               cat >>confdefs.h <<_ACEOF
+#define $ac_tr_func 1
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking for getnameinfo function prototype in netdb.h" >&5
+echo $ECHO_N "checking for getnameinfo function prototype in netdb.h... $ECHO_C" >&6
+if test "${ac_cv_have_getnameinfo_proto+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netdb.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "getnameinfo" >/dev/null 2>&1; then
+  ac_cv_have_getnameinfo_proto=yes
+else
+  ac_cv_have_getnameinfo_proto=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_getnameinfo_proto" >&5
+echo "${ECHO_T}$ac_cv_have_getnameinfo_proto" >&6
+       if test $ac_cv_have_getnameinfo_proto = yes ; then
+               ac_tr_func=HAVE_`echo getnameinfo | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO
+               cat >>confdefs.h <<_ACEOF
+#define $ac_tr_func 1
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking for gethostname function prototype in unistd.h" >&5
+echo $ECHO_N "checking for gethostname function prototype in unistd.h... $ECHO_C" >&6
+if test "${ac_cv_have_gethostname_proto+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <unistd.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "gethostname" >/dev/null 2>&1; then
+  ac_cv_have_gethostname_proto=yes
+else
+  ac_cv_have_gethostname_proto=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_gethostname_proto" >&5
+echo "${ECHO_T}$ac_cv_have_gethostname_proto" >&6
+       if test $ac_cv_have_gethostname_proto = yes ; then
+               ac_tr_func=HAVE_`echo gethostname | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO
+               cat >>confdefs.h <<_ACEOF
+#define $ac_tr_func 1
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking for getrusage function prototype in sys/resource.h" >&5
+echo $ECHO_N "checking for getrusage function prototype in sys/resource.h... $ECHO_C" >&6
+if test "${ac_cv_have_getrusage_proto+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/resource.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "getrusage" >/dev/null 2>&1; then
+  ac_cv_have_getrusage_proto=yes
+else
+  ac_cv_have_getrusage_proto=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_getrusage_proto" >&5
+echo "${ECHO_T}$ac_cv_have_getrusage_proto" >&6
+       if test $ac_cv_have_getrusage_proto = yes ; then
+               ac_tr_func=HAVE_`echo getrusage | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO
+               cat >>confdefs.h <<_ACEOF
+#define $ac_tr_func 1
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking for hstrerror function prototype in netdb.h" >&5
+echo $ECHO_N "checking for hstrerror function prototype in netdb.h... $ECHO_C" >&6
+if test "${ac_cv_have_hstrerror_proto+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netdb.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "hstrerror" >/dev/null 2>&1; then
+  ac_cv_have_hstrerror_proto=yes
+else
+  ac_cv_have_hstrerror_proto=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_hstrerror_proto" >&5
+echo "${ECHO_T}$ac_cv_have_hstrerror_proto" >&6
+       if test $ac_cv_have_hstrerror_proto = yes ; then
+               ac_tr_func=HAVE_`echo hstrerror | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO
+               cat >>confdefs.h <<_ACEOF
+#define $ac_tr_func 1
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking for if_nametoindex function prototype in net/if.h" >&5
+echo $ECHO_N "checking for if_nametoindex function prototype in net/if.h... $ECHO_C" >&6
+if test "${ac_cv_have_if_nametoindex_proto+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <net/if.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "if_nametoindex" >/dev/null 2>&1; then
+  ac_cv_have_if_nametoindex_proto=yes
+else
+  ac_cv_have_if_nametoindex_proto=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_if_nametoindex_proto" >&5
+echo "${ECHO_T}$ac_cv_have_if_nametoindex_proto" >&6
+       if test $ac_cv_have_if_nametoindex_proto = yes ; then
+               ac_tr_func=HAVE_`echo if_nametoindex | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO
+               cat >>confdefs.h <<_ACEOF
+#define $ac_tr_func 1
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking for inet_aton function prototype in arpa/inet.h" >&5
+echo $ECHO_N "checking for inet_aton function prototype in arpa/inet.h... $ECHO_C" >&6
+if test "${ac_cv_have_inet_aton_proto+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <arpa/inet.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "inet_aton" >/dev/null 2>&1; then
+  ac_cv_have_inet_aton_proto=yes
+else
+  ac_cv_have_inet_aton_proto=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_inet_aton_proto" >&5
+echo "${ECHO_T}$ac_cv_have_inet_aton_proto" >&6
+       if test $ac_cv_have_inet_aton_proto = yes ; then
+               ac_tr_func=HAVE_`echo inet_aton | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO
+               cat >>confdefs.h <<_ACEOF
+#define $ac_tr_func 1
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking for inet_pton function prototype in arpa/inet.h" >&5
+echo $ECHO_N "checking for inet_pton function prototype in arpa/inet.h... $ECHO_C" >&6
+if test "${ac_cv_have_inet_pton_proto+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <arpa/inet.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "inet_pton" >/dev/null 2>&1; then
+  ac_cv_have_inet_pton_proto=yes
+else
+  ac_cv_have_inet_pton_proto=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_inet_pton_proto" >&5
+echo "${ECHO_T}$ac_cv_have_inet_pton_proto" >&6
+       if test $ac_cv_have_inet_pton_proto = yes ; then
+               ac_tr_func=HAVE_`echo inet_pton | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO
+               cat >>confdefs.h <<_ACEOF
+#define $ac_tr_func 1
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking for pselect function prototype in sys/select.h" >&5
+echo $ECHO_N "checking for pselect function prototype in sys/select.h... $ECHO_C" >&6
+if test "${ac_cv_have_pselect_proto+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/select.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "pselect" >/dev/null 2>&1; then
+  ac_cv_have_pselect_proto=yes
+else
+  ac_cv_have_pselect_proto=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_pselect_proto" >&5
+echo "${ECHO_T}$ac_cv_have_pselect_proto" >&6
+       if test $ac_cv_have_pselect_proto = yes ; then
+               ac_tr_func=HAVE_`echo pselect | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO
+               cat >>confdefs.h <<_ACEOF
+#define $ac_tr_func 1
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking for snprintf function prototype in stdio.h" >&5
+echo $ECHO_N "checking for snprintf function prototype in stdio.h... $ECHO_C" >&6
+if test "${ac_cv_have_snprintf_proto+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "snprintf" >/dev/null 2>&1; then
+  ac_cv_have_snprintf_proto=yes
+else
+  ac_cv_have_snprintf_proto=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_snprintf_proto" >&5
+echo "${ECHO_T}$ac_cv_have_snprintf_proto" >&6
+       if test $ac_cv_have_snprintf_proto = yes ; then
+               ac_tr_func=HAVE_`echo snprintf | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO
+               cat >>confdefs.h <<_ACEOF
+#define $ac_tr_func 1
+_ACEOF
+
+       fi
+
+echo "$as_me:$LINENO: checking for sockatmark function prototype in sys/socket.h" >&5
+echo $ECHO_N "checking for sockatmark function prototype in sys/socket.h... $ECHO_C" >&6
+if test "${ac_cv_have_sockatmark_proto+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/socket.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "sockatmark" >/dev/null 2>&1; then
+  ac_cv_have_sockatmark_proto=yes
+else
+  ac_cv_have_sockatmark_proto=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_sockatmark_proto" >&5
+echo "${ECHO_T}$ac_cv_have_sockatmark_proto" >&6
+       if test $ac_cv_have_sockatmark_proto = yes ; then
+               ac_tr_func=HAVE_`echo sockatmark | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`_PROTO
+               cat >>confdefs.h <<_ACEOF
+#define $ac_tr_func 1
+_ACEOF
+
+       fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking for struct addrinfo" >&5
+echo $ECHO_N "checking for struct addrinfo... $ECHO_C" >&6
+if test "${ac_cv_type_struct_addrinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <netdb.h>
+
+int
+main ()
+{
+if ((struct addrinfo *) 0)
+  return 0;
+if (sizeof (struct addrinfo))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_struct_addrinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_struct_addrinfo=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_struct_addrinfo" >&5
+echo "${ECHO_T}$ac_cv_type_struct_addrinfo" >&6
+if test $ac_cv_type_struct_addrinfo = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ADDRINFO_STRUCT 1
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking for struct if_nameindex" >&5
+echo $ECHO_N "checking for struct if_nameindex... $ECHO_C" >&6
+if test "${ac_cv_type_struct_if_nameindex+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+int
+main ()
+{
+if ((struct if_nameindex *) 0)
+  return 0;
+if (sizeof (struct if_nameindex))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_struct_if_nameindex=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_struct_if_nameindex=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_struct_if_nameindex" >&5
+echo "${ECHO_T}$ac_cv_type_struct_if_nameindex" >&6
+if test $ac_cv_type_struct_if_nameindex = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_IF_NAMEINDEX_STRUCT 1
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking for struct sockaddr_dl" >&5
+echo $ECHO_N "checking for struct sockaddr_dl... $ECHO_C" >&6
+if test "${ac_cv_type_struct_sockaddr_dl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if_dl.h>
+
+int
+main ()
+{
+if ((struct sockaddr_dl *) 0)
+  return 0;
+if (sizeof (struct sockaddr_dl))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_struct_sockaddr_dl=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_struct_sockaddr_dl=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_dl" >&5
+echo "${ECHO_T}$ac_cv_type_struct_sockaddr_dl" >&6
+if test $ac_cv_type_struct_sockaddr_dl = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SOCKADDR_DL_STRUCT 1
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking for struct timespec" >&5
+echo $ECHO_N "checking for struct timespec... $ECHO_C" >&6
+if test "${ac_cv_type_struct_timespec+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+
+
+int
+main ()
+{
+if ((struct timespec *) 0)
+  return 0;
+if (sizeof (struct timespec))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_struct_timespec=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_struct_timespec=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_struct_timespec" >&5
+echo "${ECHO_T}$ac_cv_type_struct_timespec" >&6
+if test $ac_cv_type_struct_timespec = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TIMESPEC_STRUCT 1
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking for /dev/tcp" >&5
+echo $ECHO_N "checking for /dev/tcp... $ECHO_C" >&6
+if test -r /dev/tcp ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DEV_TCP 1
+_ACEOF
+
+       echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+       echo "$as_me:$LINENO: checking for /dev/xti/tcp" >&5
+echo $ECHO_N "checking for /dev/xti/tcp... $ECHO_C" >&6
+       if test -r /dev/xti/tcp ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DEV_XTI_TCP 1
+_ACEOF
+
+               echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+               echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+               echo "$as_me:$LINENO: checking for /dev/streams/xtiso/tcp" >&5
+echo $ECHO_N "checking for /dev/streams/xtiso/tcp... $ECHO_C" >&6
+               if test -r /dev/streams/xtiso/tcp ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DEV_STREAMS_XTISO_TCP 1
+_ACEOF
+
+                       echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+               else
+                       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+               fi
+       fi
+fi
+
+
+for ac_func in bzero
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in getaddrinfo
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in gethostname
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in gethostbyname2
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in gethostbyname_r
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in getnameinfo
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in hstrerror
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in if_nametoindex
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in inet_aton
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in inet_pton
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in inet6_rth_init
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+for ac_func in kqueue kevent
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in mkstemp
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in poll
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in pselect
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in snprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in sockatmark
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in vsnprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+echo "$as_me:$LINENO: checking for IPv4 support" >&5
+echo $ECHO_N "checking for IPv4 support... $ECHO_C" >&6
+if test "${ac_cv_ipv4+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_ipv4=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#      include <sys/types.h>
+#      include <sys/socket.h>
+#      include <netinet/in.h>
+       /* Make sure the definitions for AF_INET and struct sockaddr_in
+        * are defined, and that we can actually create an IPv4 TCP socket.
+        */
+       main()
+       {
+               int fd;
+               struct sockaddr_in foo;
+               fd = socket(AF_INET, SOCK_STREAM, 0);
+               exit(fd >= 0 ? 0 : 1);
+       }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_ipv4=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+(exit $ac_status )
+ac_cv_ipv4=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+
+echo "$as_me:$LINENO: result: $ac_cv_ipv4" >&5
+echo "${ECHO_T}$ac_cv_ipv4" >&6
+if test $ac_cv_ipv4 = yes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define IPV4 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define IPv4 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for IPv6 support" >&5
+echo $ECHO_N "checking for IPv6 support... $ECHO_C" >&6
+if test "${ac_cv_ipv6+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_ipv6=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#      include <sys/types.h>
+#      include <sys/socket.h>
+#      include <netinet/in.h>
+       /* Make sure the definitions for AF_INET6 and struct sockaddr_in6
+        * are defined, and that we can actually create an IPv6 TCP socket.
+        */
+       main()
+       {
+               int fd;
+               struct sockaddr_in6 foo;
+               fd = socket(AF_INET6, SOCK_STREAM, 0);
+               exit(fd >= 0 ? 0 : 1);
+       }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_ipv6=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+(exit $ac_status )
+ac_cv_ipv6=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+
+echo "$as_me:$LINENO: result: $ac_cv_ipv6" >&5
+echo "${ECHO_T}$ac_cv_ipv6" >&6
+if test $ac_cv_ipv6 = yes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define IPV6 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define IPv6 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for Unix domain sockets" >&5
+echo $ECHO_N "checking for Unix domain sockets... $ECHO_C" >&6
+if test "${ac_cv_unixdomain+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_unixdomain=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#      include <sys/types.h>
+#      include <sys/socket.h>
+#      include <sys/un.h>
+       /* Make sure the definitions for AF_UNIX and struct sockaddr_un
+        * are defined, and that we can actually create an IPv4 TCP socket.
+        */
+       main()
+       {
+               int fd;
+               struct sockaddr_un foo;
+               fd = socket(AF_UNIX, SOCK_STREAM, 0);
+               exit(fd >= 0 ? 0 : 1);
+       }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_unixdomain=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+(exit $ac_status )
+ac_cv_unixdomain=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+
+echo "$as_me:$LINENO: result: $ac_cv_unixdomain" >&5
+echo "${ECHO_T}$ac_cv_unixdomain" >&6
+if test $ac_cv_unixdomain = yes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define UNIXDOMAIN 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define UNIXdomain 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for multicast support" >&5
+echo $ECHO_N "checking for multicast support... $ECHO_C" >&6
+if test "${ac_cv_multicast+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_multicast=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#      include <sys/types.h>
+#      include <sys/socket.h>
+#      include <netinet/in.h>
+       main()
+       {
+               int fd;
+               unsigned char flag = 1;
+               struct sockaddr_in foo;
+               struct ip_mreq mreq;
+               fd = socket(AF_INET, SOCK_DGRAM, 0);
+               if (fd < 0) exit(1);
+               if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
+                              (void*)&flag, sizeof(flag)) < 0)
+                       exit(1);
+               exit(0);
+       }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_multicast=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+(exit $ac_status )
+ac_cv_multicast=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+
+echo "$as_me:$LINENO: result: $ac_cv_multicast" >&5
+echo "${ECHO_T}$ac_cv_multicast" >&6
+if test $ac_cv_multicast = yes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define MCAST 1
+_ACEOF
+
+fi
+
+LIB_OBJS=
+LIB_OBJS="$LIB_OBJS connect_nonb.o"
+LIB_OBJS="$LIB_OBJS connect_timeo.o"
+LIB_OBJS="$LIB_OBJS daemon_inetd.o"
+LIB_OBJS="$LIB_OBJS daemon_init.o"
+LIB_OBJS="$LIB_OBJS dg_cli.o"
+LIB_OBJS="$LIB_OBJS dg_echo.o"
+LIB_OBJS="$LIB_OBJS error.o"
+LIB_OBJS="$LIB_OBJS get_ifi_info.o"
+LIB_OBJS="$LIB_OBJS gf_time.o"
+LIB_OBJS="$LIB_OBJS host_serv.o"
+if test "$ac_cv_func_hstrerror" = no ; then
+   LIBFREE_OBJS="$LIBFREE_OBJS hstrerror.o"
+fi
+if test "$ac_cv_func_if_nametoindex" = no ; then
+   LIB_OBJS="$LIB_OBJS if_nametoindex.o if_indextoname.o if_nameindex.o"
+fi
+if test "$ac_cv_multicast" = yes ; then
+   LIB_OBJS="$LIB_OBJS family_to_level.o"
+   LIB_OBJS="$LIB_OBJS mcast_leave.o mcast_join.o"
+   LIB_OBJS="$LIB_OBJS mcast_get_if.o mcast_get_loop.o mcast_get_ttl.o"
+   LIB_OBJS="$LIB_OBJS mcast_set_if.o mcast_set_loop.o mcast_set_ttl.o"
+fi
+LIB_OBJS="$LIB_OBJS my_addrs.o"
+if test "$ac_cv_func_pselect" = no ; then
+   LIB_OBJS="$LIB_OBJS pselect.o"
+fi
+LIB_OBJS="$LIB_OBJS read_fd.o"
+LIB_OBJS="$LIB_OBJS readline.o"
+LIB_OBJS="$LIB_OBJS readn.o"
+LIB_OBJS="$LIB_OBJS readable_timeo.o"
+LIB_OBJS="$LIB_OBJS rtt.o"
+LIB_OBJS="$LIB_OBJS signal.o"
+LIB_OBJS="$LIB_OBJS signal_intr.o"
+if test "$ac_cv_func_snprintf" = no ; then
+   LIB_OBJS="$LIB_OBJS snprintf.o"
+fi
+if test "$ac_cv_func_sockatmark" = no ; then
+   LIB_OBJS="$LIB_OBJS sockatmark.o"
+fi
+LIB_OBJS="$LIB_OBJS sock_bind_wild.o"
+LIB_OBJS="$LIB_OBJS sock_cmp_addr.o"
+LIB_OBJS="$LIB_OBJS sock_cmp_port.o"
+LIB_OBJS="$LIB_OBJS sock_ntop.o"
+LIB_OBJS="$LIB_OBJS sock_ntop_host.o"
+LIB_OBJS="$LIB_OBJS sock_get_port.o"
+LIB_OBJS="$LIB_OBJS sock_set_addr.o"
+LIB_OBJS="$LIB_OBJS sock_set_port.o"
+LIB_OBJS="$LIB_OBJS sock_set_wild.o"
+LIB_OBJS="$LIB_OBJS sockfd_to_family.o"
+LIB_OBJS="$LIB_OBJS str_cli.o"
+LIB_OBJS="$LIB_OBJS str_echo.o"
+LIB_OBJS="$LIB_OBJS tcp_connect.o"
+LIB_OBJS="$LIB_OBJS tcp_listen.o"
+LIB_OBJS="$LIB_OBJS tv_sub.o"
+LIB_OBJS="$LIB_OBJS udp_client.o"
+LIB_OBJS="$LIB_OBJS udp_connect.o"
+LIB_OBJS="$LIB_OBJS udp_server.o"
+LIB_OBJS="$LIB_OBJS wraplib.o"
+LIB_OBJS="$LIB_OBJS wrapsock.o"
+LIB_OBJS="$LIB_OBJS wrapstdio.o"
+if test "$ac_cv_header_pthread_h" = yes ; then
+   LIB_OBJS="$LIB_OBJS wrappthread.o"
+fi
+LIB_OBJS="$LIB_OBJS wrapunix.o"
+LIB_OBJS="$LIB_OBJS write_fd.o"
+LIB_OBJS="$LIB_OBJS writen.o"
+LIB_OBJS="$LIB_OBJS writable_timeo.o"
+
+LIBFREE_OBJS=
+
+LIBFREE_OBJS="$LIBFREE_OBJS in_cksum.o"
+if test "$ac_cv_func_inet_aton" = no ; then
+   LIBFREE_OBJS="$LIBFREE_OBJS inet_aton.o"
+fi
+
+LIBFREE_OBJS="$LIBFREE_OBJS inet_ntop.o inet_pton.o"
+
+if test "$ac_cv_func_getaddrinfo" = no ; then
+LIBGAI_OBJS="getaddrinfo.o getnameinfo.o freeaddrinfo.o gai_strerror.o"
+LIBGAI_OBJS="$LIBGAI_OBJS ga_aistruct.o ga_clone.o ga_echeck.o ga_nsearch.o"
+LIBGAI_OBJS="$LIBGAI_OBJS ga_port.o ga_serv.o ga_unix.o gn_ipv46.o"
+else
+LIBGAI_OBJS=""
+fi
+
+LIBROUTE_OBJS="get_rtaddrs.o"
+LIBROUTE_OBJS="$LIBROUTE_OBJS if_indextoname.o if_nameindex.o if_nametoindex.o"
+LIBROUTE_OBJS="$LIBROUTE_OBJS net_rt_iflist.o net_rt_dump.o"
+LIBROUTE_OBJS="$LIBROUTE_OBJS sock_masktop.o"
+
+LIBXTI_OBJS=
+if test "$ac_cv_header_netdir_h" = yes ; then
+   LIBXTI_OBJS="$LIBXTI_OBJS tcp_connect.o"
+   LIBXTI_OBJS="$LIBXTI_OBJS tcp_listen.o"
+   LIBXTI_OBJS="$LIBXTI_OBJS udp_server.o"
+   LIBXTI_OBJS="$LIBXTI_OBJS udp_client.o"
+fi
+LIBXTI_OBJS="$LIBXTI_OBJS wrapxti.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_accept.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_flags_str.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_getopt.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_ntop.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_ntop_host.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_rdwr.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_setopt.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_str_opts.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_tlook_str.o"
+
+
+
+
+
+
+
+LIBS_XTI=`echo $LIBS | sed 's/-lsocket//'`
+LIBS=`echo $LIBS | sed 's/-lxti//'`
+
+
+
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking for -I$HOME/doc/unp2ev1/src/include" >&5
+echo $ECHO_N "checking for -I$HOME/doc/unp2ev1/src/include... $ECHO_C" >&6
+if test -d $HOME/doc/unp2ev1/src/include ; then
+       CFLAGS="$CFLAGS -I$HOME/doc/unp2ev1/src/include"
+       echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+       echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test "$ac_cv_c_compiler_gnu" = yes; then
+   CFLAGS="$CFLAGS -Wall"
+         fi
+
+case "$host_os" in
+*aix*)         CFLAGS="$CFLAGS -D_ALL_SOURCE" ;;
+*osf*)         CFLAGS="$CFLAGS -D_SOCKADDR_LEN" ;;
+*solaris*)     if test "$ac_cv_c_compiler_gnu" = yes; then
+                  CFLAGS="$CFLAGS -D__EXTENSIONS__"
+               else
+                  CFLAGS="$CFLAGS -D__STDC__"
+               fi ;;
+esac
+
+                    ac_config_files="$ac_config_files Makefile Make.defines"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+        "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[   ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[     ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+         sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.57.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.57,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "Make.defines" ) CONFIG_FILES="$CONFIG_FILES Make.defines" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@LIB_OBJS@,$LIB_OBJS,;t t
+s,@LIBFREE_OBJS@,$LIBFREE_OBJS,;t t
+s,@LIBGAI_OBJS@,$LIBGAI_OBJS,;t t
+s,@LIBROUTE_OBJS@,$LIBROUTE_OBJS,;t t
+s,@LIBXTI_OBJS@,$LIBXTI_OBJS,;t t
+s,@LIBS_XTI@,$LIBS_XTI,;t t
+s,@LIBUNP@,$LIBUNP,;t t
+s,@LIBUNPXTI@,$LIBUNPXTI,;t t
+s,@LIBUNP_NAME@,$LIBUNP_NAME,;t t
+s,@LIBUNPXTI_NAME@,$LIBUNPXTI_NAME,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+        cat >$tmp/stdin
+        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_file" : 'X\(//\)[^/]' \| \
+         X"$ac_file" : 'X\(//\)$' \| \
+         X"$ac_file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$as_dir" : 'X\(//\)[^/]' \| \
+         X"$as_dir" : 'X\(//\)$' \| \
+         X"$as_dir" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+         # Absolute (can't be DOS-style, as IFS=:)
+         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         echo $f;;
+      *) # Relative
+         if test -f "$f"; then
+           # Build tree
+           echo $f
+         elif test -f "$srcdir/$f"; then
+           # Source tree
+           echo $srcdir/$f
+         else
+           # /dev/null tree
+           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([  ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='[       ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+        cat >$tmp/stdin
+        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+         # Absolute (can't be DOS-style, as IFS=:)
+         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         echo $f;;
+      *) # Relative
+         if test -f "$f"; then
+           # Build tree
+           echo $f
+         elif test -f "$srcdir/$f"; then
+           # Source tree
+           echo $srcdir/$f
+         else
+           # /dev/null tree
+           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[     ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[   ]*#[    ]*define[       ][      ]*\([^  (][^    (]*\)\(([^)]*)\)[       ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[   ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[   ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[    ]*#[    ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[    ]*#[    ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[    ]*#[    ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_file" : 'X\(//\)[^/]' \| \
+         X"$ac_file" : 'X\(//\)$' \| \
+         X"$ac_file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$as_dir" : 'X\(//\)[^/]' \| \
+         X"$as_dir" : 'X\(//\)$' \| \
+         X"$as_dir" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+
+if test -d "$host" ; then
+   cp -p config.h config.cache config.status Makefile Make.defines $host
+   echo "saving copies in $host/"
+fi
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..ef3fbcd
--- /dev/null
@@ -0,0 +1,716 @@
+dnl
+dnl autoconf script for UNP 3/e Volume 1 source code.
+dnl Process this file with autoconf to produce a configure script.
+dnl
+dnl The end result of running configure is the "config.h" file and the
+dnl "Make.defines" file in the current directory.  These two files are
+dnl created from the "config.h.in" and "Make.defines.in" files in the
+dnl current directory.
+dnl
+dnl The header "unp.h" that is in every source directory then does a
+dnl #include "../config.h" and the Makefile in each source directory
+dnl then does a include of ../Make.defines.
+dnl
+AC_REVISION($Revision: 1.13 $)
+AC_INIT(lib/unp.h)
+AC_CANONICAL_HOST
+AC_CONFIG_HEADER(config.h)
+
+dnl The following cpu_vendor_os string goes into config.h.
+dnl
+AC_DEFINE_UNQUOTED(CPU_VENDOR_OS, "$host", [CPU, vendor, and operating system])
+
+dnl ##################################################################
+dnl Checks for programs.
+dnl
+
+dnl Some system-specific stuff ...
+dnl Some operating systems require additional flags in order to get all
+dnl the definitions that we're looking for in some system headers.
+dnl The configure script uses both CFLAGS and CPPFLAGS when compiling.
+case "$host_os" in
+*aix*)         CPPFLAGS="$CPPFLAGS -D_ALL_SOURCE" ;;
+*osf*)         CPPFLAGS="$CPPFLAGS -D_SOCKADDR_LEN" ;;
+esac
+
+AC_PROG_CC
+AC_PROG_RANLIB
+
+dnl ##################################################################
+dnl Checks for libraries.
+dnl The order of these tests is the *reverse* order of the libraries in
+dnl the LIBS variable that is constructed: each new one gets prepended,
+dnl not appended.
+dnl
+dnl We are building three strings here; something like:
+dnl    LIBS="-lresolv -lsocket -lnsl -lpthread"
+dnl    LIBS_XTI="-lxti -lresolv -lnsl -lpthread"
+dnl    LIBUNP="./libunp.a"
+dnl    LIBUNPXTI="./libunpxti.a"
+dnl
+dnl If a threads library is found, need to update CFLAGS too.
+dnl
+AC_CHECK_LIB(pthread, pthread_create)
+if test "$ac_cv_lib_pthread_pthread_create" = yes ; then
+   CFLAGS="$CFLAGS -D_REENTRANT"
+else
+   AC_CHECK_LIB(pthreads, pthread_create)
+   if test "$ac_cv_lib_pthreads_pthread_create" = yes ; then
+      CFLAGS="$CFLAGS -D_REENTRANT"
+   fi
+fi
+
+AC_CHECK_LIB(nsl, t_open)
+AC_SEARCH_LIBS(socket, socket)
+
+dnl Bind 8.1.1 places its library in /usr/local/bind/lib/libbind.a; we check
+dnl for it first.  Also check for libbind.a in user's home directory.
+dnl If there is a libresolv.a in the user's HOME directory, we will use
+dnl that instead of -lresolv.  Need this for people interested in building
+dnl an IPv6-knowledgable resolver, instead of using the system provided
+dnl resolver (which is often way out of date).
+dnl
+AC_MSG_CHECKING(for /usr/local/bind/lib/libbind.a)
+if test -f /usr/local/bind/lib/libbind.a ; then
+       AC_MSG_RESULT(yes)
+       LIBS="/usr/local/bind/lib/libbind.a  $LIBS"
+else
+       AC_MSG_RESULT(no)
+       AC_MSG_CHECKING(for $HOME/libbind.a)
+       if test -f $HOME/libbind.a ; then
+               AC_MSG_RESULT(yes)
+               LIBS="$HOME/libbind.a  $LIBS"
+       else
+               AC_MSG_RESULT(no)
+               AC_MSG_CHECKING(for $HOME/libresolv.a)
+               if test -f $HOME/libresolv.a ; then
+                       AC_MSG_RESULT(yes)
+                       LIBS="$HOME/libresolv.a  $LIBS"
+               else
+                       AC_MSG_RESULT(no)
+                       AC_CHECK_LIB(resolv, res_init)
+               fi
+       fi
+fi
+
+dnl Now check for XTI library.
+dnl
+AC_CHECK_LIB(xti, t_open)
+
+dnl We now need to check for our own libraries, but we cannot prepend
+dnl them to the LIBS variable, as that variable is used when compiling
+dnl programs later in this script, and that would mess things up.
+dnl
+dnl If the user has a file named $HOME/libunp.a, then use it.
+dnl Else store our library in current directory.
+dnl I use this because my source directory is NFS mounted from my various
+dnl systems, but I have a unique home directory on each system.
+dnl
+AC_MSG_CHECKING(for $HOME/libunp.a)
+if test -f $HOME/libunp.a ; then
+       AC_MSG_RESULT(yes)
+       LIBUNP="$HOME/libunp.a"
+       LIBUNP_NAME=$HOME/libunp.a
+else
+       AC_MSG_RESULT(no, using ./libunp.a)
+       LIBUNP="../libunp.a"
+       LIBUNP_NAME=../libunp.a
+fi
+
+dnl If the user has a file named $HOME/libunpxti.a, then use it.
+dnl Else store our library in current directory.
+dnl Same reasoning as above.
+dnl
+AC_MSG_CHECKING(for $HOME/libunpxti.a)
+if test -f $HOME/libunpxti.a ; then
+       AC_MSG_RESULT(yes)
+       LIBUNPXTI="$HOME/libunpxti.a"
+       LIBUNPXTI_NAME=$HOME/libunpxti.a
+else
+       AC_MSG_RESULT(no, using ./libunpxti.a)
+       LIBUNPXTI="../libunpxti.a"
+       LIBUNPXTI_NAME=../libunpxti.a
+fi
+
+dnl ##################################################################
+dnl Checks for header files.
+dnl
+dnl The list of headers in the AC_CHECK_HEADERS macro is the same as in
+dnl our "unp.h" header, followed by our "unpxti.h" header.
+dnl
+AC_HEADER_STDC
+dnl
+dnl The includes (the 4th argument to AC_CHECK_HEADERS) here are
+dnl the defeault set ($ac_includes_default) plus <sys/param.h>
+dnl for <sys/sysctl.h> on NetBSD and OpenBSD.
+AC_CHECK_HEADERS(sys/types.h sys/socket.h sys/time.h time.h netinet/in.h arpa/inet.h errno.h fcntl.h netdb.h signal.h stdio.h stdlib.h string.h sys/stat.h sys/uio.h unistd.h sys/wait.h sys/un.h sys/param.h sys/select.h sys/sysctl.h poll.h sys/event.h strings.h sys/ioctl.h sys/filio.h sys/sockio.h pthread.h net/if_dl.h xti.h xti_inet.h netconfig.h netdir.h stropts.h, [], [], [
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif])
+
+dnl ##################################################################
+dnl Checks for typedefs.
+dnl
+dnl We use our own AC_UNP_CHECK_TYPE macro, instead of AC_CHECK_TYPE,
+dnl to #include more headers.  Our macro is defined in "aclocal.m4".
+dnl
+AC_HEADER_TIME
+AC_UNP_CHECK_TYPE(uint8_t, unsigned char, 8-bit unsigned type)
+AC_UNP_CHECK_TYPE(int16_t, short, 16 bit signed type)
+AC_UNP_CHECK_TYPE(uint16_t, unsigned short, 16 bit unsigned type)
+AC_UNP_CHECK_TYPE(int32_t, int, 32 bit signed type)
+AC_UNP_CHECK_TYPE(uint32_t, unsigned int, 32 bit unsigned type)
+AC_UNP_CHECK_TYPE(size_t, unsigned int, unsigned integer type of the result of the sizeof operator)
+AC_UNP_CHECK_TYPE(ssize_t, int, a signed type appropriate for a count of bytes or an error indication)
+AC_UNP_CHECK_TYPE(socklen_t, unsigned int, a type appropriate for address, hostname, buffer, etc. lengths)
+dnl
+dnl The SA_FAMILY_T in the following is #defined later, as its definition
+dnl depends on whether socket address structures have a length field or not.
+dnl
+AC_UNP_CHECK_TYPE(sa_family_t, SA_FAMILY_T, the type of the sa_family struct member)
+
+dnl We also have our own macro to check for XTI definitions, that can
+dnl be defined after #include of our "unpxti.h" header.
+dnl
+AC_UNPXTI_CHECK_TYPE(t_scalar_t, int32_t, scalar type)
+AC_UNPXTI_CHECK_TYPE(t_uscalar_t, uint32_t, unsigned scalar type)
+
+dnl ##################################################################
+dnl Check if sockaddr{} has sa_len member.
+dnl
+AC_CHECK_MEMBER([struct sockaddr.sa_len],
+ AC_DEFINE(HAVE_SOCKADDR_SA_LEN, 1, define if socket address structures have length fields),,[
+#include <sys/types.h>
+#include <sys/socket.h>])
+
+dnl Now we can complete the definition for sa_family_t, if needed.
+dnl The size of this datatype depends whether socket address structures
+dnl have a length field or not.
+dnl
+if test $ac_cv_type_sa_family_t = no ; then
+   if test $ac_cv_member_struct_sockaddr_sa_len = yes ; then
+      AC_DEFINE(SA_FAMILY_T, uint8_t, the size of the sa_family field in a socket address structure)
+   else
+      AC_DEFINE(SA_FAMILY_T, uint16_t)
+   fi
+fi
+
+dnl
+dnl Check for sockaddr_storage.
+dnl If it's present, check for ss_family.
+dnl If ss_family isn't there, check for __ss_family and
+dnl  #define ss_family __ss_family if so.
+dnl If neither is there, I don't know what to do.
+dnl
+AC_CHECK_TYPES([struct sockaddr_storage],
+  AC_CHECK_MEMBER([struct sockaddr_storage.ss_family],,
+   AC_CHECK_MEMBER([struct sockaddr_storage.__ss_family],
+    AC_DEFINE([ss_family],[__ss_family],[define to __ss_family if sockaddr_storage has that instead of ss_family]),
+    AC_MSG_ERROR([cannot find ss_family in sockaddr_storage]),[
+#include <sys/types.h>
+#include <sys/socket.h>]),[
+#include <sys/types.h>
+#include <sys/socket.h>]),,[
+#include <sys/types.h>
+#include <sys/socket.h>])
+
+dnl Check if msghdr{} has msg_control member.
+dnl
+AC_CHECK_MEMBER([struct msghdr.msg_control],
+ AC_DEFINE(HAVE_MSGHDR_MSG_CONTROL, 1, define if struct msghdr contains the msg_control member),,[
+#include <sys/types.h>
+#include <sys/socket.h>])
+
+dnl
+dnl Check for ifr_mtu in ifreq - some systems have SIOCGIFMTU
+dnl but don't have ifr_mtu!!
+AC_CHECK_MEMBERS([struct ifreq.ifr_mtu],,,
+[#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>])
+
+dnl ##################################################################
+dnl Check for function prototypes in headers.
+dnl AC_CHECK_FUNC_PROTO is our own macro in "aclocal.m4".
+dnl
+AC_CHECK_FUNC_PROTO(getaddrinfo, netdb.h)
+AC_CHECK_FUNC_PROTO(getnameinfo, netdb.h)
+AC_CHECK_FUNC_PROTO(gethostname, unistd.h)
+AC_CHECK_FUNC_PROTO(getrusage, sys/resource.h)
+AC_CHECK_FUNC_PROTO(hstrerror, netdb.h)
+AC_CHECK_FUNC_PROTO(if_nametoindex, net/if.h)
+AC_CHECK_FUNC_PROTO(inet_aton, arpa/inet.h)
+AC_CHECK_FUNC_PROTO(inet_pton, arpa/inet.h)
+AC_CHECK_FUNC_PROTO(pselect, sys/select.h)
+AC_CHECK_FUNC_PROTO(snprintf, stdio.h)
+AC_CHECK_FUNC_PROTO(sockatmark, sys/socket.h)
+dnl
+dnl autoheader doesn't know how to handle the above, so we have
+dnl to help it out.
+AH_TEMPLATE(HAVE_GETADDRINFO_PROTO, define if getaddrinfo prototype is in <netdb.h>)
+AH_TEMPLATE(HAVE_GETNAMEINFO_PROTO, define if getnameinfo prototype is in <netdb.h>)
+AH_TEMPLATE(HAVE_GETHOSTNAME_PROTO, define if gethostname prototype is in <unistd.h>)
+AH_TEMPLATE(HAVE_GETRUSAGE_PROTO, define if getrusage prototype is in <sys/resource.h>)
+AH_TEMPLATE(HAVE_HSTRERROR_PROTO, define if hstrerror prototype is in <netdb.h>)
+AH_TEMPLATE(HAVE_IF_NAMETOINDEX_PROTO, define if if_nametoindex prototype is in <net/if.h>)
+AH_TEMPLATE(HAVE_INET_ATON_PROTO, define if inet_aton prototype is in <arpa/inet.h>)
+AH_TEMPLATE(HAVE_INET_PTON_PROTO, define if inet_pton prototype is in <arpa/inet.h>)
+AH_TEMPLATE(HAVE_PSELECT_PROTO, define if pselect prototype is in <sys/stat.h>)
+AH_TEMPLATE(HAVE_SNPRINTF_PROTO, define if snprintf prototype is in <stdio.h>)
+AH_TEMPLATE(HAVE_SOCKATMARK_PROTO, define if sockatmark prototype is in <sys/socket.h>)
+
+dnl ##################################################################
+dnl Check for structure definitions.
+dnl
+AC_CHECK_TYPE(struct addrinfo,
+ AC_DEFINE(HAVE_ADDRINFO_STRUCT, 1, Define to 1 if <netdb.h> defines struct addrinfo),,[
+#include <netdb.h>])
+
+dnl
+AC_CHECK_TYPE(struct if_nameindex,
+ AC_DEFINE(HAVE_IF_NAMEINDEX_STRUCT, 1, Define to 1 if <net/if.h> defines struct if_nameindex),,[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>])
+
+dnl
+AC_CHECK_TYPE([struct sockaddr_dl],
+ AC_DEFINE(HAVE_SOCKADDR_DL_STRUCT, 1, Define to 1 if <net/if_dl.h> defines struct sockaddr_dl),,[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if_dl.h>])
+
+dnl  OpenBSD puts struct timespec in <sys/time.h> instead of <time.h>,
+dnl  thus this complex test.
+AC_CHECK_TYPE([struct timespec],
+ AC_DEFINE(HAVE_TIMESPEC_STRUCT, 1, Define to 1 if <time.h> or <sys/time.h> defines struct timespec),,[
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+])
+
+dnl ##################################################################
+dnl Check for XTI devices.
+dnl
+AC_MSG_CHECKING(for /dev/tcp)
+if test -r /dev/tcp ; then
+       AC_DEFINE(HAVE_DEV_TCP, 1, Define to 1 if the /dev/tcp device exists)
+       AC_MSG_RESULT(yes)
+else
+       AC_MSG_RESULT(no)
+
+       AC_MSG_CHECKING(for /dev/xti/tcp)
+       if test -r /dev/xti/tcp ; then
+               AC_DEFINE(HAVE_DEV_XTI_TCP, 1, Define to 1 if the /dev/xti/tcp device exists)
+               AC_MSG_RESULT(yes)
+       else
+               AC_MSG_RESULT(no)
+
+               AC_MSG_CHECKING(for /dev/streams/xtiso/tcp)
+               if test -r /dev/streams/xtiso/tcp ; then
+                       AC_DEFINE(HAVE_DEV_STREAMS_XTISO_TCP, 1, Define to 1 if the /dev/streams/xtiso/tcp device exists)
+                       AC_MSG_RESULT(yes)
+               else
+                       AC_MSG_RESULT(no)
+               fi
+       fi
+fi
+
+dnl ##################################################################
+dnl Checks for library functions.
+dnl
+AC_CHECK_FUNCS(bzero)
+AC_CHECK_FUNCS(getaddrinfo)
+AC_CHECK_FUNCS(gethostname)
+AC_CHECK_FUNCS(gethostbyname2)
+AC_CHECK_FUNCS(gethostbyname_r)
+AC_CHECK_FUNCS(getnameinfo)
+AC_CHECK_FUNCS(hstrerror)
+AC_CHECK_FUNCS(if_nametoindex)
+AC_CHECK_FUNCS(inet_aton)
+AC_CHECK_FUNCS(inet_pton)
+AC_CHECK_FUNCS(inet6_rth_init)
+AC_CHECK_FUNCS(kqueue kevent)
+AC_CHECK_FUNCS(mkstemp)
+AC_CHECK_FUNCS(poll)
+AC_CHECK_FUNCS(pselect)
+AC_CHECK_FUNCS(snprintf)
+AC_CHECK_FUNCS(sockatmark)
+AC_CHECK_FUNCS(vsnprintf)
+
+dnl ##################################################################
+dnl Check for system services.
+
+dnl Let's see if the system really supports IPv4.
+dnl
+AC_MSG_CHECKING(for IPv4 support)
+AC_CACHE_VAL(ac_cv_ipv4,
+       AC_TRY_RUN([
+#      include <sys/types.h>
+#      include <sys/socket.h>
+#      include <netinet/in.h>
+       /* Make sure the definitions for AF_INET and struct sockaddr_in
+        * are defined, and that we can actually create an IPv4 TCP socket.
+        */
+       main()
+       {
+               int fd;
+               struct sockaddr_in foo;
+               fd = socket(AF_INET, SOCK_STREAM, 0);
+               exit(fd >= 0 ? 0 : 1);
+       }],
+       ac_cv_ipv4=yes,
+       ac_cv_ipv4=no,
+       ac_cv_ipv4=no))
+AC_MSG_RESULT($ac_cv_ipv4)
+if test $ac_cv_ipv4 = yes ; then
+       AC_DEFINE(IPV4, 1, Define to 1 if the system supports IPv4)
+       AC_DEFINE(IPv4, 1, Define to 1 if the system supports IPv4)
+fi
+
+dnl Let's see if the system really supports IPv6.
+dnl
+AC_MSG_CHECKING(for IPv6 support)
+AC_CACHE_VAL(ac_cv_ipv6,
+       AC_TRY_RUN([
+#      include <sys/types.h>
+#      include <sys/socket.h>
+#      include <netinet/in.h>
+       /* Make sure the definitions for AF_INET6 and struct sockaddr_in6
+        * are defined, and that we can actually create an IPv6 TCP socket.
+        */
+       main()
+       {
+               int fd;
+               struct sockaddr_in6 foo;
+               fd = socket(AF_INET6, SOCK_STREAM, 0);
+               exit(fd >= 0 ? 0 : 1);
+       }],
+       ac_cv_ipv6=yes,
+       ac_cv_ipv6=no,
+       ac_cv_ipv6=no))
+AC_MSG_RESULT($ac_cv_ipv6)
+if test $ac_cv_ipv6 = yes ; then
+       AC_DEFINE(IPV6, 1, Define to 1 if the system supports IPv6)
+       AC_DEFINE(IPv6, 1, Define to 1 if the system supports IPv6)
+fi
+
+dnl Let's see if the system really supports Unix domain sockets.
+dnl
+AC_MSG_CHECKING(for Unix domain sockets)
+AC_CACHE_VAL(ac_cv_unixdomain,
+       AC_TRY_RUN([
+#      include <sys/types.h>
+#      include <sys/socket.h>
+#      include <sys/un.h>
+       /* Make sure the definitions for AF_UNIX and struct sockaddr_un
+        * are defined, and that we can actually create an IPv4 TCP socket.
+        */
+       main()
+       {
+               int fd;
+               struct sockaddr_un foo;
+               fd = socket(AF_UNIX, SOCK_STREAM, 0);
+               exit(fd >= 0 ? 0 : 1);
+       }],
+       ac_cv_unixdomain=yes,
+       ac_cv_unixdomain=no,
+       ac_cv_unixdomain=no))
+AC_MSG_RESULT($ac_cv_unixdomain)
+if test $ac_cv_unixdomain = yes ; then
+       AC_DEFINE(UNIXDOMAIN, 1, Define to 1 if the system supports UNIX domain sockets)
+       AC_DEFINE(UNIXdomain, 1, Define to 1 if the system supports UNIX domain sockets)
+fi
+
+dnl Let's see if the system really supports multicasting.
+dnl
+AC_MSG_CHECKING(for multicast support)
+AC_CACHE_VAL(ac_cv_multicast,
+       AC_TRY_RUN([
+#      include <sys/types.h>
+#      include <sys/socket.h>
+#      include <netinet/in.h>
+       main()
+       {
+               int fd;
+               unsigned char flag = 1;
+               struct sockaddr_in foo;
+               struct ip_mreq mreq;
+               fd = socket(AF_INET, SOCK_DGRAM, 0);
+               if (fd < 0) exit(1);
+               if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
+                              (void*)&flag, sizeof(flag)) < 0)
+                       exit(1);
+               exit(0);
+       }],
+       ac_cv_multicast=yes,
+       ac_cv_multicast=no,
+       ac_cv_multicast=no))
+AC_MSG_RESULT($ac_cv_multicast)
+if test $ac_cv_multicast = yes ; then
+       AC_DEFINE(MCAST, 1, Define to 1 if the system supports IP Multicast)
+fi
+
+dnl ##################################################################
+dnl Build the list of object files to build from the source files in
+dnl the lib/ directory.
+dnl
+LIB_OBJS=
+LIB_OBJS="$LIB_OBJS connect_nonb.o"
+LIB_OBJS="$LIB_OBJS connect_timeo.o"
+LIB_OBJS="$LIB_OBJS daemon_inetd.o"
+LIB_OBJS="$LIB_OBJS daemon_init.o"
+LIB_OBJS="$LIB_OBJS dg_cli.o"
+LIB_OBJS="$LIB_OBJS dg_echo.o"
+LIB_OBJS="$LIB_OBJS error.o"
+LIB_OBJS="$LIB_OBJS get_ifi_info.o"
+LIB_OBJS="$LIB_OBJS gf_time.o"
+LIB_OBJS="$LIB_OBJS host_serv.o"
+if test "$ac_cv_func_hstrerror" = no ; then
+   LIBFREE_OBJS="$LIBFREE_OBJS hstrerror.o"
+fi
+if test "$ac_cv_func_if_nametoindex" = no ; then
+   LIB_OBJS="$LIB_OBJS if_nametoindex.o if_indextoname.o if_nameindex.o"
+fi
+if test "$ac_cv_multicast" = yes ; then
+   LIB_OBJS="$LIB_OBJS family_to_level.o"
+   LIB_OBJS="$LIB_OBJS mcast_leave.o mcast_join.o"
+   LIB_OBJS="$LIB_OBJS mcast_get_if.o mcast_get_loop.o mcast_get_ttl.o"
+   LIB_OBJS="$LIB_OBJS mcast_set_if.o mcast_set_loop.o mcast_set_ttl.o"
+fi
+LIB_OBJS="$LIB_OBJS my_addrs.o"
+if test "$ac_cv_func_pselect" = no ; then
+   LIB_OBJS="$LIB_OBJS pselect.o"
+fi
+LIB_OBJS="$LIB_OBJS read_fd.o"
+LIB_OBJS="$LIB_OBJS readline.o"
+LIB_OBJS="$LIB_OBJS readn.o"
+LIB_OBJS="$LIB_OBJS readable_timeo.o"
+LIB_OBJS="$LIB_OBJS rtt.o"
+LIB_OBJS="$LIB_OBJS signal.o"
+LIB_OBJS="$LIB_OBJS signal_intr.o"
+if test "$ac_cv_func_snprintf" = no ; then
+   LIB_OBJS="$LIB_OBJS snprintf.o"
+fi
+if test "$ac_cv_func_sockatmark" = no ; then
+   LIB_OBJS="$LIB_OBJS sockatmark.o"
+fi
+LIB_OBJS="$LIB_OBJS sock_bind_wild.o"
+LIB_OBJS="$LIB_OBJS sock_cmp_addr.o"
+LIB_OBJS="$LIB_OBJS sock_cmp_port.o"
+LIB_OBJS="$LIB_OBJS sock_ntop.o"
+LIB_OBJS="$LIB_OBJS sock_ntop_host.o"
+LIB_OBJS="$LIB_OBJS sock_get_port.o"
+LIB_OBJS="$LIB_OBJS sock_set_addr.o"
+LIB_OBJS="$LIB_OBJS sock_set_port.o"
+LIB_OBJS="$LIB_OBJS sock_set_wild.o"
+LIB_OBJS="$LIB_OBJS sockfd_to_family.o"
+LIB_OBJS="$LIB_OBJS str_cli.o"
+LIB_OBJS="$LIB_OBJS str_echo.o"
+LIB_OBJS="$LIB_OBJS tcp_connect.o"
+LIB_OBJS="$LIB_OBJS tcp_listen.o"
+LIB_OBJS="$LIB_OBJS tv_sub.o"
+LIB_OBJS="$LIB_OBJS udp_client.o"
+LIB_OBJS="$LIB_OBJS udp_connect.o"
+LIB_OBJS="$LIB_OBJS udp_server.o"
+LIB_OBJS="$LIB_OBJS wraplib.o"
+LIB_OBJS="$LIB_OBJS wrapsock.o"
+LIB_OBJS="$LIB_OBJS wrapstdio.o"
+if test "$ac_cv_header_pthread_h" = yes ; then
+   LIB_OBJS="$LIB_OBJS wrappthread.o"
+fi
+LIB_OBJS="$LIB_OBJS wrapunix.o"
+LIB_OBJS="$LIB_OBJS write_fd.o"
+LIB_OBJS="$LIB_OBJS writen.o"
+LIB_OBJS="$LIB_OBJS writable_timeo.o"
+
+dnl ##################################################################
+dnl Build the list of object files to build from the source files in
+dnl the libfree/ directory.
+dnl
+LIBFREE_OBJS=
+
+LIBFREE_OBJS="$LIBFREE_OBJS in_cksum.o"
+if test "$ac_cv_func_inet_aton" = no ; then
+   LIBFREE_OBJS="$LIBFREE_OBJS inet_aton.o"
+fi
+
+dnl We always include both inet_ntop() and inet_pton() because some
+dnl vendor's implementations are from the Internet Drafts leading to
+dnl RFC 1323, and are wrong.
+LIBFREE_OBJS="$LIBFREE_OBJS inet_ntop.o inet_pton.o"
+dnl if test "$ac_cv_func_inet_pton" = no ; then
+dnl    LIBFREE_OBJS="$LIBFREE_OBJS inet_pton.o"
+dnl fi
+
+dnl ##################################################################
+dnl Build the list of object files to build from the source files in
+dnl the libgai/ directory (getaddrinfo() and friends).
+dnl
+dnl If the system has a getaddrinfo implementation, then
+dnl there should be nothing here.
+if test "$ac_cv_func_getaddrinfo" = no ; then
+LIBGAI_OBJS="getaddrinfo.o getnameinfo.o freeaddrinfo.o gai_strerror.o"
+LIBGAI_OBJS="$LIBGAI_OBJS ga_aistruct.o ga_clone.o ga_echeck.o ga_nsearch.o"
+LIBGAI_OBJS="$LIBGAI_OBJS ga_port.o ga_serv.o ga_unix.o gn_ipv46.o"
+else
+LIBGAI_OBJS=""
+fi
+
+dnl ##################################################################
+dnl Build the list of object files to build from the source files in
+dnl the libroute/ directory (routing socket functions).
+dnl
+LIBROUTE_OBJS="get_rtaddrs.o"
+LIBROUTE_OBJS="$LIBROUTE_OBJS if_indextoname.o if_nameindex.o if_nametoindex.o"
+LIBROUTE_OBJS="$LIBROUTE_OBJS net_rt_iflist.o net_rt_dump.o"
+LIBROUTE_OBJS="$LIBROUTE_OBJS sock_masktop.o"
+
+dnl ##################################################################
+dnl Build the list of object files to build from the source files in
+dnl the libxti/ directory.
+dnl Systems that do not provide <netdir.h> and <netconfig.h> do not
+dnl support our tcp_XXX and udp_XXX functions.
+dnl
+LIBXTI_OBJS=
+if test "$ac_cv_header_netdir_h" = yes ; then
+   LIBXTI_OBJS="$LIBXTI_OBJS tcp_connect.o"
+   LIBXTI_OBJS="$LIBXTI_OBJS tcp_listen.o"
+   LIBXTI_OBJS="$LIBXTI_OBJS udp_server.o"
+   LIBXTI_OBJS="$LIBXTI_OBJS udp_client.o"
+fi
+LIBXTI_OBJS="$LIBXTI_OBJS wrapxti.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_accept.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_flags_str.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_getopt.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_ntop.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_ntop_host.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_rdwr.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_setopt.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_str_opts.o"
+LIBXTI_OBJS="$LIBXTI_OBJS xti_tlook_str.o"
+
+dnl Now make certain that when configure is run, AC_OUTPUT replaces these
+dnl strings that we built in shell variables in the output files that
+dnl it generates.
+dnl
+AC_SUBST(LIB_OBJS)
+AC_SUBST(LIBFREE_OBJS)
+AC_SUBST(LIBGAI_OBJS)
+AC_SUBST(LIBROUTE_OBJS)
+AC_SUBST(LIBXTI_OBJS)
+
+dnl We need our own variable LIBS_XTI for linking XTI programs,
+dnl but do not want -lsocket in there.
+dnl Ditto for -lxti in LIBS.
+dnl
+LIBS_XTI=`echo $LIBS | sed 's/-lsocket//'`
+LIBS=`echo $LIBS | sed 's/-lxti//'`
+
+AC_SUBST(LIBS_XTI)
+
+AC_SUBST(LIBUNP)
+AC_SUBST(LIBUNPXTI)
+
+AC_SUBST(LIBUNP_NAME)
+AC_SUBST(LIBUNPXTI_NAME)
+
+dnl ##################################################################
+dnl Now that we're doing compiling, modify CFLAGS.
+dnl
+dnl If the directory $HOME/doc/unp2ev1/src/include exists, the user can
+dnl place modified copies of the system's headers in there, with the
+dnl function prototypes corrected, as per Posix and X/Open.  Lots of
+dnl system headers today are missing const qualifiers, they have char*
+dnl instead of void*, and so on.
+dnl
+AC_MSG_CHECKING(for -I$HOME/doc/unp2ev1/src/include)
+if test -d $HOME/doc/unp2ev1/src/include ; then
+       CFLAGS="$CFLAGS -I$HOME/doc/unp2ev1/src/include"
+       AC_MSG_RESULT(yes)
+else
+       AC_MSG_RESULT(no)
+fi
+
+dnl If the compiler is gcc, enable all warnings.  Main purpose is to
+dnl catch any function call where the function has not been prototyped.
+dnl
+if test "$ac_cv_prog_gcc" = yes; then
+   CFLAGS="$CFLAGS -Wall"
+   dnl
+   dnl These warnings are useful during development, but not to deploy.
+   dnl CFLAGS="$CFLAGS -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wno-format-extra-args"
+fi
+
+dnl Some system-specific stuff ...
+dnl Some operating systems require additional flags in order to get all
+dnl the definitions that we're looking for in some system headers.
+case "$host_os" in
+*aix*)         CFLAGS="$CFLAGS -D_ALL_SOURCE" ;;
+*osf*)         CFLAGS="$CFLAGS -D_SOCKADDR_LEN" ;;
+*solaris*)     if test "$ac_cv_prog_gcc" = yes; then
+                  CFLAGS="$CFLAGS -D__EXTENSIONS__"
+               else
+                  CFLAGS="$CFLAGS -D__STDC__"
+               fi ;;
+esac
+
+dnl ##################################################################
+dnl We also create a "Makefile" but it is not used for much.
+dnl
+AC_OUTPUT(Makefile Make.defines)
+
+dnl
+dnl If a directory exists whose name equals the host
+dnl (e.g., sparc-sun-solaris2.5.1), then save the five files that we
+dnl create in that directory also.
+dnl Quick and dirty to be able to NFS mount this directory on different
+dnl systems and move quickly between the systems, without having to
+dnl rerun configure each time.
+dnl The "myconfig" script in this directory does the move.
+dnl
+if test -d "$host" ; then
+   cp -p config.h config.cache config.status Makefile Make.defines $host
+   echo "saving copies in $host/"
+fi
diff --git a/debug/Makefile b/debug/Makefile
new file mode 100644 (file)
index 0000000..bc3eaab
--- /dev/null
@@ -0,0 +1,32 @@
+include ../Make.defines
+
+PROGS =        qlen backlog test01 test02 test03 test04 test05 test06
+
+all:   ${PROGS}
+
+backlog:       backlog.o
+               ${CC} ${CFLAGS} -o $@ backlog.o ${LIBS}
+
+qlen:  qlen.o
+               ${CC} ${CFLAGS} -o $@ qlen.o ${LIBS_XTI}
+
+test01:        test01.o
+               ${CC} ${CFLAGS} -o $@ test01.o ${LIBS_XTI}
+
+test02:        test02.o
+               ${CC} ${CFLAGS} -o $@ test02.o ${LIBS}
+
+test03:        test03.o
+               ${CC} ${CFLAGS} -o $@ test03.o ${LIBS_XTI}
+
+test04:        test04.o
+               ${CC} ${CFLAGS} -o $@ test04.o ${LIBS}
+
+test05:        test05.o
+               ${CC} ${CFLAGS} -o $@ test05.o ${LIBS_XTI}
+
+test06:        test06.o
+               ${CC} ${CFLAGS} -o $@ test06.o ${LIBS_XTI}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/debug/backlog.c b/debug/backlog.c
new file mode 100644 (file)
index 0000000..94c1fa4
--- /dev/null
@@ -0,0 +1,99 @@
+#include       "unp.h"
+
+#define        PORT            9999
+#define        ADDR            "127.0.0.1"
+#define        MAXBACKLOG      100
+
+                       /* globals */
+struct sockaddr_in     serv;
+pid_t                          pid;    /* of child */
+
+int                    pipefd[2];
+#define        pfd     pipefd[1]       /* parent's end */
+#define        cfd     pipefd[0]       /* child's end */
+
+                       /* function prototypes */
+void   do_parent(void);
+void   do_child(void);
+
+int
+main(int argc, char **argv)
+{
+       if (argc != 1)
+               err_quit("usage: backlog");
+
+       Socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd);
+
+       bzero(&serv, sizeof(serv));
+       serv.sin_family = AF_INET;
+       serv.sin_port = htons(PORT);
+       Inet_pton(AF_INET, ADDR, &serv.sin_addr);
+
+       if ( (pid = Fork()) == 0)
+               do_child();
+       else
+               do_parent();
+               
+       exit(0);
+}
+
+void
+parent_alrm(int signo)
+{
+       return;         /* just interrupt blocked connect() */
+}
+
+void
+do_parent(void)
+{
+       int             backlog, j, k, junk, fd[MAXBACKLOG + 1];
+
+       Close(cfd);
+       Signal(SIGALRM, parent_alrm);
+
+       for (backlog = 0; backlog <= 14; backlog++) {
+               printf("backlog = %d: ", backlog);
+               Write(pfd, &backlog, sizeof(int));      /* tell child value */
+               Read(pfd, &junk, sizeof(int));          /* wait for child */
+
+               for (j = 1; j <= MAXBACKLOG; j++) {
+                       fd[j] = Socket(AF_INET, SOCK_STREAM, 0);
+                       alarm(2);
+                       if (connect(fd[j], (SA * ) &serv, sizeof(serv)) < 0) {
+                               if (errno != EINTR)
+                                       err_sys("connect error, j = %d", j);
+                               printf("timeout, %d connections completed\n", j-1);
+                               for (k = 1; k <= j; k++)
+                                       Close(fd[k]);
+                               break;  /* next value of backlog */
+                       }
+                       alarm(0);
+               }
+               if (j > MAXBACKLOG)
+                       printf("%d connections?\n", MAXBACKLOG);
+       }
+       backlog = -1;           /* tell child we're all done */
+       Write(pfd, &backlog, sizeof(int));
+}
+
+void
+do_child(void)
+{
+       int             listenfd, backlog, junk;
+       const int       on = 1;
+
+       Close(pfd);
+
+       Read(cfd, &backlog, sizeof(int));       /* wait for parent */
+       while (backlog >= 0) {
+               listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+               Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+               Bind(listenfd, (SA *) &serv, sizeof(serv));
+               Listen(listenfd, backlog);              /* start the listen */
+
+               Write(cfd, &junk, sizeof(int)); /* tell parent */
+
+               Read(cfd, &backlog, sizeof(int));/* just wait for parent */
+               Close(listenfd);        /* closes all queued connections, too */
+       }
+}
diff --git a/debug/backlog.lc b/debug/backlog.lc
new file mode 100644 (file)
index 0000000..f37170c
--- /dev/null
@@ -0,0 +1,99 @@
+#include    "unp.h"##  1 ##src/debug/backlog.c##
+
+#define PORT        9999##  2 ##src/debug/backlog.c##
+#define ADDR        "127.0.0.1"##  3 ##src/debug/backlog.c##
+#define MAXBACKLOG  100##  4 ##src/debug/backlog.c##
+
+            /* globals */##  5 ##src/debug/backlog.c##
+struct sockaddr_in serv;##  6 ##src/debug/backlog.c##
+pid_t   pid;                    /* of child */##  7 ##src/debug/backlog.c##
+
+int     pipefd[2];##  8 ##src/debug/backlog.c##
+#define pfd pipefd[1]           /* parent's end */##  9 ##src/debug/backlog.c##
+#define cfd pipefd[0]           /* child's end */## 10 ##src/debug/backlog.c##
+
+            /* function prototypes */## 11 ##src/debug/backlog.c##
+void    do_parent(void);## 12 ##src/debug/backlog.c##
+void    do_child(void);## 13 ##src/debug/backlog.c##
+
+int## 14 ##src/debug/backlog.c##
+main(int argc, char **argv)## 15 ##src/debug/backlog.c##
+{## 16 ##src/debug/backlog.c##
+    if (argc != 1)## 17 ##src/debug/backlog.c##
+        err_quit("usage: backlog");## 18 ##src/debug/backlog.c##
+
+    Socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd);## 19 ##src/debug/backlog.c##
+
+    bzero(&serv, sizeof(serv));## 20 ##src/debug/backlog.c##
+    serv.sin_family = AF_INET;## 21 ##src/debug/backlog.c##
+    serv.sin_port = htons(PORT);## 22 ##src/debug/backlog.c##
+    Inet_pton(AF_INET, ADDR, &serv.sin_addr);## 23 ##src/debug/backlog.c##
+
+    if ((pid = Fork()) == 0)## 24 ##src/debug/backlog.c##
+        do_child();## 25 ##src/debug/backlog.c##
+    else## 26 ##src/debug/backlog.c##
+        do_parent();## 27 ##src/debug/backlog.c##
+
+    exit(0);## 28 ##src/debug/backlog.c##
+}## 29 ##src/debug/backlog.c##
+
+void## 30 ##src/debug/backlog.c##
+parent_alrm(int signo)## 31 ##src/debug/backlog.c##
+{## 32 ##src/debug/backlog.c##
+    return;                     /* just interrupt blocked connect() */## 33 ##src/debug/backlog.c##
+}## 34 ##src/debug/backlog.c##
+
+void## 35 ##src/debug/backlog.c##
+do_parent(void)## 36 ##src/debug/backlog.c##
+{## 37 ##src/debug/backlog.c##
+    int     backlog, j, k, junk, fd[MAXBACKLOG + 1];## 38 ##src/debug/backlog.c##
+
+    Close(cfd);## 39 ##src/debug/backlog.c##
+    Signal(SIGALRM, parent_alrm);## 40 ##src/debug/backlog.c##
+
+    for (backlog = 0; backlog <= 14; backlog++) {## 41 ##src/debug/backlog.c##
+        printf("backlog = %d: ", backlog);## 42 ##src/debug/backlog.c##
+        Write(pfd, &backlog, sizeof(int));  /* tell child value */## 43 ##src/debug/backlog.c##
+        Read(pfd, &junk, sizeof(int));  /* wait for child */## 44 ##src/debug/backlog.c##
+
+        for (j = 1; j <= MAXBACKLOG; j++) {## 45 ##src/debug/backlog.c##
+            fd[j] = Socket(AF_INET, SOCK_STREAM, 0);## 46 ##src/debug/backlog.c##
+            alarm(2);## 47 ##src/debug/backlog.c##
+            if (connect(fd[j], (SA *) &serv, sizeof(serv)) < 0) {## 48 ##src/debug/backlog.c##
+                if (errno != EINTR)## 49 ##src/debug/backlog.c##
+                    err_sys("connect error, j = %d", j);## 50 ##src/debug/backlog.c##
+                printf("timeout, %d connections completed\n", j - 1);## 51 ##src/debug/backlog.c##
+                for (k = 1; k <= j; k++)## 52 ##src/debug/backlog.c##
+                    Close(fd[k]);## 53 ##src/debug/backlog.c##
+                break;          /* next value of backlog */## 54 ##src/debug/backlog.c##
+            }## 55 ##src/debug/backlog.c##
+            alarm(0);## 56 ##src/debug/backlog.c##
+        }## 57 ##src/debug/backlog.c##
+        if (j > MAXBACKLOG)## 58 ##src/debug/backlog.c##
+            printf("%d connections?\n", MAXBACKLOG);## 59 ##src/debug/backlog.c##
+    }## 60 ##src/debug/backlog.c##
+    backlog = -1;               /* tell child we're all done */## 61 ##src/debug/backlog.c##
+    Write(pfd, &backlog, sizeof(int));## 62 ##src/debug/backlog.c##
+}## 63 ##src/debug/backlog.c##
+
+void## 64 ##src/debug/backlog.c##
+do_child(void)## 65 ##src/debug/backlog.c##
+{## 66 ##src/debug/backlog.c##
+    int     listenfd, backlog, junk;## 67 ##src/debug/backlog.c##
+    const int on = 1;## 68 ##src/debug/backlog.c##
+
+    Close(pfd);## 69 ##src/debug/backlog.c##
+
+    Read(cfd, &backlog, sizeof(int));   /* wait for parent */## 70 ##src/debug/backlog.c##
+    while (backlog >= 0) {## 71 ##src/debug/backlog.c##
+        listenfd = Socket(AF_INET, SOCK_STREAM, 0);## 72 ##src/debug/backlog.c##
+        Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 73 ##src/debug/backlog.c##
+        Bind(listenfd, (SA *) &serv, sizeof(serv));## 74 ##src/debug/backlog.c##
+        Listen(listenfd, backlog);  /* start the listen */## 75 ##src/debug/backlog.c##
+
+        Write(cfd, &junk, sizeof(int)); /* tell parent */## 76 ##src/debug/backlog.c##
+
+        Read(cfd, &backlog, sizeof(int));   /* just wait for parent */## 77 ##src/debug/backlog.c##
+        Close(listenfd);        /* closes all queued connections too */## 78 ##src/debug/backlog.c##
+    }## 79 ##src/debug/backlog.c##
+}## 80 ##src/debug/backlog.c##
diff --git a/debug/qlen.c b/debug/qlen.c
new file mode 100644 (file)
index 0000000..294b9a5
--- /dev/null
@@ -0,0 +1,119 @@
+#include       "unpxti.h"
+
+#define        PORT            9999
+#define        ADDR            "127.0.0.1"
+#define        MAXBACKLOG      100
+
+                       /* globals */
+struct sockaddr_in     serv;
+pid_t                          pid;    /* of child */
+
+int                    pipefd[2];
+#define        pfd     pipefd[1]       /* parent's end */
+#define        cfd     pipefd[0]       /* child's end */
+
+                       /* function prototypes */
+void   do_parent(void);
+void   do_child(void);
+
+int
+main(int argc, char **argv)
+{
+       if (argc != 1)
+               err_quit("usage: qlen");
+
+       Socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd);
+
+       bzero(&serv, sizeof(serv));
+       serv.sin_family = AF_INET;
+       serv.sin_port = htons(PORT);
+       Inet_pton(AF_INET, ADDR, &serv.sin_addr);
+
+       if ( (pid = Fork()) == 0)
+               do_child();
+       else
+               do_parent();
+               
+       exit(0);
+}
+
+void
+parent_alrm(int signo)
+{
+       return;         /* just interrupt blocked connect() */
+}
+
+/* include qlen */
+void
+do_parent(void)
+{
+       int                             qlen, j, k, junk, fd[MAXBACKLOG + 1];
+       struct t_call   tcall;
+
+       Close(cfd);
+       Signal(SIGALRM, parent_alrm);
+
+       for (qlen = 0; qlen <= 14; qlen++) {
+               printf("qlen = %d: ", qlen);
+               Write(pfd, &qlen, sizeof(int)); /* tell child value */
+               Read(pfd, &junk, sizeof(int));  /* wait for child */
+
+               for (j = 0; j <= MAXBACKLOG; j++) {
+                       fd[j] = T_open(XTI_TCP, O_RDWR, NULL);
+                       T_bind(fd[j], NULL, NULL);
+
+                       tcall.addr.maxlen = sizeof(serv);
+                       tcall.addr.len = sizeof(serv);
+                       tcall.addr.buf = &serv;
+                       tcall.opt.len = 0;
+                       tcall.udata.len = 0;
+
+                       alarm(2);
+                       if (t_connect(fd[j], &tcall, NULL) < 0) {
+                               if (errno != EINTR)
+                                       err_xti("t_connect error, j = %d", j);
+                               printf("timeout, %d connections completed\n", j-1);
+                               for (k = 1; k < j; k++)
+                                       T_close(fd[k]);
+                               break;  /* next value of qlen */
+                       }
+                       alarm(0);
+               }
+               if (j > MAXBACKLOG)
+                       printf("%d connections?\n", MAXBACKLOG);
+       }
+       qlen = -1;              /* tell child we're all done */
+       Write(pfd, &qlen, sizeof(int));
+}
+
+void
+do_child(void)
+{
+       int                             listenfd, qlen, junk;
+       struct t_bind   tbind, tbindret;
+
+       Close(pipefd[1]);
+
+       Read(cfd, &qlen, sizeof(int));  /* wait for parent */
+       while (qlen >= 0) {
+               listenfd = T_open(XTI_TCP, O_RDWR, NULL);
+
+               tbind.addr.maxlen = sizeof(serv);
+               tbind.addr.len = sizeof(serv);
+               tbind.addr.buf = &serv;
+               tbind.qlen = qlen;
+
+               tbindret.addr.maxlen = 0;
+               tbindret.addr.len = 0;
+
+               T_bind(listenfd, &tbind, &tbindret);
+               printf("returned qlen = %d, ", tbindret.qlen);
+               fflush(stdout);
+
+               Write(cfd, &junk, sizeof(int)); /* tell parent */
+
+               Read(cfd, &qlen, sizeof(int));  /* just wait for parent */
+               T_close(listenfd);      /* closes all queued connections too */
+       }
+}
+/* end qlen */
diff --git a/debug/qlen.lc b/debug/qlen.lc
new file mode 100644 (file)
index 0000000..1b7cb0d
--- /dev/null
@@ -0,0 +1,119 @@
+#include    "unpxti.h"##  1 ##src/debug/qlen.c##
+
+#define PORT        9999##  2 ##src/debug/qlen.c##
+#define ADDR        "127.0.0.1"##  3 ##src/debug/qlen.c##
+#define MAXBACKLOG  100##  4 ##src/debug/qlen.c##
+
+            /* globals */##  5 ##src/debug/qlen.c##
+struct sockaddr_in serv;##  6 ##src/debug/qlen.c##
+pid_t   pid;                    /* of child */##  7 ##src/debug/qlen.c##
+
+int     pipefd[2];##  8 ##src/debug/qlen.c##
+#define pfd pipefd[1]           /* parent's end */##  9 ##src/debug/qlen.c##
+#define cfd pipefd[0]           /* child's end */## 10 ##src/debug/qlen.c##
+
+            /* function prototypes */## 11 ##src/debug/qlen.c##
+void    do_parent(void);## 12 ##src/debug/qlen.c##
+void    do_child(void);## 13 ##src/debug/qlen.c##
+
+int## 14 ##src/debug/qlen.c##
+main(int argc, char **argv)## 15 ##src/debug/qlen.c##
+{## 16 ##src/debug/qlen.c##
+    if (argc != 1)## 17 ##src/debug/qlen.c##
+        err_quit("usage: qlen");## 18 ##src/debug/qlen.c##
+
+    Socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd);## 19 ##src/debug/qlen.c##
+
+    bzero(&serv, sizeof(serv));## 20 ##src/debug/qlen.c##
+    serv.sin_family = AF_INET;## 21 ##src/debug/qlen.c##
+    serv.sin_port = htons(PORT);## 22 ##src/debug/qlen.c##
+    Inet_pton(AF_INET, ADDR, &serv.sin_addr);## 23 ##src/debug/qlen.c##
+
+    if ((pid = Fork()) == 0)## 24 ##src/debug/qlen.c##
+        do_child();## 25 ##src/debug/qlen.c##
+    else## 26 ##src/debug/qlen.c##
+        do_parent();## 27 ##src/debug/qlen.c##
+
+    exit(0);## 28 ##src/debug/qlen.c##
+}## 29 ##src/debug/qlen.c##
+
+void## 30 ##src/debug/qlen.c##
+parent_alrm(int signo)## 31 ##src/debug/qlen.c##
+{## 32 ##src/debug/qlen.c##
+    return;                     /* just interrupt blocked connect() */## 33 ##src/debug/qlen.c##
+}## 34 ##src/debug/qlen.c##
+
+/* include qlen */
+void## 35 ##src/debug/qlen.c##
+do_parent(void)## 36 ##src/debug/qlen.c##
+{## 37 ##src/debug/qlen.c##
+    int     qlen, j, k, junk, fd[MAXBACKLOG + 1];## 38 ##src/debug/qlen.c##
+    struct t_call tcall;## 39 ##src/debug/qlen.c##
+
+    Close(cfd);## 40 ##src/debug/qlen.c##
+    Signal(SIGALRM, parent_alrm);## 41 ##src/debug/qlen.c##
+
+    for (qlen = 0; qlen <= 14; qlen++) {## 42 ##src/debug/qlen.c##
+        printf("qlen = %d: ", qlen);## 43 ##src/debug/qlen.c##
+        Write(pfd, &qlen, sizeof(int)); /* tell child value */## 44 ##src/debug/qlen.c##
+        Read(pfd, &junk, sizeof(int));  /* wait for child */## 45 ##src/debug/qlen.c##
+
+        for (j = 0; j <= MAXBACKLOG; j++) {## 46 ##src/debug/qlen.c##
+            fd[j] = T_open(XTI_TCP, O_RDWR, NULL);## 47 ##src/debug/qlen.c##
+            T_bind(fd[j], NULL, NULL);## 48 ##src/debug/qlen.c##
+
+            tcall.addr.maxlen = sizeof(serv);## 49 ##src/debug/qlen.c##
+            tcall.addr.len = sizeof(serv);## 50 ##src/debug/qlen.c##
+            tcall.addr.buf = &serv;## 51 ##src/debug/qlen.c##
+            tcall.opt.len = 0;## 52 ##src/debug/qlen.c##
+            tcall.udata.len = 0;## 53 ##src/debug/qlen.c##
+
+            alarm(2);## 54 ##src/debug/qlen.c##
+            if (t_connect(fd[j], &tcall, NULL) < 0) {## 55 ##src/debug/qlen.c##
+                if (errno != EINTR)## 56 ##src/debug/qlen.c##
+                    err_xti("t_connect error, j = %d", j);## 57 ##src/debug/qlen.c##
+                printf("timeout, %d connections completed\n", j - 1);## 58 ##src/debug/qlen.c##
+                for (k = 1; k < j; k++)## 59 ##src/debug/qlen.c##
+                    T_close(fd[k]);## 60 ##src/debug/qlen.c##
+                break;          /* next value of qlen */## 61 ##src/debug/qlen.c##
+            }## 62 ##src/debug/qlen.c##
+            alarm(0);## 63 ##src/debug/qlen.c##
+        }## 64 ##src/debug/qlen.c##
+        if (j > MAXBACKLOG)## 65 ##src/debug/qlen.c##
+            printf("%d connections?\n", MAXBACKLOG);## 66 ##src/debug/qlen.c##
+    }## 67 ##src/debug/qlen.c##
+    qlen = -1;                  /* tell child we're all done */## 68 ##src/debug/qlen.c##
+    Write(pfd, &qlen, sizeof(int));## 69 ##src/debug/qlen.c##
+}## 70 ##src/debug/qlen.c##
+
+void## 71 ##src/debug/qlen.c##
+do_child(void)## 72 ##src/debug/qlen.c##
+{## 73 ##src/debug/qlen.c##
+    int     listenfd, qlen, junk;## 74 ##src/debug/qlen.c##
+    struct t_bind tbind, tbindret;## 75 ##src/debug/qlen.c##
+
+    Close(pipefd[1]);## 76 ##src/debug/qlen.c##
+
+    Read(cfd, &qlen, sizeof(int));  /* wait for parent */## 77 ##src/debug/qlen.c##
+    while (qlen >= 0) {## 78 ##src/debug/qlen.c##
+        listenfd = T_open(XTI_TCP, O_RDWR, NULL);## 79 ##src/debug/qlen.c##
+
+        tbind.addr.maxlen = sizeof(serv);## 80 ##src/debug/qlen.c##
+        tbind.addr.len = sizeof(serv);## 81 ##src/debug/qlen.c##
+        tbind.addr.buf = &serv;## 82 ##src/debug/qlen.c##
+        tbind.qlen = qlen;## 83 ##src/debug/qlen.c##
+
+        tbindret.addr.maxlen = 0;## 84 ##src/debug/qlen.c##
+        tbindret.addr.len = 0;## 85 ##src/debug/qlen.c##
+
+        T_bind(listenfd, &tbind, &tbindret);## 86 ##src/debug/qlen.c##
+        printf("returned qlen = %d, ", tbindret.qlen);## 87 ##src/debug/qlen.c##
+        fflush(stdout);## 88 ##src/debug/qlen.c##
+
+        Write(cfd, &junk, sizeof(int)); /* tell parent */## 89 ##src/debug/qlen.c##
+
+        Read(cfd, &qlen, sizeof(int));  /* just wait for parent */## 90 ##src/debug/qlen.c##
+        T_close(listenfd);      /* closes all queued connections too */## 91 ##src/debug/qlen.c##
+    }## 92 ##src/debug/qlen.c##
+}## 93 ##src/debug/qlen.c##
+/* end qlen */
diff --git a/debug/test01.c b/debug/test01.c
new file mode 100644 (file)
index 0000000..1535d1a
--- /dev/null
@@ -0,0 +1,16 @@
+#include       "unpxti.h"
+
+int
+main(int argc, char **argv)
+{
+       int             tfd;
+
+       if (argc != 3)
+               err_quit("usage: test01 <hostname/IPaddress> <service/port#>");
+
+       tfd = Tcp_connect(argv[1], argv[2]);
+
+       t_snd(tfd, "", 1, T_EXPEDITED);
+
+       exit(0);
+}
diff --git a/debug/test01.lc b/debug/test01.lc
new file mode 100644 (file)
index 0000000..40a8994
--- /dev/null
@@ -0,0 +1,16 @@
+#include    "unpxti.h"##  1 ##src/debug/test01.c##
+
+int##  2 ##src/debug/test01.c##
+main(int argc, char **argv)##  3 ##src/debug/test01.c##
+{##  4 ##src/debug/test01.c##
+    int     tfd;##  5 ##src/debug/test01.c##
+
+    if (argc != 3)##  6 ##src/debug/test01.c##
+        err_quit("usage: test01 <hostname/IPaddress> <service/port#>");##  7 ##src/debug/test01.c##
+
+    tfd = Tcp_connect(argv[1], argv[2]);##  8 ##src/debug/test01.c##
+
+    t_snd(tfd, "", 1, T_EXPEDITED);##  9 ##src/debug/test01.c##
+
+    exit(0);## 10 ##src/debug/test01.c##
+}## 11 ##src/debug/test01.c##
diff --git a/debug/test02.c b/debug/test02.c
new file mode 100644 (file)
index 0000000..1eab86d
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             fd;
+       fd_set  exset;
+
+       if (argc != 3)
+               err_quit("usage: test01 <hostname/IPaddress> <service/port#>");
+
+       fd = Tcp_connect(argv[1], argv[2]);
+
+       FD_ZERO(&exset);
+       FD_SET(fd, &exset);
+       select(fd+1, NULL, NULL, &exset, NULL);
+
+       exit(0);
+}
diff --git a/debug/test03.c b/debug/test03.c
new file mode 100644 (file)
index 0000000..38feda8
--- /dev/null
@@ -0,0 +1,28 @@
+#include       "unpxti.h"
+
+int
+main(int argc, char **argv)
+{
+       int                             listenfd, connfd, n, flags;
+       char                    buff[MAXLINE];
+       struct pollfd   fds[1];
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], NULL);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], NULL);
+       else
+               err_quit("usage: daytimetcpsrv01 [ <host> ] <service or port>");
+       
+       connfd = Xti_accept(listenfd, NULL, 0);
+
+       fds[0].fd = connfd;
+       fds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI;
+       for ( ; ; ) {
+               n = poll(fds, 1, INFTIM);
+               printf("poll returned %d, revents = 0x%x\n", n, fds[0].revents);
+
+               n = T_rcv(connfd, buff, sizeof(buff), &flags);
+               printf("received %d bytes, flags = %d\n", n, flags);
+       }
+}
diff --git a/debug/test04.c b/debug/test04.c
new file mode 100644 (file)
index 0000000..4f86b87
--- /dev/null
@@ -0,0 +1,64 @@
+#include       "unp.h"
+
+void
+sig_alrm(int signo)
+{
+}
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, n;
+       struct sockaddr_in      servaddr;
+       struct itimerval        val;
+       fd_set                          rset, wset;
+
+       if (argc != 2)
+               err_quit("usage: a.out <IPaddress>");
+
+       if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+               err_sys("socket error");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port   = htons(13);        /* echo server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+               /* Set interval timer to go off before 3WHS completes */
+       Signal(SIGALRM, sig_alrm);
+       val.it_interval.tv_sec  = 0;
+       val.it_interval.tv_usec = 0;
+       val.it_value.tv_sec  = 0;
+       val.it_value.tv_usec = 50000;   /* 50 ms */
+       if (setitimer(ITIMER_REAL, &val, NULL) == -1)
+               err_sys("setitimer error");
+
+again:
+       if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) {
+               if (errno == EINTR) {
+#ifdef notdef
+                       goto again;     /* second call to connect() -> EADDRINUSE */
+#endif
+#ifdef notdef
+                       printf("interrupted system call\n");
+                       exit(0);
+#endif
+               } else
+                       err_sys("connect error");
+       }
+
+       FD_ZERO(&rset);
+       FD_SET(sockfd, &rset);
+       wset = rset;
+sleep(4);
+       n = Select(sockfd+1, &rset, &wset, NULL, NULL);
+       printf("select returned %d\n", n);
+       if (FD_ISSET(sockfd, &rset))
+               printf("socket is readable\n");
+       if (FD_ISSET(sockfd, &wset))
+               printf("socket is writable\n");
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/debug/test05.c b/debug/test05.c
new file mode 100644 (file)
index 0000000..ab0b41f
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unpxti.h"
+
+int            listenfd, connfd;
+
+void
+sig_poll(int signo)
+{
+       int             n, flags;
+       char    buff[MAXLINE];
+
+       printf("SIGPOLL, event = %d\n", t_look(connfd));
+       n = T_rcv(connfd, buff, sizeof(buff), &flags);
+       printf("received %d bytes, flags = %d\n", n, flags);
+}
+
+int
+main(int argc, char **argv)
+{
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], NULL);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], NULL);
+       else
+               err_quit("usage: test05 [ <host> ] <service or port>");
+       
+       connfd = Xti_accept(listenfd, NULL, 0);
+
+       Signal(SIGPOLL, sig_poll);
+       Ioctl(connfd, I_SETSIG, S_RDNORM);
+
+       for ( ; ; ) {
+               pause();
+       }
+}
diff --git a/debug/test06.c b/debug/test06.c
new file mode 100644 (file)
index 0000000..0d99456
--- /dev/null
@@ -0,0 +1,18 @@
+#include       "unpxti.h"
+
+int
+main(int argc, char **argv)
+{
+       int                             fd;
+       struct t_call   *tcall;
+
+       fd = T_open(XTI_TCP, O_RDWR, NULL);
+
+       tcall = T_alloc(fd, T_CALL, T_ALL);
+       printf("first t_alloc OK\n");
+
+       tcall = T_alloc(fd, T_CALL, T_ADDR | T_OPT | T_UDATA);
+       printf("second t_alloc OK\n");
+
+       exit(0);
+}
diff --git a/debug/unpxti.h b/debug/unpxti.h
new file mode 100644 (file)
index 0000000..6fe4b18
--- /dev/null
@@ -0,0 +1,152 @@
+/* include unpxtih1 */
+#ifndef        __unp_xti_h
+#define        __unp_xti_h
+
+#include       "unp.h"
+
+#include       <xti.h>
+#ifdef HAVE_XTI_INET_H
+# include      <xti_inet.h>
+#endif
+#ifdef HAVE_NETCONFIG_H
+# include      <netconfig.h>
+#endif
+#ifdef HAVE_NETDIR_H
+# include      <netdir.h>
+#endif
+
+#ifdef INFTIM_UNPH
+#undef INFTIM  /* was not in <poll.h>, undef for <stropts.h> */
+#endif
+
+#include       <stropts.h>
+
+/* Provide compatibility with the new names prepended with T_
+   in XNS Issue 5, which are not in Posix.1g. */
+
+#ifndef        T_INET_TCP
+#define        T_INET_TCP              INET_TCP
+/* $$.Ic T_INET_TCP$$ */
+#endif
+/* end unpxtih1 */
+#ifndef        T_INET_UDP
+#define        T_INET_UDP              INET_UDP
+#endif
+#ifndef        T_INET_IP
+#define        T_INET_IP               INET_IP
+#endif
+#ifndef        T_TCP_NODELAY
+#define        T_TCP_NODELAY   TCP_NODELAY
+#endif
+#ifndef        T_TCP_MAXSEG
+#define        T_TCP_MAXSEG    TCP_MAXSEG
+#endif
+#ifndef        T_TCP_KEEPALIVE
+#define        T_TCP_KEEPALIVE TCP_KEEPALIVE
+#endif
+#ifndef        T_UDP_CHECKSUM
+#define        T_UDP_CHECKSUM  UDP_CHECKSUM
+#endif
+#ifndef        T_IP_OPTIONS
+#define        T_IP_OPTIONS    IP_OPTIONS
+#endif
+#ifndef        T_IP_TOS
+#define        T_IP_TOS                IP_TOS
+#endif
+#ifndef        T_IP_TTL
+#define        T_IP_TTL                IP_TTL
+#endif
+#ifndef        T_IP_REUSEADDR
+#define        T_IP_REUSEADDR  IP_REUSEADDR
+#endif
+#ifndef        T_IP_DONTROUTE
+#define        T_IP_DONTROUTE  IP_DONTROUTE
+#endif
+/* include unpxtih2 */
+#ifndef        T_IP_BROADCAST
+#define        T_IP_BROADCAST  IP_BROADCAST
+/* $$.Ic T_IP_BROADCAST$$ */
+#endif
+
+/* Define the appropriate devices for t_open(). */
+#ifdef HAVE_DEV_TCP
+# define       XTI_TCP         "/dev/tcp"
+# define       XTI_UDP         "/dev/udp"
+#endif
+#ifdef HAVE_DEV_XTI_TCP
+# define       XTI_TCP         "/dev/xti/tcp"
+# define       XTI_UDP         "/dev/xti/udp"
+#endif
+#ifdef HAVE_DEV_STREAMS_XTISO_TCP
+# define       XTI_TCP         "/dev/streams/xtiso/tcp+"       /* + for XPG4 */
+# define       XTI_UDP         "/dev/streams/xtiso/udp+"       /* + for XPG4 */
+#endif
+
+       /* 4device to t_open() for t_accept(); set by tcp_listen() */
+/* $$.Id xti_serv_dev$$ */
+extern char    xti_serv_dev[];
+/* end unpxtih2 */
+
+void    err_xti(const char *fmt, ...);
+void    err_xti_ret(const char *fmt, ...);
+
+int             Getmsg(int, struct strbuf *, struct strbuf *, int *);
+void    Putmsg(int, const struct strbuf *, const struct strbuf *, int);
+
+#ifdef HAVE_NETCONFIG_H
+void   *Setnetconfig(void);
+void   *Setnetpath(void);
+#endif
+
+void   *T_alloc(int, int, int);
+int             T_accept(int, int, struct t_call *);
+void    T_bind(int, const struct t_bind *, struct t_bind *);
+void    T_close(int);
+void    T_connect(int, const struct t_call *, struct t_call *);
+void    T_free(void *, int);
+void    T_getprotaddr(int, struct t_bind *, struct t_bind *);
+int             T_getstate(int);
+void    T_listen(int, struct t_call *);
+int             T_look(int);
+int             T_open(const char *, int, struct t_info *);
+void    T_optmgmt(int, const struct t_optmgmt *, struct t_optmgmt *);
+int             T_rcv(int, void *, unsigned int, int *);
+void    T_rcvdis(int, struct t_discon *);
+void    T_rcvrel(int);
+void    T_rcvudata(int, struct t_unitdata *, int *);
+void    T_rcvuderr(int, struct t_uderr *);
+void    T_snd(int, void *, unsigned int, int);
+void    T_sndrel(int);
+void    T_sndudata(int, struct t_unitdata *);
+
+int             xti_accept(int, struct netbuf *, int);
+int             xti_getopt(int, int, int, void *, socklen_t *);
+char   *xti_flags_str(int);
+char   *xti_tlook_str(int);
+char   *xti_ntop(const struct netbuf *);
+char   *xti_ntop_host(const struct netbuf *);
+int             xti_rdwr(int);
+int             xti_setopt(int, int, int, void *, socklen_t);
+
+int             Xti_accept(int, struct netbuf *, int);
+void    Xti_getopt(int, int, int, void *, socklen_t *);
+char   *Xti_flags_str(int);
+char   *Xti_tlook_str(int);
+char   *Xti_ntop(const struct netbuf *);
+char   *Xti_ntop_host(const struct netbuf *);
+void    Xti_rdwr(int);
+void    Xti_setopt(int, int, int, void *, socklen_t);
+
+char   *xti_str_lend(struct t_opthdr *);
+char   *xti_str_uscalard(struct t_opthdr *);
+char   *xti_str_uchard(struct t_opthdr *);
+char   *xti_str_ucharx(struct t_opthdr *);
+char   *xti_str_yn(t_uscalar_t);
+char   *xti_str_syng(t_scalar_t);
+char   *xti_str_uiyn(struct t_opthdr *);
+char   *xti_str_usyn(struct t_opthdr *);
+char   *xti_str_linger(struct t_opthdr *);
+char   *xti_str_kpalive(struct t_opthdr *);
+char   *xti_str_flags(t_scalar_t);
+
+#endif /* __unp_xti_h */
diff --git a/icmpd/Makefile b/icmpd/Makefile
new file mode 100644 (file)
index 0000000..3bf94de
--- /dev/null
@@ -0,0 +1,16 @@
+include ../Make.defines
+
+OBJS = icmpd.o readable_listen.o readable_conn.o readable_v4.o readable_v6.o
+
+PROGS =        icmpd udpcli01
+
+all:   ${PROGS}
+
+icmpd: ${OBJS}
+               ${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS}
+
+udpcli01:      udpcli01.o dgcli01.o
+               ${CC} ${CFLAGS} -o $@ udpcli01.o dgcli01.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/icmpd/dgcli01.c b/icmpd/dgcli01.c
new file mode 100644 (file)
index 0000000..ae801d6
--- /dev/null
@@ -0,0 +1,62 @@
+/* include dgcli011 */
+#include       "unpicmpd.h"
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                             icmpfd, maxfdp1;
+       char                    sendline[MAXLINE], recvline[MAXLINE + 1];
+       fd_set                  rset;
+       ssize_t                 n;
+       struct timeval  tv;
+       struct icmpd_err icmpd_err;
+       struct sockaddr_un sun;
+
+       Sock_bind_wild(sockfd, pservaddr->sa_family);
+
+       icmpfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
+       sun.sun_family = AF_LOCAL;
+       strcpy(sun.sun_path, ICMPD_PATH);
+       Connect(icmpfd, (SA *)&sun, sizeof(sun));
+       Write_fd(icmpfd, "1", 1, sockfd);
+       n = Read(icmpfd, recvline, 1);
+       if (n != 1 || recvline[0] != '1')
+               err_quit("error creating icmp socket, n = %d, char = %c",
+                                n, recvline[0]);
+
+       FD_ZERO(&rset);
+       maxfdp1 = max(sockfd, icmpfd) + 1;
+/* end dgcli011 */
+
+/* include dgcli012 */
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               tv.tv_sec = 5;
+               tv.tv_usec = 0;
+               FD_SET(sockfd, &rset);
+               FD_SET(icmpfd, &rset);
+               if ( (n = Select(maxfdp1, &rset, NULL, NULL, &tv)) == 0) {
+                       fprintf(stderr, "socket timeout\n");
+                       continue;
+               }
+
+               if (FD_ISSET(sockfd, &rset)) {
+                       n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
+                       recvline[n] = 0;        /* null terminate */
+                       Fputs(recvline, stdout);
+               }
+
+               if (FD_ISSET(icmpfd, &rset)) {
+                       if ( (n = Read(icmpfd, &icmpd_err, sizeof(icmpd_err))) == 0)
+                               err_quit("ICMP daemon terminated");
+                       else if (n != sizeof(icmpd_err))
+                               err_quit("n = %d, expected %d", n, sizeof(icmpd_err));
+                       printf("ICMP error: dest = %s, %s, type = %d, code = %d\n",
+                                  Sock_ntop(&icmpd_err.icmpd_dest, icmpd_err.icmpd_len),
+                                  strerror(icmpd_err.icmpd_errno),
+                                  icmpd_err.icmpd_type, icmpd_err.icmpd_code);
+               }
+       }
+}
+/* end dgcli012 */
diff --git a/icmpd/dgcli01.lc b/icmpd/dgcli01.lc
new file mode 100644 (file)
index 0000000..f9d7ebc
--- /dev/null
@@ -0,0 +1,58 @@
+/* include dgcli011 */
+#include    "unpicmpd.h"##  1 ##src/icmpd/dgcli01.c##
+
+void##  2 ##src/icmpd/dgcli01.c##
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)##  3 ##src/icmpd/dgcli01.c##
+{##  4 ##src/icmpd/dgcli01.c##
+    int     icmpfd, maxfdp1;##  5 ##src/icmpd/dgcli01.c##
+    char    sendline[MAXLINE], recvline[MAXLINE + 1];##  6 ##src/icmpd/dgcli01.c##
+    fd_set  rset;##  7 ##src/icmpd/dgcli01.c##
+    ssize_t n;##  8 ##src/icmpd/dgcli01.c##
+    struct timeval tv;##  9 ##src/icmpd/dgcli01.c##
+    struct icmpd_err icmpd_err;## 10 ##src/icmpd/dgcli01.c##
+
+    Sock_bind_wild(sockfd, pservaddr->sa_family);## 11 ##src/icmpd/dgcli01.c##
+
+    icmpfd = Tcp_connect("/unix", ICMPD_PATH);## 12 ##src/icmpd/dgcli01.c##
+    Write_fd(icmpfd, "1", 1, sockfd);## 13 ##src/icmpd/dgcli01.c##
+    n = Read(icmpfd, recvline, 1);## 14 ##src/icmpd/dgcli01.c##
+    if (n != 1 || recvline[0] != '1')## 15 ##src/icmpd/dgcli01.c##
+        err_quit("error creating icmp socket, n = %d, char = %c",## 16 ##src/icmpd/dgcli01.c##
+                 n, recvline[0]);## 17 ##src/icmpd/dgcli01.c##
+
+    FD_ZERO(&rset);## 18 ##src/icmpd/dgcli01.c##
+    maxfdp1 = max(sockfd, icmpfd) + 1;## 19 ##src/icmpd/dgcli01.c##
+/* end dgcli011 */
+
+/* include dgcli012 */
+    while (Fgets(sendline, MAXLINE, fp) != NULL) {## 20 ##src/icmpd/dgcli01.c##
+        Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);## 21 ##src/icmpd/dgcli01.c##
+
+        tv.tv_sec = 5;## 22 ##src/icmpd/dgcli01.c##
+        tv.tv_usec = 0;## 23 ##src/icmpd/dgcli01.c##
+        FD_SET(sockfd, &rset);## 24 ##src/icmpd/dgcli01.c##
+        FD_SET(icmpfd, &rset);## 25 ##src/icmpd/dgcli01.c##
+        if ((n = Select(maxfdp1, &rset, NULL, NULL, &tv)) == 0) {## 26 ##src/icmpd/dgcli01.c##
+            fprintf(stderr, "socket timeout\n");## 27 ##src/icmpd/dgcli01.c##
+            continue;## 28 ##src/icmpd/dgcli01.c##
+        }## 29 ##src/icmpd/dgcli01.c##
+
+        if (FD_ISSET(sockfd, &rset)) {## 30 ##src/icmpd/dgcli01.c##
+            n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);## 31 ##src/icmpd/dgcli01.c##
+            recvline[n] = 0;    /* null terminate */## 32 ##src/icmpd/dgcli01.c##
+            Fputs(recvline, stdout);## 33 ##src/icmpd/dgcli01.c##
+        }## 34 ##src/icmpd/dgcli01.c##
+
+        if (FD_ISSET(icmpfd, &rset)) {## 35 ##src/icmpd/dgcli01.c##
+            if ((n = Read(icmpfd, &icmpd_err, sizeof(icmpd_err))) == 0)## 36 ##src/icmpd/dgcli01.c##
+                err_quit("ICMP daemon terminated");## 37 ##src/icmpd/dgcli01.c##
+            else if (n != sizeof(icmpd_err))## 38 ##src/icmpd/dgcli01.c##
+                err_quit("n = %d, expected %d", n, sizeof(icmpd_err));## 39 ##src/icmpd/dgcli01.c##
+            printf("ICMP error: dest = %s, %s, type = %d, code = %d\n",## 40 ##src/icmpd/dgcli01.c##
+                   Sock_ntop(&icmpd_err.icmpd_dest, icmpd_err.icmpd_len),## 41 ##src/icmpd/dgcli01.c##
+                   strerror(icmpd_err.icmpd_errno),## 42 ##src/icmpd/dgcli01.c##
+                   icmpd_err.icmpd_type, icmpd_err.icmpd_code);## 43 ##src/icmpd/dgcli01.c##
+        }## 44 ##src/icmpd/dgcli01.c##
+    }## 45 ##src/icmpd/dgcli01.c##
+}## 46 ##src/icmpd/dgcli01.c##
+/* end dgcli012 */
diff --git a/icmpd/icmpd.c b/icmpd/icmpd.c
new file mode 100644 (file)
index 0000000..e02d2b0
--- /dev/null
@@ -0,0 +1,67 @@
+/* include icmpd1 */
+#include       "icmpd.h"
+
+int
+main(int argc, char **argv)
+{
+       int             i, sockfd;
+       struct sockaddr_un sun;
+
+       if (argc != 1)
+               err_quit("usage: icmpd");
+
+       maxi = -1;                                      /* index into client[] array */
+       for (i = 0; i < FD_SETSIZE; i++)
+               client[i].connfd = -1;  /* -1 indicates available entry */
+       FD_ZERO(&allset);
+
+       fd4 = Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+       FD_SET(fd4, &allset);
+       maxfd = fd4;
+
+#ifdef IPV6
+       fd6 = Socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+       FD_SET(fd6, &allset);
+       maxfd = max(maxfd, fd6);
+#endif
+
+       listenfd = Socket(AF_UNIX, SOCK_STREAM, 0);
+       sun.sun_family = AF_LOCAL;
+       strcpy(sun.sun_path, ICMPD_PATH);
+       unlink(ICMPD_PATH);
+       Bind(listenfd, (SA *)&sun, sizeof(sun));
+       Listen(listenfd, LISTENQ);
+       FD_SET(listenfd, &allset);
+       maxfd = max(maxfd, listenfd);
+/* end icmpd1 */
+
+/* include icmpd2 */
+       for ( ; ; ) {
+               rset = allset;
+               nready = Select(maxfd+1, &rset, NULL, NULL, NULL);
+
+               if (FD_ISSET(listenfd, &rset))
+                       if (readable_listen() <= 0)
+                               continue;
+
+               if (FD_ISSET(fd4, &rset))
+                       if (readable_v4() <= 0)
+                               continue;
+
+#ifdef IPV6
+               if (FD_ISSET(fd6, &rset))
+                       if (readable_v6() <= 0)
+                               continue;
+#endif
+
+               for (i = 0; i <= maxi; i++) {   /* check all clients for data */
+                       if ( (sockfd = client[i].connfd) < 0)
+                               continue;
+                       if (FD_ISSET(sockfd, &rset))
+                               if (readable_conn(i) <= 0)
+                                       break;                          /* no more readable descriptors */
+               }
+       }
+       exit(0);
+}
+/* end icmpd2 */
diff --git a/icmpd/icmpd.h b/icmpd/icmpd.h
new file mode 100644 (file)
index 0000000..f77e3e0
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "unpicmpd.h"
+
+struct client {
+  int  connfd;                 /* Unix domain stream socket to client */
+  int  family;                 /* AF_INET or AF_INET6 */
+  int  lport;                  /* local port bound to client's UDP socket */
+                                               /* network byte ordered */
+} client[FD_SETSIZE];
+
+                                       /* 4globals */
+int                            fd4, fd6, listenfd, maxi, maxfd, nready;
+fd_set                 rset, allset;
+struct sockaddr_un     cliaddr;
+
+                       /* 4function prototypes */
+int             readable_conn(int);
+int             readable_listen(void);
+int             readable_v4(void);
+int             readable_v6(void);
diff --git a/icmpd/icmpd.lc b/icmpd/icmpd.lc
new file mode 100644 (file)
index 0000000..9f49428
--- /dev/null
@@ -0,0 +1,62 @@
+/* include icmpd1 */
+#include    "icmpd.h"##  1 ##src/icmpd/icmpd.c##
+
+int##  2 ##src/icmpd/icmpd.c##
+main(int argc, char **argv)##  3 ##src/icmpd/icmpd.c##
+{##  4 ##src/icmpd/icmpd.c##
+    int     i, sockfd;##  5 ##src/icmpd/icmpd.c##
+
+    if (argc != 1)##  6 ##src/icmpd/icmpd.c##
+        err_quit("usage: icmpd");##  7 ##src/icmpd/icmpd.c##
+
+    maxi = -1;                  /* index into client[] array */##  8 ##src/icmpd/icmpd.c##
+    for (i = 0; i < FD_SETSIZE; i++)##  9 ##src/icmpd/icmpd.c##
+        client[i].connfd = -1;  /* -1 indicates available entry */## 10 ##src/icmpd/icmpd.c##
+    FD_ZERO(&allset);## 11 ##src/icmpd/icmpd.c##
+
+    fd4 = Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);## 12 ##src/icmpd/icmpd.c##
+    FD_SET(fd4, &allset);## 13 ##src/icmpd/icmpd.c##
+    maxfd = fd4;## 14 ##src/icmpd/icmpd.c##
+
+#ifdef  IPV6## 15 ##src/icmpd/icmpd.c##
+    fd6 = Socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);## 16 ##src/icmpd/icmpd.c##
+    FD_SET(fd6, &allset);## 17 ##src/icmpd/icmpd.c##
+    maxfd = max(maxfd, fd6);## 18 ##src/icmpd/icmpd.c##
+#endif## 19 ##src/icmpd/icmpd.c##
+
+    listenfd = Tcp_listen("/unix", ICMPD_PATH, &addrlen);## 20 ##src/icmpd/icmpd.c##
+    FD_SET(listenfd, &allset);## 21 ##src/icmpd/icmpd.c##
+    maxfd = max(maxfd, listenfd);## 22 ##src/icmpd/icmpd.c##
+    cliaddr = Malloc(addrlen);## 23 ##src/icmpd/icmpd.c##
+/* end icmpd1 */
+
+/* include icmpd2 */
+    for (;;) {## 24 ##src/icmpd/icmpd.c##
+        rset = allset;## 25 ##src/icmpd/icmpd.c##
+        nready = Select(maxfd + 1, &rset, NULL, NULL, NULL);## 26 ##src/icmpd/icmpd.c##
+
+        if (FD_ISSET(listenfd, &rset))## 27 ##src/icmpd/icmpd.c##
+            if (readable_listen() <= 0)## 28 ##src/icmpd/icmpd.c##
+                continue;## 29 ##src/icmpd/icmpd.c##
+
+        if (FD_ISSET(fd4, &rset))## 30 ##src/icmpd/icmpd.c##
+            if (readable_v4() <= 0)## 31 ##src/icmpd/icmpd.c##
+                continue;## 32 ##src/icmpd/icmpd.c##
+
+#ifdef  IPV6## 33 ##src/icmpd/icmpd.c##
+        if (FD_ISSET(fd6, &rset))## 34 ##src/icmpd/icmpd.c##
+            if (readable_v6() <= 0)## 35 ##src/icmpd/icmpd.c##
+                continue;## 36 ##src/icmpd/icmpd.c##
+#endif## 37 ##src/icmpd/icmpd.c##
+
+        for (i = 0; i <= maxi; i++) {   /* check all clients for data */## 38 ##src/icmpd/icmpd.c##
+            if ((sockfd = client[i].connfd) < 0)## 39 ##src/icmpd/icmpd.c##
+                continue;## 40 ##src/icmpd/icmpd.c##
+            if (FD_ISSET(sockfd, &rset))## 41 ##src/icmpd/icmpd.c##
+                if (readable_conn(i) <= 0)## 42 ##src/icmpd/icmpd.c##
+                    break;      /* no more readable descriptors */## 43 ##src/icmpd/icmpd.c##
+        }## 44 ##src/icmpd/icmpd.c##
+    }## 45 ##src/icmpd/icmpd.c##
+    exit(0);## 46 ##src/icmpd/icmpd.c##
+}## 47 ##src/icmpd/icmpd.c##
+/* end icmpd2 */
diff --git a/icmpd/readable_conn.c b/icmpd/readable_conn.c
new file mode 100644 (file)
index 0000000..4d4f973
--- /dev/null
@@ -0,0 +1,56 @@
+/* include readable_conn1 */
+#include       "icmpd.h"
+
+int
+readable_conn(int i)
+{
+       int                             unixfd, recvfd;
+       char                    c;
+       ssize_t                 n;
+       socklen_t               len;
+       struct sockaddr_storage ss;
+
+       unixfd = client[i].connfd;
+       recvfd = -1;
+       if ( (n = Read_fd(unixfd, &c, 1, &recvfd)) == 0) {
+               err_msg("client %d terminated, recvfd = %d", i, recvfd);
+               goto clientdone;        /* client probably terminated */
+       }
+
+               /* 4data from client; should be descriptor */
+       if (recvfd < 0) {
+               err_msg("read_fd did not return descriptor");
+               goto clienterr;
+       }
+/* end readable_conn1 */
+
+/* include readable_conn2 */
+       len = sizeof(ss);
+       if (getsockname(recvfd, (SA *) &ss, &len) < 0) {
+               err_ret("getsockname error");
+               goto clienterr;
+       }
+
+       client[i].family = ss.ss_family;
+       if ( (client[i].lport = sock_get_port((SA *)&ss, len)) == 0) {
+               client[i].lport = sock_bind_wild(recvfd, client[i].family);
+               if (client[i].lport <= 0) {
+                       err_ret("error binding ephemeral port");
+                       goto clienterr;
+               }
+       }
+       Write(unixfd, "1", 1);  /* tell client all OK */
+       Close(recvfd);                  /* all done with client's UDP socket */
+       return(--nready);
+
+clienterr:
+       Write(unixfd, "0", 1);  /* tell client error occurred */
+clientdone:
+       Close(unixfd);
+       if (recvfd >= 0)
+               Close(recvfd);
+       FD_CLR(unixfd, &allset);
+       client[i].connfd = -1;
+       return(--nready);
+}
+/* end readable_conn2 */
diff --git a/icmpd/readable_conn.lc b/icmpd/readable_conn.lc
new file mode 100644 (file)
index 0000000..21be2e7
--- /dev/null
@@ -0,0 +1,64 @@
+/* include readable_conn1 */
+#include    "icmpd.h"##  1 ##src/icmpd/readable_conn.c##
+
+int##  2 ##src/icmpd/readable_conn.c##
+readable_conn(int i)##  3 ##src/icmpd/readable_conn.c##
+{##  4 ##src/icmpd/readable_conn.c##
+    int     unixfd, recvfd;##  5 ##src/icmpd/readable_conn.c##
+    char    c;##  6 ##src/icmpd/readable_conn.c##
+    ssize_t n;##  7 ##src/icmpd/readable_conn.c##
+    socklen_t len;##  8 ##src/icmpd/readable_conn.c##
+    union {##  9 ##src/icmpd/readable_conn.c##
+        char    buf[MAXSOCKADDR];## 10 ##src/icmpd/readable_conn.c##
+        struct sockaddr sock;## 11 ##src/icmpd/readable_conn.c##
+    } un;## 12 ##src/icmpd/readable_conn.c##
+
+    unixfd = client[i].connfd;## 13 ##src/icmpd/readable_conn.c##
+    recvfd = -1;## 14 ##src/icmpd/readable_conn.c##
+    if ((n = Read_fd(unixfd, &c, 1, &recvfd)) == 0) {## 15 ##src/icmpd/readable_conn.c##
+        err_msg("client %d terminated, recvfd = %d", i, recvfd);## 16 ##src/icmpd/readable_conn.c##
+        goto clientdone;        /* client probably terminated */## 17 ##src/icmpd/readable_conn.c##
+    }## 18 ##src/icmpd/readable_conn.c##
+
+    /* 4data from client; should be descriptor */## 19 ##src/icmpd/readable_conn.c##
+    if (recvfd < 0) {## 20 ##src/icmpd/readable_conn.c##
+        err_msg("read_fd did not return descriptor");## 21 ##src/icmpd/readable_conn.c##
+        goto clienterr;## 22 ##src/icmpd/readable_conn.c##
+    }## 23 ##src/icmpd/readable_conn.c##
+/* end readable_conn1 */
+
+/* include readable_conn2 */
+    len = sizeof(un.buf);## 24 ##src/icmpd/readable_conn.c##
+    if (getsockname(recvfd, (SA *) un.buf, &len) < 0) {## 25 ##src/icmpd/readable_conn.c##
+        err_ret("getsockname error");## 26 ##src/icmpd/readable_conn.c##
+        goto clienterr;## 27 ##src/icmpd/readable_conn.c##
+    }## 28 ##src/icmpd/readable_conn.c##
+
+    client[i].family = un.sock.sa_family;## 29 ##src/icmpd/readable_conn.c##
+    if ((client[i].lport = sock_get_port(&un.sock, len)) == 0) {## 30 ##src/icmpd/readable_conn.c##
+        client[i].lport = sock_bind_wild(recvfd, client[i].family);## 31 ##src/icmpd/readable_conn.c##
+        if (client[i].lport <= 0) {## 32 ##src/icmpd/readable_conn.c##
+            err_ret("error binding ephemeral port");## 33 ##src/icmpd/readable_conn.c##
+            goto clienterr;## 34 ##src/icmpd/readable_conn.c##
+        }## 35 ##src/icmpd/readable_conn.c##
+    }## 36 ##src/icmpd/readable_conn.c##
+    Write(unixfd, "1", 1);      /* tell client all OK */## 37 ##src/icmpd/readable_conn.c##
+    FD_SET(unixfd, &allset);## 38 ##src/icmpd/readable_conn.c##
+    if (unixfd > maxfd)## 39 ##src/icmpd/readable_conn.c##
+        maxfd = unixfd;## 40 ##src/icmpd/readable_conn.c##
+    if (i > maxi)## 41 ##src/icmpd/readable_conn.c##
+        maxi = i;## 42 ##src/icmpd/readable_conn.c##
+    Close(recvfd);              /* all done with client's UDP socket */## 43 ##src/icmpd/readable_conn.c##
+    return (--nready);## 44 ##src/icmpd/readable_conn.c##
+
+  clienterr:## 45 ##src/icmpd/readable_conn.c##
+    Write(unixfd, "0", 1);      /* tell client error occurred */## 46 ##src/icmpd/readable_conn.c##
+  clientdone:## 47 ##src/icmpd/readable_conn.c##
+    Close(unixfd);## 48 ##src/icmpd/readable_conn.c##
+    if (recvfd >= 0)## 49 ##src/icmpd/readable_conn.c##
+        Close(recvfd);## 50 ##src/icmpd/readable_conn.c##
+    FD_CLR(unixfd, &allset);## 51 ##src/icmpd/readable_conn.c##
+    client[i].connfd = -1;## 52 ##src/icmpd/readable_conn.c##
+    return (--nready);## 53 ##src/icmpd/readable_conn.c##
+}## 54 ##src/icmpd/readable_conn.c##
+/* end readable_conn2 */
diff --git a/icmpd/readable_listen.c b/icmpd/readable_listen.c
new file mode 100644 (file)
index 0000000..7ec6a52
--- /dev/null
@@ -0,0 +1,31 @@
+#include       "icmpd.h"
+
+int
+readable_listen(void)
+{
+       int                     i, connfd;
+       socklen_t       clilen;
+
+       clilen = sizeof(cliaddr);
+       connfd = Accept(listenfd, (SA *)&cliaddr, &clilen);
+
+               /* 4find first available client[] structure */
+       for (i = 0; i < FD_SETSIZE; i++)
+               if (client[i].connfd < 0) {
+                       client[i].connfd = connfd;      /* save descriptor */
+                       break;
+               }
+       if (i == FD_SETSIZE) {
+               close(connfd);          /* can't handle new client, */
+               return(--nready);       /* rudely close the new connection */
+       }
+       printf("new connection, i = %d, connfd = %d\n", i, connfd);
+
+       FD_SET(connfd, &allset);        /* add new descriptor to set */
+       if (connfd > maxfd)
+               maxfd = connfd;                 /* for select() */
+       if (i > maxi)
+               maxi = i;                               /* max index in client[] array */
+
+       return(--nready);
+}
diff --git a/icmpd/readable_listen.lc b/icmpd/readable_listen.lc
new file mode 100644 (file)
index 0000000..d65eab1
--- /dev/null
@@ -0,0 +1,29 @@
+#include    "icmpd.h"##  1 ##src/icmpd/readable_listen.c##
+
+int##  2 ##src/icmpd/readable_listen.c##
+readable_listen(void)##  3 ##src/icmpd/readable_listen.c##
+{##  4 ##src/icmpd/readable_listen.c##
+    int     i, connfd;##  5 ##src/icmpd/readable_listen.c##
+    socklen_t clilen;##  6 ##src/icmpd/readable_listen.c##
+
+    clilen = addrlen;##  7 ##src/icmpd/readable_listen.c##
+    connfd = Accept(listenfd, cliaddr, &clilen);##  8 ##src/icmpd/readable_listen.c##
+
+    /* 4find first available client[] structure */##  9 ##src/icmpd/readable_listen.c##
+    for (i = 0; i < FD_SETSIZE; i++)## 10 ##src/icmpd/readable_listen.c##
+        if (client[i].connfd < 0) {## 11 ##src/icmpd/readable_listen.c##
+            client[i].connfd = connfd;  /* save descriptor */## 12 ##src/icmpd/readable_listen.c##
+            break;## 13 ##src/icmpd/readable_listen.c##
+        }## 14 ##src/icmpd/readable_listen.c##
+    if (i == FD_SETSIZE)## 15 ##src/icmpd/readable_listen.c##
+        err_quit("too many clients");## 16 ##src/icmpd/readable_listen.c##
+    printf("new connection, i = %d, connfd = %d\n", i, connfd);## 17 ##src/icmpd/readable_listen.c##
+
+    FD_SET(connfd, &allset);    /* add new descriptor to set */## 18 ##src/icmpd/readable_listen.c##
+    if (connfd > maxfd)## 19 ##src/icmpd/readable_listen.c##
+        maxfd = connfd;         /* for select() */## 20 ##src/icmpd/readable_listen.c##
+    if (i > maxi)## 21 ##src/icmpd/readable_listen.c##
+        maxi = i;               /* max index in client[] array */## 22 ##src/icmpd/readable_listen.c##
+
+    return (--nready);## 23 ##src/icmpd/readable_listen.c##
+}## 24 ##src/icmpd/readable_listen.c##
diff --git a/icmpd/readable_v4.c b/icmpd/readable_v4.c
new file mode 100644 (file)
index 0000000..29f068a
--- /dev/null
@@ -0,0 +1,90 @@
+/* include readable_v41 */
+#include       "icmpd.h"
+#include       <netinet/in_systm.h>
+#include       <netinet/ip.h>
+#include       <netinet/ip_icmp.h>
+#include       <netinet/udp.h>
+
+int
+readable_v4(void)
+{
+       int                                     i, hlen1, hlen2, icmplen, sport;
+       char                            buf[MAXLINE];
+       char                            srcstr[INET_ADDRSTRLEN], dststr[INET_ADDRSTRLEN];
+       ssize_t                         n;
+       socklen_t                       len;
+       struct ip                       *ip, *hip;
+       struct icmp                     *icmp;
+       struct udphdr           *udp;
+       struct sockaddr_in      from, dest;
+       struct icmpd_err        icmpd_err;
+
+       len = sizeof(from);
+       n = Recvfrom(fd4, buf, MAXLINE, 0, (SA *) &from, &len);
+
+       printf("%d bytes ICMPv4 from %s:",
+                  n, Sock_ntop_host((SA *) &from, len));
+
+       ip = (struct ip *) buf;         /* start of IP header */
+       hlen1 = ip->ip_hl << 2;         /* length of IP header */
+
+       icmp = (struct icmp *) (buf + hlen1);   /* start of ICMP header */
+       if ( (icmplen = n - hlen1) < 8)
+               err_quit("icmplen (%d) < 8", icmplen);
+
+       printf(" type = %d, code = %d\n", icmp->icmp_type, icmp->icmp_code);
+/* end readable_v41 */
+
+/* include readable_v42 */
+       if (icmp->icmp_type == ICMP_UNREACH ||
+               icmp->icmp_type == ICMP_TIMXCEED ||
+               icmp->icmp_type == ICMP_SOURCEQUENCH) {
+               if (icmplen < 8 + 20 + 8)
+                       err_quit("icmplen (%d) < 8 + 20 + 8", icmplen);
+
+               hip = (struct ip *) (buf + hlen1 + 8);
+               hlen2 = hip->ip_hl << 2;
+               printf("\tsrcip = %s, dstip = %s, proto = %d\n",
+                          Inet_ntop(AF_INET, &hip->ip_src, srcstr, sizeof(srcstr)),
+                          Inet_ntop(AF_INET, &hip->ip_dst, dststr, sizeof(dststr)),
+                          hip->ip_p);
+               if (hip->ip_p == IPPROTO_UDP) {
+                       udp = (struct udphdr *) (buf + hlen1 + 8 + hlen2);
+                       sport = udp->uh_sport;
+
+                               /* 4find client's Unix domain socket, send headers */
+                       for (i = 0; i <= maxi; i++) {
+                               if (client[i].connfd >= 0 &&
+                                       client[i].family == AF_INET &&
+                                       client[i].lport == sport) {
+
+                                       bzero(&dest, sizeof(dest));
+                                       dest.sin_family = AF_INET;
+#ifdef HAVE_SOCKADDR_SA_LEN
+                                       dest.sin_len = sizeof(dest);
+#endif
+                                       memcpy(&dest.sin_addr, &hip->ip_dst,
+                                                  sizeof(struct in_addr));
+                                       dest.sin_port = udp->uh_dport;
+
+                                       icmpd_err.icmpd_type = icmp->icmp_type;
+                                       icmpd_err.icmpd_code = icmp->icmp_code;
+                                       icmpd_err.icmpd_len = sizeof(struct sockaddr_in);
+                                       memcpy(&icmpd_err.icmpd_dest, &dest, sizeof(dest));
+
+                                               /* 4convert type & code to reasonable errno value */
+                                       icmpd_err.icmpd_errno = EHOSTUNREACH;   /* default */
+                                       if (icmp->icmp_type == ICMP_UNREACH) {
+                                               if (icmp->icmp_code == ICMP_UNREACH_PORT)
+                                                       icmpd_err.icmpd_errno = ECONNREFUSED;
+                                               else if (icmp->icmp_code == ICMP_UNREACH_NEEDFRAG)
+                                                       icmpd_err.icmpd_errno = EMSGSIZE;
+                                       }
+                                       Write(client[i].connfd, &icmpd_err, sizeof(icmpd_err));
+                               }
+                       }
+               }
+       }
+       return(--nready);
+}
+/* end readable_v42 */
diff --git a/icmpd/readable_v4.lc b/icmpd/readable_v4.lc
new file mode 100644 (file)
index 0000000..6ae8d5b
--- /dev/null
@@ -0,0 +1,89 @@
+/* include readable_v41 */
+#include    "icmpd.h"##  1 ##src/icmpd/readable_v4.c##
+#include    <netinet/in_systm.h>##  2 ##src/icmpd/readable_v4.c##
+#include    <netinet/ip.h>##  3 ##src/icmpd/readable_v4.c##
+#include    <netinet/ip_icmp.h>##  4 ##src/icmpd/readable_v4.c##
+#include    <netinet/udp.h>##  5 ##src/icmpd/readable_v4.c##
+
+int##  6 ##src/icmpd/readable_v4.c##
+readable_v4(void)##  7 ##src/icmpd/readable_v4.c##
+{##  8 ##src/icmpd/readable_v4.c##
+    int     i, hlen1, hlen2, icmplen, sport;##  9 ##src/icmpd/readable_v4.c##
+    char    buf[MAXLINE];## 10 ##src/icmpd/readable_v4.c##
+    char    srcstr[INET_ADDRSTRLEN], dststr[INET_ADDRSTRLEN];## 11 ##src/icmpd/readable_v4.c##
+    ssize_t n;## 12 ##src/icmpd/readable_v4.c##
+    socklen_t len;## 13 ##src/icmpd/readable_v4.c##
+    struct ip *ip, *hip;## 14 ##src/icmpd/readable_v4.c##
+    struct icmp *icmp;## 15 ##src/icmpd/readable_v4.c##
+    struct udphdr *udp;## 16 ##src/icmpd/readable_v4.c##
+    struct sockaddr_in from, dest;## 17 ##src/icmpd/readable_v4.c##
+    struct icmpd_err icmpd_err;## 18 ##src/icmpd/readable_v4.c##
+
+    len = sizeof(from);## 19 ##src/icmpd/readable_v4.c##
+    n = Recvfrom(fd4, buf, MAXLINE, 0, (SA *) &from, &len);## 20 ##src/icmpd/readable_v4.c##
+
+    printf("%d bytes ICMPv4 from %s:", n, Sock_ntop_host((SA *) &from, len));## 21 ##src/icmpd/readable_v4.c##
+
+    ip = (struct ip *) buf;     /* start of IP header */## 22 ##src/icmpd/readable_v4.c##
+    hlen1 = ip->ip_hl << 2;     /* length of IP header */## 23 ##src/icmpd/readable_v4.c##
+
+    icmp = (struct icmp *) (buf + hlen1);   /* start of ICMP header */## 24 ##src/icmpd/readable_v4.c##
+    if ((icmplen = n - hlen1) < 8)## 25 ##src/icmpd/readable_v4.c##
+        err_quit("icmplen (%d) < 8", icmplen);## 26 ##src/icmpd/readable_v4.c##
+
+    printf(" type = %d, code = %d\n", icmp->icmp_type, icmp->icmp_code);## 27 ##src/icmpd/readable_v4.c##
+/* end readable_v41 */
+
+/* include readable_v42 */
+    if (icmp->icmp_type == ICMP_UNREACH ||## 28 ##src/icmpd/readable_v4.c##
+        icmp->icmp_type == ICMP_TIMXCEED ||## 29 ##src/icmpd/readable_v4.c##
+        icmp->icmp_type == ICMP_SOURCEQUENCH) {## 30 ##src/icmpd/readable_v4.c##
+        if (icmplen < 8 + 20 + 8)## 31 ##src/icmpd/readable_v4.c##
+            err_quit("icmplen (%d) < 8 + 20 + 8", icmplen);## 32 ##src/icmpd/readable_v4.c##
+
+        hip = (struct ip *) (buf + hlen1 + 8);## 33 ##src/icmpd/readable_v4.c##
+        hlen2 = hip->ip_hl << 2;## 34 ##src/icmpd/readable_v4.c##
+        printf("\tsrcip = %s, dstip = %s, proto = %d\n",## 35 ##src/icmpd/readable_v4.c##
+               Inet_ntop(AF_INET, &hip->ip_src, srcstr, sizeof(srcstr)),## 36 ##src/icmpd/readable_v4.c##
+               Inet_ntop(AF_INET, &hip->ip_dst, dststr, sizeof(dststr)),## 37 ##src/icmpd/readable_v4.c##
+               hip->ip_p);## 38 ##src/icmpd/readable_v4.c##
+        if (hip->ip_p == IPPROTO_UDP) {## 39 ##src/icmpd/readable_v4.c##
+            udp = (struct udphdr *) (buf + hlen1 + 8 + hlen2);## 40 ##src/icmpd/readable_v4.c##
+            sport = udp->uh_sport;## 41 ##src/icmpd/readable_v4.c##
+
+            /* 4find client's Unix domain socket, send headers */## 42 ##src/icmpd/readable_v4.c##
+            for (i = 0; i <= maxi; i++) {## 43 ##src/icmpd/readable_v4.c##
+                if (client[i].connfd >= 0 &&## 44 ##src/icmpd/readable_v4.c##
+                    client[i].family == AF_INET &&## 45 ##src/icmpd/readable_v4.c##
+                    client[i].lport == sport) {## 46 ##src/icmpd/readable_v4.c##
+
+                    bzero(&dest, sizeof(dest));## 47 ##src/icmpd/readable_v4.c##
+                    dest.sin_family = AF_INET;## 48 ##src/icmpd/readable_v4.c##
+#ifdef  HAVE_SOCKADDR_SA_LEN## 49 ##src/icmpd/readable_v4.c##
+                    dest.sin_len = sizeof(dest);## 50 ##src/icmpd/readable_v4.c##
+#endif## 51 ##src/icmpd/readable_v4.c##
+                    memcpy(&dest.sin_addr, &hip->ip_dst,## 52 ##src/icmpd/readable_v4.c##
+                           sizeof(struct in_addr));## 53 ##src/icmpd/readable_v4.c##
+                    dest.sin_port = udp->uh_dport;## 54 ##src/icmpd/readable_v4.c##
+
+                    icmpd_err.icmpd_type = icmp->icmp_type;## 55 ##src/icmpd/readable_v4.c##
+                    icmpd_err.icmpd_code = icmp->icmp_code;## 56 ##src/icmpd/readable_v4.c##
+                    icmpd_err.icmpd_len = sizeof(struct sockaddr_in);## 57 ##src/icmpd/readable_v4.c##
+                    memcpy(&icmpd_err.icmpd_dest, &dest, sizeof(dest));## 58 ##src/icmpd/readable_v4.c##
+
+                    /* 4convert type & code to reasonable errno value */## 59 ##src/icmpd/readable_v4.c##
+                    icmpd_err.icmpd_errno = EHOSTUNREACH;   /* default */## 60 ##src/icmpd/readable_v4.c##
+                    if (icmp->icmp_type == ICMP_UNREACH) {## 61 ##src/icmpd/readable_v4.c##
+                        if (icmp->icmp_code == ICMP_UNREACH_PORT)## 62 ##src/icmpd/readable_v4.c##
+                            icmpd_err.icmpd_errno = ECONNREFUSED;## 63 ##src/icmpd/readable_v4.c##
+                        else if (icmp->icmp_code == ICMP_UNREACH_NEEDFRAG)## 64 ##src/icmpd/readable_v4.c##
+                            icmpd_err.icmpd_errno = EMSGSIZE;## 65 ##src/icmpd/readable_v4.c##
+                    }## 66 ##src/icmpd/readable_v4.c##
+                    Write(client[i].connfd, &icmpd_err, sizeof(icmpd_err));## 67 ##src/icmpd/readable_v4.c##
+                }## 68 ##src/icmpd/readable_v4.c##
+            }## 69 ##src/icmpd/readable_v4.c##
+        }## 70 ##src/icmpd/readable_v4.c##
+    }## 71 ##src/icmpd/readable_v4.c##
+    return (--nready);## 72 ##src/icmpd/readable_v4.c##
+}## 73 ##src/icmpd/readable_v4.c##
+/* end readable_v42 */
diff --git a/icmpd/readable_v6.c b/icmpd/readable_v6.c
new file mode 100644 (file)
index 0000000..48f058d
--- /dev/null
@@ -0,0 +1,93 @@
+/* include readable_v61 */
+#include       "icmpd.h"
+#include       <netinet/in_systm.h>
+#include       <netinet/ip.h>
+#include       <netinet/ip_icmp.h>
+#include       <netinet/udp.h>
+
+#ifdef IPV6
+#include       <netinet/ip6.h>
+#include       <netinet/icmp6.h>
+#endif
+
+int
+readable_v6(void)
+{
+#ifdef IPV6
+       int                                     i, hlen2, icmp6len, sport;
+       char                            buf[MAXLINE];
+       char                            srcstr[INET6_ADDRSTRLEN], dststr[INET6_ADDRSTRLEN];
+       ssize_t                         n;
+       socklen_t                       len;
+       struct ip6_hdr          *ip6, *hip6;
+       struct icmp6_hdr        *icmp6;
+       struct udphdr           *udp;
+       struct sockaddr_in6     from, dest;
+       struct icmpd_err        icmpd_err;
+
+       len = sizeof(from);
+       n = Recvfrom(fd6, buf, MAXLINE, 0, (SA *) &from, &len);
+
+       printf("%d bytes ICMPv6 from %s:",
+                  n, Sock_ntop_host((SA *) &from, len));
+
+       icmp6 = (struct icmp6_hdr *) buf;               /* start of ICMPv6 header */
+       if ( (icmp6len = n) < 8)
+               err_quit("icmp6len (%d) < 8", icmp6len);
+
+       printf(" type = %d, code = %d\n", icmp6->icmp6_type, icmp6->icmp6_code);
+/* end readable_v61 */
+
+/* include readable_v62 */
+       if (icmp6->icmp6_type == ICMP6_DST_UNREACH ||
+               icmp6->icmp6_type == ICMP6_PACKET_TOO_BIG ||
+               icmp6->icmp6_type == ICMP6_TIME_EXCEEDED) {
+               if (icmp6len < 8 + 8)
+                       err_quit("icmp6len (%d) < 8 + 8", icmp6len);
+
+               hip6 = (struct ip6_hdr *) (buf + 8);
+               hlen2 = sizeof(struct ip6_hdr);
+               printf("\tsrcip = %s, dstip = %s, next hdr = %d\n",
+                          Inet_ntop(AF_INET6, &hip6->ip6_src, srcstr, sizeof(srcstr)),
+                          Inet_ntop(AF_INET6, &hip6->ip6_dst, dststr, sizeof(dststr)),
+                          hip6->ip6_nxt);
+               if (hip6->ip6_nxt == IPPROTO_UDP) {
+                       udp = (struct udphdr *) (buf + 8 + hlen2);
+                       sport = udp->uh_sport;
+
+                               /* 4find client's Unix domain socket, send headers */
+                       for (i = 0; i <= maxi; i++) {
+                               if (client[i].connfd >= 0 &&
+                                       client[i].family == AF_INET6 &&
+                                       client[i].lport == sport) {
+
+                                       bzero(&dest, sizeof(dest));
+                                       dest.sin6_family = AF_INET6;
+#ifdef HAVE_SOCKADDR_SA_LEN
+                                       dest.sin6_len = sizeof(dest);
+#endif
+                                       memcpy(&dest.sin6_addr, &hip6->ip6_dst,
+                                                  sizeof(struct in6_addr));
+                                       dest.sin6_port = udp->uh_dport;
+
+                                       icmpd_err.icmpd_type = icmp6->icmp6_type;
+                                       icmpd_err.icmpd_code = icmp6->icmp6_code;
+                                       icmpd_err.icmpd_len = sizeof(struct sockaddr_in6);
+                                       memcpy(&icmpd_err.icmpd_dest, &dest, sizeof(dest));
+
+                                               /* 4convert type & code to reasonable errno value */
+                                       icmpd_err.icmpd_errno = EHOSTUNREACH;   /* default */
+                                       if (icmp6->icmp6_type == ICMP6_DST_UNREACH &&
+                                               icmp6->icmp6_code == ICMP6_DST_UNREACH_NOPORT)
+                                               icmpd_err.icmpd_errno = ECONNREFUSED;
+                                       if (icmp6->icmp6_type == ICMP6_PACKET_TOO_BIG)
+                                                       icmpd_err.icmpd_errno = EMSGSIZE;
+                                       Write(client[i].connfd, &icmpd_err, sizeof(icmpd_err));
+                               }
+                       }
+               }
+       }
+       return(--nready);
+#endif
+}
+/* end readable_v62 */
diff --git a/icmpd/readable_v6.lc b/icmpd/readable_v6.lc
new file mode 100644 (file)
index 0000000..0211b50
--- /dev/null
@@ -0,0 +1,98 @@
+/* include readable_v61 */
+#include    "icmpd.h"##  1 ##src/icmpd/readable_v6.c##
+#include    <netinet/in_systm.h>##  2 ##src/icmpd/readable_v6.c##
+#include    <netinet/ip.h>##  3 ##src/icmpd/readable_v6.c##
+#include    <netinet/ip_icmp.h>##  4 ##src/icmpd/readable_v6.c##
+#include    <netinet/udp.h>##  5 ##src/icmpd/readable_v6.c##
+
+#ifdef  IPV6##  6 ##src/icmpd/readable_v6.c##
+#include    <netinet/ip6.h>##  7 ##src/icmpd/readable_v6.c##
+#include    <netinet/icmp6.h>##  8 ##src/icmpd/readable_v6.c##
+#endif##  9 ##src/icmpd/readable_v6.c##
+
+int## 10 ##src/icmpd/readable_v6.c##
+readable_v6(void)## 11 ##src/icmpd/readable_v6.c##
+{## 12 ##src/icmpd/readable_v6.c##
+#ifdef  IPV6## 13 ##src/icmpd/readable_v6.c##
+    int     i, hlen1, hlen2, icmp6len, sport;## 14 ##src/icmpd/readable_v6.c##
+    char    buf[MAXLINE];## 15 ##src/icmpd/readable_v6.c##
+    char    srcstr[INET6_ADDRSTRLEN], dststr[INET6_ADDRSTRLEN];## 16 ##src/icmpd/readable_v6.c##
+    ssize_t n;## 17 ##src/icmpd/readable_v6.c##
+    socklen_t len;## 18 ##src/icmpd/readable_v6.c##
+    struct ip6_hdr *ip6, *hip6;## 19 ##src/icmpd/readable_v6.c##
+    struct icmp6_hdr *icmp6;## 20 ##src/icmpd/readable_v6.c##
+    struct udphdr *udp;## 21 ##src/icmpd/readable_v6.c##
+    struct sockaddr_in6 from, dest;## 22 ##src/icmpd/readable_v6.c##
+    struct icmpd_err icmpd_err;## 23 ##src/icmpd/readable_v6.c##
+
+    len = sizeof(from);## 24 ##src/icmpd/readable_v6.c##
+    n = Recvfrom(fd6, buf, MAXLINE, 0, (SA *) &from, &len);## 25 ##src/icmpd/readable_v6.c##
+
+    printf("%d bytes ICMPv6 from %s:", n, Sock_ntop_host((SA *) &from, len));## 26 ##src/icmpd/readable_v6.c##
+
+    ip6 = (struct ip6_hdr *) buf;   /* start of IPv6 header */## 27 ##src/icmpd/readable_v6.c##
+    hlen1 = sizeof(struct ip6_hdr);## 28 ##src/icmpd/readable_v6.c##
+    if (ip6->ip6_nxt != IPPROTO_ICMPV6)## 29 ##src/icmpd/readable_v6.c##
+        err_quit("next header not IPPROTO_ICMPV6");## 30 ##src/icmpd/readable_v6.c##
+
+    icmp6 = (struct icmp6_hdr *) (buf + hlen1);## 31 ##src/icmpd/readable_v6.c##
+    if ((icmp6len = n - hlen1) < 8)## 32 ##src/icmpd/readable_v6.c##
+        err_quit("icmp6len (%d) < 8", icmp6len);## 33 ##src/icmpd/readable_v6.c##
+
+    printf(" type = %d, code = %d\n", icmp6->icmp6_type, icmp6->icmp6_code);## 34 ##src/icmpd/readable_v6.c##
+/* end readable_v61 */
+
+/* include readable_v62 */
+    if (icmp6->icmp6_type == ICMP6_DST_UNREACH ||## 35 ##src/icmpd/readable_v6.c##
+        icmp6->icmp6_type == ICMP6_PACKET_TOO_BIG ||## 36 ##src/icmpd/readable_v6.c##
+        icmp6->icmp6_type == ICMP6_TIME_EXCEEDED) {## 37 ##src/icmpd/readable_v6.c##
+        if (icmp6len < 8 + 40 + 8)## 38 ##src/icmpd/readable_v6.c##
+            err_quit("icmp6len (%d) < 8 + 40 + 8", icmp6len);## 39 ##src/icmpd/readable_v6.c##
+
+        hip6 = (struct ip6_hdr *) (buf + hlen1 + 8);## 40 ##src/icmpd/readable_v6.c##
+        hlen2 = sizeof(struct ip6_hdr);## 41 ##src/icmpd/readable_v6.c##
+        printf("\tsrcip = %s, dstip = %s, next hdr = %d\n",## 42 ##src/icmpd/readable_v6.c##
+               Inet_ntop(AF_INET6, &hip6->ip6_src, srcstr, sizeof(srcstr)),## 43 ##src/icmpd/readable_v6.c##
+               Inet_ntop(AF_INET6, &hip6->ip6_dst, dststr, sizeof(dststr)),## 44 ##src/icmpd/readable_v6.c##
+               hip6->ip6_nxt);## 45 ##src/icmpd/readable_v6.c##
+        if (hip6->ip6_nxt == IPPROTO_UDP) {## 46 ##src/icmpd/readable_v6.c##
+            udp = (struct udphdr *) (buf + hlen1 + 8 + hlen2);## 47 ##src/icmpd/readable_v6.c##
+            sport = udp->uh_sport;## 48 ##src/icmpd/readable_v6.c##
+
+            /* 4find client's Unix domain socket, send headers */## 49 ##src/icmpd/readable_v6.c##
+            for (i = 0; i <= maxi; i++) {## 50 ##src/icmpd/readable_v6.c##
+                if (client[i].connfd >= 0 &&## 51 ##src/icmpd/readable_v6.c##
+                    client[i].family == AF_INET6 &&## 52 ##src/icmpd/readable_v6.c##
+                    client[i].lport == sport) {## 53 ##src/icmpd/readable_v6.c##
+
+                    bzero(&dest, sizeof(dest));## 54 ##src/icmpd/readable_v6.c##
+                    dest.sin6_family = AF_INET6;## 55 ##src/icmpd/readable_v6.c##
+#ifdef  HAVE_SOCKADDR_SA_LEN## 56 ##src/icmpd/readable_v6.c##
+                    dest.sin6_len = sizeof(dest);## 57 ##src/icmpd/readable_v6.c##
+#endif## 58 ##src/icmpd/readable_v6.c##
+                    memcpy(&dest.sin6_addr, &hip6->ip6_dst,## 59 ##src/icmpd/readable_v6.c##
+                           sizeof(struct in6_addr));## 60 ##src/icmpd/readable_v6.c##
+                    dest.sin6_port = udp->uh_dport;## 61 ##src/icmpd/readable_v6.c##
+
+                    icmpd_err.icmpd_type = icmp6->icmp6_type;## 62 ##src/icmpd/readable_v6.c##
+                    icmpd_err.icmpd_code = icmp6->icmp6_code;## 63 ##src/icmpd/readable_v6.c##
+                    icmpd_err.icmpd_len = sizeof(struct sockaddr_in6);## 64 ##src/icmpd/readable_v6.c##
+                    memcpy(&icmpd_err.icmpd_dest, &dest, sizeof(dest));## 65 ##src/icmpd/readable_v6.c##
+
+                    /* 4convert type & code to reasonable errno value */## 66 ##src/icmpd/readable_v6.c##
+                    icmpd_err.icmpd_errno = EHOSTUNREACH;   /* default */## 67 ##src/icmpd/readable_v6.c##
+                    if (icmp6->icmp6_type == ICMP6_DST_UNREACH) {## 68 ##src/icmpd/readable_v6.c##
+                        if (icmp6->icmp6_code == ICMP_UNREACH_PORT)## 69 ##src/icmpd/readable_v6.c##
+                            icmpd_err.icmpd_errno = ECONNREFUSED;## 70 ##src/icmpd/readable_v6.c##
+                        else if (icmp6->icmp6_code == ICMP_UNREACH_NEEDFRAG)## 71 ##src/icmpd/readable_v6.c##
+                            icmpd_err.icmpd_errno = EMSGSIZE;## 72 ##src/icmpd/readable_v6.c##
+                    }## 73 ##src/icmpd/readable_v6.c##
+                    Write(client[i].connfd, &icmpd_err, sizeof(icmpd_err));## 74 ##src/icmpd/readable_v6.c##
+                }## 75 ##src/icmpd/readable_v6.c##
+            }## 76 ##src/icmpd/readable_v6.c##
+        }## 77 ##src/icmpd/readable_v6.c##
+    }## 78 ##src/icmpd/readable_v6.c##
+    return (--nready);## 79 ##src/icmpd/readable_v6.c##
+#endif## 80 ##src/icmpd/readable_v6.c##
+}## 81 ##src/icmpd/readable_v6.c##
+/* end readable_v62 */
diff --git a/icmpd/script.1 b/icmpd/script.1
new file mode 100644 (file)
index 0000000..7e6cd69
--- /dev/null
@@ -0,0 +1,14 @@
+kalae % ./udpcli01 198.82.204.99 echo
+hello, world
+ICMP error: type = 11, code = 0
+testing
+ICMP error: type = 11, code = 0
+
+kalae % ./udpcli01 gemini.tuc.noao.edu echo
+hi there
+ICMP error: type = 3, code = 3
+hello
+socket timeout
+testing
+ICMP error: type = 3, code = 3
+
diff --git a/icmpd/script.2 b/icmpd/script.2
new file mode 100644 (file)
index 0000000..3b0542e
--- /dev/null
@@ -0,0 +1,12 @@
+kalae % ./udpcli01 gemini.tuc.noao.edu echo
+hi there
+ICMPv4 error: dest = 140.252.8.54.1792, type = 3, code = 3
+
+
+kalae % ./udpcli01 198.82.204.99 echo
+hello, world
+ICMPv4 error: dest = 198.82.204.99.1792, type = 11, code = 0
+testing
+ICMPv4 error: dest = 198.82.204.99.1792, type = 11, code = 0
+
+
diff --git a/icmpd/script.3 b/icmpd/script.3
new file mode 100644 (file)
index 0000000..81ec8ee
--- /dev/null
@@ -0,0 +1,16 @@
+kohala % ./udpcli01 gemini.tuc.noao.edu  echo
+hello, world
+ICMP error: dest = 140.252.1.11.7, type = 3, code = 3
+kohala % 
+kohala % ./udpcli 198.82.204.99 echo
+ksh: ./udpcli:  not found
+kohala % ./udpcli01 198.82.204.99 echo
+hello, world
+ICMP error: dest = 198.82.204.99.7, type = 3, code = 3
+kohala % ./udpcli01 192.3.4.5.82.204.99 echo
+udp_client error for 192.3.4.5.82.204.99, echo: host nor service provided, or not known
+kohala % ./udpcli01 192.3.4.5 echo          
+hello
+ICMP error: dest = 192.3.4.5.7, type = 3, code = 1
+
+
diff --git a/icmpd/script.4 b/icmpd/script.4
new file mode 100644 (file)
index 0000000..cee9ba7
--- /dev/null
@@ -0,0 +1,12 @@
+kohala % ./udpcli01 192.3.4.5 echo
+hi there
+socket timeout
+and hello
+socket timeout
+kohala % ./udpcli01  gemini.tuc.noao.edu echo
+hello, world
+ICMP error: dest = 140.252.4.54.7, Connection refused, type = 3, code = 3
+kohala % ./udpcli01 192.3.4.5 echo           
+hello
+ICMP error: dest = 192.3.4.5.7, No route to host, type = 3, code = 1
+
diff --git a/icmpd/udpcli01.c b/icmpd/udpcli01.c
new file mode 100644 (file)
index 0000000..381d19c
--- /dev/null
@@ -0,0 +1,18 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       socklen_t                       salen;
+       struct sockaddr         *sa;
+
+       if (argc != 3)
+               err_quit("usage: udpcli01 <hostname> <service>");
+
+       sockfd = Udp_client(argv[1], argv[2], &sa, &salen);
+
+       dg_cli(stdin, sockfd, sa, salen);
+
+       exit(0);
+}
diff --git a/icmpd/unpicmpd.h b/icmpd/unpicmpd.h
new file mode 100644 (file)
index 0000000..6fe1469
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef        __unpicmp_h
+#define        __unpicmp_h
+
+#include       "unp.h"
+
+#define        ICMPD_PATH              "/tmp/icmpd"    /* server's well-known pathname */
+
+struct icmpd_err {
+  int                          icmpd_errno;/* EHOSTUNREACH, EMSGSIZE, ECONNREFUSED */
+  char                         icmpd_type;     /* actual ICMPv[46] type */
+  char                         icmpd_code;     /* actual ICMPv[46] code */
+  socklen_t                    icmpd_len;      /* length of sockaddr{} that follows */
+  struct sockaddr_storage      icmpd_dest;     /* sockaddr_storage handles any size */
+};
+
+#endif /* __unpicmp_h */
diff --git a/inetd/Makefile b/inetd/Makefile
new file mode 100644 (file)
index 0000000..4c5cf8d
--- /dev/null
@@ -0,0 +1,14 @@
+include ../Make.defines
+
+PROGS =        daytimetcpsrv2 daytimetcpsrv3
+
+all:   ${PROGS}
+
+daytimetcpsrv2:        daytimetcpsrv2.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpsrv2.o ${LIBS}
+
+daytimetcpsrv3:        daytimetcpsrv3.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpsrv3.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/inetd/daytimetcpsrv2.c b/inetd/daytimetcpsrv2.c
new file mode 100644 (file)
index 0000000..dee7617
--- /dev/null
@@ -0,0 +1,36 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       int listenfd, connfd;
+       socklen_t addrlen, len;
+       struct sockaddr *cliaddr;
+       char buff[MAXLINE];
+       time_t ticks;
+
+       if (argc < 2 || argc > 3)
+               err_quit("usage: daytimetcpsrv2 [ <host> ] <service or port>");
+
+       daemon_init(argv[0], 0);
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+
+       cliaddr = Malloc(addrlen);
+
+       for ( ; ; ) {
+               len = addrlen;
+               connfd = Accept(listenfd, cliaddr, &len);
+               err_msg("connection from %s", Sock_ntop(cliaddr, len));
+
+               ticks = time(NULL);
+               snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+               Write(connfd, buff, strlen(buff));
+
+               Close(connfd);
+       }
+}
diff --git a/inetd/daytimetcpsrv3.c b/inetd/daytimetcpsrv3.c
new file mode 100644 (file)
index 0000000..348078f
--- /dev/null
@@ -0,0 +1,25 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       socklen_t               len;
+       struct sockaddr *cliaddr;
+       char                    buff[MAXLINE];
+       time_t                  ticks;
+
+       daemon_inetd(argv[0], 0);
+
+       cliaddr = Malloc(sizeof(struct sockaddr_storage));
+       len = sizeof(struct sockaddr_storage);
+       Getpeername(0, cliaddr, &len);
+       err_msg("connection from %s", Sock_ntop(cliaddr, len));
+
+    ticks = time(NULL);
+    snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+    Write(0, buff, strlen(buff));
+
+       Close(0);       /* close TCP connection */
+       exit(0);
+}
diff --git a/inetd/daytimetcpsrv3.lc b/inetd/daytimetcpsrv3.lc
new file mode 100644 (file)
index 0000000..58936b7
--- /dev/null
@@ -0,0 +1,25 @@
+#include    "unp.h"##  1 ##src/inetd/daytimetcpsrv3.c##
+#include    <time.h>##  2 ##src/inetd/daytimetcpsrv3.c##
+
+int##  3 ##src/inetd/daytimetcpsrv3.c##
+main(int argc, char **argv)##  4 ##src/inetd/daytimetcpsrv3.c##
+{##  5 ##src/inetd/daytimetcpsrv3.c##
+    socklen_t len;##  6 ##src/inetd/daytimetcpsrv3.c##
+    struct sockaddr *cliaddr;##  7 ##src/inetd/daytimetcpsrv3.c##
+    char    buff[MAXLINE];##  8 ##src/inetd/daytimetcpsrv3.c##
+    time_t  ticks;##  9 ##src/inetd/daytimetcpsrv3.c##
+
+    daemon_inetd(argv[0], 0);## 10 ##src/inetd/daytimetcpsrv3.c##
+
+    cliaddr = Malloc(MAXSOCKADDR);## 11 ##src/inetd/daytimetcpsrv3.c##
+    len = MAXSOCKADDR;## 12 ##src/inetd/daytimetcpsrv3.c##
+    Getpeername(0, cliaddr, &len);## 13 ##src/inetd/daytimetcpsrv3.c##
+    err_msg("connection from %s", Sock_ntop(cliaddr, len));## 14 ##src/inetd/daytimetcpsrv3.c##
+
+    ticks = time(NULL);## 15 ##src/inetd/daytimetcpsrv3.c##
+    snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));## 16 ##src/inetd/daytimetcpsrv3.c##
+    Write(0, buff, strlen(buff));## 17 ##src/inetd/daytimetcpsrv3.c##
+
+    Close(0);                   /* close TCP connection */## 18 ##src/inetd/daytimetcpsrv3.c##
+    exit(0);## 19 ##src/inetd/daytimetcpsrv3.c##
+}## 20 ##src/inetd/daytimetcpsrv3.c##
diff --git a/install-sh b/install-sh
new file mode 100755 (executable)
index 0000000..ebc6691
--- /dev/null
@@ -0,0 +1,250 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/intro/Makefile b/intro/Makefile
new file mode 100644 (file)
index 0000000..2d16d4f
--- /dev/null
@@ -0,0 +1,44 @@
+include ../Make.defines
+
+PROGS =        daytimetcpcli daytimetcpcli1 daytimetcpcli2 daytimetcpcli3 \
+               daytimetcpsrv daytimetcpsrv1 daytimetcpsrv2 daytimetcpsrv3 \
+               daytimetcpcliv6 daytimetcpsrvv6 \
+               byteorder
+
+all:   ${PROGS}
+
+daytimetcpcli: daytimetcpcli.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpcli.o ${LIBS}
+
+daytimetcpcli1:        daytimetcpcli1.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpcli1.o ${LIBS}
+
+daytimetcpcli2:        daytimetcpcli2.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpcli2.o ${LIBS}
+
+daytimetcpcli3:        daytimetcpcli3.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpcli3.o ${LIBS}
+
+daytimetcpsrv: daytimetcpsrv.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpsrv.o ${LIBS}
+
+daytimetcpsrv1:        daytimetcpsrv1.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpsrv1.o ${LIBS}
+
+daytimetcpsrv2:        daytimetcpsrv2.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpsrv2.o ${LIBS}
+
+daytimetcpsrv3:        daytimetcpsrv3.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpsrv3.o ${LIBS}
+
+daytimetcpcliv6:       daytimetcpcliv6.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpcliv6.o ${LIBS}
+
+daytimetcpsrvv6:       daytimetcpsrvv6.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpsrvv6.o ${LIBS}
+
+byteorder:     byteorder.o
+               ${CC} ${CFLAGS} -o $@ byteorder.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/intro/byteorder.c b/intro/byteorder.c
new file mode 100644 (file)
index 0000000..beb40fd
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       union {
+         short  s;
+      char   c[sizeof(short)];
+    } un;
+
+       un.s = 0x0102;
+       printf("%s: ", CPU_VENDOR_OS);
+       if (sizeof(short) == 2) {
+               if (un.c[0] == 1 && un.c[1] == 2)
+                       printf("big-endian\n");
+               else if (un.c[0] == 2 && un.c[1] == 1)
+                       printf("little-endian\n");
+               else
+                       printf("unknown\n");
+       } else
+               printf("sizeof(short) = %d\n", sizeof(short));
+
+       exit(0);
+}
diff --git a/intro/daytimetcpcli.c b/intro/daytimetcpcli.c
new file mode 100644 (file)
index 0000000..cc34e3a
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, n;
+       char                            recvline[MAXLINE + 1];
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: a.out <IPaddress>");
+
+       if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+               err_sys("socket error");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port   = htons(13);        /* daytime server */
+       if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
+               err_quit("inet_pton error for %s", argv[1]);
+
+       if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
+               err_sys("connect error");
+
+       while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
+               recvline[n] = 0;        /* null terminate */
+               if (fputs(recvline, stdout) == EOF)
+                       err_sys("fputs error");
+       }
+       if (n < 0)
+               err_sys("read error");
+
+       exit(0);
+}
diff --git a/intro/daytimetcpcli1.c b/intro/daytimetcpcli1.c
new file mode 100644 (file)
index 0000000..fc10beb
--- /dev/null
@@ -0,0 +1,36 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, n, counter = 0;
+       char                            recvline[MAXLINE + 1];
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: a.out <IPaddress>");
+
+       if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+               err_sys("socket error");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port   = htons(13);        /* daytime server */
+       if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
+               err_quit("inet_pton error for %s", argv[1]);
+
+       if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
+               err_sys("connect error");
+
+       while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
+               counter++;
+               recvline[n] = 0;        /* null terminate */
+               if (fputs(recvline, stdout) == EOF)
+                       err_sys("fputs error");
+       }
+       if (n < 0)
+               err_sys("read error");
+
+       printf("counter = %d\n", counter);
+       exit(0);
+}
diff --git a/intro/daytimetcpcli2.c b/intro/daytimetcpcli2.c
new file mode 100644 (file)
index 0000000..99e030a
--- /dev/null
@@ -0,0 +1,36 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, n, counter = 0;
+       char                            recvline[MAXLINE + 1];
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: a.out <IPaddress>");
+
+       if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+               err_sys("socket error");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port   = htons(9999);      /* daytime server */
+       if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
+               err_quit("inet_pton error for %s", argv[1]);
+
+       if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
+               err_sys("connect error");
+
+       while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
+               counter++;
+               recvline[n] = 0;        /* null terminate */
+               if (fputs(recvline, stdout) == EOF)
+                       err_sys("fputs error");
+       }
+       if (n < 0)
+               err_sys("read error");
+
+       printf("counter = %d\n", counter);
+       exit(0);
+}
diff --git a/intro/daytimetcpcli3.c b/intro/daytimetcpcli3.c
new file mode 100644 (file)
index 0000000..bc8444a
--- /dev/null
@@ -0,0 +1,40 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, n;
+       socklen_t                       len;
+       char                            recvline[MAXLINE + 1];
+       struct sockaddr_in      servaddr, cliaddr;
+
+       if (argc != 2)
+               err_quit("usage: a.out <IPaddress>");
+
+       if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+               err_sys("socket error");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port   = htons(13);        /* daytime server */
+       if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
+               err_quit("inet_pton error for %s", argv[1]);
+
+       if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
+               err_sys("connect error");
+
+       len = sizeof(cliaddr);
+       Getsockname(sockfd, (SA *) &cliaddr, &len);
+       printf("local addr: %s\n",
+                  Sock_ntop((SA *) &cliaddr, sizeof(cliaddr)));
+
+       while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
+               recvline[n] = 0;        /* null terminate */
+               if (fputs(recvline, stdout) == EOF)
+                       err_sys("fputs error");
+       }
+       if (n < 0)
+               err_sys("read error");
+
+       exit(0);
+}
diff --git a/intro/daytimetcpcliv6.c b/intro/daytimetcpcliv6.c
new file mode 100644 (file)
index 0000000..986198c
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, n;
+       struct sockaddr_in6     servaddr;
+       char                            recvline[MAXLINE + 1];
+
+       if (argc != 2)
+               err_quit("usage: a.out <IPaddress>");
+
+       if ( (sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0)
+               err_sys("socket error");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin6_family = AF_INET6;
+       servaddr.sin6_port   = htons(13);       /* daytime server */
+       if (inet_pton(AF_INET6, argv[1], &servaddr.sin6_addr) <= 0)
+               err_quit("inet_pton error for %s", argv[1]);
+
+       if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
+               err_sys("connect error");
+
+       while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
+               recvline[n] = 0;        /* null terminate */
+               if (fputs(recvline, stdout) == EOF)
+                       err_sys("fputs error");
+       }
+       if (n < 0)
+               err_sys("read error");
+
+       exit(0);
+}
diff --git a/intro/daytimetcpsrv.c b/intro/daytimetcpsrv.c
new file mode 100644 (file)
index 0000000..bd225f4
--- /dev/null
@@ -0,0 +1,32 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       struct sockaddr_in      servaddr;
+       char                            buff[MAXLINE];
+       time_t                          ticks;
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(13);   /* daytime server */
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       for ( ; ; ) {
+               connfd = Accept(listenfd, (SA *) NULL, NULL);
+
+        ticks = time(NULL);
+        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+        Write(connfd, buff, strlen(buff));
+
+               Close(connfd);
+       }
+}
diff --git a/intro/daytimetcpsrv.lc b/intro/daytimetcpsrv.lc
new file mode 100644 (file)
index 0000000..4d87102
--- /dev/null
@@ -0,0 +1,32 @@
+#include    "unp.h"##  1 ##src/intro/daytimetcpsrv.c##
+#include    <time.h>##  2 ##src/intro/daytimetcpsrv.c##
+
+int##  3 ##src/intro/daytimetcpsrv.c##
+main(int argc, char **argv)##  4 ##src/intro/daytimetcpsrv.c##
+{##  5 ##src/intro/daytimetcpsrv.c##
+    int     listenfd, connfd;##  6 ##src/intro/daytimetcpsrv.c##
+    struct sockaddr_in servaddr;##  7 ##src/intro/daytimetcpsrv.c##
+    char    buff[MAXLINE];##  8 ##src/intro/daytimetcpsrv.c##
+    time_t  ticks;##  9 ##src/intro/daytimetcpsrv.c##
+
+    listenfd = Socket(AF_INET, SOCK_STREAM, 0);## 10 ##src/intro/daytimetcpsrv.c##
+
+    bzero(&servaddr, sizeof(servaddr));## 11 ##src/intro/daytimetcpsrv.c##
+    servaddr.sin_family = AF_INET;## 12 ##src/intro/daytimetcpsrv.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 13 ##src/intro/daytimetcpsrv.c##
+    servaddr.sin_port = htons(13);  /* daytime server */## 14 ##src/intro/daytimetcpsrv.c##
+
+    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 15 ##src/intro/daytimetcpsrv.c##
+
+    Listen(listenfd, LISTENQ);## 16 ##src/intro/daytimetcpsrv.c##
+
+    for (;;) {## 17 ##src/intro/daytimetcpsrv.c##
+        connfd = Accept(listenfd, (SA *) NULL, NULL);## 18 ##src/intro/daytimetcpsrv.c##
+
+        ticks = time(NULL);## 19 ##src/intro/daytimetcpsrv.c##
+        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));## 20 ##src/intro/daytimetcpsrv.c##
+        Write(connfd, buff, strlen(buff));## 21 ##src/intro/daytimetcpsrv.c##
+
+        Close(connfd);## 22 ##src/intro/daytimetcpsrv.c##
+    }## 23 ##src/intro/daytimetcpsrv.c##
+}## 24 ##src/intro/daytimetcpsrv.c##
diff --git a/intro/daytimetcpsrv1.c b/intro/daytimetcpsrv1.c
new file mode 100644 (file)
index 0000000..f13fd30
--- /dev/null
@@ -0,0 +1,37 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       socklen_t                       len;
+       struct sockaddr_in      servaddr, cliaddr;
+       char                            buff[MAXLINE];
+       time_t                          ticks;
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(13);   /* daytime server */
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       for ( ; ; ) {
+               len = sizeof(cliaddr);
+               connfd = Accept(listenfd, (SA *) &cliaddr, &len);
+               printf("connection from %s, port %d\n",
+                          Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
+                          ntohs(cliaddr.sin_port));
+
+        ticks = time(NULL);
+        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+        Write(connfd, buff, strlen(buff));
+
+               Close(connfd);
+       }
+}
diff --git a/intro/daytimetcpsrv2.c b/intro/daytimetcpsrv2.c
new file mode 100644 (file)
index 0000000..9c5cd14
--- /dev/null
@@ -0,0 +1,33 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd, i;
+       struct sockaddr_in      servaddr;
+       char                            buff[MAXLINE];
+       time_t                          ticks;
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(9999);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       for ( ; ; ) {
+               connfd = Accept(listenfd, (SA *) NULL, NULL);
+
+        ticks = time(NULL);
+        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+               for (i = 0; i < strlen(buff); i++)
+               Write(connfd, &buff[i], 1);
+
+               Close(connfd);
+       }
+}
diff --git a/intro/daytimetcpsrv3.c b/intro/daytimetcpsrv3.c
new file mode 100644 (file)
index 0000000..c958bca
--- /dev/null
@@ -0,0 +1,37 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       socklen_t                       len;
+       struct sockaddr_in      servaddr, cliaddr;
+       char                            buff[MAXLINE];
+       time_t                          ticks;
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(9999); /* daytime server */
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       for ( ; ; ) {
+               len = sizeof(cliaddr);
+               connfd = Accept(listenfd, (SA *) &cliaddr, &len);
+               printf("connection from %s, port %d\n",
+                          Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
+                          ntohs(cliaddr.sin_port));
+
+        ticks = time(NULL);
+        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+        Write(connfd, buff, strlen(buff));
+
+               Close(connfd);
+       }
+}
diff --git a/intro/daytimetcpsrvv6.c b/intro/daytimetcpsrvv6.c
new file mode 100644 (file)
index 0000000..c11f384
--- /dev/null
@@ -0,0 +1,36 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       socklen_t                       len;
+       char                            buff[MAXLINE];
+       time_t                          ticks;
+       struct sockaddr_in6     servaddr, cliaddr;
+
+       listenfd = Socket(AF_INET6, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin6_family = AF_INET6;
+       servaddr.sin6_addr   = in6addr_any;
+       servaddr.sin6_port   = htons(13);       /* daytime server */
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       for ( ; ; ) {
+               len = sizeof(cliaddr);
+               connfd = Accept(listenfd, (SA *) &cliaddr, &len);
+               printf("connection from %s\n",
+                          Sock_ntop((SA *) &cliaddr, len));
+
+        ticks = time(NULL);
+        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+        Write(connfd, buff, strlen(buff));
+
+               Close(connfd);
+       }
+}
diff --git a/intro/truss.solaris.2.6 b/intro/truss.solaris.2.6
new file mode 100644 (file)
index 0000000..65bea8b
--- /dev/null
@@ -0,0 +1,8 @@
+so_socket(2, 2, 0, "", 1)                       = 3
+connect(3, 0xEFFFE8C8, 16)                      = 0
+read(3, " F r i   A p r     4   1".., 4096)     = 26
+ioctl(1, TCGETA, 0xEFFFE69C)                    = 0
+write(1, " F r i   A p r     4   1".., 26)      = 26
+read(3, 0xEFFFE8D8, 4096)                       = 0
+llseek(0, 0, SEEK_CUR)                          = 179866
+_exit(0)
diff --git a/intro/truss.unixware.2.1 b/intro/truss.unixware.2.1
new file mode 100644 (file)
index 0000000..c64430b
--- /dev/null
@@ -0,0 +1,102 @@
+execve("./daytimetcpcli", 0x08047BA8, 0x08047BB4)  argc = 2
+open("/usr/lib/libsocket.so.2", O_RDONLY, 0)   = 3
+fxstat(2, 3, 0x0804794C)                       = 0
+mmap(0x00000000, 4096, PROT_READ, MAP_SHARED, 3, 0) = 0xBFF9E000
+mmap(0x00000000, 98280, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xBFF85000
+mmap(0xBFF9A000, 6888, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 81920) = 0xBFF9A000
+open("/dev/zero", O_RDONLY, 027777756064)      = 4
+mmap(0xBFF9C000, 4072, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 4, 0) = 0xBFF9C000
+close(3)                                       = 0
+munmap(0xBFF9E000, 4096)                       = 0
+open("/usr/lib/libresolv.so.1", O_RDONLY, 0)   = 3
+fxstat(2, 3, 0x0804794C)                       = 0
+mmap(0x00000000, 4096, PROT_READ, MAP_SHARED, 3, 0) = 0xBFF9E000
+mmap(0x00000000, 31060, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xBFF7C000
+mmap(0xBFF82000, 3604, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 20480) = 0xBFF82000
+mmap(0xBFF83000, 2388, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 4, 0) = 0xBFF83000
+close(3)                                       = 0
+munmap(0xBFF9E000, 4096)                       = 0
+open("/usr/lib/libnsl.so.1", O_RDONLY, 0)      = 3
+fxstat(2, 3, 0x0804794C)                       = 0
+mmap(0x00000000, 4096, PROT_READ, MAP_SHARED, 3, 0) = 0xBFF9E000
+mmap(0x00000000, 248004, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xBFF3E000
+mmap(0xBFF77000, 6456, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 229376) = 0xBFF77000
+mmap(0xBFF79000, 6340, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 4, 0) = 0xBFF79000
+close(3)                                       = 0
+munmap(0xBFF9E000, 4096)                       = 0
+mmap(0x00000000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE, 4, 0) = 0xBFF9E000
+open("/usr/lib/libnsl.so.1", O_RDONLY, 0)      = 3
+fxstat(2, 3, 0x0804794C)                       = 0
+close(3)                                       = 0
+open("/usr/lib/libsocket.so.2", O_RDONLY, 0)   = 3
+fxstat(2, 3, 0x0804794C)                       = 0
+close(3)                                       = 0
+open("/usr/lib/libnsl.so.1", O_RDONLY, 0)      = 3
+fxstat(2, 3, 0x0804794C)                       = 0
+close(3)                                       = 0
+close(4)                                       = 0
+brk(0x0804B52C)                                        = 0
+open("/etc/netconfig", O_RDONLY, 0666)         = 3
+ioctl(3, TCGETA, 0x080465E6)                   Err#25 ENOTTY
+ioctl(3, I_GETTP, 0x00000000)                  Err#25 ENOTTY
+fxstat(2, 3, 0x08046614)                       = 0
+brk(0x0804E52C)                                        = 0
+read(3, " t c p\t t p i _ c o t s".., 8192)    = 806
+read(3, 0x0804A6B8, 8192)                      = 0
+lseek(3, 0, 0)                                 = 0
+read(3, " t c p\t t p i _ c o t s".., 8192)    = 806
+brk(0x0804F52C)                                        = 0
+brk(0x0805052C)                                        = 0
+read(3, 0x0804A6B8, 8192)                      = 0
+close(3)                                       = 0
+open("/dev/tcp", O_RDWR, 027776333624)         = 3
+ioctl(3, I_FIND, "sockmod")                    = 0
+ioctl(3, I_PUSH, "sockmod")                    = 0
+ioctl(3, I_SETCLTIME, 0x08046B50)              = 0
+ioctl(3, I_SWROPT, 0x00000002)                 = 0
+sigfillset(0xBFFFEBE4)                         = 0
+sigprocmask(SIG_BLOCK, 0x08046AD8, 0x08046AE8) = 0
+ioctl(3, I_STR, 0x08046AA0)                    = 0
+       cmd=(('I'<<8)|101) timout=-1 len=28 dp=0x08046AF8
+  \0 @\0\010\0\0\0 h01\0\080\0\0\002\0\0\0\0\0\0\0\0\0\0\0
+sigprocmask(SIG_SETMASK, 0x08046AE8, 0x00000000) = 0
+ioctl(3, I_GETSIG, 0x08046B18)                 Err#22 EINVAL
+sigprocmask(SIG_BLOCK, 0x08046B20, 0x08046B30) = 0
+ioctl(3, I_STR, 0x08046AE0)                    = 0
+       cmd=TI_OPTMGMT timout=-1 len=32 dp=0x0804ABA8
+  16\0\0\010\0\0\010\0\0\004\0\0\0FFFF\0\00110\0\004\0\0\0\0 `\0\0
+sigprocmask(SIG_SETMASK, 0x08046B30, 0x00000000) = 0
+sigprocmask(SIG_BLOCK, 0x08046B0C, 0x08046B1C) = 0
+ioctl(3, I_STR, 0x08046ACC)                    = 0
+       cmd=TI_OPTMGMT timout=-1 len=32 dp=0x0804ABA8
+  16\0\0\010\0\0\010\0\0\004\0\0\0FFFF\0\00210\0\004\0\0\0\0 `\0\0
+sigprocmask(SIG_SETMASK, 0x08046B1C, 0x00000000) = 0
+fcntl(3, F_GETFL, 0x00000000)                  = 2
+sigprocmask(SIG_BLOCK, 0x08046828, 0x08046838) = 0
+ioctl(3, I_STR, 0x080467E4)                    = 0
+       cmd=TI_BIND timout=-1 len=32 dp=0x0804ABA8
+  11\0\0\010\0\0\010\0\0\0\0\0\0\002\004 1\0\0\0\0\0\0\0\0\0\0\0\0
+sigprocmask(SIG_SETMASK, 0x08046838, 0x00000000) = 0
+sigprocmask(SIG_BLOCK, 0x080469B0, 0x080469C0) = 0
+putmsg(3, 0x08046958, 0x00000000, 0)           = 0
+       ctl:  maxlen=428  len=36   buf=0x0804ABA8
+fcntl(3, F_GETFL, 0x00000000)                  = 2
+getmsg(3, 0x08046924, 0x08046918, 0x08046934)  = 0
+       ctl:  maxlen=428  len=8    buf=0x0804ABA8
+       dat:  maxlen=128  len=-1   buf=0x08046898
+fcntl(3, F_GETFL, 0x00000000)                  = 2
+getmsg(3, 0x08046964, 0x08046958, 0x0804697C)  = 0
+       ctl:  maxlen=428  len=56   buf=0x0804ABA8
+       dat:  maxlen=128  len=-1   buf=0x080468D8
+sigprocmask(SIG_SETMASK, 0x080469C0, 0x00000000) = 0
+getmsg(3, 0x08046AEC, 0x08046AE0, 0x08046B14)  = 0
+       ctl:  maxlen=428  len=8    buf=0x0804ABA8
+       dat:  maxlen=4096 len=26   buf=0x08046BB0
+ioctl(1, TCGETA, 0x08046A9A)                   = 0
+       iflag=0002406 oflag=0000005 cflag=0002275 lflag=0000053 line=0
+           cc:  177 034 010 025 004 000 000 000
+write(1, " F r i   A p r     4   0".., 26)     = 26
+getmsg(3, 0x08046AEC, 0x08046AE0, 0x08046B14)  = 0
+       ctl:  maxlen=428  len=-1   buf=0x0804ABA8
+       dat:  maxlen=4096 len=0    buf=0x08046BB0
+_exit(0)
diff --git a/ioctl/Makefile b/ioctl/Makefile
new file mode 100644 (file)
index 0000000..94dbb31
--- /dev/null
@@ -0,0 +1,23 @@
+include ../Make.defines
+
+PROGS =        lsif01 lsif02 prifinfo prmac
+
+all:   ${PROGS}
+
+lsif01:        lsif01.o
+               ${CC} ${CFLAGS} -o $@ lsif01.o ${LIBS}
+
+lsif02:        lsif02.o
+               ${CC} ${CFLAGS} -o $@ lsif02.o ${LIBS}
+
+prifinfo:      prifinfo.o
+               ${CC} ${CFLAGS} -o $@ prifinfo.o ${LIBS}
+
+prmac: prmac.o
+               ${CC} ${CFLAGS} -o $@ prmac.o ${LIBS}
+
+test1: test1.o
+               ${CC} ${CFLAGS} -o $@ test1.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/ioctl/Progs.siocgifconf b/ioctl/Progs.siocgifconf
new file mode 100644 (file)
index 0000000..30288f3
--- /dev/null
@@ -0,0 +1,93 @@
+       if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0)
+./games/hunt/hunt/hunt.c
+       i =  ioctl(sock, SIOCGIFCONF, (char *)&ifc);
+./lib/libc/net/getifaddrs.c
+       if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+./lib/librpc/rpc/get_myaddress.c
+        if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
+./lib/librpc/rpc/pmap_rmt.c
+               ioc.ic_cmd = SIOCGIFCONF;
+               m = ioctl(s, SIOCGIFCONF, (caddr_t) & ifconf);
+                       report(LOG_ERR, "ioctl SIOCGIFCONF");
+./libexec/bootpd/bootpd/getif.c
+       if (ioctl(fd, SIOCGIFCONF, (char *) &ifc) < 0 ||
+               report(LOG_ERR, "getether: SIOCGIFCONF: %s", get_errmsg);
+./libexec/bootpd/bootptest/getether.c
+#ifdef OSIOCGIFCONF
+       if (ioctl(fd, OSIOCGIFCONF, (char *)&ifc) < 0 ||
+               (void) strcpy(errbuf, "bpf: ioctl(OSIOCGIFCONF): %m");
+       if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 ||
+               (void) strcpy(errbuf, "bpf: ioctl(SIOCGIFCONF): %m");
+./libexec/rbootd/bpf.c
+#define        SCO_SIOCGIFCONF         0xc0084911
+       if ((r = ioctl(f, SIOCGIFCONF, &bifc)) == -1) {
+       case SCO_SIOCGIFCONF:
+./sco/emulator/sco_sockops.c
+       case SIOCGIFCONF:
+       case OSIOCGIFCONF:
+                       if (cmd == OSIOCGIFCONF) {
+./sys/net/if.c
+       case SIOCGIFCONF_X25:
+./sys/netccitt/pk_usrreq.c
+       if (ioctl(sk, SIOCGIFCONF, (caddr_t) &ifc) < 0)
+./usr.sbin/amd/amd/wire.c
+       if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0) {
+./usr.sbin/named/named/ns_main.c
+       if (ioctl(fd, SIOCGIFCONF, (caddr_t)&ifc) < 0 ||
+               err(FATAL, "init_all: SIOCGIFCONF: %s", strerror(errno));
+          We must instead get all the interfaces with SIOCGIFCONF
+       if (ioctl(fd, SIOCGIFCONF, (caddr_t)&ifc) < 0 ||
+./usr.sbin/rarpd/rarpd.c
+#ifdef SIOCGIFCONF
+#ifdef SIOCGIFCONF
+       if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
+./usr.sbin/sendmail/src/conf.c
+       if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 ||
+               (void)sprintf(errbuf, "SIOCGIFCONF: %s", pcap_strerror(errno));
+./usr.sbin/tcpdump/libpcap/inet.c
+       if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
+./usr.sbin/timed/timed/timed.c
+       ioc.ic_cmd = SIOCGIFCONF;
+       if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0) {
+#ifdef SIOCGIFCONF
+#endif /* SIOCGIFCONF */
+./usr.sbin/xntp/xntpd/ntp_io.c
+#if ((defined(SVR4) && !defined(sun)) || defined(ISC)) && defined(SIOCGIFCONF)
+#define SYSV_SIOCGIFCONF
+#ifdef SYSV_SIOCGIFCONF
+/* Deal with different SIOCGIFCONF ioctl semantics on SYSV, SVR4 */
+    if (cmd == SIOCGIFCONF)
+       /* SIOCGIFCONF is somewhat brain damaged on ISC. The argument
+    if (ret >= 0 && cmd == SIOCGIFCONF)
+#else /* SYSV_SIOCGIFCONF */
+#endif /* SYSV_SIOCGIFCONF */
+#if defined(STREAMSCONN) && !defined(SYSV_SIOCGIFCONF) && !defined(NCR)
+#ifdef SIOCGIFCONF
+    if (ifioctl (fd, SIOCGIFCONF, (char *) &ifc) < 0)
+        * this is ugly but SIOCGIFCONF returns decnet addresses in
+#else /* SIOCGIFCONF */
+#endif /* SIOCGIFCONF else */
+#endif /* STREAMSCONN && !SYSV_SIOCGIFCONF else */
+./X11/xc/programs/xdm/auth.c
+#if ((defined(SVR4) && !defined(sun) && !defined(NCR)) || defined(ISC)) && defined(SIOCGIFCONF)
+/* Deal with different SIOCGIFCONF ioctl semantics on these OSs */
+    if (cmd == SIOCGIFCONF)
+       /* SIOCGIFCONF is somewhat brain damaged on ISC. The argument
+    if (ret >= 0 && cmd == SIOCGIFCONF)
+#else /* ((SVR4 && !sun && !NCR) || ISC) && SIOCGIFCONF */
+#endif /* ((SVR4 && !sun) || ISC) && SIOCGIFCONF */
+       if (ifioctl (socketFD, (int) SIOCGIFCONF, (char *) &ifc) < 0)
+./X11/xc/programs/xdm/chooser.c
+#if ((defined(SVR4) && !defined(sun) && !defined(NCR)) || defined(ISC)) && defined(SIOCGIFCONF)
+/* Deal with different SIOCGIFCONF ioctl semantics on these OSs */
+    if (cmd == SIOCGIFCONF)
+       /* SIOCGIFCONF is somewhat brain damaged on ISC. The argument
+    if (ret >= 0 && cmd == SIOCGIFCONF)
+#else /* ((SVR4 && !sun) || ISC) && SIOCGIFCONF */
+#endif /* ((SVR4 && !sun) || ISC) && SIOCGIFCONF */
+#if !defined(SIOCGIFCONF) || (defined (hpux) && ! defined (HAS_IFREQ))
+    if (ifioctl (fd, (int) SIOCGIFCONF, (pointer) &ifc) < 0)
+./X11/xc/programs/Xserver/os/access.c
+#if !defined(SIOCGIFCONF) || (defined (hpux) && ! defined (HAS_IFREQ))
+    if (ioctl (fd, (int) SIOCGIFCONF, (pointer) &ifc) < 0)
+./X11/xc/workInProgress/lbx/programs/lbxproxy/os/access.c
diff --git a/ioctl/Script.solaris b/ioctl/Script.solaris
new file mode 100644 (file)
index 0000000..0801961
--- /dev/null
@@ -0,0 +1,28 @@
+kohala % ./prifinfo 4 1
+trying len = 64
+ioctl error
+trying len = 96
+ioctl error
+trying len = 128
+ioctl error
+trying len = 160
+ioctl error
+trying len = 192
+returned len = 160
+trying len = 224
+returned len = 160
+success, len = 160
+lo0: <UP MCAST LOOP >
+  IP addr: 127.0.0.1
+le0: <UP BCAST MCAST >
+  IP addr: 206.62.226.33
+  broadcast addr: 206.62.226.63
+le0:1: <UP BCAST MCAST >
+  IP addr: 140.252.13.47
+  broadcast addr: 140.252.13.63
+le0:2: <UP BCAST MCAST >
+  IP addr: 140.252.13.48
+  broadcast addr: 140.252.13.63
+le0:3: <UP BCAST MCAST >
+  IP addr: 140.252.13.49
+  broadcast addr: 140.252.13.63
diff --git a/ioctl/lsif01.c b/ioctl/lsif01.c
new file mode 100644 (file)
index 0000000..ed77acf
--- /dev/null
@@ -0,0 +1,42 @@
+#include       "unp.h"
+
+#include       <net/if.h>
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, len;
+       char                            *ptr, buf[2048], addrstr[INET_ADDRSTRLEN];
+       struct ifconf           ifc;
+       struct ifreq            *ifr;
+       struct sockaddr_in      *sinptr;
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       ifc.ifc_len = sizeof(buf);
+       ifc.ifc_req = (struct ifreq *) buf;
+       Ioctl(sockfd, SIOCGIFCONF, &ifc);
+
+       for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
+               ifr = (struct ifreq *) ptr;
+               len = sizeof(struct sockaddr);
+#ifdef HAVE_SOCKADDR_SA_LEN
+               if (ifr->ifr_addr.sa_len > len)
+                       len = ifr->ifr_addr.sa_len;             /* length > 16 */
+#endif
+               ptr += sizeof(ifr->ifr_name) + len;     /* for next one in buffer */
+
+               switch (ifr->ifr_addr.sa_family) {
+               case AF_INET:
+                       sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
+                       printf("%s\t%s\n", ifr->ifr_name,
+                                  Inet_ntop(AF_INET, &sinptr->sin_addr, addrstr, sizeof(addrstr)));
+                       break;
+
+               default:
+                       printf("%s\n", ifr->ifr_name);
+                       break;
+               }
+       }
+       exit(0);
+}
diff --git a/ioctl/lsif02.c b/ioctl/lsif02.c
new file mode 100644 (file)
index 0000000..4bb0dd6
--- /dev/null
@@ -0,0 +1,88 @@
+#include       "unp.h"
+
+#include       <net/if.h>
+#ifdef HAVE_SOCKADDR_DL_STRUCT
+#include       <net/if_dl.h>
+#include       <net/if_types.h>
+#endif
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, len;
+       char                            *ptr, buf[2048], addrstr[INET_ADDRSTRLEN];
+       struct ifconf           ifc;
+       struct ifreq            *ifr;
+       struct sockaddr_in      *sinptr;
+
+       if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+               err_sys("socket error");
+
+       ifc.ifc_len = sizeof(buf);
+       ifc.ifc_req = (struct ifreq *) buf;
+       if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0)
+               err_sys("ioctl SIOCGIFCONF error");
+
+       for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
+               ifr = (struct ifreq *) ptr;
+               len = sizeof(struct sockaddr);
+#ifdef HAVE_SOCKADDR_SA_LEN
+               if (ifr->ifr_addr.sa_len > len)
+                       len = ifr->ifr_addr.sa_len;             /* length > 16 */
+#endif
+               ptr += sizeof(ifr->ifr_name) + len;     /* for next one in buffer */
+
+               switch (ifr->ifr_addr.sa_family) {
+               case AF_INET:
+                       sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
+                       printf("%s\t%s\n", ifr->ifr_name,
+                                  Inet_ntop(AF_INET, &sinptr->sin_addr, addrstr, sizeof(addrstr)));
+                       break;
+
+#ifdef AF_INET6
+               case AF_INET6: {
+                       struct sockaddr_in6     *sin6ptr;
+                       char addr6str[INET6_ADDRSTRLEN];
+
+                       sin6ptr = (struct sockaddr_in6 *) &ifr->ifr_addr;
+                       printf("%s\t%s\n", ifr->ifr_name,
+                                  Inet_ntop(AF_INET6, &sin6ptr->sin6_addr, addr6str, sizeof(addr6str)));
+                       break;
+               }
+#endif
+
+#ifdef HAVE_SOCKADDR_DL_STRUCT
+               case AF_LINK: {
+                       struct sockaddr_dl      *sdlptr;
+                       char                            str[18];
+                       char                            *etherprint(const u_char *, char *);
+
+                       sdlptr = (struct sockaddr_dl *) &ifr->ifr_addr;
+                       printf("%s", ifr->ifr_name);
+                       if (sdlptr->sdl_index)
+                               printf("\t<link %d>", sdlptr->sdl_index);
+                       if (sdlptr->sdl_type == IFT_ETHER && sdlptr->sdl_alen)
+                               printf("\t%s", etherprint((u_char *) LLADDR(sdlptr), str));
+                       putchar('\n');
+                       break;
+               }
+#endif
+
+               default:
+                       printf("%s\n", ifr->ifr_name);
+                       break;
+               }
+       }
+       exit(0);
+}
+
+#ifdef HAVE_SOCKADDR_DL_STRUCT
+char *
+etherprint(const u_char eaddr[6], char string[18])
+{
+       snprintf(string, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+                   eaddr[0], eaddr[1], eaddr[2], eaddr[3], eaddr[4], eaddr[5] );
+       string[17] = '\0';
+       return(string);
+}
+#endif
diff --git a/ioctl/prifinfo.c b/ioctl/prifinfo.c
new file mode 100644 (file)
index 0000000..846f6dc
--- /dev/null
@@ -0,0 +1,61 @@
+#include       "unpifi.h"
+
+int
+main(int argc, char **argv)
+{
+       struct ifi_info *ifi, *ifihead;
+       struct sockaddr *sa;
+       u_char                  *ptr;
+       int                             i, family, doaliases;
+
+       if (argc != 3)
+               err_quit("usage: prifinfo <inet4|inet6> <doaliases>");
+
+       if (strcmp(argv[1], "inet4") == 0)
+               family = AF_INET;
+#ifdef IPv6
+       else if (strcmp(argv[1], "inet6") == 0)
+               family = AF_INET6;
+#endif
+       else
+               err_quit("invalid <address-family>");
+       doaliases = atoi(argv[2]);
+
+       for (ifihead = ifi = Get_ifi_info(family, doaliases);
+                ifi != NULL; ifi = ifi->ifi_next) {
+               printf("%s: ", ifi->ifi_name);
+               if (ifi->ifi_index != 0)
+                       printf("(%d) ", ifi->ifi_index);
+               printf("<");
+/* *INDENT-OFF* */
+               if (ifi->ifi_flags & IFF_UP)                    printf("UP ");
+               if (ifi->ifi_flags & IFF_BROADCAST)             printf("BCAST ");
+               if (ifi->ifi_flags & IFF_MULTICAST)             printf("MCAST ");
+               if (ifi->ifi_flags & IFF_LOOPBACK)              printf("LOOP ");
+               if (ifi->ifi_flags & IFF_POINTOPOINT)   printf("P2P ");
+               printf(">\n");
+/* *INDENT-ON* */
+
+               if ( (i = ifi->ifi_hlen) > 0) {
+                       ptr = ifi->ifi_haddr;
+                       do {
+                               printf("%s%x", (i == ifi->ifi_hlen) ? "  " : ":", *ptr++);
+                       } while (--i > 0);
+                       printf("\n");
+               }
+               if (ifi->ifi_mtu != 0)
+                       printf("  MTU: %d\n", ifi->ifi_mtu);
+
+               if ( (sa = ifi->ifi_addr) != NULL)
+                       printf("  IP addr: %s\n",
+                                               Sock_ntop_host(sa, sizeof(*sa)));
+               if ( (sa = ifi->ifi_brdaddr) != NULL)
+                       printf("  broadcast addr: %s\n",
+                                               Sock_ntop_host(sa, sizeof(*sa)));
+               if ( (sa = ifi->ifi_dstaddr) != NULL)
+                       printf("  destination addr: %s\n",
+                                               Sock_ntop_host(sa, sizeof(*sa)));
+       }
+       free_ifi_info(ifihead);
+       exit(0);
+}
diff --git a/ioctl/prifinfo.lc b/ioctl/prifinfo.lc
new file mode 100644 (file)
index 0000000..2b08c73
--- /dev/null
@@ -0,0 +1,53 @@
+#include    "unpifi.h"##  1 ##src/ioctl/prifinfo.c##
+
+int##  2 ##src/ioctl/prifinfo.c##
+main(int argc, char **argv)##  3 ##src/ioctl/prifinfo.c##
+{##  4 ##src/ioctl/prifinfo.c##
+    struct ifi_info *ifi, *ifihead;##  5 ##src/ioctl/prifinfo.c##
+    struct sockaddr *sa;##  6 ##src/ioctl/prifinfo.c##
+    u_char *ptr;##  7 ##src/ioctl/prifinfo.c##
+    int     i, family, doaliases;##  8 ##src/ioctl/prifinfo.c##
+
+    if (argc != 3)##  9 ##src/ioctl/prifinfo.c##
+        err_quit("usage: prifinfo <inet4|inet6> <doaliases>");## 10 ##src/ioctl/prifinfo.c##
+
+    if (strcmp(argv[1], "inet4") == 0)## 11 ##src/ioctl/prifinfo.c##
+        family = AF_INET;## 12 ##src/ioctl/prifinfo.c##
+#ifdef  IPV6## 13 ##src/ioctl/prifinfo.c##
+    else if (strcmp(argv[1], "inet6") == 0)## 14 ##src/ioctl/prifinfo.c##
+        family = AF_INET6;## 15 ##src/ioctl/prifinfo.c##
+#endif## 16 ##src/ioctl/prifinfo.c##
+    else## 17 ##src/ioctl/prifinfo.c##
+        err_quit("invalid <address-family>");## 18 ##src/ioctl/prifinfo.c##
+    doaliases = atoi(argv[2]);## 19 ##src/ioctl/prifinfo.c##
+
+    for (ifihead = ifi = Get_ifi_info(family, doaliases);## 20 ##src/ioctl/prifinfo.c##
+         ifi != NULL; ifi = ifi->ifi_next) {## 21 ##src/ioctl/prifinfo.c##
+        printf("%s: (%d) <", ifi->ifi_name, ifi->ifi_index);## 22 ##src/ioctl/prifinfo.c##
+        if (ifi->ifi_flags & IFF_UP)            printf("UP ");## 23 ##src/ioctl/prifinfo.c##
+        if (ifi->ifi_flags & IFF_BROADCAST)     printf("BCAST ");## 24 ##src/ioctl/prifinfo.c##
+        if (ifi->ifi_flags & IFF_MULTICAST)     printf("MCAST ");## 25 ##src/ioctl/prifinfo.c##
+        if (ifi->ifi_flags & IFF_LOOPBACK)      printf("LOOP ");## 26 ##src/ioctl/prifinfo.c##
+        if (ifi->ifi_flags & IFF_POINTOPOINT)   printf("P2P ");## 27 ##src/ioctl/prifinfo.c##
+        printf(">\n");## 28 ##src/ioctl/prifinfo.c##
+
+        if ((i = ifi->ifi_hlen) > 0) {## 29 ##src/ioctl/prifinfo.c##
+            ptr = ifi->ifi_haddr;## 30 ##src/ioctl/prifinfo.c##
+            do {## 31 ##src/ioctl/prifinfo.c##
+                printf("%s%x", (i == ifi->ifi_hlen) ? "  " : ":", *ptr++);## 32 ##src/ioctl/prifinfo.c##
+            } while (--i > 0);## 33 ##src/ioctl/prifinfo.c##
+            printf("\n");## 34 ##src/ioctl/prifinfo.c##
+        }## 35 ##src/ioctl/prifinfo.c##
+
+        if ((sa = ifi->ifi_addr) != NULL)## 36 ##src/ioctl/prifinfo.c##
+            printf("  IP addr: %s\n", Sock_ntop_host(sa, sizeof(*sa)));## 37 ##src/ioctl/prifinfo.c##
+        if ((sa = ifi->ifi_brdaddr) != NULL)## 38 ##src/ioctl/prifinfo.c##
+            printf("  broadcast addr: %s\n",## 39 ##src/ioctl/prifinfo.c##
+                   Sock_ntop_host(sa, sizeof(*sa)));## 40 ##src/ioctl/prifinfo.c##
+        if ((sa = ifi->ifi_dstaddr) != NULL)## 41 ##src/ioctl/prifinfo.c##
+            printf("  destination addr: %s\n",## 42 ##src/ioctl/prifinfo.c##
+                   Sock_ntop_host(sa, sizeof(*sa)));## 43 ##src/ioctl/prifinfo.c##
+    }## 44 ##src/ioctl/prifinfo.c##
+    free_ifi_info(ifihead);## 45 ##src/ioctl/prifinfo.c##
+    exit(0);## 46 ##src/ioctl/prifinfo.c##
+}## 47 ##src/ioctl/prifinfo.c##
diff --git a/ioctl/prmac.c b/ioctl/prmac.c
new file mode 100644 (file)
index 0000000..f2b6a89
--- /dev/null
@@ -0,0 +1,30 @@
+#include       "unpifi.h"
+#include       <net/if_arp.h>
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct ifi_info                 *ifi;
+       unsigned char           *ptr;
+       struct arpreq           arpreq;
+       struct sockaddr_in      *sin;
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+       for (ifi = get_ifi_info(AF_INET, 0); ifi != NULL; ifi = ifi->ifi_next) {
+               printf("%s: ", Sock_ntop(ifi->ifi_addr, sizeof(struct sockaddr_in)));
+
+               sin = (struct sockaddr_in *) &arpreq.arp_pa;
+               memcpy(sin, ifi->ifi_addr, sizeof(struct sockaddr_in));
+
+               if (ioctl(sockfd, SIOCGARP, &arpreq) < 0) {
+                       err_ret("ioctl SIOCGARP");
+                       continue;
+               }
+
+               ptr = &arpreq.arp_ha.sa_data[0];
+               printf("%x:%x:%x:%x:%x:%x\n", *ptr, *(ptr+1),
+                          *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5));
+       }
+       exit(0);
+}
diff --git a/ioctl/test1.c b/ioctl/test1.c
new file mode 100644 (file)
index 0000000..c5e0c36
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "unp.h"
+#include       <net/if.h>
+
+int
+main(int argc, char **argv)
+{
+       int             i, sockfd, numif;
+       char    buf[1024];
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       numif = 999;
+       Ioctl(sockfd, SIOCGIFNUM, &numif);
+       printf("numif = %d\n", numif);
+
+       i = ioctl(sockfd, SIOCGHIWAT, &buf);
+       printf("i = %d, errno = %d\n", i, errno);
+       exit(0);
+}
diff --git a/ipopts/Makefile b/ipopts/Makefile
new file mode 100644 (file)
index 0000000..adbc2e0
--- /dev/null
@@ -0,0 +1,22 @@
+include ../Make.defines
+
+PROGS =        tcpcli01 tcpserv01
+
+all:   ${PROGS}
+
+tcpcli01:      tcpcli01.o sourceroute.o
+               ${CC} ${CFLAGS} -o $@ tcpcli01.o sourceroute.o ${LIBS}
+
+tcpserv01:     tcpserv01.o sourceroute.o sigchldwaitpid.o
+               ${CC} ${CFLAGS} -o $@ tcpserv01.o sourceroute.o sigchldwaitpid.o \
+                               ${LIBS}
+
+udpcli01:      udpcli01.o 
+               ${CC} ${CFLAGS} -o $@ udpcli01.o ${LIBS}
+
+udpserv01:     udpserv01.o sourceroute6.o dgechoprintroute.o
+               ${CC} ${CFLAGS} -o $@ udpserv01.o sourceroute6.o dgechoprintroute.o ${LIBS}
+
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/ipopts/dgechoprintroute.c b/ipopts/dgechoprintroute.c
new file mode 100644 (file)
index 0000000..1dcae5a
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unp.h"
+
+void
+dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
+{
+       int                             n;
+       char                    mesg[MAXLINE];
+       int                             on;
+       char                    control[MAXLINE];
+       struct msghdr   msg;
+       struct cmsghdr  *cmsg;
+       struct iovec    iov[1];
+
+       on = 1;
+       Setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVRTHDR, &on, sizeof(on));
+
+       bzero(&msg, sizeof(msg));
+       iov[0].iov_base = mesg;
+       msg.msg_name = pcliaddr;
+       msg.msg_iov = iov;
+       msg.msg_iovlen = 1;
+       msg.msg_control = control;
+       for ( ; ; ) {
+               msg.msg_namelen = clilen;
+               msg.msg_controllen = sizeof(control);
+               iov[0].iov_len = MAXLINE;
+               n = Recvmsg(sockfd, &msg, 0);
+
+               for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+                        cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+                       if (cmsg->cmsg_level == IPPROTO_IPV6 &&
+                               cmsg->cmsg_type == IPV6_RTHDR) {
+                               inet6_srcrt_print(CMSG_DATA(cmsg));
+                               Inet6_rth_reverse(CMSG_DATA(cmsg), CMSG_DATA(cmsg));
+                       }
+               }
+
+               iov[0].iov_len = n;
+               Sendmsg(sockfd, &msg, 0);
+       }
+}
diff --git a/ipopts/sigchldwaitpid.c b/ipopts/sigchldwaitpid.c
new file mode 100644 (file)
index 0000000..5fa9cbf
--- /dev/null
@@ -0,0 +1,13 @@
+#include       "unp.h"
+
+void
+sig_chld(int signo)
+{
+       pid_t   pid;
+       int             stat;
+
+       while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) {
+               printf("child %d terminated\n", pid);
+       }
+       return;
+}
diff --git a/ipopts/sourceroute.c b/ipopts/sourceroute.c
new file mode 100644 (file)
index 0000000..9673d0c
--- /dev/null
@@ -0,0 +1,82 @@
+/* include inet_srcrt_init */
+#include       "unp.h"
+#include       <netinet/in_systm.h>
+#include       <netinet/ip.h>
+
+static u_char  *optr;          /* pointer into options being formed */
+static u_char  *lenptr;        /* pointer to length byte in SRR option */
+static int             ocnt;           /* count of # addresses */
+
+u_char *
+inet_srcrt_init(int type)
+{
+       optr = Malloc(44);              /* NOP, code, len, ptr, up to 10 addresses */
+       bzero(optr, 44);                /* guarantees EOLs at end */
+       ocnt = 0;
+       *optr++ = IPOPT_NOP;    /* NOP for alignment */
+       *optr++ = type ? IPOPT_SSRR : IPOPT_LSRR;
+       lenptr = optr++;                /* we fill in length later */
+       *optr++ = 4;                    /* offset to first address */
+
+       return(optr - 4);               /* pointer for setsockopt() */
+}
+/* end inet_srcrt_init */
+
+/* include inet_srcrt_add */
+int
+inet_srcrt_add(char *hostptr)
+{
+       int                                     len;
+       struct addrinfo         *ai;
+       struct sockaddr_in      *sin;
+
+       if (ocnt > 9)
+               err_quit("too many source routes with: %s", hostptr);
+
+       ai = Host_serv(hostptr, NULL, AF_INET, 0);
+       sin = (struct sockaddr_in *) ai->ai_addr;
+       memcpy(optr, &sin->sin_addr, sizeof(struct in_addr));
+       freeaddrinfo(ai);
+
+       optr += sizeof(struct in_addr);
+       ocnt++;
+       len = 3 + (ocnt * sizeof(struct in_addr));
+       *lenptr = len;
+       return(len + 1);        /* size for setsockopt() */
+}
+/* end inet_srcrt_add */
+
+/* include inet_srcrt_print */
+void
+inet_srcrt_print(u_char *ptr, int len)
+{
+       u_char                  c;
+       char                    str[INET_ADDRSTRLEN];
+       struct in_addr  hop1;
+
+       memcpy(&hop1, ptr, sizeof(struct in_addr));
+       ptr += sizeof(struct in_addr);
+
+       while ( (c = *ptr++) == IPOPT_NOP)
+               ;               /* skip any leading NOPs */
+
+       if (c == IPOPT_LSRR)
+               printf("received LSRR: ");
+       else if (c == IPOPT_SSRR)
+               printf("received SSRR: ");
+       else {
+               printf("received option type %d\n", c);
+               return;
+       }
+       printf("%s ", Inet_ntop(AF_INET, &hop1, str, sizeof(str)));
+
+       len = *ptr++ - sizeof(struct in_addr);  /* subtract dest IP addr */
+       ptr++;          /* skip over pointer */
+       while (len > 0) {
+               printf("%s ", Inet_ntop(AF_INET, ptr, str, sizeof(str)));
+               ptr += sizeof(struct in_addr);
+               len -= sizeof(struct in_addr);
+       }
+       printf("\n");
+}
+/* end inet_srcrt_print */
diff --git a/ipopts/sourceroute.lc b/ipopts/sourceroute.lc
new file mode 100644 (file)
index 0000000..cb7bb7a
--- /dev/null
@@ -0,0 +1,83 @@
+/* include inet_srcrt_init */
+#include    "unp.h"##  1 ##src/ipopts/sourceroute.c##
+#include    <netinet/in_systm.h>##  2 ##src/ipopts/sourceroute.c##
+#include    <netinet/ip.h>##  3 ##src/ipopts/sourceroute.c##
+
+static u_char *optr;            /* pointer into options being formed */##  4 ##src/ipopts/sourceroute.c##
+static u_char *lenptr;          /* pointer to length byte in SRR option */##  5 ##src/ipopts/sourceroute.c##
+static int ocnt;                /* count of # addresses */##  6 ##src/ipopts/sourceroute.c##
+
+u_char *##  7 ##src/ipopts/sourceroute.c##
+inet_srcrt_init(void)##  8 ##src/ipopts/sourceroute.c##
+{##  9 ##src/ipopts/sourceroute.c##
+    optr = Malloc(44);          /* NOP, code, len, ptr, up to 10 addresses */## 10 ##src/ipopts/sourceroute.c##
+    bzero(optr, 44);            /* guarantees EOLs at end */## 11 ##src/ipopts/sourceroute.c##
+    ocnt = 0;## 12 ##src/ipopts/sourceroute.c##
+    return (optr);              /* pointer for setsockopt() */## 13 ##src/ipopts/sourceroute.c##
+}## 14 ##src/ipopts/sourceroute.c##
+/* end inet_srcrt_init */
+
+/* include inet_srcrt_add */
+int## 15 ##src/ipopts/sourceroute.c##
+inet_srcrt_add(char *hostptr, int type)## 16 ##src/ipopts/sourceroute.c##
+{## 17 ##src/ipopts/sourceroute.c##
+    int     len;## 18 ##src/ipopts/sourceroute.c##
+    struct addrinfo *ai;## 19 ##src/ipopts/sourceroute.c##
+    struct sockaddr_in *sin;## 20 ##src/ipopts/sourceroute.c##
+
+    if (ocnt > 9)## 21 ##src/ipopts/sourceroute.c##
+        err_quit("too many source routes with: %s", hostptr);## 22 ##src/ipopts/sourceroute.c##
+
+    if (ocnt == 0) {## 23 ##src/ipopts/sourceroute.c##
+        *optr++ = IPOPT_NOP;    /* NOP for alignment */## 24 ##src/ipopts/sourceroute.c##
+        *optr++ = type ? IPOPT_SSRR : IPOPT_LSRR;## 25 ##src/ipopts/sourceroute.c##
+        lenptr = optr++;        /* we fill in the length later */## 26 ##src/ipopts/sourceroute.c##
+        *optr++ = 4;            /* offset to first address */## 27 ##src/ipopts/sourceroute.c##
+    }## 28 ##src/ipopts/sourceroute.c##
+
+    ai = Host_serv(hostptr, "", AF_INET, 0);## 29 ##src/ipopts/sourceroute.c##
+    sin = (struct sockaddr_in *) ai->ai_addr;## 30 ##src/ipopts/sourceroute.c##
+    memcpy(optr, &sin->sin_addr, sizeof(struct in_addr));## 31 ##src/ipopts/sourceroute.c##
+    freeaddrinfo(ai);## 32 ##src/ipopts/sourceroute.c##
+
+    optr += sizeof(struct in_addr);## 33 ##src/ipopts/sourceroute.c##
+    ocnt++;## 34 ##src/ipopts/sourceroute.c##
+    len = 3 + (ocnt * sizeof(struct in_addr));## 35 ##src/ipopts/sourceroute.c##
+    *lenptr = len;## 36 ##src/ipopts/sourceroute.c##
+    return (len + 1);           /* size for setsockopt() */## 37 ##src/ipopts/sourceroute.c##
+}## 38 ##src/ipopts/sourceroute.c##
+/* end inet_srcrt_add */
+
+/* include inet_srcrt_print */
+void## 39 ##src/ipopts/sourceroute.c##
+inet_srcrt_print(u_char *ptr, int len)## 40 ##src/ipopts/sourceroute.c##
+{## 41 ##src/ipopts/sourceroute.c##
+    u_char  c;## 42 ##src/ipopts/sourceroute.c##
+    char    str[INET_ADDRSTRLEN];## 43 ##src/ipopts/sourceroute.c##
+    struct in_addr hop1;## 44 ##src/ipopts/sourceroute.c##
+
+    memcpy(&hop1, ptr, sizeof(struct in_addr));## 45 ##src/ipopts/sourceroute.c##
+    ptr += sizeof(struct in_addr);## 46 ##src/ipopts/sourceroute.c##
+
+    while ((c = *ptr++) == IPOPT_NOP) ; /* skip any leading NOPs */## 47 ##src/ipopts/sourceroute.c##
+
+    if (c == IPOPT_LSRR)## 48 ##src/ipopts/sourceroute.c##
+        printf("received LSRR: ");## 49 ##src/ipopts/sourceroute.c##
+    else if (c == IPOPT_SSRR)## 50 ##src/ipopts/sourceroute.c##
+        printf("received SSRR: ");## 51 ##src/ipopts/sourceroute.c##
+    else {## 52 ##src/ipopts/sourceroute.c##
+        printf("received option type %d\n", c);## 53 ##src/ipopts/sourceroute.c##
+        return;## 54 ##src/ipopts/sourceroute.c##
+    }## 55 ##src/ipopts/sourceroute.c##
+    printf("%s ", Inet_ntop(AF_INET, &hop1, str, sizeof(str)));## 56 ##src/ipopts/sourceroute.c##
+
+    len = *ptr++ - sizeof(struct in_addr);  /* subtract dest IP addr */## 57 ##src/ipopts/sourceroute.c##
+    ptr++;                      /* skip over pointer */## 58 ##src/ipopts/sourceroute.c##
+    while (len > 0) {## 59 ##src/ipopts/sourceroute.c##
+        printf("%s ", Inet_ntop(AF_INET, ptr, str, sizeof(str)));## 60 ##src/ipopts/sourceroute.c##
+        ptr += sizeof(struct in_addr);## 61 ##src/ipopts/sourceroute.c##
+        len -= sizeof(struct in_addr);## 62 ##src/ipopts/sourceroute.c##
+    }## 63 ##src/ipopts/sourceroute.c##
+    printf("\n");## 64 ##src/ipopts/sourceroute.c##
+}## 65 ##src/ipopts/sourceroute.c##
+/* end inet_srcrt_print */
diff --git a/ipopts/sourceroute6.c b/ipopts/sourceroute6.c
new file mode 100644 (file)
index 0000000..e6e0cce
--- /dev/null
@@ -0,0 +1,15 @@
+#include       "unp.h"
+
+void
+inet6_srcrt_print(void *ptr)
+{
+       int                     i, segments;
+       char                    str[INET6_ADDRSTRLEN];
+
+       segments = Inet6_rth_segments(ptr);
+       printf("received source route: ");
+       for (i = 0; i < segments; i++)
+               printf("%s ", Inet_ntop(AF_INET6, Inet6_rth_getaddr(ptr, i),
+                                                               str, sizeof(str)));
+       printf("\n");
+}
diff --git a/ipopts/tcpcli01.c b/ipopts/tcpcli01.c
new file mode 100644 (file)
index 0000000..27ebd71
--- /dev/null
@@ -0,0 +1,58 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     c, sockfd, len = 0;
+       u_char                          *ptr = NULL;
+       struct addrinfo         *ai;
+
+       if (argc < 2)
+               err_quit("usage: tcpcli01 [ -[gG] <hostname> ... ] <hostname>");
+
+       opterr = 0;             /* don't want getopt() writing to stderr */
+       while ( (c = getopt(argc, argv, "gG")) != -1) {
+               switch (c) {
+               case 'g':                       /* loose source route */
+                       if (ptr)
+                               err_quit("can't use both -g and -G");
+                       ptr = inet_srcrt_init(0);
+                       break;
+
+               case 'G':                       /* strict source route */
+                       if (ptr)
+                               err_quit("can't use both -g and -G");
+                       ptr = inet_srcrt_init(1);
+                       break;
+
+               case '?':
+                       err_quit("unrecognized option: %c", c);
+               }
+       }
+
+       if (ptr)
+               while (optind < argc-1)
+                       len = inet_srcrt_add(argv[optind++]);
+       else
+               if (optind < argc-1)
+                       err_quit("need -g or -G to specify route");
+
+       if (optind != argc-1)
+               err_quit("missing <hostname>");
+
+       ai = Host_serv(argv[optind], SERV_PORT_STR, AF_INET, SOCK_STREAM);
+
+       sockfd = Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+
+       if (ptr) {
+               len = inet_srcrt_add(argv[optind]);     /* dest at end */
+               Setsockopt(sockfd, IPPROTO_IP, IP_OPTIONS, ptr, len);
+               free(ptr);
+       }
+
+       Connect(sockfd, ai->ai_addr, ai->ai_addrlen);
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/ipopts/tcpserv01.c b/ipopts/tcpserv01.c
new file mode 100644 (file)
index 0000000..04274fd
--- /dev/null
@@ -0,0 +1,51 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       u_char                          *opts;
+       pid_t                           childpid;
+       socklen_t                       clilen, len;
+       struct sockaddr_in      cliaddr, servaddr;
+       void                            sig_chld(int);
+
+       opts = Malloc(44);
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       Signal(SIGCHLD, sig_chld);
+
+       for ( ; ; ) {
+               clilen = sizeof(cliaddr);
+               if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
+                       if (errno == EINTR)
+                               continue;               /* back to for() */
+                       else
+                               err_sys("accept error");
+               }
+
+               len = 44;
+               Getsockopt(connfd, IPPROTO_IP, IP_OPTIONS, opts, &len);
+               if (len > 0) {
+                       printf("received IP options, len = %d\n", len);
+                       inet_srcrt_print(opts, len);
+               }
+
+               if ( (childpid = Fork()) == 0) {        /* child process */
+                       Close(listenfd);        /* close listening socket */
+                       str_echo(connfd);       /* process the request */
+                       exit(0);
+               }
+               Close(connfd);                  /* parent closes connected socket */
+       }
+}
diff --git a/ipopts/udpcli01.c b/ipopts/udpcli01.c
new file mode 100644 (file)
index 0000000..4a5a7ed
--- /dev/null
@@ -0,0 +1,38 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     c, sockfd, len = 0;
+       u_char                          *ptr = NULL;
+       void                            *rth;
+       struct addrinfo         *ai;
+
+       if (argc < 2)
+               err_quit("usage: udpcli01 [ <hostname> ... ] <hostname>");
+
+       if (argc > 2) {
+               int i;
+
+               len = Inet6_rth_space(IPV6_RTHDR_TYPE_0, argc-2);
+               ptr = Malloc(len);
+               Inet6_rth_init(ptr, len, IPV6_RTHDR_TYPE_0, argc-2);
+               for (i = 1; i < argc-1; i++) {
+                       ai = Host_serv(argv[i], NULL, AF_INET6, 0);
+                       Inet6_rth_add(ptr, &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr);
+               }
+       }
+
+       ai = Host_serv(argv[argc-1], SERV_PORT_STR, AF_INET6, SOCK_DGRAM);
+
+       sockfd = Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+
+       if (ptr) {
+               Setsockopt(sockfd, IPPROTO_IPV6, IPV6_RTHDR, ptr, len);
+               free(ptr);
+       }
+
+       dg_cli(stdin, sockfd, ai->ai_addr, ai->ai_addrlen);     /* do it all */
+
+       exit(0);
+}
diff --git a/ipopts/udpserv01.c b/ipopts/udpserv01.c
new file mode 100644 (file)
index 0000000..8915f16
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in6     servaddr, cliaddr;
+
+       sockfd = Socket(AF_INET6, SOCK_DGRAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin6_family     = AF_INET6;
+       servaddr.sin6_addr       = in6addr_any;
+       servaddr.sin6_port       = htons(SERV_PORT);
+
+       Bind(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
+}
diff --git a/key/Makefile b/key/Makefile
new file mode 100644 (file)
index 0000000..4709357
--- /dev/null
@@ -0,0 +1,15 @@
+include ../Make.defines
+
+PROGS =        dump register add
+OBJS = printsadbmsg.o name.o
+
+all:   ${PROGS}
+
+dump:  dump.o ${OBJS}
+               ${CC} ${CFLAGS} -o $@ $@.o ${OBJS} ${LIBS}
+
+register:      register.o ${OBJS}
+               ${CC} ${CFLAGS} -o $@ $@.o ${OBJS} ${LIBS}
+
+add:   add.o ${OBJS}
+       ${CC} ${CFLAGS} -o $@ $@.o ${OBJS} ${LIBS}
diff --git a/key/add.c b/key/add.c
new file mode 100644 (file)
index 0000000..a9cd814
--- /dev/null
+++ b/key/add.c
@@ -0,0 +1,181 @@
+#include "unp.h"
+#include <net/pfkeyv2.h>
+
+int
+salen(struct sockaddr *sa)
+{
+#ifdef HAVE_SOCKADDR_SA_LEN
+       return sa->sa_len;
+#else
+       switch (sa->sa_family) {
+       case AF_INET:
+               return sizeof(struct sockaddr_in);
+#ifdef IPV6
+       case AF_INET6:
+               return sizeof(struct sockaddr_in6);
+#endif
+       default:
+               return 0;       /* XXX */
+       }
+#endif
+}
+
+int
+prefix_all(struct sockaddr *sa)
+{
+       switch (sa->sa_family) {
+       case AF_INET:
+               return 32;
+#ifdef IPV6
+       case AF_INET6:
+               return 128;
+#endif
+       default:
+               return 0;       /* XXX */
+       }
+}
+
+/* include sadb_add */
+void
+sadb_add(struct sockaddr *src, struct sockaddr *dst, int type, int alg,
+               int spi, int keybits, unsigned char *keydata)
+{
+       int s;
+       char buf[4096], *p;     /* XXX */
+       struct sadb_msg *msg;
+       struct sadb_sa *saext;
+       struct sadb_address *addrext;
+       struct sadb_key *keyext;
+       int len;
+       int mypid;
+
+       s = Socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
+
+       mypid = getpid();
+
+       /* Build and write SADB_ADD request */
+       bzero(&buf, sizeof(buf));
+       p = buf;
+       msg = (struct sadb_msg *)p;
+       msg->sadb_msg_version = PF_KEY_V2;
+       msg->sadb_msg_type = SADB_ADD;
+       msg->sadb_msg_satype = type;
+       msg->sadb_msg_pid = getpid();
+       len = sizeof(*msg);
+       p += sizeof(*msg);
+        
+       saext = (struct sadb_sa *)p;
+       saext->sadb_sa_len = sizeof(*saext) / 8;
+       saext->sadb_sa_exttype = SADB_EXT_SA;
+       saext->sadb_sa_spi = htonl(spi);
+       saext->sadb_sa_replay = 0;      /* no replay protection with static keys */
+       saext->sadb_sa_state = SADB_SASTATE_MATURE;
+       saext->sadb_sa_auth = alg;
+       saext->sadb_sa_encrypt = SADB_EALG_NONE;
+       saext->sadb_sa_flags = 0;
+       len += saext->sadb_sa_len * 8;
+       p += saext->sadb_sa_len * 8;
+
+       addrext = (struct sadb_address *)p;
+       addrext->sadb_address_len = (sizeof(*addrext) + salen(src) + 7) / 8;
+       addrext->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
+       addrext->sadb_address_proto = 0;        /* any protocol */
+       addrext->sadb_address_prefixlen = prefix_all(src);
+       addrext->sadb_address_reserved = 0;
+       memcpy(addrext + 1, src, salen(src));
+       len += addrext->sadb_address_len * 8;
+       p += addrext->sadb_address_len * 8;
+        
+       addrext = (struct sadb_address *)p;
+       addrext->sadb_address_len = (sizeof(*addrext) + salen(dst) + 7) / 8;
+       addrext->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
+       addrext->sadb_address_proto = 0;        /* any protocol */
+       addrext->sadb_address_prefixlen = prefix_all(dst);
+       addrext->sadb_address_reserved = 0;
+       memcpy(addrext + 1, dst, salen(dst));
+       len += addrext->sadb_address_len * 8;
+       p += addrext->sadb_address_len * 8;
+
+       keyext = (struct sadb_key *)p;
+       /* "+7" handles alignment requirements */
+       keyext->sadb_key_len = (sizeof(*keyext) + (keybits / 8) + 7) / 8;
+       keyext->sadb_key_exttype = SADB_EXT_KEY_AUTH;
+       keyext->sadb_key_bits = keybits;
+       keyext->sadb_key_reserved = 0;
+       memcpy(keyext + 1, keydata, keybits / 8);
+       len += keyext->sadb_key_len * 8;
+       p += keyext->sadb_key_len * 8;
+        
+       msg->sadb_msg_len = len / 8;
+       printf("Sending add message:\n");
+       print_sadb_msg(buf, len);
+       Write(s, buf, len);
+
+       printf("\nReply returned:\n");
+       /* Read and print SADB_ADD reply, discarding any others */
+       for (;;) {
+               int msglen;
+               struct sadb_msg *msgp;
+
+               msglen = Read(s, &buf, sizeof(buf));
+               msgp = (struct sadb_msg *)&buf;
+               if (msgp->sadb_msg_pid == mypid &&
+                       msgp->sadb_msg_type == SADB_ADD) {
+                       print_sadb_msg(msgp, msglen);
+                       break;
+               }
+       }
+       close(s);
+}
+/* end sadb_add */
+
+int
+main(int argc, char **argv)
+{
+       struct addrinfo hints, *src, *dst;
+       unsigned char *p, *keydata, *kp;
+       char *ep;
+       int ret, len, i;
+       int satype, alg, keybits;
+
+       bzero(&hints, sizeof(hints));
+       if ((ret = getaddrinfo(argv[1], NULL, &hints, &src)) != 0) {
+               err_quit("%s: %s\n", argv[1], gai_strerror(ret));
+       }
+       if ((ret = getaddrinfo(argv[2], NULL, &hints, &dst)) != 0) {
+               err_quit("%s: %s\n", argv[2], gai_strerror(ret));
+       }
+       if (src->ai_family != dst->ai_family) {
+               err_quit("%s and %s not same addr family\n", argv[1], argv[2]);
+       }
+       satype = SADB_SATYPE_AH;
+       if ((alg = getsaalgbyname(satype, argv[3])) < 0) {
+               err_quit("Unknown SA type / algorithm pair ah/%s\n", argv[3]);
+       }
+       keybits = strtoul(argv[4], &ep, 0);
+       if (ep == argv[4] || *ep != '\0' || (keybits % 8) != 0) {
+               err_quit("Invalid number of bits %s\n", argv[4]);
+       }
+       p = argv[5];
+       if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
+               p += 2;
+       len = strlen(p);
+       kp = keydata = malloc(keybits / 8);
+       for (i = 0; i < keybits; i += 8) {
+               int c;
+
+               if (len < 2) {
+                       err_quit("%s: not enough bytes (expected %d)\n", argv[5], keybits / 8);
+               }
+               if (sscanf(p, "%2x", &c) != 1) {
+                       err_quit("%s contains invalid hex digit\n", argv[5]);
+               }
+               *kp++ = c;
+               p += 2;
+               len -= 2;
+       }
+       if (len > 0) {
+               err_quit("%s: too many bytes (expected %d)\n", argv[5], keybits / 8);
+       }
+       sadb_add(src->ai_addr, dst->ai_addr, satype, alg, 0x9876, keybits, keydata);
+}
diff --git a/key/dump.c b/key/dump.c
new file mode 100644 (file)
index 0000000..25ba3c6
--- /dev/null
@@ -0,0 +1,63 @@
+#include "unp.h"
+#include <net/pfkeyv2.h>
+
+/* include sadb_dump */
+void
+sadb_dump(int type)
+{
+       int s;
+       char buf[4096];
+       struct sadb_msg msg;
+       int goteof;
+
+       s = Socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
+
+       /* Build and write SADB_DUMP request */
+       bzero(&msg, sizeof(msg));
+       msg.sadb_msg_version = PF_KEY_V2;
+       msg.sadb_msg_type = SADB_DUMP;
+       msg.sadb_msg_satype = type;
+       msg.sadb_msg_len = sizeof(msg) / 8;
+       msg.sadb_msg_pid = getpid();
+       printf("Sending dump message:\n");
+       print_sadb_msg(&msg, sizeof(msg));
+       Write(s, &msg, sizeof(msg));
+
+       printf("\nMessages returned:\n");
+       /* Read and print SADB_DUMP replies until done */
+       goteof = 0;
+       while (goteof == 0) {
+               int msglen;
+               struct sadb_msg *msgp;
+
+               msglen = Read(s, &buf, sizeof(buf));
+               msgp = (struct sadb_msg *)&buf;
+               print_sadb_msg(msgp, msglen);
+               if (msgp->sadb_msg_seq == 0)
+                       goteof = 1;
+       }
+       close(s);
+}
+
+int
+main(int argc, char **argv)
+{
+       int satype = SADB_SATYPE_UNSPEC;
+       int c;
+
+       opterr = 0;             /* don't want getopt() writing to stderr */
+       while ( (c = getopt(argc, argv, "t:")) != -1) {
+               switch (c) {
+               case 't':
+                       if ((satype = getsatypebyname(optarg)) == -1)
+                               err_quit("invalid -t option %s", optarg);
+                       break;
+
+               default:
+                       err_quit("unrecognized option: %c", c);
+               }
+       }
+
+       sadb_dump(satype);
+}
+/* end sadb_dump */
diff --git a/key/name.c b/key/name.c
new file mode 100644 (file)
index 0000000..b39cd39
--- /dev/null
@@ -0,0 +1,59 @@
+#include "unp.h"
+#include <net/pfkeyv2.h>
+
+struct idlist {
+       int val;
+       const char *name;
+};
+
+static struct idlist satype[] = {
+       { SADB_SATYPE_UNSPEC,   "unspec" },
+       { SADB_SATYPE_AH,               "ah" },
+       { SADB_SATYPE_ESP,              "esp" },
+       { SADB_SATYPE_RSVP,             "rsvp" },
+       { SADB_SATYPE_OSPFV2,   "ospfv2" },
+       { SADB_SATYPE_RIPV2,    "ripv2" },
+       { SADB_SATYPE_MIP,              "mip" },
+       { 0,                                    NULL } };
+
+static struct idlist ahalg[] = {
+       { SADB_AALG_NONE,               "none" },
+       { SADB_AALG_MD5HMAC,    "HMAC-MD5-96" },
+       { SADB_AALG_SHA1HMAC,   "HMAC-SHA-1-96" },
+       { 0,                                    NULL } };
+
+static struct idlist espalg[] = {
+       { SADB_EALG_NONE,               "none" },
+       { SADB_EALG_DESCBC,             "DES-CBC" },
+       { SADB_EALG_3DESCBC,    "3DES-CBC" },
+       { SADB_EALG_NULL,               "NULL" },
+       { 0,                                    NULL } };
+
+int
+idlistlookup(char *name, struct idlist *il)
+{
+       for (; il->name != NULL; il++) {
+               if (strcmp(name, il->name) == 0)
+                       return il->val;
+       }
+       return -1;
+}
+
+int
+getsatypebyname(char *name)
+{
+       return idlistlookup(name, satype);
+}
+
+int
+getsaalgbyname(int type, char *name)
+{
+       switch (type) {
+       case SADB_SATYPE_AH:
+               return idlistlookup(name, ahalg);
+       case SADB_SATYPE_ESP:
+               return idlistlookup(name, espalg);
+       default:
+               return -1;
+       }
+}
diff --git a/key/printsadbmsg.c b/key/printsadbmsg.c
new file mode 100644 (file)
index 0000000..76ab4d6
--- /dev/null
@@ -0,0 +1,297 @@
+#include "unp.h"
+#include <net/pfkeyv2.h>
+
+const char *
+get_sadb_msg_type(int type)
+{
+       static char buf[100];
+       switch (type) {
+       case SADB_RESERVED:     return "Reserved";
+       case SADB_GETSPI:       return "Get SPI";
+       case SADB_UPDATE:       return "Update";
+       case SADB_ADD:          return "Add";
+       case SADB_DELETE:       return "Delete";
+       case SADB_GET:          return "Get";
+       case SADB_ACQUIRE:      return "Acquire";
+       case SADB_REGISTER:     return "Register";
+       case SADB_EXPIRE:       return "Expire";
+       case SADB_FLUSH:        return "Flush";
+       case SADB_DUMP:         return "Dump";
+       default:                        sprintf(buf, "[Unknown type %d]", type);
+                                               return buf;
+       }
+}
+
+const char *
+get_sadb_satype(int type)
+{
+       static char buf[100];
+       switch (type) {
+       case SADB_SATYPE_UNSPEC:        return "Unspecified";
+       case SADB_SATYPE_AH:            return "IPsec AH";
+       case SADB_SATYPE_ESP:           return "IPsec ESP";
+       case SADB_SATYPE_RSVP:          return "RSVP";
+       case SADB_SATYPE_OSPFV2:        return "OSPFv2";
+       case SADB_SATYPE_RIPV2:         return "RIPv2";
+       case SADB_SATYPE_MIP:           return "Mobile IP";
+       default:                                        sprintf(buf, "[Unknown satype %d]", type);
+                                                               return buf;
+       }
+}
+
+const char *
+get_auth_alg(int alg)
+{
+       static char buf[100];
+       switch (alg) {
+       case SADB_AALG_NONE:            return "None";
+       case SADB_AALG_MD5HMAC:         return "HMAC-MD5";
+       case SADB_AALG_SHA1HMAC:        return "HMAC-SHA-1";
+#ifdef SADB_X_AALG_MD5
+       case SADB_X_AALG_MD5:           return "Keyed MD5";
+#endif
+#ifdef SADB_X_AALG_SHA
+       case SADB_X_AALG_SHA:           return "Keyed SHA-1";
+#endif
+#ifdef SADB_X_AALG_NULL
+       case SADB_X_AALG_NULL:          return "Null";
+#endif
+#ifdef SADB_X_AALG_SHA2_256
+       case SADB_X_AALG_SHA2_256:      return "SHA2-256";
+#endif
+#ifdef SADB_X_AALG_SHA2_384
+       case SADB_X_AALG_SHA2_384:      return "SHA2-384";
+#endif
+#ifdef SADB_X_AALG_SHA2_512
+       case SADB_X_AALG_SHA2_512:      return "SHA2-512";
+#endif
+       default:                                        sprintf(buf, "[Unknown authentication algorithm %d]", alg);
+                                                               return buf;
+       }
+}
+
+const char *
+get_encrypt_alg(int alg)
+{
+       static char buf[100];
+       switch (alg) {
+       case SADB_EALG_NONE:            return "None";
+       case SADB_EALG_DESCBC:          return "DES-CBC";
+       case SADB_EALG_3DESCBC:         return "3DES-CBC";
+       case SADB_EALG_NULL:            return "Null";
+#ifdef SADB_X_EALG_CAST128CBC
+       case SADB_X_EALG_CAST128CBC:    return "CAST128-CBC";
+#endif
+#ifdef SADB_X_EALG_BLOWFISHCBC
+       case SADB_X_EALG_BLOWFISHCBC:   return "Blowfish-CBC";
+#endif
+#ifdef SADB_X_EALG_AES
+       case SADB_X_EALG_AES:                   return "AES";
+#endif
+       default:                                        sprintf(buf, "[Unknown encryption algorithm %d]", alg);
+                                                               return buf;
+       }
+}
+
+const char *
+get_sa_state(int state)
+{
+       static char buf[100];
+       switch (state) {
+       case SADB_SASTATE_LARVAL:       return "Larval";
+       case SADB_SASTATE_MATURE:       return "Mature";
+       case SADB_SASTATE_DYING:        return "Dying";
+       case SADB_SASTATE_DEAD:         return "Dead";
+       default:                                        sprintf(buf, "[Unknown SA state %d]", state);
+                                                               return buf;
+       }
+}
+
+const char *
+get_sadb_alg_type(int alg, int authenc)
+{
+       if (authenc == SADB_EXT_SUPPORTED_AUTH) {
+               return get_auth_alg(alg);
+       } else {
+               return get_encrypt_alg(alg);
+       }
+}
+
+void
+sa_print(struct sadb_ext *ext)
+{
+       struct sadb_sa *sa = (struct sadb_sa *)ext;
+       printf(" SA: SPI=%d Replay Window=%d State=%s\n",
+               sa->sadb_sa_spi, sa->sadb_sa_replay,
+               get_sa_state(sa->sadb_sa_state));
+       printf("  Authentication Algorithm: %s\n",
+               get_auth_alg(sa->sadb_sa_auth));
+       printf("  Encryption Algorithm: %s\n",
+               get_encrypt_alg(sa->sadb_sa_encrypt));
+       if (sa->sadb_sa_flags & SADB_SAFLAGS_PFS)
+               printf("  Perfect Forward Secrecy\n");
+}
+
+void
+supported_print(struct sadb_ext *ext)
+{
+       struct sadb_supported *sup = (struct sadb_supported *)ext;
+       struct sadb_alg *alg;
+       int len;
+
+       printf(" Supported %s algorithms:\n",
+               sup->sadb_supported_exttype == SADB_EXT_SUPPORTED_AUTH ?
+               "authentication" :
+               "encryption");
+       len = sup->sadb_supported_len * 8;
+       len -= sizeof(*sup);
+       if (len == 0) {
+               printf("  None\n");
+               return;
+       }
+       for (alg = (struct sadb_alg *)(sup + 1); len>0; len -= sizeof(*alg), alg++) {
+               printf("  %s ivlen %d bits %d-%d\n",
+                       get_sadb_alg_type(alg->sadb_alg_id, sup->sadb_supported_exttype),
+                       alg->sadb_alg_ivlen, alg->sadb_alg_minbits, alg->sadb_alg_maxbits);
+       }
+}
+
+void
+lifetime_print(struct sadb_ext *ext)
+{
+       struct sadb_lifetime *life = (struct sadb_lifetime *)ext;
+
+       printf(" %s lifetime:\n",
+               life->sadb_lifetime_exttype == SADB_EXT_LIFETIME_CURRENT ?
+               "Current" :
+               life->sadb_lifetime_exttype == SADB_EXT_LIFETIME_HARD ?
+               "Hard" :
+               "Soft");
+       printf("  %d allocations, %d bytes", life->sadb_lifetime_allocations,
+               life->sadb_lifetime_bytes);
+       if (life->sadb_lifetime_exttype == SADB_EXT_LIFETIME_CURRENT) {
+               time_t t;
+               struct tmp *tm;
+               char buf[100];
+
+               /* absolute times */
+               t = life->sadb_lifetime_addtime;
+               tm = localtime(&t);
+               strftime(buf, sizeof(buf), "%c", tm);
+               printf("\n  added at %s, ", buf);
+               if (life->sadb_lifetime_usetime == 0) {
+                       printf("never used\n");
+               } else {
+                       t = life->sadb_lifetime_usetime;
+                       tm = localtime(&t);
+                       strftime(buf, sizeof(buf), "%c", tm);
+                       printf("first used at %s\n", buf);
+               }
+       } else {
+               printf("%d addtime, %d usetime\n", life->sadb_lifetime_addtime,
+                       life->sadb_lifetime_usetime);
+       }
+}
+
+void
+address_print(struct sadb_ext *ext)
+{
+       struct sadb_address *addr = (struct sadb_address *)ext;
+       struct sockaddr *sa;
+
+       printf(" %s address: ",
+               addr->sadb_address_exttype == SADB_EXT_ADDRESS_SRC ?
+               "Source" :
+               addr->sadb_address_exttype == SADB_EXT_ADDRESS_DST ?
+               "Dest" :
+               "Proxy");
+       sa = (struct sockaddr *)(addr + 1);
+       printf("  %s", sock_ntop(sa, addr->sadb_address_len * 8 - sizeof(*addr)));
+       if (addr->sadb_address_prefixlen == 0)
+               printf(" ");
+       else
+               printf("/%d ", addr->sadb_address_prefixlen);
+       switch (addr->sadb_address_proto) {
+               case IPPROTO_UDP:       printf("(UDP)"); break;
+               case IPPROTO_TCP:       printf("(TCP)"); break;
+               case 0:                         break;
+               default:                        printf("(IP proto %d)", addr->sadb_address_proto);
+                                                       break;
+       }
+       printf("\n");
+}
+
+void
+key_print(struct sadb_ext *ext)
+{
+       struct sadb_key *key = (struct sadb_key *)ext;
+       int bits;
+       unsigned char *p;
+
+       printf(" %s key, %d bits: 0x",
+               key->sadb_key_exttype == SADB_EXT_KEY_AUTH ?
+               "Authentication" : "Encryption",
+               key->sadb_key_bits);
+       for (p = (unsigned char *)(key + 1), bits = key->sadb_key_bits;
+                       bits > 0; p++, bits -= 8)
+               printf("%02x", *p);
+       printf("\n");
+}
+
+void
+print_sadb_msg(struct sadb_msg *msg, int msglen)
+{
+       struct sadb_ext *ext;
+
+       if (msglen != msg->sadb_msg_len * 8) {
+               err_msg("SADB Message length (%d) doesn't match msglen (%d)\n",
+                       msg->sadb_msg_len * 8, msglen);
+               return;
+       }
+       if (msg->sadb_msg_version != PF_KEY_V2) {
+               err_msg("SADB Message version not PF_KEY_V2\n");
+               return;
+       }
+       printf("SADB Message %s, errno %d, satype %s, seq %d, pid %d\n",
+               get_sadb_msg_type(msg->sadb_msg_type), msg->sadb_msg_errno,
+               get_sadb_satype(msg->sadb_msg_satype), msg->sadb_msg_seq,
+               msg->sadb_msg_pid);
+       if (msg->sadb_msg_errno != 0)
+               printf(" errno %s\n", strerror(msg->sadb_msg_errno));
+       if (msglen == sizeof(struct sadb_msg))
+               return; /* no extensions */
+       msglen -= sizeof(struct sadb_msg);
+       ext = (struct sadb_ext *)(msg + 1);
+       while (msglen > 0) {
+               switch (ext->sadb_ext_type) {
+               case SADB_EXT_RESERVED: printf(" Reserved Extension\n"); break;
+               case SADB_EXT_SA:       sa_print(ext); break;
+               case SADB_EXT_LIFETIME_CURRENT:
+               case SADB_EXT_LIFETIME_HARD:
+               case SADB_EXT_LIFETIME_SOFT:
+                                       lifetime_print(ext); break;
+               case SADB_EXT_ADDRESS_SRC:
+               case SADB_EXT_ADDRESS_DST:
+               case SADB_EXT_ADDRESS_PROXY:
+                                       address_print(ext); break;
+               case SADB_EXT_KEY_AUTH:
+               case SADB_EXT_KEY_ENCRYPT:
+                                       key_print(ext); break;
+               case SADB_EXT_IDENTITY_SRC:
+               case SADB_EXT_IDENTITY_DST:
+                                       printf(" [identity...]\n"); break;
+               case SADB_EXT_SENSITIVITY:
+                                       printf(" [sensitivity...]\n"); break;
+               case SADB_EXT_PROPOSAL:
+                                       printf(" [proposal...]\n"); break;
+               case SADB_EXT_SUPPORTED_AUTH:
+               case SADB_EXT_SUPPORTED_ENCRYPT:
+                                       supported_print(ext); break;
+               case SADB_EXT_SPIRANGE:
+                                       printf(" [spirange...]\n"); break;
+               default:        printf(" [unknown extension %d]\n", ext->sadb_ext_type);
+               }
+               msglen -= ext->sadb_ext_len << 3;
+               ext = (char *)ext + (ext->sadb_ext_len << 3);
+       }
+}
diff --git a/key/register.c b/key/register.c
new file mode 100644 (file)
index 0000000..64620b5
--- /dev/null
@@ -0,0 +1,71 @@
+#include "unp.h"
+#include <net/pfkeyv2.h>
+
+/* include sadb_register */
+void
+sadb_register(int type)
+{
+       int s;
+       char buf[4096]; /* XXX */
+       struct sadb_msg msg;
+       int goteof;
+       int mypid;
+
+       s = Socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
+
+       mypid = getpid();
+
+       /* Build and write SADB_REGISTER request */
+       bzero(&msg, sizeof(msg));
+       msg.sadb_msg_version = PF_KEY_V2;
+       msg.sadb_msg_type = SADB_REGISTER;
+       msg.sadb_msg_satype = type;
+       msg.sadb_msg_len = sizeof(msg) / 8;
+       msg.sadb_msg_pid = mypid;
+       printf("Sending register message:\n");
+       print_sadb_msg(&msg, sizeof(msg));
+       Write(s, &msg, sizeof(msg));
+
+       printf("\nReply returned:\n");
+       /* Read and print SADB_REGISTER reply, discarding any others */
+       for (;;) {
+               int msglen;
+               struct sadb_msg *msgp;
+
+               msglen = Read(s, &buf, sizeof(buf));
+               msgp = (struct sadb_msg *)&buf;
+               if (msgp->sadb_msg_pid == mypid &&
+                       msgp->sadb_msg_type == SADB_REGISTER) {
+                       print_sadb_msg(msgp, msglen);
+                       break;
+               }
+       }
+       close(s);
+}
+/* end sadb_register */
+
+int
+main(int argc, char **argv)
+{
+       int satype = SADB_SATYPE_UNSPEC;
+       int c;
+
+       opterr = 0;             /* don't want getopt() writing to stderr */
+       while ( (c = getopt(argc, argv, "t:")) != -1) {
+               switch (c) {
+               case 't':
+                       if ((satype = getsatypebyname(optarg)) == -1)
+                               err_quit("invalid -t option %s", optarg);
+                       break;
+
+               default:
+                       err_quit("unrecognized option: %c", c);
+               }
+       }
+
+       if (satype == SADB_SATYPE_UNSPEC) {
+               err_quit("must specify SA type");
+       }
+
+       sadb_register(satype);
+}
diff --git a/key/unp.h b/key/unp.h
new file mode 100644 (file)
index 0000000..45669cf
--- /dev/null
+++ b/key/unp.h
@@ -0,0 +1,467 @@
+/* include unph */
+/* Our own header.  Tabs are set for 4 spaces, not 8 */
+
+#ifndef        __unp_h
+#define        __unp_h
+
+#include       "../config.h"   /* configuration options for current OS */
+                                                       /* "../config.h" is generated by configure */
+
+/* If anything changes in the following list of #includes, must change
+   acsite.m4 also, for configure's tests. */
+
+#include       <sys/types.h>   /* basic system data types */
+#include       <sys/socket.h>  /* basic socket definitions */
+#include       <sys/time.h>    /* timeval{} for select() */
+#include       <time.h>                /* timespec{} for pselect() */
+#include       <netinet/in.h>  /* sockaddr_in{} and other Internet defns */
+#include       <arpa/inet.h>   /* inet(3) functions */
+#include       <errno.h>
+#include       <fcntl.h>               /* for nonblocking */
+#include       <netdb.h>
+#include       <signal.h>
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+#include       <sys/stat.h>    /* for S_xxx file mode constants */
+#include       <sys/uio.h>             /* for iovec{} and readv/writev */
+#include       <unistd.h>
+#include       <sys/wait.h>
+#include       <sys/un.h>              /* for Unix domain sockets */
+
+#ifdef HAVE_SYS_SELECT_H
+# include      <sys/select.h>  /* for convenience */
+#endif
+
+#ifdef HAVE_SYS_SYSCTL_H
+# include      <sys/sysctl.h>
+#endif
+
+#ifdef HAVE_POLL_H
+# include      <poll.h>                /* for convenience */
+#endif
+
+#ifdef HAVE_STRINGS_H
+# include      <strings.h>             /* for convenience */
+#endif
+
+/* Three headers are normally needed for socket/file ioctl's:
+ * <sys/ioctl.h>, <sys/filio.h>, and <sys/sockio.h>.
+ */
+#ifdef HAVE_SYS_IOCTL_H
+# include      <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include      <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include      <sys/sockio.h>
+#endif
+
+#ifdef HAVE_PTHREAD_H
+# include      <pthread.h>
+#endif
+
+#ifdef HAVE_NET_IF_DL_H
+# include      <net/if_dl.h>
+#endif
+
+/* OSF/1 actually disables recv() and send() in <sys/socket.h> */
+#ifdef __osf__
+#undef recv
+#undef send
+#define        recv(a,b,c,d)   recvfrom(a,b,c,d,0,0)
+#define        send(a,b,c,d)   sendto(a,b,c,d,0,0)
+#endif
+
+#ifndef        INADDR_NONE
+/* $$.Ic INADDR_NONE$$ */
+#define        INADDR_NONE     0xffffffff      /* should have been in <netinet/in.h> */
+#endif
+
+#ifndef        SHUT_RD                         /* these three Posix.1g names are quite new */
+#define        SHUT_RD         0       /* shutdown for reading */
+#define        SHUT_WR         1       /* shutdown for writing */
+#define        SHUT_RDWR       2       /* shutdown for reading and writing */
+/* $$.Ic SHUT_RD$$ */
+/* $$.Ic SHUT_WR$$ */
+/* $$.Ic SHUT_RDWR$$ */
+#endif
+
+/* *INDENT-OFF* */
+#ifndef INET_ADDRSTRLEN
+/* $$.Ic INET_ADDRSTRLEN$$ */
+#define        INET_ADDRSTRLEN         16      /* "ddd.ddd.ddd.ddd\0"
+                                                                   1234567890123456 */
+#endif
+
+/* Define following even if IPv6 not supported, so we can always allocate
+   an adequately-sized buffer, without #ifdefs in the code. */
+#ifndef INET6_ADDRSTRLEN
+/* $$.Ic INET6_ADDRSTRLEN$$ */
+#define        INET6_ADDRSTRLEN        46      /* max size of IPv6 address string:
+                                  "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" or
+                                  "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd\0"
+                                   1234567890123456789012345678901234567890123456 */
+#endif
+/* *INDENT-ON* */
+
+/* Define bzero() as a macro if it's not in standard C library. */
+#ifndef        HAVE_BZERO
+#define        bzero(ptr,n)            memset(ptr, 0, n)
+/* $$.If bzero$$ */
+/* $$.If memset$$ */
+#endif
+
+/* Older resolvers do not have gethostbyname2() */
+#ifndef        HAVE_GETHOSTBYNAME2
+#define        gethostbyname2(host,family)             gethostbyname((host))
+#endif
+
+/* The structure returned by recvfrom_flags() */
+struct in_pktinfo {
+  struct in_addr       ipi_addr;       /* dst IPv4 address */
+  int                          ipi_ifindex;/* received interface index */
+};
+/* $$.It in_pktinfo$$ */
+/* $$.Ib ipi_addr$$ */
+/* $$.Ib ipi_ifindex$$ */
+
+/* We need the newer CMSG_LEN() and CMSG_SPACE() macros, but few
+   implementations support them today.  These two macros really need
+    an ALIGN() macro, but each implementation does this differently. */
+#ifndef        CMSG_LEN
+/* $$.Ic CMSG_LEN$$ */
+#define        CMSG_LEN(size)          (sizeof(struct cmsghdr) + (size))
+#endif
+#ifndef        CMSG_SPACE
+/* $$.Ic CMSG_SPACE$$ */
+#define        CMSG_SPACE(size)        (sizeof(struct cmsghdr) + (size))
+#endif
+
+/* Posix.1g requires the SUN_LEN() macro but not all implementations DefinE
+   it (yet).  Note that this 4.4BSD macro works regardless whether there is
+   a length field or not. */
+#ifndef        SUN_LEN
+/* $$.Im SUN_LEN$$ */
+# define       SUN_LEN(su) \
+       (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
+#endif
+
+/* Posix.1g renames "Unix domain" as "local IPC".
+   But not all systems DefinE AF_LOCAL and PF_LOCAL (yet). */
+#ifndef        AF_LOCAL
+#define AF_LOCAL       AF_UNIX
+#endif
+#ifndef        PF_LOCAL
+#define PF_LOCAL       PF_UNIX
+#endif
+
+/* Posix.1g requires that an #include of <poll.h> DefinE INFTIM, but many
+   systems still DefinE it in <sys/stropts.h>.  We don't want to include
+   all the streams stuff if it's not needed, so we just DefinE INFTIM here.
+   This is the standard value, but there's no guarantee it is -1. */
+#ifndef INFTIM
+#define INFTIM          (-1)    /* infinite poll timeout */
+/* $$.Ic INFTIM$$ */
+#ifdef HAVE_POLL_H
+#define        INFTIM_UNPH                             /* tell unpxti.h we defined it */
+#endif
+#endif
+
+/* Following could be derived from SOMAXCONN in <sys/socket.h>, but many
+   kernels still #define it as 5, while actually supporting many more */
+#define        LISTENQ         1024    /* 2nd argument to listen() */
+
+/* Miscellaneous constants */
+#define        MAXLINE         4096    /* max text line length */
+#define        MAXSOCKADDR  128        /* max socket address structure size */
+#define        BUFFSIZE        8192    /* buffer size for reads and writes */
+
+/* Define some port number that can be used for client-servers */
+#define        SERV_PORT                9877                   /* TCP and UDP client-servers */
+#define        SERV_PORT_STR   "9877"                  /* TCP and UDP client-servers */
+#define        UNIXSTR_PATH    "/tmp/unix.str" /* Unix domain stream cli-serv */
+#define        UNIXDG_PATH             "/tmp/unix.dg"  /* Unix domain datagram cli-serv */
+/* $$.ix [LISTENQ]~constant,~definition~of$$ */
+/* $$.ix [MAXLINE]~constant,~definition~of$$ */
+/* $$.ix [MAXSOCKADDR]~constant,~definition~of$$ */
+/* $$.ix [BUFFSIZE]~constant,~definition~of$$ */
+/* $$.ix [SERV_PORT]~constant,~definition~of$$ */
+/* $$.ix [UNIXSTR_PATH]~constant,~definition~of$$ */
+/* $$.ix [UNIXDG_PATH]~constant,~definition~of$$ */
+
+/* Following shortens all the type casts of pointer arguments */
+#define        SA      struct sockaddr
+
+#define        FILE_MODE       (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
+                                       /* default file access permissions for new files */
+#define        DIR_MODE        (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)
+                                       /* default permissions for new directories */
+
+typedef        void    Sigfunc(int);   /* for signal handlers */
+
+#define        min(a,b)        ((a) < (b) ? (a) : (b))
+#define        max(a,b)        ((a) > (b) ? (a) : (b))
+
+#ifndef        HAVE_ADDRINFO_STRUCT
+# include      "../lib/addrinfo.h"
+#endif
+
+#ifndef        HAVE_IF_NAMEINDEX_STRUCT
+struct if_nameindex {
+  unsigned int   if_index;  /* 1, 2, ... */
+  char          *if_name;   /* null terminated name: "le0", ... */
+};
+/* $$.It if_nameindex$$ */
+/* $$.Ib if_index$$ */
+/* $$.Ib if_name$$ */
+#endif
+
+#ifndef        HAVE_TIMESPEC_STRUCT
+struct timespec {
+  time_t       tv_sec;         /* seconds */
+  long         tv_nsec;        /* and nanoseconds */
+};
+/* $$.It timespec$$ */
+/* $$.Ib tv_sec$$ */
+/* $$.Ib tv_nsec$$ */
+#endif
+/* end unph */
+
+                       /* prototypes for our own library functions */
+int             connect_nonb(int, const SA *, socklen_t, int);
+int             connect_timeo(int, const SA *, socklen_t, int);
+void    daemon_init(const char *, int);
+void    daemon_inetd(const char *, int);
+void    dg_cli(FILE *, int, const SA *, socklen_t);
+void    dg_echo(int, SA *, socklen_t);
+int             family_to_level(int);
+char   *gf_time(void);
+void    heartbeat_cli(int, int, int);
+void    heartbeat_serv(int, int, int);
+struct addrinfo *host_serv(const char *, const char *, int, int);
+int             inet_srcrt_add(char *, int);
+u_char  *inet_srcrt_init(void);
+void    inet_srcrt_print(u_char *, int);
+char   **my_addrs(int *);
+int             readable_timeo(int, int);
+ssize_t         readline(int, void *, size_t);
+ssize_t         readn(int, void *, size_t);
+ssize_t         read_fd(int, void *, size_t, int *);
+ssize_t         recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *,
+                struct in_pktinfo *);
+Sigfunc *signal_intr(int, Sigfunc *);
+int             sock_bind_wild(int, int);
+int             sock_cmp_addr(const SA *, const SA *, socklen_t);
+int             sock_cmp_port(const SA *, const SA *, socklen_t);
+int             sock_get_port(const SA *, socklen_t);
+void    sock_set_addr(SA *, socklen_t, const void *);
+void    sock_set_port(SA *, socklen_t, int);
+void    sock_set_wild(SA *, socklen_t);
+char   *sock_ntop(const SA *, socklen_t);
+char   *sock_ntop_host(const SA *, socklen_t);
+int             sockfd_to_family(int);
+void    str_echo(int);
+void    str_cli(FILE *, int);
+int             tcp_connect(const char *, const char *);
+int             tcp_listen(const char *, const char *, socklen_t *);
+void    tv_sub(struct timeval *, struct timeval *);
+int             udp_client(const char *, const char *, void **, socklen_t *);
+int             udp_connect(const char *, const char *);
+int             udp_server(const char *, const char *, socklen_t *);
+int             writable_timeo(int, int);
+ssize_t         writen(int, const void *, size_t);
+ssize_t         write_fd(int, void *, size_t, int);
+
+#ifdef MCAST
+int             mcast_leave(int, const SA *, socklen_t);
+int             mcast_join(int, const SA *, socklen_t, const char *, u_int);
+int             mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen,
+                                                                 const SA *grp, socklen_t grplen);
+int             mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen,
+                                                                const SA *grp, socklen_t grplen,
+                                                                const char *ifname, u_int ifindex);
+int             mcast_block_source(int sockfd, const SA *src, socklen_t srclen,
+                                                       const SA *grp, socklen_t grplen);
+int             mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen,
+                                                         const SA *grp, socklen_t grplen);
+int             mcast_get_if(int);
+int             mcast_get_loop(int);
+int             mcast_get_ttl(int);
+int             mcast_set_if(int, const char *, u_int);
+int             mcast_set_loop(int, int);
+int             mcast_set_ttl(int, int);
+
+void    Mcast_leave(int, const SA *, socklen_t);
+void    Mcast_join(int, const SA *, socklen_t, const char *, u_int);
+void    Mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen,
+                                                                 const SA *grp, socklen_t grplen);
+void    Mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen,
+                                                                const SA *grp, socklen_t grplen,
+                                                                const char *ifname, u_int ifindex);
+void    Mcast_block_source(int sockfd, const SA *src, socklen_t srclen,
+                                                       const SA *grp, socklen_t grplen);
+void    Mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen,
+                                                         const SA *grp, socklen_t grplen);
+int             Mcast_get_if(int);
+int             Mcast_get_loop(int);
+int             Mcast_get_ttl(int);
+void    Mcast_set_if(int, const char *, u_int);
+void    Mcast_set_loop(int, int);
+void    Mcast_set_ttl(int, int);
+#endif
+
+unsigned short in_cksum(unsigned short *, int);
+
+#ifndef        HAVE_GETADDRINFO_PROTO
+int             getaddrinfo(const char *, const char *, const struct addrinfo *,
+                                        struct addrinfo **);
+void    freeaddrinfo(struct addrinfo *);
+char   *gai_strerror(int);
+#endif
+
+#ifndef        HAVE_GETNAMEINFO_PROTO
+int             getnameinfo(const SA *, socklen_t, char *, size_t, char *, size_t, int);
+#endif
+
+#ifndef        HAVE_GETHOSTNAME_PROTO
+int             gethostname(char *, int);
+#endif
+
+#ifndef        HAVE_HSTRERROR_PROTO
+const char     *hstrerror(int);
+#endif
+
+#ifndef        HAVE_IF_NAMETOINDEX_PROTO
+unsigned int    if_nametoindex(const char *);
+char                   *if_indextoname(unsigned int, char *);
+void                    if_freenameindex(struct if_nameindex *);
+struct if_nameindex *if_nameindex(void);
+#endif
+
+#ifndef        HAVE_INET_PTON_PROTO
+int                     inet_pton(int, const char *, void *);
+const char     *inet_ntop(int, const void *, char *, size_t);
+#endif
+
+#ifndef        HAVE_INET_ATON_PROTO
+int             inet_aton(const char *, struct in_addr *);
+#endif
+
+#ifndef        HAVE_ISFDTYPE_PROTO
+int             isfdtype(int, int);
+#endif
+
+#ifndef        HAVE_PSELECT_PROTO
+int             pselect(int, fd_set *, fd_set *, fd_set *,
+                                const struct timespec *, const sigset_t *);
+#endif
+
+#ifndef        HAVE_SOCKATMARK_PROTO
+int             sockatmark(int);
+#endif
+
+#ifndef        HAVE_SNPRINTF_PROTO
+int             snprintf(char *, size_t, const char *, ...);
+#endif
+
+                       /* prototypes for our own library wrapper functions */
+void    Connect_timeo(int, const SA *, socklen_t, int);
+int             Family_to_level(int);
+struct addrinfo *Host_serv(const char *, const char *, int, int);
+const char             *Inet_ntop(int, const void *, char *, size_t);
+void                    Inet_pton(int, const char *, void *);
+char                   *If_indextoname(unsigned int, char *);
+unsigned int            If_nametoindex(const char *);
+struct if_nameindex    *If_nameindex(void);
+char   **My_addrs(int *);
+ssize_t         Read_fd(int, void *, size_t, int *);
+int             Readable_timeo(int, int);
+ssize_t         Recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *,
+                struct in_pktinfo *);
+Sigfunc *Signal(int, Sigfunc *);
+Sigfunc *Signal_intr(int, Sigfunc *);
+int             Sock_bind_wild(int, int);
+char   *Sock_ntop(const SA *, socklen_t);
+char   *Sock_ntop_host(const SA *, socklen_t);
+int             Sockfd_to_family(int);
+int             Tcp_connect(const char *, const char *);
+int             Tcp_listen(const char *, const char *, socklen_t *);
+int             Udp_client(const char *, const char *, void **, socklen_t *);
+int             Udp_connect(const char *, const char *);
+int             Udp_server(const char *, const char *, socklen_t *);
+ssize_t         Write_fd(int, void *, size_t, int);
+int             Writable_timeo(int, int);
+
+                       /* prototypes for our Unix wrapper functions: see {Sec errors} */
+void   *Calloc(size_t, size_t);
+void    Close(int);
+void    Dup2(int, int);
+int             Fcntl(int, int, int);
+void    Gettimeofday(struct timeval *, void *);
+int             Ioctl(int, int, void *);
+pid_t   Fork(void);
+void   *Malloc(size_t);
+int     Mkstemp(char *);
+void   *Mmap(void *, size_t, int, int, int, off_t);
+int             Open(const char *, int, mode_t);
+void    Pipe(int *fds);
+ssize_t         Read(int, void *, size_t);
+void    Sigaddset(sigset_t *, int);
+void    Sigdelset(sigset_t *, int);
+void    Sigemptyset(sigset_t *);
+void    Sigfillset(sigset_t *);
+int             Sigismember(const sigset_t *, int);
+void    Sigpending(sigset_t *);
+void    Sigprocmask(int, const sigset_t *, sigset_t *);
+char   *Strdup(const char *);
+long    Sysconf(int);
+void    Sysctl(int *, u_int, void *, size_t *, void *, size_t);
+void    Unlink(const char *);
+pid_t   Wait(int *);
+pid_t   Waitpid(pid_t, int *, int);
+void    Write(int, void *, size_t);
+
+                       /* prototypes for our stdio wrapper functions: see {Sec errors} */
+void    Fclose(FILE *);
+FILE   *Fdopen(int, const char *);
+char   *Fgets(char *, int, FILE *);
+FILE   *Fopen(const char *, const char *);
+void    Fputs(const char *, FILE *);
+
+                       /* prototypes for our socket wrapper functions: see {Sec errors} */
+int             Accept(int, SA *, socklen_t *);
+void    Bind(int, const SA *, socklen_t);
+void    Connect(int, const SA *, socklen_t);
+void    Getpeername(int, SA *, socklen_t *);
+void    Getsockname(int, SA *, socklen_t *);
+void    Getsockopt(int, int, int, void *, socklen_t *);
+int             Isfdtype(int, int);
+void    Listen(int, int);
+#ifdef HAVE_POLL
+int             Poll(struct pollfd *, unsigned long, int);
+#endif
+ssize_t         Readline(int, void *, size_t);
+ssize_t         Readn(int, void *, size_t);
+ssize_t         Recv(int, void *, size_t, int);
+ssize_t         Recvfrom(int, void *, size_t, int, SA *, socklen_t *);
+ssize_t         Recvmsg(int, struct msghdr *, int);
+int             Select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+void    Send(int, const void *, size_t, int);
+void    Sendto(int, const void *, size_t, int, const SA *, socklen_t);
+void    Sendmsg(int, const struct msghdr *, int);
+void    Setsockopt(int, int, int, const void *, socklen_t);
+void    Shutdown(int, int);
+int             Sockatmark(int);
+int             Socket(int, int, int);
+void    Socketpair(int, int, int, int *);
+void    Writen(int, void *, size_t);
+
+void    err_dump(const char *, ...);
+void    err_msg(const char *, ...);
+void    err_quit(const char *, ...);
+void    err_ret(const char *, ...);
+void    err_sys(const char *, ...);
+
+#endif /* __unp_h */
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644 (file)
index 0000000..fa97028
--- /dev/null
@@ -0,0 +1,8 @@
+include ../Make.defines
+
+all:   ${LIB_OBJS}
+               ar rv ${LIBUNP_NAME} $?
+               ${RANLIB} ${LIBUNP_NAME}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/lib/addrinfo.h b/lib/addrinfo.h
new file mode 100644 (file)
index 0000000..7cef135
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef        __addrinfo_h
+#define        __addrinfo_h
+
+/*
+ * Everything here really belongs in <netdb.h>.
+ * These defines are separate for now, to avoid having to modify the
+ * system's header.
+ */
+
+struct addrinfo {
+  int          ai_flags;                       /* AI_PASSIVE, AI_CANONNAME */
+  int          ai_family;                      /* PF_xxx */
+  int          ai_socktype;            /* SOCK_xxx */
+  int          ai_protocol;            /* IPPROTO_xxx for IPv4 and IPv6 */
+  size_t       ai_addrlen;                     /* length of ai_addr */
+  char         *ai_canonname;          /* canonical name for host */
+  struct sockaddr      *ai_addr;       /* binary address */
+  struct addrinfo      *ai_next;       /* next structure in linked list */
+};
+
+                       /* following for getaddrinfo() */
+#define        AI_PASSIVE               1      /* socket is intended for bind() + listen() */
+#define        AI_CANONNAME     2      /* return canonical name */
+
+                       /* following for getnameinfo() */
+#define        NI_MAXHOST        1025  /* max hostname returned */
+#define        NI_MAXSERV          32  /* max service name returned */
+
+#define        NI_NOFQDN            1  /* do not return FQDN */
+#define        NI_NUMERICHOST   2      /* return numeric form of hostname */
+#define        NI_NAMEREQD          4  /* return error if hostname not found */
+#define        NI_NUMERICSERV   8      /* return numeric form of service name */
+#define        NI_DGRAM            16  /* datagram service for getservbyname() */
+
+                       /* error returns */
+#define        EAI_ADDRFAMILY   1      /* address family for host not supported */
+#define        EAI_AGAIN                2      /* temporary failure in name resolution */
+#define        EAI_BADFLAGS     3      /* invalid value for ai_flags */
+#define        EAI_FAIL                 4      /* non-recoverable failure in name resolution */
+#define        EAI_FAMILY               5      /* ai_family not supported */
+#define        EAI_MEMORY               6      /* memory allocation failure */
+#define        EAI_NODATA               7      /* no address associated with host */
+#define        EAI_NONAME               8      /* host nor service provided, or not known */
+#define        EAI_SERVICE              9      /* service not supported for ai_socktype */
+#define        EAI_SOCKTYPE    10      /* ai_socktype not supported */
+#define        EAI_SYSTEM              11      /* system error returned in errno */
+
+#endif /* __addrinfo_h */
diff --git a/lib/connect_nonb.c b/lib/connect_nonb.c
new file mode 100644 (file)
index 0000000..53a92e7
--- /dev/null
@@ -0,0 +1,53 @@
+#include       "unp.h"
+
+int
+connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec)
+{
+       int                             flags, n, error;
+       socklen_t               len;
+       fd_set                  rset, wset;
+       struct timeval  tval;
+
+       flags = Fcntl(sockfd, F_GETFL, 0);
+       Fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+
+       error = 0;
+       if ( (n = connect(sockfd, saptr, salen)) < 0)
+               if (errno != EINPROGRESS)
+                       return(-1);
+
+       /* Do whatever we want while the connect is taking place. */
+
+       if (n == 0)
+               goto done;      /* connect completed immediately */
+
+       FD_ZERO(&rset);
+       FD_SET(sockfd, &rset);
+       wset = rset;
+       tval.tv_sec = nsec;
+       tval.tv_usec = 0;
+
+       if ( (n = Select(sockfd+1, &rset, &wset, NULL,
+                                        nsec ? &tval : NULL)) == 0) {
+               close(sockfd);          /* timeout */
+               errno = ETIMEDOUT;
+               return(-1);
+       }
+
+       if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
+               len = sizeof(error);
+               if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
+                       return(-1);                     /* Solaris pending error */
+       } else
+               err_quit("select error: sockfd not set");
+
+done:
+       Fcntl(sockfd, F_SETFL, flags);  /* restore file status flags */
+
+       if (error) {
+               close(sockfd);          /* just in case */
+               errno = error;
+               return(-1);
+       }
+       return(0);
+}
diff --git a/lib/connect_nonb.lc b/lib/connect_nonb.lc
new file mode 100644 (file)
index 0000000..79f4749
--- /dev/null
@@ -0,0 +1,53 @@
+#include    "unp.h"##  1 ##src/lib/connect_nonb.c##
+
+int##  2 ##src/lib/connect_nonb.c##
+connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec)##  3 ##src/lib/connect_nonb.c##
+{##  4 ##src/lib/connect_nonb.c##
+    int     flags, n, error;##  5 ##src/lib/connect_nonb.c##
+    socklen_t len;##  6 ##src/lib/connect_nonb.c##
+    fd_set  rset, wset;##  7 ##src/lib/connect_nonb.c##
+    struct timeval tval;##  8 ##src/lib/connect_nonb.c##
+
+    flags = Fcntl(sockfd, F_GETFL, 0);##  9 ##src/lib/connect_nonb.c##
+    Fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);## 10 ##src/lib/connect_nonb.c##
+
+    error = 0;## 11 ##src/lib/connect_nonb.c##
+    if ((n = connect(sockfd, saptr, salen)) < 0)## 12 ##src/lib/connect_nonb.c##
+        if (errno != EINPROGRESS)## 13 ##src/lib/connect_nonb.c##
+            return (-1);## 14 ##src/lib/connect_nonb.c##
+
+    /* Do whatever we want while the connect is taking place. */## 15 ##src/lib/connect_nonb.c##
+
+    if (n == 0)## 16 ##src/lib/connect_nonb.c##
+        goto done;              /* connect completed immediately */## 17 ##src/lib/connect_nonb.c##
+
+    FD_ZERO(&rset);## 18 ##src/lib/connect_nonb.c##
+    FD_SET(sockfd, &rset);## 19 ##src/lib/connect_nonb.c##
+    wset = rset;## 20 ##src/lib/connect_nonb.c##
+    tval.tv_sec = nsec;## 21 ##src/lib/connect_nonb.c##
+    tval.tv_usec = 0;## 22 ##src/lib/connect_nonb.c##
+
+    if ((n = Select(sockfd + 1, &rset, &wset, NULL,## 23 ##src/lib/connect_nonb.c##
+                    nsec ? &tval : NULL)) == 0) {## 24 ##src/lib/connect_nonb.c##
+        close(sockfd);          /* timeout */## 25 ##src/lib/connect_nonb.c##
+        errno = ETIMEDOUT;## 26 ##src/lib/connect_nonb.c##
+        return (-1);## 27 ##src/lib/connect_nonb.c##
+    }## 28 ##src/lib/connect_nonb.c##
+
+    if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {## 29 ##src/lib/connect_nonb.c##
+        len = sizeof(error);## 30 ##src/lib/connect_nonb.c##
+        if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)## 31 ##src/lib/connect_nonb.c##
+            return (-1);        /* Solaris pending error */## 32 ##src/lib/connect_nonb.c##
+    } else## 33 ##src/lib/connect_nonb.c##
+        err_quit("select error: sockfd not set");## 34 ##src/lib/connect_nonb.c##
+
+  done:## 35 ##src/lib/connect_nonb.c##
+    Fcntl(sockfd, F_SETFL, flags);  /* restore file status flags */## 36 ##src/lib/connect_nonb.c##
+
+    if (error) {## 37 ##src/lib/connect_nonb.c##
+        close(sockfd);          /* just in case */## 38 ##src/lib/connect_nonb.c##
+        errno = error;## 39 ##src/lib/connect_nonb.c##
+        return (-1);## 40 ##src/lib/connect_nonb.c##
+    }## 41 ##src/lib/connect_nonb.c##
+    return (0);## 42 ##src/lib/connect_nonb.c##
+}## 43 ##src/lib/connect_nonb.c##
diff --git a/lib/connect_timeo.c b/lib/connect_timeo.c
new file mode 100644 (file)
index 0000000..5693ee9
--- /dev/null
@@ -0,0 +1,39 @@
+/* include connect_timeo */
+#include       "unp.h"
+
+static void    connect_alarm(int);
+
+int
+connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int nsec)
+{
+       Sigfunc *sigfunc;
+       int             n;
+
+       sigfunc = Signal(SIGALRM, connect_alarm);
+       if (alarm(nsec) != 0)
+               err_msg("connect_timeo: alarm was already set");
+
+       if ( (n = connect(sockfd, saptr, salen)) < 0) {
+               close(sockfd);
+               if (errno == EINTR)
+                       errno = ETIMEDOUT;
+       }
+       alarm(0);                                       /* turn off the alarm */
+       Signal(SIGALRM, sigfunc);       /* restore previous signal handler */
+
+       return(n);
+}
+
+static void
+connect_alarm(int signo)
+{
+       return;         /* just interrupt the connect() */
+}
+/* end connect_timeo */
+
+void
+Connect_timeo(int fd, const SA *sa, socklen_t salen, int sec)
+{
+       if (connect_timeo(fd, sa, salen, sec) < 0)
+               err_sys("connect_timeo error");
+}
diff --git a/lib/connect_timeo.lc b/lib/connect_timeo.lc
new file mode 100644 (file)
index 0000000..847ab4a
--- /dev/null
@@ -0,0 +1,39 @@
+/* include connect_timeo */
+#include    "unp.h"##  1 ##src/lib/connect_timeo.c##
+
+static void connect_alarm(int);##  2 ##src/lib/connect_timeo.c##
+
+int##  3 ##src/lib/connect_timeo.c##
+connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int nsec)##  4 ##src/lib/connect_timeo.c##
+{##  5 ##src/lib/connect_timeo.c##
+    Sigfunc *sigfunc;##  6 ##src/lib/connect_timeo.c##
+    int     n;##  7 ##src/lib/connect_timeo.c##
+
+    sigfunc = Signal(SIGALRM, connect_alarm);##  8 ##src/lib/connect_timeo.c##
+    if (alarm(nsec) != 0)##  9 ##src/lib/connect_timeo.c##
+        err_msg("connect_timeo: alarm was already set");## 10 ##src/lib/connect_timeo.c##
+
+    if ((n = connect(sockfd, saptr, salen)) < 0) {## 11 ##src/lib/connect_timeo.c##
+        close(sockfd);## 12 ##src/lib/connect_timeo.c##
+        if (errno == EINTR)## 13 ##src/lib/connect_timeo.c##
+            errno = ETIMEDOUT;## 14 ##src/lib/connect_timeo.c##
+    }## 15 ##src/lib/connect_timeo.c##
+    alarm(0);                   /* turn off the alarm */## 16 ##src/lib/connect_timeo.c##
+    Signal(SIGALRM, sigfunc);   /* restore previous signal handler */## 17 ##src/lib/connect_timeo.c##
+
+    return (n);## 18 ##src/lib/connect_timeo.c##
+}## 19 ##src/lib/connect_timeo.c##
+
+static void## 20 ##src/lib/connect_timeo.c##
+connect_alarm(int signo)## 21 ##src/lib/connect_timeo.c##
+{## 22 ##src/lib/connect_timeo.c##
+    return;                     /* just interrupt the connect() */## 23 ##src/lib/connect_timeo.c##
+}## 24 ##src/lib/connect_timeo.c##
+/* end connect_timeo */
+
+void## 25 ##src/lib/connect_timeo.c##
+Connect_timeo(int fd, const SA *sa, socklen_t salen, int sec)## 26 ##src/lib/connect_timeo.c##
+{## 27 ##src/lib/connect_timeo.c##
+    if (connect_timeo(fd, sa, salen, sec) < 0)## 28 ##src/lib/connect_timeo.c##
+        err_sys("connect_timeo error");## 29 ##src/lib/connect_timeo.c##
+}## 30 ##src/lib/connect_timeo.c##
diff --git a/lib/daemon_inetd.c b/lib/daemon_inetd.c
new file mode 100644 (file)
index 0000000..ada76e0
--- /dev/null
@@ -0,0 +1,11 @@
+#include       "unp.h"
+#include       <syslog.h>
+
+extern int     daemon_proc;    /* defined in error.c */
+
+void
+daemon_inetd(const char *pname, int facility)
+{
+       daemon_proc = 1;                /* for our err_XXX() functions */
+       openlog(pname, LOG_PID, facility);
+}
diff --git a/lib/daemon_inetd.lc b/lib/daemon_inetd.lc
new file mode 100644 (file)
index 0000000..d593dc4
--- /dev/null
@@ -0,0 +1,11 @@
+#include    "unp.h"##  1 ##src/lib/daemon_inetd.c##
+#include    <syslog.h>##  2 ##src/lib/daemon_inetd.c##
+
+extern int daemon_proc;         /* defined in error.c */##  3 ##src/lib/daemon_inetd.c##
+
+void##  4 ##src/lib/daemon_inetd.c##
+daemon_inetd(const char *pname, int facility)##  5 ##src/lib/daemon_inetd.c##
+{##  6 ##src/lib/daemon_inetd.c##
+    daemon_proc = 1;            /* for our err_XXX() functions */##  7 ##src/lib/daemon_inetd.c##
+    openlog(pname, LOG_PID, facility);##  8 ##src/lib/daemon_inetd.c##
+}##  9 ##src/lib/daemon_inetd.c##
diff --git a/lib/daemon_init.c b/lib/daemon_init.c
new file mode 100644 (file)
index 0000000..53dfa89
--- /dev/null
@@ -0,0 +1,48 @@
+#include       "unp.h"
+#include       <syslog.h>
+
+#define        MAXFD   64
+
+extern int     daemon_proc;    /* defined in error.c */
+
+int
+daemon_init(const char *pname, int facility)
+{
+       int             i;
+       pid_t   pid;
+
+       if ( (pid = Fork()) < 0)
+               return (-1);
+       else if (pid)
+               _exit(0);                       /* parent terminates */
+
+       /* child 1 continues... */
+
+       if (setsid() < 0)                       /* become session leader */
+               return (-1);
+
+       Signal(SIGHUP, SIG_IGN);
+       if ( (pid = Fork()) < 0)
+               return (-1);
+       else if (pid)
+               _exit(0);                       /* child 1 terminates */
+
+       /* child 2 continues... */
+
+       daemon_proc = 1;                        /* for err_XXX() functions */
+
+       chdir("/");                             /* change working directory */
+
+       /* close off file descriptors */
+       for (i = 0; i < MAXFD; i++)
+               close(i);
+
+       /* redirect stdin, stdout, and stderr to /dev/null */
+       open("/dev/null", O_RDONLY);
+       open("/dev/null", O_RDWR);
+       open("/dev/null", O_RDWR);
+
+       openlog(pname, LOG_PID, facility);
+
+       return (0);                             /* success */
+}
diff --git a/lib/dg_cli.c b/lib/dg_cli.c
new file mode 100644 (file)
index 0000000..b3e9fbd
--- /dev/null
@@ -0,0 +1,18 @@
+#include       "unp.h"
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int     n;
+       char    sendline[MAXLINE], recvline[MAXLINE + 1];
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
+
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+}
diff --git a/lib/dg_echo.c b/lib/dg_echo.c
new file mode 100644 (file)
index 0000000..03af97a
--- /dev/null
@@ -0,0 +1,16 @@
+#include       "unp.h"
+
+void
+dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
+{
+       int                     n;
+       socklen_t       len;
+       char            mesg[MAXLINE];
+
+       for ( ; ; ) {
+               len = clilen;
+               n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
+
+               Sendto(sockfd, mesg, n, 0, pcliaddr, len);
+       }
+}
diff --git a/lib/error.c b/lib/error.c
new file mode 100644 (file)
index 0000000..3e1b63c
--- /dev/null
@@ -0,0 +1,109 @@
+#include       "unp.h"
+
+#include       <stdarg.h>              /* ANSI C header file */
+#include       <syslog.h>              /* for syslog() */
+
+int            daemon_proc;            /* set nonzero by daemon_init() */
+
+static void    err_doit(int, int, const char *, va_list);
+
+/* Nonfatal error related to system call
+ * Print message and return */
+
+void
+err_ret(const char *fmt, ...)
+{
+       va_list         ap;
+
+       va_start(ap, fmt);
+       err_doit(1, LOG_INFO, fmt, ap);
+       va_end(ap);
+       return;
+}
+
+/* Fatal error related to system call
+ * Print message and terminate */
+
+void
+err_sys(const char *fmt, ...)
+{
+       va_list         ap;
+
+       va_start(ap, fmt);
+       err_doit(1, LOG_ERR, fmt, ap);
+       va_end(ap);
+       exit(1);
+}
+
+/* Fatal error related to system call
+ * Print message, dump core, and terminate */
+
+void
+err_dump(const char *fmt, ...)
+{
+       va_list         ap;
+
+       va_start(ap, fmt);
+       err_doit(1, LOG_ERR, fmt, ap);
+       va_end(ap);
+       abort();                /* dump core and terminate */
+       exit(1);                /* shouldn't get here */
+}
+
+/* Nonfatal error unrelated to system call
+ * Print message and return */
+
+void
+err_msg(const char *fmt, ...)
+{
+       va_list         ap;
+
+       va_start(ap, fmt);
+       err_doit(0, LOG_INFO, fmt, ap);
+       va_end(ap);
+       return;
+}
+
+/* Fatal error unrelated to system call
+ * Print message and terminate */
+
+void
+err_quit(const char *fmt, ...)
+{
+       va_list         ap;
+
+       va_start(ap, fmt);
+       err_doit(0, LOG_ERR, fmt, ap);
+       va_end(ap);
+       exit(1);
+}
+
+/* Print message and return to caller
+ * Caller specifies "errnoflag" and "level" */
+
+static void
+err_doit(int errnoflag, int level, const char *fmt, va_list ap)
+{
+       int             errno_save, n;
+       char    buf[MAXLINE + 1];
+
+       errno_save = errno;             /* value caller might want printed */
+#ifdef HAVE_VSNPRINTF
+       vsnprintf(buf, MAXLINE, fmt, ap);       /* safe */
+#else
+       vsprintf(buf, fmt, ap);                                 /* not safe */
+#endif
+       n = strlen(buf);
+       if (errnoflag)
+               snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));
+       strcat(buf, "\n");
+
+       if (daemon_proc) {
+               syslog(level, buf);
+       } else {
+               fflush(stdout);         /* in case stdout and stderr are the same */
+               fputs(buf, stderr);
+               fflush(stderr);
+       }
+       return;
+}
diff --git a/lib/family_to_level.c b/lib/family_to_level.c
new file mode 100644 (file)
index 0000000..413c58b
--- /dev/null
@@ -0,0 +1,27 @@
+#include "unp.h"
+
+int
+family_to_level(int family)
+{
+       switch (family) {
+       case AF_INET:
+               return IPPROTO_IP;
+#ifdef IPV6
+       case AF_INET6:
+               return IPPROTO_IPV6;
+#endif
+       default:
+               return -1;
+       }
+}
+
+int
+Family_to_level(int family)
+{
+       int             rc;
+
+       if ( (rc = family_to_level(family)) < 0)
+               err_sys("family_to_level error");
+
+       return(rc);
+}
diff --git a/lib/get_ifi_info.c b/lib/get_ifi_info.c
new file mode 100644 (file)
index 0000000..4859ff1
--- /dev/null
@@ -0,0 +1,194 @@
+/* include get_ifi_info1 */
+#include       "unpifi.h"
+
+struct ifi_info *
+get_ifi_info(int family, int doaliases)
+{
+       struct ifi_info         *ifi, *ifihead, **ifipnext;
+       int                                     sockfd, len, lastlen, flags, myflags, idx = 0, hlen = 0;
+       char                            *ptr, *buf, lastname[IFNAMSIZ], *cptr, *haddr, *sdlname;
+       struct ifconf           ifc;
+       struct ifreq            *ifr, ifrcopy;
+       struct sockaddr_in      *sinptr;
+       struct sockaddr_in6     *sin6ptr;
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       lastlen = 0;
+       len = 100 * sizeof(struct ifreq);       /* initial buffer size guess */
+       for ( ; ; ) {
+               buf = Malloc(len);
+               ifc.ifc_len = len;
+               ifc.ifc_buf = buf;
+               if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
+                       if (errno != EINVAL || lastlen != 0)
+                               err_sys("ioctl error");
+               } else {
+                       if (ifc.ifc_len == lastlen)
+                               break;          /* success, len has not changed */
+                       lastlen = ifc.ifc_len;
+               }
+               len += 10 * sizeof(struct ifreq);       /* increment */
+               free(buf);
+       }
+       ifihead = NULL;
+       ifipnext = &ifihead;
+       lastname[0] = 0;
+       sdlname = NULL;
+/* end get_ifi_info1 */
+
+/* include get_ifi_info2 */
+       for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
+               ifr = (struct ifreq *) ptr;
+
+#ifdef HAVE_SOCKADDR_SA_LEN
+               len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);
+#else
+               switch (ifr->ifr_addr.sa_family) {
+#ifdef IPV6
+               case AF_INET6:  
+                       len = sizeof(struct sockaddr_in6);
+                       break;
+#endif
+               case AF_INET:   
+               default:        
+                       len = sizeof(struct sockaddr);
+                       break;
+               }
+#endif /* HAVE_SOCKADDR_SA_LEN */
+               ptr += sizeof(ifr->ifr_name) + len;     /* for next one in buffer */
+
+#ifdef HAVE_SOCKADDR_DL_STRUCT
+               /* assumes that AF_LINK precedes AF_INET or AF_INET6 */
+               if (ifr->ifr_addr.sa_family == AF_LINK) {
+                       struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
+                       sdlname = ifr->ifr_name;
+                       idx = sdl->sdl_index;
+                       haddr = sdl->sdl_data + sdl->sdl_nlen;
+                       hlen = sdl->sdl_alen;
+               }
+#endif
+
+               if (ifr->ifr_addr.sa_family != family)
+                       continue;       /* ignore if not desired address family */
+
+               myflags = 0;
+               if ( (cptr = strchr(ifr->ifr_name, ':')) != NULL)
+                       *cptr = 0;              /* replace colon with null */
+               if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
+                       if (doaliases == 0)
+                               continue;       /* already processed this interface */
+                       myflags = IFI_ALIAS;
+               }
+               memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
+
+               ifrcopy = *ifr;
+               Ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
+               flags = ifrcopy.ifr_flags;
+               if ((flags & IFF_UP) == 0)
+                       continue;       /* ignore if interface not up */
+/* end get_ifi_info2 */
+
+/* include get_ifi_info3 */
+               ifi = Calloc(1, sizeof(struct ifi_info));
+               *ifipnext = ifi;                        /* prev points to this new one */
+               ifipnext = &ifi->ifi_next;      /* pointer to next one goes here */
+
+               ifi->ifi_flags = flags;         /* IFF_xxx values */
+               ifi->ifi_myflags = myflags;     /* IFI_xxx values */
+#if defined(SIOCGIFMTU) && defined(HAVE_STRUCT_IFREQ_IFR_MTU)
+               Ioctl(sockfd, SIOCGIFMTU, &ifrcopy);
+               ifi->ifi_mtu = ifrcopy.ifr_mtu;
+#else
+               ifi->ifi_mtu = 0;
+#endif
+               memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);
+               ifi->ifi_name[IFI_NAME-1] = '\0';
+               /* If the sockaddr_dl is from a different interface, ignore it */
+               if (sdlname == NULL || strcmp(sdlname, ifr->ifr_name) != 0)
+                       idx = hlen = 0;
+               ifi->ifi_index = idx;
+               ifi->ifi_hlen = hlen;
+               if (ifi->ifi_hlen > IFI_HADDR)
+                       ifi->ifi_hlen = IFI_HADDR;
+               if (hlen)
+                       memcpy(ifi->ifi_haddr, haddr, ifi->ifi_hlen);
+/* end get_ifi_info3 */
+/* include get_ifi_info4 */
+               switch (ifr->ifr_addr.sa_family) {
+               case AF_INET:
+                       sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
+                       ifi->ifi_addr = Calloc(1, sizeof(struct sockaddr_in));
+                       memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));
+
+#ifdef SIOCGIFBRDADDR
+                       if (flags & IFF_BROADCAST) {
+                               Ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy);
+                               sinptr = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr;
+                               ifi->ifi_brdaddr = Calloc(1, sizeof(struct sockaddr_in));
+                               memcpy(ifi->ifi_brdaddr, sinptr, sizeof(struct sockaddr_in));
+                       }
+#endif
+
+#ifdef SIOCGIFDSTADDR
+                       if (flags & IFF_POINTOPOINT) {
+                               Ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy);
+                               sinptr = (struct sockaddr_in *) &ifrcopy.ifr_dstaddr;
+                               ifi->ifi_dstaddr = Calloc(1, sizeof(struct sockaddr_in));
+                               memcpy(ifi->ifi_dstaddr, sinptr, sizeof(struct sockaddr_in));
+                       }
+#endif
+                       break;
+
+               case AF_INET6:
+                       sin6ptr = (struct sockaddr_in6 *) &ifr->ifr_addr;
+                       ifi->ifi_addr = Calloc(1, sizeof(struct sockaddr_in6));
+                       memcpy(ifi->ifi_addr, sin6ptr, sizeof(struct sockaddr_in6));
+
+#ifdef SIOCGIFDSTADDR
+                       if (flags & IFF_POINTOPOINT) {
+                               Ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy);
+                               sin6ptr = (struct sockaddr_in6 *) &ifrcopy.ifr_dstaddr;
+                               ifi->ifi_dstaddr = Calloc(1, sizeof(struct sockaddr_in6));
+                               memcpy(ifi->ifi_dstaddr, sin6ptr, sizeof(struct sockaddr_in6));
+                       }
+#endif
+                       break;
+
+               default:
+                       break;
+               }
+       }
+       free(buf);
+       return(ifihead);        /* pointer to first structure in linked list */
+}
+/* end get_ifi_info4 */
+
+/* include free_ifi_info */
+void
+free_ifi_info(struct ifi_info *ifihead)
+{
+       struct ifi_info *ifi, *ifinext;
+
+       for (ifi = ifihead; ifi != NULL; ifi = ifinext) {
+               if (ifi->ifi_addr != NULL)
+                       free(ifi->ifi_addr);
+               if (ifi->ifi_brdaddr != NULL)
+                       free(ifi->ifi_brdaddr);
+               if (ifi->ifi_dstaddr != NULL)
+                       free(ifi->ifi_dstaddr);
+               ifinext = ifi->ifi_next;        /* can't fetch ifi_next after free() */
+               free(ifi);                                      /* the ifi_info{} itself */
+       }
+}
+/* end free_ifi_info */
+
+struct ifi_info *
+Get_ifi_info(int family, int doaliases)
+{
+       struct ifi_info *ifi;
+
+       if ( (ifi = get_ifi_info(family, doaliases)) == NULL)
+               err_quit("get_ifi_info error");
+       return(ifi);
+}
diff --git a/lib/get_ifi_info.lc b/lib/get_ifi_info.lc
new file mode 100644 (file)
index 0000000..5b9ad7e
--- /dev/null
@@ -0,0 +1,189 @@
+/* include get_ifi_info1 */
+#include    "unpifi.h"##  1 ##src/lib/get_ifi_info.c##
+
+struct ifi_info *##  2 ##src/lib/get_ifi_info.c##
+get_ifi_info(int family, int doaliases)##  3 ##src/lib/get_ifi_info.c##
+{##  4 ##src/lib/get_ifi_info.c##
+    struct ifi_info *ifi, *ifihead, **ifipnext;##  5 ##src/lib/get_ifi_info.c##
+    int     sockfd, len, lastlen, flags, myflags, idx = 0, hlen = 0;##  6 ##src/lib/get_ifi_info.c##
+    char   *ptr, *buf, lastname[IFNAMSIZ], *cptr, *haddr;##  7 ##src/lib/get_ifi_info.c##
+    struct ifconf ifc;##  8 ##src/lib/get_ifi_info.c##
+    struct ifreq *ifr, ifrcopy;##  9 ##src/lib/get_ifi_info.c##
+    struct sockaddr_in *sinptr;## 10 ##src/lib/get_ifi_info.c##
+    struct sockaddr_in6 *sin6ptr;## 11 ##src/lib/get_ifi_info.c##
+
+    sockfd = Socket(AF_INET, SOCK_DGRAM, 0);## 12 ##src/lib/get_ifi_info.c##
+
+    lastlen = 0;## 13 ##src/lib/get_ifi_info.c##
+    len = 100 * sizeof(struct ifreq);   /* initial buffer size guess */## 14 ##src/lib/get_ifi_info.c##
+    for (;;) {## 15 ##src/lib/get_ifi_info.c##
+        buf = Malloc(len);## 16 ##src/lib/get_ifi_info.c##
+        ifc.ifc_len = len;## 17 ##src/lib/get_ifi_info.c##
+        ifc.ifc_buf = buf;## 18 ##src/lib/get_ifi_info.c##
+        if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {## 19 ##src/lib/get_ifi_info.c##
+            if (errno != EINVAL || lastlen != 0)## 20 ##src/lib/get_ifi_info.c##
+                err_sys("ioctl error");## 21 ##src/lib/get_ifi_info.c##
+        } else {## 22 ##src/lib/get_ifi_info.c##
+            if (ifc.ifc_len == lastlen)## 23 ##src/lib/get_ifi_info.c##
+                break;          /* success, len has not changed */## 24 ##src/lib/get_ifi_info.c##
+            lastlen = ifc.ifc_len;## 25 ##src/lib/get_ifi_info.c##
+        }## 26 ##src/lib/get_ifi_info.c##
+        len += 10 * sizeof(struct ifreq);   /* increment */## 27 ##src/lib/get_ifi_info.c##
+        free(buf);## 28 ##src/lib/get_ifi_info.c##
+    }## 29 ##src/lib/get_ifi_info.c##
+    ifihead = NULL;## 30 ##src/lib/get_ifi_info.c##
+    ifipnext = &ifihead;## 31 ##src/lib/get_ifi_info.c##
+    lastname[0] = 0;## 32 ##src/lib/get_ifi_info.c##
+/* end get_ifi_info1 */
+
+/* include get_ifi_info2 */
+    for (ptr = buf; ptr < buf + ifc.ifc_len;) {## 33 ##src/lib/get_ifi_info.c##
+        ifr = (struct ifreq *) ptr;## 34 ##src/lib/get_ifi_info.c##
+
+#ifdef  HAVE_SOCKADDR_SA_LEN## 35 ##src/lib/get_ifi_info.c##
+        len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);## 36 ##src/lib/get_ifi_info.c##
+#else## 37 ##src/lib/get_ifi_info.c##
+        switch (ifr->ifr_addr.sa_family) {## 38 ##src/lib/get_ifi_info.c##
+#ifdef  IPV6## 39 ##src/lib/get_ifi_info.c##
+        case AF_INET6:## 40 ##src/lib/get_ifi_info.c##
+            len = sizeof(struct sockaddr_in6);## 41 ##src/lib/get_ifi_info.c##
+            break;## 42 ##src/lib/get_ifi_info.c##
+#endif## 43 ##src/lib/get_ifi_info.c##
+        case AF_INET:## 44 ##src/lib/get_ifi_info.c##
+        default:## 45 ##src/lib/get_ifi_info.c##
+            len = sizeof(struct sockaddr);## 46 ##src/lib/get_ifi_info.c##
+            break;## 47 ##src/lib/get_ifi_info.c##
+        }## 48 ##src/lib/get_ifi_info.c##
+#endif  /* HAVE_SOCKADDR_SA_LEN */## 49 ##src/lib/get_ifi_info.c##
+        ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */## 50 ##src/lib/get_ifi_info.c##
+
+#ifdef  HAVE_SOCKADDR_DL## 51 ##src/lib/get_ifi_info.c##
+        /* assumes that AF_LINK precedes AF_INET or AF_INET6 */## 52 ##src/lib/get_ifi_info.c##
+        if (ifr->ifr_addr.sa_family == AF_LINK) {## 53 ##src/lib/get_ifi_info.c##
+            struct sockaddr_dl *sdl = (struct sockaddr_dl *) &ifr->ifr_addr;## 54 ##src/lib/get_ifi_info.c##
+            idx = sdl->sdl_index;## 55 ##src/lib/get_ifi_info.c##
+            haddr = sdl->sdl_data + sdl->sdl_nlen;## 56 ##src/lib/get_ifi_info.c##
+            hlen = sdl->sdl_alen;## 57 ##src/lib/get_ifi_info.c##
+        }## 58 ##src/lib/get_ifi_info.c##
+#endif## 59 ##src/lib/get_ifi_info.c##
+
+        if (ifr->ifr_addr.sa_family != family)## 60 ##src/lib/get_ifi_info.c##
+            continue;           /* ignore if not desired address family */## 61 ##src/lib/get_ifi_info.c##
+
+        myflags = 0;## 62 ##src/lib/get_ifi_info.c##
+        if ((cptr = strchr(ifr->ifr_name, ':')) != NULL)## 63 ##src/lib/get_ifi_info.c##
+            *cptr = 0;          /* replace colon with null */## 64 ##src/lib/get_ifi_info.c##
+        if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {## 65 ##src/lib/get_ifi_info.c##
+            if (doaliases == 0)## 66 ##src/lib/get_ifi_info.c##
+                continue;       /* already processed this interface */## 67 ##src/lib/get_ifi_info.c##
+            myflags = IFI_ALIAS;## 68 ##src/lib/get_ifi_info.c##
+        }## 69 ##src/lib/get_ifi_info.c##
+        memcpy(lastname, ifr->ifr_name, IFNAMSIZ);## 70 ##src/lib/get_ifi_info.c##
+
+        ifrcopy = *ifr;## 71 ##src/lib/get_ifi_info.c##
+        Ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);## 72 ##src/lib/get_ifi_info.c##
+        flags = ifrcopy.ifr_flags;## 73 ##src/lib/get_ifi_info.c##
+        if ((flags & IFF_UP) == 0)## 74 ##src/lib/get_ifi_info.c##
+            continue;           /* ignore if interface not up */## 75 ##src/lib/get_ifi_info.c##
+
+        ifi = Calloc(1, sizeof(struct ifi_info));## 76 ##src/lib/get_ifi_info.c##
+        *ifipnext = ifi;        /* prev points to this new one */## 77 ##src/lib/get_ifi_info.c##
+        ifipnext = &ifi->ifi_next;  /* pointer to next one goes here */## 78 ##src/lib/get_ifi_info.c##
+
+        ifi->ifi_flags = flags; /* IFF_xxx values */## 79 ##src/lib/get_ifi_info.c##
+        ifi->ifi_myflags = myflags; /* IFI_xxx values */## 80 ##src/lib/get_ifi_info.c##
+        ifi->ifi_index = idx;## 81 ##src/lib/get_ifi_info.c##
+        memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);## 82 ##src/lib/get_ifi_info.c##
+        ifi->ifi_hlen = hlen;## 83 ##src/lib/get_ifi_info.c##
+        if (ifi->ifi_hlen > IFI_HADDR)## 84 ##src/lib/get_ifi_info.c##
+            ifi->ifi_hlen = IFI_HADDR;## 85 ##src/lib/get_ifi_info.c##
+        memcpy(ifi->ifi_haddr, haddr, ifi->ifi_hlen);## 86 ##src/lib/get_ifi_info.c##
+        ifi->ifi_name[IFI_NAME - 1] = '\0';## 87 ##src/lib/get_ifi_info.c##
+        idx = hlen = 0;## 88 ##src/lib/get_ifi_info.c##
+/* end get_ifi_info2 */
+/* include get_ifi_info3 */
+        switch (ifr->ifr_addr.sa_family) {## 89 ##src/lib/get_ifi_info.c##
+        case AF_INET:## 90 ##src/lib/get_ifi_info.c##
+            sinptr = (struct sockaddr_in *) &ifr->ifr_addr;## 91 ##src/lib/get_ifi_info.c##
+            if (ifi->ifi_addr == NULL) {## 92 ##src/lib/get_ifi_info.c##
+                ifi->ifi_addr = Calloc(1, sizeof(struct sockaddr_in));## 93 ##src/lib/get_ifi_info.c##
+                memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));## 94 ##src/lib/get_ifi_info.c##
+
+#ifdef  SIOCGIFBRDADDR## 95 ##src/lib/get_ifi_info.c##
+                if (flags & IFF_BROADCAST) {## 96 ##src/lib/get_ifi_info.c##
+                    Ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy);## 97 ##src/lib/get_ifi_info.c##
+                    sinptr = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr;## 98 ##src/lib/get_ifi_info.c##
+                    ifi->ifi_brdaddr = Calloc(1, sizeof(struct sockaddr_in));## 99 ##src/lib/get_ifi_info.c##
+                    memcpy(ifi->ifi_brdaddr, sinptr,##100 ##src/lib/get_ifi_info.c##
+                           sizeof(struct sockaddr_in));##101 ##src/lib/get_ifi_info.c##
+                }##102 ##src/lib/get_ifi_info.c##
+#endif##103 ##src/lib/get_ifi_info.c##
+
+#ifdef  SIOCGIFDSTADDR##104 ##src/lib/get_ifi_info.c##
+                if (flags & IFF_POINTOPOINT) {##105 ##src/lib/get_ifi_info.c##
+                    Ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy);##106 ##src/lib/get_ifi_info.c##
+                    sinptr = (struct sockaddr_in *) &ifrcopy.ifr_dstaddr;##107 ##src/lib/get_ifi_info.c##
+                    ifi->ifi_dstaddr = Calloc(1, sizeof(struct sockaddr_in));##108 ##src/lib/get_ifi_info.c##
+                    memcpy(ifi->ifi_dstaddr, sinptr,##109 ##src/lib/get_ifi_info.c##
+                           sizeof(struct sockaddr_in));##110 ##src/lib/get_ifi_info.c##
+                }##111 ##src/lib/get_ifi_info.c##
+#endif##112 ##src/lib/get_ifi_info.c##
+            }##113 ##src/lib/get_ifi_info.c##
+            break;##114 ##src/lib/get_ifi_info.c##
+
+        case AF_INET6:##115 ##src/lib/get_ifi_info.c##
+            sin6ptr = (struct sockaddr_in6 *) &ifr->ifr_addr;##116 ##src/lib/get_ifi_info.c##
+            if (ifi->ifi_addr == NULL) {##117 ##src/lib/get_ifi_info.c##
+                ifi->ifi_addr = Calloc(1, sizeof(struct sockaddr_in6));##118 ##src/lib/get_ifi_info.c##
+                memcpy(ifi->ifi_addr, sin6ptr, sizeof(struct sockaddr_in6));##119 ##src/lib/get_ifi_info.c##
+
+#ifdef  SIOCGIFDSTADDR##120 ##src/lib/get_ifi_info.c##
+                if (flags & IFF_POINTOPOINT) {##121 ##src/lib/get_ifi_info.c##
+                    Ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy);##122 ##src/lib/get_ifi_info.c##
+                    sin6ptr = (struct sockaddr_in6 *) &ifrcopy.ifr_dstaddr;##123 ##src/lib/get_ifi_info.c##
+                    ifi->ifi_dstaddr =##124 ##src/lib/get_ifi_info.c##
+                        Calloc(1, sizeof(struct sockaddr_in6));##125 ##src/lib/get_ifi_info.c##
+                    memcpy(ifi->ifi_dstaddr, sin6ptr,##126 ##src/lib/get_ifi_info.c##
+                           sizeof(struct sockaddr_in6));##127 ##src/lib/get_ifi_info.c##
+                }##128 ##src/lib/get_ifi_info.c##
+#endif##129 ##src/lib/get_ifi_info.c##
+            }##130 ##src/lib/get_ifi_info.c##
+            break;##131 ##src/lib/get_ifi_info.c##
+
+        default:##132 ##src/lib/get_ifi_info.c##
+            break;##133 ##src/lib/get_ifi_info.c##
+        }##134 ##src/lib/get_ifi_info.c##
+    }##135 ##src/lib/get_ifi_info.c##
+    free(buf);##136 ##src/lib/get_ifi_info.c##
+    return (ifihead);           /* pointer to first structure in linked list */##137 ##src/lib/get_ifi_info.c##
+}##138 ##src/lib/get_ifi_info.c##
+/* end get_ifi_info3 */
+
+/* include free_ifi_info */
+void##139 ##src/lib/get_ifi_info.c##
+free_ifi_info(struct ifi_info *ifihead)##140 ##src/lib/get_ifi_info.c##
+{##141 ##src/lib/get_ifi_info.c##
+    struct ifi_info *ifi, *ifinext;##142 ##src/lib/get_ifi_info.c##
+
+    for (ifi = ifihead; ifi != NULL; ifi = ifinext) {##143 ##src/lib/get_ifi_info.c##
+        if (ifi->ifi_addr != NULL)##144 ##src/lib/get_ifi_info.c##
+            free(ifi->ifi_addr);##145 ##src/lib/get_ifi_info.c##
+        if (ifi->ifi_brdaddr != NULL)##146 ##src/lib/get_ifi_info.c##
+            free(ifi->ifi_brdaddr);##147 ##src/lib/get_ifi_info.c##
+        if (ifi->ifi_dstaddr != NULL)##148 ##src/lib/get_ifi_info.c##
+            free(ifi->ifi_dstaddr);##149 ##src/lib/get_ifi_info.c##
+        ifinext = ifi->ifi_next;    /* can't fetch ifi_next after free() */##150 ##src/lib/get_ifi_info.c##
+        free(ifi);              /* the ifi_info{} itself */##151 ##src/lib/get_ifi_info.c##
+    }##152 ##src/lib/get_ifi_info.c##
+}##153 ##src/lib/get_ifi_info.c##
+/* end free_ifi_info */
+
+struct ifi_info *##154 ##src/lib/get_ifi_info.c##
+Get_ifi_info(int family, int doaliases)##155 ##src/lib/get_ifi_info.c##
+{##156 ##src/lib/get_ifi_info.c##
+    struct ifi_info *ifi;##157 ##src/lib/get_ifi_info.c##
+
+    if ((ifi = get_ifi_info(family, doaliases)) == NULL)##158 ##src/lib/get_ifi_info.c##
+        err_quit("get_ifi_info error");##159 ##src/lib/get_ifi_info.c##
+    return (ifi);##160 ##src/lib/get_ifi_info.c##
+}##161 ##src/lib/get_ifi_info.c##
diff --git a/lib/gf_time.c b/lib/gf_time.c
new file mode 100644 (file)
index 0000000..56aa524
--- /dev/null
@@ -0,0 +1,23 @@
+#include       "unp.h"
+#include       <time.h>
+
+char *
+gf_time(void)
+{
+       struct timeval  tv;
+       time_t                  t;
+       static char             str[30];
+       char                    *ptr;
+
+       if (gettimeofday(&tv, NULL) < 0)
+               err_sys("gettimeofday error");
+
+       t = tv.tv_sec;  /* POSIX says tv.tv_sec is time_t; some BSDs don't agree. */
+       ptr = ctime(&t);
+       strcpy(str, &ptr[11]);
+               /* Fri Sep 13 00:00:00 1986\n\0 */
+               /* 0123456789012345678901234 5  */
+       snprintf(str+8, sizeof(str)-8, ".%06ld", tv.tv_usec);
+
+       return(str);
+}
diff --git a/lib/host_serv.c b/lib/host_serv.c
new file mode 100644 (file)
index 0000000..553ce45
--- /dev/null
@@ -0,0 +1,47 @@
+/* include host_serv */
+#include       "unp.h"
+
+struct addrinfo *
+host_serv(const char *host, const char *serv, int family, int socktype)
+{
+       int                             n;
+       struct addrinfo hints, *res;
+
+       bzero(&hints, sizeof(struct addrinfo));
+       hints.ai_flags = AI_CANONNAME;  /* always return canonical name */
+       hints.ai_family = family;               /* AF_UNSPEC, AF_INET, AF_INET6, etc. */
+       hints.ai_socktype = socktype;   /* 0, SOCK_STREAM, SOCK_DGRAM, etc. */
+
+       if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0)
+               return(NULL);
+
+       return(res);    /* return pointer to first on linked list */
+}
+/* end host_serv */
+
+/*
+ * There is no easy way to pass back the integer return code from
+ * getaddrinfo() in the function above, short of adding another argument
+ * that is a pointer, so the easiest way to provide the wrapper function
+ * is just to duplicate the simple function as we do here.
+ */
+
+struct addrinfo *
+Host_serv(const char *host, const char *serv, int family, int socktype)
+{
+       int                             n;
+       struct addrinfo hints, *res;
+
+       bzero(&hints, sizeof(struct addrinfo));
+       hints.ai_flags = AI_CANONNAME;  /* always return canonical name */
+       hints.ai_family = family;               /* 0, AF_INET, AF_INET6, etc. */
+       hints.ai_socktype = socktype;   /* 0, SOCK_STREAM, SOCK_DGRAM, etc. */
+
+       if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0)
+               err_quit("host_serv error for %s, %s: %s",
+                                (host == NULL) ? "(no hostname)" : host,
+                                (serv == NULL) ? "(no service name)" : serv,
+                                gai_strerror(n));
+
+       return(res);    /* return pointer to first on linked list */
+}
diff --git a/lib/host_serv.lc b/lib/host_serv.lc
new file mode 100644 (file)
index 0000000..77e241d
--- /dev/null
@@ -0,0 +1,47 @@
+/* include host_serv */
+#include    "unp.h"##  1 ##src/lib/host_serv.c##
+
+struct addrinfo *##  2 ##src/lib/host_serv.c##
+host_serv(const char *host, const char *serv, int family, int socktype)##  3 ##src/lib/host_serv.c##
+{##  4 ##src/lib/host_serv.c##
+    int     n;##  5 ##src/lib/host_serv.c##
+    struct addrinfo hints, *res;##  6 ##src/lib/host_serv.c##
+
+    bzero(&hints, sizeof(struct addrinfo));##  7 ##src/lib/host_serv.c##
+    hints.ai_flags = AI_CANONNAME;  /* always return canonical name */##  8 ##src/lib/host_serv.c##
+    hints.ai_family = family;   /* AF_UNSPEC, AF_INET, AF_INET6, etc. */##  9 ##src/lib/host_serv.c##
+    hints.ai_socktype = socktype;   /* 0, SOCK_STREAM, SOCK_DGRAM, etc. */## 10 ##src/lib/host_serv.c##
+
+    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 11 ##src/lib/host_serv.c##
+        return (NULL);## 12 ##src/lib/host_serv.c##
+
+    return (res);               /* return pointer to first on linked list */## 13 ##src/lib/host_serv.c##
+}## 14 ##src/lib/host_serv.c##
+/* end host_serv */
+
+/*## 15 ##src/lib/host_serv.c##
+ * There is no easy way to pass back the integer return code from## 16 ##src/lib/host_serv.c##
+ * getaddrinfo() in the function above, short of adding another argument## 17 ##src/lib/host_serv.c##
+ * that is a pointer, so the easiest way to provide the wrapper function## 18 ##src/lib/host_serv.c##
+ * is just to duplicate the simple function as we do here.## 19 ##src/lib/host_serv.c##
+ */## 20 ##src/lib/host_serv.c##
+
+struct addrinfo *## 21 ##src/lib/host_serv.c##
+Host_serv(const char *host, const char *serv, int family, int socktype)## 22 ##src/lib/host_serv.c##
+{## 23 ##src/lib/host_serv.c##
+    int     n;## 24 ##src/lib/host_serv.c##
+    struct addrinfo hints, *res;## 25 ##src/lib/host_serv.c##
+
+    bzero(&hints, sizeof(struct addrinfo));## 26 ##src/lib/host_serv.c##
+    hints.ai_flags = AI_CANONNAME;  /* always return canonical name */## 27 ##src/lib/host_serv.c##
+    hints.ai_family = family;   /* 0, AF_INET, AF_INET6, etc. */## 28 ##src/lib/host_serv.c##
+    hints.ai_socktype = socktype;   /* 0, SOCK_STREAM, SOCK_DGRAM, etc. */## 29 ##src/lib/host_serv.c##
+
+    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 30 ##src/lib/host_serv.c##
+        err_quit("host_serv error for %s, %s: %s",## 31 ##src/lib/host_serv.c##
+                 (host == NULL) ? "(no hostname)" : host,## 32 ##src/lib/host_serv.c##
+                 (serv == NULL) ? "(no service name)" : serv,## 33 ##src/lib/host_serv.c##
+                 gai_strerror(n));## 34 ##src/lib/host_serv.c##
+
+    return (res);               /* return pointer to first on linked list */## 35 ##src/lib/host_serv.c##
+}## 36 ##src/lib/host_serv.c##
diff --git a/lib/hstrerror.c b/lib/hstrerror.c
new file mode 100644 (file)
index 0000000..92d2b92
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Return a string containing some additional information after a
+ * host name or address lookup error - gethostbyname() or gethostbyaddr().
+ *
+ * This is only compiled if the local host does not provide it--recent
+ * versions of BIND supply this function.
+ */
+
+#include       "unp.h"
+
+const char *
+hstrerror(int err)
+{
+       if (err == 0)
+               return("no error");
+
+       if (err == HOST_NOT_FOUND)
+               return("Unknown host");
+
+       if (err == TRY_AGAIN)
+               return("Hostname lookup failure");
+
+       if (err == NO_RECOVERY)
+               return("Unknown server error");
+
+       if (err == NO_DATA)
+        return("No address associated with name");
+
+       return("unknown error");
+}
diff --git a/lib/if_indextoname.c b/lib/if_indextoname.c
new file mode 100644 (file)
index 0000000..255e33e
--- /dev/null
@@ -0,0 +1,23 @@
+#include       "unp.h"
+
+/*
+ * This is a placeholder if the system does not provide this RFC 2133
+ * function.  If routing sockets with sysctl() are provided, then the
+ * if_XXX() functions in the libroute/ directory will replace these.
+ */
+
+char *
+if_indextoname(unsigned int index, char *name)
+{
+       return(NULL);
+}
+
+char *
+If_indextoname(unsigned int index, char *name)
+{
+       char    *ptr;
+
+       if ( (ptr = if_indextoname(index, name)) == NULL)
+               err_quit("if_indextoname error for %d", index);
+       return(ptr);
+}
diff --git a/lib/if_nameindex.c b/lib/if_nameindex.c
new file mode 100644 (file)
index 0000000..3519faf
--- /dev/null
@@ -0,0 +1,28 @@
+#include       "unp.h"
+
+/*
+ * This is a placeholder if the system does not provide this RFC 2133
+ * function.  If routing sockets with sysctl() are provided, then the
+ * if_XXX() functions in the libroute/ directory will replace these.
+ */
+
+struct if_nameindex *
+if_nameindex(void)
+{
+       return(NULL);
+}
+
+void
+if_freenameindex(struct if_nameindex *ptr)
+{
+}
+
+struct if_nameindex *
+If_nameindex(void)
+{
+       struct if_nameindex     *ifptr;
+
+       if ( (ifptr = if_nameindex()) == NULL)
+               err_quit("if_nameindex error");
+       return(ifptr);
+}
diff --git a/lib/if_nametoindex.c b/lib/if_nametoindex.c
new file mode 100644 (file)
index 0000000..87276f6
--- /dev/null
@@ -0,0 +1,23 @@
+#include       "unp.h"
+
+/*
+ * This is a placeholder if the system does not provide this RFC 2133
+ * function.  If routing sockets with sysctl() are provided, then the
+ * if_XXX() functions in the libroute/ directory will replace these.
+ */
+
+unsigned int
+if_nametoindex(const char *name)
+{
+       return(0);
+}
+
+unsigned int
+If_nametoindex(const char *name)
+{
+       int             index;
+
+       if ( (index = if_nametoindex(name)) == 0)
+               err_quit("if_nametoindex error for %s", name);
+       return(index);
+}
diff --git a/lib/in6addr_any.c b/lib/in6addr_any.c
new file mode 100644 (file)
index 0000000..ea62e9f
--- /dev/null
@@ -0,0 +1,5 @@
+#include       "unp.h"
+
+#ifdef IPV6
+const struct in6_addr in6addr_any;
+#endif
diff --git a/lib/mcast_get_if.c b/lib/mcast_get_if.c
new file mode 100644 (file)
index 0000000..da6a528
--- /dev/null
@@ -0,0 +1,39 @@
+#include       "unp.h"
+
+int
+mcast_get_if(int sockfd)
+{
+       switch (sockfd_to_family(sockfd)) {
+       case AF_INET: {
+               /* TODO: similar to mcast_set_if() */
+               return(-1);
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               u_int           idx;
+               socklen_t       len;
+
+               len = sizeof(idx);
+               if (getsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+                                          &idx, &len) < 0)
+                       return(-1);
+               return(idx);
+       }
+#endif
+
+       default:
+               errno = EAFNOSUPPORT;
+               return(-1);
+       }
+}
+
+int
+Mcast_get_if(int sockfd)
+{
+       int             rc;
+
+       if ( (rc = mcast_get_if(sockfd)) < 0)
+               err_sys("mcast_get_if error");
+       return(rc);
+}
diff --git a/lib/mcast_get_loop.c b/lib/mcast_get_loop.c
new file mode 100644 (file)
index 0000000..553abe2
--- /dev/null
@@ -0,0 +1,45 @@
+#include       "unp.h"
+
+int
+mcast_get_loop(int sockfd)
+{
+       switch (sockfd_to_family(sockfd)) {
+       case AF_INET: {
+               u_char          flag;
+               socklen_t       len;
+
+               len = sizeof(flag);
+               if (getsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP,
+                                          &flag, &len) < 0)
+                       return(-1);
+               return(flag);
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               u_int           flag;
+               socklen_t       len;
+
+               len = sizeof(flag);
+               if (getsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
+                                          &flag, &len) < 0)
+                       return(-1);
+               return(flag);
+       }
+#endif
+
+       default:
+               errno = EAFNOSUPPORT;
+               return(-1);
+       }
+}
+
+int
+Mcast_get_loop(int sockfd)
+{
+       int             rc;
+
+       if ( (rc = mcast_get_loop(sockfd)) < 0)
+               err_sys("mcast_get_loop error");
+       return(rc);
+}
diff --git a/lib/mcast_get_ttl.c b/lib/mcast_get_ttl.c
new file mode 100644 (file)
index 0000000..b3fe107
--- /dev/null
@@ -0,0 +1,45 @@
+#include       "unp.h"
+
+int
+mcast_get_ttl(int sockfd)
+{
+       switch (sockfd_to_family(sockfd)) {
+       case AF_INET: {
+               u_char          ttl;
+               socklen_t       len;
+
+               len = sizeof(ttl);
+               if (getsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,
+                                          &ttl, &len) < 0)
+                       return(-1);
+               return(ttl);
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               int                     hop;
+               socklen_t       len;
+
+               len = sizeof(hop);
+               if (getsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+                                          &hop, &len) < 0)
+                       return(-1);
+               return(hop);
+       }
+#endif
+
+       default:
+               errno = EAFNOSUPPORT;
+               return(-1);
+       }
+}
+
+int
+Mcast_get_ttl(int sockfd)
+{
+       int             rc;
+
+       if ( (rc = mcast_get_ttl(sockfd)) < 0)
+               err_sys("mcast_get_ttl error");
+       return(rc);
+}
diff --git a/lib/mcast_join.c b/lib/mcast_join.c
new file mode 100644 (file)
index 0000000..26a6375
--- /dev/null
@@ -0,0 +1,287 @@
+/* include mcast_join1 */
+#include       "unp.h"
+#include       <net/if.h>
+
+int
+mcast_join(int sockfd, const SA *grp, socklen_t grplen,
+                  const char *ifname, u_int ifindex)
+{
+#ifdef MCAST_JOIN_GROUP
+       struct group_req req;
+       if (ifindex > 0) {
+               req.gr_interface = ifindex;
+       } else if (ifname != NULL) {
+               if ( (req.gr_interface = if_nametoindex(ifname)) == 0) {
+                       errno = ENXIO;  /* i/f name not found */
+                       return(-1);
+               }
+       } else
+               req.gr_interface = 0;
+       if (grplen > sizeof(req.gr_group)) {
+               errno = EINVAL;
+               return -1;
+       }
+       memcpy(&req.gr_group, grp, grplen);
+       return (setsockopt(sockfd, family_to_level(grp->sa_family),
+                       MCAST_JOIN_GROUP, &req, sizeof(req)));
+#else
+/* end mcast_join1 */
+
+/* include mcast_join2 */
+       switch (grp->sa_family) {
+       case AF_INET: {
+               struct ip_mreq          mreq;
+               struct ifreq            ifreq;
+
+               memcpy(&mreq.imr_multiaddr,
+                          &((const struct sockaddr_in *) grp)->sin_addr,
+                          sizeof(struct in_addr));
+
+               if (ifindex > 0) {
+                       if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) {
+                               errno = ENXIO;  /* i/f index not found */
+                               return(-1);
+                       }
+                       goto doioctl;
+               } else if (ifname != NULL) {
+                       strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);
+doioctl:
+                       if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0)
+                               return(-1);
+                       memcpy(&mreq.imr_interface,
+                                  &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr,
+                                  sizeof(struct in_addr));
+               } else
+                       mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+
+               return(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+                                                 &mreq, sizeof(mreq)));
+       }
+/* end mcast_join2 */
+
+/* include mcast_join3 */
+#ifdef IPV6
+#ifndef        IPV6_JOIN_GROUP         /* APIv0 compatibility */
+#define        IPV6_JOIN_GROUP         IPV6_ADD_MEMBERSHIP
+#endif
+       case AF_INET6: {
+               struct ipv6_mreq        mreq6;
+
+               memcpy(&mreq6.ipv6mr_multiaddr,
+                          &((const struct sockaddr_in6 *) grp)->sin6_addr,
+                          sizeof(struct in6_addr));
+
+               if (ifindex > 0) {
+                       mreq6.ipv6mr_interface = ifindex;
+               } else if (ifname != NULL) {
+                       if ( (mreq6.ipv6mr_interface = if_nametoindex(ifname)) == 0) {
+                               errno = ENXIO;  /* i/f name not found */
+                               return(-1);
+                       }
+               } else
+                       mreq6.ipv6mr_interface = 0;
+
+               return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
+                                                 &mreq6, sizeof(mreq6)));
+       }
+#endif
+
+       default:
+               errno = EAFNOSUPPORT;
+               return(-1);
+       }
+#endif
+}
+/* end mcast_join3 */
+
+void
+Mcast_join(int sockfd, const SA *grp, socklen_t grplen,
+                  const char *ifname, u_int ifindex)
+{
+       if (mcast_join(sockfd, grp, grplen, ifname, ifindex) < 0)
+               err_sys("mcast_join error");
+}
+
+int
+mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen,
+                                               const SA *grp, socklen_t grplen,
+                                               const char *ifname, u_int ifindex)
+{
+#ifdef MCAST_JOIN_SOURCE_GROUP
+       struct group_source_req req;
+       if (ifindex > 0) {
+               req.gsr_interface = ifindex;
+       } else if (ifname != NULL) {
+               if ( (req.gsr_interface = if_nametoindex(ifname)) == 0) {
+                       errno = ENXIO;  /* i/f name not found */
+                       return(-1);
+               }
+       } else
+               req.gsr_interface = 0;
+       if (grplen > sizeof(req.gsr_group) || srclen > sizeof(req.gsr_source)) {
+               errno = EINVAL;
+               return -1;
+       }
+       memcpy(&req.gsr_group, grp, grplen);
+       memcpy(&req.gsr_source, src, srclen);
+       return (setsockopt(sockfd, family_to_level(grp->sa_family),
+                       MCAST_JOIN_SOURCE_GROUP, &req, sizeof(req)));
+#else
+       switch (grp->sa_family) {
+#ifdef IP_ADD_SOURCE_MEMBERSHIP
+       case AF_INET: {
+               struct ip_mreq_source   mreq;
+               struct ifreq                    ifreq;
+
+               memcpy(&mreq.imr_multiaddr,
+                          &((struct sockaddr_in *) grp)->sin_addr,
+                          sizeof(struct in_addr));
+               memcpy(&mreq.imr_sourceaddr,
+                          &((struct sockaddr_in *) src)->sin_addr,
+                          sizeof(struct in_addr));
+
+               if (ifindex > 0) {
+                       if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) {
+                               errno = ENXIO;  /* i/f index not found */
+                               return(-1);
+                       }
+                       goto doioctl;
+               } else if (ifname != NULL) {
+                       strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);
+doioctl:
+                       if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0)
+                               return(-1);
+                       memcpy(&mreq.imr_interface,
+                                  &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr,
+                                  sizeof(struct in_addr));
+               } else
+                       mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+
+               return(setsockopt(sockfd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP,
+                                                 &mreq, sizeof(mreq)));
+       }
+#endif
+
+#ifdef IPV6
+       case AF_INET6: /* IPv6 source-specific API is MCAST_JOIN_SOURCE_GROUP */
+#endif
+       default:
+               errno = EAFNOSUPPORT;
+               return(-1);
+       }
+#endif
+}
+
+void
+Mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen,
+                                               const SA *grp, socklen_t grplen,
+                                               const char *ifname, u_int ifindex)
+{
+       if (mcast_join_source_group(sockfd, src, srclen, grp, grplen,
+                                                               ifname, ifindex) < 0)
+               err_sys("mcast_join_source_group error");
+}
+
+int
+mcast_block_source(int sockfd, const SA *src, socklen_t srclen,
+                                               const SA *grp, socklen_t grplen)
+{
+#ifdef MCAST_BLOCK_SOURCE
+       struct group_source_req req;
+       req.gsr_interface = 0;
+       if (grplen > sizeof(req.gsr_group) || srclen > sizeof(req.gsr_source)) {
+               errno = EINVAL;
+               return -1;
+       }
+       memcpy(&req.gsr_group, grp, grplen);
+       memcpy(&req.gsr_source, src, srclen);
+       return (setsockopt(sockfd, family_to_level(grp->sa_family),
+                       MCAST_BLOCK_SOURCE, &req, sizeof(req)));
+#else
+       switch (grp->sa_family) {
+#ifdef IP_BLOCK_SOURCE
+       case AF_INET: {
+               struct ip_mreq_source   mreq;
+
+               memcpy(&mreq.imr_multiaddr,
+                          &((struct sockaddr_in *) grp)->sin_addr,
+                          sizeof(struct in_addr));
+               memcpy(&mreq.imr_sourceaddr,
+                          &((struct sockaddr_in *) src)->sin_addr,
+                          sizeof(struct in_addr));
+               mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+
+               return(setsockopt(sockfd, IPPROTO_IP, IP_BLOCK_SOURCE,
+                                                 &mreq, sizeof(mreq)));
+       }
+#endif
+
+#ifdef IPV6
+       case AF_INET6: /* IPv6 source-specific API is MCAST_BLOCK_SOURCE */
+#endif
+       default:
+               errno = EAFNOSUPPORT;
+               return(-1);
+       }
+#endif
+}
+
+void
+Mcast_block_source(int sockfd, const SA *src, socklen_t srclen,
+                                               const SA *grp, socklen_t grplen)
+{
+       if (mcast_block_source(sockfd, src, srclen, grp, grplen) < 0)
+               err_sys("mcast_block_source error");
+}
+
+int
+mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen,
+                                               const SA *grp, socklen_t grplen)
+{
+#ifdef MCAST_UNBLOCK_SOURCE
+       struct group_source_req req;
+       req.gsr_interface = 0;
+       if (grplen > sizeof(req.gsr_group) || srclen > sizeof(req.gsr_source)) {
+               errno = EINVAL;
+               return -1;
+       }
+       memcpy(&req.gsr_group, grp, grplen);
+       memcpy(&req.gsr_source, src, srclen);
+       return (setsockopt(sockfd, family_to_level(grp->sa_family),
+                       MCAST_UNBLOCK_SOURCE, &req, sizeof(req)));
+#else
+       switch (grp->sa_family) {
+#ifdef IP_UNBLOCK_SOURCE
+       case AF_INET: {
+               struct ip_mreq_source   mreq;
+
+               memcpy(&mreq.imr_multiaddr,
+                          &((struct sockaddr_in *) grp)->sin_addr,
+                          sizeof(struct in_addr));
+               memcpy(&mreq.imr_sourceaddr,
+                          &((struct sockaddr_in *) src)->sin_addr,
+                          sizeof(struct in_addr));
+               mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+
+               return(setsockopt(sockfd, IPPROTO_IP, IP_UNBLOCK_SOURCE,
+                                                 &mreq, sizeof(mreq)));
+       }
+#endif
+
+#ifdef IPV6
+       case AF_INET6: /* IPv6 source-specific API is MCAST_UNBLOCK_SOURCE */
+#endif
+       default:
+               errno = EAFNOSUPPORT;
+               return(-1);
+       }
+#endif
+}
+
+void
+Mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen,
+                                               const SA *grp, socklen_t grplen)
+{
+       if (mcast_unblock_source(sockfd, src, srclen, grp, grplen) < 0)
+               err_sys("mcast_unblock_source error");
+}
diff --git a/lib/mcast_join.lc b/lib/mcast_join.lc
new file mode 100644 (file)
index 0000000..9c4b02e
--- /dev/null
@@ -0,0 +1,271 @@
+/* include mcast_join1 */
+#include    "unp.h"##  1 ##src/lib/mcast_join.c##
+#include    <net/if.h>##  2 ##src/lib/mcast_join.c##
+
+int##  3 ##src/lib/mcast_join.c##
+mcast_join(int sockfd, const SA *grp, socklen_t grplen,##  4 ##src/lib/mcast_join.c##
+           const char *ifname, u_int ifindex)##  5 ##src/lib/mcast_join.c##
+{##  6 ##src/lib/mcast_join.c##
+#ifdef MCAST_JOIN_GROUP##  7 ##src/lib/mcast_join.c##
+    struct group_req req;##  8 ##src/lib/mcast_join.c##
+    if (ifindex > 0) {##  9 ##src/lib/mcast_join.c##
+        req.gr_interface = ifindex;## 10 ##src/lib/mcast_join.c##
+    } else if (ifname != NULL) {## 11 ##src/lib/mcast_join.c##
+        if ((req.gr_interface = if_nametoindex(ifname)) == 0) {## 12 ##src/lib/mcast_join.c##
+            errno = ENXIO;      /* i/f name not found */## 13 ##src/lib/mcast_join.c##
+            return (-1);## 14 ##src/lib/mcast_join.c##
+        }## 15 ##src/lib/mcast_join.c##
+    } else## 16 ##src/lib/mcast_join.c##
+        req.gr_interface = 0;## 17 ##src/lib/mcast_join.c##
+    memcpy(&req.gr_group, grp, grplen);## 18 ##src/lib/mcast_join.c##
+    return (setsockopt(sockfd, family_to_level(grp->sa_family),## 19 ##src/lib/mcast_join.c##
+                       MCAST_JOIN_GROUP, &req, sizeof(req)));## 20 ##src/lib/mcast_join.c##
+/* end mcast_join1 */
+#else## 21 ##src/lib/mcast_join.c##
+
+/* include mcast_join2 */
+    switch (grp->sa_family) {## 22 ##src/lib/mcast_join.c##
+    case AF_INET:{## 23 ##src/lib/mcast_join.c##
+            struct ip_mreq mreq;## 24 ##src/lib/mcast_join.c##
+            struct ifreq ifreq;## 25 ##src/lib/mcast_join.c##
+
+            memcpy(&mreq.imr_multiaddr,## 26 ##src/lib/mcast_join.c##
+                   &((const struct sockaddr_in *) grp)->sin_addr,## 27 ##src/lib/mcast_join.c##
+                   sizeof(struct in_addr));## 28 ##src/lib/mcast_join.c##
+
+            if (ifindex > 0) {## 29 ##src/lib/mcast_join.c##
+                if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) {## 30 ##src/lib/mcast_join.c##
+                    errno = ENXIO;  /* i/f index not found */## 31 ##src/lib/mcast_join.c##
+                    return (-1);## 32 ##src/lib/mcast_join.c##
+                }## 33 ##src/lib/mcast_join.c##
+                goto doioctl;## 34 ##src/lib/mcast_join.c##
+            } else if (ifname != NULL) {## 35 ##src/lib/mcast_join.c##
+                strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);## 36 ##src/lib/mcast_join.c##
+              doioctl:## 37 ##src/lib/mcast_join.c##
+                if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0)## 38 ##src/lib/mcast_join.c##
+                    return (-1);## 39 ##src/lib/mcast_join.c##
+                memcpy(&mreq.imr_interface,## 40 ##src/lib/mcast_join.c##
+                       &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr,## 41 ##src/lib/mcast_join.c##
+                       sizeof(struct in_addr));## 42 ##src/lib/mcast_join.c##
+            } else## 43 ##src/lib/mcast_join.c##
+                mreq.imr_interface.s_addr = htonl(INADDR_ANY);## 44 ##src/lib/mcast_join.c##
+
+            return (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,## 45 ##src/lib/mcast_join.c##
+                               &mreq, sizeof(mreq)));## 46 ##src/lib/mcast_join.c##
+        }## 47 ##src/lib/mcast_join.c##
+/* end mcast_join2 */
+
+/* include mcast_join3 */
+#ifdef  IPV6## 48 ##src/lib/mcast_join.c##
+#ifndef IPV6_JOIN_GROUP         /* APIv0 compatibility */## 49 ##src/lib/mcast_join.c##
+#define IPV6_JOIN_GROUP     IPV6_ADD_MEMBERSHIP## 50 ##src/lib/mcast_join.c##
+#endif## 51 ##src/lib/mcast_join.c##
+    case AF_INET6:{## 52 ##src/lib/mcast_join.c##
+            struct ipv6_mreq mreq6;## 53 ##src/lib/mcast_join.c##
+
+            memcpy(&mreq6.ipv6mr_multiaddr,## 54 ##src/lib/mcast_join.c##
+                   &((const struct sockaddr_in6 *) grp)->sin6_addr,## 55 ##src/lib/mcast_join.c##
+                   sizeof(struct in6_addr));## 56 ##src/lib/mcast_join.c##
+
+            if (ifindex > 0) {## 57 ##src/lib/mcast_join.c##
+                mreq6.ipv6mr_interface = ifindex;## 58 ##src/lib/mcast_join.c##
+            } else if (ifname != NULL) {## 59 ##src/lib/mcast_join.c##
+                if ((mreq6.ipv6mr_interface = if_nametoindex(ifname)) == 0) {## 60 ##src/lib/mcast_join.c##
+                    errno = ENXIO;  /* i/f name not found */## 61 ##src/lib/mcast_join.c##
+                    return (-1);## 62 ##src/lib/mcast_join.c##
+                }## 63 ##src/lib/mcast_join.c##
+            } else## 64 ##src/lib/mcast_join.c##
+                mreq6.ipv6mr_interface = 0;## 65 ##src/lib/mcast_join.c##
+
+            return (setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP,## 66 ##src/lib/mcast_join.c##
+                               &mreq6, sizeof(mreq6)));## 67 ##src/lib/mcast_join.c##
+        }## 68 ##src/lib/mcast_join.c##
+#endif## 69 ##src/lib/mcast_join.c##
+
+    default:## 70 ##src/lib/mcast_join.c##
+        errno = EPROTONOSUPPORT;## 71 ##src/lib/mcast_join.c##
+        return (-1);## 72 ##src/lib/mcast_join.c##
+    }## 73 ##src/lib/mcast_join.c##
+#endif## 74 ##src/lib/mcast_join.c##
+}## 75 ##src/lib/mcast_join.c##
+/* end mcast_join3 */
+
+void## 76 ##src/lib/mcast_join.c##
+Mcast_join(int sockfd, const SA *grp, socklen_t grplen,## 77 ##src/lib/mcast_join.c##
+           const char *ifname, u_int ifindex)## 78 ##src/lib/mcast_join.c##
+{## 79 ##src/lib/mcast_join.c##
+    if (mcast_join(sockfd, grp, grplen, ifname, ifindex) < 0)## 80 ##src/lib/mcast_join.c##
+        err_sys("mcast_join error");## 81 ##src/lib/mcast_join.c##
+}## 82 ##src/lib/mcast_join.c##
+
+int## 83 ##src/lib/mcast_join.c##
+mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen,## 84 ##src/lib/mcast_join.c##
+                        const SA *grp, socklen_t grplen,## 85 ##src/lib/mcast_join.c##
+                        const char *ifname, u_int ifindex)## 86 ##src/lib/mcast_join.c##
+{## 87 ##src/lib/mcast_join.c##
+#ifdef MCAST_JOIN_SOURCE_GROUP## 88 ##src/lib/mcast_join.c##
+    struct group_source_req req;## 89 ##src/lib/mcast_join.c##
+    if (ifindex > 0) {## 90 ##src/lib/mcast_join.c##
+        req.gr_interface = ifindex;## 91 ##src/lib/mcast_join.c##
+    } else if (ifname != NULL) {## 92 ##src/lib/mcast_join.c##
+        if ((req.gr_interface = if_nametoindex(ifname)) == 0) {## 93 ##src/lib/mcast_join.c##
+            errno = ENXIO;      /* i/f name not found */## 94 ##src/lib/mcast_join.c##
+            return (-1);## 95 ##src/lib/mcast_join.c##
+        }## 96 ##src/lib/mcast_join.c##
+    } else## 97 ##src/lib/mcast_join.c##
+        req.gr_interface = 0;## 98 ##src/lib/mcast_join.c##
+    memcpy(&req.gr_group, grp, grplen);## 99 ##src/lib/mcast_join.c##
+    memcpy(&req.gr_src, src, srclen);##100 ##src/lib/mcast_join.c##
+    return (setsockopt(sockfd, family_to_level(grp->sa_family),##101 ##src/lib/mcast_join.c##
+                       MCAST_JOIN_SOURCE_GROUP, &req, sizeof(req)));##102 ##src/lib/mcast_join.c##
+#else##103 ##src/lib/mcast_join.c##
+    switch (grp->sa_family) {##104 ##src/lib/mcast_join.c##
+#ifdef IP_ADD_SOURCE_MEMBERSHIP##105 ##src/lib/mcast_join.c##
+    case AF_INET:{##106 ##src/lib/mcast_join.c##
+            struct ip_mreq_source mreq;##107 ##src/lib/mcast_join.c##
+            struct ifreq ifreq;##108 ##src/lib/mcast_join.c##
+
+            memcpy(&mreq.imr_multiaddr,##109 ##src/lib/mcast_join.c##
+                   &((struct sockaddr_in *) grp)->sin_addr,##110 ##src/lib/mcast_join.c##
+                   sizeof(struct in_addr));##111 ##src/lib/mcast_join.c##
+            memcpy(&mreq.imr_sourceaddr,##112 ##src/lib/mcast_join.c##
+                   &((struct sockaddr_in *) src)->sin_addr,##113 ##src/lib/mcast_join.c##
+                   sizeof(struct in_addr));##114 ##src/lib/mcast_join.c##
+
+            if (ifindex > 0) {##115 ##src/lib/mcast_join.c##
+                if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) {##116 ##src/lib/mcast_join.c##
+                    errno = ENXIO;  /* i/f index not found */##117 ##src/lib/mcast_join.c##
+                    return (-1);##118 ##src/lib/mcast_join.c##
+                }##119 ##src/lib/mcast_join.c##
+                goto doioctl;##120 ##src/lib/mcast_join.c##
+            } else if (ifname != NULL) {##121 ##src/lib/mcast_join.c##
+                strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);##122 ##src/lib/mcast_join.c##
+              doioctl:##123 ##src/lib/mcast_join.c##
+                if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0)##124 ##src/lib/mcast_join.c##
+                    return (-1);##125 ##src/lib/mcast_join.c##
+                memcpy(&mreq.imr_interface,##126 ##src/lib/mcast_join.c##
+                       &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr,##127 ##src/lib/mcast_join.c##
+                       sizeof(struct in_addr));##128 ##src/lib/mcast_join.c##
+            } else##129 ##src/lib/mcast_join.c##
+                mreq.imr_interface.s_addr = htonl(INADDR_ANY);##130 ##src/lib/mcast_join.c##
+
+            return (setsockopt(sockfd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP,##131 ##src/lib/mcast_join.c##
+                               &mreq, sizeof(mreq)));##132 ##src/lib/mcast_join.c##
+        }##133 ##src/lib/mcast_join.c##
+#endif##134 ##src/lib/mcast_join.c##
+
+#ifdef  IPV6##135 ##src/lib/mcast_join.c##
+    case AF_INET6:              /* IPv6 source-specific API is MCAST_JOIN_SOURCE_GROUP */##136 ##src/lib/mcast_join.c##
+#endif##137 ##src/lib/mcast_join.c##
+    default:##138 ##src/lib/mcast_join.c##
+        errno = EPROTONOSUPPORT;##139 ##src/lib/mcast_join.c##
+        return (-1);##140 ##src/lib/mcast_join.c##
+    }##141 ##src/lib/mcast_join.c##
+#endif##142 ##src/lib/mcast_join.c##
+}##143 ##src/lib/mcast_join.c##
+
+void##144 ##src/lib/mcast_join.c##
+Mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen,##145 ##src/lib/mcast_join.c##
+                        const SA *grp, socklen_t grplen,##146 ##src/lib/mcast_join.c##
+                        const char *ifname, u_int ifindex)##147 ##src/lib/mcast_join.c##
+{##148 ##src/lib/mcast_join.c##
+    if (mcast_join_source_group(sockfd, src, srclen, grp, grplen,##149 ##src/lib/mcast_join.c##
+                                ifname, ifindex) < 0)##150 ##src/lib/mcast_join.c##
+        err_sys("mcast_join_source_group error");##151 ##src/lib/mcast_join.c##
+}##152 ##src/lib/mcast_join.c##
+
+int##153 ##src/lib/mcast_join.c##
+mcast_block_source(int sockfd, const SA *src, socklen_t srclen,##154 ##src/lib/mcast_join.c##
+                   const SA *grp, socklen_t grplen)##155 ##src/lib/mcast_join.c##
+{##156 ##src/lib/mcast_join.c##
+#ifdef MCAST_BLOCK_SOURCE##157 ##src/lib/mcast_join.c##
+    struct group_source_req req;##158 ##src/lib/mcast_join.c##
+    req.gr_interface = 0;##159 ##src/lib/mcast_join.c##
+    memcpy(&req.gr_group, grp, grplen);##160 ##src/lib/mcast_join.c##
+    memcpy(&req.gr_src, src, srclen);##161 ##src/lib/mcast_join.c##
+    return (setsockopt(sockfd, family_to_level(grp->sa_family),##162 ##src/lib/mcast_join.c##
+                       MCAST_BLOCK_SOURCE, &req, sizeof(req)));##163 ##src/lib/mcast_join.c##
+#else##164 ##src/lib/mcast_join.c##
+    switch (grp->sa_family) {##165 ##src/lib/mcast_join.c##
+#ifdef IP_BLOCK_SOURCE##166 ##src/lib/mcast_join.c##
+    case AF_INET:{##167 ##src/lib/mcast_join.c##
+            struct ip_mreq_source mreq;##168 ##src/lib/mcast_join.c##
+
+            memcpy(&mreq.imr_multiaddr,##169 ##src/lib/mcast_join.c##
+                   &((struct sockaddr_in *) grp)->sin_addr,##170 ##src/lib/mcast_join.c##
+                   sizeof(struct in_addr));##171 ##src/lib/mcast_join.c##
+            memcpy(&mreq.imr_sourceaddr,##172 ##src/lib/mcast_join.c##
+                   &((struct sockaddr_in *) src)->sin_addr,##173 ##src/lib/mcast_join.c##
+                   sizeof(struct in_addr));##174 ##src/lib/mcast_join.c##
+            mreq.imr_interface.s_addr = htonl(INADDR_ANY);##175 ##src/lib/mcast_join.c##
+
+            return (setsockopt(sockfd, IPPROTO_IP, IP_BLOCK_SOURCE,##176 ##src/lib/mcast_join.c##
+                               &mreq, sizeof(mreq)));##177 ##src/lib/mcast_join.c##
+        }##178 ##src/lib/mcast_join.c##
+#endif##179 ##src/lib/mcast_join.c##
+
+#ifdef  IPV6##180 ##src/lib/mcast_join.c##
+    case AF_INET6:              /* IPv6 source-specific API is MCAST_BLOCK_SOURCE */##181 ##src/lib/mcast_join.c##
+#endif##182 ##src/lib/mcast_join.c##
+    default:##183 ##src/lib/mcast_join.c##
+        errno = EPROTONOSUPPORT;##184 ##src/lib/mcast_join.c##
+        return (-1);##185 ##src/lib/mcast_join.c##
+    }##186 ##src/lib/mcast_join.c##
+#endif##187 ##src/lib/mcast_join.c##
+}##188 ##src/lib/mcast_join.c##
+
+void##189 ##src/lib/mcast_join.c##
+Mcast_block_source(int sockfd, const SA *src, socklen_t srclen,##190 ##src/lib/mcast_join.c##
+                   const SA *grp, socklen_t grplen)##191 ##src/lib/mcast_join.c##
+{##192 ##src/lib/mcast_join.c##
+    if (mcast_block_source(sockfd, src, srclen, grp, grplen) < 0)##193 ##src/lib/mcast_join.c##
+        err_sys("mcast_block_source error");##194 ##src/lib/mcast_join.c##
+}##195 ##src/lib/mcast_join.c##
+
+int##196 ##src/lib/mcast_join.c##
+mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen,##197 ##src/lib/mcast_join.c##
+                     const SA *grp, socklen_t grplen)##198 ##src/lib/mcast_join.c##
+{##199 ##src/lib/mcast_join.c##
+#ifdef MCAST_UNBLOCK_SOURCE##200 ##src/lib/mcast_join.c##
+    struct group_source_req req;##201 ##src/lib/mcast_join.c##
+    req.gr_interface = 0;##202 ##src/lib/mcast_join.c##
+    memcpy(&req.gr_group, grp, grplen);##203 ##src/lib/mcast_join.c##
+    memcpy(&req.gr_src, src, srclen);##204 ##src/lib/mcast_join.c##
+    return (setsockopt(sockfd, family_to_level(grp->sa_family),##205 ##src/lib/mcast_join.c##
+                       MCAST_UNBLOCK_SOURCE, &req, sizeof(req)));##206 ##src/lib/mcast_join.c##
+#else##207 ##src/lib/mcast_join.c##
+    switch (grp->sa_family) {##208 ##src/lib/mcast_join.c##
+#ifdef IP_UNBLOCK_SOURCE##209 ##src/lib/mcast_join.c##
+    case AF_INET:{##210 ##src/lib/mcast_join.c##
+            struct ip_mreq_source mreq;##211 ##src/lib/mcast_join.c##
+
+            memcpy(&mreq.imr_multiaddr,##212 ##src/lib/mcast_join.c##
+                   &((struct sockaddr_in *) grp)->sin_addr,##213 ##src/lib/mcast_join.c##
+                   sizeof(struct in_addr));##214 ##src/lib/mcast_join.c##
+            memcpy(&mreq.imr_sourceaddr,##215 ##src/lib/mcast_join.c##
+                   &((struct sockaddr_in *) src)->sin_addr,##216 ##src/lib/mcast_join.c##
+                   sizeof(struct in_addr));##217 ##src/lib/mcast_join.c##
+            mreq.imr_interface.s_addr = htonl(INADDR_ANY);##218 ##src/lib/mcast_join.c##
+
+            return (setsockopt(sockfd, IPPROTO_IP, IP_UNBLOCK_SOURCE,##219 ##src/lib/mcast_join.c##
+                               &mreq, sizeof(mreq)));##220 ##src/lib/mcast_join.c##
+        }##221 ##src/lib/mcast_join.c##
+#endif##222 ##src/lib/mcast_join.c##
+
+#ifdef  IPV6##223 ##src/lib/mcast_join.c##
+    case AF_INET6:              /* IPv6 source-specific API is MCAST_UNBLOCK_SOURCE */##224 ##src/lib/mcast_join.c##
+#endif##225 ##src/lib/mcast_join.c##
+    default:##226 ##src/lib/mcast_join.c##
+        errno = EPROTONOSUPPORT;##227 ##src/lib/mcast_join.c##
+        return (-1);##228 ##src/lib/mcast_join.c##
+    }##229 ##src/lib/mcast_join.c##
+#endif##230 ##src/lib/mcast_join.c##
+}##231 ##src/lib/mcast_join.c##
+
+void##232 ##src/lib/mcast_join.c##
+Mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen,##233 ##src/lib/mcast_join.c##
+                     const SA *grp, socklen_t grplen)##234 ##src/lib/mcast_join.c##
+{##235 ##src/lib/mcast_join.c##
+    if (mcast_unblock_source(sockfd, src, srclen, grp, grplen) < 0)##236 ##src/lib/mcast_join.c##
+        err_sys("mcast_unblock_source error");##237 ##src/lib/mcast_join.c##
+}##238 ##src/lib/mcast_join.c##
diff --git a/lib/mcast_leave.c b/lib/mcast_leave.c
new file mode 100644 (file)
index 0000000..b899512
--- /dev/null
@@ -0,0 +1,109 @@
+#include       "unp.h"
+
+int
+mcast_leave(int sockfd, const SA *grp, socklen_t grplen)
+{
+#ifdef MCAST_JOIN_GROUP
+       struct group_req req;
+       req.gr_interface = 0;
+       if (grplen > sizeof(req.gr_group)) {
+               errno = EINVAL;
+               return -1;
+       }
+       memcpy(&req.gr_group, grp, grplen);
+       return (setsockopt(sockfd, family_to_level(grp->sa_family),
+                       MCAST_LEAVE_GROUP, &req, sizeof(req)));
+#else
+       switch (grp->sa_family) {
+       case AF_INET: {
+               struct ip_mreq          mreq;
+
+               memcpy(&mreq.imr_multiaddr,
+                          &((const struct sockaddr_in *) grp)->sin_addr,
+                          sizeof(struct in_addr));
+               mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+               return(setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+                                                 &mreq, sizeof(mreq)));
+       }
+
+#ifdef IPV6
+#ifndef        IPV6_LEAVE_GROUP        /* APIv0 compatibility */
+#define        IPV6_LEAVE_GROUP        IPV6_DROP_MEMBERSHIP
+#endif
+       case AF_INET6: {
+               struct ipv6_mreq        mreq6;
+
+               memcpy(&mreq6.ipv6mr_multiaddr,
+                          &((const struct sockaddr_in6 *) grp)->sin6_addr,
+                          sizeof(struct in6_addr));
+               mreq6.ipv6mr_interface = 0;
+               return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
+                                                 &mreq6, sizeof(mreq6)));
+       }
+#endif
+
+       default:
+               errno = EAFNOSUPPORT;
+               return(-1);
+       }
+#endif
+}
+
+void
+Mcast_leave(int sockfd, const SA *grp, socklen_t grplen)
+{
+       if (mcast_leave(sockfd, grp, grplen) < 0)
+               err_sys("mcast_leave error");
+}
+
+int
+mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen,
+                                               const SA *grp, socklen_t grplen)
+{
+#ifdef MCAST_LEAVE_SOURCE_GROUP
+       struct group_source_req req;
+       req.gsr_interface = 0;
+       if (grplen > sizeof(req.gsr_group) || srclen > sizeof(req.gsr_source)) {
+               errno = EINVAL;
+               return -1;
+       }
+       memcpy(&req.gsr_group, grp, grplen);
+       memcpy(&req.gsr_source, src, srclen);
+       return (setsockopt(sockfd, family_to_level(grp->sa_family),
+                       MCAST_LEAVE_SOURCE_GROUP, &req, sizeof(req)));
+#else
+       switch (grp->sa_family) {
+#ifdef IP_DROP_SOURCE_MEMBERSHIP
+       case AF_INET: {
+               struct ip_mreq_source   mreq;
+
+               memcpy(&mreq.imr_multiaddr,
+                          &((struct sockaddr_in *) grp)->sin_addr,
+                          sizeof(struct in_addr));
+               memcpy(&mreq.imr_sourceaddr,
+                          &((struct sockaddr_in *) src)->sin_addr,
+                          sizeof(struct in_addr));
+               mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+
+               return(setsockopt(sockfd, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP,
+                                                 &mreq, sizeof(mreq)));
+       }
+#endif
+
+#ifdef IPV6
+       case AF_INET6: /* IPv6 source-specific API is MCAST_LEAVE_SOURCE_GROUP */
+#endif
+       default:
+               errno = EAFNOSUPPORT;
+               return(-1);
+       }
+#endif
+}
+
+void
+Mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen,
+                                               const SA *grp, socklen_t grplen)
+{
+       if (mcast_leave_source_group(sockfd, src, srclen, grp, grplen) < 0)
+               err_sys("mcast_leave_source_group error");
+}
diff --git a/lib/mcast_set_if.c b/lib/mcast_set_if.c
new file mode 100644 (file)
index 0000000..87bf450
--- /dev/null
@@ -0,0 +1,63 @@
+#include       "unp.h"
+#include       <net/if.h>
+
+int
+mcast_set_if(int sockfd, const char *ifname, u_int ifindex)
+{
+       switch (sockfd_to_family(sockfd)) {
+       case AF_INET: {
+               struct in_addr          inaddr;
+               struct ifreq            ifreq;
+
+               if (ifindex > 0) {
+                       if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) {
+                               errno = ENXIO;  /* i/f index not found */
+                               return(-1);
+                       }
+                       goto doioctl;
+               } else if (ifname != NULL) {
+                       strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);
+doioctl:
+                       if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0)
+                               return(-1);
+                       memcpy(&inaddr,
+                                  &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr,
+                                  sizeof(struct in_addr));
+               } else
+                       inaddr.s_addr = htonl(INADDR_ANY);      /* remove prev. set default */
+
+               return(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF,
+                                                 &inaddr, sizeof(struct in_addr)));
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               u_int   idx;
+
+               if ( (idx = ifindex) == 0) {
+                       if (ifname == NULL) {
+                               errno = EINVAL; /* must supply either index or name */
+                               return(-1);
+                       }
+                       if ( (idx = if_nametoindex(ifname)) == 0) {
+                               errno = ENXIO;  /* i/f name not found */
+                               return(-1);
+                       }
+               }
+               return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+                                                 &idx, sizeof(idx)));
+       }
+#endif
+
+       default:
+               errno = EAFNOSUPPORT;
+               return(-1);
+       }
+}
+
+void
+Mcast_set_if(int sockfd, const char *ifname, u_int ifindex)
+{
+       if (mcast_set_if(sockfd, ifname, ifindex) < 0)
+               err_sys("mcast_set_if error");
+}
diff --git a/lib/mcast_set_loop.c b/lib/mcast_set_loop.c
new file mode 100644 (file)
index 0000000..ed0505a
--- /dev/null
@@ -0,0 +1,38 @@
+/* include mcast_set_loop */
+#include       "unp.h"
+
+int
+mcast_set_loop(int sockfd, int onoff)
+{
+       switch (sockfd_to_family(sockfd)) {
+       case AF_INET: {
+               u_char          flag;
+
+               flag = onoff;
+               return(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP,
+                                                 &flag, sizeof(flag)));
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               u_int           flag;
+
+               flag = onoff;
+               return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
+                                                 &flag, sizeof(flag)));
+       }
+#endif
+
+       default:
+               errno = EAFNOSUPPORT;
+               return(-1);
+       }
+}
+/* end mcast_set_loop */
+
+void
+Mcast_set_loop(int sockfd, int onoff)
+{
+       if (mcast_set_loop(sockfd, onoff) < 0)
+               err_sys("mcast_set_loop error");
+}
diff --git a/lib/mcast_set_loop.lc b/lib/mcast_set_loop.lc
new file mode 100644 (file)
index 0000000..ddca361
--- /dev/null
@@ -0,0 +1,38 @@
+/* include mcast_set_loop */
+#include    "unp.h"##  1 ##src/lib/mcast_set_loop.c##
+
+int##  2 ##src/lib/mcast_set_loop.c##
+mcast_set_loop(int sockfd, int onoff)##  3 ##src/lib/mcast_set_loop.c##
+{##  4 ##src/lib/mcast_set_loop.c##
+    switch (sockfd_to_family(sockfd)) {##  5 ##src/lib/mcast_set_loop.c##
+    case AF_INET:{##  6 ##src/lib/mcast_set_loop.c##
+            u_char  flag;##  7 ##src/lib/mcast_set_loop.c##
+
+            flag = onoff;##  8 ##src/lib/mcast_set_loop.c##
+            return (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP,##  9 ##src/lib/mcast_set_loop.c##
+                               &flag, sizeof(flag)));## 10 ##src/lib/mcast_set_loop.c##
+        }## 11 ##src/lib/mcast_set_loop.c##
+
+#ifdef  IPV6## 12 ##src/lib/mcast_set_loop.c##
+    case AF_INET6:{## 13 ##src/lib/mcast_set_loop.c##
+            u_int   flag;## 14 ##src/lib/mcast_set_loop.c##
+
+            flag = onoff;## 15 ##src/lib/mcast_set_loop.c##
+            return (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,## 16 ##src/lib/mcast_set_loop.c##
+                               &flag, sizeof(flag)));## 17 ##src/lib/mcast_set_loop.c##
+        }## 18 ##src/lib/mcast_set_loop.c##
+#endif## 19 ##src/lib/mcast_set_loop.c##
+
+    default:## 20 ##src/lib/mcast_set_loop.c##
+        errno = EPROTONOSUPPORT;## 21 ##src/lib/mcast_set_loop.c##
+        return (-1);## 22 ##src/lib/mcast_set_loop.c##
+    }## 23 ##src/lib/mcast_set_loop.c##
+}## 24 ##src/lib/mcast_set_loop.c##
+/* end mcast_set_loop */
+
+void## 25 ##src/lib/mcast_set_loop.c##
+Mcast_set_loop(int sockfd, int onoff)## 26 ##src/lib/mcast_set_loop.c##
+{## 27 ##src/lib/mcast_set_loop.c##
+    if (mcast_set_loop(sockfd, onoff) < 0)## 28 ##src/lib/mcast_set_loop.c##
+        err_sys("mcast_set_loop error");## 29 ##src/lib/mcast_set_loop.c##
+}## 30 ##src/lib/mcast_set_loop.c##
diff --git a/lib/mcast_set_ttl.c b/lib/mcast_set_ttl.c
new file mode 100644 (file)
index 0000000..a3b110f
--- /dev/null
@@ -0,0 +1,36 @@
+#include       "unp.h"
+
+int
+mcast_set_ttl(int sockfd, int val)
+{
+       switch (sockfd_to_family(sockfd)) {
+       case AF_INET: {
+               u_char          ttl;
+
+               ttl = val;
+               return(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,
+                                                 &ttl, sizeof(ttl)));
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               int             hop;
+
+               hop = val;
+               return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+                                                 &hop, sizeof(hop)));
+       }
+#endif
+
+       default:
+               errno = EAFNOSUPPORT;
+               return(-1);
+       }
+}
+
+void
+Mcast_set_ttl(int sockfd, int val)
+{
+       if (mcast_set_ttl(sockfd, val) < 0)
+               err_sys("mcast_set_ttl error");
+}
diff --git a/lib/my_addrs.c b/lib/my_addrs.c
new file mode 100644 (file)
index 0000000..e059e1c
--- /dev/null
@@ -0,0 +1,30 @@
+/* include my_addrs */
+#include       "unp.h"
+#include       <sys/utsname.h>
+
+char **
+my_addrs(int *addrtype)
+{
+       struct hostent  *hptr;
+       struct utsname  myname;
+
+       if (uname(&myname) < 0)
+               return(NULL);
+
+       if ( (hptr = gethostbyname(myname.nodename)) == NULL)
+               return(NULL);
+
+       *addrtype = hptr->h_addrtype;
+       return(hptr->h_addr_list);
+}
+/* end my_addrs */
+
+char **
+My_addrs(int *pfamily)
+{
+       char    **pptr;
+
+       if ( (pptr = my_addrs(pfamily)) == NULL)
+               err_sys("my_addrs error");
+       return(pptr);
+}
diff --git a/lib/my_addrs.lc b/lib/my_addrs.lc
new file mode 100644 (file)
index 0000000..2911735
--- /dev/null
@@ -0,0 +1,30 @@
+/* include my_addrs */
+#include    "unp.h"##  1 ##src/lib/my_addrs.c##
+#include    <sys/utsname.h>##  2 ##src/lib/my_addrs.c##
+
+char  **##  3 ##src/lib/my_addrs.c##
+my_addrs(int *addrtype)##  4 ##src/lib/my_addrs.c##
+{##  5 ##src/lib/my_addrs.c##
+    struct hostent *hptr;##  6 ##src/lib/my_addrs.c##
+    struct utsname myname;##  7 ##src/lib/my_addrs.c##
+
+    if (uname(&myname) < 0)##  8 ##src/lib/my_addrs.c##
+        return (NULL);##  9 ##src/lib/my_addrs.c##
+
+    if ((hptr = gethostbyname(myname.nodename)) == NULL)## 10 ##src/lib/my_addrs.c##
+        return (NULL);## 11 ##src/lib/my_addrs.c##
+
+    *addrtype = hptr->h_addrtype;## 12 ##src/lib/my_addrs.c##
+    return (hptr->h_addr_list);## 13 ##src/lib/my_addrs.c##
+}## 14 ##src/lib/my_addrs.c##
+/* end my_addrs */
+
+char  **## 15 ##src/lib/my_addrs.c##
+My_addrs(int *pfamily)## 16 ##src/lib/my_addrs.c##
+{## 17 ##src/lib/my_addrs.c##
+    char  **pptr;## 18 ##src/lib/my_addrs.c##
+
+    if ((pptr = my_addrs(pfamily)) == NULL)## 19 ##src/lib/my_addrs.c##
+        err_sys("my_addrs error");## 20 ##src/lib/my_addrs.c##
+    return (pptr);## 21 ##src/lib/my_addrs.c##
+}## 22 ##src/lib/my_addrs.c##
diff --git a/lib/pselect.c b/lib/pselect.c
new file mode 100644 (file)
index 0000000..db89f57
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * This is *not* a complete implementation of the Posix.1g pselect()
+ * function.  For atomicity this must be implemented within the kernel,
+ * with the sigprocmask/select/sigprocmask performed as a single atomic
+ * operation.
+ * This is just a quick hack to allow simple programs using it to compile.
+ * Using such programs with this hack will probably lead to race conditions.
+ */
+/* include pselect */
+#include       "unp.h"
+
+int
+pselect(int nfds, fd_set *rset, fd_set *wset, fd_set *xset,
+               const struct timespec *ts, const sigset_t *sigmask)
+{
+       int                             n;
+       struct timeval  tv;
+       sigset_t                savemask;
+
+       if (ts != NULL) {
+               tv.tv_sec = ts->tv_sec;
+               tv.tv_usec = ts->tv_nsec / 1000;        /* nanosec -> microsec */
+       }
+
+       sigprocmask(SIG_SETMASK, sigmask, &savemask);   /* caller's mask */
+       n = select(nfds, rset, wset, xset, (ts == NULL) ? NULL : &tv);
+       sigprocmask(SIG_SETMASK, &savemask, NULL);              /* restore mask */
+
+       return(n);
+}
+/* end pselect */
diff --git a/lib/pselect.lc b/lib/pselect.lc
new file mode 100644 (file)
index 0000000..67bf3cb
--- /dev/null
@@ -0,0 +1,31 @@
+/*##  1 ##src/lib/pselect.c##
+ * This is *not* a complete implementation of the Posix.1g pselect()##  2 ##src/lib/pselect.c##
+ * function.  For atomicity this must be implemented within the kernel,##  3 ##src/lib/pselect.c##
+ * with the sigprocmask/select/sigprocmask performed as a single atomic##  4 ##src/lib/pselect.c##
+ * operation.##  5 ##src/lib/pselect.c##
+ * This is just a quick hack to allow simple programs using it to compile.##  6 ##src/lib/pselect.c##
+ * Using such programs with this hack will probably lead to race conditions.##  7 ##src/lib/pselect.c##
+ */##  8 ##src/lib/pselect.c##
+/* include pselect */
+#include    "unp.h"##  9 ##src/lib/pselect.c##
+
+int## 10 ##src/lib/pselect.c##
+pselect(int nfds, fd_set *rset, fd_set *wset, fd_set *xset,## 11 ##src/lib/pselect.c##
+        const struct timespec *ts, const sigset_t *sigmask)## 12 ##src/lib/pselect.c##
+{## 13 ##src/lib/pselect.c##
+    int     n;## 14 ##src/lib/pselect.c##
+    struct timeval tv;## 15 ##src/lib/pselect.c##
+    sigset_t savemask;## 16 ##src/lib/pselect.c##
+
+    if (ts != NULL) {## 17 ##src/lib/pselect.c##
+        tv.tv_sec = ts->tv_sec;## 18 ##src/lib/pselect.c##
+        tv.tv_usec = ts->tv_nsec / 1000;    /* nanosec -> microsec */## 19 ##src/lib/pselect.c##
+    }## 20 ##src/lib/pselect.c##
+
+    sigprocmask(SIG_SETMASK, sigmask, &savemask);   /* caller's mask */## 21 ##src/lib/pselect.c##
+    n = select(nfds, rset, wset, xset, (ts == NULL) ? NULL : &tv);## 22 ##src/lib/pselect.c##
+    sigprocmask(SIG_SETMASK, &savemask, NULL);  /* restore mask */## 23 ##src/lib/pselect.c##
+
+    return (n);## 24 ##src/lib/pselect.c##
+}## 25 ##src/lib/pselect.c##
+/* end pselect */
diff --git a/lib/read_fd.c b/lib/read_fd.c
new file mode 100644 (file)
index 0000000..f2a17f6
--- /dev/null
@@ -0,0 +1,70 @@
+/* include read_fd */
+#include       "unp.h"
+
+ssize_t
+read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
+{
+       struct msghdr   msg;
+       struct iovec    iov[1];
+       ssize_t                 n;
+
+#ifdef HAVE_MSGHDR_MSG_CONTROL
+       union {
+         struct cmsghdr        cm;
+         char                          control[CMSG_SPACE(sizeof(int))];
+       } control_un;
+       struct cmsghdr  *cmptr;
+
+       msg.msg_control = control_un.control;
+       msg.msg_controllen = sizeof(control_un.control);
+#else
+       int                             newfd;
+
+       msg.msg_accrights = (caddr_t) &newfd;
+       msg.msg_accrightslen = sizeof(int);
+#endif
+
+       msg.msg_name = NULL;
+       msg.msg_namelen = 0;
+
+       iov[0].iov_base = ptr;
+       iov[0].iov_len = nbytes;
+       msg.msg_iov = iov;
+       msg.msg_iovlen = 1;
+
+       if ( (n = recvmsg(fd, &msg, 0)) <= 0)
+               return(n);
+
+#ifdef HAVE_MSGHDR_MSG_CONTROL
+       if ( (cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&
+           cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
+               if (cmptr->cmsg_level != SOL_SOCKET)
+                       err_quit("control level != SOL_SOCKET");
+               if (cmptr->cmsg_type != SCM_RIGHTS)
+                       err_quit("control type != SCM_RIGHTS");
+               *recvfd = *((int *) CMSG_DATA(cmptr));
+       } else
+               *recvfd = -1;           /* descriptor was not passed */
+#else
+/* *INDENT-OFF* */
+       if (msg.msg_accrightslen == sizeof(int))
+               *recvfd = newfd;
+       else
+               *recvfd = -1;           /* descriptor was not passed */
+/* *INDENT-ON* */
+#endif
+
+       return(n);
+}
+/* end read_fd */
+
+ssize_t
+Read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
+{
+       ssize_t         n;
+
+       if ( (n = read_fd(fd, ptr, nbytes, recvfd)) < 0)
+               err_sys("read_fd error");
+
+       return(n);
+}
diff --git a/lib/read_fd.lc b/lib/read_fd.lc
new file mode 100644 (file)
index 0000000..afe0c47
--- /dev/null
@@ -0,0 +1,68 @@
+/* include read_fd */
+#include    "unp.h"##  1 ##src/lib/read_fd.c##
+
+ssize_t##  2 ##src/lib/read_fd.c##
+read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)##  3 ##src/lib/read_fd.c##
+{##  4 ##src/lib/read_fd.c##
+    struct msghdr msg;##  5 ##src/lib/read_fd.c##
+    struct iovec iov[1];##  6 ##src/lib/read_fd.c##
+    ssize_t n;##  7 ##src/lib/read_fd.c##
+
+#ifdef  HAVE_MSGHDR_MSG_CONTROL##  8 ##src/lib/read_fd.c##
+    union {##  9 ##src/lib/read_fd.c##
+        struct cmsghdr cm;## 10 ##src/lib/read_fd.c##
+        char    control[CMSG_SPACE(sizeof(int))];## 11 ##src/lib/read_fd.c##
+    } control_un;## 12 ##src/lib/read_fd.c##
+    struct cmsghdr *cmptr;## 13 ##src/lib/read_fd.c##
+
+    msg.msg_control = control_un.control;## 14 ##src/lib/read_fd.c##
+    msg.msg_controllen = sizeof(control_un.control);## 15 ##src/lib/read_fd.c##
+#else## 16 ##src/lib/read_fd.c##
+    int     newfd;## 17 ##src/lib/read_fd.c##
+
+    msg.msg_accrights = (caddr_t) & newfd;## 18 ##src/lib/read_fd.c##
+    msg.msg_accrightslen = sizeof(int);## 19 ##src/lib/read_fd.c##
+#endif## 20 ##src/lib/read_fd.c##
+
+    msg.msg_name = NULL;## 21 ##src/lib/read_fd.c##
+    msg.msg_namelen = 0;## 22 ##src/lib/read_fd.c##
+
+    iov[0].iov_base = ptr;## 23 ##src/lib/read_fd.c##
+    iov[0].iov_len = nbytes;## 24 ##src/lib/read_fd.c##
+    msg.msg_iov = iov;## 25 ##src/lib/read_fd.c##
+    msg.msg_iovlen = 1;## 26 ##src/lib/read_fd.c##
+
+    if ((n = recvmsg(fd, &msg, 0)) <= 0)## 27 ##src/lib/read_fd.c##
+        return (n);## 28 ##src/lib/read_fd.c##
+
+#ifdef  HAVE_MSGHDR_MSG_CONTROL## 29 ##src/lib/read_fd.c##
+    if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&## 30 ##src/lib/read_fd.c##
+        cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {## 31 ##src/lib/read_fd.c##
+        if (cmptr->cmsg_level != SOL_SOCKET)## 32 ##src/lib/read_fd.c##
+            err_quit("control level != SOL_SOCKET");## 33 ##src/lib/read_fd.c##
+        if (cmptr->cmsg_type != SCM_RIGHTS)## 34 ##src/lib/read_fd.c##
+            err_quit("control type != SCM_RIGHTS");## 35 ##src/lib/read_fd.c##
+        *recvfd = *((int *) CMSG_DATA(cmptr));## 36 ##src/lib/read_fd.c##
+    } else## 37 ##src/lib/read_fd.c##
+        *recvfd = -1;           /* descriptor was not passed */## 38 ##src/lib/read_fd.c##
+#else## 39 ##src/lib/read_fd.c##
+    if (msg.msg_accrightslen == sizeof(int))## 40 ##src/lib/read_fd.c##
+        *recvfd = newfd;## 41 ##src/lib/read_fd.c##
+    else## 42 ##src/lib/read_fd.c##
+        *recvfd = -1;       /* descriptor was not passed */## 43 ##src/lib/read_fd.c##
+#endif## 44 ##src/lib/read_fd.c##
+
+    return (n);## 45 ##src/lib/read_fd.c##
+}## 46 ##src/lib/read_fd.c##
+/* end read_fd */
+
+ssize_t## 47 ##src/lib/read_fd.c##
+Read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)## 48 ##src/lib/read_fd.c##
+{## 49 ##src/lib/read_fd.c##
+    ssize_t n;## 50 ##src/lib/read_fd.c##
+
+    if ((n = read_fd(fd, ptr, nbytes, recvfd)) < 0)## 51 ##src/lib/read_fd.c##
+        err_sys("read_fd error");## 52 ##src/lib/read_fd.c##
+
+    return (n);## 53 ##src/lib/read_fd.c##
+}## 54 ##src/lib/read_fd.c##
diff --git a/lib/readable_timeo.c b/lib/readable_timeo.c
new file mode 100644 (file)
index 0000000..c6ee3d8
--- /dev/null
@@ -0,0 +1,29 @@
+/* include readable_timeo */
+#include       "unp.h"
+
+int
+readable_timeo(int fd, int sec)
+{
+       fd_set                  rset;
+       struct timeval  tv;
+
+       FD_ZERO(&rset);
+       FD_SET(fd, &rset);
+
+       tv.tv_sec = sec;
+       tv.tv_usec = 0;
+
+       return(select(fd+1, &rset, NULL, NULL, &tv));
+               /* 4> 0 if descriptor is readable */
+}
+/* end readable_timeo */
+
+int
+Readable_timeo(int fd, int sec)
+{
+       int             n;
+
+       if ( (n = readable_timeo(fd, sec)) < 0)
+               err_sys("readable_timeo error");
+       return(n);
+}
diff --git a/lib/readable_timeo.lc b/lib/readable_timeo.lc
new file mode 100644 (file)
index 0000000..2c9fb4b
--- /dev/null
@@ -0,0 +1,29 @@
+/* include readable_timeo */
+#include    "unp.h"##  1 ##src/lib/readable_timeo.c##
+
+int##  2 ##src/lib/readable_timeo.c##
+readable_timeo(int fd, int sec)##  3 ##src/lib/readable_timeo.c##
+{##  4 ##src/lib/readable_timeo.c##
+    fd_set  rset;##  5 ##src/lib/readable_timeo.c##
+    struct timeval tv;##  6 ##src/lib/readable_timeo.c##
+
+    FD_ZERO(&rset);##  7 ##src/lib/readable_timeo.c##
+    FD_SET(fd, &rset);##  8 ##src/lib/readable_timeo.c##
+
+    tv.tv_sec = sec;##  9 ##src/lib/readable_timeo.c##
+    tv.tv_usec = 0;## 10 ##src/lib/readable_timeo.c##
+
+    return (select(fd + 1, &rset, NULL, NULL, &tv));## 11 ##src/lib/readable_timeo.c##
+    /* 4> 0 if descriptor is readable */## 12 ##src/lib/readable_timeo.c##
+}## 13 ##src/lib/readable_timeo.c##
+/* end readable_timeo */
+
+int## 14 ##src/lib/readable_timeo.c##
+Readable_timeo(int fd, int sec)## 15 ##src/lib/readable_timeo.c##
+{## 16 ##src/lib/readable_timeo.c##
+    int     n;## 17 ##src/lib/readable_timeo.c##
+
+    if ((n = readable_timeo(fd, sec)) < 0)## 18 ##src/lib/readable_timeo.c##
+        err_sys("readable_timeo error");## 19 ##src/lib/readable_timeo.c##
+    return (n);## 20 ##src/lib/readable_timeo.c##
+}## 21 ##src/lib/readable_timeo.c##
diff --git a/lib/readline.c b/lib/readline.c
new file mode 100644 (file)
index 0000000..040cfe5
--- /dev/null
@@ -0,0 +1,68 @@
+/* include readline */
+#include       "unp.h"
+
+static int     read_cnt;
+static char    *read_ptr;
+static char    read_buf[MAXLINE];
+
+static ssize_t
+my_read(int fd, char *ptr)
+{
+
+       if (read_cnt <= 0) {
+again:
+               if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {
+                       if (errno == EINTR)
+                               goto again;
+                       return(-1);
+               } else if (read_cnt == 0)
+                       return(0);
+               read_ptr = read_buf;
+       }
+
+       read_cnt--;
+       *ptr = *read_ptr++;
+       return(1);
+}
+
+ssize_t
+readline(int fd, void *vptr, size_t maxlen)
+{
+       ssize_t n, rc;
+       char    c, *ptr;
+
+       ptr = vptr;
+       for (n = 1; n < maxlen; n++) {
+               if ( (rc = my_read(fd, &c)) == 1) {
+                       *ptr++ = c;
+                       if (c == '\n')
+                               break;  /* newline is stored, like fgets() */
+               } else if (rc == 0) {
+                       *ptr = 0;
+                       return(n - 1);  /* EOF, n - 1 bytes were read */
+               } else
+                       return(-1);             /* error, errno set by read() */
+       }
+
+       *ptr = 0;       /* null terminate like fgets() */
+       return(n);
+}
+
+ssize_t
+readlinebuf(void **vptrptr)
+{
+       if (read_cnt)
+               *vptrptr = read_ptr;
+       return(read_cnt);
+}
+/* end readline */
+
+ssize_t
+Readline(int fd, void *ptr, size_t maxlen)
+{
+       ssize_t         n;
+
+       if ( (n = readline(fd, ptr, maxlen)) < 0)
+               err_sys("readline error");
+       return(n);
+}
diff --git a/lib/readline.lc b/lib/readline.lc
new file mode 100644 (file)
index 0000000..7653b3f
--- /dev/null
@@ -0,0 +1,68 @@
+/* include readline */
+#include    "unp.h"##  1 ##src/lib/readline.c##
+
+static int read_cnt;##  2 ##src/lib/readline.c##
+static char *read_ptr;##  3 ##src/lib/readline.c##
+static char read_buf[MAXLINE];##  4 ##src/lib/readline.c##
+
+static ssize_t##  5 ##src/lib/readline.c##
+my_read(int fd, char *ptr)##  6 ##src/lib/readline.c##
+{##  7 ##src/lib/readline.c##
+
+    if (read_cnt <= 0) {##  8 ##src/lib/readline.c##
+      again:##  9 ##src/lib/readline.c##
+        if ((read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {## 10 ##src/lib/readline.c##
+            if (errno == EINTR)## 11 ##src/lib/readline.c##
+                goto again;## 12 ##src/lib/readline.c##
+            return (-1);## 13 ##src/lib/readline.c##
+        } else if (read_cnt == 0)## 14 ##src/lib/readline.c##
+            return (0);## 15 ##src/lib/readline.c##
+        read_ptr = read_buf;## 16 ##src/lib/readline.c##
+    }## 17 ##src/lib/readline.c##
+
+    read_cnt--;## 18 ##src/lib/readline.c##
+    *ptr = *read_ptr++;## 19 ##src/lib/readline.c##
+    return (1);## 20 ##src/lib/readline.c##
+}## 21 ##src/lib/readline.c##
+
+ssize_t## 22 ##src/lib/readline.c##
+readline(int fd, void *vptr, size_t maxlen)## 23 ##src/lib/readline.c##
+{## 24 ##src/lib/readline.c##
+    ssize_t n, rc;## 25 ##src/lib/readline.c##
+    char    c, *ptr;## 26 ##src/lib/readline.c##
+
+    ptr = vptr;## 27 ##src/lib/readline.c##
+    for (n = 1; n < maxlen; n++) {## 28 ##src/lib/readline.c##
+        if ((rc = my_read(fd, &c)) == 1) {## 29 ##src/lib/readline.c##
+            *ptr++ = c;## 30 ##src/lib/readline.c##
+            if (c == '\n')## 31 ##src/lib/readline.c##
+                break;          /* newline is stored, like fgets() */## 32 ##src/lib/readline.c##
+        } else if (rc == 0) {## 33 ##src/lib/readline.c##
+            *ptr = 0;## 34 ##src/lib/readline.c##
+            return (n - 1);     /* EOF, n - 1 bytes were read */## 35 ##src/lib/readline.c##
+        } else## 36 ##src/lib/readline.c##
+            return (-1);        /* error, errno set by read() */## 37 ##src/lib/readline.c##
+    }## 38 ##src/lib/readline.c##
+
+    *ptr = 0;                   /* null terminate like fgets() */## 39 ##src/lib/readline.c##
+    return (n);## 40 ##src/lib/readline.c##
+}## 41 ##src/lib/readline.c##
+
+ssize_t## 42 ##src/lib/readline.c##
+readlinebuf(void **vptrptr)## 43 ##src/lib/readline.c##
+{## 44 ##src/lib/readline.c##
+    if (read_cnt)## 45 ##src/lib/readline.c##
+        *vptrptr = read_ptr;## 46 ##src/lib/readline.c##
+    return (read_cnt);## 47 ##src/lib/readline.c##
+}## 48 ##src/lib/readline.c##
+/* end readline */
+
+ssize_t## 49 ##src/lib/readline.c##
+Readline(int fd, void *ptr, size_t maxlen)## 50 ##src/lib/readline.c##
+{## 51 ##src/lib/readline.c##
+    ssize_t n;## 52 ##src/lib/readline.c##
+
+    if ((n = readline(fd, ptr, maxlen)) < 0)## 53 ##src/lib/readline.c##
+        err_sys("readline error");## 54 ##src/lib/readline.c##
+    return (n);## 55 ##src/lib/readline.c##
+}## 56 ##src/lib/readline.c##
diff --git a/lib/readn.c b/lib/readn.c
new file mode 100644 (file)
index 0000000..54e7fc5
--- /dev/null
@@ -0,0 +1,37 @@
+/* include readn */
+#include       "unp.h"
+
+ssize_t                                                /* Read "n" bytes from a descriptor. */
+readn(int fd, void *vptr, size_t n)
+{
+       size_t  nleft;
+       ssize_t nread;
+       char    *ptr;
+
+       ptr = vptr;
+       nleft = n;
+       while (nleft > 0) {
+               if ( (nread = read(fd, ptr, nleft)) < 0) {
+                       if (errno == EINTR)
+                               nread = 0;              /* and call read() again */
+                       else
+                               return(-1);
+               } else if (nread == 0)
+                       break;                          /* EOF */
+
+               nleft -= nread;
+               ptr   += nread;
+       }
+       return(n - nleft);              /* return >= 0 */
+}
+/* end readn */
+
+ssize_t
+Readn(int fd, void *ptr, size_t nbytes)
+{
+       ssize_t         n;
+
+       if ( (n = readn(fd, ptr, nbytes)) < 0)
+               err_sys("readn error");
+       return(n);
+}
diff --git a/lib/readn.lc b/lib/readn.lc
new file mode 100644 (file)
index 0000000..9bf845f
--- /dev/null
@@ -0,0 +1,37 @@
+/* include readn */
+#include    "unp.h"##  1 ##src/lib/readn.c##
+
+ssize_t                         /* Read "n" bytes from a descriptor. */##  2 ##src/lib/readn.c##
+readn(int fd, void *vptr, size_t n)##  3 ##src/lib/readn.c##
+{##  4 ##src/lib/readn.c##
+    size_t  nleft;##  5 ##src/lib/readn.c##
+    ssize_t nread;##  6 ##src/lib/readn.c##
+    char   *ptr;##  7 ##src/lib/readn.c##
+
+    ptr = vptr;##  8 ##src/lib/readn.c##
+    nleft = n;##  9 ##src/lib/readn.c##
+    while (nleft > 0) {## 10 ##src/lib/readn.c##
+        if ((nread = read(fd, ptr, nleft)) < 0) {## 11 ##src/lib/readn.c##
+            if (errno == EINTR)## 12 ##src/lib/readn.c##
+                nread = 0;      /* and call read() again */## 13 ##src/lib/readn.c##
+            else## 14 ##src/lib/readn.c##
+                return (-1);## 15 ##src/lib/readn.c##
+        } else if (nread == 0)## 16 ##src/lib/readn.c##
+            break;              /* EOF */## 17 ##src/lib/readn.c##
+
+        nleft -= nread;## 18 ##src/lib/readn.c##
+        ptr += nread;## 19 ##src/lib/readn.c##
+    }## 20 ##src/lib/readn.c##
+    return (n - nleft);         /* return >= 0 */## 21 ##src/lib/readn.c##
+}## 22 ##src/lib/readn.c##
+/* end readn */
+
+ssize_t## 23 ##src/lib/readn.c##
+Readn(int fd, void *ptr, size_t nbytes)## 24 ##src/lib/readn.c##
+{## 25 ##src/lib/readn.c##
+    ssize_t n;## 26 ##src/lib/readn.c##
+
+    if ((n = readn(fd, ptr, nbytes)) < 0)## 27 ##src/lib/readn.c##
+        err_sys("readn error");## 28 ##src/lib/readn.c##
+    return (n);## 29 ##src/lib/readn.c##
+}## 30 ##src/lib/readn.c##
diff --git a/lib/rtt.c b/lib/rtt.c
new file mode 100644 (file)
index 0000000..d912380
--- /dev/null
+++ b/lib/rtt.c
@@ -0,0 +1,135 @@
+/* include rtt1 */
+#include       "unprtt.h"
+
+int            rtt_d_flag = 0;         /* debug flag; can be set by caller */
+
+/*
+ * Calculate the RTO value based on current estimators:
+ *             smoothed RTT plus four times the deviation
+ */
+#define        RTT_RTOCALC(ptr) ((ptr)->rtt_srtt + (4.0 * (ptr)->rtt_rttvar))
+
+static float
+rtt_minmax(float rto)
+{
+       if (rto < RTT_RXTMIN)
+               rto = RTT_RXTMIN;
+       else if (rto > RTT_RXTMAX)
+               rto = RTT_RXTMAX;
+       return(rto);
+}
+
+void
+rtt_init(struct rtt_info *ptr)
+{
+       struct timeval  tv;
+
+       Gettimeofday(&tv, NULL);
+       ptr->rtt_base = tv.tv_sec;              /* # sec since 1/1/1970 at start */
+
+       ptr->rtt_rtt    = 0;
+       ptr->rtt_srtt   = 0;
+       ptr->rtt_rttvar = 0.75;
+       ptr->rtt_rto = rtt_minmax(RTT_RTOCALC(ptr));
+               /* first RTO at (srtt + (4 * rttvar)) = 3 seconds */
+}
+/* end rtt1 */
+
+/*
+ * Return the current timestamp.
+ * Our timestamps are 32-bit integers that count milliseconds since
+ * rtt_init() was called.
+ */
+
+/* include rtt_ts */
+uint32_t
+rtt_ts(struct rtt_info *ptr)
+{
+       uint32_t                ts;
+       struct timeval  tv;
+
+       Gettimeofday(&tv, NULL);
+       ts = ((tv.tv_sec - ptr->rtt_base) * 1000) + (tv.tv_usec / 1000);
+       return(ts);
+}
+
+void
+rtt_newpack(struct rtt_info *ptr)
+{
+       ptr->rtt_nrexmt = 0;
+}
+
+int
+rtt_start(struct rtt_info *ptr)
+{
+       return((int) (ptr->rtt_rto + 0.5));             /* round float to int */
+               /* 4return value can be used as: alarm(rtt_start(&foo)) */
+}
+/* end rtt_ts */
+
+/*
+ * A response was received.
+ * Stop the timer and update the appropriate values in the structure
+ * based on this packet's RTT.  We calculate the RTT, then update the
+ * estimators of the RTT and its mean deviation.
+ * This function should be called right after turning off the
+ * timer with alarm(0), or right after a timeout occurs.
+ */
+
+/* include rtt_stop */
+void
+rtt_stop(struct rtt_info *ptr, uint32_t ms)
+{
+       double          delta;
+
+       ptr->rtt_rtt = ms / 1000.0;             /* measured RTT in seconds */
+
+       /*
+        * Update our estimators of RTT and mean deviation of RTT.
+        * See Jacobson's SIGCOMM '88 paper, Appendix A, for the details.
+        * We use floating point here for simplicity.
+        */
+
+       delta = ptr->rtt_rtt - ptr->rtt_srtt;
+       ptr->rtt_srtt += delta / 8;             /* g = 1/8 */
+
+       if (delta < 0.0)
+               delta = -delta;                         /* |delta| */
+
+       ptr->rtt_rttvar += (delta - ptr->rtt_rttvar) / 4;       /* h = 1/4 */
+
+       ptr->rtt_rto = rtt_minmax(RTT_RTOCALC(ptr));
+}
+/* end rtt_stop */
+
+/*
+ * A timeout has occurred.
+ * Return -1 if it's time to give up, else return 0.
+ */
+
+/* include rtt_timeout */
+int
+rtt_timeout(struct rtt_info *ptr)
+{
+       ptr->rtt_rto *= 2;              /* next RTO */
+
+       if (++ptr->rtt_nrexmt > RTT_MAXNREXMT)
+               return(-1);                     /* time to give up for this packet */
+       return(0);
+}
+/* end rtt_timeout */
+
+/*
+ * Print debugging information on stderr, if the "rtt_d_flag" is nonzero.
+ */
+
+void
+rtt_debug(struct rtt_info *ptr)
+{
+       if (rtt_d_flag == 0)
+               return;
+
+       fprintf(stderr, "rtt = %.3f, srtt = %.3f, rttvar = %.3f, rto = %.3f\n",
+                       ptr->rtt_rtt, ptr->rtt_srtt, ptr->rtt_rttvar, ptr->rtt_rto);
+       fflush(stderr);
+}
diff --git a/lib/rtt.lc b/lib/rtt.lc
new file mode 100644 (file)
index 0000000..5bf9b40
--- /dev/null
@@ -0,0 +1,135 @@
+/* include rtt1 */
+#include    "unprtt.h"##  1 ##src/lib/rtt.c##
+
+int     rtt_d_flag = 0;         /* debug flag; can be set nonzero by caller */##  2 ##src/lib/rtt.c##
+
+/*##  3 ##src/lib/rtt.c##
+ * Calculate the RTO value based on current estimators:##  4 ##src/lib/rtt.c##
+ *      smoothed RTT plus four times the deviation.##  5 ##src/lib/rtt.c##
+ */##  6 ##src/lib/rtt.c##
+#define RTT_RTOCALC(ptr) ((ptr)->rtt_srtt + (4.0 * (ptr)->rtt_rttvar))##  7 ##src/lib/rtt.c##
+
+static float##  8 ##src/lib/rtt.c##
+rtt_minmax(float rto)##  9 ##src/lib/rtt.c##
+{## 10 ##src/lib/rtt.c##
+    if (rto < RTT_RXTMIN)## 11 ##src/lib/rtt.c##
+        rto = RTT_RXTMIN;## 12 ##src/lib/rtt.c##
+    else if (rto > RTT_RXTMAX)## 13 ##src/lib/rtt.c##
+        rto = RTT_RXTMAX;## 14 ##src/lib/rtt.c##
+    return (rto);## 15 ##src/lib/rtt.c##
+}## 16 ##src/lib/rtt.c##
+
+void## 17 ##src/lib/rtt.c##
+rtt_init(struct rtt_info *ptr)## 18 ##src/lib/rtt.c##
+{## 19 ##src/lib/rtt.c##
+    struct timeval tv;## 20 ##src/lib/rtt.c##
+
+    Gettimeofday(&tv, NULL);## 21 ##src/lib/rtt.c##
+    ptr->rtt_base = tv.tv_sec;  /* #sec since 1/1/1970 at start */## 22 ##src/lib/rtt.c##
+
+    ptr->rtt_rtt = 0;## 23 ##src/lib/rtt.c##
+    ptr->rtt_srtt = 0;## 24 ##src/lib/rtt.c##
+    ptr->rtt_rttvar = 0.75;## 25 ##src/lib/rtt.c##
+    ptr->rtt_rto = rtt_minmax(RTT_RTOCALC(ptr));## 26 ##src/lib/rtt.c##
+    /* first RTO at (srtt + (4 * rttvar)) = 3 seconds */## 27 ##src/lib/rtt.c##
+}## 28 ##src/lib/rtt.c##
+/* end rtt1 */
+
+/*## 29 ##src/lib/rtt.c##
+ * Return the current timestamp.## 30 ##src/lib/rtt.c##
+ * Our timestamps are 32-bit integers that count milliseconds since## 31 ##src/lib/rtt.c##
+ * rtt_init() was called.## 32 ##src/lib/rtt.c##
+ */## 33 ##src/lib/rtt.c##
+
+/* include rtt_ts */
+uint32_t## 34 ##src/lib/rtt.c##
+rtt_ts(struct rtt_info *ptr)## 35 ##src/lib/rtt.c##
+{## 36 ##src/lib/rtt.c##
+    uint32_t ts;## 37 ##src/lib/rtt.c##
+    struct timeval tv;## 38 ##src/lib/rtt.c##
+
+    Gettimeofday(&tv, NULL);## 39 ##src/lib/rtt.c##
+    ts = ((tv.tv_sec - ptr->rtt_base) * 1000) + (tv.tv_usec / 1000);## 40 ##src/lib/rtt.c##
+    return (ts);## 41 ##src/lib/rtt.c##
+}## 42 ##src/lib/rtt.c##
+
+void## 43 ##src/lib/rtt.c##
+rtt_newpack(struct rtt_info *ptr)## 44 ##src/lib/rtt.c##
+{## 45 ##src/lib/rtt.c##
+    ptr->rtt_nrexmt = 0;## 46 ##src/lib/rtt.c##
+}## 47 ##src/lib/rtt.c##
+
+int## 48 ##src/lib/rtt.c##
+rtt_start(struct rtt_info *ptr)## 49 ##src/lib/rtt.c##
+{## 50 ##src/lib/rtt.c##
+    return ((int) (ptr->rtt_rto + 0.5));    /* round float to int */## 51 ##src/lib/rtt.c##
+    /* 4return value can be used as: alarm(rtt_start(&foo)) */## 52 ##src/lib/rtt.c##
+}## 53 ##src/lib/rtt.c##
+/* end rtt_ts */
+
+/*## 54 ##src/lib/rtt.c##
+ * A response was received.## 55 ##src/lib/rtt.c##
+ * Stop the timer and update the appropriate values in the structure## 56 ##src/lib/rtt.c##
+ * based on this packet's RTT.  We calculate the RTT, then update the## 57 ##src/lib/rtt.c##
+ * estimators of the RTT and its mean deviation.## 58 ##src/lib/rtt.c##
+ * This function should be called right after turning off the## 59 ##src/lib/rtt.c##
+ * timer with alarm(0), or right after a timeout occurs.## 60 ##src/lib/rtt.c##
+ */## 61 ##src/lib/rtt.c##
+
+/* include rtt_stop */
+void## 62 ##src/lib/rtt.c##
+rtt_stop(struct rtt_info *ptr, uint32_t ms)## 63 ##src/lib/rtt.c##
+{## 64 ##src/lib/rtt.c##
+    double  delta;## 65 ##src/lib/rtt.c##
+
+    ptr->rtt_rtt = ms / 1000.0; /* measured RTT in seconds */## 66 ##src/lib/rtt.c##
+
+    /* ## 67 ##src/lib/rtt.c##
+     * Update our estimators of RTT and mean deviation of RTT.## 68 ##src/lib/rtt.c##
+     * See Jacobson's SIGCOMM '88 paper, Appendix A, for the details.## 69 ##src/lib/rtt.c##
+     * We use floating point here for simplicity.## 70 ##src/lib/rtt.c##
+     */## 71 ##src/lib/rtt.c##
+
+    delta = ptr->rtt_rtt - ptr->rtt_srtt;## 72 ##src/lib/rtt.c##
+    ptr->rtt_srtt += delta / 8; /* g = 1/8 */## 73 ##src/lib/rtt.c##
+
+    if (delta < 0.0)## 74 ##src/lib/rtt.c##
+        delta = -delta;         /* |delta| */## 75 ##src/lib/rtt.c##
+
+    ptr->rtt_rttvar += (delta - ptr->rtt_rttvar) / 4;   /* h = 1/4 */## 76 ##src/lib/rtt.c##
+
+    ptr->rtt_rto = rtt_minmax(RTT_RTOCALC(ptr));## 77 ##src/lib/rtt.c##
+}## 78 ##src/lib/rtt.c##
+/* end rtt_stop */
+
+/*## 79 ##src/lib/rtt.c##
+ * A timeout has occurred.## 80 ##src/lib/rtt.c##
+ * Return -1 if it's time to give up, else return 0.## 81 ##src/lib/rtt.c##
+ */## 82 ##src/lib/rtt.c##
+
+/* include rtt_timeout */
+int## 83 ##src/lib/rtt.c##
+rtt_timeout(struct rtt_info *ptr)## 84 ##src/lib/rtt.c##
+{## 85 ##src/lib/rtt.c##
+    ptr->rtt_rto *= 2;          /* next RTO */## 86 ##src/lib/rtt.c##
+
+    if (++ptr->rtt_nrexmt > RTT_MAXNREXMT)## 87 ##src/lib/rtt.c##
+        return (-1);            /* time to give up for this packet */## 88 ##src/lib/rtt.c##
+    return (0);## 89 ##src/lib/rtt.c##
+}## 90 ##src/lib/rtt.c##
+/* end rtt_timeout */
+
+/*## 91 ##src/lib/rtt.c##
+ * Print debugging information on stderr, if the "rtt_d_flag" is nonzero.## 92 ##src/lib/rtt.c##
+ */## 93 ##src/lib/rtt.c##
+
+void## 94 ##src/lib/rtt.c##
+rtt_debug(struct rtt_info *ptr)## 95 ##src/lib/rtt.c##
+{## 96 ##src/lib/rtt.c##
+    if (rtt_d_flag == 0)## 97 ##src/lib/rtt.c##
+        return;## 98 ##src/lib/rtt.c##
+
+    fprintf(stderr, "rtt = %.3f, srtt = %.3f, rttvar = %.3f, rto = %.3f\n",## 99 ##src/lib/rtt.c##
+            ptr->rtt_rtt, ptr->rtt_srtt, ptr->rtt_rttvar, ptr->rtt_rto);##100 ##src/lib/rtt.c##
+    fflush(stderr);##101 ##src/lib/rtt.c##
+}##102 ##src/lib/rtt.c##
diff --git a/lib/signal.c b/lib/signal.c
new file mode 100644 (file)
index 0000000..52932ff
--- /dev/null
@@ -0,0 +1,35 @@
+/* include signal */
+#include       "unp.h"
+
+Sigfunc *
+signal(int signo, Sigfunc *func)
+{
+       struct sigaction        act, oact;
+
+       act.sa_handler = func;
+       sigemptyset(&act.sa_mask);
+       act.sa_flags = 0;
+       if (signo == SIGALRM) {
+#ifdef SA_INTERRUPT
+               act.sa_flags |= SA_INTERRUPT;   /* SunOS 4.x */
+#endif
+       } else {
+#ifdef SA_RESTART
+               act.sa_flags |= SA_RESTART;             /* SVR4, 44BSD */
+#endif
+       }
+       if (sigaction(signo, &act, &oact) < 0)
+               return(SIG_ERR);
+       return(oact.sa_handler);
+}
+/* end signal */
+
+Sigfunc *
+Signal(int signo, Sigfunc *func)       /* for our signal() function */
+{
+       Sigfunc *sigfunc;
+
+       if ( (sigfunc = signal(signo, func)) == SIG_ERR)
+               err_sys("signal error");
+       return(sigfunc);
+}
diff --git a/lib/signal.lc b/lib/signal.lc
new file mode 100644 (file)
index 0000000..de48817
--- /dev/null
@@ -0,0 +1,35 @@
+/* include signal */
+#include    "unp.h"##  1 ##src/lib/signal.c##
+
+Sigfunc *##  2 ##src/lib/signal.c##
+signal(int signo, Sigfunc *func)##  3 ##src/lib/signal.c##
+{##  4 ##src/lib/signal.c##
+    struct sigaction act, oact;##  5 ##src/lib/signal.c##
+
+    act.sa_handler = func;##  6 ##src/lib/signal.c##
+    sigemptyset(&act.sa_mask);##  7 ##src/lib/signal.c##
+    act.sa_flags = 0;##  8 ##src/lib/signal.c##
+    if (signo == SIGALRM) {##  9 ##src/lib/signal.c##
+#ifdef  SA_INTERRUPT## 10 ##src/lib/signal.c##
+        act.sa_flags |= SA_INTERRUPT;   /* SunOS 4.x */## 11 ##src/lib/signal.c##
+#endif## 12 ##src/lib/signal.c##
+    } else {## 13 ##src/lib/signal.c##
+#ifdef  SA_RESTART## 14 ##src/lib/signal.c##
+        act.sa_flags |= SA_RESTART; /* SVR4, 44BSD */## 15 ##src/lib/signal.c##
+#endif## 16 ##src/lib/signal.c##
+    }## 17 ##src/lib/signal.c##
+    if (sigaction(signo, &act, &oact) < 0)## 18 ##src/lib/signal.c##
+        return (SIG_ERR);## 19 ##src/lib/signal.c##
+    return (oact.sa_handler);## 20 ##src/lib/signal.c##
+}## 21 ##src/lib/signal.c##
+/* end signal */
+
+Sigfunc *## 22 ##src/lib/signal.c##
+Signal(int signo, Sigfunc *func)## 23 ##src/lib/signal.c##
+{                               /* for our signal() function */## 24 ##src/lib/signal.c##
+    Sigfunc *sigfunc;## 25 ##src/lib/signal.c##
+
+    if ((sigfunc = signal(signo, func)) == SIG_ERR)## 26 ##src/lib/signal.c##
+        err_sys("signal error");## 27 ##src/lib/signal.c##
+    return (sigfunc);## 28 ##src/lib/signal.c##
+}## 29 ##src/lib/signal.c##
diff --git a/lib/signal_intr.c b/lib/signal_intr.c
new file mode 100644 (file)
index 0000000..2fa1103
--- /dev/null
@@ -0,0 +1,29 @@
+/* include signal_intr */
+#include       "unp.h"
+
+Sigfunc *
+signal_intr(int signo, Sigfunc *func)
+{
+       struct sigaction        act, oact;
+
+       act.sa_handler = func;
+       sigemptyset(&act.sa_mask);
+       act.sa_flags = 0;
+#ifdef SA_INTERRUPT    /* SunOS */
+       act.sa_flags |= SA_INTERRUPT;
+#endif
+       if (sigaction(signo, &act, &oact) < 0)
+               return(SIG_ERR);
+       return(oact.sa_handler);
+}
+/* end signal_intr */
+
+Sigfunc *
+Signal_intr(int signo, Sigfunc *func)
+{
+       Sigfunc *sigfunc;
+
+       if ( (sigfunc = signal_intr(signo, func)) == SIG_ERR)
+               err_sys("signal_intr error");
+       return(sigfunc);
+}
diff --git a/lib/snprintf.c b/lib/snprintf.c
new file mode 100644 (file)
index 0000000..27c3361
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Throughout the book I use snprintf() because it's safer than sprintf().
+ * But as of the time of this writing, not all systems provide this
+ * function.  The function below should only be built on those systems
+ * that do not provide a real snprintf().
+ * The function below just acts like sprintf(); it is not safe, but it
+ * tries to detect overflow.
+ */
+
+#include       "unp.h"
+
+#include       <stdarg.h>              /* ANSI C header file */
+
+int
+snprintf(char *buf, size_t size, const char *fmt, ...)
+{
+       int                     n;
+       va_list         ap;
+
+       va_start(ap, fmt);
+       vsprintf(buf, fmt, ap); /* Sigh, some vsprintf's return ptr, not length */
+       n = strlen(buf);
+       va_end(ap);
+       if (n >= size)
+               err_quit("snprintf: '%s' overflowed array", fmt);
+       return(n);
+}
diff --git a/lib/sock_bind_wild.c b/lib/sock_bind_wild.c
new file mode 100644 (file)
index 0000000..6c4b223
--- /dev/null
@@ -0,0 +1,55 @@
+#include       "unp.h"
+
+int
+sock_bind_wild(int sockfd, int family)
+{
+       socklen_t       len;
+
+       switch (family) {
+       case AF_INET: {
+               struct sockaddr_in      sin;
+
+               bzero(&sin, sizeof(sin));
+               sin.sin_family = AF_INET;
+               sin.sin_addr.s_addr = htonl(INADDR_ANY);
+               sin.sin_port = htons(0);        /* bind ephemeral port */
+
+               if (bind(sockfd, (SA *) &sin, sizeof(sin)) < 0)
+                       return(-1);
+               len = sizeof(sin);
+               if (getsockname(sockfd, (SA *) &sin, &len) < 0)
+                       return(-1);
+               return(sin.sin_port);
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               struct sockaddr_in6     sin6;
+
+               bzero(&sin6, sizeof(sin6));
+               sin6.sin6_family = AF_INET6;
+               sin6.sin6_addr = in6addr_any;
+               sin6.sin6_port = htons(0);      /* bind ephemeral port */
+
+               if (bind(sockfd, (SA *) &sin6, sizeof(sin6)) < 0)
+                       return(-1);
+               len = sizeof(sin6);
+               if (getsockname(sockfd, (SA *) &sin6, &len) < 0)
+                       return(-1);
+               return(sin6.sin6_port);
+       }
+#endif
+       }
+       return(-1);
+}
+
+int
+Sock_bind_wild(int sockfd, int family)
+{
+       int             port;
+
+       if ( (port = sock_bind_wild(sockfd, family)) < 0)
+               err_sys("sock_bind_wild error");
+
+       return(port);
+}
diff --git a/lib/sock_cmp_addr.c b/lib/sock_cmp_addr.c
new file mode 100644 (file)
index 0000000..ee84969
--- /dev/null
@@ -0,0 +1,43 @@
+#include       "unp.h"
+
+#ifdef HAVE_SOCKADDR_DL_STRUCT
+#include       <net/if_dl.h>
+#endif
+
+int
+sock_cmp_addr(const struct sockaddr *sa1, const struct sockaddr *sa2,
+                        socklen_t salen)
+{
+       if (sa1->sa_family != sa2->sa_family)
+               return(-1);
+
+       switch (sa1->sa_family) {
+       case AF_INET: {
+               return(memcmp( &((struct sockaddr_in *) sa1)->sin_addr,
+                                          &((struct sockaddr_in *) sa2)->sin_addr,
+                                          sizeof(struct in_addr)));
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               return(memcmp( &((struct sockaddr_in6 *) sa1)->sin6_addr,
+                                          &((struct sockaddr_in6 *) sa2)->sin6_addr,
+                                          sizeof(struct in6_addr)));
+       }
+#endif
+
+#ifdef AF_UNIX
+       case AF_UNIX: {
+               return(strcmp( ((struct sockaddr_un *) sa1)->sun_path,
+                                          ((struct sockaddr_un *) sa2)->sun_path));
+       }
+#endif
+
+#ifdef HAVE_SOCKADDR_DL_STRUCT
+       case AF_LINK: {
+               return(-1);             /* no idea what to compare here ? */
+       }
+#endif
+       }
+    return (-1);
+}
diff --git a/lib/sock_cmp_port.c b/lib/sock_cmp_port.c
new file mode 100644 (file)
index 0000000..1e106e8
--- /dev/null
@@ -0,0 +1,29 @@
+#include       "unp.h"
+
+#ifdef HAVE_SOCKADDR_DL_STRUCT
+#include       <net/if_dl.h>
+#endif
+
+int
+sock_cmp_port(const struct sockaddr *sa1, const struct sockaddr *sa2,
+                        socklen_t salen)
+{
+       if (sa1->sa_family != sa2->sa_family)
+               return(-1);
+
+       switch (sa1->sa_family) {
+       case AF_INET: {
+               return( ((struct sockaddr_in *) sa1)->sin_port ==
+                               ((struct sockaddr_in *) sa2)->sin_port);
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               return( ((struct sockaddr_in6 *) sa1)->sin6_port ==
+                               ((struct sockaddr_in6 *) sa2)->sin6_port);
+       }
+#endif
+
+       }
+    return (-1);
+}
diff --git a/lib/sock_get_port.c b/lib/sock_get_port.c
new file mode 100644 (file)
index 0000000..fe08b25
--- /dev/null
@@ -0,0 +1,23 @@
+#include       "unp.h"
+
+int
+sock_get_port(const struct sockaddr *sa, socklen_t salen)
+{
+       switch (sa->sa_family) {
+       case AF_INET: {
+               struct sockaddr_in      *sin = (struct sockaddr_in *) sa;
+
+               return(sin->sin_port);
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               struct sockaddr_in6     *sin6 = (struct sockaddr_in6 *) sa;
+
+               return(sin6->sin6_port);
+       }
+#endif
+       }
+
+    return(-1);                /* ??? */
+}
diff --git a/lib/sock_ntop.c b/lib/sock_ntop.c
new file mode 100644 (file)
index 0000000..698147e
--- /dev/null
@@ -0,0 +1,86 @@
+#include       "unp.h"
+
+#ifdef HAVE_SOCKADDR_DL_STRUCT
+#include       <net/if_dl.h>
+#endif
+
+/* include sock_ntop */
+char *
+sock_ntop(const struct sockaddr *sa, socklen_t salen)
+{
+    char               portstr[8];
+    static char str[128];              /* Unix domain is largest */
+
+       switch (sa->sa_family) {
+       case AF_INET: {
+               struct sockaddr_in      *sin = (struct sockaddr_in *) sa;
+
+               if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL)
+                       return(NULL);
+               if (ntohs(sin->sin_port) != 0) {
+                       snprintf(portstr, sizeof(portstr), ":%d", ntohs(sin->sin_port));
+                       strcat(str, portstr);
+               }
+               return(str);
+       }
+/* end sock_ntop */
+
+#ifdef IPV6
+       case AF_INET6: {
+               struct sockaddr_in6     *sin6 = (struct sockaddr_in6 *) sa;
+
+               str[0] = '[';
+               if (inet_ntop(AF_INET6, &sin6->sin6_addr, str + 1, sizeof(str) - 1) == NULL)
+                       return(NULL);
+               if (ntohs(sin6->sin6_port) != 0) {
+                       snprintf(portstr, sizeof(portstr), "]:%d", ntohs(sin6->sin6_port));
+                       strcat(str, portstr);
+                       return(str);
+               }
+               return (str + 1);
+       }
+#endif
+
+#ifdef AF_UNIX
+       case AF_UNIX: {
+               struct sockaddr_un      *unp = (struct sockaddr_un *) sa;
+
+                       /* OK to have no pathname bound to the socket: happens on
+                          every connect() unless client calls bind() first. */
+               if (unp->sun_path[0] == 0)
+                       strcpy(str, "(no pathname bound)");
+               else
+                       snprintf(str, sizeof(str), "%s", unp->sun_path);
+               return(str);
+       }
+#endif
+
+#ifdef HAVE_SOCKADDR_DL_STRUCT
+       case AF_LINK: {
+               struct sockaddr_dl      *sdl = (struct sockaddr_dl *) sa;
+
+               if (sdl->sdl_nlen > 0)
+                       snprintf(str, sizeof(str), "%*s (index %d)",
+                                        sdl->sdl_nlen, &sdl->sdl_data[0], sdl->sdl_index);
+               else
+                       snprintf(str, sizeof(str), "AF_LINK, index=%d", sdl->sdl_index);
+               return(str);
+       }
+#endif
+       default:
+               snprintf(str, sizeof(str), "sock_ntop: unknown AF_xxx: %d, len %d",
+                                sa->sa_family, salen);
+               return(str);
+       }
+    return (NULL);
+}
+
+char *
+Sock_ntop(const struct sockaddr *sa, socklen_t salen)
+{
+       char    *ptr;
+
+       if ( (ptr = sock_ntop(sa, salen)) == NULL)
+               err_sys("sock_ntop error");     /* inet_ntop() sets errno */
+       return(ptr);
+}
diff --git a/lib/sock_ntop.lc b/lib/sock_ntop.lc
new file mode 100644 (file)
index 0000000..1210330
--- /dev/null
@@ -0,0 +1,90 @@
+#include    "unp.h"##  1 ##src/lib/sock_ntop.c##
+
+#ifdef  HAVE_SOCKADDR_DL_STRUCT##  2 ##src/lib/sock_ntop.c##
+#include    <net/if_dl.h>##  3 ##src/lib/sock_ntop.c##
+#endif##  4 ##src/lib/sock_ntop.c##
+
+/* include sock_ntop */
+char   *##  5 ##src/lib/sock_ntop.c##
+sock_ntop(const struct sockaddr *sa, socklen_t salen)##  6 ##src/lib/sock_ntop.c##
+{##  7 ##src/lib/sock_ntop.c##
+    char    portstr[8];##  8 ##src/lib/sock_ntop.c##
+    static char str[128];       /* Unix domain is largest */##  9 ##src/lib/sock_ntop.c##
+
+    switch (sa->sa_family) {## 10 ##src/lib/sock_ntop.c##
+    case AF_INET:{## 11 ##src/lib/sock_ntop.c##
+            struct sockaddr_in *sin = (struct sockaddr_in *) sa;## 12 ##src/lib/sock_ntop.c##
+
+            if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL)## 13 ##src/lib/sock_ntop.c##
+                return (NULL);## 14 ##src/lib/sock_ntop.c##
+            if (ntohs(sin->sin_port) != 0) {## 15 ##src/lib/sock_ntop.c##
+                snprintf(portstr, sizeof(portstr), ":%d",## 16 ##src/lib/sock_ntop.c##
+                         ntohs(sin->sin_port));## 17 ##src/lib/sock_ntop.c##
+                strcat(str, portstr);## 18 ##src/lib/sock_ntop.c##
+            }## 19 ##src/lib/sock_ntop.c##
+            return (str);## 20 ##src/lib/sock_ntop.c##
+        }## 21 ##src/lib/sock_ntop.c##
+/* end sock_ntop */
+
+#ifdef  IPV6## 22 ##src/lib/sock_ntop.c##
+    case AF_INET6:{## 23 ##src/lib/sock_ntop.c##
+            struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;## 24 ##src/lib/sock_ntop.c##
+
+            str[0] = '[';## 25 ##src/lib/sock_ntop.c##
+            if (inet_ntop## 26 ##src/lib/sock_ntop.c##
+                (AF_INET6, &sin6->sin6_addr, str + 1,## 27 ##src/lib/sock_ntop.c##
+                 sizeof(str) - 1) == NULL)## 28 ##src/lib/sock_ntop.c##
+                return (NULL);## 29 ##src/lib/sock_ntop.c##
+            if (ntohs(sin6->sin6_port) != 0) {## 30 ##src/lib/sock_ntop.c##
+                snprintf(portstr, sizeof(portstr), "]:%d",## 31 ##src/lib/sock_ntop.c##
+                         ntohs(sin6->sin6_port));## 32 ##src/lib/sock_ntop.c##
+                strcat(str, portstr);## 33 ##src/lib/sock_ntop.c##
+                return (str);## 34 ##src/lib/sock_ntop.c##
+            }## 35 ##src/lib/sock_ntop.c##
+            return (str + 1);## 36 ##src/lib/sock_ntop.c##
+        }## 37 ##src/lib/sock_ntop.c##
+#endif## 38 ##src/lib/sock_ntop.c##
+
+#ifdef  AF_UNIX## 39 ##src/lib/sock_ntop.c##
+    case AF_UNIX:{## 40 ##src/lib/sock_ntop.c##
+            struct sockaddr_un *unp = (struct sockaddr_un *) sa;## 41 ##src/lib/sock_ntop.c##
+
+            /* OK to have no pathname bound to the socket: happens on every connect() unless client calls bind() first. */## 42 ##src/lib/sock_ntop.c##
+            if (unp->sun_path[0] == 0)## 43 ##src/lib/sock_ntop.c##
+                strcpy(str, "(no pathname bound)");## 44 ##src/lib/sock_ntop.c##
+            else## 45 ##src/lib/sock_ntop.c##
+                snprintf(str, sizeof(str), "%s", unp->sun_path);## 46 ##src/lib/sock_ntop.c##
+            return (str);## 47 ##src/lib/sock_ntop.c##
+        }## 48 ##src/lib/sock_ntop.c##
+#endif## 49 ##src/lib/sock_ntop.c##
+
+#ifdef  HAVE_SOCKADDR_DL_STRUCT## 50 ##src/lib/sock_ntop.c##
+    case AF_LINK:{## 51 ##src/lib/sock_ntop.c##
+            struct sockaddr_dl *sdl = (struct sockaddr_dl *) sa;## 52 ##src/lib/sock_ntop.c##
+
+            if (sdl->sdl_nlen > 0)## 53 ##src/lib/sock_ntop.c##
+                snprintf(str, sizeof(str), "%*s (index %d)",## 54 ##src/lib/sock_ntop.c##
+                         sdl->sdl_nlen, &sdl->sdl_data[0], sdl->sdl_index);## 55 ##src/lib/sock_ntop.c##
+            else## 56 ##src/lib/sock_ntop.c##
+                snprintf(str, sizeof(str), "AF_LINK, index=%d",## 57 ##src/lib/sock_ntop.c##
+                         sdl->sdl_index);## 58 ##src/lib/sock_ntop.c##
+            return (str);## 59 ##src/lib/sock_ntop.c##
+        }## 60 ##src/lib/sock_ntop.c##
+#endif## 61 ##src/lib/sock_ntop.c##
+    default:## 62 ##src/lib/sock_ntop.c##
+        snprintf(str, sizeof(str), "sock_ntop: unknown AF_xxx: %d, len %d",## 63 ##src/lib/sock_ntop.c##
+                 sa->sa_family, salen);## 64 ##src/lib/sock_ntop.c##
+        return (str);## 65 ##src/lib/sock_ntop.c##
+    }## 66 ##src/lib/sock_ntop.c##
+    return (NULL);## 67 ##src/lib/sock_ntop.c##
+}## 68 ##src/lib/sock_ntop.c##
+
+char   *## 69 ##src/lib/sock_ntop.c##
+Sock_ntop(const struct sockaddr *sa, socklen_t salen)## 70 ##src/lib/sock_ntop.c##
+{## 71 ##src/lib/sock_ntop.c##
+    char   *ptr;## 72 ##src/lib/sock_ntop.c##
+
+    if ((ptr = sock_ntop(sa, salen)) == NULL)## 73 ##src/lib/sock_ntop.c##
+        err_sys("sock_ntop error"); /* inet_ntop() sets errno */## 74 ##src/lib/sock_ntop.c##
+    return (ptr);## 75 ##src/lib/sock_ntop.c##
+}## 76 ##src/lib/sock_ntop.c##
diff --git a/lib/sock_ntop_host.c b/lib/sock_ntop_host.c
new file mode 100644 (file)
index 0000000..801bc2c
--- /dev/null
@@ -0,0 +1,73 @@
+#include       "unp.h"
+
+#ifdef HAVE_SOCKADDR_DL_STRUCT
+#include       <net/if_dl.h>
+#endif
+
+char *
+sock_ntop_host(const struct sockaddr *sa, socklen_t salen)
+{
+    static char str[128];              /* Unix domain is largest */
+
+       switch (sa->sa_family) {
+       case AF_INET: {
+               struct sockaddr_in      *sin = (struct sockaddr_in *) sa;
+
+               if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL)
+                       return(NULL);
+               return(str);
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               struct sockaddr_in6     *sin6 = (struct sockaddr_in6 *) sa;
+
+               if (inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str)) == NULL)
+                       return(NULL);
+               return(str);
+       }
+#endif
+
+#ifdef AF_UNIX
+       case AF_UNIX: {
+               struct sockaddr_un      *unp = (struct sockaddr_un *) sa;
+
+                       /* OK to have no pathname bound to the socket: happens on
+                          every connect() unless client calls bind() first. */
+               if (unp->sun_path[0] == 0)
+                       strcpy(str, "(no pathname bound)");
+               else
+                       snprintf(str, sizeof(str), "%s", unp->sun_path);
+               return(str);
+       }
+#endif
+
+#ifdef HAVE_SOCKADDR_DL_STRUCT
+       case AF_LINK: {
+               struct sockaddr_dl      *sdl = (struct sockaddr_dl *) sa;
+
+               if (sdl->sdl_nlen > 0)
+                       snprintf(str, sizeof(str), "%*s",
+                                        sdl->sdl_nlen, &sdl->sdl_data[0]);
+               else
+                       snprintf(str, sizeof(str), "AF_LINK, index=%d", sdl->sdl_index);
+               return(str);
+       }
+#endif
+       default:
+               snprintf(str, sizeof(str), "sock_ntop_host: unknown AF_xxx: %d, len %d",
+                                sa->sa_family, salen);
+               return(str);
+       }
+    return (NULL);
+}
+
+char *
+Sock_ntop_host(const struct sockaddr *sa, socklen_t salen)
+{
+       char    *ptr;
+
+       if ( (ptr = sock_ntop_host(sa, salen)) == NULL)
+               err_sys("sock_ntop_host error");        /* inet_ntop() sets errno */
+       return(ptr);
+}
diff --git a/lib/sock_set_addr.c b/lib/sock_set_addr.c
new file mode 100644 (file)
index 0000000..f2abe31
--- /dev/null
@@ -0,0 +1,25 @@
+#include       "unp.h"
+
+void
+sock_set_addr(struct sockaddr *sa, socklen_t salen, const void *addr)
+{
+       switch (sa->sa_family) {
+       case AF_INET: {
+               struct sockaddr_in      *sin = (struct sockaddr_in *) sa;
+
+               memcpy(&sin->sin_addr, addr, sizeof(struct in_addr));
+               return;
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               struct sockaddr_in6     *sin6 = (struct sockaddr_in6 *) sa;
+
+               memcpy(&sin6->sin6_addr, addr, sizeof(struct in6_addr));
+               return;
+       }
+#endif
+       }
+
+    return;
+}
diff --git a/lib/sock_set_port.c b/lib/sock_set_port.c
new file mode 100644 (file)
index 0000000..5bcdefa
--- /dev/null
@@ -0,0 +1,25 @@
+#include       "unp.h"
+
+void
+sock_set_port(struct sockaddr *sa, socklen_t salen, int port)
+{
+       switch (sa->sa_family) {
+       case AF_INET: {
+               struct sockaddr_in      *sin = (struct sockaddr_in *) sa;
+
+               sin->sin_port = port;
+               return;
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               struct sockaddr_in6     *sin6 = (struct sockaddr_in6 *) sa;
+
+               sin6->sin6_port = port;
+               return;
+       }
+#endif
+       }
+
+    return;
+}
diff --git a/lib/sock_set_wild.c b/lib/sock_set_wild.c
new file mode 100644 (file)
index 0000000..201392a
--- /dev/null
@@ -0,0 +1,29 @@
+#include       "unp.h"
+
+void
+sock_set_wild(struct sockaddr *sa, socklen_t salen)
+{
+       const void      *wildptr;
+
+       switch (sa->sa_family) {
+       case AF_INET: {
+               static struct in_addr   in4addr_any;
+
+               in4addr_any.s_addr = htonl(INADDR_ANY);
+               wildptr = &in4addr_any;
+               break;
+       }
+
+#ifdef IPV6
+       case AF_INET6: {
+               wildptr = &in6addr_any;
+               break;
+       }
+#endif
+
+       default:
+               return;
+       }
+       sock_set_addr(sa, salen, wildptr);
+    return;
+}
diff --git a/lib/sockatmark.c b/lib/sockatmark.c
new file mode 100644 (file)
index 0000000..f115f5d
--- /dev/null
@@ -0,0 +1,11 @@
+#include       "unp.h"
+
+int
+sockatmark(int fd)
+{
+       int             flag;
+
+       if (ioctl(fd, SIOCATMARK, &flag) < 0)
+               return(-1);
+       return(flag != 0);
+}
diff --git a/lib/sockfd_to_family.c b/lib/sockfd_to_family.c
new file mode 100644 (file)
index 0000000..d925a0f
--- /dev/null
@@ -0,0 +1,26 @@
+/* include sockfd_to_family */
+#include       "unp.h"
+
+int
+sockfd_to_family(int sockfd)
+{
+       struct sockaddr_storage ss;
+       socklen_t       len;
+
+       len = sizeof(ss);
+       if (getsockname(sockfd, (SA *) &ss, &len) < 0)
+               return(-1);
+       return(ss.ss_family);
+}
+/* end sockfd_to_family */
+
+int
+Sockfd_to_family(int sockfd)
+{
+       int             rc;
+
+       if ( (rc = sockfd_to_family(sockfd)) < 0)
+               err_sys("sockfd_to_family error");
+
+       return(rc);
+}
diff --git a/lib/sockfd_to_family.lc b/lib/sockfd_to_family.lc
new file mode 100644 (file)
index 0000000..48beea0
--- /dev/null
@@ -0,0 +1,26 @@
+/* include sockfd_to_family */
+#include    "unp.h"##  1 ##src/lib/sockfd_to_family.c##
+
+int##  2 ##src/lib/sockfd_to_family.c##
+sockfd_to_family(int sockfd)##  3 ##src/lib/sockfd_to_family.c##
+{##  4 ##src/lib/sockfd_to_family.c##
+    struct sockaddr_storage ss;##  5 ##src/lib/sockfd_to_family.c##
+    socklen_t len;##  6 ##src/lib/sockfd_to_family.c##
+
+    len = sizeof(ss);##  7 ##src/lib/sockfd_to_family.c##
+    if (getsockname(sockfd, (SA *) &ss, &len) < 0)##  8 ##src/lib/sockfd_to_family.c##
+        return (-1);##  9 ##src/lib/sockfd_to_family.c##
+    return (ss.ss_family);## 10 ##src/lib/sockfd_to_family.c##
+}## 11 ##src/lib/sockfd_to_family.c##
+/* end sockfd_to_family */
+
+int## 12 ##src/lib/sockfd_to_family.c##
+Sockfd_to_family(int sockfd)## 13 ##src/lib/sockfd_to_family.c##
+{## 14 ##src/lib/sockfd_to_family.c##
+    int     rc;## 15 ##src/lib/sockfd_to_family.c##
+
+    if ((rc = sockfd_to_family(sockfd)) < 0)## 16 ##src/lib/sockfd_to_family.c##
+        err_sys("sockfd_to_family error");## 17 ##src/lib/sockfd_to_family.c##
+
+    return (rc);## 18 ##src/lib/sockfd_to_family.c##
+}## 19 ##src/lib/sockfd_to_family.c##
diff --git a/lib/str_cli.c b/lib/str_cli.c
new file mode 100644 (file)
index 0000000..ea0f9da
--- /dev/null
@@ -0,0 +1,17 @@
+#include       "unp.h"
+
+void
+str_cli(FILE *fp, int sockfd)
+{
+       char    sendline[MAXLINE], recvline[MAXLINE];
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Writen(sockfd, sendline, strlen(sendline));
+
+               if (Readline(sockfd, recvline, MAXLINE) == 0)
+                       err_quit("str_cli: server terminated prematurely");
+
+               Fputs(recvline, stdout);
+       }
+}
diff --git a/lib/str_cli.lc b/lib/str_cli.lc
new file mode 100644 (file)
index 0000000..0c8b17e
--- /dev/null
@@ -0,0 +1,17 @@
+#include    "unp.h"##  1 ##src/lib/str_cli.c##
+
+void##  2 ##src/lib/str_cli.c##
+str_cli(FILE *fp, int sockfd)##  3 ##src/lib/str_cli.c##
+{##  4 ##src/lib/str_cli.c##
+    char    sendline[MAXLINE], recvline[MAXLINE];##  5 ##src/lib/str_cli.c##
+
+    while (Fgets(sendline, MAXLINE, fp) != NULL) {##  6 ##src/lib/str_cli.c##
+
+        Writen(sockfd, sendline, strlen(sendline));##  7 ##src/lib/str_cli.c##
+
+        if (Readline(sockfd, recvline, MAXLINE) == 0)##  8 ##src/lib/str_cli.c##
+            err_quit("str_cli: server terminated prematurely");##  9 ##src/lib/str_cli.c##
+
+        Fputs(recvline, stdout);## 10 ##src/lib/str_cli.c##
+    }## 11 ##src/lib/str_cli.c##
+}## 12 ##src/lib/str_cli.c##
diff --git a/lib/str_echo.c b/lib/str_echo.c
new file mode 100644 (file)
index 0000000..dab6613
--- /dev/null
@@ -0,0 +1,17 @@
+#include       "unp.h"
+
+void
+str_echo(int sockfd)
+{
+       ssize_t         n;
+       char            buf[MAXLINE];
+
+again:
+       while ( (n = read(sockfd, buf, MAXLINE)) > 0)
+               Writen(sockfd, buf, n);
+
+       if (n < 0 && errno == EINTR)
+               goto again;
+       else if (n < 0)
+               err_sys("str_echo: read error");
+}
diff --git a/lib/str_echo.lc b/lib/str_echo.lc
new file mode 100644 (file)
index 0000000..49b79b7
--- /dev/null
@@ -0,0 +1,17 @@
+#include    "unp.h"##  1 ##src/lib/str_echo.c##
+
+void##  2 ##src/lib/str_echo.c##
+str_echo(int sockfd)##  3 ##src/lib/str_echo.c##
+{##  4 ##src/lib/str_echo.c##
+    ssize_t n;##  5 ##src/lib/str_echo.c##
+    char    buf[MAXLINE];##  6 ##src/lib/str_echo.c##
+
+  again:##  7 ##src/lib/str_echo.c##
+    while ((n = read(sockfd, buf, MAXLINE)) > 0)##  8 ##src/lib/str_echo.c##
+        Writen(sockfd, buf, n);##  9 ##src/lib/str_echo.c##
+
+    if (n < 0 && errno == EINTR)## 10 ##src/lib/str_echo.c##
+        goto again;## 11 ##src/lib/str_echo.c##
+    else if (n < 0)## 12 ##src/lib/str_echo.c##
+        err_sys("str_echo: read error");## 13 ##src/lib/str_echo.c##
+}## 14 ##src/lib/str_echo.c##
diff --git a/lib/tcp_connect.c b/lib/tcp_connect.c
new file mode 100644 (file)
index 0000000..30e9bcd
--- /dev/null
@@ -0,0 +1,49 @@
+/* include tcp_connect */
+#include       "unp.h"
+
+int
+tcp_connect(const char *host, const char *serv)
+{
+       int                             sockfd, n;
+       struct addrinfo hints, *res, *ressave;
+
+       bzero(&hints, sizeof(struct addrinfo));
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_STREAM;
+
+       if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0)
+               err_quit("tcp_connect error for %s, %s: %s",
+                                host, serv, gai_strerror(n));
+       ressave = res;
+
+       do {
+               sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+               if (sockfd < 0)
+                       continue;       /* ignore this one */
+
+               if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
+                       break;          /* success */
+
+               Close(sockfd);  /* ignore this one */
+       } while ( (res = res->ai_next) != NULL);
+
+       if (res == NULL)        /* errno set from final connect() */
+               err_sys("tcp_connect error for %s, %s", host, serv);
+
+       freeaddrinfo(ressave);
+
+       return(sockfd);
+}
+/* end tcp_connect */
+
+/*
+ * We place the wrapper function here, not in wraplib.c, because some
+ * XTI programs need to include wraplib.c, and it also defines
+ * a Tcp_connect() function.
+ */
+
+int
+Tcp_connect(const char *host, const char *serv)
+{
+       return(tcp_connect(host, serv));
+}
diff --git a/lib/tcp_connect.lc b/lib/tcp_connect.lc
new file mode 100644 (file)
index 0000000..989f60d
--- /dev/null
@@ -0,0 +1,49 @@
+/* include tcp_connect */
+#include    "unp.h"##  1 ##src/lib/tcp_connect.c##
+
+int##  2 ##src/lib/tcp_connect.c##
+tcp_connect(const char *host, const char *serv)##  3 ##src/lib/tcp_connect.c##
+{##  4 ##src/lib/tcp_connect.c##
+    int     sockfd, n;##  5 ##src/lib/tcp_connect.c##
+    struct addrinfo hints, *res, *ressave;##  6 ##src/lib/tcp_connect.c##
+
+    bzero(&hints, sizeof(struct addrinfo));##  7 ##src/lib/tcp_connect.c##
+    hints.ai_family = AF_UNSPEC;##  8 ##src/lib/tcp_connect.c##
+    hints.ai_socktype = SOCK_STREAM;##  9 ##src/lib/tcp_connect.c##
+
+    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 10 ##src/lib/tcp_connect.c##
+        err_quit("tcp_connect error for %s, %s: %s",## 11 ##src/lib/tcp_connect.c##
+                 host, serv, gai_strerror(n));## 12 ##src/lib/tcp_connect.c##
+    ressave = res;## 13 ##src/lib/tcp_connect.c##
+
+    do {## 14 ##src/lib/tcp_connect.c##
+        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);## 15 ##src/lib/tcp_connect.c##
+        if (sockfd < 0)## 16 ##src/lib/tcp_connect.c##
+            continue;           /* ignore this one */## 17 ##src/lib/tcp_connect.c##
+
+        if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)## 18 ##src/lib/tcp_connect.c##
+            break;              /* success */## 19 ##src/lib/tcp_connect.c##
+
+        Close(sockfd);          /* ignore this one */## 20 ##src/lib/tcp_connect.c##
+    } while ((res = res->ai_next) != NULL);## 21 ##src/lib/tcp_connect.c##
+
+    if (res == NULL)            /* errno set from final connect() */## 22 ##src/lib/tcp_connect.c##
+        err_sys("tcp_connect error for %s, %s", host, serv);## 23 ##src/lib/tcp_connect.c##
+
+    freeaddrinfo(ressave);## 24 ##src/lib/tcp_connect.c##
+
+    return (sockfd);## 25 ##src/lib/tcp_connect.c##
+}## 26 ##src/lib/tcp_connect.c##
+/* end tcp_connect */
+
+/*## 27 ##src/lib/tcp_connect.c##
+ * We place the wrapper function here, not in wraplib.c, because some## 28 ##src/lib/tcp_connect.c##
+ * XTI programs need to include wraplib.c, and it also defines## 29 ##src/lib/tcp_connect.c##
+ * a Tcp_connect() function.## 30 ##src/lib/tcp_connect.c##
+ */## 31 ##src/lib/tcp_connect.c##
+
+int## 32 ##src/lib/tcp_connect.c##
+Tcp_connect(const char *host, const char *serv)## 33 ##src/lib/tcp_connect.c##
+{## 34 ##src/lib/tcp_connect.c##
+    return (tcp_connect(host, serv));## 35 ##src/lib/tcp_connect.c##
+}## 36 ##src/lib/tcp_connect.c##
diff --git a/lib/tcp_listen.c b/lib/tcp_listen.c
new file mode 100644 (file)
index 0000000..2f5755c
--- /dev/null
@@ -0,0 +1,57 @@
+/* include tcp_listen */
+#include       "unp.h"
+
+int
+tcp_listen(const char *host, const char *serv, socklen_t *addrlenp)
+{
+       int                             listenfd, n;
+       const int               on = 1;
+       struct addrinfo hints, *res, *ressave;
+
+       bzero(&hints, sizeof(struct addrinfo));
+       hints.ai_flags = AI_PASSIVE;
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_STREAM;
+
+       if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0)
+               err_quit("tcp_listen error for %s, %s: %s",
+                                host, serv, gai_strerror(n));
+       ressave = res;
+
+       do {
+               listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+               if (listenfd < 0)
+                       continue;               /* error, try next one */
+
+               Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+               if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0)
+                       break;                  /* success */
+
+               Close(listenfd);        /* bind error, close and try next one */
+       } while ( (res = res->ai_next) != NULL);
+
+       if (res == NULL)        /* errno from final socket() or bind() */
+               err_sys("tcp_listen error for %s, %s", host, serv);
+
+       Listen(listenfd, LISTENQ);
+
+       if (addrlenp)
+               *addrlenp = res->ai_addrlen;    /* return size of protocol address */
+
+       freeaddrinfo(ressave);
+
+       return(listenfd);
+}
+/* end tcp_listen */
+
+/*
+ * We place the wrapper function here, not in wraplib.c, because some
+ * XTI programs need to include wraplib.c, and it also defines
+ * a Tcp_listen() function.
+ */
+
+int
+Tcp_listen(const char *host, const char *serv, socklen_t *addrlenp)
+{
+       return(tcp_listen(host, serv, addrlenp));
+}
diff --git a/lib/tcp_listen.lc b/lib/tcp_listen.lc
new file mode 100644 (file)
index 0000000..874e303
--- /dev/null
@@ -0,0 +1,58 @@
+/* include tcp_listen */
+#include    "unp.h"##  1 ##src/lib/tcp_listen.c##
+
+int##  2 ##src/lib/tcp_listen.c##
+tcp_listen(const char *host, const char *serv, socklen_t *addrlenp)##  3 ##src/lib/tcp_listen.c##
+{##  4 ##src/lib/tcp_listen.c##
+    int     listenfd, n;##  5 ##src/lib/tcp_listen.c##
+    const int on = 1;##  6 ##src/lib/tcp_listen.c##
+    struct addrinfo hints, *res, *ressave;##  7 ##src/lib/tcp_listen.c##
+
+    bzero(&hints, sizeof(struct addrinfo));##  8 ##src/lib/tcp_listen.c##
+    hints.ai_flags = AI_PASSIVE;##  9 ##src/lib/tcp_listen.c##
+    hints.ai_family = AF_UNSPEC;## 10 ##src/lib/tcp_listen.c##
+    hints.ai_socktype = SOCK_STREAM;## 11 ##src/lib/tcp_listen.c##
+
+    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 12 ##src/lib/tcp_listen.c##
+        err_quit("tcp_listen error for %s, %s: %s",## 13 ##src/lib/tcp_listen.c##
+                 host, serv, gai_strerror(n));## 14 ##src/lib/tcp_listen.c##
+    ressave = res;## 15 ##src/lib/tcp_listen.c##
+
+    do {## 16 ##src/lib/tcp_listen.c##
+        listenfd =## 17 ##src/lib/tcp_listen.c##
+            socket(res->ai_family, res->ai_socktype, res->ai_protocol);## 18 ##src/lib/tcp_listen.c##
+        if (listenfd < 0)## 19 ##src/lib/tcp_listen.c##
+            continue;           /* error, try next one */## 20 ##src/lib/tcp_listen.c##
+
+        Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 21 ##src/lib/tcp_listen.c##
+        if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0)## 22 ##src/lib/tcp_listen.c##
+            break;              /* success */## 23 ##src/lib/tcp_listen.c##
+
+        Close(listenfd);        /* bind error, close and try next one */## 24 ##src/lib/tcp_listen.c##
+    } while ((res = res->ai_next) != NULL);## 25 ##src/lib/tcp_listen.c##
+
+    if (res == NULL)            /* errno from final socket() or bind() */## 26 ##src/lib/tcp_listen.c##
+        err_sys("tcp_listen error for %s, %s", host, serv);## 27 ##src/lib/tcp_listen.c##
+
+    Listen(listenfd, LISTENQ);## 28 ##src/lib/tcp_listen.c##
+
+    if (addrlenp)## 29 ##src/lib/tcp_listen.c##
+        *addrlenp = res->ai_addrlen;    /* return size of protocol address */## 30 ##src/lib/tcp_listen.c##
+
+    freeaddrinfo(ressave);## 31 ##src/lib/tcp_listen.c##
+
+    return (listenfd);## 32 ##src/lib/tcp_listen.c##
+}## 33 ##src/lib/tcp_listen.c##
+/* end tcp_listen */
+
+/*## 34 ##src/lib/tcp_listen.c##
+ * We place the wrapper function here, not in wraplib.c, because some## 35 ##src/lib/tcp_listen.c##
+ * XTI programs need to include wraplib.c, and it also defines## 36 ##src/lib/tcp_listen.c##
+ * a Tcp_listen() function.## 37 ##src/lib/tcp_listen.c##
+ */## 38 ##src/lib/tcp_listen.c##
+
+int## 39 ##src/lib/tcp_listen.c##
+Tcp_listen(const char *host, const char *serv, socklen_t *addrlenp)## 40 ##src/lib/tcp_listen.c##
+{## 41 ##src/lib/tcp_listen.c##
+    return (tcp_listen(host, serv, addrlenp));## 42 ##src/lib/tcp_listen.c##
+}## 43 ##src/lib/tcp_listen.c##
diff --git a/lib/tv_sub.c b/lib/tv_sub.c
new file mode 100644 (file)
index 0000000..7ad7830
--- /dev/null
@@ -0,0 +1,11 @@
+#include       "unp.h"
+
+void
+tv_sub(struct timeval *out, struct timeval *in)
+{
+       if ( (out->tv_usec -= in->tv_usec) < 0) {       /* out -= in */
+               --out->tv_sec;
+               out->tv_usec += 1000000;
+       }
+       out->tv_sec -= in->tv_sec;
+}
diff --git a/lib/udp_client.c b/lib/udp_client.c
new file mode 100644 (file)
index 0000000..abe780f
--- /dev/null
@@ -0,0 +1,42 @@
+/* include udp_client */
+#include       "unp.h"
+
+int
+udp_client(const char *host, const char *serv, SA **saptr, socklen_t *lenp)
+{
+       int                             sockfd, n;
+       struct addrinfo hints, *res, *ressave;
+
+       bzero(&hints, sizeof(struct addrinfo));
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_DGRAM;
+
+       if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0)
+               err_quit("udp_client error for %s, %s: %s",
+                                host, serv, gai_strerror(n));
+       ressave = res;
+
+       do {
+               sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+               if (sockfd >= 0)
+                       break;          /* success */
+       } while ( (res = res->ai_next) != NULL);
+
+       if (res == NULL)        /* errno set from final socket() */
+               err_sys("udp_client error for %s, %s", host, serv);
+
+       *saptr = Malloc(res->ai_addrlen);
+       memcpy(*saptr, res->ai_addr, res->ai_addrlen);
+       *lenp = res->ai_addrlen;
+
+       freeaddrinfo(ressave);
+
+       return(sockfd);
+}
+/* end udp_client */
+
+int
+Udp_client(const char *host, const char *serv, SA **saptr, socklen_t *lenptr)
+{
+       return(udp_client(host, serv, saptr, lenptr));
+}
diff --git a/lib/udp_client.lc b/lib/udp_client.lc
new file mode 100644 (file)
index 0000000..055ccc9
--- /dev/null
@@ -0,0 +1,42 @@
+/* include udp_client */
+#include    "unp.h"##  1 ##src/lib/udp_client.c##
+
+int##  2 ##src/lib/udp_client.c##
+udp_client(const char *host, const char *serv, SA **saptr, socklen_t *lenp)##  3 ##src/lib/udp_client.c##
+{##  4 ##src/lib/udp_client.c##
+    int     sockfd, n;##  5 ##src/lib/udp_client.c##
+    struct addrinfo hints, *res, *ressave;##  6 ##src/lib/udp_client.c##
+
+    bzero(&hints, sizeof(struct addrinfo));##  7 ##src/lib/udp_client.c##
+    hints.ai_family = AF_UNSPEC;##  8 ##src/lib/udp_client.c##
+    hints.ai_socktype = SOCK_DGRAM;##  9 ##src/lib/udp_client.c##
+
+    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 10 ##src/lib/udp_client.c##
+        err_quit("udp_client error for %s, %s: %s",## 11 ##src/lib/udp_client.c##
+                 host, serv, gai_strerror(n));## 12 ##src/lib/udp_client.c##
+    ressave = res;## 13 ##src/lib/udp_client.c##
+
+    do {## 14 ##src/lib/udp_client.c##
+        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);## 15 ##src/lib/udp_client.c##
+        if (sockfd >= 0)## 16 ##src/lib/udp_client.c##
+            break;              /* success */## 17 ##src/lib/udp_client.c##
+    } while ((res = res->ai_next) != NULL);## 18 ##src/lib/udp_client.c##
+
+    if (res == NULL)            /* errno set from final socket() */## 19 ##src/lib/udp_client.c##
+        err_sys("udp_client error for %s, %s", host, serv);## 20 ##src/lib/udp_client.c##
+
+    *saptr = Malloc(res->ai_addrlen);## 21 ##src/lib/udp_client.c##
+    memcpy(*saptr, res->ai_addr, res->ai_addrlen);## 22 ##src/lib/udp_client.c##
+    *lenp = res->ai_addrlen;## 23 ##src/lib/udp_client.c##
+
+    freeaddrinfo(ressave);## 24 ##src/lib/udp_client.c##
+
+    return (sockfd);## 25 ##src/lib/udp_client.c##
+}## 26 ##src/lib/udp_client.c##
+/* end udp_client */
+
+int## 27 ##src/lib/udp_client.c##
+Udp_client(const char *host, const char *serv, SA **saptr, socklen_t *lenptr)## 28 ##src/lib/udp_client.c##
+{## 29 ##src/lib/udp_client.c##
+    return (udp_client(host, serv, saptr, lenptr));## 30 ##src/lib/udp_client.c##
+}## 31 ##src/lib/udp_client.c##
diff --git a/lib/udp_connect.c b/lib/udp_connect.c
new file mode 100644 (file)
index 0000000..5b90357
--- /dev/null
@@ -0,0 +1,49 @@
+/* include udp_connect */
+#include       "unp.h"
+
+int
+udp_connect(const char *host, const char *serv)
+{
+       int                             sockfd, n;
+       struct addrinfo hints, *res, *ressave;
+
+       bzero(&hints, sizeof(struct addrinfo));
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_DGRAM;
+
+       if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0)
+               err_quit("udp_connect error for %s, %s: %s",
+                                host, serv, gai_strerror(n));
+       ressave = res;
+
+       do {
+               sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+               if (sockfd < 0)
+                       continue;       /* ignore this one */
+
+               if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)
+                       break;          /* success */
+
+               Close(sockfd);  /* ignore this one */
+       } while ( (res = res->ai_next) != NULL);
+
+       if (res == NULL)        /* errno set from final connect() */
+               err_sys("udp_connect error for %s, %s", host, serv);
+
+       freeaddrinfo(ressave);
+
+       return(sockfd);
+}
+/* end udp_connect */
+
+int
+Udp_connect(const char *host, const char *serv)
+{
+       int             n;
+
+       if ( (n = udp_connect(host, serv)) < 0) {
+               err_quit("udp_connect error for %s, %s: %s",
+                                        host, serv, gai_strerror(-n));
+       }
+       return(n);
+}
diff --git a/lib/udp_connect.lc b/lib/udp_connect.lc
new file mode 100644 (file)
index 0000000..96b98e8
--- /dev/null
@@ -0,0 +1,49 @@
+/* include udp_connect */
+#include    "unp.h"##  1 ##src/lib/udp_connect.c##
+
+int##  2 ##src/lib/udp_connect.c##
+udp_connect(const char *host, const char *serv)##  3 ##src/lib/udp_connect.c##
+{##  4 ##src/lib/udp_connect.c##
+    int     sockfd, n;##  5 ##src/lib/udp_connect.c##
+    struct addrinfo hints, *res, *ressave;##  6 ##src/lib/udp_connect.c##
+
+    bzero(&hints, sizeof(struct addrinfo));##  7 ##src/lib/udp_connect.c##
+    hints.ai_family = AF_UNSPEC;##  8 ##src/lib/udp_connect.c##
+    hints.ai_socktype = SOCK_DGRAM;##  9 ##src/lib/udp_connect.c##
+
+    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 10 ##src/lib/udp_connect.c##
+        err_quit("udp_connect error for %s, %s: %s",## 11 ##src/lib/udp_connect.c##
+                 host, serv, gai_strerror(n));## 12 ##src/lib/udp_connect.c##
+    ressave = res;## 13 ##src/lib/udp_connect.c##
+
+    do {## 14 ##src/lib/udp_connect.c##
+        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);## 15 ##src/lib/udp_connect.c##
+        if (sockfd < 0)## 16 ##src/lib/udp_connect.c##
+            continue;           /* ignore this one */## 17 ##src/lib/udp_connect.c##
+
+        if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0)## 18 ##src/lib/udp_connect.c##
+            break;              /* success */## 19 ##src/lib/udp_connect.c##
+
+        Close(sockfd);          /* ignore this one */## 20 ##src/lib/udp_connect.c##
+    } while ((res = res->ai_next) != NULL);## 21 ##src/lib/udp_connect.c##
+
+    if (res == NULL)            /* errno set from final connect() */## 22 ##src/lib/udp_connect.c##
+        err_sys("udp_connect error for %s, %s", host, serv);## 23 ##src/lib/udp_connect.c##
+
+    freeaddrinfo(ressave);## 24 ##src/lib/udp_connect.c##
+
+    return (sockfd);## 25 ##src/lib/udp_connect.c##
+}## 26 ##src/lib/udp_connect.c##
+/* end udp_connect */
+
+int## 27 ##src/lib/udp_connect.c##
+Udp_connect(const char *host, const char *serv)## 28 ##src/lib/udp_connect.c##
+{## 29 ##src/lib/udp_connect.c##
+    int     n;## 30 ##src/lib/udp_connect.c##
+
+    if ((n = udp_connect(host, serv)) < 0) {## 31 ##src/lib/udp_connect.c##
+        err_quit("udp_connect error for %s, %s: %s",## 32 ##src/lib/udp_connect.c##
+                 host, serv, gai_strerror(-n));## 33 ##src/lib/udp_connect.c##
+    }## 34 ##src/lib/udp_connect.c##
+    return (n);## 35 ##src/lib/udp_connect.c##
+}## 36 ##src/lib/udp_connect.c##
diff --git a/lib/udp_server.c b/lib/udp_server.c
new file mode 100644 (file)
index 0000000..d9c2dcf
--- /dev/null
@@ -0,0 +1,47 @@
+/* include udp_server */
+#include       "unp.h"
+
+int
+udp_server(const char *host, const char *serv, socklen_t *addrlenp)
+{
+       int                             sockfd, n;
+       struct addrinfo hints, *res, *ressave;
+
+       bzero(&hints, sizeof(struct addrinfo));
+       hints.ai_flags = AI_PASSIVE;
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_DGRAM;
+
+       if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0)
+               err_quit("udp_server error for %s, %s: %s",
+                                host, serv, gai_strerror(n));
+       ressave = res;
+
+       do {
+               sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+               if (sockfd < 0)
+                       continue;               /* error - try next one */
+
+               if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0)
+                       break;                  /* success */
+
+               Close(sockfd);          /* bind error - close and try next one */
+       } while ( (res = res->ai_next) != NULL);
+
+       if (res == NULL)        /* errno from final socket() or bind() */
+               err_sys("udp_server error for %s, %s", host, serv);
+
+       if (addrlenp)
+               *addrlenp = res->ai_addrlen;    /* return size of protocol address */
+
+       freeaddrinfo(ressave);
+
+       return(sockfd);
+}
+/* end udp_server */
+
+int
+Udp_server(const char *host, const char *serv, socklen_t *addrlenp)
+{
+       return(udp_server(host, serv, addrlenp));
+}
diff --git a/lib/udp_server.lc b/lib/udp_server.lc
new file mode 100644 (file)
index 0000000..3e9e6a7
--- /dev/null
@@ -0,0 +1,47 @@
+/* include udp_server */
+#include    "unp.h"##  1 ##src/lib/udp_server.c##
+
+int##  2 ##src/lib/udp_server.c##
+udp_server(const char *host, const char *serv, socklen_t *addrlenp)##  3 ##src/lib/udp_server.c##
+{##  4 ##src/lib/udp_server.c##
+    int     sockfd, n;##  5 ##src/lib/udp_server.c##
+    struct addrinfo hints, *res, *ressave;##  6 ##src/lib/udp_server.c##
+
+    bzero(&hints, sizeof(struct addrinfo));##  7 ##src/lib/udp_server.c##
+    hints.ai_flags = AI_PASSIVE;##  8 ##src/lib/udp_server.c##
+    hints.ai_family = AF_UNSPEC;##  9 ##src/lib/udp_server.c##
+    hints.ai_socktype = SOCK_DGRAM;## 10 ##src/lib/udp_server.c##
+
+    if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)## 11 ##src/lib/udp_server.c##
+        err_quit("udp_server error for %s, %s: %s",## 12 ##src/lib/udp_server.c##
+                 host, serv, gai_strerror(n));## 13 ##src/lib/udp_server.c##
+    ressave = res;## 14 ##src/lib/udp_server.c##
+
+    do {## 15 ##src/lib/udp_server.c##
+        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);## 16 ##src/lib/udp_server.c##
+        if (sockfd < 0)## 17 ##src/lib/udp_server.c##
+            continue;           /* error, try next one */## 18 ##src/lib/udp_server.c##
+
+        if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0)## 19 ##src/lib/udp_server.c##
+            break;              /* success */## 20 ##src/lib/udp_server.c##
+
+        Close(sockfd);          /* bind error, close and try next one */## 21 ##src/lib/udp_server.c##
+    } while ((res = res->ai_next) != NULL);## 22 ##src/lib/udp_server.c##
+
+    if (res == NULL)            /* errno from final socket() or bind() */## 23 ##src/lib/udp_server.c##
+        err_sys("udp_server error for %s, %s", host, serv);## 24 ##src/lib/udp_server.c##
+
+    if (addrlenp)## 25 ##src/lib/udp_server.c##
+        *addrlenp = res->ai_addrlen;    /* return size of protocol address */## 26 ##src/lib/udp_server.c##
+
+    freeaddrinfo(ressave);## 27 ##src/lib/udp_server.c##
+
+    return (sockfd);## 28 ##src/lib/udp_server.c##
+}## 29 ##src/lib/udp_server.c##
+/* end udp_server */
+
+int## 30 ##src/lib/udp_server.c##
+Udp_server(const char *host, const char *serv, socklen_t *addrlenp)## 31 ##src/lib/udp_server.c##
+{## 32 ##src/lib/udp_server.c##
+    return (udp_server(host, serv, addrlenp));## 33 ##src/lib/udp_server.c##
+}## 34 ##src/lib/udp_server.c##
diff --git a/lib/unp.h b/lib/unp.h
new file mode 100644 (file)
index 0000000..5b8e2a2
--- /dev/null
+++ b/lib/unp.h
@@ -0,0 +1,517 @@
+/* include unph */
+/* Our own header.  Tabs are set for 4 spaces, not 8 */
+
+#ifndef        __unp_h
+#define        __unp_h
+
+#include       "../config.h"   /* configuration options for current OS */
+                                                       /* "../config.h" is generated by configure */
+
+/* If anything changes in the following list of #includes, must change
+   acsite.m4 also, for configure's tests. */
+
+#include       <sys/types.h>   /* basic system data types */
+#include       <sys/socket.h>  /* basic socket definitions */
+#if TIME_WITH_SYS_TIME
+#include       <sys/time.h>    /* timeval{} for select() */
+#include       <time.h>                /* timespec{} for pselect() */
+#else
+#if HAVE_SYS_TIME_H
+#include       <sys/time.h>    /* includes <time.h> unsafely */
+#else
+#include       <time.h>                /* old system? */
+#endif
+#endif
+#include       <netinet/in.h>  /* sockaddr_in{} and other Internet defns */
+#include       <arpa/inet.h>   /* inet(3) functions */
+#include       <errno.h>
+#include       <fcntl.h>               /* for nonblocking */
+#include       <netdb.h>
+#include       <signal.h>
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+#include       <sys/stat.h>    /* for S_xxx file mode constants */
+#include       <sys/uio.h>             /* for iovec{} and readv/writev */
+#include       <unistd.h>
+#include       <sys/wait.h>
+#include       <sys/un.h>              /* for Unix domain sockets */
+
+#ifdef HAVE_SYS_SELECT_H
+# include      <sys/select.h>  /* for convenience */
+#endif
+
+#ifdef HAVE_SYS_SYSCTL_H
+#ifdef HAVE_SYS_PARAM_H
+# include      <sys/param.h>   /* OpenBSD prereq for sysctl.h */
+#endif
+# include      <sys/sysctl.h>
+#endif
+
+#ifdef HAVE_POLL_H
+# include      <poll.h>                /* for convenience */
+#endif
+
+#ifdef HAVE_SYS_EVENT_H
+# include      <sys/event.h>   /* for kqueue */
+#endif
+
+#ifdef HAVE_STRINGS_H
+# include      <strings.h>             /* for convenience */
+#endif
+
+/* Three headers are normally needed for socket/file ioctl's:
+ * <sys/ioctl.h>, <sys/filio.h>, and <sys/sockio.h>.
+ */
+#ifdef HAVE_SYS_IOCTL_H
+# include      <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include      <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include      <sys/sockio.h>
+#endif
+
+#ifdef HAVE_PTHREAD_H
+# include      <pthread.h>
+#endif
+
+#ifdef HAVE_NET_IF_DL_H
+# include      <net/if_dl.h>
+#endif
+
+#ifdef HAVE_NETINET_SCTP_H
+#include       <netinet/sctp.h>
+#endif
+
+/* OSF/1 actually disables recv() and send() in <sys/socket.h> */
+#ifdef __osf__
+#undef recv
+#undef send
+#define        recv(a,b,c,d)   recvfrom(a,b,c,d,0,0)
+#define        send(a,b,c,d)   sendto(a,b,c,d,0,0)
+#endif
+
+#ifndef        INADDR_NONE
+/* $$.Ic INADDR_NONE$$ */
+#define        INADDR_NONE     0xffffffff      /* should have been in <netinet/in.h> */
+#endif
+
+#ifndef        SHUT_RD                         /* these three POSIX names are new */
+#define        SHUT_RD         0       /* shutdown for reading */
+#define        SHUT_WR         1       /* shutdown for writing */
+#define        SHUT_RDWR       2       /* shutdown for reading and writing */
+/* $$.Ic SHUT_RD$$ */
+/* $$.Ic SHUT_WR$$ */
+/* $$.Ic SHUT_RDWR$$ */
+#endif
+
+/* *INDENT-OFF* */
+#ifndef INET_ADDRSTRLEN
+/* $$.Ic INET_ADDRSTRLEN$$ */
+#define        INET_ADDRSTRLEN         16      /* "ddd.ddd.ddd.ddd\0"
+                                                                   1234567890123456 */
+#endif
+
+/* Define following even if IPv6 not supported, so we can always allocate
+   an adequately sized buffer without #ifdefs in the code. */
+#ifndef INET6_ADDRSTRLEN
+/* $$.Ic INET6_ADDRSTRLEN$$ */
+#define        INET6_ADDRSTRLEN        46      /* max size of IPv6 address string:
+                                  "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" or
+                                  "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd\0"
+                                   1234567890123456789012345678901234567890123456 */
+#endif
+/* *INDENT-ON* */
+
+/* Define bzero() as a macro if it's not in standard C library. */
+#ifndef        HAVE_BZERO
+#define        bzero(ptr,n)            memset(ptr, 0, n)
+/* $$.If bzero$$ */
+/* $$.If memset$$ */
+#endif
+
+/* Older resolvers do not have gethostbyname2() */
+#ifndef        HAVE_GETHOSTBYNAME2
+#define        gethostbyname2(host,family)             gethostbyname((host))
+#endif
+
+/* The structure returned by recvfrom_flags() */
+struct unp_in_pktinfo {
+  struct in_addr       ipi_addr;       /* dst IPv4 address */
+  int                          ipi_ifindex;/* received interface index */
+};
+/* $$.It unp_in_pktinfo$$ */
+/* $$.Ib ipi_addr$$ */
+/* $$.Ib ipi_ifindex$$ */
+
+/* We need the newer CMSG_LEN() and CMSG_SPACE() macros, but few
+   implementations support them today.  These two macros really need
+    an ALIGN() macro, but each implementation does this differently. */
+#ifndef        CMSG_LEN
+/* $$.Im CMSG_LEN$$ */
+#define        CMSG_LEN(size)          (sizeof(struct cmsghdr) + (size))
+#endif
+#ifndef        CMSG_SPACE
+/* $$.Im CMSG_SPACE$$ */
+#define        CMSG_SPACE(size)        (sizeof(struct cmsghdr) + (size))
+#endif
+
+/* POSIX requires the SUN_LEN() macro, but not all implementations DefinE
+   it (yet).  Note that this 4.4BSD macro works regardless whether there is
+   a length field or not. */
+#ifndef        SUN_LEN
+/* $$.Im SUN_LEN$$ */
+# define       SUN_LEN(su) \
+       (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
+#endif
+
+/* POSIX renames "Unix domain" as "local IPC."
+   Not all systems DefinE AF_LOCAL and PF_LOCAL (yet). */
+#ifndef        AF_LOCAL
+#define AF_LOCAL       AF_UNIX
+#endif
+#ifndef        PF_LOCAL
+#define PF_LOCAL       PF_UNIX
+#endif
+
+/* POSIX requires that an #include of <poll.h> DefinE INFTIM, but many
+   systems still DefinE it in <sys/stropts.h>.  We don't want to include
+   all the STREAMS stuff if it's not needed, so we just DefinE INFTIM here.
+   This is the standard value, but there's no guarantee it is -1. */
+#ifndef INFTIM
+#define INFTIM          (-1)    /* infinite poll timeout */
+/* $$.Ic INFTIM$$ */
+#ifdef HAVE_POLL_H
+#define        INFTIM_UNPH                             /* tell unpxti.h we defined it */
+#endif
+#endif
+
+/* Following could be derived from SOMAXCONN in <sys/socket.h>, but many
+   kernels still #define it as 5, while actually supporting many more */
+#define        LISTENQ         1024    /* 2nd argument to listen() */
+
+/* Miscellaneous constants */
+#define        MAXLINE         4096    /* max text line length */
+#define        BUFFSIZE        8192    /* buffer size for reads and writes */
+
+/* Define some port number that can be used for our examples */
+#define        SERV_PORT                9877                   /* TCP and UDP */
+#define        SERV_PORT_STR   "9877"                  /* TCP and UDP */
+#define        UNIXSTR_PATH    "/tmp/unix.str" /* Unix domain stream */
+#define        UNIXDG_PATH             "/tmp/unix.dg"  /* Unix domain datagram */
+/* $$.ix [LISTENQ]~constant,~definition~of$$ */
+/* $$.ix [MAXLINE]~constant,~definition~of$$ */
+/* $$.ix [BUFFSIZE]~constant,~definition~of$$ */
+/* $$.ix [SERV_PORT]~constant,~definition~of$$ */
+/* $$.ix [UNIXSTR_PATH]~constant,~definition~of$$ */
+/* $$.ix [UNIXDG_PATH]~constant,~definition~of$$ */
+
+/* Following shortens all the typecasts of pointer arguments: */
+#define        SA      struct sockaddr
+
+#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
+/*
+ * RFC 3493: protocol-independent placeholder for socket addresses
+ */
+#define        __SS_MAXSIZE    128
+#define        __SS_ALIGNSIZE  (sizeof(int64_t))
+#ifdef HAVE_SOCKADDR_SA_LEN
+#define        __SS_PAD1SIZE   (__SS_ALIGNSIZE - sizeof(u_char) - sizeof(sa_family_t))
+#else
+#define        __SS_PAD1SIZE   (__SS_ALIGNSIZE - sizeof(sa_family_t))
+#endif
+#define        __SS_PAD2SIZE   (__SS_MAXSIZE - 2*__SS_ALIGNSIZE)
+
+struct sockaddr_storage {
+#ifdef HAVE_SOCKADDR_SA_LEN
+       u_char          ss_len;
+#endif
+       sa_family_t     ss_family;
+       char            __ss_pad1[__SS_PAD1SIZE];
+       int64_t         __ss_align;
+       char            __ss_pad2[__SS_PAD2SIZE];
+};
+#endif
+
+#define        FILE_MODE       (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
+                                       /* default file access permissions for new files */
+#define        DIR_MODE        (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)
+                                       /* default permissions for new directories */
+
+typedef        void    Sigfunc(int);   /* for signal handlers */
+
+#define        min(a,b)        ((a) < (b) ? (a) : (b))
+#define        max(a,b)        ((a) > (b) ? (a) : (b))
+
+#ifndef        HAVE_ADDRINFO_STRUCT
+# include      "../lib/addrinfo.h"
+#endif
+
+#ifndef        HAVE_IF_NAMEINDEX_STRUCT
+struct if_nameindex {
+  unsigned int   if_index;  /* 1, 2, ... */
+  char          *if_name;   /* null-terminated name: "le0", ... */
+};
+/* $$.It if_nameindex$$ */
+/* $$.Ib if_index$$ */
+/* $$.Ib if_name$$ */
+#endif
+
+#ifndef        HAVE_TIMESPEC_STRUCT
+struct timespec {
+  time_t       tv_sec;         /* seconds */
+  long         tv_nsec;        /* and nanoseconds */
+};
+/* $$.It timespec$$ */
+/* $$.Ib tv_sec$$ */
+/* $$.Ib tv_nsec$$ */
+#endif
+/* end unph */
+
+                       /* prototypes for our own library functions */
+int             connect_nonb(int, const SA *, socklen_t, int);
+int             connect_timeo(int, const SA *, socklen_t, int);
+int     daemon_init(const char *, int);
+void    daemon_inetd(const char *, int);
+void    dg_cli(FILE *, int, const SA *, socklen_t);
+void    dg_echo(int, SA *, socklen_t);
+int             family_to_level(int);
+char   *gf_time(void);
+void    heartbeat_cli(int, int, int);
+void    heartbeat_serv(int, int, int);
+struct addrinfo *host_serv(const char *, const char *, int, int);
+int             inet_srcrt_add(char *);
+u_char  *inet_srcrt_init(int);
+void    inet_srcrt_print(u_char *, int);
+void    inet6_srcrt_print(void *);
+char   **my_addrs(int *);
+int             readable_timeo(int, int);
+ssize_t         readline(int, void *, size_t);
+ssize_t         readn(int, void *, size_t);
+ssize_t         read_fd(int, void *, size_t, int *);
+ssize_t         recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *,
+                struct unp_in_pktinfo *);
+Sigfunc *signal_intr(int, Sigfunc *);
+int             sock_bind_wild(int, int);
+int             sock_cmp_addr(const SA *, const SA *, socklen_t);
+int             sock_cmp_port(const SA *, const SA *, socklen_t);
+int             sock_get_port(const SA *, socklen_t);
+void    sock_set_addr(SA *, socklen_t, const void *);
+void    sock_set_port(SA *, socklen_t, int);
+void    sock_set_wild(SA *, socklen_t);
+char   *sock_ntop(const SA *, socklen_t);
+char   *sock_ntop_host(const SA *, socklen_t);
+int             sockfd_to_family(int);
+void    str_echo(int);
+void    str_cli(FILE *, int);
+int             tcp_connect(const char *, const char *);
+int             tcp_listen(const char *, const char *, socklen_t *);
+void    tv_sub(struct timeval *, struct timeval *);
+int             udp_client(const char *, const char *, SA **, socklen_t *);
+int             udp_connect(const char *, const char *);
+int             udp_server(const char *, const char *, socklen_t *);
+int             writable_timeo(int, int);
+ssize_t         writen(int, const void *, size_t);
+ssize_t         write_fd(int, void *, size_t, int);
+
+#ifdef MCAST
+int             mcast_leave(int, const SA *, socklen_t);
+int             mcast_join(int, const SA *, socklen_t, const char *, u_int);
+int             mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen,
+                                                                 const SA *grp, socklen_t grplen);
+int             mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen,
+                                                                const SA *grp, socklen_t grplen,
+                                                                const char *ifname, u_int ifindex);
+int             mcast_block_source(int sockfd, const SA *src, socklen_t srclen,
+                                                       const SA *grp, socklen_t grplen);
+int             mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen,
+                                                         const SA *grp, socklen_t grplen);
+int             mcast_get_if(int);
+int             mcast_get_loop(int);
+int             mcast_get_ttl(int);
+int             mcast_set_if(int, const char *, u_int);
+int             mcast_set_loop(int, int);
+int             mcast_set_ttl(int, int);
+
+void    Mcast_leave(int, const SA *, socklen_t);
+void    Mcast_join(int, const SA *, socklen_t, const char *, u_int);
+void    Mcast_leave_source_group(int sockfd, const SA *src, socklen_t srclen,
+                                                                 const SA *grp, socklen_t grplen);
+void    Mcast_join_source_group(int sockfd, const SA *src, socklen_t srclen,
+                                                                const SA *grp, socklen_t grplen,
+                                                                const char *ifname, u_int ifindex);
+void    Mcast_block_source(int sockfd, const SA *src, socklen_t srclen,
+                                                       const SA *grp, socklen_t grplen);
+void    Mcast_unblock_source(int sockfd, const SA *src, socklen_t srclen,
+                                                         const SA *grp, socklen_t grplen);
+int             Mcast_get_if(int);
+int             Mcast_get_loop(int);
+int             Mcast_get_ttl(int);
+void    Mcast_set_if(int, const char *, u_int);
+void    Mcast_set_loop(int, int);
+void    Mcast_set_ttl(int, int);
+#endif
+
+uint16_t       in_cksum(uint16_t *, int);
+
+#ifndef        HAVE_GETADDRINFO_PROTO
+int             getaddrinfo(const char *, const char *, const struct addrinfo *,
+                                        struct addrinfo **);
+void    freeaddrinfo(struct addrinfo *);
+char   *gai_strerror(int);
+#endif
+
+#ifndef        HAVE_GETNAMEINFO_PROTO
+int             getnameinfo(const SA *, socklen_t, char *, size_t, char *, size_t, int);
+#endif
+
+#ifndef        HAVE_GETHOSTNAME_PROTO
+int             gethostname(char *, int);
+#endif
+
+#ifndef        HAVE_HSTRERROR_PROTO
+const char     *hstrerror(int);
+#endif
+
+#ifndef        HAVE_IF_NAMETOINDEX_PROTO
+unsigned int    if_nametoindex(const char *);
+char                   *if_indextoname(unsigned int, char *);
+void                    if_freenameindex(struct if_nameindex *);
+struct if_nameindex *if_nameindex(void);
+#endif
+
+#ifndef        HAVE_INET_PTON_PROTO
+int                     inet_pton(int, const char *, void *);
+const char     *inet_ntop(int, const void *, char *, size_t);
+#endif
+
+#ifndef        HAVE_INET_ATON_PROTO
+int             inet_aton(const char *, struct in_addr *);
+#endif
+
+#ifndef        HAVE_PSELECT_PROTO
+int             pselect(int, fd_set *, fd_set *, fd_set *,
+                                const struct timespec *, const sigset_t *);
+#endif
+
+#ifndef        HAVE_SOCKATMARK_PROTO
+int             sockatmark(int);
+#endif
+
+#ifndef        HAVE_SNPRINTF_PROTO
+int             snprintf(char *, size_t, const char *, ...);
+#endif
+
+                       /* prototypes for our own library wrapper functions */
+void    Connect_timeo(int, const SA *, socklen_t, int);
+int             Family_to_level(int);
+struct addrinfo *Host_serv(const char *, const char *, int, int);
+const char             *Inet_ntop(int, const void *, char *, size_t);
+void                    Inet_pton(int, const char *, void *);
+char                   *If_indextoname(unsigned int, char *);
+unsigned int            If_nametoindex(const char *);
+struct if_nameindex    *If_nameindex(void);
+char   **My_addrs(int *);
+ssize_t         Read_fd(int, void *, size_t, int *);
+int             Readable_timeo(int, int);
+ssize_t         Recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *,
+                struct unp_in_pktinfo *);
+Sigfunc *Signal(int, Sigfunc *);
+Sigfunc *Signal_intr(int, Sigfunc *);
+int             Sock_bind_wild(int, int);
+char   *Sock_ntop(const SA *, socklen_t);
+char   *Sock_ntop_host(const SA *, socklen_t);
+int             Sockfd_to_family(int);
+int             Tcp_connect(const char *, const char *);
+int             Tcp_listen(const char *, const char *, socklen_t *);
+int             Udp_client(const char *, const char *, SA **, socklen_t *);
+int             Udp_connect(const char *, const char *);
+int             Udp_server(const char *, const char *, socklen_t *);
+ssize_t         Write_fd(int, void *, size_t, int);
+int             Writable_timeo(int, int);
+
+                       /* prototypes for our Unix wrapper functions: see {Sec errors} */
+void   *Calloc(size_t, size_t);
+void    Close(int);
+void    Dup2(int, int);
+int             Fcntl(int, int, int);
+void    Gettimeofday(struct timeval *, void *);
+int             Ioctl(int, int, void *);
+pid_t   Fork(void);
+void   *Malloc(size_t);
+int     Mkstemp(char *);
+void   *Mmap(void *, size_t, int, int, int, off_t);
+int             Open(const char *, int, mode_t);
+void    Pipe(int *fds);
+ssize_t         Read(int, void *, size_t);
+void    Sigaddset(sigset_t *, int);
+void    Sigdelset(sigset_t *, int);
+void    Sigemptyset(sigset_t *);
+void    Sigfillset(sigset_t *);
+int             Sigismember(const sigset_t *, int);
+void    Sigpending(sigset_t *);
+void    Sigprocmask(int, const sigset_t *, sigset_t *);
+char   *Strdup(const char *);
+long    Sysconf(int);
+void    Sysctl(int *, u_int, void *, size_t *, void *, size_t);
+void    Unlink(const char *);
+pid_t   Wait(int *);
+pid_t   Waitpid(pid_t, int *, int);
+void    Write(int, void *, size_t);
+
+                       /* prototypes for our stdio wrapper functions: see {Sec errors} */
+void    Fclose(FILE *);
+FILE   *Fdopen(int, const char *);
+char   *Fgets(char *, int, FILE *);
+FILE   *Fopen(const char *, const char *);
+void    Fputs(const char *, FILE *);
+
+                       /* prototypes for our socket wrapper functions: see {Sec errors} */
+int             Accept(int, SA *, socklen_t *);
+void    Bind(int, const SA *, socklen_t);
+void    Connect(int, const SA *, socklen_t);
+void    Getpeername(int, SA *, socklen_t *);
+void    Getsockname(int, SA *, socklen_t *);
+void    Getsockopt(int, int, int, void *, socklen_t *);
+#ifdef HAVE_INET6_RTH_INIT
+int             Inet6_rth_space(int, int);
+void   *Inet6_rth_init(void *, socklen_t, int, int);
+void    Inet6_rth_add(void *, const struct in6_addr *);
+void    Inet6_rth_reverse(const void *, void *);
+int             Inet6_rth_segments(const void *);
+struct in6_addr *Inet6_rth_getaddr(const void *, int);
+#endif
+#ifdef HAVE_KQUEUE
+int             Kqueue(void);
+int             Kevent(int, const struct kevent *, int,
+                               struct kevent *, int, const struct timespec *);
+#endif
+void    Listen(int, int);
+#ifdef HAVE_POLL
+int             Poll(struct pollfd *, unsigned long, int);
+#endif
+ssize_t         Readline(int, void *, size_t);
+ssize_t         Readn(int, void *, size_t);
+ssize_t         Recv(int, void *, size_t, int);
+ssize_t         Recvfrom(int, void *, size_t, int, SA *, socklen_t *);
+ssize_t         Recvmsg(int, struct msghdr *, int);
+int             Select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+void    Send(int, const void *, size_t, int);
+void    Sendto(int, const void *, size_t, int, const SA *, socklen_t);
+void    Sendmsg(int, const struct msghdr *, int);
+void    Setsockopt(int, int, int, const void *, socklen_t);
+void    Shutdown(int, int);
+int             Sockatmark(int);
+int             Socket(int, int, int);
+void    Socketpair(int, int, int, int *);
+void    Writen(int, void *, size_t);
+
+void    err_dump(const char *, ...);
+void    err_msg(const char *, ...);
+void    err_quit(const char *, ...);
+void    err_ret(const char *, ...);
+void    err_sys(const char *, ...);
+
+#endif /* __unp_h */
diff --git a/lib/unp.lh b/lib/unp.lh
new file mode 100644 (file)
index 0000000..ce55419
--- /dev/null
@@ -0,0 +1,436 @@
+/* include unph */
+/* Our own header.  Tabs are set for 4 spaces, not 8 */##  1 ##src/lib/unp.h##
+
+#ifndef __unp_h##  2 ##src/lib/unp.h##
+#define __unp_h##  3 ##src/lib/unp.h##
+
+#include    "../config.h"       /* configuration options for current OS */##  4 ##src/lib/unp.h##
+                            /* "../config.h" is generated by configure */##  5 ##src/lib/unp.h##
+
+/* If anything changes in the following list of #includes, must change##  6 ##src/lib/unp.h##
+   acsite.m4 also, for configure's tests. */##  7 ##src/lib/unp.h##
+
+#include    <sys/types.h>       /* basic system data types */##  8 ##src/lib/unp.h##
+#include    <sys/socket.h>      /* basic socket definitions */##  9 ##src/lib/unp.h##
+#include    <sys/time.h>        /* timeval{} for select() */## 10 ##src/lib/unp.h##
+#include    <time.h>            /* timespec{} for pselect() */## 11 ##src/lib/unp.h##
+#include    <netinet/in.h>      /* sockaddr_in{} and other Internet defns */## 12 ##src/lib/unp.h##
+#include    <arpa/inet.h>       /* inet(3) functions */## 13 ##src/lib/unp.h##
+#include    <errno.h>## 14 ##src/lib/unp.h##
+#include    <fcntl.h>           /* for nonblocking */## 15 ##src/lib/unp.h##
+#include    <netdb.h>## 16 ##src/lib/unp.h##
+#include    <signal.h>## 17 ##src/lib/unp.h##
+#include    <stdio.h>## 18 ##src/lib/unp.h##
+#include    <stdlib.h>## 19 ##src/lib/unp.h##
+#include    <string.h>## 20 ##src/lib/unp.h##
+#include    <sys/stat.h>        /* for S_xxx file mode constants */## 21 ##src/lib/unp.h##
+#include    <sys/uio.h>         /* for iovec{} and readv/writev */## 22 ##src/lib/unp.h##
+#include    <unistd.h>## 23 ##src/lib/unp.h##
+#include    <sys/wait.h>## 24 ##src/lib/unp.h##
+#include    <sys/un.h>          /* for Unix domain sockets */## 25 ##src/lib/unp.h##
+
+#ifdef  HAVE_SYS_SELECT_H## 26 ##src/lib/unp.h##
+#include    <sys/select.h>      /* for convenience */## 27 ##src/lib/unp.h##
+#endif## 28 ##src/lib/unp.h##
+
+#ifdef  HAVE_POLL_H## 29 ##src/lib/unp.h##
+#include    <poll.h>            /* for convenience */## 30 ##src/lib/unp.h##
+#endif## 31 ##src/lib/unp.h##
+
+#ifdef  HAVE_STRINGS_H## 32 ##src/lib/unp.h##
+#include    <strings.h>         /* for convenience */## 33 ##src/lib/unp.h##
+#endif## 34 ##src/lib/unp.h##
+
+/* Three headers are normally needed for socket/file ioctl's:## 35 ##src/lib/unp.h##
+ * <sys/ioctl.h>, <sys/filio.h>, and <sys/sockio.h>.## 36 ##src/lib/unp.h##
+ */## 37 ##src/lib/unp.h##
+#ifdef  HAVE_SYS_IOCTL_H## 38 ##src/lib/unp.h##
+#include    <sys/ioctl.h>## 39 ##src/lib/unp.h##
+#endif## 40 ##src/lib/unp.h##
+#ifdef  HAVE_SYS_FILIO_H## 41 ##src/lib/unp.h##
+#include    <sys/filio.h>## 42 ##src/lib/unp.h##
+#endif## 43 ##src/lib/unp.h##
+#ifdef  HAVE_SYS_SOCKIO_H## 44 ##src/lib/unp.h##
+#include    <sys/sockio.h>## 45 ##src/lib/unp.h##
+#endif## 46 ##src/lib/unp.h##
+
+#ifdef  HAVE_PTHREAD_H## 47 ##src/lib/unp.h##
+#include    <pthread.h>## 48 ##src/lib/unp.h##
+#endif## 49 ##src/lib/unp.h##
+
+/* OSF/1 actually disables recv() and send() in <sys/socket.h> */## 50 ##src/lib/unp.h##
+#ifdef  __osf__## 51 ##src/lib/unp.h##
+#undef  recv## 52 ##src/lib/unp.h##
+#undef  send## 53 ##src/lib/unp.h##
+#define recv(a,b,c,d)   recvfrom(a,b,c,d,0,0)## 54 ##src/lib/unp.h##
+#define send(a,b,c,d)   sendto(a,b,c,d,0,0)## 55 ##src/lib/unp.h##
+#endif## 56 ##src/lib/unp.h##
+
+#ifndef INADDR_NONE## 57 ##src/lib/unp.h##
+/* $$.Ic INADDR_NONE$$ */
+#define INADDR_NONE 0xffffffff  /* should have been in <netinet/in.h> */## 58 ##src/lib/unp.h##
+#endif## 59 ##src/lib/unp.h##
+
+#ifndef SHUT_RD                 /* these three Posix.1g names are quite new */## 60 ##src/lib/unp.h##
+#define SHUT_RD     0           /* shutdown for reading */## 61 ##src/lib/unp.h##
+#define SHUT_WR     1           /* shutdown for writing */## 62 ##src/lib/unp.h##
+#define SHUT_RDWR   2           /* shutdown for reading and writing */## 63 ##src/lib/unp.h##
+/* $$.Ic SHUT_RD$$ */
+/* $$.Ic SHUT_WR$$ */
+/* $$.Ic SHUT_RDWR$$ */
+#endif## 64 ##src/lib/unp.h##
+#ifndef INET_ADDRSTRLEN## 65 ##src/lib/unp.h##
+/* $$.Ic INET_ADDRSTRLEN$$ */
+#define INET_ADDRSTRLEN     16  /* "ddd.ddd.ddd.ddd\0"## 66 ##src/lib/unp.h##
+                                    1234567890123456 */## 67 ##src/lib/unp.h##
+#endif## 68 ##src/lib/unp.h##
+
+/* Define following even if IPv6 not supported, so we can always allocate## 69 ##src/lib/unp.h##
+   an adequately-sized buffer, without #ifdefs in the code. */## 70 ##src/lib/unp.h##
+#ifndef INET6_ADDRSTRLEN## 71 ##src/lib/unp.h##
+/* $$.Ic INET6_ADDRSTRLEN$$ */
+#define INET6_ADDRSTRLEN    46  /* max size of IPv6 address string:## 72 ##src/lib/unp.h##
+                   "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" or## 73 ##src/lib/unp.h##
+                   "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd\0"## 74 ##src/lib/unp.h##
+                    1234567890123456789012345678901234567890123456 */## 75 ##src/lib/unp.h##
+#endif## 76 ##src/lib/unp.h##
+
+/* Define bzero() as a macro if it's not in standard C library. */## 77 ##src/lib/unp.h##
+#ifndef HAVE_BZERO## 78 ##src/lib/unp.h##
+#define bzero(ptr,n)        memset(ptr, 0, n)## 79 ##src/lib/unp.h##
+/* $$.If bzero$$ */
+/* $$.If memset$$ */
+#endif## 80 ##src/lib/unp.h##
+
+/* Older resolvers do not have gethostbyname2() */## 81 ##src/lib/unp.h##
+#ifndef HAVE_GETHOSTBYNAME2## 82 ##src/lib/unp.h##
+#define gethostbyname2(host,family)     gethostbyname((host))## 83 ##src/lib/unp.h##
+#endif## 84 ##src/lib/unp.h##
+
+/* The structure returned by recvfrom_flags() */## 85 ##src/lib/unp.h##
+struct in_pktinfo {## 86 ##src/lib/unp.h##
+    struct in_addr ipi_addr;    /* dst IPv4 address */## 87 ##src/lib/unp.h##
+    int     ipi_ifindex;        /* received interface index */## 88 ##src/lib/unp.h##
+};## 89 ##src/lib/unp.h##
+/* $$.It in_pktinfo$$ */
+/* $$.Ib ipi_addr$$ */
+/* $$.Ib ipi_ifindex$$ */
+
+/* We need the newer CMSG_LEN() and CMSG_SPACE() macros, but few## 90 ##src/lib/unp.h##
+   implementations support them today.  These two macros really need## 91 ##src/lib/unp.h##
+   an ALIGN() macro, but each implementation does this differently. */## 92 ##src/lib/unp.h##
+#ifndef CMSG_LEN## 93 ##src/lib/unp.h##
+/* $$.Ic CMSG_LEN$$ */
+#define CMSG_LEN(size)      (sizeof(struct cmsghdr) + (size))## 94 ##src/lib/unp.h##
+#endif## 95 ##src/lib/unp.h##
+#ifndef CMSG_SPACE## 96 ##src/lib/unp.h##
+/* $$.Ic CMSG_SPACE$$ */
+#define CMSG_SPACE(size)    (sizeof(struct cmsghdr) + (size))## 97 ##src/lib/unp.h##
+#endif## 98 ##src/lib/unp.h##
+
+/* Posix.1g requires the SUN_LEN() macro but not all implementations define## 99 ##src/lib/unp.h##
+   it (yet).  Note that this 4.4BSD macro works regardless whether there is##100 ##src/lib/unp.h##
+   a length field or not. */##101 ##src/lib/unp.h##
+#ifndef SUN_LEN##102 ##src/lib/unp.h##
+/* $$.Im SUN_LEN$$ */
+#define SUN_LEN(su) \##103 ##src/lib/unp.h##
+    (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))##104 ##src/lib/unp.h##
+#endif##105 ##src/lib/unp.h##
+
+/* Posix.1g renames "Unix domain" as "local IPC".##106 ##src/lib/unp.h##
+   But not all systems define AF_LOCAL and PF_LOCAL (yet). */##107 ##src/lib/unp.h##
+#ifndef AF_LOCAL##108 ##src/lib/unp.h##
+#define AF_LOCAL    AF_UNIX##109 ##src/lib/unp.h##
+#endif##110 ##src/lib/unp.h##
+#ifndef PF_LOCAL##111 ##src/lib/unp.h##
+#define PF_LOCAL    PF_UNIX##112 ##src/lib/unp.h##
+#endif##113 ##src/lib/unp.h##
+
+/* Posix.1g requires that an #include of <poll.h> define INFTIM, but many##114 ##src/lib/unp.h##
+   systems still define it in <sys/stropts.h>.  We don't want to include##115 ##src/lib/unp.h##
+   all the streams stuff if it's not needed, so we just define INFTIM here.##116 ##src/lib/unp.h##
+   This is the standard value, but there's no guarantee it is -1. */##117 ##src/lib/unp.h##
+#ifndef INFTIM##118 ##src/lib/unp.h##
+#define INFTIM          (-1)    /* infinite poll timeout */##119 ##src/lib/unp.h##
+/* $$.Ic INFTIM$$ */
+#ifdef  HAVE_POLL_H##120 ##src/lib/unp.h##
+#define INFTIM_UNPH             /* tell unpxti.h we defined it */##121 ##src/lib/unp.h##
+#endif##122 ##src/lib/unp.h##
+#endif##123 ##src/lib/unp.h##
+
+/* Following could be derived from SOMAXCONN in <sys/socket.h>, but many##124 ##src/lib/unp.h##
+   kernels still #define it as 5, while actually supporting many more */##125 ##src/lib/unp.h##
+#define LISTENQ     1024        /* 2nd argument to listen() */##126 ##src/lib/unp.h##
+
+/* Miscellaneous constants */##127 ##src/lib/unp.h##
+#define MAXLINE     4096        /* max text line length */##128 ##src/lib/unp.h##
+#define MAXSOCKADDR  128        /* max socket address structure size */##129 ##src/lib/unp.h##
+#define BUFFSIZE    8192        /* buffer size for reads and writes */##130 ##src/lib/unp.h##
+
+/* Define some port number that can be used for client-servers */##131 ##src/lib/unp.h##
+#define SERV_PORT        9877   /* TCP and UDP client-servers */##132 ##src/lib/unp.h##
+#define SERV_PORT_STR   "9877"  /* TCP and UDP client-servers */##133 ##src/lib/unp.h##
+#define UNIXSTR_PATH    "/tmp/unix.str"     /* Unix domain stream cli-serv */##134 ##src/lib/unp.h##
+#define UNIXDG_PATH     "/tmp/unix.dg"  /* Unix domain datagram cli-serv */##135 ##src/lib/unp.h##
+/* $$.ix [LISTENQ]~constant,~definition~of$$ */
+/* $$.ix [MAXLINE]~constant,~definition~of$$ */
+/* $$.ix [MAXSOCKADDR]~constant,~definition~of$$ */
+/* $$.ix [BUFFSIZE]~constant,~definition~of$$ */
+/* $$.ix [SERV_PORT]~constant,~definition~of$$ */
+/* $$.ix [UNIXSTR_PATH]~constant,~definition~of$$ */
+/* $$.ix [UNIXDG_PATH]~constant,~definition~of$$ */
+
+/* Following shortens all the type casts of pointer arguments */##136 ##src/lib/unp.h##
+#define SA  struct sockaddr##137 ##src/lib/unp.h##
+
+#define FILE_MODE   (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)##138 ##src/lib/unp.h##
+                    /* default file access permissions for new files */##139 ##src/lib/unp.h##
+#define DIR_MODE    (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)##140 ##src/lib/unp.h##
+                    /* default permissions for new directories */##141 ##src/lib/unp.h##
+
+typedef void Sigfunc (int);     /* for signal handlers */##142 ##src/lib/unp.h##
+
+#define min(a,b)    ((a) < (b) ? (a) : (b))##143 ##src/lib/unp.h##
+#define max(a,b)    ((a) > (b) ? (a) : (b))##144 ##src/lib/unp.h##
+
+#ifndef HAVE_ADDRINFO_STRUCT##145 ##src/lib/unp.h##
+#include    "../lib/addrinfo.h"##146 ##src/lib/unp.h##
+#endif##147 ##src/lib/unp.h##
+
+#ifndef HAVE_IF_NAMEINDEX_STRUCT##148 ##src/lib/unp.h##
+struct if_nameindex {##149 ##src/lib/unp.h##
+    unsigned int if_index;      /* 1, 2, ... */##150 ##src/lib/unp.h##
+    char   *if_name;            /* null terminated name: "le0", ... */##151 ##src/lib/unp.h##
+};##152 ##src/lib/unp.h##
+/* $$.It if_nameindex$$ */
+/* $$.Ib if_index$$ */
+/* $$.Ib if_name$$ */
+#endif##153 ##src/lib/unp.h##
+
+#ifndef HAVE_TIMESPEC_STRUCT##154 ##src/lib/unp.h##
+struct timespec {##155 ##src/lib/unp.h##
+    time_t  tv_sec;             /* seconds */##156 ##src/lib/unp.h##
+    long    tv_nsec;            /* and nanoseconds */##157 ##src/lib/unp.h##
+};##158 ##src/lib/unp.h##
+/* $$.It timespec$$ */
+/* $$.Ib tv_sec$$ */
+/* $$.Ib tv_nsec$$ */
+#endif##159 ##src/lib/unp.h##
+/* end unph */
+
+            /* prototypes for our own library functions */##160 ##src/lib/unp.h##
+int     connect_nonb(int, const SA *, socklen_t, int);##161 ##src/lib/unp.h##
+int     connect_timeo(int, const SA *, socklen_t, int);##162 ##src/lib/unp.h##
+void    daemon_init(const char *, int);##163 ##src/lib/unp.h##
+void    daemon_inetd(const char *, int);##164 ##src/lib/unp.h##
+void    dg_cli(FILE *, int, const SA *, socklen_t);##165 ##src/lib/unp.h##
+void    dg_echo(int, SA *, socklen_t);##166 ##src/lib/unp.h##
+char   *gf_time(void);##167 ##src/lib/unp.h##
+void    heartbeat_cli(int, int, int);##168 ##src/lib/unp.h##
+void    heartbeat_serv(int, int, int);##169 ##src/lib/unp.h##
+struct addrinfo *host_serv(const char *, const char *, int, int);##170 ##src/lib/unp.h##
+int     inet_srcrt_add(char *, int);##171 ##src/lib/unp.h##
+u_char *inet_srcrt_init(void);##172 ##src/lib/unp.h##
+void    inet_srcrt_print(u_char *, int);##173 ##src/lib/unp.h##
+char  **my_addrs(int *);##174 ##src/lib/unp.h##
+int     readable_timeo(int, int);##175 ##src/lib/unp.h##
+ssize_t readline(int, void *, size_t);##176 ##src/lib/unp.h##
+ssize_t readn(int, void *, size_t);##177 ##src/lib/unp.h##
+ssize_t read_fd(int, void *, size_t, int *);##178 ##src/lib/unp.h##
+ssize_t recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *,##179 ##src/lib/unp.h##
+                       struct in_pktinfo *);##180 ##src/lib/unp.h##
+Sigfunc *signal_intr(int, Sigfunc *);##181 ##src/lib/unp.h##
+int     sock_bind_wild(int, int);##182 ##src/lib/unp.h##
+int     sock_cmp_addr(const SA *, const SA *, socklen_t);##183 ##src/lib/unp.h##
+int     sock_cmp_port(const SA *, const SA *, socklen_t);##184 ##src/lib/unp.h##
+int     sock_get_port(const SA *, socklen_t);##185 ##src/lib/unp.h##
+void    sock_set_addr(SA *, socklen_t, const void *);##186 ##src/lib/unp.h##
+void    sock_set_port(SA *, socklen_t, int);##187 ##src/lib/unp.h##
+void    sock_set_wild(SA *, socklen_t);##188 ##src/lib/unp.h##
+char   *sock_ntop(const SA *, socklen_t);##189 ##src/lib/unp.h##
+char   *sock_ntop_host(const SA *, socklen_t);##190 ##src/lib/unp.h##
+int     sockfd_to_family(int);##191 ##src/lib/unp.h##
+void    str_echo(int);##192 ##src/lib/unp.h##
+void    str_cli(FILE *, int);##193 ##src/lib/unp.h##
+int     tcp_connect(const char *, const char *);##194 ##src/lib/unp.h##
+int     tcp_listen(const char *, const char *, socklen_t *);##195 ##src/lib/unp.h##
+void    tv_sub(struct timeval *, struct timeval *);##196 ##src/lib/unp.h##
+int     udp_client(const char *, const char *, void **, socklen_t *);##197 ##src/lib/unp.h##
+int     udp_connect(const char *, const char *);##198 ##src/lib/unp.h##
+int     udp_server(const char *, const char *, socklen_t *);##199 ##src/lib/unp.h##
+int     writable_timeo(int, int);##200 ##src/lib/unp.h##
+ssize_t writen(int, const void *, size_t);##201 ##src/lib/unp.h##
+ssize_t write_fd(int, void *, size_t, int);##202 ##src/lib/unp.h##
+
+#ifdef  MCAST##203 ##src/lib/unp.h##
+int     mcast_leave(int, const SA *, socklen_t);##204 ##src/lib/unp.h##
+int     mcast_join(int, const SA *, socklen_t, const char *, u_int);##205 ##src/lib/unp.h##
+int     mcast_get_if(int);##206 ##src/lib/unp.h##
+int     mcast_get_loop(int);##207 ##src/lib/unp.h##
+int     mcast_get_ttl(int);##208 ##src/lib/unp.h##
+int     mcast_set_if(int, const char *, u_int);##209 ##src/lib/unp.h##
+int     mcast_set_loop(int, int);##210 ##src/lib/unp.h##
+int     mcast_set_ttl(int, int);##211 ##src/lib/unp.h##
+
+void    Mcast_leave(int, const SA *, socklen_t);##212 ##src/lib/unp.h##
+void    Mcast_join(int, const SA *, socklen_t, const char *, u_int);##213 ##src/lib/unp.h##
+int     Mcast_get_if(int);##214 ##src/lib/unp.h##
+int     Mcast_get_loop(int);##215 ##src/lib/unp.h##
+int     Mcast_get_ttl(int);##216 ##src/lib/unp.h##
+void    Mcast_set_if(int, const char *, u_int);##217 ##src/lib/unp.h##
+void    Mcast_set_loop(int, int);##218 ##src/lib/unp.h##
+void    Mcast_set_ttl(int, int);##219 ##src/lib/unp.h##
+#endif##220 ##src/lib/unp.h##
+
+unsigned short in_cksum(unsigned short *, int);##221 ##src/lib/unp.h##
+
+#ifndef HAVE_GETADDRINFO_PROTO##222 ##src/lib/unp.h##
+int     getaddrinfo(const char *, const char *, const struct addrinfo *,##223 ##src/lib/unp.h##
+                    struct addrinfo **);##224 ##src/lib/unp.h##
+void    freeaddrinfo(struct addrinfo *);##225 ##src/lib/unp.h##
+char   *gai_strerror(int);##226 ##src/lib/unp.h##
+#endif##227 ##src/lib/unp.h##
+
+#ifndef HAVE_GETNAMEINFO_PROTO##228 ##src/lib/unp.h##
+int     getnameinfo(const SA *, socklen_t, char *, size_t, char *, size_t, int);##229 ##src/lib/unp.h##
+#endif##230 ##src/lib/unp.h##
+
+#ifndef HAVE_GETHOSTNAME_PROTO##231 ##src/lib/unp.h##
+int     gethostname(char *, int);##232 ##src/lib/unp.h##
+#endif##233 ##src/lib/unp.h##
+
+#ifndef HAVE_HSTRERROR_PROTO##234 ##src/lib/unp.h##
+const char *hstrerror(int);##235 ##src/lib/unp.h##
+#endif##236 ##src/lib/unp.h##
+
+#ifndef HAVE_IF_NAMETOINDEX_PROTO##237 ##src/lib/unp.h##
+unsigned int if_nametoindex(const char *);##238 ##src/lib/unp.h##
+char   *if_indextoname(unsigned int, char *);##239 ##src/lib/unp.h##
+void    if_freenameindex(struct if_nameindex *);##240 ##src/lib/unp.h##
+struct if_nameindex *if_nameindex(void);##241 ##src/lib/unp.h##
+#endif##242 ##src/lib/unp.h##
+
+#ifndef HAVE_INET_PTON_PROTO##243 ##src/lib/unp.h##
+int     inet_pton(int, const char *, void *);##244 ##src/lib/unp.h##
+const char *inet_ntop(int, const void *, char *, size_t);##245 ##src/lib/unp.h##
+#endif##246 ##src/lib/unp.h##
+
+#ifndef HAVE_INET_ATON_PROTO##247 ##src/lib/unp.h##
+int     inet_aton(const char *, struct in_addr *);##248 ##src/lib/unp.h##
+#endif##249 ##src/lib/unp.h##
+
+#ifndef HAVE_ISFDTYPE_PROTO##250 ##src/lib/unp.h##
+int     isfdtype(int, int);##251 ##src/lib/unp.h##
+#endif##252 ##src/lib/unp.h##
+
+#ifndef HAVE_PSELECT_PROTO##253 ##src/lib/unp.h##
+int     pselect(int, fd_set *, fd_set *, fd_set *,##254 ##src/lib/unp.h##
+                const struct timespec *, const sigset_t *);##255 ##src/lib/unp.h##
+#endif##256 ##src/lib/unp.h##
+
+#ifndef HAVE_SOCKATMARK_PROTO##257 ##src/lib/unp.h##
+int     sockatmark(int);##258 ##src/lib/unp.h##
+#endif##259 ##src/lib/unp.h##
+
+#ifndef HAVE_SNPRINTF_PROTO##260 ##src/lib/unp.h##
+int     snprintf(char *, size_t, const char *,...);##261 ##src/lib/unp.h##
+#endif##262 ##src/lib/unp.h##
+
+            /* prototypes for our own library wrapper functions */##263 ##src/lib/unp.h##
+void    Connect_timeo(int, const SA *, socklen_t, int);##264 ##src/lib/unp.h##
+struct addrinfo *Host_serv(const char *, const char *, int, int);##265 ##src/lib/unp.h##
+const char *Inet_ntop(int, const void *, char *, size_t);##266 ##src/lib/unp.h##
+void    Inet_pton(int, const char *, void *);##267 ##src/lib/unp.h##
+char   *If_indextoname(unsigned int, char *);##268 ##src/lib/unp.h##
+unsigned int If_nametoindex(const char *);##269 ##src/lib/unp.h##
+struct if_nameindex *If_nameindex(void);##270 ##src/lib/unp.h##
+char  **My_addrs(int *);##271 ##src/lib/unp.h##
+ssize_t Read_fd(int, void *, size_t, int *);##272 ##src/lib/unp.h##
+int     Readable_timeo(int, int);##273 ##src/lib/unp.h##
+ssize_t Recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *,##274 ##src/lib/unp.h##
+                       struct in_pktinfo *);##275 ##src/lib/unp.h##
+Sigfunc *Signal(int, Sigfunc *);##276 ##src/lib/unp.h##
+Sigfunc *Signal_intr(int, Sigfunc *);##277 ##src/lib/unp.h##
+int     Sock_bind_wild(int, int);##278 ##src/lib/unp.h##
+char   *Sock_ntop(const SA *, socklen_t);##279 ##src/lib/unp.h##
+char   *Sock_ntop_host(const SA *, socklen_t);##280 ##src/lib/unp.h##
+int     Sockfd_to_family(int);##281 ##src/lib/unp.h##
+int     Tcp_connect(const char *, const char *);##282 ##src/lib/unp.h##
+int     Tcp_listen(const char *, const char *, socklen_t *);##283 ##src/lib/unp.h##
+int     Udp_client(const char *, const char *, void **, socklen_t *);##284 ##src/lib/unp.h##
+int     Udp_connect(const char *, const char *);##285 ##src/lib/unp.h##
+int     Udp_server(const char *, const char *, socklen_t *);##286 ##src/lib/unp.h##
+ssize_t Write_fd(int, void *, size_t, int);##287 ##src/lib/unp.h##
+int     Writable_timeo(int, int);##288 ##src/lib/unp.h##
+
+            /* prototypes for our Unix wrapper functions: see {Sec errors} */##289 ##src/lib/unp.h##
+void   *Calloc(size_t, size_t);##290 ##src/lib/unp.h##
+void    Close(int);##291 ##src/lib/unp.h##
+void    Dup2(int, int);##292 ##src/lib/unp.h##
+int     Fcntl(int, int, int);##293 ##src/lib/unp.h##
+void    Gettimeofday(struct timeval *, void *);##294 ##src/lib/unp.h##
+int     Ioctl(int, int, void *);##295 ##src/lib/unp.h##
+pid_t   Fork(void);##296 ##src/lib/unp.h##
+void   *Malloc(size_t);##297 ##src/lib/unp.h##
+void    Mktemp(char *);##298 ##src/lib/unp.h##
+void   *Mmap(void *, size_t, int, int, int, off_t);##299 ##src/lib/unp.h##
+int     Open(const char *, int, mode_t);##300 ##src/lib/unp.h##
+void    Pipe(int *fds);##301 ##src/lib/unp.h##
+ssize_t Read(int, void *, size_t);##302 ##src/lib/unp.h##
+void    Sigaddset(sigset_t *, int);##303 ##src/lib/unp.h##
+void    Sigdelset(sigset_t *, int);##304 ##src/lib/unp.h##
+void    Sigemptyset(sigset_t *);##305 ##src/lib/unp.h##
+void    Sigfillset(sigset_t *);##306 ##src/lib/unp.h##
+int     Sigismember(const sigset_t *, int);##307 ##src/lib/unp.h##
+void    Sigpending(sigset_t *);##308 ##src/lib/unp.h##
+void    Sigprocmask(int, const sigset_t *, sigset_t *);##309 ##src/lib/unp.h##
+char   *Strdup(const char *);##310 ##src/lib/unp.h##
+long    Sysconf(int);##311 ##src/lib/unp.h##
+void    Sysctl(int *, u_int, void *, size_t *, void *, size_t);##312 ##src/lib/unp.h##
+void    Unlink(const char *);##313 ##src/lib/unp.h##
+pid_t   Wait(int *);##314 ##src/lib/unp.h##
+pid_t   Waitpid(pid_t, int *, int);##315 ##src/lib/unp.h##
+void    Write(int, void *, size_t);##316 ##src/lib/unp.h##
+
+            /* prototypes for our stdio wrapper functions: see {Sec errors} */##317 ##src/lib/unp.h##
+void    Fclose(FILE *);##318 ##src/lib/unp.h##
+FILE   *Fdopen(int, const char *);##319 ##src/lib/unp.h##
+char   *Fgets(char *, int, FILE *);##320 ##src/lib/unp.h##
+FILE   *Fopen(const char *, const char *);##321 ##src/lib/unp.h##
+void    Fputs(const char *, FILE *);##322 ##src/lib/unp.h##
+
+            /* prototypes for our socket wrapper functions: see {Sec errors} */##323 ##src/lib/unp.h##
+int     Accept(int, SA *, socklen_t *);##324 ##src/lib/unp.h##
+void    Bind(int, const SA *, socklen_t);##325 ##src/lib/unp.h##
+void    Connect(int, const SA *, socklen_t);##326 ##src/lib/unp.h##
+void    Getpeername(int, SA *, socklen_t *);##327 ##src/lib/unp.h##
+void    Getsockname(int, SA *, socklen_t *);##328 ##src/lib/unp.h##
+void    Getsockopt(int, int, int, void *, socklen_t *);##329 ##src/lib/unp.h##
+int     Isfdtype(int, int);##330 ##src/lib/unp.h##
+void    Listen(int, int);##331 ##src/lib/unp.h##
+#ifdef  HAVE_POLL##332 ##src/lib/unp.h##
+int     Poll(struct pollfd *, unsigned long, int);##333 ##src/lib/unp.h##
+#endif##334 ##src/lib/unp.h##
+ssize_t Readline(int, void *, size_t);##335 ##src/lib/unp.h##
+ssize_t Readn(int, void *, size_t);##336 ##src/lib/unp.h##
+ssize_t Recv(int, void *, size_t, int);##337 ##src/lib/unp.h##
+ssize_t Recvfrom(int, void *, size_t, int, SA *, socklen_t *);##338 ##src/lib/unp.h##
+ssize_t Recvmsg(int, struct msghdr *, int);##339 ##src/lib/unp.h##
+int     Select(int, fd_set *, fd_set *, fd_set *, struct timeval *);##340 ##src/lib/unp.h##
+void    Send(int, const void *, size_t, int);##341 ##src/lib/unp.h##
+void    Sendto(int, const void *, size_t, int, const SA *, socklen_t);##342 ##src/lib/unp.h##
+void    Sendmsg(int, const struct msghdr *, int);##343 ##src/lib/unp.h##
+void    Setsockopt(int, int, int, const void *, socklen_t);##344 ##src/lib/unp.h##
+void    Shutdown(int, int);##345 ##src/lib/unp.h##
+int     Sockatmark(int);##346 ##src/lib/unp.h##
+int     Socket(int, int, int);##347 ##src/lib/unp.h##
+void    Socketpair(int, int, int, int *);##348 ##src/lib/unp.h##
+void    Writen(int, void *, size_t);##349 ##src/lib/unp.h##
+
+void    err_dump(const char *,...);##350 ##src/lib/unp.h##
+void    err_msg(const char *,...);##351 ##src/lib/unp.h##
+void    err_quit(const char *,...);##352 ##src/lib/unp.h##
+void    err_ret(const char *,...);##353 ##src/lib/unp.h##
+void    err_sys(const char *,...);##354 ##src/lib/unp.h##
+
+#endif  /* __unp_h */##355 ##src/lib/unp.h##
diff --git a/lib/unpifi.h b/lib/unpifi.h
new file mode 100644 (file)
index 0000000..ca10965
--- /dev/null
@@ -0,0 +1,34 @@
+/* Our own header for the programs that need interface configuration info.
+   Include this file, instead of "unp.h". */
+
+#ifndef        __unp_ifi_h
+#define        __unp_ifi_h
+
+#include       "unp.h"
+#include       <net/if.h>
+
+#define        IFI_NAME        16                      /* same as IFNAMSIZ in <net/if.h> */
+#define        IFI_HADDR        8                      /* allow for 64-bit EUI-64 in future */
+
+struct ifi_info {
+  char    ifi_name[IFI_NAME];  /* interface name, null-terminated */
+  short   ifi_index;                   /* interface index */
+  short   ifi_mtu;                             /* interface MTU */
+  u_char  ifi_haddr[IFI_HADDR];        /* hardware address */
+  u_short ifi_hlen;                            /* # bytes in hardware address: 0, 6, 8 */
+  short   ifi_flags;                   /* IFF_xxx constants from <net/if.h> */
+  short   ifi_myflags;                 /* our own IFI_xxx flags */
+  struct sockaddr  *ifi_addr;  /* primary address */
+  struct sockaddr  *ifi_brdaddr;/* broadcast address */
+  struct sockaddr  *ifi_dstaddr;/* destination address */
+  struct ifi_info  *ifi_next;  /* next of these structures */
+};
+
+#define        IFI_ALIAS       1                       /* ifi_addr is an alias */
+
+                                       /* function prototypes */
+struct ifi_info        *get_ifi_info(int, int);
+struct ifi_info        *Get_ifi_info(int, int);
+void                    free_ifi_info(struct ifi_info *);
+
+#endif /* __unp_ifi_h */
diff --git a/lib/unprtt.h b/lib/unprtt.h
new file mode 100644 (file)
index 0000000..a96b94f
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef        __unp_rtt_h
+#define        __unp_rtt_h
+
+#include       "unp.h"
+
+struct rtt_info {
+  float                rtt_rtt;        /* most recent measured RTT, in seconds */
+  float                rtt_srtt;       /* smoothed RTT estimator, in seconds */
+  float                rtt_rttvar;     /* smoothed mean deviation, in seconds */
+  float                rtt_rto;        /* current RTO to use, in seconds */
+  int          rtt_nrexmt;     /* # times retransmitted: 0, 1, 2, ... */
+  uint32_t     rtt_base;       /* # sec since 1/1/1970 at start */
+};
+
+#define        RTT_RXTMIN      2       /* min retransmit timeout value, in seconds */
+#define        RTT_RXTMAX     60       /* max retransmit timeout value, in seconds */
+#define        RTT_MAXNREXMT   3       /* max # times to retransmit */
+
+                               /* function prototypes */
+void    rtt_debug(struct rtt_info *);
+void    rtt_init(struct rtt_info *);
+void    rtt_newpack(struct rtt_info *);
+int             rtt_start(struct rtt_info *);
+void    rtt_stop(struct rtt_info *, uint32_t);
+int             rtt_timeout(struct rtt_info *);
+uint32_t rtt_ts(struct rtt_info *);
+
+extern int     rtt_d_flag;     /* can be set to nonzero for addl info */
+
+#endif /* __unp_rtt_h */
diff --git a/lib/unprtt.lh b/lib/unprtt.lh
new file mode 100644 (file)
index 0000000..47d5c74
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef __unp_rtt_h##  1 ##src/lib/unprtt.h##
+#define __unp_rtt_h##  2 ##src/lib/unprtt.h##
+
+#include    "unp.h"##  3 ##src/lib/unprtt.h##
+
+struct rtt_info {##  4 ##src/lib/unprtt.h##
+    float   rtt_rtt;            /* most recent measured RTT, seconds */##  5 ##src/lib/unprtt.h##
+    float   rtt_srtt;           /* smoothed RTT estimator, seconds */##  6 ##src/lib/unprtt.h##
+    float   rtt_rttvar;         /* smoothed mean deviation, seconds */##  7 ##src/lib/unprtt.h##
+    float   rtt_rto;            /* current RTO to use, seconds */##  8 ##src/lib/unprtt.h##
+    int     rtt_nrexmt;         /* #times retransmitted: 0, 1, 2, ... */##  9 ##src/lib/unprtt.h##
+    uint32_t rtt_base;          /* #sec since 1/1/1970 at start */## 10 ##src/lib/unprtt.h##
+};## 11 ##src/lib/unprtt.h##
+
+#define RTT_RXTMIN      2       /* min retransmit timeout value, seconds */## 12 ##src/lib/unprtt.h##
+#define RTT_RXTMAX     60       /* max retransmit timeout value, seconds */## 13 ##src/lib/unprtt.h##
+#define RTT_MAXNREXMT   3       /* max #times to retransmit */## 14 ##src/lib/unprtt.h##
+
+                /* function prototypes */## 15 ##src/lib/unprtt.h##
+void    rtt_debug(struct rtt_info *);## 16 ##src/lib/unprtt.h##
+void    rtt_init(struct rtt_info *);## 17 ##src/lib/unprtt.h##
+void    rtt_newpack(struct rtt_info *);## 18 ##src/lib/unprtt.h##
+int     rtt_start(struct rtt_info *);## 19 ##src/lib/unprtt.h##
+void    rtt_stop(struct rtt_info *, uint32_t);## 20 ##src/lib/unprtt.h##
+int     rtt_timeout(struct rtt_info *);## 21 ##src/lib/unprtt.h##
+uint32_t rtt_ts(struct rtt_info *);## 22 ##src/lib/unprtt.h##
+
+extern int rtt_d_flag;          /* can be set nonzero for addl info */## 23 ##src/lib/unprtt.h##
+
+#endif  /* __unp_rtt_h */## 24 ##src/lib/unprtt.h##
diff --git a/lib/unpthread.h b/lib/unpthread.h
new file mode 100644 (file)
index 0000000..e79b779
--- /dev/null
@@ -0,0 +1,31 @@
+/* Our own header for the programs that use threads.
+   Include this file, instead of "unp.h". */
+
+#ifndef        __unp_pthread_h
+#define        __unp_pthread_h
+
+#include       "unp.h"
+
+void   Pthread_create(pthread_t *, const pthread_attr_t *,
+                                          void * (*)(void *), void *);
+void   Pthread_join(pthread_t, void **);
+void   Pthread_detach(pthread_t);
+void   Pthread_kill(pthread_t, int);
+
+void   Pthread_mutexattr_init(pthread_mutexattr_t *);
+void   Pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
+void   Pthread_mutex_init(pthread_mutex_t *, pthread_mutexattr_t *);
+void   Pthread_mutex_lock(pthread_mutex_t *);
+void   Pthread_mutex_unlock(pthread_mutex_t *);
+
+void   Pthread_cond_broadcast(pthread_cond_t *);
+void   Pthread_cond_signal(pthread_cond_t *);
+void   Pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
+void   Pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *,
+                                                          const struct timespec *);
+
+void   Pthread_key_create(pthread_key_t *, void (*)(void *));
+void   Pthread_setspecific(pthread_key_t, const void *);
+void   Pthread_once(pthread_once_t *, void (*)(void));
+
+#endif /* __unp_pthread_h */
diff --git a/lib/wraplib.c b/lib/wraplib.c
new file mode 100644 (file)
index 0000000..c73cbb8
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Wrapper functions for our own library functions.
+ * Most are included in the source file for the function itself.
+ */
+
+#include       "unp.h"
+
+const char *
+Inet_ntop(int family, const void *addrptr, char *strptr, size_t len)
+{
+       const char      *ptr;
+
+       if (strptr == NULL)             /* check for old code */
+               err_quit("NULL 3rd argument to inet_ntop");
+       if ( (ptr = inet_ntop(family, addrptr, strptr, len)) == NULL)
+               err_sys("inet_ntop error");             /* sets errno */
+       return(ptr);
+}
+
+void
+Inet_pton(int family, const char *strptr, void *addrptr)
+{
+       int             n;
+
+       if ( (n = inet_pton(family, strptr, addrptr)) < 0)
+               err_sys("inet_pton error for %s", strptr);      /* errno set */
+       else if (n == 0)
+               err_quit("inet_pton error for %s", strptr);     /* errno not set */
+
+       /* nothing to return */
+}
diff --git a/lib/wrappthread.c b/lib/wrappthread.c
new file mode 100644 (file)
index 0000000..c307cf3
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * pthreads wrapper functions.
+ */
+
+#include       "unp.h"
+#include       "unpthread.h"
+
+void
+Pthread_create(pthread_t *tid, const pthread_attr_t *attr,
+                          void * (*func)(void *), void *arg)
+{
+       int             n;
+
+       if ( (n = pthread_create(tid, attr, func, arg)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_create error");
+}
+
+void
+Pthread_join(pthread_t tid, void **status)
+{
+       int             n;
+
+       if ( (n = pthread_join(tid, status)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_join error");
+}
+
+void
+Pthread_detach(pthread_t tid)
+{
+       int             n;
+
+       if ( (n = pthread_detach(tid)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_detach error");
+}
+
+void
+Pthread_kill(pthread_t tid, int signo)
+{
+       int             n;
+
+       if ( (n = pthread_kill(tid, signo)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_kill error");
+}
+
+void
+Pthread_mutexattr_init(pthread_mutexattr_t *attr)
+{
+       int             n;
+
+       if ( (n = pthread_mutexattr_init(attr)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_mutexattr_init error");
+}
+
+#ifdef _POSIX_THREAD_PROCESS_SHARED
+void
+Pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int flag)
+{
+       int             n;
+
+       if ( (n = pthread_mutexattr_setpshared(attr, flag)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_mutexattr_setpshared error");
+}
+#endif
+
+void
+Pthread_mutex_init(pthread_mutex_t *mptr, pthread_mutexattr_t *attr)
+{
+       int             n;
+
+       if ( (n = pthread_mutex_init(mptr, attr)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_mutex_init error");
+}
+
+/* include Pthread_mutex_lock */
+void
+Pthread_mutex_lock(pthread_mutex_t *mptr)
+{
+       int             n;
+
+       if ( (n = pthread_mutex_lock(mptr)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_mutex_lock error");
+}
+/* end Pthread_mutex_lock */
+
+void
+Pthread_mutex_unlock(pthread_mutex_t *mptr)
+{
+       int             n;
+
+       if ( (n = pthread_mutex_unlock(mptr)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_mutex_unlock error");
+}
+
+void
+Pthread_cond_broadcast(pthread_cond_t *cptr)
+{
+       int             n;
+
+       if ( (n = pthread_cond_broadcast(cptr)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_cond_broadcast error");
+}
+
+void
+Pthread_cond_signal(pthread_cond_t *cptr)
+{
+       int             n;
+
+       if ( (n = pthread_cond_signal(cptr)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_cond_signal error");
+}
+
+void
+Pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr)
+{
+       int             n;
+
+       if ( (n = pthread_cond_wait(cptr, mptr)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_cond_wait error");
+}
+
+void
+Pthread_cond_timedwait(pthread_cond_t *cptr, pthread_mutex_t *mptr,
+                                          const struct timespec *tsptr)
+{
+       int             n;
+
+       if ( (n = pthread_cond_timedwait(cptr, mptr, tsptr)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_cond_timedwait error");
+}
+
+void
+Pthread_once(pthread_once_t *ptr, void (*func)(void))
+{
+       int             n;
+
+       if ( (n = pthread_once(ptr, func)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_once error");
+}
+
+void
+Pthread_key_create(pthread_key_t *key, void (*func)(void *))
+{
+       int             n;
+
+       if ( (n = pthread_key_create(key, func)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_key_create error");
+}
+
+void
+Pthread_setspecific(pthread_key_t key, const void *value)
+{
+       int             n;
+
+       if ( (n = pthread_setspecific(key, value)) == 0)
+               return;
+       errno = n;
+       err_sys("pthread_setspecific error");
+}
diff --git a/lib/wrappthread.lc b/lib/wrappthread.lc
new file mode 100644 (file)
index 0000000..16a6f8a
--- /dev/null
@@ -0,0 +1,188 @@
+/*##  1 ##src/lib/wrappthread.c##
+ * pthreads wrapper functions.##  2 ##src/lib/wrappthread.c##
+ */##  3 ##src/lib/wrappthread.c##
+
+#include    "unp.h"##  4 ##src/lib/wrappthread.c##
+#include    "unpthread.h"##  5 ##src/lib/wrappthread.c##
+
+void##  6 ##src/lib/wrappthread.c##
+Pthread_create(pthread_t * tid, const pthread_attr_t * attr,##  7 ##src/lib/wrappthread.c##
+               void *(*func) (void *), void *arg)##  8 ##src/lib/wrappthread.c##
+{##  9 ##src/lib/wrappthread.c##
+    int     n;## 10 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_create(tid, attr, func, arg)) == 0)## 11 ##src/lib/wrappthread.c##
+        return;## 12 ##src/lib/wrappthread.c##
+    errno = n;## 13 ##src/lib/wrappthread.c##
+    err_sys("pthread_create error");## 14 ##src/lib/wrappthread.c##
+}## 15 ##src/lib/wrappthread.c##
+
+void## 16 ##src/lib/wrappthread.c##
+Pthread_join(pthread_t tid, void **status)## 17 ##src/lib/wrappthread.c##
+{## 18 ##src/lib/wrappthread.c##
+    int     n;## 19 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_join(tid, status)) == 0)## 20 ##src/lib/wrappthread.c##
+        return;## 21 ##src/lib/wrappthread.c##
+    errno = n;## 22 ##src/lib/wrappthread.c##
+    err_sys("pthread_join error");## 23 ##src/lib/wrappthread.c##
+}## 24 ##src/lib/wrappthread.c##
+
+void## 25 ##src/lib/wrappthread.c##
+Pthread_detach(pthread_t tid)## 26 ##src/lib/wrappthread.c##
+{## 27 ##src/lib/wrappthread.c##
+    int     n;## 28 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_detach(tid)) == 0)## 29 ##src/lib/wrappthread.c##
+        return;## 30 ##src/lib/wrappthread.c##
+    errno = n;## 31 ##src/lib/wrappthread.c##
+    err_sys("pthread_detach error");## 32 ##src/lib/wrappthread.c##
+}## 33 ##src/lib/wrappthread.c##
+
+void## 34 ##src/lib/wrappthread.c##
+Pthread_kill(pthread_t tid, int signo)## 35 ##src/lib/wrappthread.c##
+{## 36 ##src/lib/wrappthread.c##
+    int     n;## 37 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_kill(tid, signo)) == 0)## 38 ##src/lib/wrappthread.c##
+        return;## 39 ##src/lib/wrappthread.c##
+    errno = n;## 40 ##src/lib/wrappthread.c##
+    err_sys("pthread_kill error");## 41 ##src/lib/wrappthread.c##
+}## 42 ##src/lib/wrappthread.c##
+
+void## 43 ##src/lib/wrappthread.c##
+Pthread_mutexattr_init(pthread_mutexattr_t * attr)## 44 ##src/lib/wrappthread.c##
+{## 45 ##src/lib/wrappthread.c##
+    int     n;## 46 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_mutexattr_init(attr)) == 0)## 47 ##src/lib/wrappthread.c##
+        return;## 48 ##src/lib/wrappthread.c##
+    errno = n;## 49 ##src/lib/wrappthread.c##
+    err_sys("pthread_mutexattr_init error");## 50 ##src/lib/wrappthread.c##
+}## 51 ##src/lib/wrappthread.c##
+
+#ifdef  _POSIX_THREAD_PROCESS_SHARED## 52 ##src/lib/wrappthread.c##
+void## 53 ##src/lib/wrappthread.c##
+Pthread_mutexattr_setpshared(pthread_mutexattr_t * attr, int flag)## 54 ##src/lib/wrappthread.c##
+{## 55 ##src/lib/wrappthread.c##
+    int     n;## 56 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_mutexattr_setpshared(attr, flag)) == 0)## 57 ##src/lib/wrappthread.c##
+        return;## 58 ##src/lib/wrappthread.c##
+    errno = n;## 59 ##src/lib/wrappthread.c##
+    err_sys("pthread_mutexattr_setpshared error");## 60 ##src/lib/wrappthread.c##
+}## 61 ##src/lib/wrappthread.c##
+#endif## 62 ##src/lib/wrappthread.c##
+
+void## 63 ##src/lib/wrappthread.c##
+Pthread_mutex_init(pthread_mutex_t *mptr, pthread_mutexattr_t * attr)## 64 ##src/lib/wrappthread.c##
+{## 65 ##src/lib/wrappthread.c##
+    int     n;## 66 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_mutex_init(mptr, attr)) == 0)## 67 ##src/lib/wrappthread.c##
+        return;## 68 ##src/lib/wrappthread.c##
+    errno = n;## 69 ##src/lib/wrappthread.c##
+    err_sys("pthread_mutex_init error");## 70 ##src/lib/wrappthread.c##
+}## 71 ##src/lib/wrappthread.c##
+
+/* include Pthread_mutex_lock */
+void## 72 ##src/lib/wrappthread.c##
+Pthread_mutex_lock(pthread_mutex_t *mptr)## 73 ##src/lib/wrappthread.c##
+{## 74 ##src/lib/wrappthread.c##
+    int     n;## 75 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_mutex_lock(mptr)) == 0)## 76 ##src/lib/wrappthread.c##
+        return;## 77 ##src/lib/wrappthread.c##
+    errno = n;## 78 ##src/lib/wrappthread.c##
+    err_sys("pthread_mutex_lock error");## 79 ##src/lib/wrappthread.c##
+}## 80 ##src/lib/wrappthread.c##
+/* end Pthread_mutex_lock */
+
+void## 81 ##src/lib/wrappthread.c##
+Pthread_mutex_unlock(pthread_mutex_t *mptr)## 82 ##src/lib/wrappthread.c##
+{## 83 ##src/lib/wrappthread.c##
+    int     n;## 84 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_mutex_unlock(mptr)) == 0)## 85 ##src/lib/wrappthread.c##
+        return;## 86 ##src/lib/wrappthread.c##
+    errno = n;## 87 ##src/lib/wrappthread.c##
+    err_sys("pthread_mutex_unlock error");## 88 ##src/lib/wrappthread.c##
+}## 89 ##src/lib/wrappthread.c##
+
+void## 90 ##src/lib/wrappthread.c##
+Pthread_cond_broadcast(pthread_cond_t *cptr)## 91 ##src/lib/wrappthread.c##
+{## 92 ##src/lib/wrappthread.c##
+    int     n;## 93 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_cond_broadcast(cptr)) == 0)## 94 ##src/lib/wrappthread.c##
+        return;## 95 ##src/lib/wrappthread.c##
+    errno = n;## 96 ##src/lib/wrappthread.c##
+    err_sys("pthread_cond_broadcast error");## 97 ##src/lib/wrappthread.c##
+}## 98 ##src/lib/wrappthread.c##
+
+void## 99 ##src/lib/wrappthread.c##
+Pthread_cond_signal(pthread_cond_t *cptr)##100 ##src/lib/wrappthread.c##
+{##101 ##src/lib/wrappthread.c##
+    int     n;##102 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_cond_signal(cptr)) == 0)##103 ##src/lib/wrappthread.c##
+        return;##104 ##src/lib/wrappthread.c##
+    errno = n;##105 ##src/lib/wrappthread.c##
+    err_sys("pthread_cond_signal error");##106 ##src/lib/wrappthread.c##
+}##107 ##src/lib/wrappthread.c##
+
+void##108 ##src/lib/wrappthread.c##
+Pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr)##109 ##src/lib/wrappthread.c##
+{##110 ##src/lib/wrappthread.c##
+    int     n;##111 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_cond_wait(cptr, mptr)) == 0)##112 ##src/lib/wrappthread.c##
+        return;##113 ##src/lib/wrappthread.c##
+    errno = n;##114 ##src/lib/wrappthread.c##
+    err_sys("pthread_cond_wait error");##115 ##src/lib/wrappthread.c##
+}##116 ##src/lib/wrappthread.c##
+
+void##117 ##src/lib/wrappthread.c##
+Pthread_cond_timedwait(pthread_cond_t *cptr, pthread_mutex_t *mptr,##118 ##src/lib/wrappthread.c##
+                       const struct timespec *tsptr)##119 ##src/lib/wrappthread.c##
+{##120 ##src/lib/wrappthread.c##
+    int     n;##121 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_cond_timedwait(cptr, mptr, tsptr)) == 0)##122 ##src/lib/wrappthread.c##
+        return;##123 ##src/lib/wrappthread.c##
+    errno = n;##124 ##src/lib/wrappthread.c##
+    err_sys("pthread_cond_timedwait error");##125 ##src/lib/wrappthread.c##
+}##126 ##src/lib/wrappthread.c##
+
+void##127 ##src/lib/wrappthread.c##
+Pthread_once(pthread_once_t * ptr, void (*func) (void))##128 ##src/lib/wrappthread.c##
+{##129 ##src/lib/wrappthread.c##
+    int     n;##130 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_once(ptr, func)) == 0)##131 ##src/lib/wrappthread.c##
+        return;##132 ##src/lib/wrappthread.c##
+    errno = n;##133 ##src/lib/wrappthread.c##
+    err_sys("pthread_once error");##134 ##src/lib/wrappthread.c##
+}##135 ##src/lib/wrappthread.c##
+
+void##136 ##src/lib/wrappthread.c##
+Pthread_key_create(pthread_key_t * key, void (*func) (void *))##137 ##src/lib/wrappthread.c##
+{##138 ##src/lib/wrappthread.c##
+    int     n;##139 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_key_create(key, func)) == 0)##140 ##src/lib/wrappthread.c##
+        return;##141 ##src/lib/wrappthread.c##
+    errno = n;##142 ##src/lib/wrappthread.c##
+    err_sys("pthread_key_create error");##143 ##src/lib/wrappthread.c##
+}##144 ##src/lib/wrappthread.c##
+
+void##145 ##src/lib/wrappthread.c##
+Pthread_setspecific(pthread_key_t key, const void *value)##146 ##src/lib/wrappthread.c##
+{##147 ##src/lib/wrappthread.c##
+    int     n;##148 ##src/lib/wrappthread.c##
+
+    if ((n = pthread_setspecific(key, value)) == 0)##149 ##src/lib/wrappthread.c##
+        return;##150 ##src/lib/wrappthread.c##
+    errno = n;##151 ##src/lib/wrappthread.c##
+    err_sys("pthread_setspecific error");##152 ##src/lib/wrappthread.c##
+}##153 ##src/lib/wrappthread.c##
diff --git a/lib/wrapsock.c b/lib/wrapsock.c
new file mode 100644 (file)
index 0000000..4ae03c9
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * Socket wrapper functions.
+ * These could all go into separate files, so only the ones needed cause
+ * the corresponding function to be added to the executable.  If sockets
+ * are a library (SVR4) this might make a difference (?), but if sockets
+ * are in the kernel (BSD) it doesn't matter.
+ *
+ * These wrapper functions also use the same prototypes as POSIX.1g,
+ * which might differ from many implementations (i.e., POSIX.1g specifies
+ * the fourth argument to getsockopt() as "void *", not "char *").
+ *
+ * If your system's headers are not correct [i.e., the Solaris 2.5
+ * <sys/socket.h> omits the "const" from the second argument to both
+ * bind() and connect()], you'll get warnings of the form:
+ *warning: passing arg 2 of `bind' discards `const' from pointer target type
+ *warning: passing arg 2 of `connect' discards `const' from pointer target type
+ */
+
+#include       "unp.h"
+
+int
+Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)
+{
+       int             n;
+
+again:
+       if ( (n = accept(fd, sa, salenptr)) < 0) {
+#ifdef EPROTO
+               if (errno == EPROTO || errno == ECONNABORTED)
+#else
+               if (errno == ECONNABORTED)
+#endif
+                       goto again;
+               else
+                       err_sys("accept error");
+       }
+       return(n);
+}
+
+void
+Bind(int fd, const struct sockaddr *sa, socklen_t salen)
+{
+       if (bind(fd, sa, salen) < 0)
+               err_sys("bind error");
+}
+
+void
+Connect(int fd, const struct sockaddr *sa, socklen_t salen)
+{
+       if (connect(fd, sa, salen) < 0)
+               err_sys("connect error");
+}
+
+void
+Getpeername(int fd, struct sockaddr *sa, socklen_t *salenptr)
+{
+       if (getpeername(fd, sa, salenptr) < 0)
+               err_sys("getpeername error");
+}
+
+void
+Getsockname(int fd, struct sockaddr *sa, socklen_t *salenptr)
+{
+       if (getsockname(fd, sa, salenptr) < 0)
+               err_sys("getsockname error");
+}
+
+void
+Getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlenptr)
+{
+       if (getsockopt(fd, level, optname, optval, optlenptr) < 0)
+               err_sys("getsockopt error");
+}
+
+#ifdef HAVE_INET6_RTH_INIT
+int
+Inet6_rth_space(int type, int segments)
+{
+       int ret;
+       
+       ret = inet6_rth_space(type, segments);
+       if (ret < 0)
+               err_quit("inet6_rth_space error");
+
+       return ret;
+}
+
+void *
+Inet6_rth_init(void *rthbuf, socklen_t rthlen, int type, int segments)
+{
+       void *ret;
+
+       ret = inet6_rth_init(rthbuf, rthlen, type, segments);
+       if (ret == NULL)
+               err_quit("inet6_rth_init error");
+
+       return ret;
+}
+
+void
+Inet6_rth_add(void *rthbuf, const struct in6_addr *addr)
+{
+       if (inet6_rth_add(rthbuf, addr) < 0)
+               err_quit("inet6_rth_add error");
+}
+
+void
+Inet6_rth_reverse(const void *in, void *out)
+{
+       if (inet6_rth_reverse(in, out) < 0)
+               err_quit("inet6_rth_reverse error");
+}
+
+int
+Inet6_rth_segments(const void *rthbuf)
+{
+       int ret;
+
+       ret = inet6_rth_segments(rthbuf);
+       if (ret < 0)
+               err_quit("inet6_rth_segments error");
+
+       return ret;
+}
+
+struct in6_addr *
+Inet6_rth_getaddr(const void *rthbuf, int idx)
+{
+       struct in6_addr *ret;
+
+       ret = inet6_rth_getaddr(rthbuf, idx);
+       if (ret == NULL)
+               err_quit("inet6_rth_getaddr error");
+
+       return ret;
+}
+#endif
+
+#ifdef HAVE_KQUEUE
+int
+Kqueue(void)
+{
+       int ret;
+
+       if ((ret = kqueue()) < 0)
+               err_sys("kqueue error");
+       return ret;
+}
+
+int
+Kevent(int kq, const struct kevent *changelist, int nchanges,
+       struct kevent *eventlist, int nevents, const struct timespec *timeout)
+{
+       int ret;
+
+       if ((ret = kevent(kq, changelist, nchanges,
+                                         eventlist, nevents, timeout)) < 0)
+               err_sys("kevent error");
+       return ret;
+}
+#endif
+
+
+/* include Listen */
+void
+Listen(int fd, int backlog)
+{
+       char    *ptr;
+
+               /*4can override 2nd argument with environment variable */
+       if ( (ptr = getenv("LISTENQ")) != NULL)
+               backlog = atoi(ptr);
+
+       if (listen(fd, backlog) < 0)
+               err_sys("listen error");
+}
+/* end Listen */
+
+#ifdef HAVE_POLL
+int
+Poll(struct pollfd *fdarray, unsigned long nfds, int timeout)
+{
+       int             n;
+
+       if ( (n = poll(fdarray, nfds, timeout)) < 0)
+               err_sys("poll error");
+
+       return(n);
+}
+#endif
+
+ssize_t
+Recv(int fd, void *ptr, size_t nbytes, int flags)
+{
+       ssize_t         n;
+
+       if ( (n = recv(fd, ptr, nbytes, flags)) < 0)
+               err_sys("recv error");
+       return(n);
+}
+
+ssize_t
+Recvfrom(int fd, void *ptr, size_t nbytes, int flags,
+                struct sockaddr *sa, socklen_t *salenptr)
+{
+       ssize_t         n;
+
+       if ( (n = recvfrom(fd, ptr, nbytes, flags, sa, salenptr)) < 0)
+               err_sys("recvfrom error");
+       return(n);
+}
+
+ssize_t
+Recvmsg(int fd, struct msghdr *msg, int flags)
+{
+       ssize_t         n;
+
+       if ( (n = recvmsg(fd, msg, flags)) < 0)
+               err_sys("recvmsg error");
+       return(n);
+}
+
+int
+Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+       struct timeval *timeout)
+{
+       int             n;
+
+       if ( (n = select(nfds, readfds, writefds, exceptfds, timeout)) < 0)
+               err_sys("select error");
+       return(n);              /* can return 0 on timeout */
+}
+
+void
+Send(int fd, const void *ptr, size_t nbytes, int flags)
+{
+       if (send(fd, ptr, nbytes, flags) != (ssize_t)nbytes)
+               err_sys("send error");
+}
+
+void
+Sendto(int fd, const void *ptr, size_t nbytes, int flags,
+          const struct sockaddr *sa, socklen_t salen)
+{
+       if (sendto(fd, ptr, nbytes, flags, sa, salen) != (ssize_t)nbytes)
+               err_sys("sendto error");
+}
+
+void
+Sendmsg(int fd, const struct msghdr *msg, int flags)
+{
+       unsigned int    i;
+       ssize_t                 nbytes;
+
+       nbytes = 0;     /* must first figure out what return value should be */
+       for (i = 0; i < msg->msg_iovlen; i++)
+               nbytes += msg->msg_iov[i].iov_len;
+
+       if (sendmsg(fd, msg, flags) != nbytes)
+               err_sys("sendmsg error");
+}
+
+void
+Setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
+{
+       if (setsockopt(fd, level, optname, optval, optlen) < 0)
+               err_sys("setsockopt error");
+}
+
+void
+Shutdown(int fd, int how)
+{
+       if (shutdown(fd, how) < 0)
+               err_sys("shutdown error");
+}
+
+int
+Sockatmark(int fd)
+{
+       int             n;
+
+       if ( (n = sockatmark(fd)) < 0)
+               err_sys("sockatmark error");
+       return(n);
+}
+
+/* include Socket */
+int
+Socket(int family, int type, int protocol)
+{
+       int             n;
+
+       if ( (n = socket(family, type, protocol)) < 0)
+               err_sys("socket error");
+       return(n);
+}
+/* end Socket */
+
+void
+Socketpair(int family, int type, int protocol, int *fd)
+{
+       int             n;
+
+       if ( (n = socketpair(family, type, protocol, fd)) < 0)
+               err_sys("socketpair error");
+}
diff --git a/lib/wrapsock.lc b/lib/wrapsock.lc
new file mode 100644 (file)
index 0000000..963b3f8
--- /dev/null
@@ -0,0 +1,219 @@
+/*##  1 ##src/lib/wrapsock.c##
+ * Socket wrapper functions.##  2 ##src/lib/wrapsock.c##
+ * These could all go into separate files, so only the ones needed cause##  3 ##src/lib/wrapsock.c##
+ * the corresponding function to be added to the executable.  If sockets##  4 ##src/lib/wrapsock.c##
+ * are a library (SVR4) this might make a difference (?), but if sockets##  5 ##src/lib/wrapsock.c##
+ * are in the kernel (BSD) it doesn't matter.##  6 ##src/lib/wrapsock.c##
+ *##  7 ##src/lib/wrapsock.c##
+ * These wrapper functions also use the same prototypes as POSIX.1g,##  8 ##src/lib/wrapsock.c##
+ * which might differ from many implementations (i.e., POSIX.1g specifies##  9 ##src/lib/wrapsock.c##
+ * the fourth argument to getsockopt() as "void *", not "char *").## 10 ##src/lib/wrapsock.c##
+ *## 11 ##src/lib/wrapsock.c##
+ * If your system's headers are not correct [i.e., the Solaris 2.5## 12 ##src/lib/wrapsock.c##
+ * <sys/socket.h> omits the "const" from the second argument to both## 13 ##src/lib/wrapsock.c##
+ * bind() and connect()], you'll get warnings of the form:## 14 ##src/lib/wrapsock.c##
+ *warning: passing arg 2 of bind discards const from pointer target type## 15 ##src/lib/wrapsock.c##
+ *warning: passing arg 2 of connect discards const from pointer target type## 16 ##src/lib/wrapsock.c##
+ */## 17 ##src/lib/wrapsock.c##
+
+#include    "unp.h"## 18 ##src/lib/wrapsock.c##
+
+int## 19 ##src/lib/wrapsock.c##
+Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)## 20 ##src/lib/wrapsock.c##
+{## 21 ##src/lib/wrapsock.c##
+    int     n;## 22 ##src/lib/wrapsock.c##
+
+  again:## 23 ##src/lib/wrapsock.c##
+    if ((n = accept(fd, sa, salenptr)) < 0) {## 24 ##src/lib/wrapsock.c##
+#ifdef  EPROTO## 25 ##src/lib/wrapsock.c##
+        if (errno == EPROTO || errno == ECONNABORTED)## 26 ##src/lib/wrapsock.c##
+#else## 27 ##src/lib/wrapsock.c##
+        if (errno == ECONNABORTED)## 28 ##src/lib/wrapsock.c##
+#endif## 29 ##src/lib/wrapsock.c##
+            goto again;## 30 ##src/lib/wrapsock.c##
+        else## 31 ##src/lib/wrapsock.c##
+            err_sys("accept error");## 32 ##src/lib/wrapsock.c##
+    }## 33 ##src/lib/wrapsock.c##
+    return (n);## 34 ##src/lib/wrapsock.c##
+}## 35 ##src/lib/wrapsock.c##
+
+void## 36 ##src/lib/wrapsock.c##
+Bind(int fd, const struct sockaddr *sa, socklen_t salen)## 37 ##src/lib/wrapsock.c##
+{## 38 ##src/lib/wrapsock.c##
+    if (bind(fd, sa, salen) < 0)## 39 ##src/lib/wrapsock.c##
+        err_sys("bind error");## 40 ##src/lib/wrapsock.c##
+}## 41 ##src/lib/wrapsock.c##
+
+void## 42 ##src/lib/wrapsock.c##
+Connect(int fd, const struct sockaddr *sa, socklen_t salen)## 43 ##src/lib/wrapsock.c##
+{## 44 ##src/lib/wrapsock.c##
+    if (connect(fd, sa, salen) < 0)## 45 ##src/lib/wrapsock.c##
+        err_sys("connect error");## 46 ##src/lib/wrapsock.c##
+}## 47 ##src/lib/wrapsock.c##
+
+void## 48 ##src/lib/wrapsock.c##
+Getpeername(int fd, struct sockaddr *sa, socklen_t *salenptr)## 49 ##src/lib/wrapsock.c##
+{## 50 ##src/lib/wrapsock.c##
+    if (getpeername(fd, sa, salenptr) < 0)## 51 ##src/lib/wrapsock.c##
+        err_sys("getpeername error");## 52 ##src/lib/wrapsock.c##
+}## 53 ##src/lib/wrapsock.c##
+
+void## 54 ##src/lib/wrapsock.c##
+Getsockname(int fd, struct sockaddr *sa, socklen_t *salenptr)## 55 ##src/lib/wrapsock.c##
+{## 56 ##src/lib/wrapsock.c##
+    if (getsockname(fd, sa, salenptr) < 0)## 57 ##src/lib/wrapsock.c##
+        err_sys("getsockname error");## 58 ##src/lib/wrapsock.c##
+}## 59 ##src/lib/wrapsock.c##
+
+void## 60 ##src/lib/wrapsock.c##
+Getsockopt(int fd, int level, int optname, void *optval,## 61 ##src/lib/wrapsock.c##
+           socklen_t *optlenptr)## 62 ##src/lib/wrapsock.c##
+{## 63 ##src/lib/wrapsock.c##
+    if (getsockopt(fd, level, optname, optval, optlenptr) < 0)## 64 ##src/lib/wrapsock.c##
+        err_sys("getsockopt error");## 65 ##src/lib/wrapsock.c##
+}## 66 ##src/lib/wrapsock.c##
+
+/* include Listen */
+void## 67 ##src/lib/wrapsock.c##
+Listen(int fd, int backlog)## 68 ##src/lib/wrapsock.c##
+{## 69 ##src/lib/wrapsock.c##
+    char   *ptr;## 70 ##src/lib/wrapsock.c##
+
+    /* 4can override 2nd argument with environment variable */## 71 ##src/lib/wrapsock.c##
+    if ((ptr = getenv("LISTENQ")) != NULL)## 72 ##src/lib/wrapsock.c##
+        backlog = atoi(ptr);## 73 ##src/lib/wrapsock.c##
+
+    if (listen(fd, backlog) < 0)## 74 ##src/lib/wrapsock.c##
+        err_sys("listen error");## 75 ##src/lib/wrapsock.c##
+}## 76 ##src/lib/wrapsock.c##
+/* end Listen */
+
+#ifdef  HAVE_POLL## 77 ##src/lib/wrapsock.c##
+int## 78 ##src/lib/wrapsock.c##
+Poll(struct pollfd *fdarray, unsigned long nfds, int timeout)## 79 ##src/lib/wrapsock.c##
+{## 80 ##src/lib/wrapsock.c##
+    int     n;## 81 ##src/lib/wrapsock.c##
+
+    if ((n = poll(fdarray, nfds, timeout)) < 0)## 82 ##src/lib/wrapsock.c##
+        err_sys("poll error");## 83 ##src/lib/wrapsock.c##
+
+    return (n);## 84 ##src/lib/wrapsock.c##
+}## 85 ##src/lib/wrapsock.c##
+#endif## 86 ##src/lib/wrapsock.c##
+
+ssize_t## 87 ##src/lib/wrapsock.c##
+Recv(int fd, void *ptr, size_t nbytes, int flags)## 88 ##src/lib/wrapsock.c##
+{## 89 ##src/lib/wrapsock.c##
+    ssize_t n;## 90 ##src/lib/wrapsock.c##
+
+    if ((n = recv(fd, ptr, nbytes, flags)) < 0)## 91 ##src/lib/wrapsock.c##
+        err_sys("recv error");## 92 ##src/lib/wrapsock.c##
+    return (n);## 93 ##src/lib/wrapsock.c##
+}## 94 ##src/lib/wrapsock.c##
+
+ssize_t## 95 ##src/lib/wrapsock.c##
+Recvfrom(int fd, void *ptr, size_t nbytes, int flags,## 96 ##src/lib/wrapsock.c##
+         struct sockaddr *sa, socklen_t *salenptr)## 97 ##src/lib/wrapsock.c##
+{## 98 ##src/lib/wrapsock.c##
+    ssize_t n;## 99 ##src/lib/wrapsock.c##
+
+    if ((n = recvfrom(fd, ptr, nbytes, flags, sa, salenptr)) < 0)##100 ##src/lib/wrapsock.c##
+        err_sys("recvfrom error");##101 ##src/lib/wrapsock.c##
+    return (n);##102 ##src/lib/wrapsock.c##
+}##103 ##src/lib/wrapsock.c##
+
+ssize_t##104 ##src/lib/wrapsock.c##
+Recvmsg(int fd, struct msghdr *msg, int flags)##105 ##src/lib/wrapsock.c##
+{##106 ##src/lib/wrapsock.c##
+    ssize_t n;##107 ##src/lib/wrapsock.c##
+
+    if ((n = recvmsg(fd, msg, flags)) < 0)##108 ##src/lib/wrapsock.c##
+        err_sys("recvmsg error");##109 ##src/lib/wrapsock.c##
+    return (n);##110 ##src/lib/wrapsock.c##
+}##111 ##src/lib/wrapsock.c##
+
+int##112 ##src/lib/wrapsock.c##
+Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,##113 ##src/lib/wrapsock.c##
+       struct timeval *timeout)##114 ##src/lib/wrapsock.c##
+{##115 ##src/lib/wrapsock.c##
+    int     n;##116 ##src/lib/wrapsock.c##
+
+    if ((n = select(nfds, readfds, writefds, exceptfds, timeout)) < 0)##117 ##src/lib/wrapsock.c##
+        err_sys("select error");##118 ##src/lib/wrapsock.c##
+    return (n);                 /* can return 0 on timeout */##119 ##src/lib/wrapsock.c##
+}##120 ##src/lib/wrapsock.c##
+
+void##121 ##src/lib/wrapsock.c##
+Send(int fd, const void *ptr, size_t nbytes, int flags)##122 ##src/lib/wrapsock.c##
+{##123 ##src/lib/wrapsock.c##
+    if (send(fd, ptr, nbytes, flags) != (ssize_t) nbytes)##124 ##src/lib/wrapsock.c##
+        err_sys("send error");##125 ##src/lib/wrapsock.c##
+}##126 ##src/lib/wrapsock.c##
+
+void##127 ##src/lib/wrapsock.c##
+Sendto(int fd, const void *ptr, size_t nbytes, int flags,##128 ##src/lib/wrapsock.c##
+       const struct sockaddr *sa, socklen_t salen)##129 ##src/lib/wrapsock.c##
+{##130 ##src/lib/wrapsock.c##
+    if (sendto(fd, ptr, nbytes, flags, sa, salen) != (ssize_t) nbytes)##131 ##src/lib/wrapsock.c##
+        err_sys("sendto error");##132 ##src/lib/wrapsock.c##
+}##133 ##src/lib/wrapsock.c##
+
+void##134 ##src/lib/wrapsock.c##
+Sendmsg(int fd, const struct msghdr *msg, int flags)##135 ##src/lib/wrapsock.c##
+{##136 ##src/lib/wrapsock.c##
+    unsigned int i;##137 ##src/lib/wrapsock.c##
+    ssize_t nbytes;##138 ##src/lib/wrapsock.c##
+
+    nbytes = 0;                 /* must first figure out what return value should be */##139 ##src/lib/wrapsock.c##
+    for (i = 0; i < msg->msg_iovlen; i++)##140 ##src/lib/wrapsock.c##
+        nbytes += msg->msg_iov[i].iov_len;##141 ##src/lib/wrapsock.c##
+
+    if (sendmsg(fd, msg, flags) != nbytes)##142 ##src/lib/wrapsock.c##
+        err_sys("sendmsg error");##143 ##src/lib/wrapsock.c##
+}##144 ##src/lib/wrapsock.c##
+
+void##145 ##src/lib/wrapsock.c##
+Setsockopt(int fd, int level, int optname, const void *optval,##146 ##src/lib/wrapsock.c##
+           socklen_t optlen)##147 ##src/lib/wrapsock.c##
+{##148 ##src/lib/wrapsock.c##
+    if (setsockopt(fd, level, optname, optval, optlen) < 0)##149 ##src/lib/wrapsock.c##
+        err_sys("setsockopt error");##150 ##src/lib/wrapsock.c##
+}##151 ##src/lib/wrapsock.c##
+
+void##152 ##src/lib/wrapsock.c##
+Shutdown(int fd, int how)##153 ##src/lib/wrapsock.c##
+{##154 ##src/lib/wrapsock.c##
+    if (shutdown(fd, how) < 0)##155 ##src/lib/wrapsock.c##
+        err_sys("shutdown error");##156 ##src/lib/wrapsock.c##
+}##157 ##src/lib/wrapsock.c##
+
+int##158 ##src/lib/wrapsock.c##
+Sockatmark(int fd)##159 ##src/lib/wrapsock.c##
+{##160 ##src/lib/wrapsock.c##
+    int     n;##161 ##src/lib/wrapsock.c##
+
+    if ((n = sockatmark(fd)) < 0)##162 ##src/lib/wrapsock.c##
+        err_sys("sockatmark error");##163 ##src/lib/wrapsock.c##
+    return (n);##164 ##src/lib/wrapsock.c##
+}##165 ##src/lib/wrapsock.c##
+
+/* include Socket */
+int##166 ##src/lib/wrapsock.c##
+Socket(int family, int type, int protocol)##167 ##src/lib/wrapsock.c##
+{##168 ##src/lib/wrapsock.c##
+    int     n;##169 ##src/lib/wrapsock.c##
+
+    if ((n = socket(family, type, protocol)) < 0)##170 ##src/lib/wrapsock.c##
+        err_sys("socket error");##171 ##src/lib/wrapsock.c##
+    return (n);##172 ##src/lib/wrapsock.c##
+}##173 ##src/lib/wrapsock.c##
+/* end Socket */
+
+void##174 ##src/lib/wrapsock.c##
+Socketpair(int family, int type, int protocol, int *fd)##175 ##src/lib/wrapsock.c##
+{##176 ##src/lib/wrapsock.c##
+    int     n;##177 ##src/lib/wrapsock.c##
+
+    if ((n = socketpair(family, type, protocol, fd)) < 0)##178 ##src/lib/wrapsock.c##
+        err_sys("socketpair error");##179 ##src/lib/wrapsock.c##
+}##180 ##src/lib/wrapsock.c##
diff --git a/lib/wrapstdio.c b/lib/wrapstdio.c
new file mode 100644 (file)
index 0000000..a156c45
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Standard I/O wrapper functions.
+ */
+
+#include       "unp.h"
+
+void
+Fclose(FILE *fp)
+{
+       if (fclose(fp) != 0)
+               err_sys("fclose error");
+}
+
+FILE *
+Fdopen(int fd, const char *type)
+{
+       FILE    *fp;
+
+       if ( (fp = fdopen(fd, type)) == NULL)
+               err_sys("fdopen error");
+
+       return(fp);
+}
+
+char *
+Fgets(char *ptr, int n, FILE *stream)
+{
+       char    *rptr;
+
+       if ( (rptr = fgets(ptr, n, stream)) == NULL && ferror(stream))
+               err_sys("fgets error");
+
+       return (rptr);
+}
+
+FILE *
+Fopen(const char *filename, const char *mode)
+{
+       FILE    *fp;
+
+       if ( (fp = fopen(filename, mode)) == NULL)
+               err_sys("fopen error");
+
+       return(fp);
+}
+
+void
+Fputs(const char *ptr, FILE *stream)
+{
+       if (fputs(ptr, stream) == EOF)
+               err_sys("fputs error");
+}
diff --git a/lib/wrapunix.c b/lib/wrapunix.c
new file mode 100644 (file)
index 0000000..d6a23ce
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Socket wrapper functions.
+ * These could all go into separate files, so only the ones needed cause
+ * the corresponding function to be added to the executable.  If sockets
+ * are a library (SVR4) this might make a difference (?), but if sockets
+ * are in the kernel (BSD) it doesn't matter.
+ *
+ * These wrapper functions also use the same prototypes as POSIX.1g,
+ * which might differ from many implementations (i.e., POSIX.1g specifies
+ * the fourth argument to getsockopt() as "void *", not "char *").
+ *
+ * If your system's headers are not correct [i.e., the Solaris 2.5
+ * <sys/socket.h> omits the "const" from the second argument to both
+ * bind() and connect()], you'll get warnings of the form:
+ *warning: passing arg 2 of `bind' discards `const' from pointer target type
+ *warning: passing arg 2 of `connect' discards `const' from pointer target type
+ */
+
+#include       "unp.h"
+
+void *
+Calloc(size_t n, size_t size)
+{
+       void    *ptr;
+
+       if ( (ptr = calloc(n, size)) == NULL)
+               err_sys("calloc error");
+       return(ptr);
+}
+
+void
+Close(int fd)
+{
+       if (close(fd) == -1)
+               err_sys("close error");
+}
+
+void
+Dup2(int fd1, int fd2)
+{
+       if (dup2(fd1, fd2) == -1)
+               err_sys("dup2 error");
+}
+
+int
+Fcntl(int fd, int cmd, int arg)
+{
+       int     n;
+
+       if ( (n = fcntl(fd, cmd, arg)) == -1)
+               err_sys("fcntl error");
+       return(n);
+}
+
+void
+Gettimeofday(struct timeval *tv, void *foo)
+{
+       if (gettimeofday(tv, foo) == -1)
+               err_sys("gettimeofday error");
+       return;
+}
+
+int
+Ioctl(int fd, int request, void *arg)
+{
+       int             n;
+
+       if ( (n = ioctl(fd, request, arg)) == -1)
+               err_sys("ioctl error");
+       return(n);      /* streamio of I_LIST returns value */
+}
+
+pid_t
+Fork(void)
+{
+       pid_t   pid;
+
+       if ( (pid = fork()) == -1)
+               err_sys("fork error");
+       return(pid);
+}
+
+void *
+Malloc(size_t size)
+{
+       void    *ptr;
+
+       if ( (ptr = malloc(size)) == NULL)
+               err_sys("malloc error");
+       return(ptr);
+}
+
+int
+Mkstemp(char *template)
+{
+       int i;
+
+#ifdef HAVE_MKSTEMP
+       if ((i = mkstemp(template)) < 0)
+               err_quit("mkstemp error");
+#else
+       if (mktemp(template) == NULL || template[0] == 0)
+               err_quit("mktemp error");
+       i = Open(template, O_CREAT | O_WRONLY, FILE_MODE);
+#endif
+
+       return i;
+}
+
+#include       <sys/mman.h>
+
+void *
+Mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
+{
+       void    *ptr;
+
+       if ( (ptr = mmap(addr, len, prot, flags, fd, offset)) == ((void *) -1))
+               err_sys("mmap error");
+       return(ptr);
+}
+
+int
+Open(const char *pathname, int oflag, mode_t mode)
+{
+       int             fd;
+
+       if ( (fd = open(pathname, oflag, mode)) == -1)
+               err_sys("open error for %s", pathname);
+       return(fd);
+}
+
+void
+Pipe(int *fds)
+{
+       if (pipe(fds) < 0)
+               err_sys("pipe error");
+}
+
+ssize_t
+Read(int fd, void *ptr, size_t nbytes)
+{
+       ssize_t         n;
+
+       if ( (n = read(fd, ptr, nbytes)) == -1)
+               err_sys("read error");
+       return(n);
+}
+
+void
+Sigaddset(sigset_t *set, int signo)
+{
+       if (sigaddset(set, signo) == -1)
+               err_sys("sigaddset error");
+}
+
+void
+Sigdelset(sigset_t *set, int signo)
+{
+       if (sigdelset(set, signo) == -1)
+               err_sys("sigdelset error");
+}
+
+void
+Sigemptyset(sigset_t *set)
+{
+       if (sigemptyset(set) == -1)
+               err_sys("sigemptyset error");
+}
+
+void
+Sigfillset(sigset_t *set)
+{
+       if (sigfillset(set) == -1)
+               err_sys("sigfillset error");
+}
+
+int
+Sigismember(const sigset_t *set, int signo)
+{
+       int             n;
+
+       if ( (n = sigismember(set, signo)) == -1)
+               err_sys("sigismember error");
+       return(n);
+}
+
+void
+Sigpending(sigset_t *set)
+{
+       if (sigpending(set) == -1)
+               err_sys("sigpending error");
+}
+
+void
+Sigprocmask(int how, const sigset_t *set, sigset_t *oset)
+{
+       if (sigprocmask(how, set, oset) == -1)
+               err_sys("sigprocmask error");
+}
+
+char *
+Strdup(const char *str)
+{
+       char    *ptr;
+
+       if ( (ptr = strdup(str)) == NULL)
+               err_sys("strdup error");
+       return(ptr);
+}
+
+long
+Sysconf(int name)
+{
+       long    val;
+
+       errno = 0;              /* in case sysconf() does not change this */
+       if ( (val = sysconf(name)) == -1)
+               err_sys("sysconf error");
+       return(val);
+}
+
+#ifdef HAVE_SYS_SYSCTL_H
+void
+Sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
+          void *newp, size_t newlen)
+{
+       if (sysctl(name, namelen, oldp, oldlenp, newp, newlen) == -1)
+               err_sys("sysctl error");
+}
+#endif
+
+void
+Unlink(const char *pathname)
+{
+       if (unlink(pathname) == -1)
+               err_sys("unlink error for %s", pathname);
+}
+
+pid_t
+Wait(int *iptr)
+{
+       pid_t   pid;
+
+       if ( (pid = wait(iptr)) == -1)
+               err_sys("wait error");
+       return(pid);
+}
+
+pid_t
+Waitpid(pid_t pid, int *iptr, int options)
+{
+       pid_t   retpid;
+
+       if ( (retpid = waitpid(pid, iptr, options)) == -1)
+               err_sys("waitpid error");
+       return(retpid);
+}
+
+void
+Write(int fd, void *ptr, size_t nbytes)
+{
+       if (write(fd, ptr, nbytes) != nbytes)
+               err_sys("write error");
+}
diff --git a/lib/writable_timeo.c b/lib/writable_timeo.c
new file mode 100644 (file)
index 0000000..b0c35e2
--- /dev/null
@@ -0,0 +1,29 @@
+/* include writable_timeo */
+#include       "unp.h"
+
+int
+writable_timeo(int fd, int sec)
+{
+       fd_set                  wset;
+       struct timeval  tv;
+
+       FD_ZERO(&wset);
+       FD_SET(fd, &wset);
+
+       tv.tv_sec = sec;
+       tv.tv_usec = 0;
+
+       return(select(fd+1, NULL, &wset, NULL, &tv));
+               /* > 0 if descriptor is writable */
+}
+/* end writable_timeo */
+
+int
+Writable_timeo(int fd, int sec)
+{
+       int             n;
+
+       if ( (n = writable_timeo(fd, sec)) < 0)
+               err_sys("writable_timeo error");
+       return(n);
+}
diff --git a/lib/write_fd.c b/lib/write_fd.c
new file mode 100644 (file)
index 0000000..789136a
--- /dev/null
@@ -0,0 +1,51 @@
+/* include write_fd */
+#include       "unp.h"
+
+ssize_t
+write_fd(int fd, void *ptr, size_t nbytes, int sendfd)
+{
+       struct msghdr   msg;
+       struct iovec    iov[1];
+
+#ifdef HAVE_MSGHDR_MSG_CONTROL
+       union {
+         struct cmsghdr        cm;
+         char                          control[CMSG_SPACE(sizeof(int))];
+       } control_un;
+       struct cmsghdr  *cmptr;
+
+       msg.msg_control = control_un.control;
+       msg.msg_controllen = sizeof(control_un.control);
+
+       cmptr = CMSG_FIRSTHDR(&msg);
+       cmptr->cmsg_len = CMSG_LEN(sizeof(int));
+       cmptr->cmsg_level = SOL_SOCKET;
+       cmptr->cmsg_type = SCM_RIGHTS;
+       *((int *) CMSG_DATA(cmptr)) = sendfd;
+#else
+       msg.msg_accrights = (caddr_t) &sendfd;
+       msg.msg_accrightslen = sizeof(int);
+#endif
+
+       msg.msg_name = NULL;
+       msg.msg_namelen = 0;
+
+       iov[0].iov_base = ptr;
+       iov[0].iov_len = nbytes;
+       msg.msg_iov = iov;
+       msg.msg_iovlen = 1;
+
+       return(sendmsg(fd, &msg, 0));
+}
+/* end write_fd */
+
+ssize_t
+Write_fd(int fd, void *ptr, size_t nbytes, int sendfd)
+{
+       ssize_t         n;
+
+       if ( (n = write_fd(fd, ptr, nbytes, sendfd)) < 0)
+               err_sys("write_fd error");
+
+       return(n);
+}
diff --git a/lib/write_fd.lc b/lib/write_fd.lc
new file mode 100644 (file)
index 0000000..672e2b9
--- /dev/null
@@ -0,0 +1,51 @@
+/* include write_fd */
+#include    "unp.h"##  1 ##src/lib/write_fd.c##
+
+ssize_t##  2 ##src/lib/write_fd.c##
+write_fd(int fd, void *ptr, size_t nbytes, int sendfd)##  3 ##src/lib/write_fd.c##
+{##  4 ##src/lib/write_fd.c##
+    struct msghdr msg;##  5 ##src/lib/write_fd.c##
+    struct iovec iov[1];##  6 ##src/lib/write_fd.c##
+
+#ifdef  HAVE_MSGHDR_MSG_CONTROL##  7 ##src/lib/write_fd.c##
+    union {##  8 ##src/lib/write_fd.c##
+        struct cmsghdr cm;##  9 ##src/lib/write_fd.c##
+        char    control[CMSG_SPACE(sizeof(int))];## 10 ##src/lib/write_fd.c##
+    } control_un;## 11 ##src/lib/write_fd.c##
+    struct cmsghdr *cmptr;## 12 ##src/lib/write_fd.c##
+
+    msg.msg_control = control_un.control;## 13 ##src/lib/write_fd.c##
+    msg.msg_controllen = sizeof(control_un.control);## 14 ##src/lib/write_fd.c##
+
+    cmptr = CMSG_FIRSTHDR(&msg);## 15 ##src/lib/write_fd.c##
+    cmptr->cmsg_len = CMSG_LEN(sizeof(int));## 16 ##src/lib/write_fd.c##
+    cmptr->cmsg_level = SOL_SOCKET;## 17 ##src/lib/write_fd.c##
+    cmptr->cmsg_type = SCM_RIGHTS;## 18 ##src/lib/write_fd.c##
+    *((int *) CMSG_DATA(cmptr)) = sendfd;## 19 ##src/lib/write_fd.c##
+#else## 20 ##src/lib/write_fd.c##
+    msg.msg_accrights = (caddr_t) & sendfd;## 21 ##src/lib/write_fd.c##
+    msg.msg_accrightslen = sizeof(int);## 22 ##src/lib/write_fd.c##
+#endif## 23 ##src/lib/write_fd.c##
+
+    msg.msg_name = NULL;## 24 ##src/lib/write_fd.c##
+    msg.msg_namelen = 0;## 25 ##src/lib/write_fd.c##
+
+    iov[0].iov_base = ptr;## 26 ##src/lib/write_fd.c##
+    iov[0].iov_len = nbytes;## 27 ##src/lib/write_fd.c##
+    msg.msg_iov = iov;## 28 ##src/lib/write_fd.c##
+    msg.msg_iovlen = 1;## 29 ##src/lib/write_fd.c##
+
+    return (sendmsg(fd, &msg, 0));## 30 ##src/lib/write_fd.c##
+}## 31 ##src/lib/write_fd.c##
+/* end write_fd */
+
+ssize_t## 32 ##src/lib/write_fd.c##
+Write_fd(int fd, void *ptr, size_t nbytes, int sendfd)## 33 ##src/lib/write_fd.c##
+{## 34 ##src/lib/write_fd.c##
+    ssize_t n;## 35 ##src/lib/write_fd.c##
+
+    if ((n = write_fd(fd, ptr, nbytes, sendfd)) < 0)## 36 ##src/lib/write_fd.c##
+        err_sys("write_fd error");## 37 ##src/lib/write_fd.c##
+
+    return (n);## 38 ##src/lib/write_fd.c##
+}## 39 ##src/lib/write_fd.c##
diff --git a/lib/writen.c b/lib/writen.c
new file mode 100644 (file)
index 0000000..0bf8eb7
--- /dev/null
@@ -0,0 +1,33 @@
+/* include writen */
+#include       "unp.h"
+
+ssize_t                                                /* Write "n" bytes to a descriptor. */
+writen(int fd, const void *vptr, size_t n)
+{
+       size_t          nleft;
+       ssize_t         nwritten;
+       const char      *ptr;
+
+       ptr = vptr;
+       nleft = n;
+       while (nleft > 0) {
+               if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
+                       if (nwritten < 0 && errno == EINTR)
+                               nwritten = 0;           /* and call write() again */
+                       else
+                               return(-1);                     /* error */
+               }
+
+               nleft -= nwritten;
+               ptr   += nwritten;
+       }
+       return(n);
+}
+/* end writen */
+
+void
+Writen(int fd, void *ptr, size_t nbytes)
+{
+       if (writen(fd, ptr, nbytes) != nbytes)
+               err_sys("writen error");
+}
diff --git a/lib/writen.lc b/lib/writen.lc
new file mode 100644 (file)
index 0000000..0fe387d
--- /dev/null
@@ -0,0 +1,33 @@
+/* include writen */
+#include    "unp.h"##  1 ##src/lib/writen.c##
+
+ssize_t                         /* Write "n" bytes to a descriptor. */##  2 ##src/lib/writen.c##
+writen(int fd, const void *vptr, size_t n)##  3 ##src/lib/writen.c##
+{##  4 ##src/lib/writen.c##
+    size_t  nleft;##  5 ##src/lib/writen.c##
+    ssize_t nwritten;##  6 ##src/lib/writen.c##
+    const char *ptr;##  7 ##src/lib/writen.c##
+
+    ptr = vptr;##  8 ##src/lib/writen.c##
+    nleft = n;##  9 ##src/lib/writen.c##
+    while (nleft > 0) {## 10 ##src/lib/writen.c##
+        if ((nwritten = write(fd, ptr, nleft)) <= 0) {## 11 ##src/lib/writen.c##
+            if (nwritten < 0 && errno == EINTR)## 12 ##src/lib/writen.c##
+                nwritten = 0;   /* and call write() again */## 13 ##src/lib/writen.c##
+            else## 14 ##src/lib/writen.c##
+                return (-1);    /* error */## 15 ##src/lib/writen.c##
+        }## 16 ##src/lib/writen.c##
+
+        nleft -= nwritten;## 17 ##src/lib/writen.c##
+        ptr += nwritten;## 18 ##src/lib/writen.c##
+    }## 19 ##src/lib/writen.c##
+    return (n);## 20 ##src/lib/writen.c##
+}## 21 ##src/lib/writen.c##
+/* end writen */
+
+void## 22 ##src/lib/writen.c##
+Writen(int fd, void *ptr, size_t nbytes)## 23 ##src/lib/writen.c##
+{## 24 ##src/lib/writen.c##
+    if (writen(fd, ptr, nbytes) != nbytes)## 25 ##src/lib/writen.c##
+        err_sys("writen error");## 26 ##src/lib/writen.c##
+}## 27 ##src/lib/writen.c##
diff --git a/libfree/Make.tar b/libfree/Make.tar
new file mode 100755 (executable)
index 0000000..770dd04
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+tar -cvf addrinfo.tar README.getaddrinfo addrinfo.h getaddrinfo.c \
+                       getnameinfo.c test_addrinfo.c inet_ntop.c inet_pton.c
+
+compress addrinfo.tar
diff --git a/libfree/Makefile b/libfree/Makefile
new file mode 100644 (file)
index 0000000..8578107
--- /dev/null
@@ -0,0 +1,11 @@
+include ../Make.defines
+
+all:   ${LIBFREE_OBJS}
+               ar rv ${LIBUNP_NAME} $?
+               ${RANLIB} ${LIBUNP_NAME}
+
+test_inet_pton:        test_inet_pton.o
+               ${CC} ${CFLAGS} -o $@ test_inet_pton.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/libfree/README b/libfree/README
new file mode 100644 (file)
index 0000000..cd4d816
--- /dev/null
@@ -0,0 +1,3 @@
+This directory contains the library files that do *not* #include unp.h.
+The intent is that these functions can stand alone, without the rest
+of the code from the book.
diff --git a/libfree/README.getaddrinfo b/libfree/README.getaddrinfo
new file mode 100644 (file)
index 0000000..5c0e0ff
--- /dev/null
@@ -0,0 +1,19 @@
+09Sep96
+
+Please read the comments at the begiinning of getaddrinfo.c.
+
+Supplied with this function are the two files inet_pton.c and
+inet_ntop.c from the BIND-4.9.4 release.  The arguments of
+these two functions differ from the current (but old) Internet
+Draft "ipngwg-bsd-api-05.txt", but the next revision of this
+draft will document these functions as they exist in BIND-4.9.4.
+
+Beware that most IPv6 releases are "alpha" at this time.  The
+use of the RES_USE_INET6 option in getaddrinfo() is again from
+the BIND-4.9.4 release, as this is what will become the standard.
+But few implementations, if any, support this unless you install
+BIND-4.9.4 (or later) yourself.
+
+Buf fixes, suggestions, etc. are welcome.
+
+       Rich Stevens  (rstevens@kohala.com)
diff --git a/libfree/addrinfo.h b/libfree/addrinfo.h
new file mode 100644 (file)
index 0000000..7cef135
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef        __addrinfo_h
+#define        __addrinfo_h
+
+/*
+ * Everything here really belongs in <netdb.h>.
+ * These defines are separate for now, to avoid having to modify the
+ * system's header.
+ */
+
+struct addrinfo {
+  int          ai_flags;                       /* AI_PASSIVE, AI_CANONNAME */
+  int          ai_family;                      /* PF_xxx */
+  int          ai_socktype;            /* SOCK_xxx */
+  int          ai_protocol;            /* IPPROTO_xxx for IPv4 and IPv6 */
+  size_t       ai_addrlen;                     /* length of ai_addr */
+  char         *ai_canonname;          /* canonical name for host */
+  struct sockaddr      *ai_addr;       /* binary address */
+  struct addrinfo      *ai_next;       /* next structure in linked list */
+};
+
+                       /* following for getaddrinfo() */
+#define        AI_PASSIVE               1      /* socket is intended for bind() + listen() */
+#define        AI_CANONNAME     2      /* return canonical name */
+
+                       /* following for getnameinfo() */
+#define        NI_MAXHOST        1025  /* max hostname returned */
+#define        NI_MAXSERV          32  /* max service name returned */
+
+#define        NI_NOFQDN            1  /* do not return FQDN */
+#define        NI_NUMERICHOST   2      /* return numeric form of hostname */
+#define        NI_NAMEREQD          4  /* return error if hostname not found */
+#define        NI_NUMERICSERV   8      /* return numeric form of service name */
+#define        NI_DGRAM            16  /* datagram service for getservbyname() */
+
+                       /* error returns */
+#define        EAI_ADDRFAMILY   1      /* address family for host not supported */
+#define        EAI_AGAIN                2      /* temporary failure in name resolution */
+#define        EAI_BADFLAGS     3      /* invalid value for ai_flags */
+#define        EAI_FAIL                 4      /* non-recoverable failure in name resolution */
+#define        EAI_FAMILY               5      /* ai_family not supported */
+#define        EAI_MEMORY               6      /* memory allocation failure */
+#define        EAI_NODATA               7      /* no address associated with host */
+#define        EAI_NONAME               8      /* host nor service provided, or not known */
+#define        EAI_SERVICE              9      /* service not supported for ai_socktype */
+#define        EAI_SOCKTYPE    10      /* ai_socktype not supported */
+#define        EAI_SYSTEM              11      /* system error returned in errno */
+
+#endif /* __addrinfo_h */
diff --git a/libfree/getaddrinfo.c b/libfree/getaddrinfo.c
new file mode 100644 (file)
index 0000000..6b221e1
--- /dev/null
@@ -0,0 +1,769 @@
+/*
+ * Copyright (c) 1996 W. Richard Stevens.  All rights reserved. 
+ *
+ * Permission to use or modify this software for educational or
+ * for commercial purposes, and without fee, is hereby granted,
+ * provided that the above copyright notice appears in connection
+ * with any and all uses, with clear indication as to any
+ * modifications made.  The author RESERVES the sole rights of
+ * reproduction, publication and distribution and hence permission
+ * to print this source code in any book, reference manual,
+ * magazine, or other type of publication, including any digital
+ * medium, must be granted in writing by W. Richard Stevens.
+ *
+ * The author makes no representations about the suitability of this 
+ * software for any purpose.  It is provided "as is" without express
+ * or implied warranty. 
+ */
+
+/* tabs set for 4 spaces, not 8 */
+
+#ifdef __osf__
+#define        _SOCKADDR_LEN           /* required for this implementation */
+#define        INET6                           /* required for this implementation */
+#endif
+
+#include       <sys/types.h>
+#include       <sys/socket.h>
+#include       <netinet/in.h>
+#include       <ctype.h>               /* isdigit() */
+#include       <netdb.h>               /* hostent{}, servent{}, etc. */
+#include       <arpa/inet.h>   /* inet_pton() */
+#include       <arpa/nameser.h>
+#include       <resolv.h>              /* DNS resolver */
+#include       <stdlib.h>              /* malloc() and calloc() */
+#include       <string.h>              /* strdup() and strncpy() */
+#include       <unistd.h>              /* unlink() */
+#include       <sys/un.h>              /* for Unix domain socket stuff */
+
+#ifndef        __osf__
+#include       "addrinfo.h"    /* defines in here really belong in <netdb.h> */
+#endif
+
+/* NOTE: this code assumes you have the inet_pton() function as defined
+ * in the BIND-4.9.4 release or later (ftp://ftp.vix.com/pub/bind).
+ * If you don't have this in your resolver library, in this tar file is
+ * a copy of it, along with inet_ntop(). */
+
+/* We need a way to determine if the compiling host supports IPv4/IPv6.
+ * Cannot test for AF_INET6, as some vendors #define it, even though
+ * they don't support it. */
+
+#ifdef AF_INET
+#define        IPV4    /* this is tested throughout the code that follows */
+#endif
+
+                       /* no one constant that all implementations define, sigh */
+#if            defined(IPV6ADDR_ANY_INIT)
+#define        IPV6    /* this is tested throughout the code that follows */
+#elif  defined(IPV6_FLOWINFO_FLOWLABEL)
+#define        IPV6    /* this is tested throughout the code that follows */
+#endif
+
+/* There is no requirement that getaddrinfo() support Unix domain sockets,
+ * but what the heck, it doesn't take too much code, and it's a real good
+ * test whether an application is *really* protocol-independent. */
+
+#ifdef AF_UNIX
+#define        LOCAL   /* this is tested throughout the code that follows */
+
+#ifndef        AF_LOCAL
+#define        AF_LOCAL        AF_UNIX         /* the Posix.1g correct term */
+#endif
+#ifndef        PF_LOCAL
+#define        PF_LOCAL        PF_UNIX         /* the Posix.1g correct term */
+#endif
+
+#endif /* AF_UNIX */
+
+/* Define REENTRANT if the reentrant versions of get{host|serv}byname
+ * are to be used.
+ * Note that getaddrinfo{} *must* be reentrant if the underlying
+ * get{host|serv}byname_r functions are provided.
+ * This program has only been tested with the Solaris 2.x functions.
+ * (I have no idea if other vendors have the same functions or not.)
+ *
+ * Long diatribe: Don't define REENTRANT.  At least not until you know
+ * what your vendor's gethostbyname_r() function does with regard to
+ * IPv4/IPv6 addresses.  If you really need a reentrant version of this
+ * function, because you call it from different threads, then use a
+ * mutex lock to protect the calls.
+ * The problem at the time of this writing is the handling of IPv4/IPv6
+ * addresses.  BIND-4.9.4 does it the "right" way :-), but this won't
+ * be documented until a later revision of the IPv6 BSD API spec.  Also
+ * BIND-4.9.4 doesn't provide the reentrant _r() functions, and I have
+ * no idea what the vendors like Sun have done with these functions.
+ * The code far below that calls gethostbyname() sets the resolver
+ * RES_USE_INET6 option if the caller specifies an ai_family of AF_INET6.
+ * This causes 16-byte addresses to be returned, regardless, either
+ * "true" IPv6 address from AAAA records, or IPv4-mapped IPv6 addresses
+ * from A records.  If the caller specifies an ai_family of AF_INET6,
+ * then we should return 16-byte addresses.
+ * With BIND-4.9.4 the caller can also force the return of 16-byte addresses
+ * by setting the environment variable RES_OPTIONS, as in
+ *    % RES_OPTIONS=inet6 ./a.out arguments...
+ * This way the caller need not pollute the code with code like
+ * ai_family = AF_INET6, making the code protocol-dependent.
+ */
+
+/* #define     REENTRANT */
+
+/* Define following function prototype if your headers don't define it */
+
+int     inet_pton(int, const char *, void *);
+
+#define        HENTBUFSIZ      8*1024
+#define        HENTMAXADDR         32  /* max binary address: 16 for IPv4, 24 for IPv6 */
+
+               /* following internal flags cannot overlap with other AI_xxx flags */
+#define        AI_CLONE             4  /* clone this entry for other socket types */
+
+               /* function prototypes for our own internal functions */
+static int     getaddrinfo_host(const char *, struct hostent *,
+                                                        struct hostent **, char *, int, int);
+static int     getaddrinfo_serv(struct addrinfo *,
+                                                        const struct addrinfo *, const char *,
+                                                        struct servent *, char *, int);
+static int     getaddrinfo_port(struct addrinfo *, int , int);
+static int     addrinfo_local(const char *, struct addrinfo *,
+                                                  struct addrinfo **);
+static struct addrinfo *getaddrinfo_clone(struct addrinfo *);
+
+               /* globals for all functions in this file; these *must* be
+                  read-only if this function is to be reentrant */
+static struct addrinfo hints_default;
+
+int
+getaddrinfo(const char *host, const char *serv,
+                       const struct addrinfo *hintsptr, struct addrinfo **result)
+{
+       int                                     rc, error;
+       struct hostent          *hptr, hent;
+       struct servent          sent;
+       char                            hentbuf[HENTBUFSIZ], hent_addr[HENTMAXADDR];
+       char                            *hent_aliases[1], *hent_addr_list[2];
+       char                            **ap;
+       struct addrinfo         hints, *ai, *aihead, **aipnext;
+
+#ifdef IPV4
+       struct sockaddr_in      *sinptr;
+#endif
+
+#ifdef IPV6
+       struct sockaddr_in6     *sin6ptr;
+#endif
+
+/* If we encounter an error we want to free() any dynamic memory
+   that we've allocated.  This is our hack to simplify the code. */
+#define        error(e) { error = (e); goto bad; }
+
+       /*
+        * We must make a copy of the caller's hints structure, so we can
+        * modify ai_family.  If the caller doesn't provide a hints structure,
+        * use a default one.  This simplifies all the following code.
+        * In the default one, ai_flags, ai_socktype, and ai_protocol are all 0,
+        * but we have to set ai_family to AF_UNSPEC, which isn't guaranteed to
+        * be 0.
+        */ 
+       if (hintsptr == NULL) {
+               hints_default.ai_family = AF_UNSPEC;
+               hints = hints_default;  /* struct copy */
+       } else
+               hints = *hintsptr;              /* struct copy */
+
+       /*
+        * First some error checking.
+        */
+       if (hints.ai_flags & ~(AI_PASSIVE | AI_CANONNAME))
+               error(EAI_BADFLAGS);    /* unknown flag bits */
+
+       /*
+        * Check that the family is valid, and if a socket type is also
+        * specified, check that it's valid for the family.
+        */
+       if (hints.ai_family != 0) {
+               switch(hints.ai_family) {
+                       case AF_UNSPEC: break;
+                               /* Actually, AF_UNSPEC is normally defined as 0,
+                                  but Posix.1g does not require this. */
+#ifdef IPV4
+                       case AF_INET:
+                               if (hints.ai_socktype != 0 &&
+                                       (hints.ai_socktype != SOCK_STREAM &&
+                                        hints.ai_socktype != SOCK_DGRAM &&
+                                        hints.ai_socktype != SOCK_RAW))
+                                       error(EAI_SOCKTYPE);    /* invalid socket type */
+                               break;
+#endif
+#ifdef IPV6
+                       case AF_INET6:
+                               if (hints.ai_socktype != 0 &&
+                                       (hints.ai_socktype != SOCK_STREAM &&
+                                        hints.ai_socktype != SOCK_DGRAM &&
+                                        hints.ai_socktype != SOCK_RAW))
+                                       error(EAI_SOCKTYPE);    /* invalid socket type */
+                               break;
+#endif
+#ifdef LOCAL
+                       case AF_LOCAL:
+                               if (hints.ai_socktype != 0 &&
+                                       (hints.ai_socktype != SOCK_STREAM &&
+                                        hints.ai_socktype != SOCK_DGRAM))
+                                       error(EAI_SOCKTYPE);    /* invalid socket type */
+                               break;
+#endif
+               default:
+                       error(EAI_FAMILY);              /* unknown protocol family */
+               }
+       }
+
+       if (host == NULL || host[0] == '\0') {
+               if (serv == NULL || serv[0] == '\0')
+                       error(EAI_NONAME);      /* either host or serv must be specified */
+
+               if (hints.ai_flags & AI_PASSIVE) {
+                       /*
+                        * No "host" and AI_PASSIVE: the returned address must be
+                        * ready for bind(): 0.0.0.0 for IPv4 or 0::0 for IPv6.
+                        */
+                       switch (hints.ai_family) {
+#ifdef IPV4
+                       case AF_INET:   host = "0.0.0.0"; break;
+#endif
+#ifdef IPV6
+                       case AF_INET6:  host = "0::0"; break;
+#endif
+#ifdef LOCAL
+                       case AF_LOCAL:
+                               if (serv[0] != '/')             /* allow service to specify path */
+                                       error(EAI_ADDRFAMILY);
+                               break;
+#endif
+                       case 0:                 error(EAI_ADDRFAMILY);
+                                       /* How can we initialize a socket address structure
+                                          for a passive open if we don't even know the family? */
+                       }
+               } else {
+                       /*
+                        * No host and not AI_PASSIVE: caller implies connect() to
+                        * local host.
+                        */
+
+                       host = "localhost";
+               }
+       } else if (hints.ai_family == 0) {
+               /*
+                * Caller specifies a host but no address family.
+                * If the host string is really a valid IPv4 dotted-decimal address,
+                * set family to IPv4.  Similarly for IPv6 strings.
+                * This allows server applications to be protocol independent
+                * (not having to hard code a protocol family), allowing the
+                * user who starts the program to specify either 0.0.0.0 or 0::0.
+                *
+                * Assumed below is that inet_pton() allows only "valid" strings,
+                * which Paul Vixie put into the BIND-4.9.4 version of this function.
+                */
+
+               char    temp[16];
+
+#ifdef IPV4
+               if (inet_pton(AF_INET, host, temp) == 1)
+                       hints.ai_family = AF_INET;
+#endif
+#ifdef IPV6
+               if (inet_pton(AF_INET6, host, temp) == 1)
+                       hints.ai_family = AF_INET6;
+#endif
+               /*
+                * Note that we could bypass some of the testing done in
+                * getaddrinfo_host(), but it doesn't seem worth complicating
+                * this (already long) function.
+                */
+       }
+
+#ifdef LOCAL
+       /*
+        * For a Unix domain socket only one string can be provided and we
+        * require it to be an absolute pathname.  (Using relative pathnames
+        * is asking for trouble.)  We allow this string to be specified as
+        * either the hostname or the service name, in which case we ignore
+        * the other string.  Notice that a slash is not allowed in a DNS
+        * hostname (see RFC 1912) and a slash does not appear in any of the
+        * service names in /etc/services either.  Hence no conflict.
+        * For example, often a protocol-independent server will allow an
+        * argument to specify the service (e.g., port number) and let the
+        * hostname be wildcarded.  Similarly, a protocol-independent client
+        * often allows only the hostname as a command-line argument, hardcoding
+        * a service name in the program (which we ignore).
+        */
+
+       if ((host != NULL && host[0] == '/'))
+               return(addrinfo_local(host, &hints, result));
+
+       if ((serv != NULL && serv[0] == '/'))
+               return(addrinfo_local(serv, &hints, result));
+#endif
+
+       /*
+        * Look up the host.  The code above guarantees that "host"
+        * is a nonnull pointer to a nonull string.
+        *
+        * We first initialize "hent" assuming "host" is an IPv4/IPv6 address
+        * (instead of a name).  This saves passing lots of additional
+        * arguments to getaddrinfo_host().
+        */
+
+       hent.h_name = hentbuf;          /* char string specifying address goes here */
+       hent.h_aliases = hent_aliases;
+       hent_aliases[0] = NULL;                 /* no aliases */
+       hent.h_addr_list = hent_addr_list;
+       hent_addr_list[0] = hent_addr;  /* one binary address in [0] */
+       hent_addr_list[1] = NULL;
+       hptr = &hent;
+
+       if ( (rc = getaddrinfo_host(host, &hent, &hptr, hentbuf, HENTBUFSIZ,
+                                                               hints.ai_family)) != 0)
+               error(rc);
+
+       /*
+        * "hptr" now points to a filled in hostent{}.
+        * If "host" was an IPv4/IPv6 address, instead of a name, then
+        * "hptr" points to our own "hent" structure.
+        * If gethostbyname_r() was called, then "hptr" points to our own
+        * "hent" structure, which was passed as as an argument to the
+        * reentrant function.
+        * If gethostbyname() was called, then "hptr" points to the static
+        * hostent{} that it returned.
+        *
+        * Check for address family mismatch if the caller specified one.
+        * Note that Posix.1g assumes that AF_foo == PF_foo.
+        */
+       if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype)
+               error(EAI_ADDRFAMILY);
+
+       /*
+        * Go through the list of returned addresses and create one
+        * addrinfo{} for each one, linking all the structures together.
+        * We still have not looked at the service--that comes after this.
+        */
+
+       aihead = NULL;
+       aipnext = &aihead;
+       for (ap = hptr->h_addr_list; *ap != NULL; ap++) {
+               if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL)
+                       error(EAI_MEMORY);
+               *aipnext = ai;                  /* prev points to this new one */
+               aipnext = &ai->ai_next; /* pointer to next one goes here */
+
+                       /* initialize from hints; could be 0 */
+               if ( (ai->ai_socktype = hints.ai_socktype) == 0)
+                       ai->ai_flags |= AI_CLONE;
+               ai->ai_protocol = hints.ai_protocol;
+
+               ai->ai_family = hptr->h_addrtype;
+               switch (ai->ai_family) {
+                       /*
+                        * Allocate a socket address structure and fill it in.
+                        * The port number will be filled in later, when the service
+                        * is processed.
+                        */
+#ifdef IPV4
+                       case AF_INET:
+                               if ( (sinptr = calloc(1, sizeof(struct sockaddr_in))) == NULL)
+                                       error(EAI_MEMORY);
+#ifdef SIN_LEN
+                               sinptr->sin_len = sizeof(struct sockaddr_in);
+#endif
+                               sinptr->sin_family = AF_INET;
+                               memcpy(&sinptr->sin_addr, *ap, sizeof(struct in_addr));
+                               ai->ai_addr = (struct sockaddr *) sinptr;
+                               ai->ai_addrlen = sizeof(struct sockaddr_in);
+                               break;
+#endif /* IPV4 */
+
+#ifdef IPV6
+                       case AF_INET6:
+                               if ( (sin6ptr = calloc(1, sizeof(struct sockaddr_in6))) == NULL)
+                                       error(EAI_MEMORY);
+#ifdef SIN6_LEN
+                               sin6ptr->sin6_len = sizeof(struct sockaddr_in6);
+#endif
+                               sin6ptr->sin6_family = AF_INET6;
+                               memcpy(&sin6ptr->sin6_addr, *ap, sizeof(struct in6_addr));
+                               ai->ai_addr = (struct sockaddr *) sin6ptr;
+                               ai->ai_addrlen = sizeof(struct sockaddr_in6);
+                               break;
+#endif /* IPV6 */
+               }
+       }
+       /* "aihead" points to the first structure in the linked list */
+
+       if (hints.ai_flags & AI_CANONNAME) {
+               /*
+                * Posix.1g doesn't say what to do if this flag is set and
+                * multiple addrinfo structures are returned.
+                * We return the canonical name only in the first addrinfo{}.
+                */
+               if (hptr->h_name != NULL) {
+                       if ( (aihead->ai_canonname = strdup(hptr->h_name)) == NULL)
+                               error(EAI_MEMORY);
+               } else {
+                       /*
+                        * Posix.1g says we can just set ai_canonname to point to the
+                        * "host" argument, but that makes freeaddrinfo() harder.
+                        * We dynamically allocate room for a copy of "host".
+                        */
+                       if ( (aihead->ai_canonname = strdup(host)) == NULL)
+                               error(EAI_MEMORY);
+               }
+       }
+
+       /*
+        * Now look up the service, if specified.
+        */
+       if (serv != NULL && serv[0] != '\0') {
+               if ( (rc = getaddrinfo_serv(aihead, &hints, serv, &sent,
+                                                                       hentbuf, HENTBUFSIZ)) != 0)
+                       error(rc);
+       }
+
+       *result = aihead;       /* pointer to first structure in linked list */
+       return(0);
+
+bad:
+       freeaddrinfo(aihead);   /* free any alloc'ed memory */
+       return(error);
+}
+
+/*
+ * This function handles the host string.
+ */
+
+static int
+getaddrinfo_host(const char *host,
+                                struct hostent *hptr, struct hostent **hptrptr,
+                                char *buf, int bufsiz, int family)
+{
+
+#ifdef REENTRANT
+       int             h_errno;
+#endif /* REENTRANT */
+
+#ifdef IPV4
+       /*
+        * We explicitly check for an IPv4 dotted-decimal string.
+        * Recent versions of gethostbyname(), starting around BIND 4.9.2
+        * do this too, but we have the check here so we don't depend on
+        * this newer feature.  (You wouldn't believe the ancient versions
+        * of BIND that some vendors ship.)
+        */
+       if (isdigit(host[0])) {
+               if (inet_pton(AF_INET, host, hptr->h_addr_list[0]) == 1) {
+                               /* Success.  Finish making up the hostent{} as though
+                                  we had called gethostbyname(). */
+                       strncpy(hptr->h_name, host, bufsiz-1);
+                       buf[bufsiz-1] = '\0';
+                       hptr->h_addrtype = AF_INET;
+                       hptr->h_length = sizeof(struct in_addr);
+                       return(0);
+               }
+       }
+#endif /* IPV4 */
+
+#ifdef IPV6
+       /*
+        * Check for an IPv6 hex string.
+        */
+       if (isxdigit(host[0]) || host[0] == ':') {
+               if (inet_pton(AF_INET6, host, hptr->h_addr_list[0]) == 1) {
+                               /* Success.  Finish making up a hostent{} as though
+                                  we had called gethostbyname(). */
+                       strncpy(buf, host, bufsiz-1);
+                       buf[bufsiz-1] = '\0';
+                       hptr->h_addrtype = AF_INET6;
+                       hptr->h_length = sizeof(struct in6_addr);
+                       return(0);
+               }
+       }
+#endif /* IPV6 */
+
+       /*
+        * Not an address, must be a hostname, try the DNS.
+        * Initialize the resolver, if not already initialized.
+        */
+
+       if ((_res.options & RES_INIT) == 0)
+               res_init();                     /* need this to set _res.options below */
+
+#ifdef IPV6
+       /*
+        * Notice that the following might be considered optional, and
+        * could be #ifdef'ed out if your <resolv.h> does not define
+        * RES_USE_INET6.  But I am assuming you have BIND-4.9.4 installed
+        * and want the IPv4/IPv6 semantics that it defines for gethostbyname().
+        */
+
+#ifndef        RES_USE_INET6
+       /* This is a gross hack; following line from BIND-4.9.4 release ... */
+       /* (if you're using 4.9.4, but have not installed the include files) */
+#define        RES_USE_INET6   0x00002000      /* use/map IPv6 in gethostbyname() */
+#endif
+       if (family == AF_INET6)
+               _res.options |= RES_USE_INET6;
+#endif /* IPV6 */
+
+#ifdef REENTRANT
+       hptr = gethostbyname_r(host, hptr, buf, bufsiz, &h_errno);
+#else
+       hptr = gethostbyname(host);
+#endif /* REENTRANT */
+       if (hptr == NULL) {
+               switch (h_errno) {
+                       case HOST_NOT_FOUND:    return(EAI_NONAME);
+                       case TRY_AGAIN:                 return(EAI_AGAIN);
+                       case NO_RECOVERY:               return(EAI_FAIL);
+                       case NO_DATA:                   return(EAI_NODATA);
+                       default:                                return(EAI_NONAME);
+               }
+       }
+       *hptrptr = hptr;
+       return(0);
+}
+
+/*
+ * This function handles the service string.
+ */
+
+static int
+getaddrinfo_serv(struct addrinfo *aihead,
+                                const struct addrinfo *hintsptr, const char *serv,
+                                struct servent *sptrarg, char *buf, int bufsiz)
+{
+       int                             port, rc;
+       int                             nfound = 0;
+       struct servent  *sptr;
+
+       /*
+        * We allow the service to be a numeric string, which we
+        * interpret as a decimal port number.  Posix.1g doesn't
+        * explicitly say to do this, but it just makes sense.
+        * But to do this the caller must specify a socket type,
+        * else there's no way to return values for socket().
+        */
+
+       if (isdigit(serv[0]) && hintsptr->ai_socktype != 0) {
+               port = htons(atoi(serv));
+               if ( (rc = getaddrinfo_port(aihead, port, hintsptr->ai_socktype)) == 0)
+                       return(EAI_NONAME);
+               else if (rc < 0)
+                       return(EAI_MEMORY);
+               else
+                       return(0);
+       }
+
+       /*
+        * Not a special case, try the "/etc/services" file (or whatever).
+        * We first try TCP, if applicable.
+        */
+
+       if (hintsptr->ai_socktype == 0 || hintsptr->ai_socktype == SOCK_STREAM) {
+#ifdef REENTRANT
+               sptr = getservbyname_r(serv, "tcp", sptrarg, buf, bufsiz);
+#else
+               sptr = getservbyname(serv, "tcp");
+#endif /* REENTRANT */
+               if (sptr != NULL) {
+                       rc = getaddrinfo_port(aihead, sptr->s_port, SOCK_STREAM);
+                       if (rc < 0)
+                               return(EAI_MEMORY);
+                       nfound += rc;
+               }
+       }
+
+       /*
+        * Now try UDP, if applicable.
+        */
+       if (hintsptr->ai_socktype == 0 || hintsptr->ai_socktype == SOCK_DGRAM) {
+#ifdef REENTRANT
+               sptr = getservbyname_r(serv, "udp", sptrarg, buf, bufsiz);
+#else
+               sptr = getservbyname(serv, "udp");
+#endif /* REENTRANT */
+               if (sptr != NULL) {
+                       rc = getaddrinfo_port(aihead, sptr->s_port, SOCK_DGRAM);
+                       if (rc < 0)
+                               return(EAI_MEMORY);
+                       nfound += rc;
+               }
+       }
+
+       if (nfound == 0) {
+                       /* You could call getservbyname() one more time, with no
+                          protocol specified, but "tcp" and "udp" are all that
+                          are supported today. */
+
+               if (hintsptr->ai_socktype == 0)
+                       return(EAI_NONAME);     /* all calls to getservbyname() failed */
+               else
+                       return(EAI_SERVICE);/* service not supported for socket type */
+       }
+       return(0);
+}
+
+/*
+ * Go through all the addrinfo structures, checking for a match of the
+ * socket type and filling in the socket type, and then the port number
+ * in the corresponding socket address structures.
+ *
+ * The AI_CLONE flag works as follows.  Consider a multihomed host with
+ * two IP addresses and no socket type specified by the caller.  After
+ * the "host" search there are two addrinfo structures, one per IP address.
+ * Assuming a service supported by both TCP and UDP (say the daytime
+ * service) we need to return *four* addrinfo structures:
+ *             IP#1, SOCK_STREAM, TCP port,
+ *             IP#1, SOCK_DGRAM, UDP port,
+ *             IP#2, SOCK_STREAM, TCP port,
+ *             IP#2, SOCK_DGRAM, UDP port.
+ * To do this, when the "host" loop creates an addrinfo structure, if the
+ * caller has not specified a socket type (hints->ai_socktype == 0), the
+ * AI_CLONE flag is set.  When the following function finds an entry like
+ * this it is handled as follows: If the entry's ai_socktype is still 0,
+ * this is the first use of the structure, and the ai_socktype field is set.
+ * But, if the entry's ai_socktype is nonzero, then we clone a new addrinfo
+ * structure and set it's ai_socktype to the new value.  Although we only
+ * need two socket types today (SOCK_STREAM and SOCK_DGRAM) this algorithm
+ * will handle any number.  Also notice that Posix.1g requires all socket
+ * types to be nonzero.
+ */
+
+static int
+getaddrinfo_port(struct addrinfo *aihead, int port, int socktype)
+               /* port must be in network byte order */
+{
+       int                             nfound = 0;
+       struct addrinfo *ai;
+
+       for (ai = aihead; ai != NULL; ai = ai->ai_next) {
+               /*
+                * We set the socket type but not the protocol, because if a
+                * port number is specified, the protocol must be TCP or UDP,
+                * and a protocol of 0 for socket() is fine for TCP and UDP.
+                * The only time a nonzero protocol argument is required by
+                * socket() is for a raw socket, in which case a service will
+                * not be specified to getaddrinfo().
+                */
+
+               if (ai->ai_flags & AI_CLONE) {
+                       if (ai->ai_socktype != 0) {
+                               if ( (ai = getaddrinfo_clone(ai)) == NULL)
+                                       return(-1);     /* tell caller it's a memory allocation error */
+                               /* ai points to newly cloned entry, which is what we want */
+                       }
+               } else if (ai->ai_socktype != socktype)
+                       continue;               /* ignore if mismatch on socket type */
+
+               ai->ai_socktype = socktype;
+
+               switch (ai->ai_family) {
+#ifdef IPV4
+                       case AF_INET:
+                               ((struct sockaddr_in *) ai->ai_addr)->sin_port = port;
+                               nfound++;
+                               break;
+#endif
+#ifdef IPV6
+                       case AF_INET6:
+                               ((struct sockaddr_in6 *) ai->ai_addr)->sin6_port = port;
+                               nfound++;
+                               break;
+#endif
+               }
+       }
+       return(nfound);
+}
+
+/*
+ * Clone a new addrinfo structure from an existing one.
+ */
+
+static struct addrinfo *
+getaddrinfo_clone(struct addrinfo *ai)
+{
+       struct addrinfo *new;
+
+       if ( (new = calloc(1, sizeof(struct addrinfo))) == NULL)
+               return(NULL);
+
+       new->ai_next = ai->ai_next;
+       ai->ai_next = new;
+
+       new->ai_flags = 0;                              /* make sure AI_CLONE is off */
+       new->ai_family = ai->ai_family;
+       new->ai_socktype = ai->ai_socktype;
+       new->ai_protocol = ai->ai_protocol;
+       new->ai_canonname = NULL;
+       new->ai_addrlen = ai->ai_addrlen;
+       if ( (new->ai_addr = malloc(ai->ai_addrlen)) == NULL)
+               return(NULL);
+       memcpy(new->ai_addr, ai->ai_addr, ai->ai_addrlen);
+
+       return(new);
+}
+
+#ifdef LOCAL
+/*
+ * Do everything for a Unix domain socket.
+ * Only one addrinfo{} is returned.
+ */
+
+static int
+addrinfo_local(const char *path, struct addrinfo *hints,
+                          struct addrinfo **result)
+{
+       struct addrinfo         *ai;
+       struct sockaddr_un      *unp;
+
+       if (hints->ai_socktype == 0)
+               return(EAI_SOCKTYPE);   /* we cannot tell socket type from service */
+
+       if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL)
+               return(NULL);
+
+       ai->ai_flags = 0;
+       ai->ai_family = AF_LOCAL;
+       ai->ai_socktype = hints->ai_socktype;
+       ai->ai_protocol = 0;
+
+               /* allocate and fill in a socket address structure */
+       ai->ai_addrlen = sizeof(struct sockaddr_un);
+       if ( (ai->ai_addr = malloc(ai->ai_addrlen)) == NULL)
+               return(EAI_MEMORY);
+       unp = (struct sockaddr_un *) ai->ai_addr;
+       unp->sun_family = AF_UNIX;
+       strncpy(unp->sun_path, path, sizeof(unp->sun_path));
+
+       ai->ai_canonname = NULL;        /* maybe return the i-node number :-) */
+       ai->ai_next = NULL;
+       *result = ai;
+
+       if (hints->ai_flags & AI_PASSIVE)
+               unlink(path);           /* OK if this fails */
+
+       return(0);              /* success */
+}
+#endif /* LOCAL */
+
+void
+freeaddrinfo(struct addrinfo *aihead)
+{
+       struct addrinfo *ai, *ainext;
+
+       for (ai = aihead; ai != NULL; ai = ainext) {
+               if (ai->ai_addr != NULL)
+                       free(ai->ai_addr);              /* the socket address structure */
+               if (ai->ai_canonname != NULL)
+                       free(ai->ai_canonname); /* the canonical name */
+               ainext = ai->ai_next;           /* can't fetch ai_next after free() */
+               free(ai);                                       /* the addrinfo{} itself */
+       }
+}
diff --git a/libfree/getnameinfo.c b/libfree/getnameinfo.c
new file mode 100644 (file)
index 0000000..90c0bef
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1996 W. Richard Stevens.  All rights reserved. 
+ *
+ * Permission to use or modify this software for educational or
+ * for commercial purposes, and without fee, is hereby granted,
+ * provided that the above copyright notice appears in connection
+ * with any and all uses, with clear indication as to any
+ * modifications made.  The author RESERVES the sole rights of
+ * reproduction, publication and distribution and hence permission
+ * to print this source code in any book, reference manual,
+ * magazine, or other type of publication, including any digital
+ * medium, must be granted in writing by W. Richard Stevens.
+ *
+ * The author makes no representations about the suitability of this 
+ * software for any purpose.  It is provided "as is" without express
+ * or implied warranty. 
+ */
+
+/* tabs set for 4 spaces, not 8 */
+#include       <sys/types.h>
+#include       <sys/socket.h>
+#include       <netinet/in.h>
+#include       <netdb.h>               /* hostent{}, servent{}, etc. */
+#include       <string.h>              /* strncpy() */
+
+/* We need a way to determine if the compiling host supports IPv4/IPv6.
+   Cannot test for AF_INET6, as some vendors #define it, even though
+   they don't support it. */
+#ifdef AF_INET
+#define        IPV4    /* this is tested throughout the code that follows */
+#endif
+#ifdef IPV6ADDR_ANY_INIT
+#define        IPV6    /* this is tested throughout the code that follows */
+#endif
+
+/* Define following if the reentrant versions of get{host|serv}byaddr
+   are to be used.
+   Note that getaddrinfo{} must be reentrant if the underlying
+   get{host|serv}byaddr_r functions are provided. */
+/* #define     REENTRANT */
+
+#define        HENTBUFSIZ      8*1024
+
+               /* function prototypes for our own internal functions */
+static int     do_ipv46(char *, size_t, char *, size_t,
+                                        void *, size_t, int, int);
+
+int
+getnameinfo(const struct sockaddr *sa, size_t salen,
+                   char *host, size_t hostlen, char *serv, size_t servlen)
+{
+
+       switch (sa->sa_family) {
+#ifdef IPV4
+       case AF_INET: {
+               struct sockaddr_in      *sain = (struct sockaddr_in *) sa;
+
+               return(do_ipv46(host, hostlen, serv, servlen,
+                                        &sain->sin_addr, sizeof(struct in_addr), AF_INET,
+                                        sain->sin_port));
+       }
+#endif /* IPV4 */
+
+#ifdef IPV6
+       case AF_INET6: {
+               struct sockaddr_in6     *sain = (struct sockaddr_in6 *) sa;
+
+               return(do_ipv46(host, hostlen, serv, servlen,
+                                        &sain->sin6_addr, sizeof(struct in6_addr), AF_INET6,
+                                        sain->sin6_port));
+       }
+#endif /* IPV6 */
+
+       default:
+               return(1);
+       }
+}
+
+/*
+ * Handle either an IPv4 or an IPv6 address and port.
+ */
+
+static int
+do_ipv46(char *host, size_t hostlen, char *serv, size_t servlen,
+                void *aptr, size_t alen, int family, int port)
+{
+       struct hostent          *hptr, hent;
+       struct servent          *sptr, sent;
+       char                            hentbuf[HENTBUFSIZ];
+
+       if (hostlen > 0) {
+#ifdef REENTRANT
+               hptr = gethostbyaddr_r(aptr, alen, family,
+                                                          &hent, hentbuf, HENTBUFSIZ, &h_errno);
+#else
+               hptr = gethostbyaddr(aptr, alen, family);
+#endif
+               if (hptr != NULL && hptr->h_name != NULL)
+                       strncpy(host, hptr->h_name, hostlen);
+               else
+                       return(1);
+       }
+
+       if (servlen > 0) {
+               /*
+                * Notice that we do not have enough information to pass a
+                * "protocol" argument to getservbyport(), so the assumption
+                * is that the protocol (TCP or UDP) does not matter.
+                */
+#ifdef REENTRANT
+               sptr = getservbyport_r(port, NULL,
+                                                          &sent, hentbuf, HENTBUFSIZ);
+#else
+               sptr = getservbyport(port, NULL);
+#endif
+               if (sptr != NULL && sptr->s_name != NULL)
+                       strncpy(serv, sptr->s_name, servlen);
+               else
+                       return(1);
+       }
+       return(0);
+}
diff --git a/libfree/in_cksum.c b/libfree/in_cksum.c
new file mode 100644 (file)
index 0000000..1e42638
--- /dev/null
@@ -0,0 +1,32 @@
+#include "unp.h"
+
+uint16_t
+in_cksum(uint16_t *addr, int len)
+{
+       int                             nleft = len;
+       uint32_t                sum = 0;
+       uint16_t                *w = addr;
+       uint16_t                answer = 0;
+
+       /*
+        * Our algorithm is simple, using a 32 bit accumulator (sum), we add
+        * sequential 16 bit words to it, and at the end, fold back all the
+        * carry bits from the top 16 bits into the lower 16 bits.
+        */
+       while (nleft > 1)  {
+               sum += *w++;
+               nleft -= 2;
+       }
+
+               /* 4mop up an odd byte, if necessary */
+       if (nleft == 1) {
+               *(unsigned char *)(&answer) = *(unsigned char *)w ;
+               sum += answer;
+       }
+
+               /* 4add back carry outs from top 16 bits to low 16 bits */
+       sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
+       sum += (sum >> 16);                     /* add carry */
+       answer = ~sum;                          /* truncate to 16 bits */
+       return(answer);
+}
diff --git a/libfree/inet_aton.c b/libfree/inet_aton.c
new file mode 100644 (file)
index 0000000..abe19c1
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ *  inet_aton.c,v 1.3 1993/05/19 03:39:32 jch Exp
+ */
+
+/* Gated Release 3.5 */
+/* Copyright (c) 1990,1991,1992,1993,1994,1995 by Cornell University.  All */
+/* rights reserved.  Refer to Particulars and other Copyright notices at */
+/* the end of this file.  */
+/*  */
+
+#include       <sys/types.h>
+#include       <netinet/in.h>
+
+/* 
+ * Check whether "cp" is a valid ascii representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ */
+
+int
+inet_aton(const char *cp, struct in_addr *ap)
+{
+    int dots = 0;
+    register u_long acc = 0, addr = 0;
+
+    do {
+       register char cc = *cp;
+
+       switch (cc) {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+           acc = acc * 10 + (cc - '0');
+           break;
+
+       case '.':
+           if (++dots > 3) {
+               return 0;
+           }
+           /* Fall through */
+
+       case '\0':
+           if (acc > 255) {
+               return 0;
+           }
+           addr = addr << 8 | acc;
+           acc = 0;
+           break;
+
+       default:
+           return 0;
+       }
+    } while (*cp++) ;
+
+    /* Normalize the address */
+    if (dots < 3) {
+       addr <<= 8 * (3 - dots) ;
+    }
+
+    /* Store it if requested */
+    if (ap) {
+       ap->s_addr = htonl(addr);
+    }
+
+    return 1;    
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * 
+ *     GateD, Release 3.5
+ * 
+ *     Copyright (c) 1990,1991,1992,1993,1994,1995 by Cornell University.
+ *         All rights reserved.
+ * 
+ *     THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY
+ *     EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ *     LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ *     AND FITNESS FOR A PARTICULAR PURPOSE.
+ * 
+ *     Royalty-free licenses to redistribute GateD Release
+ *     3 in whole or in part may be obtained by writing to:
+ * 
+ *         GateDaemon Project
+ *         Information Technologies/Network Resources
+ *         200 CCC
+ *         Cornell University
+ *         Ithaca, NY  14853-2601  USA
+ * 
+ *     GateD is based on Kirton's EGP, UC Berkeley's routing
+ *     daemon   (routed), and DCN's HELLO routing Protocol.
+ *     Development of GateD has been supported in part by the
+ *     National Science Foundation.
+ * 
+ *     Please forward bug fixes, enhancements and questions to the
+ *     gated mailing list: gated-people@gated.cornell.edu.
+ * 
+ * ------------------------------------------------------------------------
+ * 
+ *       Portions of this software may fall under the following
+ *       copyrights:
+ * 
+ *     Copyright (c) 1988 Regents of the University of California.
+ *     All rights reserved.
+ * 
+ *     Redistribution and use in source and binary forms are
+ *     permitted provided that the above copyright notice and
+ *     this paragraph are duplicated in all such forms and that
+ *     any documentation, advertising materials, and other
+ *     materials related to such distribution and use
+ *     acknowledge that the software was developed by the
+ *     University of California, Berkeley.  The name of the
+ *     University may not be used to endorse or promote
+ *     products derived from this software without specific
+ *     prior written permission.  THIS SOFTWARE IS PROVIDED
+ *     ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+ *     INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
diff --git a/libfree/inet_ntop.c b/libfree/inet_ntop.c
new file mode 100644 (file)
index 0000000..192cdbd
--- /dev/null
@@ -0,0 +1,198 @@
+/* This is from the BIND 4.9.4 release, modified to compile by itself */
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: inet_ntop.c,v 1.1.1.1 2002/11/14 03:33:35 fenner Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#define        IN6ADDRSZ       16
+#define        INT16SZ          2
+
+#ifndef        AF_INET6
+#define        AF_INET6        AF_MAX+1        /* just to let this compile */
+#endif
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
+static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
+
+/* char *
+ * inet_ntop(af, src, dst, size)
+ *     convert a network format address to presentation format.
+ * return:
+ *     pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ *     Paul Vixie, 1996.
+ */
+const char *
+inet_ntop(af, src, dst, size)
+       int af;
+       const void *src;
+       char *dst;
+       size_t size;
+{
+       switch (af) {
+       case AF_INET:
+               return (inet_ntop4(src, dst, size));
+       case AF_INET6:
+               return (inet_ntop6(src, dst, size));
+       default:
+               errno = EAFNOSUPPORT;
+               return (NULL);
+       }
+       /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ *     format an IPv4 address, more or less like inet_ntoa()
+ * return:
+ *     `dst' (as a const)
+ * notes:
+ *     (1) uses no statics
+ *     (2) takes a u_char* not an in_addr as input
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(src, dst, size)
+       const u_char *src;
+       char *dst;
+       size_t size;
+{
+       static const char fmt[] = "%u.%u.%u.%u";
+       char tmp[sizeof "255.255.255.255"];
+
+       sprintf(tmp, fmt, src[0], src[1], src[2], src[3]);
+       if (strlen(tmp) > size) {
+               errno = ENOSPC;
+               return (NULL);
+       }
+       strcpy(dst, tmp);
+       return (dst);
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ *     convert IPv6 binary address into presentation (printable) format
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop6(src, dst, size)
+       const u_char *src;
+       char *dst;
+       size_t size;
+{
+       /*
+        * Note that int32_t and int16_t need only be "at least" large enough
+        * to contain a value of the specified size.  On some systems, like
+        * Crays, there is no such thing as an integer variable with 16 bits.
+        * Keep this in mind if you think this function should have been coded
+        * to use pointer overlays.  All the world's not a VAX.
+        */
+       char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+       struct { int base, len; } best, cur;
+       u_int words[IN6ADDRSZ / INT16SZ];
+       int i;
+
+       /*
+        * Preprocess:
+        *      Copy the input (bytewise) array into a wordwise array.
+        *      Find the longest run of 0x00's in src[] for :: shorthanding.
+        */
+       memset(words, 0, sizeof words);
+       for (i = 0; i < IN6ADDRSZ; i++)
+               words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+       best.base = -1;
+       cur.base = -1;
+       for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+               if (words[i] == 0) {
+                       if (cur.base == -1)
+                               cur.base = i, cur.len = 1;
+                       else
+                               cur.len++;
+               } else {
+                       if (cur.base != -1) {
+                               if (best.base == -1 || cur.len > best.len)
+                                       best = cur;
+                               cur.base = -1;
+                       }
+               }
+       }
+       if (cur.base != -1) {
+               if (best.base == -1 || cur.len > best.len)
+                       best = cur;
+       }
+       if (best.base != -1 && best.len < 2)
+               best.base = -1;
+
+       /*
+        * Format the result.
+        */
+       tp = tmp;
+       for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+               /* Are we inside the best run of 0x00's? */
+               if (best.base != -1 && i >= best.base &&
+                   i < (best.base + best.len)) {
+                       if (i == best.base)
+                               *tp++ = ':';
+                       continue;
+               }
+               /* Are we following an initial run of 0x00s or any real hex? */
+               if (i != 0)
+                       *tp++ = ':';
+               /* Is this address an encapsulated IPv4? */
+               if (i == 6 && best.base == 0 &&
+                   (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+                       if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
+                               return (NULL);
+                       tp += strlen(tp);
+                       break;
+               }
+               sprintf(tp, "%x", words[i]);
+               tp += strlen(tp);
+       }
+       /* Was it a trailing run of 0x00's? */
+       if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
+               *tp++ = ':';
+       *tp++ = '\0';
+
+       /*
+        * Check for overflow, copy, and we're done.
+        */
+       if ((tp - tmp) > size) {
+               errno = ENOSPC;
+               return (NULL);
+       }
+       strcpy(dst, tmp);
+       return (dst);
+}
diff --git a/libfree/inet_ntop_ipv4.c b/libfree/inet_ntop_ipv4.c
new file mode 100644 (file)
index 0000000..6aaae4d
--- /dev/null
@@ -0,0 +1,31 @@
+#include       <sys/types.h>
+#include       <sys/socket.h>
+#include       <errno.h>
+#include       <stdio.h>
+
+#ifndef        INET_ADDRSTRLEN
+#define        INET_ADDRSTRLEN         16
+#endif
+
+/* include inet_ntop */
+const char *
+inet_ntop(int family, const void *addrptr, char *strptr, size_t len)
+{
+       const u_char *p = (const u_char *) addrptr;
+
+       if (family == AF_INET) {
+               char    temp[INET_ADDRSTRLEN];
+
+               snprintf(temp, sizeof(temp), "%d.%d.%d.%d",
+                                p[0], p[1], p[2], p[3]);
+               if (strlen(temp) >= len) {
+                       errno = ENOSPC;
+                       return (NULL);
+               }
+               strcpy(strptr, temp);
+               return (strptr);
+       }
+       errno = EAFNOSUPPORT;
+       return (NULL);
+}
+/* end inet_ntop */
diff --git a/libfree/inet_ntop_ipv4.lc b/libfree/inet_ntop_ipv4.lc
new file mode 100644 (file)
index 0000000..d150b39
--- /dev/null
@@ -0,0 +1,30 @@
+#include    <sys/types.h>##  1 ##src/libfree/inet_ntop_ipv4.c##
+#include    <sys/socket.h>##  2 ##src/libfree/inet_ntop_ipv4.c##
+#include    <errno.h>##  3 ##src/libfree/inet_ntop_ipv4.c##
+#include    <stdio.h>##  4 ##src/libfree/inet_ntop_ipv4.c##
+
+#ifndef INET_ADDRSTRLEN##  5 ##src/libfree/inet_ntop_ipv4.c##
+#define INET_ADDRSTRLEN     16##  6 ##src/libfree/inet_ntop_ipv4.c##
+#endif##  7 ##src/libfree/inet_ntop_ipv4.c##
+
+/* include inet_ntop */
+const char *##  8 ##src/libfree/inet_ntop_ipv4.c##
+inet_ntop(int family, const void *addrptr, char *strptr, size_t len)##  9 ##src/libfree/inet_ntop_ipv4.c##
+{## 10 ##src/libfree/inet_ntop_ipv4.c##
+    const u_char *p = (const u_char *) addrptr;## 11 ##src/libfree/inet_ntop_ipv4.c##
+
+    if (family == AF_INET) {## 12 ##src/libfree/inet_ntop_ipv4.c##
+        char    temp[INET_ADDRSTRLEN];## 13 ##src/libfree/inet_ntop_ipv4.c##
+
+        snprintf(temp, sizeof(temp), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);## 14 ##src/libfree/inet_ntop_ipv4.c##
+        if (strlen(temp) >= len) {## 15 ##src/libfree/inet_ntop_ipv4.c##
+            errno = ENOSPC;## 16 ##src/libfree/inet_ntop_ipv4.c##
+            return (NULL);## 17 ##src/libfree/inet_ntop_ipv4.c##
+        }## 18 ##src/libfree/inet_ntop_ipv4.c##
+        strcpy(strptr, temp);## 19 ##src/libfree/inet_ntop_ipv4.c##
+        return (strptr);## 20 ##src/libfree/inet_ntop_ipv4.c##
+    }## 21 ##src/libfree/inet_ntop_ipv4.c##
+    errno = EAFNOSUPPORT;## 22 ##src/libfree/inet_ntop_ipv4.c##
+    return (NULL);## 23 ##src/libfree/inet_ntop_ipv4.c##
+}## 24 ##src/libfree/inet_ntop_ipv4.c##
+/* end inet_ntop */
diff --git a/libfree/inet_pton.c b/libfree/inet_pton.c
new file mode 100644 (file)
index 0000000..7f37018
--- /dev/null
@@ -0,0 +1,224 @@
+/* This is from the BIND 4.9.4 release, modified to compile by itself */
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: inet_pton.c,v 1.1.1.1 2002/11/14 03:33:35 fenner Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <errno.h>
+
+#define        IN6ADDRSZ       16
+#define        INADDRSZ         4
+#define        INT16SZ          2
+
+#ifndef        AF_INET6
+#define        AF_INET6        AF_MAX+1        /* just to let this compile */
+#endif
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int     inet_pton4(const char *src, u_char *dst);
+static int     inet_pton6(const char *src, u_char *dst);
+
+/* int
+ * inet_pton(af, src, dst)
+ *     convert from presentation format (which usually means ASCII printable)
+ *     to network format (which is usually some kind of binary format).
+ * return:
+ *     1 if the address was valid for the specified address family
+ *     0 if the address wasn't valid (`dst' is untouched in this case)
+ *     -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ *     Paul Vixie, 1996.
+ */
+int
+inet_pton(af, src, dst)
+       int af;
+       const char *src;
+       void *dst;
+{
+       switch (af) {
+       case AF_INET:
+               return (inet_pton4(src, dst));
+       case AF_INET6:
+               return (inet_pton6(src, dst));
+       default:
+               errno = EAFNOSUPPORT;
+               return (-1);
+       }
+       /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *     like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ *     1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *     does not touch `dst' unless it's returning 1.
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static int
+inet_pton4(src, dst)
+       const char *src;
+       u_char *dst;
+{
+       static const char digits[] = "0123456789";
+       int saw_digit, octets, ch;
+       u_char tmp[INADDRSZ], *tp;
+
+       saw_digit = 0;
+       octets = 0;
+       *(tp = tmp) = 0;
+       while ((ch = *src++) != '\0') {
+               const char *pch;
+
+               if ((pch = strchr(digits, ch)) != NULL) {
+                       u_int new = *tp * 10 + (pch - digits);
+
+                       if (new > 255)
+                               return (0);
+                       *tp = new;
+                       if (! saw_digit) {
+                               if (++octets > 4)
+                                       return (0);
+                               saw_digit = 1;
+                       }
+               } else if (ch == '.' && saw_digit) {
+                       if (octets == 4)
+                               return (0);
+                       *++tp = 0;
+                       saw_digit = 0;
+               } else
+                       return (0);
+       }
+       if (octets < 4)
+               return (0);
+       /* bcopy(tmp, dst, INADDRSZ); */
+       memcpy(dst, tmp, INADDRSZ);
+       return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ *     convert presentation level address to network order binary form.
+ * return:
+ *     1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ *     (1) does not touch `dst' unless it's returning 1.
+ *     (2) :: in a full address is silently ignored.
+ * credit:
+ *     inspired by Mark Andrews.
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static int
+inet_pton6(src, dst)
+       const char *src;
+       u_char *dst;
+{
+       static const char xdigits_l[] = "0123456789abcdef",
+                         xdigits_u[] = "0123456789ABCDEF";
+       u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+       const char *xdigits, *curtok;
+       int ch, saw_xdigit;
+       u_int val;
+
+       memset((tp = tmp), 0, IN6ADDRSZ);
+       endp = tp + IN6ADDRSZ;
+       colonp = NULL;
+       /* Leading :: requires some special handling. */
+       if (*src == ':')
+               if (*++src != ':')
+                       return (0);
+       curtok = src;
+       saw_xdigit = 0;
+       val = 0;
+       while ((ch = *src++) != '\0') {
+               const char *pch;
+
+               if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+                       pch = strchr((xdigits = xdigits_u), ch);
+               if (pch != NULL) {
+                       val <<= 4;
+                       val |= (pch - xdigits);
+                       if (val > 0xffff)
+                               return (0);
+                       saw_xdigit = 1;
+                       continue;
+               }
+               if (ch == ':') {
+                       curtok = src;
+                       if (!saw_xdigit) {
+                               if (colonp)
+                                       return (0);
+                               colonp = tp;
+                               continue;
+                       }
+                       if (tp + INT16SZ > endp)
+                               return (0);
+                       *tp++ = (u_char) (val >> 8) & 0xff;
+                       *tp++ = (u_char) val & 0xff;
+                       saw_xdigit = 0;
+                       val = 0;
+                       continue;
+               }
+               if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
+                   inet_pton4(curtok, tp) > 0) {
+                       tp += INADDRSZ;
+                       saw_xdigit = 0;
+                       break;  /* '\0' was seen by inet_pton4(). */
+               }
+               return (0);
+       }
+       if (saw_xdigit) {
+               if (tp + INT16SZ > endp)
+                       return (0);
+               *tp++ = (u_char) (val >> 8) & 0xff;
+               *tp++ = (u_char) val & 0xff;
+       }
+       if (colonp != NULL) {
+               /*
+                * Since some memmove()'s erroneously fail to handle
+                * overlapping regions, we'll do the shift by hand.
+                */
+               const int n = tp - colonp;
+               int i;
+
+               for (i = 1; i <= n; i++) {
+                       endp[- i] = colonp[n - i];
+                       colonp[n - i] = 0;
+               }
+               tp = endp;
+       }
+       if (tp != endp)
+               return (0);
+       /* bcopy(tmp, dst, IN6ADDRSZ); */
+       memcpy(dst, tmp, IN6ADDRSZ);
+       return (1);
+}
diff --git a/libfree/inet_pton_ipv4.c b/libfree/inet_pton_ipv4.c
new file mode 100644 (file)
index 0000000..09a7c1e
--- /dev/null
@@ -0,0 +1,28 @@
+#include       <sys/types.h>
+#include       <sys/socket.h>
+#include       <netinet/in.h>
+#include       <arpa/inet.h>
+#include       <errno.h>
+#include       <string.h>
+
+/* Delete following line if your system's headers already DefinE this
+   function prototype */
+int             inet_aton(const char *, struct in_addr *);
+
+/* include inet_pton */
+int
+inet_pton(int family, const char *strptr, void *addrptr)
+{
+    if (family == AF_INET) {
+       struct in_addr  in_val;
+
+        if (inet_aton(strptr, &in_val)) {
+            memcpy(addrptr, &in_val, sizeof(struct in_addr));
+            return (1);
+        }
+               return(0);
+    }
+       errno = EAFNOSUPPORT;
+    return (-1);
+}
+/* end inet_pton */
diff --git a/libfree/inet_pton_ipv4.lc b/libfree/inet_pton_ipv4.lc
new file mode 100644 (file)
index 0000000..93fe100
--- /dev/null
@@ -0,0 +1,28 @@
+#include    <sys/types.h>##  1 ##src/libfree/inet_pton_ipv4.c##
+#include    <sys/socket.h>##  2 ##src/libfree/inet_pton_ipv4.c##
+#include    <netinet/in.h>##  3 ##src/libfree/inet_pton_ipv4.c##
+#include    <arpa/inet.h>##  4 ##src/libfree/inet_pton_ipv4.c##
+#include    <errno.h>##  5 ##src/libfree/inet_pton_ipv4.c##
+#include    <string.h>##  6 ##src/libfree/inet_pton_ipv4.c##
+
+/* Delete following line if your system's headers already define this##  7 ##src/libfree/inet_pton_ipv4.c##
+   function prototype */##  8 ##src/libfree/inet_pton_ipv4.c##
+int     inet_aton(const char *, struct in_addr *);##  9 ##src/libfree/inet_pton_ipv4.c##
+
+/* include inet_pton */
+int## 10 ##src/libfree/inet_pton_ipv4.c##
+inet_pton(int family, const char *strptr, void *addrptr)## 11 ##src/libfree/inet_pton_ipv4.c##
+{## 12 ##src/libfree/inet_pton_ipv4.c##
+    if (family == AF_INET) {## 13 ##src/libfree/inet_pton_ipv4.c##
+        struct in_addr in_val;## 14 ##src/libfree/inet_pton_ipv4.c##
+
+        if (inet_aton(strptr, &in_val)) {## 15 ##src/libfree/inet_pton_ipv4.c##
+            memcpy(addrptr, &in_val, sizeof(struct in_addr));## 16 ##src/libfree/inet_pton_ipv4.c##
+            return (1);## 17 ##src/libfree/inet_pton_ipv4.c##
+        }## 18 ##src/libfree/inet_pton_ipv4.c##
+        return (0);## 19 ##src/libfree/inet_pton_ipv4.c##
+    }## 20 ##src/libfree/inet_pton_ipv4.c##
+    errno = EAFNOSUPPORT;## 21 ##src/libfree/inet_pton_ipv4.c##
+    return (-1);## 22 ##src/libfree/inet_pton_ipv4.c##
+}## 23 ##src/libfree/inet_pton_ipv4.c##
+/* end inet_pton */
diff --git a/libfree/test_ascii2addr.c b/libfree/test_ascii2addr.c
new file mode 100644 (file)
index 0000000..331aef4
--- /dev/null
@@ -0,0 +1,15 @@
+#include       <sys/types.h>
+#include       <sys/socket.h>
+#include       <netinet/in.h>
+#include       <netdb.h>
+#include       <stdio.h>
+
+main()
+{
+       struct in6_addr foo;
+
+       printf("ascii2addr returned %d\n",
+               ascii2addr(AF_INET6, "::140.252.13.36", &foo));
+
+       exit(0);
+}
diff --git a/libfree/test_getservbyname_r.c b/libfree/test_getservbyname_r.c
new file mode 100644 (file)
index 0000000..5f0483b
--- /dev/null
@@ -0,0 +1,21 @@
+#include       <netdb.h>
+
+main()
+{
+       char            buf[8192];
+       struct servent  sent, *sptr;
+
+       sptr = getservbyname_r("tftp", "tcp", &sent, buf, sizeof(buf));
+       printf("TCP, sptr = %p\n", sptr);
+
+       sptr = getservbyname_r("tftp", "udp", &sent, buf, sizeof(buf));
+       printf("UDP, sptr = %p\n", sptr);
+
+       sptr = getservbyname_r("tftp", "tcp", &sent, buf, sizeof(buf));
+       printf("TCP, sptr = %p\n", sptr);
+
+       sptr = getservbyname_r("tftp", "udp", &sent, buf, sizeof(buf));
+       printf("UDP, sptr = %p\n", sptr);
+
+       exit(0);
+}
diff --git a/libfree/test_inet_pton.c b/libfree/test_inet_pton.c
new file mode 100644 (file)
index 0000000..1b22adf
--- /dev/null
@@ -0,0 +1,42 @@
+#include       "../lib/unp.h"
+
+#ifndef        AF_INET6
+#define        AF_INET6        AF_MAX+1        /* just to let this compile */
+#endif
+
+int            inet_pton(int, const char *, void *);
+
+int
+main(int argc, char **argv)
+{
+       int             i;
+       char    buff[100];
+
+       /*
+        * Make certain that we can test the difference between 0.0.0.0
+        * being acceptable for AF_INET (but not acceptable for AF_INET6)
+        * and 0::0 being OK for AF_INET6 (but not OK for AF_INET).
+        * This way a server can be coded as protocol independent (IPv4 or
+        * IPv6) but let the user specify the local IP address as either
+        * 0.0.0.0 or 0::0 as an indirect way of telling the server when
+        * it starts, which protocol to use (but still allowing the server
+        * to bind the wildcard address).
+        */
+
+       if ( (i = inet_pton(AF_INET, "0.0.0.0", buff)) != 1)    /* should be OK */
+               printf("AF_INET, 0.0.0.0 returned: %d\n", i);
+       if ( (i = inet_pton(AF_INET6, "0.0.0.0", buff)) != 0)
+               printf("AF_INET6, 0.0.0.0 returned: %d\n", i);
+
+       if ( (i = inet_pton(AF_INET6, "0::0", buff)) != 1)              /* should be OK */
+               printf("AF_INET6, 0::0 returned: %d\n", i);
+       if ( (i = inet_pton(AF_INET, "0::0", buff)) != 0)
+               printf("AF_INET, 0::0 returned: %d\n", i);
+
+       printf("inet_pton(AF_INET6, \"1.2.3.4\", buff) returns %d\n",
+                   inet_pton(AF_INET6,  "1.2.3.4", buff));
+       printf("inet_pton(AF_INET6, \"::1.2.3.4\", buff) returns %d\n",
+                   inet_pton(AF_INET6,  "::1.2.3.4", buff));
+
+       exit(0);
+}
diff --git a/libgai/Makefile b/libgai/Makefile
new file mode 100644 (file)
index 0000000..e6362f1
--- /dev/null
@@ -0,0 +1,22 @@
+include ../Make.defines
+
+# Note: In the source code in this directory I #ifdef the constants
+# IPv4, IPv6 (both lowercase "v"), and UNIXdomain.  This is instead of
+# the all-uppercase constants so that these #ifdef/#endif lines do not
+# appear in the book (too much clutter, given the amount of conditional
+# testing for all the code in this directory).
+
+all:   ${LIBGAI_OBJS}
+               ar rv ${LIBUNP_NAME} $?
+               ${RANLIB} ${LIBUNP_NAME}
+
+PROGS = testga test1
+
+testga:        testga.o
+               ${CC} ${CFLAGS} -o $@ testga.o ${LIBS}
+
+test1: test1.o
+               ${CC} ${CFLAGS} -o $@ test1.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/libgai/addrinfo.h b/libgai/addrinfo.h
new file mode 100644 (file)
index 0000000..7cef135
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef        __addrinfo_h
+#define        __addrinfo_h
+
+/*
+ * Everything here really belongs in <netdb.h>.
+ * These defines are separate for now, to avoid having to modify the
+ * system's header.
+ */
+
+struct addrinfo {
+  int          ai_flags;                       /* AI_PASSIVE, AI_CANONNAME */
+  int          ai_family;                      /* PF_xxx */
+  int          ai_socktype;            /* SOCK_xxx */
+  int          ai_protocol;            /* IPPROTO_xxx for IPv4 and IPv6 */
+  size_t       ai_addrlen;                     /* length of ai_addr */
+  char         *ai_canonname;          /* canonical name for host */
+  struct sockaddr      *ai_addr;       /* binary address */
+  struct addrinfo      *ai_next;       /* next structure in linked list */
+};
+
+                       /* following for getaddrinfo() */
+#define        AI_PASSIVE               1      /* socket is intended for bind() + listen() */
+#define        AI_CANONNAME     2      /* return canonical name */
+
+                       /* following for getnameinfo() */
+#define        NI_MAXHOST        1025  /* max hostname returned */
+#define        NI_MAXSERV          32  /* max service name returned */
+
+#define        NI_NOFQDN            1  /* do not return FQDN */
+#define        NI_NUMERICHOST   2      /* return numeric form of hostname */
+#define        NI_NAMEREQD          4  /* return error if hostname not found */
+#define        NI_NUMERICSERV   8      /* return numeric form of service name */
+#define        NI_DGRAM            16  /* datagram service for getservbyname() */
+
+                       /* error returns */
+#define        EAI_ADDRFAMILY   1      /* address family for host not supported */
+#define        EAI_AGAIN                2      /* temporary failure in name resolution */
+#define        EAI_BADFLAGS     3      /* invalid value for ai_flags */
+#define        EAI_FAIL                 4      /* non-recoverable failure in name resolution */
+#define        EAI_FAMILY               5      /* ai_family not supported */
+#define        EAI_MEMORY               6      /* memory allocation failure */
+#define        EAI_NODATA               7      /* no address associated with host */
+#define        EAI_NONAME               8      /* host nor service provided, or not known */
+#define        EAI_SERVICE              9      /* service not supported for ai_socktype */
+#define        EAI_SOCKTYPE    10      /* ai_socktype not supported */
+#define        EAI_SYSTEM              11      /* system error returned in errno */
+
+#endif /* __addrinfo_h */
diff --git a/libgai/freeaddrinfo.c b/libgai/freeaddrinfo.c
new file mode 100644 (file)
index 0000000..c8d4c8b
--- /dev/null
@@ -0,0 +1,20 @@
+#include       "gai_hdr.h"
+
+/* include freeaddrinfo */
+void
+freeaddrinfo(struct addrinfo *aihead)
+{
+       struct addrinfo *ai, *ainext;
+
+       for (ai = aihead; ai != NULL; ai = ainext) {
+               if (ai->ai_addr != NULL)
+                       free(ai->ai_addr);              /* socket address structure */
+
+               if (ai->ai_canonname != NULL)
+                       free(ai->ai_canonname);
+
+               ainext = ai->ai_next;   /* can't fetch ai_next after free() */
+               free(ai);                               /* the addrinfo{} itself */
+       }
+}
+/* end freeaddrinfo */
diff --git a/libgai/ga_aistruct.c b/libgai/ga_aistruct.c
new file mode 100644 (file)
index 0000000..8abc06a
--- /dev/null
@@ -0,0 +1,89 @@
+#include       "gai_hdr.h"
+
+/*
+ * Create and fill in an addrinfo{}.
+ */
+
+/* include ga_aistruct1 */
+int
+ga_aistruct(struct addrinfo ***paipnext, const struct addrinfo *hintsp,
+                       const void *addr, int family)
+{
+       struct addrinfo *ai;
+
+       if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL)
+               return(EAI_MEMORY);
+       ai->ai_next = NULL;
+       ai->ai_canonname = NULL;
+       **paipnext = ai;
+       *paipnext = &ai->ai_next;
+
+       if ( (ai->ai_socktype = hintsp->ai_socktype) == 0)
+               ai->ai_flags |= AI_CLONE;
+
+       ai->ai_protocol = hintsp->ai_protocol;
+/* end ga_aistruct1 */
+       
+/* include ga_aistruct2 */
+       switch ((ai->ai_family = family)) {
+#ifdef IPv4
+               case AF_INET: {
+                       struct sockaddr_in      *sinptr;
+
+                               /* 4allocate sockaddr_in{} and fill in all but port */
+                       if ( (sinptr = calloc(1, sizeof(struct sockaddr_in))) == NULL)
+                               return(EAI_MEMORY);
+#ifdef HAVE_SOCKADDR_SA_LEN
+                       sinptr->sin_len = sizeof(struct sockaddr_in);
+#endif
+                       sinptr->sin_family = AF_INET;
+                       memcpy(&sinptr->sin_addr, addr, sizeof(struct in_addr));
+                       ai->ai_addr = (struct sockaddr *) sinptr;
+                       ai->ai_addrlen = sizeof(struct sockaddr_in);
+                       break;
+               }
+#endif /* IPV4 */
+#ifdef IPv6
+               case AF_INET6: {
+                       struct sockaddr_in6     *sin6ptr;
+
+                               /* 4allocate sockaddr_in6{} and fill in all but port */
+                       if ( (sin6ptr = calloc(1, sizeof(struct sockaddr_in6))) == NULL)
+                               return(EAI_MEMORY);
+#ifdef HAVE_SOCKADDR_SA_LEN
+                       sin6ptr->sin6_len = sizeof(struct sockaddr_in6);
+#endif
+                       sin6ptr->sin6_family = AF_INET6;
+                       memcpy(&sin6ptr->sin6_addr, addr, sizeof(struct in6_addr));
+                       ai->ai_addr = (struct sockaddr *) sin6ptr;
+                       ai->ai_addrlen = sizeof(struct sockaddr_in6);
+                       break;
+               }
+#endif /* IPV6 */
+#ifdef UNIXdomain
+               case AF_LOCAL: {
+                       struct sockaddr_un      *unp;
+
+                               /* 4allocate sockaddr_un{} and fill in */
+/* *INDENT-OFF* */
+                       if (strlen(addr) >= sizeof(unp->sun_path))
+                               return(EAI_SERVICE);
+                       if ( (unp = calloc(1, sizeof(struct sockaddr_un))) == NULL)
+                               return(EAI_MEMORY);
+/* *INDENT-ON* */
+                       unp->sun_family = AF_LOCAL;
+                       strcpy(unp->sun_path, addr);
+#ifdef HAVE_SOCKADDR_SA_LEN
+                       unp->sun_len = SUN_LEN(unp);
+#endif
+                       ai->ai_addr = (struct sockaddr *) unp;
+                       ai->ai_addrlen = sizeof(struct sockaddr_un);
+                       if (hintsp->ai_flags & AI_PASSIVE)
+                               unlink(unp->sun_path);  /* OK if this fails */
+                       break;
+               }
+#endif /* UNIXDOMAIN */
+       }
+       return(0);
+}
+/* end ga_aistruct2 */
diff --git a/libgai/ga_aistruct.lc b/libgai/ga_aistruct.lc
new file mode 100644 (file)
index 0000000..4de057e
--- /dev/null
@@ -0,0 +1,81 @@
+#include    "gai_hdr.h"##  1 ##src/libgai/ga_aistruct.c##
+
+/*##  2 ##src/libgai/ga_aistruct.c##
+ * Create and fill in an addrinfo{}.##  3 ##src/libgai/ga_aistruct.c##
+ */##  4 ##src/libgai/ga_aistruct.c##
+
+/* include ga_aistruct1 */
+int##  5 ##src/libgai/ga_aistruct.c##
+ga_aistruct(struct addrinfo ***paipnext, const struct addrinfo *hintsp,##  6 ##src/libgai/ga_aistruct.c##
+            const void *addr, int family)##  7 ##src/libgai/ga_aistruct.c##
+{##  8 ##src/libgai/ga_aistruct.c##
+    struct addrinfo *ai;##  9 ##src/libgai/ga_aistruct.c##
+
+    if ((ai = calloc(1, sizeof(struct addrinfo))) == NULL)## 10 ##src/libgai/ga_aistruct.c##
+        return (EAI_MEMORY);## 11 ##src/libgai/ga_aistruct.c##
+    ai->ai_next = NULL;## 12 ##src/libgai/ga_aistruct.c##
+    ai->ai_canonname = NULL;## 13 ##src/libgai/ga_aistruct.c##
+    **paipnext = ai;## 14 ##src/libgai/ga_aistruct.c##
+    *paipnext = &ai->ai_next;## 15 ##src/libgai/ga_aistruct.c##
+
+    if ((ai->ai_socktype = hintsp->ai_socktype) == 0)## 16 ##src/libgai/ga_aistruct.c##
+        ai->ai_flags |= AI_CLONE;## 17 ##src/libgai/ga_aistruct.c##
+
+    ai->ai_protocol = hintsp->ai_protocol;## 18 ##src/libgai/ga_aistruct.c##
+/* end ga_aistruct1 */
+
+/* include ga_aistruct2 */
+    switch ((ai->ai_family = family)) {## 19 ##src/libgai/ga_aistruct.c##
+    case AF_INET:{## 20 ##src/libgai/ga_aistruct.c##
+            struct sockaddr_in *sinptr;## 21 ##src/libgai/ga_aistruct.c##
+
+            /* 4allocate sockaddr_in{} and fill in all but port */## 22 ##src/libgai/ga_aistruct.c##
+            if ((sinptr = calloc(1, sizeof(struct sockaddr_in))) == NULL)## 23 ##src/libgai/ga_aistruct.c##
+                return (EAI_MEMORY);## 24 ##src/libgai/ga_aistruct.c##
+#ifdef  HAVE_SOCKADDR_SA_LEN## 25 ##src/libgai/ga_aistruct.c##
+            sinptr->sin_len = sizeof(struct sockaddr_in);## 26 ##src/libgai/ga_aistruct.c##
+#endif## 27 ##src/libgai/ga_aistruct.c##
+            sinptr->sin_family = AF_INET;## 28 ##src/libgai/ga_aistruct.c##
+            memcpy(&sinptr->sin_addr, addr, sizeof(struct in_addr));## 29 ##src/libgai/ga_aistruct.c##
+            ai->ai_addr = (struct sockaddr *) sinptr;## 30 ##src/libgai/ga_aistruct.c##
+            ai->ai_addrlen = sizeof(struct sockaddr_in);## 31 ##src/libgai/ga_aistruct.c##
+            break;## 32 ##src/libgai/ga_aistruct.c##
+        }## 33 ##src/libgai/ga_aistruct.c##
+    case AF_INET6:{## 34 ##src/libgai/ga_aistruct.c##
+            struct sockaddr_in6 *sin6ptr;## 35 ##src/libgai/ga_aistruct.c##
+
+            /* 4allocate sockaddr_in6{} and fill in all but port */## 36 ##src/libgai/ga_aistruct.c##
+            if ((sin6ptr = calloc(1, sizeof(struct sockaddr_in6))) == NULL)## 37 ##src/libgai/ga_aistruct.c##
+                return (EAI_MEMORY);## 38 ##src/libgai/ga_aistruct.c##
+#ifdef  HAVE_SOCKADDR_SA_LEN## 39 ##src/libgai/ga_aistruct.c##
+            sin6ptr->sin6_len = sizeof(struct sockaddr_in6);## 40 ##src/libgai/ga_aistruct.c##
+#endif## 41 ##src/libgai/ga_aistruct.c##
+            sin6ptr->sin6_family = AF_INET6;## 42 ##src/libgai/ga_aistruct.c##
+            memcpy(&sin6ptr->sin6_addr, addr, sizeof(struct in6_addr));## 43 ##src/libgai/ga_aistruct.c##
+            ai->ai_addr = (struct sockaddr *) sin6ptr;## 44 ##src/libgai/ga_aistruct.c##
+            ai->ai_addrlen = sizeof(struct sockaddr_in6);## 45 ##src/libgai/ga_aistruct.c##
+            break;## 46 ##src/libgai/ga_aistruct.c##
+        }## 47 ##src/libgai/ga_aistruct.c##
+    case AF_LOCAL:{## 48 ##src/libgai/ga_aistruct.c##
+            struct sockaddr_un *unp;## 49 ##src/libgai/ga_aistruct.c##
+
+            /* 4allocate sockaddr_un{} and fill in */## 50 ##src/libgai/ga_aistruct.c##
+            if (strlen(addr) >= sizeof(unp->sun_path))## 51 ##src/libgai/ga_aistruct.c##
+                return(EAI_SERVICE);## 52 ##src/libgai/ga_aistruct.c##
+            if ( (unp = calloc(1, sizeof(struct sockaddr_un))) == NULL)## 53 ##src/libgai/ga_aistruct.c##
+                return(EAI_MEMORY);## 54 ##src/libgai/ga_aistruct.c##
+            unp->sun_family = AF_LOCAL;## 55 ##src/libgai/ga_aistruct.c##
+            strcpy(unp->sun_path, addr);## 56 ##src/libgai/ga_aistruct.c##
+#ifdef  HAVE_SOCKADDR_SA_LEN## 57 ##src/libgai/ga_aistruct.c##
+            unp->sun_len = SUN_LEN(unp);## 58 ##src/libgai/ga_aistruct.c##
+#endif## 59 ##src/libgai/ga_aistruct.c##
+            ai->ai_addr = (struct sockaddr *) unp;## 60 ##src/libgai/ga_aistruct.c##
+            ai->ai_addrlen = sizeof(struct sockaddr_un);## 61 ##src/libgai/ga_aistruct.c##
+            if (hintsp->ai_flags & AI_PASSIVE)## 62 ##src/libgai/ga_aistruct.c##
+                unlink(unp->sun_path);  /* OK if this fails */## 63 ##src/libgai/ga_aistruct.c##
+            break;## 64 ##src/libgai/ga_aistruct.c##
+        }## 65 ##src/libgai/ga_aistruct.c##
+    }## 66 ##src/libgai/ga_aistruct.c##
+    return (0);## 67 ##src/libgai/ga_aistruct.c##
+}## 68 ##src/libgai/ga_aistruct.c##
+/* end ga_aistruct2 */
diff --git a/libgai/ga_clone.c b/libgai/ga_clone.c
new file mode 100644 (file)
index 0000000..b764497
--- /dev/null
@@ -0,0 +1,31 @@
+#include       "gai_hdr.h"
+
+/*
+ * Clone a new addrinfo structure from an existing one.
+ */
+
+/* include ga_clone */
+struct addrinfo *
+ga_clone(struct addrinfo *ai)
+{
+       struct addrinfo *new;
+
+       if ( (new = calloc(1, sizeof(struct addrinfo))) == NULL)
+               return(NULL);
+
+       new->ai_next = ai->ai_next;
+       ai->ai_next = new;
+
+       new->ai_flags = 0;                              /* make sure AI_CLONE is off */
+       new->ai_family = ai->ai_family;
+       new->ai_socktype = ai->ai_socktype;
+       new->ai_protocol = ai->ai_protocol;
+       new->ai_canonname = NULL;
+       new->ai_addrlen = ai->ai_addrlen;
+       if ( (new->ai_addr = malloc(ai->ai_addrlen)) == NULL)
+               return(NULL);
+       memcpy(new->ai_addr, ai->ai_addr, ai->ai_addrlen);
+
+       return(new);
+}
+/* end ga_clone */
diff --git a/libgai/ga_clone.lc b/libgai/ga_clone.lc
new file mode 100644 (file)
index 0000000..9a302c5
--- /dev/null
@@ -0,0 +1,31 @@
+#include    "gai_hdr.h"##  1 ##src/libgai/ga_clone.c##
+
+/*##  2 ##src/libgai/ga_clone.c##
+ * Clone a new addrinfo structure from an existing one.##  3 ##src/libgai/ga_clone.c##
+ */##  4 ##src/libgai/ga_clone.c##
+
+/* include ga_clone */
+struct addrinfo *##  5 ##src/libgai/ga_clone.c##
+ga_clone(struct addrinfo *ai)##  6 ##src/libgai/ga_clone.c##
+{##  7 ##src/libgai/ga_clone.c##
+    struct addrinfo *new;##  8 ##src/libgai/ga_clone.c##
+
+    if ((new = calloc(1, sizeof(struct addrinfo))) == NULL)##  9 ##src/libgai/ga_clone.c##
+        return (NULL);## 10 ##src/libgai/ga_clone.c##
+
+    new->ai_next = ai->ai_next;## 11 ##src/libgai/ga_clone.c##
+    ai->ai_next = new;## 12 ##src/libgai/ga_clone.c##
+
+    new->ai_flags = 0;          /* make sure AI_CLONE is off */## 13 ##src/libgai/ga_clone.c##
+    new->ai_family = ai->ai_family;## 14 ##src/libgai/ga_clone.c##
+    new->ai_socktype = ai->ai_socktype;## 15 ##src/libgai/ga_clone.c##
+    new->ai_protocol = ai->ai_protocol;## 16 ##src/libgai/ga_clone.c##
+    new->ai_canonname = NULL;## 17 ##src/libgai/ga_clone.c##
+    new->ai_addrlen = ai->ai_addrlen;## 18 ##src/libgai/ga_clone.c##
+    if ((new->ai_addr = malloc(ai->ai_addrlen)) == NULL)## 19 ##src/libgai/ga_clone.c##
+        return (NULL);## 20 ##src/libgai/ga_clone.c##
+    memcpy(new->ai_addr, ai->ai_addr, ai->ai_addrlen);## 21 ##src/libgai/ga_clone.c##
+
+    return (new);## 22 ##src/libgai/ga_clone.c##
+}## 23 ##src/libgai/ga_clone.c##
+/* end ga_clone */
diff --git a/libgai/ga_echeck.c b/libgai/ga_echeck.c
new file mode 100644 (file)
index 0000000..56060c7
--- /dev/null
@@ -0,0 +1,54 @@
+#include       "gai_hdr.h"
+
+/*
+ * Basic error checking of flags, family, socket type, and protocol.
+ */
+
+/* include ga_echeck */
+int
+ga_echeck(const char *hostname, const char *servname,
+                 int flags, int family, int socktype, int protocol)
+{
+       if (flags & ~(AI_PASSIVE | AI_CANONNAME))
+               return(EAI_BADFLAGS);   /* unknown flag bits */
+
+       if (hostname == NULL || hostname[0] == '\0') {
+               if (servname == NULL || servname[0] == '\0')
+                       return(EAI_NONAME);     /* host or service must be specified */
+       }
+
+       switch(family) {
+               case AF_UNSPEC:
+                       break;
+#ifdef IPv4
+               case AF_INET:
+                       if (socktype != 0 &&
+                               (socktype != SOCK_STREAM &&
+                                socktype != SOCK_DGRAM &&
+                                socktype != SOCK_RAW))
+                               return(EAI_SOCKTYPE);   /* invalid socket type */
+                       break;
+#endif
+#ifdef IPv6
+               case AF_INET6:
+                       if (socktype != 0 &&
+                               (socktype != SOCK_STREAM &&
+                                socktype != SOCK_DGRAM &&
+                                socktype != SOCK_RAW))
+                               return(EAI_SOCKTYPE);   /* invalid socket type */
+                       break;
+#endif
+#ifdef UNIXdomain
+               case AF_LOCAL:
+                       if (socktype != 0 &&
+                               (socktype != SOCK_STREAM &&
+                                socktype != SOCK_DGRAM))
+                               return(EAI_SOCKTYPE);   /* invalid socket type */
+                       break;
+#endif
+               default:
+                       return(EAI_FAMILY);             /* unknown protocol family */
+       }
+       return(0);
+}
+/* end ga_echeck */
diff --git a/libgai/ga_echeck.lc b/libgai/ga_echeck.lc
new file mode 100644 (file)
index 0000000..73aebc9
--- /dev/null
@@ -0,0 +1,45 @@
+#include    "gai_hdr.h"##  1 ##src/libgai/ga_echeck.c##
+
+/*##  2 ##src/libgai/ga_echeck.c##
+ * Basic error checking of flags, family, socket type, and protocol.##  3 ##src/libgai/ga_echeck.c##
+ */##  4 ##src/libgai/ga_echeck.c##
+
+/* include ga_echeck */
+int##  5 ##src/libgai/ga_echeck.c##
+ga_echeck(const char *hostname, const char *servname,##  6 ##src/libgai/ga_echeck.c##
+          int flags, int family, int socktype, int protocol)##  7 ##src/libgai/ga_echeck.c##
+{##  8 ##src/libgai/ga_echeck.c##
+    if (flags & ~(AI_PASSIVE | AI_CANONNAME))##  9 ##src/libgai/ga_echeck.c##
+        return (EAI_BADFLAGS);  /* unknown flag bits */## 10 ##src/libgai/ga_echeck.c##
+
+    if (hostname == NULL || hostname[0] == '\0') {## 11 ##src/libgai/ga_echeck.c##
+        if (servname == NULL || servname[0] == '\0')## 12 ##src/libgai/ga_echeck.c##
+            return (EAI_NONAME);    /* host or service must be specified */## 13 ##src/libgai/ga_echeck.c##
+    }## 14 ##src/libgai/ga_echeck.c##
+
+    switch (family) {## 15 ##src/libgai/ga_echeck.c##
+    case AF_UNSPEC:## 16 ##src/libgai/ga_echeck.c##
+        break;## 17 ##src/libgai/ga_echeck.c##
+    case AF_INET:## 18 ##src/libgai/ga_echeck.c##
+        if (socktype != 0 &&## 19 ##src/libgai/ga_echeck.c##
+            (socktype != SOCK_STREAM &&## 20 ##src/libgai/ga_echeck.c##
+             socktype != SOCK_DGRAM && socktype != SOCK_RAW))## 21 ##src/libgai/ga_echeck.c##
+            return (EAI_SOCKTYPE);  /* invalid socket type */## 22 ##src/libgai/ga_echeck.c##
+        break;## 23 ##src/libgai/ga_echeck.c##
+    case AF_INET6:## 24 ##src/libgai/ga_echeck.c##
+        if (socktype != 0 &&## 25 ##src/libgai/ga_echeck.c##
+            (socktype != SOCK_STREAM &&## 26 ##src/libgai/ga_echeck.c##
+             socktype != SOCK_DGRAM && socktype != SOCK_RAW))## 27 ##src/libgai/ga_echeck.c##
+            return (EAI_SOCKTYPE);  /* invalid socket type */## 28 ##src/libgai/ga_echeck.c##
+        break;## 29 ##src/libgai/ga_echeck.c##
+    case AF_LOCAL:## 30 ##src/libgai/ga_echeck.c##
+        if (socktype != 0 &&## 31 ##src/libgai/ga_echeck.c##
+            (socktype != SOCK_STREAM && socktype != SOCK_DGRAM))## 32 ##src/libgai/ga_echeck.c##
+            return (EAI_SOCKTYPE);  /* invalid socket type */## 33 ##src/libgai/ga_echeck.c##
+        break;## 34 ##src/libgai/ga_echeck.c##
+    default:## 35 ##src/libgai/ga_echeck.c##
+        return (EAI_FAMILY);    /* unknown protocol family */## 36 ##src/libgai/ga_echeck.c##
+    }## 37 ##src/libgai/ga_echeck.c##
+    return (0);## 38 ##src/libgai/ga_echeck.c##
+}## 39 ##src/libgai/ga_echeck.c##
+/* end ga_echeck */
diff --git a/libgai/ga_nsearch.c b/libgai/ga_nsearch.c
new file mode 100644 (file)
index 0000000..8abc433
--- /dev/null
@@ -0,0 +1,115 @@
+#include       "gai_hdr.h"
+
+/*
+ * Set up the search[] array with the hostnames and address families
+ * that we are to look up.
+ */
+
+/* include ga_nsearch1 */
+int
+ga_nsearch(const char *hostname, const struct addrinfo *hintsp,
+                  struct search *search)
+{
+       int             nsearch = 0;
+
+       if (hostname == NULL || hostname[0] == '\0') {
+               if (hintsp->ai_flags & AI_PASSIVE) {
+                               /* 4no hostname and AI_PASSIVE: implies wildcard bind */
+                       switch (hintsp->ai_family) {
+#ifdef IPv4
+                       case AF_INET:
+                               search[nsearch].host = "0.0.0.0";
+                               search[nsearch].family = AF_INET;
+                               nsearch++;
+                               break;
+#endif
+#ifdef IPv6
+                       case AF_INET6:
+                               search[nsearch].host = "0::0";
+                               search[nsearch].family = AF_INET6;
+                               nsearch++;
+                               break;
+#endif
+                       case AF_UNSPEC:
+#ifdef IPv6
+                               search[nsearch].host = "0::0";  /* IPv6 first, then IPv4 */
+                               search[nsearch].family = AF_INET6;
+                               nsearch++;
+#endif
+#ifdef IPv4
+                               search[nsearch].host = "0.0.0.0";
+                               search[nsearch].family = AF_INET;
+                               nsearch++;
+#endif
+                               break;
+                       }
+/* end ga_nsearch1 */
+/* include ga_nsearch2 */
+               } else {
+                               /* 4no host and not AI_PASSIVE: connect to local host */
+                       switch (hintsp->ai_family) {
+#ifdef IPv4
+                       case AF_INET:
+                               search[nsearch].host = "localhost";     /* 127.0.0.1 */
+                               search[nsearch].family = AF_INET;
+                               nsearch++;
+                               break;
+#endif
+#ifdef IPv6
+                       case AF_INET6:
+                               search[nsearch].host = "0::1";
+                               search[nsearch].family = AF_INET6;
+                               nsearch++;
+                               break;
+#endif
+                       case AF_UNSPEC:
+#ifdef IPv6
+                               search[nsearch].host = "0::1";  /* IPv6 first, then IPv4 */
+                               search[nsearch].family = AF_INET6;
+                               nsearch++;
+#endif
+#ifdef IPv4
+                               search[nsearch].host = "localhost";
+                               search[nsearch].family = AF_INET;
+                               nsearch++;
+#endif
+                               break;
+                       }
+               }
+/* end ga_nsearch2 */
+/* include ga_nsearch3 */
+       } else {        /* host is specified */
+               switch (hintsp->ai_family) {
+#ifdef IPv4
+               case AF_INET:
+                       search[nsearch].host = hostname;
+                       search[nsearch].family = AF_INET;
+                       nsearch++;
+                       break;
+#endif
+#ifdef IPv6
+               case AF_INET6:
+                       search[nsearch].host = hostname;
+                       search[nsearch].family = AF_INET6;
+                       nsearch++;
+                       break;
+#endif
+               case AF_UNSPEC:
+#ifdef IPv6
+                       search[nsearch].host = hostname;
+                       search[nsearch].family = AF_INET6;      /* IPv6 first */
+                       nsearch++;
+#endif
+#ifdef IPv4
+                       search[nsearch].host = hostname;
+                       search[nsearch].family = AF_INET;       /* then IPv4 */
+                       nsearch++;
+#endif
+                       break;
+               }
+       }
+       if (nsearch < 1 || nsearch > 2)
+               err_quit("nsearch = %d", nsearch);
+       return(nsearch);
+}
+/* end ga_nsearch3 */
diff --git a/libgai/ga_nsearch.lc b/libgai/ga_nsearch.lc
new file mode 100644 (file)
index 0000000..d37341c
--- /dev/null
@@ -0,0 +1,91 @@
+#include    "gai_hdr.h"##  1 ##src/libgai/ga_nsearch.c##
+
+/*##  2 ##src/libgai/ga_nsearch.c##
+ * Set up the search[] array with the hostnames and address families##  3 ##src/libgai/ga_nsearch.c##
+ * that we are to look up.##  4 ##src/libgai/ga_nsearch.c##
+ */##  5 ##src/libgai/ga_nsearch.c##
+
+/* include ga_nsearch1 */
+int##  6 ##src/libgai/ga_nsearch.c##
+ga_nsearch(const char *hostname, const struct addrinfo *hintsp,##  7 ##src/libgai/ga_nsearch.c##
+           struct search *search)##  8 ##src/libgai/ga_nsearch.c##
+{##  9 ##src/libgai/ga_nsearch.c##
+    int     nsearch = 0;## 10 ##src/libgai/ga_nsearch.c##
+
+    if (hostname == NULL || hostname[0] == '\0') {## 11 ##src/libgai/ga_nsearch.c##
+        if (hintsp->ai_flags & AI_PASSIVE) {## 12 ##src/libgai/ga_nsearch.c##
+            /* 4no hostname and AI_PASSIVE: implies wildcard bind */## 13 ##src/libgai/ga_nsearch.c##
+            switch (hintsp->ai_family) {## 14 ##src/libgai/ga_nsearch.c##
+            case AF_INET:## 15 ##src/libgai/ga_nsearch.c##
+                search[nsearch].host = "0.0.0.0";## 16 ##src/libgai/ga_nsearch.c##
+                search[nsearch].family = AF_INET;## 17 ##src/libgai/ga_nsearch.c##
+                nsearch++;## 18 ##src/libgai/ga_nsearch.c##
+                break;## 19 ##src/libgai/ga_nsearch.c##
+            case AF_INET6:## 20 ##src/libgai/ga_nsearch.c##
+                search[nsearch].host = "0::0";## 21 ##src/libgai/ga_nsearch.c##
+                search[nsearch].family = AF_INET6;## 22 ##src/libgai/ga_nsearch.c##
+                nsearch++;## 23 ##src/libgai/ga_nsearch.c##
+                break;## 24 ##src/libgai/ga_nsearch.c##
+            case AF_UNSPEC:## 25 ##src/libgai/ga_nsearch.c##
+                search[nsearch].host = "0::0";  /* IPv6 first, then IPv4 */## 26 ##src/libgai/ga_nsearch.c##
+                search[nsearch].family = AF_INET6;## 27 ##src/libgai/ga_nsearch.c##
+                nsearch++;## 28 ##src/libgai/ga_nsearch.c##
+                search[nsearch].host = "0.0.0.0";## 29 ##src/libgai/ga_nsearch.c##
+                search[nsearch].family = AF_INET;## 30 ##src/libgai/ga_nsearch.c##
+                nsearch++;## 31 ##src/libgai/ga_nsearch.c##
+                break;## 32 ##src/libgai/ga_nsearch.c##
+            }## 33 ##src/libgai/ga_nsearch.c##
+/* end ga_nsearch1 */
+/* include ga_nsearch2 */
+        } else {## 34 ##src/libgai/ga_nsearch.c##
+            /* 4no host and not AI_PASSIVE: connect to local host */## 35 ##src/libgai/ga_nsearch.c##
+            switch (hintsp->ai_family) {## 36 ##src/libgai/ga_nsearch.c##
+            case AF_INET:## 37 ##src/libgai/ga_nsearch.c##
+                search[nsearch].host = "localhost"; /* 127.0.0.1 */## 38 ##src/libgai/ga_nsearch.c##
+                search[nsearch].family = AF_INET;## 39 ##src/libgai/ga_nsearch.c##
+                nsearch++;## 40 ##src/libgai/ga_nsearch.c##
+                break;## 41 ##src/libgai/ga_nsearch.c##
+            case AF_INET6:## 42 ##src/libgai/ga_nsearch.c##
+                search[nsearch].host = "0::1";## 43 ##src/libgai/ga_nsearch.c##
+                search[nsearch].family = AF_INET6;## 44 ##src/libgai/ga_nsearch.c##
+                nsearch++;## 45 ##src/libgai/ga_nsearch.c##
+                break;## 46 ##src/libgai/ga_nsearch.c##
+            case AF_UNSPEC:## 47 ##src/libgai/ga_nsearch.c##
+                search[nsearch].host = "0::1";  /* IPv6 first, then IPv4 */## 48 ##src/libgai/ga_nsearch.c##
+                search[nsearch].family = AF_INET6;## 49 ##src/libgai/ga_nsearch.c##
+                nsearch++;## 50 ##src/libgai/ga_nsearch.c##
+                search[nsearch].host = "localhost";## 51 ##src/libgai/ga_nsearch.c##
+                search[nsearch].family = AF_INET;## 52 ##src/libgai/ga_nsearch.c##
+                nsearch++;## 53 ##src/libgai/ga_nsearch.c##
+                break;## 54 ##src/libgai/ga_nsearch.c##
+            }## 55 ##src/libgai/ga_nsearch.c##
+        }## 56 ##src/libgai/ga_nsearch.c##
+/* end ga_nsearch2 */
+/* include ga_nsearch3 */
+    } else {                    /* host is specified */## 57 ##src/libgai/ga_nsearch.c##
+        switch (hintsp->ai_family) {## 58 ##src/libgai/ga_nsearch.c##
+        case AF_INET:## 59 ##src/libgai/ga_nsearch.c##
+            search[nsearch].host = hostname;## 60 ##src/libgai/ga_nsearch.c##
+            search[nsearch].family = AF_INET;## 61 ##src/libgai/ga_nsearch.c##
+            nsearch++;## 62 ##src/libgai/ga_nsearch.c##
+            break;## 63 ##src/libgai/ga_nsearch.c##
+        case AF_INET6:## 64 ##src/libgai/ga_nsearch.c##
+            search[nsearch].host = hostname;## 65 ##src/libgai/ga_nsearch.c##
+            search[nsearch].family = AF_INET6;## 66 ##src/libgai/ga_nsearch.c##
+            nsearch++;## 67 ##src/libgai/ga_nsearch.c##
+            break;## 68 ##src/libgai/ga_nsearch.c##
+        case AF_UNSPEC:## 69 ##src/libgai/ga_nsearch.c##
+            search[nsearch].host = hostname;## 70 ##src/libgai/ga_nsearch.c##
+            search[nsearch].family = AF_INET6;  /* IPv6 first */## 71 ##src/libgai/ga_nsearch.c##
+            nsearch++;## 72 ##src/libgai/ga_nsearch.c##
+            search[nsearch].host = hostname;## 73 ##src/libgai/ga_nsearch.c##
+            search[nsearch].family = AF_INET;   /* then IPv4 */## 74 ##src/libgai/ga_nsearch.c##
+            nsearch++;## 75 ##src/libgai/ga_nsearch.c##
+            break;## 76 ##src/libgai/ga_nsearch.c##
+        }## 77 ##src/libgai/ga_nsearch.c##
+    }## 78 ##src/libgai/ga_nsearch.c##
+    if (nsearch < 1 || nsearch > 2)## 79 ##src/libgai/ga_nsearch.c##
+        err_quit("nsearch = %d", nsearch);## 80 ##src/libgai/ga_nsearch.c##
+    return (nsearch);## 81 ##src/libgai/ga_nsearch.c##
+}## 82 ##src/libgai/ga_nsearch.c##
+/* end ga_nsearch3 */
diff --git a/libgai/ga_port.c b/libgai/ga_port.c
new file mode 100644 (file)
index 0000000..655bcdf
--- /dev/null
@@ -0,0 +1,66 @@
+#include       "gai_hdr.h"
+
+/*
+ * Go through all the addrinfo structures, checking for a match of the
+ * socket type and filling in the socket type, and then the port number
+ * in the corresponding socket address structures.
+ *
+ * The AI_CLONE flag works as follows.  Consider a multihomed host with
+ * two IP addresses and no socket type specified by the caller.  After
+ * the "host" search there are two addrinfo structures, one per IP address.
+ * Assuming a service supported by both TCP and UDP (say the daytime
+ * service) we need to return *four* addrinfo structures:
+ *             IP#1, SOCK_STREAM, TCP port,
+ *             IP#1, SOCK_DGRAM, UDP port,
+ *             IP#2, SOCK_STREAM, TCP port,
+ *             IP#2, SOCK_DGRAM, UDP port.
+ * To do this, when the "host" loop creates an addrinfo structure, if the
+ * caller has not specified a socket type (hintsp->ai_socktype == 0), the
+ * AI_CLONE flag is set.  When the following function finds an entry like
+ * this it is handled as follows: If the entry's ai_socktype is still 0,
+ * this is the first use of the structure, and the ai_socktype field is set.
+ * But, if the entry's ai_socktype is nonzero, then we clone a new addrinfo
+ * structure and set it's ai_socktype to the new value.  Although we only
+ * need two socket types today (SOCK_STREAM and SOCK_DGRAM) this algorithm
+ * will handle any number.  Also notice that Posix.1g requires all socket
+ * types to be nonzero.
+ */
+
+/* include ga_port */
+int
+ga_port(struct addrinfo *aihead, int port, int socktype)
+               /* port must be in network byte order */
+{
+       int                             nfound = 0;
+       struct addrinfo *ai;
+
+       for (ai = aihead; ai != NULL; ai = ai->ai_next) {
+               if (ai->ai_flags & AI_CLONE) {
+                       if (ai->ai_socktype != 0) {
+                               if ( (ai = ga_clone(ai)) == NULL)
+                                       return(-1);             /* memory allocation error */
+                               /* ai points to newly cloned entry, which is what we want */
+                       }
+               } else if (ai->ai_socktype != socktype)
+                       continue;               /* ignore if mismatch on socket type */
+
+               ai->ai_socktype = socktype;
+
+               switch (ai->ai_family) {
+#ifdef IPv4
+                       case AF_INET:
+                               ((struct sockaddr_in *) ai->ai_addr)->sin_port = port;
+                               nfound++;
+                               break;
+#endif
+#ifdef IPv6
+                       case AF_INET6:
+                               ((struct sockaddr_in6 *) ai->ai_addr)->sin6_port = port;
+                               nfound++;
+                               break;
+#endif
+               }
+       }
+       return(nfound);
+}
+/* end ga_port */
diff --git a/libgai/ga_port.lc b/libgai/ga_port.lc
new file mode 100644 (file)
index 0000000..04171ea
--- /dev/null
@@ -0,0 +1,62 @@
+#include    "gai_hdr.h"##  1 ##src/libgai/ga_port.c##
+
+/*##  2 ##src/libgai/ga_port.c##
+ * Go through all the addrinfo structures, checking for a match of the##  3 ##src/libgai/ga_port.c##
+ * socket type and filling in the socket type, and then the port number##  4 ##src/libgai/ga_port.c##
+ * in the corresponding socket address structures.##  5 ##src/libgai/ga_port.c##
+ *##  6 ##src/libgai/ga_port.c##
+ * The AI_CLONE flag works as follows.  Consider a multihomed host with##  7 ##src/libgai/ga_port.c##
+ * two IP addresses and no socket type specified by the caller.  After##  8 ##src/libgai/ga_port.c##
+ * the "host" search there are two addrinfo structures, one per IP address.##  9 ##src/libgai/ga_port.c##
+ * Assuming a service supported by both TCP and UDP (say the daytime## 10 ##src/libgai/ga_port.c##
+ * service) we need to return *four* addrinfo structures:## 11 ##src/libgai/ga_port.c##
+ *      IP#1, SOCK_STREAM, TCP port,## 12 ##src/libgai/ga_port.c##
+ *      IP#1, SOCK_DGRAM, UDP port,## 13 ##src/libgai/ga_port.c##
+ *      IP#2, SOCK_STREAM, TCP port,## 14 ##src/libgai/ga_port.c##
+ *      IP#2, SOCK_DGRAM, UDP port.## 15 ##src/libgai/ga_port.c##
+ * To do this, when the "host" loop creates an addrinfo structure, if the## 16 ##src/libgai/ga_port.c##
+ * caller has not specified a socket type (hintsp->ai_socktype == 0), the## 17 ##src/libgai/ga_port.c##
+ * AI_CLONE flag is set.  When the following function finds an entry like## 18 ##src/libgai/ga_port.c##
+ * this it is handled as follows: If the entry's ai_socktype is still 0,## 19 ##src/libgai/ga_port.c##
+ * this is the first use of the structure, and the ai_socktype field is set.## 20 ##src/libgai/ga_port.c##
+ * But, if the entry's ai_socktype is nonzero, then we clone a new addrinfo## 21 ##src/libgai/ga_port.c##
+ * structure and set it's ai_socktype to the new value.  Although we only## 22 ##src/libgai/ga_port.c##
+ * need two socket types today (SOCK_STREAM and SOCK_DGRAM) this algorithm## 23 ##src/libgai/ga_port.c##
+ * will handle any number.  Also notice that Posix.1g requires all socket## 24 ##src/libgai/ga_port.c##
+ * types to be nonzero.## 25 ##src/libgai/ga_port.c##
+ */## 26 ##src/libgai/ga_port.c##
+
+/* include ga_port */
+int## 27 ##src/libgai/ga_port.c##
+ga_port(struct addrinfo *aihead, int port, int socktype)## 28 ##src/libgai/ga_port.c##
+        /* port must be in network byte order */## 29 ##src/libgai/ga_port.c##
+{## 30 ##src/libgai/ga_port.c##
+    int     nfound = 0;## 31 ##src/libgai/ga_port.c##
+    struct addrinfo *ai;## 32 ##src/libgai/ga_port.c##
+
+    for (ai = aihead; ai != NULL; ai = ai->ai_next) {## 33 ##src/libgai/ga_port.c##
+        if (ai->ai_flags & AI_CLONE) {## 34 ##src/libgai/ga_port.c##
+            if (ai->ai_socktype != 0) {## 35 ##src/libgai/ga_port.c##
+                if ((ai = ga_clone(ai)) == NULL)## 36 ##src/libgai/ga_port.c##
+                    return (-1);    /* memory allocation error */## 37 ##src/libgai/ga_port.c##
+                /* ai points to newly cloned entry, which is what we want */## 38 ##src/libgai/ga_port.c##
+            }## 39 ##src/libgai/ga_port.c##
+        } else if (ai->ai_socktype != socktype)## 40 ##src/libgai/ga_port.c##
+            continue;           /* ignore if mismatch on socket type */## 41 ##src/libgai/ga_port.c##
+
+        ai->ai_socktype = socktype;## 42 ##src/libgai/ga_port.c##
+
+        switch (ai->ai_family) {## 43 ##src/libgai/ga_port.c##
+        case AF_INET:## 44 ##src/libgai/ga_port.c##
+            ((struct sockaddr_in *) ai->ai_addr)->sin_port = port;## 45 ##src/libgai/ga_port.c##
+            nfound++;## 46 ##src/libgai/ga_port.c##
+            break;## 47 ##src/libgai/ga_port.c##
+        case AF_INET6:## 48 ##src/libgai/ga_port.c##
+            ((struct sockaddr_in6 *) ai->ai_addr)->sin6_port = port;## 49 ##src/libgai/ga_port.c##
+            nfound++;## 50 ##src/libgai/ga_port.c##
+            break;## 51 ##src/libgai/ga_port.c##
+        }## 52 ##src/libgai/ga_port.c##
+    }## 53 ##src/libgai/ga_port.c##
+    return (nfound);## 54 ##src/libgai/ga_port.c##
+}## 55 ##src/libgai/ga_port.c##
+/* end ga_port */
diff --git a/libgai/ga_serv.c b/libgai/ga_serv.c
new file mode 100644 (file)
index 0000000..53cd395
--- /dev/null
@@ -0,0 +1,58 @@
+#include       "gai_hdr.h"
+
+/*
+ * This function handles the service string.
+ */
+
+/* include ga_serv */
+int
+ga_serv(struct addrinfo *aihead, const struct addrinfo *hintsp,
+               const char *serv)
+{
+       int                             port, rc, nfound;
+       struct servent  *sptr;
+
+       nfound = 0;
+       if (isdigit(serv[0])) {         /* check for port number string first */
+               port = htons(atoi(serv));
+               if (hintsp->ai_socktype) {
+                               /* 4caller specifies socket type */
+                       if ( (rc = ga_port(aihead, port, hintsp->ai_socktype)) < 0)
+                               return(EAI_MEMORY);
+                       nfound += rc;
+               } else {
+                               /* 4caller does not specify socket type */
+                       if ( (rc = ga_port(aihead, port, SOCK_STREAM)) < 0)
+                               return(EAI_MEMORY);
+                       nfound += rc;
+                       if ( (rc = ga_port(aihead, port, SOCK_DGRAM)) < 0)
+                               return(EAI_MEMORY);
+                       nfound += rc;
+               }
+       } else {
+                       /* 4try service name, TCP then UDP */
+               if (hintsp->ai_socktype == 0 || hintsp->ai_socktype == SOCK_STREAM) {
+                       if ( (sptr = getservbyname(serv, "tcp")) != NULL) {
+                               if ( (rc = ga_port(aihead, sptr->s_port, SOCK_STREAM)) < 0)
+                                       return(EAI_MEMORY);
+                               nfound += rc;
+                       }
+               }
+               if (hintsp->ai_socktype == 0 || hintsp->ai_socktype == SOCK_DGRAM) {
+                       if ( (sptr = getservbyname(serv, "udp")) != NULL) {
+                               if ( (rc = ga_port(aihead, sptr->s_port, SOCK_DGRAM)) < 0)
+                                       return(EAI_MEMORY);
+                               nfound += rc;
+                       }
+               }
+       }
+
+       if (nfound == 0) {
+               if (hintsp->ai_socktype == 0)
+                       return(EAI_NONAME);     /* all calls to getservbyname() failed */
+               else
+                       return(EAI_SERVICE);/* service not supported for socket type */
+       }
+       return(0);
+}
+/* end ga_serv */
diff --git a/libgai/ga_serv.lc b/libgai/ga_serv.lc
new file mode 100644 (file)
index 0000000..f8ee780
--- /dev/null
@@ -0,0 +1,58 @@
+#include    "gai_hdr.h"##  1 ##src/libgai/ga_serv.c##
+
+/*##  2 ##src/libgai/ga_serv.c##
+ * This function handles the service string.##  3 ##src/libgai/ga_serv.c##
+ */##  4 ##src/libgai/ga_serv.c##
+
+/* include ga_serv */
+int##  5 ##src/libgai/ga_serv.c##
+ga_serv(struct addrinfo *aihead, const struct addrinfo *hintsp,##  6 ##src/libgai/ga_serv.c##
+        const char *serv)##  7 ##src/libgai/ga_serv.c##
+{##  8 ##src/libgai/ga_serv.c##
+    int     port, rc, nfound;##  9 ##src/libgai/ga_serv.c##
+    struct servent *sptr;## 10 ##src/libgai/ga_serv.c##
+
+    nfound = 0;## 11 ##src/libgai/ga_serv.c##
+    if (isdigit(serv[0])) {     /* check for port number string first */## 12 ##src/libgai/ga_serv.c##
+        port = htons(atoi(serv));## 13 ##src/libgai/ga_serv.c##
+        if (hintsp->ai_socktype) {## 14 ##src/libgai/ga_serv.c##
+            /* 4caller specifies socket type */## 15 ##src/libgai/ga_serv.c##
+            if ((rc = ga_port(aihead, port, hintsp->ai_socktype)) < 0)## 16 ##src/libgai/ga_serv.c##
+                return (EAI_MEMORY);## 17 ##src/libgai/ga_serv.c##
+            nfound += rc;## 18 ##src/libgai/ga_serv.c##
+        } else {## 19 ##src/libgai/ga_serv.c##
+            /* 4caller does not specify socket type */## 20 ##src/libgai/ga_serv.c##
+            if ((rc = ga_port(aihead, port, SOCK_STREAM)) < 0)## 21 ##src/libgai/ga_serv.c##
+                return (EAI_MEMORY);## 22 ##src/libgai/ga_serv.c##
+            nfound += rc;## 23 ##src/libgai/ga_serv.c##
+            if ((rc = ga_port(aihead, port, SOCK_DGRAM)) < 0)## 24 ##src/libgai/ga_serv.c##
+                return (EAI_MEMORY);## 25 ##src/libgai/ga_serv.c##
+            nfound += rc;## 26 ##src/libgai/ga_serv.c##
+        }## 27 ##src/libgai/ga_serv.c##
+    } else {## 28 ##src/libgai/ga_serv.c##
+        /* 4try service name, TCP then UDP */## 29 ##src/libgai/ga_serv.c##
+        if (hintsp->ai_socktype == 0 || hintsp->ai_socktype == SOCK_STREAM) {## 30 ##src/libgai/ga_serv.c##
+            if ((sptr = getservbyname(serv, "tcp")) != NULL) {## 31 ##src/libgai/ga_serv.c##
+                if ((rc = ga_port(aihead, sptr->s_port, SOCK_STREAM)) < 0)## 32 ##src/libgai/ga_serv.c##
+                    return (EAI_MEMORY);## 33 ##src/libgai/ga_serv.c##
+                nfound += rc;## 34 ##src/libgai/ga_serv.c##
+            }## 35 ##src/libgai/ga_serv.c##
+        }## 36 ##src/libgai/ga_serv.c##
+        if (hintsp->ai_socktype == 0 || hintsp->ai_socktype == SOCK_DGRAM) {## 37 ##src/libgai/ga_serv.c##
+            if ((sptr = getservbyname(serv, "udp")) != NULL) {## 38 ##src/libgai/ga_serv.c##
+                if ((rc = ga_port(aihead, sptr->s_port, SOCK_DGRAM)) < 0)## 39 ##src/libgai/ga_serv.c##
+                    return (EAI_MEMORY);## 40 ##src/libgai/ga_serv.c##
+                nfound += rc;## 41 ##src/libgai/ga_serv.c##
+            }## 42 ##src/libgai/ga_serv.c##
+        }## 43 ##src/libgai/ga_serv.c##
+    }## 44 ##src/libgai/ga_serv.c##
+
+    if (nfound == 0) {## 45 ##src/libgai/ga_serv.c##
+        if (hintsp->ai_socktype == 0)## 46 ##src/libgai/ga_serv.c##
+            return (EAI_NONAME);    /* all calls to getservbyname() failed */## 47 ##src/libgai/ga_serv.c##
+        else## 48 ##src/libgai/ga_serv.c##
+            return (EAI_SERVICE);   /* service not supported for socket type */## 49 ##src/libgai/ga_serv.c##
+    }## 50 ##src/libgai/ga_serv.c##
+    return (0);## 51 ##src/libgai/ga_serv.c##
+}## 52 ##src/libgai/ga_serv.c##
+/* end ga_serv */
diff --git a/libgai/ga_unix.c b/libgai/ga_unix.c
new file mode 100644 (file)
index 0000000..74decbf
--- /dev/null
@@ -0,0 +1,42 @@
+#include       "gai_hdr.h"
+#include       <sys/utsname.h>
+
+#ifdef UNIXdomain
+/* include ga_unix */
+int
+ga_unix(const char *path, struct addrinfo *hintsp, struct addrinfo **result)
+{
+       int                             rc;
+       struct addrinfo *aihead, **aipnext;
+
+       aihead = NULL;
+       aipnext = &aihead;
+
+       if (hintsp->ai_family != AF_UNSPEC && hintsp->ai_family != AF_LOCAL)
+               return(EAI_ADDRFAMILY);
+
+       if (hintsp->ai_socktype == 0) {
+                       /* 4no socket type specified: return stream then dgram */
+               hintsp->ai_socktype = SOCK_STREAM;
+               if ( (rc = ga_aistruct(&aipnext, hintsp, path, AF_LOCAL)) != 0)
+                       return(rc);
+               hintsp->ai_socktype = SOCK_DGRAM;
+       }
+
+       if ( (rc = ga_aistruct(&aipnext, hintsp, path, AF_LOCAL)) != 0)
+               return(rc);
+
+       if (hintsp->ai_flags & AI_CANONNAME) {
+               struct utsname  myname;
+
+               if (uname(&myname) < 0)
+                       return(EAI_SYSTEM);
+               if ( (aihead->ai_canonname = strdup(myname.nodename)) == NULL)
+                       return(EAI_MEMORY);
+       }
+
+       *result = aihead;       /* pointer to first structure in linked list */
+       return(0);
+}
+/* end ga_unix */
+#endif /* UNIXdomain */
diff --git a/libgai/ga_unix.lc b/libgai/ga_unix.lc
new file mode 100644 (file)
index 0000000..fd761a0
--- /dev/null
@@ -0,0 +1,40 @@
+#include    "gai_hdr.h"##  1 ##src/libgai/ga_unix.c##
+#include    <sys/utsname.h>##  2 ##src/libgai/ga_unix.c##
+
+/* include ga_unix */
+int##  3 ##src/libgai/ga_unix.c##
+ga_unix(const char *path, struct addrinfo *hintsp, struct addrinfo **result)##  4 ##src/libgai/ga_unix.c##
+{##  5 ##src/libgai/ga_unix.c##
+    int     rc;##  6 ##src/libgai/ga_unix.c##
+    struct addrinfo *aihead, **aipnext;##  7 ##src/libgai/ga_unix.c##
+
+    aihead = NULL;##  8 ##src/libgai/ga_unix.c##
+    aipnext = &aihead;##  9 ##src/libgai/ga_unix.c##
+
+    if (hintsp->ai_family != AF_UNSPEC && hintsp->ai_family != AF_LOCAL)## 10 ##src/libgai/ga_unix.c##
+        return (EAI_ADDRFAMILY);## 11 ##src/libgai/ga_unix.c##
+
+    if (hintsp->ai_socktype == 0) {## 12 ##src/libgai/ga_unix.c##
+        /* 4no socket type specified: return stream then dgram */## 13 ##src/libgai/ga_unix.c##
+        hintsp->ai_socktype = SOCK_STREAM;## 14 ##src/libgai/ga_unix.c##
+        if ((rc = ga_aistruct(&aipnext, hintsp, path, AF_LOCAL)) != 0)## 15 ##src/libgai/ga_unix.c##
+            return (rc);## 16 ##src/libgai/ga_unix.c##
+        hintsp->ai_socktype = SOCK_DGRAM;## 17 ##src/libgai/ga_unix.c##
+    }## 18 ##src/libgai/ga_unix.c##
+
+    if ((rc = ga_aistruct(&aipnext, hintsp, path, AF_LOCAL)) != 0)## 19 ##src/libgai/ga_unix.c##
+        return (rc);## 20 ##src/libgai/ga_unix.c##
+
+    if (hintsp->ai_flags & AI_CANONNAME) {## 21 ##src/libgai/ga_unix.c##
+        struct utsname myname;## 22 ##src/libgai/ga_unix.c##
+
+        if (uname(&myname) < 0)## 23 ##src/libgai/ga_unix.c##
+            return (EAI_SYSTEM);## 24 ##src/libgai/ga_unix.c##
+        if ((aihead->ai_canonname = strdup(myname.nodename)) == NULL)## 25 ##src/libgai/ga_unix.c##
+            return (EAI_MEMORY);## 26 ##src/libgai/ga_unix.c##
+    }## 27 ##src/libgai/ga_unix.c##
+
+    *result = aihead;           /* pointer to first structure in linked list */## 28 ##src/libgai/ga_unix.c##
+    return (0);## 29 ##src/libgai/ga_unix.c##
+}## 30 ##src/libgai/ga_unix.c##
+/* end ga_unix */
diff --git a/libgai/gai_hdr.h b/libgai/gai_hdr.h
new file mode 100644 (file)
index 0000000..a25860a
--- /dev/null
@@ -0,0 +1,23 @@
+#include       "unp.h"
+#include       <ctype.h>               /* isxdigit(), etc. */
+
+               /* following internal flag cannot overlap with other AI_xxx flags */
+#define        AI_CLONE             4  /* clone this entry for other socket types */
+
+struct search {
+  const char   *host;  /* hostname or address string */
+  int                  family; /* AF_xxx */
+};
+
+               /* 4function prototypes for our own internal functions */
+int            ga_aistruct(struct addrinfo ***, const struct addrinfo *,
+                                       const void *, int);
+struct addrinfo                *ga_clone(struct addrinfo *);
+int            ga_echeck(const char *, const char *, int, int, int, int);
+int            ga_nsearch(const char *, const struct addrinfo *, struct search *);
+int            ga_port(struct addrinfo *, int , int);
+int            ga_serv(struct addrinfo *, const struct addrinfo *, const char *);
+int            ga_unix(const char *, struct addrinfo *, struct addrinfo **);
+
+int            gn_ipv46(char *, size_t, char *, size_t, void *, size_t,
+                                int, int, int);
diff --git a/libgai/gai_hdr.lh b/libgai/gai_hdr.lh
new file mode 100644 (file)
index 0000000..4e7ac2e
--- /dev/null
@@ -0,0 +1,23 @@
+#include    "unp.h"##  1 ##src/libgai/gai_hdr.h##
+#include    <ctype.h>           /* isxdigit(), etc. */##  2 ##src/libgai/gai_hdr.h##
+
+        /* following internal flag cannot overlap with other AI_xxx flags */##  3 ##src/libgai/gai_hdr.h##
+#define AI_CLONE         4      /* clone this entry for other socket types */##  4 ##src/libgai/gai_hdr.h##
+
+struct search {##  5 ##src/libgai/gai_hdr.h##
+    const char *host;           /* hostname or address string */##  6 ##src/libgai/gai_hdr.h##
+    int     family;             /* AF_xxx */##  7 ##src/libgai/gai_hdr.h##
+};##  8 ##src/libgai/gai_hdr.h##
+
+        /* 4function prototypes for our own internal functions */##  9 ##src/libgai/gai_hdr.h##
+int     ga_aistruct(struct addrinfo ***, const struct addrinfo *,## 10 ##src/libgai/gai_hdr.h##
+                    const void *, int);## 11 ##src/libgai/gai_hdr.h##
+struct addrinfo *ga_clone(struct addrinfo *);## 12 ##src/libgai/gai_hdr.h##
+int     ga_echeck(const char *, const char *, int, int, int, int);## 13 ##src/libgai/gai_hdr.h##
+int     ga_nsearch(const char *, const struct addrinfo *, struct search *);## 14 ##src/libgai/gai_hdr.h##
+int     ga_port(struct addrinfo *, int, int);## 15 ##src/libgai/gai_hdr.h##
+int     ga_serv(struct addrinfo *, const struct addrinfo *, const char *);## 16 ##src/libgai/gai_hdr.h##
+int     ga_unix(const char *, struct addrinfo *, struct addrinfo **);## 17 ##src/libgai/gai_hdr.h##
+
+int     gn_ipv46(char *, size_t, char *, size_t, void *, size_t,## 18 ##src/libgai/gai_hdr.h##
+                 int, int, int);## 19 ##src/libgai/gai_hdr.h##
diff --git a/libgai/gai_strerror.c b/libgai/gai_strerror.c
new file mode 100644 (file)
index 0000000..c0495ab
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Return a string containing some additional information after an
+ * error from getaddrinfo().
+ */
+
+#include       <sys/types.h>
+#include       "addrinfo.h"    /* XXX should be <netdb.h> */
+
+char *
+gai_strerror(int err)
+{
+       switch (err) {
+               case EAI_ADDRFAMILY:return("address family for host not supported");
+               case EAI_AGAIN:         return("temporary failure in name resolution");
+               case EAI_BADFLAGS:      return("invalid flags value");
+               case EAI_FAIL:          return("non-recoverable failure in name resolution");
+               case EAI_FAMILY:        return("address family not supported");
+               case EAI_MEMORY:        return("memory allocation failure");
+               case EAI_NODATA:        return("no address associated with host");
+               case EAI_NONAME:        return("host nor service provided, or not known");
+               case EAI_SERVICE:       return("service not supported for socket type");
+               case EAI_SOCKTYPE:      return("socket type not supported");
+               case EAI_SYSTEM:        return("system error");
+               default:                        return("unknown getaddrinfo() error");
+       }
+}
diff --git a/libgai/getaddrinfo.c b/libgai/getaddrinfo.c
new file mode 100644 (file)
index 0000000..e4ec036
--- /dev/null
@@ -0,0 +1,168 @@
+/* include ga1 */
+#include       "gai_hdr.h"
+#include       <arpa/nameser.h>        /* needed for <resolv.h> */
+#include       <resolv.h>                      /* res_init, _res */
+
+int
+getaddrinfo(const char *hostname, const char *servname,
+                       const struct addrinfo *hintsp, struct addrinfo **result)
+{
+       int                                     rc, error, nsearch;
+       char                            **ap, *canon;
+       struct hostent          *hptr;
+       struct search           search[3], *sptr;
+       struct addrinfo         hints, *aihead, **aipnext;
+
+       /*
+        * If we encounter an error we want to free() any dynamic memory
+        * that we've allocated.  This is our hack to simplify the code.
+        */
+#define        error(e) { error = (e); goto bad; }
+
+       aihead = NULL;          /* initialize automatic variables */
+       aipnext = &aihead;
+       canon = NULL;
+
+       if (hintsp == NULL) {
+               bzero(&hints, sizeof(hints));
+               hints.ai_family = AF_UNSPEC;
+       } else
+               hints = *hintsp;                /* struct copy */
+
+               /* 4first some basic error checking */
+       if ( (rc = ga_echeck(hostname, servname, hints.ai_flags, hints.ai_family,
+                                                hints.ai_socktype, hints.ai_protocol)) != 0)
+               error(rc);
+
+#ifdef UNIXdomain
+               /* 4special case Unix domain first */
+       if (hostname != NULL &&
+               (strcmp(hostname, "/local") == 0 || strcmp(hostname, "/unix") == 0) &&
+               (servname != NULL && servname[0] == '/'))
+               return(ga_unix(servname, &hints, result));
+#endif
+/* end ga1 */
+
+/* include ga3 */
+               /* 4remainder of function for IPv4/IPv6 */
+       nsearch = ga_nsearch(hostname, &hints, &search[0]);
+       for (sptr = &search[0]; sptr < &search[nsearch]; sptr++) {
+#ifdef IPv4
+                       /* 4check for an IPv4 dotted-decimal string */
+               if (isdigit(sptr->host[0])) {
+                       struct in_addr  inaddr;
+
+                       if (inet_pton(AF_INET, sptr->host, &inaddr) == 1) {
+                               if (hints.ai_family != AF_UNSPEC &&
+                                       hints.ai_family != AF_INET)
+                                       error(EAI_ADDRFAMILY);
+                               if (sptr->family != AF_INET)
+                                       continue;               /* ignore */
+                               rc = ga_aistruct(&aipnext, &hints, &inaddr, AF_INET);
+                               if (rc != 0)
+                                       error(rc);
+                               continue;
+                       }
+               }
+#endif
+       
+#ifdef IPv6
+                       /* 4check for an IPv6 hex string */
+               if ((isxdigit(sptr->host[0]) || sptr->host[0] == ':') &&
+                       (strchr(sptr->host, ':') != NULL)) {
+                       struct in6_addr in6addr;
+
+                       if (inet_pton(AF_INET6, sptr->host, &in6addr) == 1) {
+                               if (hints.ai_family != AF_UNSPEC &&
+                                       hints.ai_family != AF_INET6)
+                                       error(EAI_ADDRFAMILY);
+                               if (sptr->family != AF_INET6)
+                                       continue;               /* ignore */
+                               rc = ga_aistruct(&aipnext, &hints, &in6addr, AF_INET6);
+                               if (rc != 0)
+                                       error(rc);
+                               continue;
+                       }
+               }
+#endif
+/* end ga3 */
+/* include ga4 */
+                       /* 4remainder of for() to look up hostname */
+               if ((_res.options & RES_INIT) == 0)
+                       res_init();                     /* need this to set _res.options */
+
+               if (nsearch == 2) {
+#ifdef IPv6
+                       _res.options &= ~RES_USE_INET6;
+#endif
+                       hptr = gethostbyname2(sptr->host, sptr->family);
+               } else {
+#ifdef  IPv6
+                       if (sptr->family == AF_INET6)
+                               _res.options |= RES_USE_INET6;
+                       else
+                               _res.options &= ~RES_USE_INET6;
+#endif
+                       hptr = gethostbyname(sptr->host);
+               }
+               if (hptr == NULL) {
+                       if (nsearch == 2)
+                               continue;       /* failure OK if multiple searches */
+
+                       switch (h_errno) {
+                               case HOST_NOT_FOUND:    error(EAI_NONAME);
+                               case TRY_AGAIN:                 error(EAI_AGAIN);
+                               case NO_RECOVERY:               error(EAI_FAIL);
+                               case NO_DATA:                   error(EAI_NODATA);
+                               default:                                error(EAI_NONAME);
+                       }
+               }
+       
+                       /* 4check for address family mismatch if one specified */
+               if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype)
+                       error(EAI_ADDRFAMILY);
+
+                       /* 4save canonical name first time */
+               if (hostname != NULL && hostname[0] != '\0' &&
+                       (hints.ai_flags & AI_CANONNAME) && canon == NULL) {
+                       if ( (canon = strdup(hptr->h_name)) == NULL)    
+                               error(EAI_MEMORY);
+               }
+       
+                       /* 4create one addrinfo{} for each returned address */
+               for (ap = hptr->h_addr_list; *ap != NULL; ap++) {
+                       rc = ga_aistruct(&aipnext, &hints, *ap, hptr->h_addrtype);
+                       if (rc != 0)
+                               error(rc);
+               }
+       }
+       if (aihead == NULL)
+               error(EAI_NONAME);              /* nothing found */
+/* end ga4 */
+
+/* include ga5 */
+               /* 4return canonical name */
+       if (hostname != NULL && hostname[0] != '\0' &&
+               hints.ai_flags & AI_CANONNAME) {
+               if (canon != NULL)
+                       aihead->ai_canonname = canon;   /* strdup'ed earlier */
+               else {
+                       if ( (aihead->ai_canonname = strdup(search[0].host)) == NULL)
+                               error(EAI_MEMORY);
+               }
+       }
+
+               /* 4now process the service name */
+       if (servname != NULL && servname[0] != '\0') {
+               if ( (rc = ga_serv(aihead, &hints, servname)) != 0)
+                       error(rc);
+       }
+
+       *result = aihead;       /* pointer to first structure in linked list */
+       return(0);
+
+bad:
+       freeaddrinfo(aihead);   /* free any alloc'ed memory */
+       return(error);
+}
+/* end ga5 */
diff --git a/libgai/getaddrinfo.lc b/libgai/getaddrinfo.lc
new file mode 100644 (file)
index 0000000..f745002
--- /dev/null
@@ -0,0 +1,164 @@
+/* include ga1 */
+#include    "gai_hdr.h"##  1 ##src/libgai/getaddrinfo.c##
+#include    <arpa/nameser.h>    /* needed for <resolv.h> */##  2 ##src/libgai/getaddrinfo.c##
+#include    <resolv.h>          /* res_init, _res */##  3 ##src/libgai/getaddrinfo.c##
+
+int##  4 ##src/libgai/getaddrinfo.c##
+getaddrinfo(const char *hostname, const char *servname,##  5 ##src/libgai/getaddrinfo.c##
+            const struct addrinfo *hintsp, struct addrinfo **result)##  6 ##src/libgai/getaddrinfo.c##
+{##  7 ##src/libgai/getaddrinfo.c##
+    int     rc, error, nsearch;##  8 ##src/libgai/getaddrinfo.c##
+    char  **ap, *canon;##  9 ##src/libgai/getaddrinfo.c##
+    struct hostent *hptr;## 10 ##src/libgai/getaddrinfo.c##
+    struct search search[3], *sptr;## 11 ##src/libgai/getaddrinfo.c##
+    struct addrinfo hints, *aihead, **aipnext;## 12 ##src/libgai/getaddrinfo.c##
+
+    /* ## 13 ##src/libgai/getaddrinfo.c##
+     * If we encounter an error we want to free() any dynamic memory## 14 ##src/libgai/getaddrinfo.c##
+     * that we've allocated.  This is our hack to simplify the code.## 15 ##src/libgai/getaddrinfo.c##
+     */## 16 ##src/libgai/getaddrinfo.c##
+#define error(e) { error = (e); goto bad; }## 17 ##src/libgai/getaddrinfo.c##
+
+    aihead = NULL;              /* initialize automatic variables */## 18 ##src/libgai/getaddrinfo.c##
+    aipnext = &aihead;## 19 ##src/libgai/getaddrinfo.c##
+    canon = NULL;## 20 ##src/libgai/getaddrinfo.c##
+
+    if (hintsp == NULL) {## 21 ##src/libgai/getaddrinfo.c##
+        bzero(&hints, sizeof(hints));## 22 ##src/libgai/getaddrinfo.c##
+        hints.ai_family = AF_UNSPEC;## 23 ##src/libgai/getaddrinfo.c##
+    } else## 24 ##src/libgai/getaddrinfo.c##
+        hints = *hintsp;        /* struct copy */## 25 ##src/libgai/getaddrinfo.c##
+
+    /* 4first some basic error checking */## 26 ##src/libgai/getaddrinfo.c##
+    if ((rc = ga_echeck(hostname, servname, hints.ai_flags, hints.ai_family,## 27 ##src/libgai/getaddrinfo.c##
+                        hints.ai_socktype, hints.ai_protocol)) != 0)## 28 ##src/libgai/getaddrinfo.c##
+        error(rc);## 29 ##src/libgai/getaddrinfo.c##
+
+    /* 4special case Unix domain first */## 30 ##src/libgai/getaddrinfo.c##
+    if (hostname != NULL &&## 31 ##src/libgai/getaddrinfo.c##
+        (strcmp(hostname, "/local") == 0 || strcmp(hostname, "/unix") == 0)## 32 ##src/libgai/getaddrinfo.c##
+        && (servname != NULL && servname[0] == '/'))## 33 ##src/libgai/getaddrinfo.c##
+        return (ga_unix(servname, &hints, result));## 34 ##src/libgai/getaddrinfo.c##
+/* end ga1 */
+
+/* include ga3 */
+    /* 4remainder of function for IPv4/IPv6 */## 35 ##src/libgai/getaddrinfo.c##
+    nsearch = ga_nsearch(hostname, &hints, &search[0]);## 36 ##src/libgai/getaddrinfo.c##
+    for (sptr = &search[0]; sptr < &search[nsearch]; sptr++) {## 37 ##src/libgai/getaddrinfo.c##
+        /* 4check for an IPv4 dotted-decimal string */## 38 ##src/libgai/getaddrinfo.c##
+        if (isdigit(sptr->host[0])) {## 39 ##src/libgai/getaddrinfo.c##
+            struct in_addr inaddr;## 40 ##src/libgai/getaddrinfo.c##
+
+            if (inet_pton(AF_INET, sptr->host, &inaddr) == 1) {## 41 ##src/libgai/getaddrinfo.c##
+                if (hints.ai_family != AF_UNSPEC &&## 42 ##src/libgai/getaddrinfo.c##
+                    hints.ai_family != AF_INET)## 43 ##src/libgai/getaddrinfo.c##
+                    error(EAI_ADDRFAMILY);## 44 ##src/libgai/getaddrinfo.c##
+                if (sptr->family != AF_INET)## 45 ##src/libgai/getaddrinfo.c##
+                    continue;   /* ignore */## 46 ##src/libgai/getaddrinfo.c##
+                rc = ga_aistruct(&aipnext, &hints, &inaddr, AF_INET);## 47 ##src/libgai/getaddrinfo.c##
+                if (rc != 0)## 48 ##src/libgai/getaddrinfo.c##
+                    error(rc);## 49 ##src/libgai/getaddrinfo.c##
+                continue;## 50 ##src/libgai/getaddrinfo.c##
+            }## 51 ##src/libgai/getaddrinfo.c##
+        }## 52 ##src/libgai/getaddrinfo.c##
+
+        /* 4check for an IPv6 hex string */## 53 ##src/libgai/getaddrinfo.c##
+        if ((isxdigit(sptr->host[0]) || sptr->host[0] == ':') &&## 54 ##src/libgai/getaddrinfo.c##
+            (strchr(sptr->host, ':') != NULL)) {## 55 ##src/libgai/getaddrinfo.c##
+            struct in6_addr in6addr;## 56 ##src/libgai/getaddrinfo.c##
+
+            if (inet_pton(AF_INET6, sptr->host, &in6addr) == 1) {## 57 ##src/libgai/getaddrinfo.c##
+                if (hints.ai_family != AF_UNSPEC &&## 58 ##src/libgai/getaddrinfo.c##
+                    hints.ai_family != AF_INET6)## 59 ##src/libgai/getaddrinfo.c##
+                    error(EAI_ADDRFAMILY);## 60 ##src/libgai/getaddrinfo.c##
+                if (sptr->family != AF_INET6)## 61 ##src/libgai/getaddrinfo.c##
+                    continue;   /* ignore */## 62 ##src/libgai/getaddrinfo.c##
+                rc = ga_aistruct(&aipnext, &hints, &in6addr, AF_INET6);## 63 ##src/libgai/getaddrinfo.c##
+                if (rc != 0)## 64 ##src/libgai/getaddrinfo.c##
+                    error(rc);## 65 ##src/libgai/getaddrinfo.c##
+                continue;## 66 ##src/libgai/getaddrinfo.c##
+            }## 67 ##src/libgai/getaddrinfo.c##
+        }## 68 ##src/libgai/getaddrinfo.c##
+/* end ga3 */
+/* include ga4 */
+        /* 4remainder of for() to look up hostname */## 69 ##src/libgai/getaddrinfo.c##
+        if ((_res.options & RES_INIT) == 0)## 70 ##src/libgai/getaddrinfo.c##
+            res_init();         /* need this to set _res.options */## 71 ##src/libgai/getaddrinfo.c##
+
+        if (nsearch == 2) {## 72 ##src/libgai/getaddrinfo.c##
+            _res.options &= ~RES_USE_INET6;## 73 ##src/libgai/getaddrinfo.c##
+            hptr = gethostbyname2(sptr->host, sptr->family);## 74 ##src/libgai/getaddrinfo.c##
+        } else {## 75 ##src/libgai/getaddrinfo.c##
+            if (sptr->family == AF_INET6)## 76 ##src/libgai/getaddrinfo.c##
+                _res.options |= RES_USE_INET6;## 77 ##src/libgai/getaddrinfo.c##
+            else## 78 ##src/libgai/getaddrinfo.c##
+                _res.options &= ~RES_USE_INET6;## 79 ##src/libgai/getaddrinfo.c##
+            hptr = gethostbyname(sptr->host);## 80 ##src/libgai/getaddrinfo.c##
+        }## 81 ##src/libgai/getaddrinfo.c##
+        if (hptr == NULL) {## 82 ##src/libgai/getaddrinfo.c##
+            if (nsearch == 2)## 83 ##src/libgai/getaddrinfo.c##
+                continue;       /* failure OK if multiple searches */## 84 ##src/libgai/getaddrinfo.c##
+
+            switch (h_errno) {## 85 ##src/libgai/getaddrinfo.c##
+            case HOST_NOT_FOUND:## 86 ##src/libgai/getaddrinfo.c##
+                error(EAI_NONAME);## 87 ##src/libgai/getaddrinfo.c##
+            case TRY_AGAIN:## 88 ##src/libgai/getaddrinfo.c##
+                error(EAI_AGAIN);## 89 ##src/libgai/getaddrinfo.c##
+            case NO_RECOVERY:## 90 ##src/libgai/getaddrinfo.c##
+                error(EAI_FAIL);## 91 ##src/libgai/getaddrinfo.c##
+            case NO_DATA:## 92 ##src/libgai/getaddrinfo.c##
+                error(EAI_NODATA);## 93 ##src/libgai/getaddrinfo.c##
+            default:## 94 ##src/libgai/getaddrinfo.c##
+                error(EAI_NONAME);## 95 ##src/libgai/getaddrinfo.c##
+            }## 96 ##src/libgai/getaddrinfo.c##
+        }## 97 ##src/libgai/getaddrinfo.c##
+
+        /* 4check for address family mismatch if one specified */## 98 ##src/libgai/getaddrinfo.c##
+        if (hints.ai_family != AF_UNSPEC## 99 ##src/libgai/getaddrinfo.c##
+            && hints.ai_family != hptr->h_addrtype)##100 ##src/libgai/getaddrinfo.c##
+            error(EAI_ADDRFAMILY);##101 ##src/libgai/getaddrinfo.c##
+
+        /* 4save canonical name first time */##102 ##src/libgai/getaddrinfo.c##
+        if (hostname != NULL && hostname[0] != '\0' &&##103 ##src/libgai/getaddrinfo.c##
+            (hints.ai_flags & AI_CANONNAME) && canon == NULL) {##104 ##src/libgai/getaddrinfo.c##
+            if ((canon = strdup(hptr->h_name)) == NULL)##105 ##src/libgai/getaddrinfo.c##
+                error(EAI_MEMORY);##106 ##src/libgai/getaddrinfo.c##
+        }##107 ##src/libgai/getaddrinfo.c##
+
+        /* 4create one addrinfo{} for each returned address */##108 ##src/libgai/getaddrinfo.c##
+        for (ap = hptr->h_addr_list; *ap != NULL; ap++) {##109 ##src/libgai/getaddrinfo.c##
+            rc = ga_aistruct(&aipnext, &hints, *ap, hptr->h_addrtype);##110 ##src/libgai/getaddrinfo.c##
+            if (rc != 0)##111 ##src/libgai/getaddrinfo.c##
+                error(rc);##112 ##src/libgai/getaddrinfo.c##
+        }##113 ##src/libgai/getaddrinfo.c##
+    }##114 ##src/libgai/getaddrinfo.c##
+    if (aihead == NULL)##115 ##src/libgai/getaddrinfo.c##
+        error(EAI_NONAME);      /* nothing found */##116 ##src/libgai/getaddrinfo.c##
+/* end ga4 */
+
+/* include ga5 */
+    /* 4return canonical name */##117 ##src/libgai/getaddrinfo.c##
+    if (hostname != NULL && hostname[0] != '\0' &&##118 ##src/libgai/getaddrinfo.c##
+        hints.ai_flags & AI_CANONNAME) {##119 ##src/libgai/getaddrinfo.c##
+        if (canon != NULL)##120 ##src/libgai/getaddrinfo.c##
+            aihead->ai_canonname = canon;   /* strdup'ed earlier */##121 ##src/libgai/getaddrinfo.c##
+        else {##122 ##src/libgai/getaddrinfo.c##
+            if ((aihead->ai_canonname = strdup(search[0].host)) == NULL)##123 ##src/libgai/getaddrinfo.c##
+                error(EAI_MEMORY);##124 ##src/libgai/getaddrinfo.c##
+        }##125 ##src/libgai/getaddrinfo.c##
+    }##126 ##src/libgai/getaddrinfo.c##
+
+    /* 4now process the service name */##127 ##src/libgai/getaddrinfo.c##
+    if (servname != NULL && servname[0] != '\0') {##128 ##src/libgai/getaddrinfo.c##
+        if ((rc = ga_serv(aihead, &hints, servname)) != 0)##129 ##src/libgai/getaddrinfo.c##
+            error(rc);##130 ##src/libgai/getaddrinfo.c##
+    }##131 ##src/libgai/getaddrinfo.c##
+
+    *result = aihead;           /* pointer to first structure in linked list */##132 ##src/libgai/getaddrinfo.c##
+    return (0);##133 ##src/libgai/getaddrinfo.c##
+
+  bad:##134 ##src/libgai/getaddrinfo.c##
+    freeaddrinfo(aihead);       /* free any alloc'ed memory */##135 ##src/libgai/getaddrinfo.c##
+    return (error);##136 ##src/libgai/getaddrinfo.c##
+}##137 ##src/libgai/getaddrinfo.c##
+/* end ga5 */
diff --git a/libgai/getnameinfo.c b/libgai/getnameinfo.c
new file mode 100644 (file)
index 0000000..95480a5
--- /dev/null
@@ -0,0 +1,47 @@
+#include       "gai_hdr.h"
+
+/* include getnameinfo */
+int
+getnameinfo(const struct sockaddr *sa, socklen_t salen,
+                   char *host, size_t hostlen,
+                       char *serv, size_t servlen, int flags)
+{
+
+       switch (sa->sa_family) {
+#ifdef IPv4
+       case AF_INET: {
+               struct sockaddr_in      *sain = (struct sockaddr_in *) sa;
+
+               return(gn_ipv46(host, hostlen, serv, servlen,
+                                               &sain->sin_addr, sizeof(struct in_addr),
+                                               AF_INET, sain->sin_port, flags));
+       }
+#endif
+
+#ifdef IPv6
+       case AF_INET6: {
+               struct sockaddr_in6     *sain = (struct sockaddr_in6 *) sa;
+
+               return(gn_ipv46(host, hostlen, serv, servlen,
+                                               &sain->sin6_addr, sizeof(struct in6_addr),
+                                               AF_INET6, sain->sin6_port, flags));
+       }
+#endif
+
+#ifdef UNIXdomain
+       case AF_LOCAL: {
+               struct sockaddr_un      *un = (struct sockaddr_un *) sa;
+
+               if (hostlen > 0)
+                       snprintf(host, hostlen, "%s", "/local");
+               if (servlen > 0)
+                       snprintf(serv, servlen, "%s", un->sun_path);
+               return(0);
+       }
+#endif
+
+       default:
+               return(1);
+       }
+}
+/* end getnameinfo */
diff --git a/libgai/getnameinfo.lc b/libgai/getnameinfo.lc
new file mode 100644 (file)
index 0000000..2318309
--- /dev/null
@@ -0,0 +1,41 @@
+#include    "gai_hdr.h"##  1 ##src/libgai/getnameinfo.c##
+
+/* include getnameinfo */
+int##  2 ##src/libgai/getnameinfo.c##
+getnameinfo(const struct sockaddr *sa, socklen_t salen,##  3 ##src/libgai/getnameinfo.c##
+            char *host, size_t hostlen,##  4 ##src/libgai/getnameinfo.c##
+            char *serv, size_t servlen, int flags)##  5 ##src/libgai/getnameinfo.c##
+{##  6 ##src/libgai/getnameinfo.c##
+
+    switch (sa->sa_family) {##  7 ##src/libgai/getnameinfo.c##
+    case AF_INET:{##  8 ##src/libgai/getnameinfo.c##
+            struct sockaddr_in *sain = (struct sockaddr_in *) sa;##  9 ##src/libgai/getnameinfo.c##
+
+            return (gn_ipv46(host, hostlen, serv, servlen,## 10 ##src/libgai/getnameinfo.c##
+                             &sain->sin_addr, sizeof(struct in_addr),## 11 ##src/libgai/getnameinfo.c##
+                             AF_INET, sain->sin_port, flags));## 12 ##src/libgai/getnameinfo.c##
+        }## 13 ##src/libgai/getnameinfo.c##
+
+    case AF_INET6:{## 14 ##src/libgai/getnameinfo.c##
+            struct sockaddr_in6 *sain = (struct sockaddr_in6 *) sa;## 15 ##src/libgai/getnameinfo.c##
+
+            return (gn_ipv46(host, hostlen, serv, servlen,## 16 ##src/libgai/getnameinfo.c##
+                             &sain->sin6_addr, sizeof(struct in6_addr),## 17 ##src/libgai/getnameinfo.c##
+                             AF_INET6, sain->sin6_port, flags));## 18 ##src/libgai/getnameinfo.c##
+        }## 19 ##src/libgai/getnameinfo.c##
+
+    case AF_LOCAL:{## 20 ##src/libgai/getnameinfo.c##
+            struct sockaddr_un *un = (struct sockaddr_un *) sa;## 21 ##src/libgai/getnameinfo.c##
+
+            if (hostlen > 0)## 22 ##src/libgai/getnameinfo.c##
+                snprintf(host, hostlen, "%s", "/local");## 23 ##src/libgai/getnameinfo.c##
+            if (servlen > 0)## 24 ##src/libgai/getnameinfo.c##
+                snprintf(serv, servlen, "%s", un->sun_path);## 25 ##src/libgai/getnameinfo.c##
+            return (0);## 26 ##src/libgai/getnameinfo.c##
+        }## 27 ##src/libgai/getnameinfo.c##
+
+    default:## 28 ##src/libgai/getnameinfo.c##
+        return (1);## 29 ##src/libgai/getnameinfo.c##
+    }## 30 ##src/libgai/getnameinfo.c##
+}## 31 ##src/libgai/getnameinfo.c##
+/* end getnameinfo */
diff --git a/libgai/gn_ipv46.c b/libgai/gn_ipv46.c
new file mode 100644 (file)
index 0000000..512f50d
--- /dev/null
@@ -0,0 +1,50 @@
+#include       "gai_hdr.h"
+
+/*
+ * Handle either an IPv4 or an IPv6 address and port.
+ */
+
+/* include gn_ipv46 */
+int
+gn_ipv46(char *host, size_t hostlen, char *serv, size_t servlen,
+                void *aptr, size_t alen, int family, int port, int flags)
+{
+       char                    *ptr;
+       struct hostent  *hptr;
+       struct servent  *sptr;
+
+       if (hostlen > 0) {
+               if (flags & NI_NUMERICHOST) {
+                       if (inet_ntop(family, aptr, host, hostlen) == NULL)
+                               return(1);
+               } else {
+                       hptr = gethostbyaddr(aptr, alen, family);
+                       if (hptr != NULL && hptr->h_name != NULL) {
+                               if (flags & NI_NOFQDN) {
+                                       if ( (ptr = strchr(hptr->h_name, '.')) != NULL)
+                                               *ptr = 0;       /* overwrite first dot */
+                               }
+                               snprintf(host, hostlen, "%s", hptr->h_name);
+                       } else {
+                               if (flags & NI_NAMEREQD)
+                                       return(1);
+                               if (inet_ntop(family, aptr, host, hostlen) == NULL)
+                                       return(1);
+                       }
+               }
+       }
+
+       if (servlen > 0) {
+               if (flags & NI_NUMERICSERV) {
+                       snprintf(serv, servlen, "%d", ntohs(port));
+               } else {
+                       sptr = getservbyport(port, (flags & NI_DGRAM) ? "udp" : NULL);
+                       if (sptr != NULL && sptr->s_name != NULL)
+                               snprintf(serv, servlen, "%s", sptr->s_name);
+                       else
+                               snprintf(serv, servlen, "%d", ntohs(port));
+               }
+       }
+       return(0);
+}
+/* end gn_ipv46 */
diff --git a/libgai/gn_ipv46.lc b/libgai/gn_ipv46.lc
new file mode 100644 (file)
index 0000000..c438878
--- /dev/null
@@ -0,0 +1,50 @@
+#include    "gai_hdr.h"##  1 ##src/libgai/gn_ipv46.c##
+
+/*##  2 ##src/libgai/gn_ipv46.c##
+ * Handle either an IPv4 or an IPv6 address and port.##  3 ##src/libgai/gn_ipv46.c##
+ */##  4 ##src/libgai/gn_ipv46.c##
+
+/* include gn_ipv46 */
+int##  5 ##src/libgai/gn_ipv46.c##
+gn_ipv46(char *host, size_t hostlen, char *serv, size_t servlen,##  6 ##src/libgai/gn_ipv46.c##
+         void *aptr, size_t alen, int family, int port, int flags)##  7 ##src/libgai/gn_ipv46.c##
+{##  8 ##src/libgai/gn_ipv46.c##
+    char   *ptr;##  9 ##src/libgai/gn_ipv46.c##
+    struct hostent *hptr;## 10 ##src/libgai/gn_ipv46.c##
+    struct servent *sptr;## 11 ##src/libgai/gn_ipv46.c##
+
+    if (hostlen > 0) {## 12 ##src/libgai/gn_ipv46.c##
+        if (flags & NI_NUMERICHOST) {## 13 ##src/libgai/gn_ipv46.c##
+            if (inet_ntop(family, aptr, host, hostlen) == NULL)## 14 ##src/libgai/gn_ipv46.c##
+                return (1);## 15 ##src/libgai/gn_ipv46.c##
+        } else {## 16 ##src/libgai/gn_ipv46.c##
+            hptr = gethostbyaddr(aptr, alen, family);## 17 ##src/libgai/gn_ipv46.c##
+            if (hptr != NULL && hptr->h_name != NULL) {## 18 ##src/libgai/gn_ipv46.c##
+                if (flags & NI_NOFQDN) {## 19 ##src/libgai/gn_ipv46.c##
+                    if ((ptr = strchr(hptr->h_name, '.')) != NULL)## 20 ##src/libgai/gn_ipv46.c##
+                        *ptr = 0;   /* overwrite first dot */## 21 ##src/libgai/gn_ipv46.c##
+                }## 22 ##src/libgai/gn_ipv46.c##
+                snprintf(host, hostlen, "%s", hptr->h_name);## 23 ##src/libgai/gn_ipv46.c##
+            } else {## 24 ##src/libgai/gn_ipv46.c##
+                if (flags & NI_NAMEREQD)## 25 ##src/libgai/gn_ipv46.c##
+                    return (1);## 26 ##src/libgai/gn_ipv46.c##
+                if (inet_ntop(family, aptr, host, hostlen) == NULL)## 27 ##src/libgai/gn_ipv46.c##
+                    return (1);## 28 ##src/libgai/gn_ipv46.c##
+            }## 29 ##src/libgai/gn_ipv46.c##
+        }## 30 ##src/libgai/gn_ipv46.c##
+    }## 31 ##src/libgai/gn_ipv46.c##
+
+    if (servlen > 0) {## 32 ##src/libgai/gn_ipv46.c##
+        if (flags & NI_NUMERICSERV) {## 33 ##src/libgai/gn_ipv46.c##
+            snprintf(serv, servlen, "%d", ntohs(port));## 34 ##src/libgai/gn_ipv46.c##
+        } else {## 35 ##src/libgai/gn_ipv46.c##
+            sptr = getservbyport(port, (flags & NI_DGRAM) ? "udp" : NULL);## 36 ##src/libgai/gn_ipv46.c##
+            if (sptr != NULL && sptr->s_name != NULL)## 37 ##src/libgai/gn_ipv46.c##
+                snprintf(serv, servlen, "%s", sptr->s_name);## 38 ##src/libgai/gn_ipv46.c##
+            else## 39 ##src/libgai/gn_ipv46.c##
+                snprintf(serv, servlen, "%d", ntohs(port));## 40 ##src/libgai/gn_ipv46.c##
+        }## 41 ##src/libgai/gn_ipv46.c##
+    }## 42 ##src/libgai/gn_ipv46.c##
+    return (0);## 43 ##src/libgai/gn_ipv46.c##
+}## 44 ##src/libgai/gn_ipv46.c##
+/* end gn_ipv46 */
diff --git a/libgai/old/ga_unixstruct.c b/libgai/old/ga_unixstruct.c
new file mode 100644 (file)
index 0000000..7b06c9d
--- /dev/null
@@ -0,0 +1,36 @@
+#include       "gai_hdr.h"
+
+#ifdef UNIXDOMAIN
+int
+ga_unixstruct(const char *path, struct addrinfo *hintsp,
+                         struct addrinfo **result, int socktype)
+{
+       struct addrinfo         *ai;
+       struct sockaddr_un      *unp;
+
+       if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL)
+               return(EAI_MEMORY);
+
+       ai->ai_flags = 0;
+       ai->ai_family = AF_LOCAL;
+       ai->ai_socktype = socktype;
+       ai->ai_protocol = 0;
+
+               /* allocate and fill in a socket address structure */
+       ai->ai_addrlen = sizeof(struct sockaddr_un);
+       if ( (ai->ai_addr = malloc(ai->ai_addrlen)) == NULL)
+               return(EAI_MEMORY);
+       unp = (struct sockaddr_un *) ai->ai_addr;
+       unp->sun_family = AF_UNIX;
+       strncpy(unp->sun_path, path, sizeof(unp->sun_path));
+
+       ai->ai_canonname = NULL;
+       ai->ai_next = NULL;
+       *result = ai;
+
+       if (hintsp->ai_flags & AI_PASSIVE)
+               unlink(path);           /* OK if this fails */
+
+       return(0);              /* success */
+}
+#endif /* UNIXDOMAIN */
diff --git a/libgai/old/savecopy.c b/libgai/old/savecopy.c
new file mode 100644 (file)
index 0000000..13c9e5d
--- /dev/null
@@ -0,0 +1,582 @@
+#include       "unp.h"
+#include       <ctype.h>               /* isxdigit(), etc. */
+#include       <arpa/nameser.h>
+#include       <resolv.h>              /* res_init, _res */
+
+               /* following internal flag cannot overlap with other AI_xxx flags */
+#define        AI_CLONE             4  /* clone this entry for other socket types */
+
+struct search {
+  const char   *host;  /* hostname of address string */
+  int                  family; /* AF_xxx */
+};
+
+               /* function prototypes for our own internal functions */
+static int     ga_echeck(const char *, const char *, const struct addrinfo *);
+static int     ga_nsearch(const char *, const struct addrinfo *,
+                                          struct search *);
+static int     ga_aistruct(struct addrinfo ***, const struct addrinfo *,
+                                               void *, int);
+static int     ga_serv(struct addrinfo *, const struct addrinfo *, const char *);
+static int     ga_port(struct addrinfo *, int , int);
+static int     ga_unix(const char *, struct addrinfo *, struct addrinfo **);
+static struct addrinfo *ga_clone(struct addrinfo *);
+
+               /* globals for all functions in this file; these *must* be
+                  read-only if this function is to be reentrant */
+static struct addrinfo hints_default;
+
+int
+getaddrinfo(const char *hostname, const char *servname,
+                       const struct addrinfo *hintsp, struct addrinfo **result)
+{
+       int                                     rc, error, nsearch;
+       char                            **ap;
+       struct hostent          *hptr;
+       struct search           search[3], *sptr;
+       struct addrinfo         hints, *ai, *aihead, **aipnext;
+
+       /*
+        * If we encounter an error we want to free() any dynamic memory
+        * that we've allocated.  This is our hack to simplify the code.
+        */
+#define        error(e) { error = (e); goto bad; }
+
+       if (hintsp == NULL) {
+               hints = hints_default;  /* struct copy */
+               hints.ai_family = AF_UNSPEC;
+       } else
+               hints = *hintsp;                /* struct copy */
+
+               /* 4first some basic error checking */
+       if ( (rc = ga_echeck(hostname, servname, &hints)) != 0)
+               error(rc);
+
+#ifdef UNIXDOMAIN
+       /*
+        * Special case Unix domain first;
+        * remainder of function for IPv4/IPv6.
+        */
+       if (hostname != NULL && hostname[0] == '/' &&
+           (servname == NULL || servname[0] == '\0'))
+               return(ga_unix(hostname, &hints, result));
+
+       if (servname != NULL && servname[0] == '/' &&
+           (hostname == NULL || hostname[0] == '\0'))
+               return(ga_unix(servname, &hints, result));
+#endif
+
+       nsearch = ga_nsearch(hostname, &hints, &search[0]);
+
+       aihead = NULL;
+       aipnext = &aihead;
+       for (sptr = &search[0]; sptr < &search[nsearch]; sptr++) {
+#ifdef IPV4
+                       /* 4check for an IPv4 dotted-decimal string */
+               if (isdigit(sptr->host[0])) {
+                       struct in_addr  inaddr;
+
+                       if (inet_pton(AF_INET, sptr->host, &inaddr) == 1) {
+                               rc = ga_aistruct(&aipnext, &hints, &inaddr, AF_INET);
+                               if (rc != 0)
+                                       error(rc);
+                               continue;
+                       }
+               }
+#endif
+       
+#ifdef IPV6
+                       /* 4check for an IPv6 hex string */
+               if (isxdigit(sptr->host[0]) || sptr->host[0] == ':') {
+                       struct in6_addr in6addr;
+
+                       if (inet_pton(AF_INET6, sptr->host, &in6addr) == 1) {
+                               rc = ga_aistruct(&aipnext, &hints, &in6addr, AF_INET6);
+                               if (rc != 0)
+                                       error(rc);
+                               continue;
+                       }
+               }
+#endif
+                       /* 4look up hostname */
+               if ((_res.options & RES_INIT) == 0)
+                       res_init();                     /* need this to set _res.options */
+
+               if (nsearch == 2)
+                       hptr = gethostbyname2(sptr->host, sptr->family);
+               else {
+#ifdef IPV6
+                       if (sptr->family == AF_INET6)
+                               _res.options |= RES_USE_INET6;
+                       else
+                               _res.options &= ~RES_USE_INET6;
+#endif
+                       hptr = gethostbyname(sptr->host);
+               }
+               if (hptr == NULL) {
+                       switch (h_errno) {
+                               case HOST_NOT_FOUND:    error(EAI_NONAME);
+                               case TRY_AGAIN:                 error(EAI_AGAIN);
+                               case NO_RECOVERY:               error(EAI_FAIL);
+                               case NO_DATA:                   error(EAI_NODATA);
+                               default:                                error(EAI_NONAME);
+                       }
+               }
+       
+                       /* 4check for address family mismatch if one specified */
+               if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype)
+                       error(EAI_ADDRFAMILY);
+       
+                       /* 4create one addrinfo{} for each returned address */
+               for (ap = hptr->h_addr_list; *ap != NULL; ap++) {
+                       if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL)
+                               error(EAI_MEMORY);
+                       *aipnext = ai;
+                       aipnext = &ai->ai_next;
+                       rc = ga_aistruct(&aipnext, &hints, *ap, hptr->h_addrtype);
+                       if (rc != 0)
+                               error(rc);
+               }
+       }
+       /* "aihead" points to the first structure in the linked list */
+
+       if (hostname != NULL && hostname[0] != '\0' &&
+               hints.ai_flags & AI_CANONNAME) {
+               aihead->ai_canonname = strdup(hptr->h_name != NULL ?
+                                                                         hptr->h_name : search[0].host);
+               if (aihead->ai_canonname == NULL)
+                       error(EAI_MEMORY);
+       }
+
+               /* 4now process the service name */
+       if (servname != NULL && servname[0] != '\0') {
+               if ( (rc = ga_serv(aihead, &hints, servname)) != 0)
+                       error(rc);
+       }
+
+       *result = aihead;       /* pointer to first structure in linked list */
+       return(0);
+
+bad:
+       freeaddrinfo(aihead);   /* free any alloc'ed memory */
+       return(error);
+}
+
+/*
+ * Basic error checking at the beginning.
+ */
+
+static int
+ga_echeck(const char *hostname, const char *servname,
+                 const struct addrinfo *hintsp)
+{
+       if (hintsp->ai_flags & ~(AI_PASSIVE | AI_CANONNAME))
+               return(EAI_BADFLAGS);   /* unknown flag bits */
+
+       if (hostname == NULL || hostname[0] == '\0') {
+               if (servname == NULL || servname[0] == '\0')
+                       return(EAI_NONAME);     /* host or service must be specified */
+       }
+
+       switch(hintsp->ai_family) {
+               case AF_UNSPEC:
+                       break;
+#ifdef IPV4
+               case AF_INET:
+                       if (hintsp->ai_socktype != 0 &&
+                               (hintsp->ai_socktype != SOCK_STREAM &&
+                                hintsp->ai_socktype != SOCK_DGRAM &&
+                                hintsp->ai_socktype != SOCK_RAW))
+                               return(EAI_SOCKTYPE);   /* invalid socket type */
+                       break;
+#endif
+#ifdef IPV6
+               case AF_INET6:
+                       if (hintsp->ai_socktype != 0 &&
+                               (hintsp->ai_socktype != SOCK_STREAM &&
+                                hintsp->ai_socktype != SOCK_DGRAM &&
+                                hintsp->ai_socktype != SOCK_RAW))
+                               return(EAI_SOCKTYPE);   /* invalid socket type */
+                       break;
+#endif
+#ifdef UNIXDOMAIN
+               case AF_LOCAL:
+                       if (hintsp->ai_socktype != 0 &&
+                               (hintsp->ai_socktype != SOCK_STREAM &&
+                                hintsp->ai_socktype != SOCK_DGRAM))
+                               return(EAI_SOCKTYPE);   /* invalid socket type */
+                       break;
+#endif
+               default:
+                       return(EAI_FAMILY);             /* unknown protocol family */
+       }
+       return(0);
+}
+
+/*
+ * Set up the search[] array with the hostnames and address families
+ * that we are to look up.
+ */
+
+static int
+ga_nsearch(const char *hostname, const struct addrinfo *hintsp,
+                  struct search *search)
+{
+       int             nsearch = 0;
+
+       if (hostname == NULL || hostname[0] == '\0') {
+               if (hintsp->ai_flags & AI_PASSIVE) {
+                               /* 4no hostname and AI_PASSIVE: implies wildcard bind */
+                       switch (hintsp->ai_family) {
+#ifdef IPV4
+                       case AF_INET:
+                               search[nsearch].host = "0.0.0.0";
+                               search[nsearch].family = AF_INET;
+                               nsearch++;
+                               break;
+#endif
+#ifdef IPV6
+                       case AF_INET6:
+                               search[nsearch].host = "0::0";
+                               search[nsearch].family = AF_INET6;
+                               nsearch++;
+                               break;
+#endif
+                       case AF_UNSPEC:
+#ifdef IPV6
+                               search[nsearch].host = "0::0";  /* IPv6 first, then IPv4 */
+                               search[nsearch].family = AF_INET6;
+                               nsearch++;
+#endif
+#ifdef IPV4
+                               search[nsearch].host = "0.0.0.0";
+                               search[nsearch].family = AF_INET;
+                               nsearch++;
+#endif
+                               break;
+                       }
+               } else {
+                               /* 4no host and not AI_PASSIVE: connect to local host */
+                       switch (hintsp->ai_family) {
+#ifdef IPV4
+                       case AF_INET:
+                               search[nsearch].host = "localhost";     /* 127.0.0.1 */
+                               search[nsearch].family = AF_INET;
+                               nsearch++;
+                               break;
+#endif
+#ifdef IPV6
+                       case AF_INET6:
+                               search[nsearch].host = "0::1";
+                               search[nsearch].family = AF_INET6;
+                               nsearch++;
+                               break;
+#endif
+                       case AF_UNSPEC:
+#ifdef IPV6
+                               search[nsearch].host = "0::1";  /* IPv6 first, then IPv4 */
+                               search[nsearch].family = AF_INET6;
+                               nsearch++;
+#endif
+#ifdef IPV4
+                               search[nsearch].host = "localhost";
+                               search[nsearch].family = AF_INET;
+                               nsearch++;
+#endif
+                               break;
+                       }
+               }
+       } else {        /* host is specified */
+               switch (hintsp->ai_family) {
+#ifdef IPV4
+               case AF_INET:
+                       search[nsearch].host = hostname;
+                       search[nsearch].family = AF_INET;
+                       nsearch++;
+                       break;
+#endif
+#ifdef IPV6
+               case AF_INET6:
+                       search[nsearch].host = hostname;
+                       search[nsearch].family = AF_INET6;
+                       nsearch++;
+                       break;
+#endif
+               case AF_UNSPEC:
+#ifdef IPV6
+                       search[nsearch].host = hostname;
+                       search[nsearch].family = AF_INET6;      /* IPv6 first */
+                       nsearch++;
+#endif
+#ifdef IPV4
+                       search[nsearch].host = hostname;
+                       search[nsearch].family = AF_INET;       /* then IPv4 */
+                       nsearch++;
+#endif
+                       break;
+               }
+       }
+       if (nsearch < 1 || nsearch > 2)
+               err_quit("nsearch = %d", nsearch);
+       return(nsearch);
+}
+
+/*
+ * Create and fill in a addrinfo{}.
+ */
+
+static int
+ga_aistruct(struct addrinfo ***paipnext, const struct addrinfo *hintsp,
+                       void *addr, int family)
+{
+       struct addrinfo *ai;
+
+       if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL)
+               return(EAI_MEMORY);
+       ai->ai_next = NULL;
+       ai->ai_canonname = NULL;
+       **paipnext = ai;
+       *paipnext = &ai->ai_next;
+
+       if ( (ai->ai_socktype = hintsp->ai_socktype) == 0)
+               ai->ai_flags |= AI_CLONE;
+
+       ai->ai_protocol = hintsp->ai_protocol;
+       
+       switch ((ai->ai_family = family)) {
+#ifdef IPV4
+               case AF_INET: {
+                       struct sockaddr_in      *sinptr;
+
+                               /* 4allocate sockaddr_in{} and fill in all but port */
+                       if ( (sinptr = calloc(1, sizeof(struct sockaddr_in))) == NULL)
+                               return(EAI_MEMORY);
+#ifdef HAVE_SOCKADDR_SA_LEN
+                       sinptr->sin_len = sizeof(struct sockaddr_in);
+#endif
+                       sinptr->sin_family = AF_INET;
+                       memcpy(&sinptr->sin_addr, addr, sizeof(struct in_addr));
+                       ai->ai_addr = (struct sockaddr *) sinptr;
+                       ai->ai_addrlen = sizeof(struct sockaddr_in);
+                       break;
+               }
+#endif /* IPV4 */
+       
+#ifdef IPV6
+                               /* 4allocate sockaddr_in6{} and fill in all but port */
+               case AF_INET6: {
+                       struct sockaddr_in6     *sin6ptr;
+
+                       if ( (sin6ptr = calloc(1, sizeof(struct sockaddr_in6))) == NULL)
+                               return(EAI_MEMORY);
+#ifdef HAVE_SOCKADDR_SA_LEN
+                       sin6ptr->sin6_len = sizeof(struct sockaddr_in6);
+#endif
+                       sin6ptr->sin6_family = AF_INET6;
+                       memcpy(&sin6ptr->sin6_addr, addr, sizeof(struct in6_addr));
+                       ai->ai_addr = (struct sockaddr *) sin6ptr;
+                       ai->ai_addrlen = sizeof(struct sockaddr_in6);
+                       break;
+               }
+#endif /* IPV6 */
+       }
+       return(0);
+}
+
+/*
+ * This function handles the service string.
+ */
+
+static int
+ga_serv(struct addrinfo *aihead, const struct addrinfo *hintsp,
+               const char *serv)
+{
+       int                             port, rc, nfound;
+       struct servent  *sptr;
+
+               /* 4check for port number first */
+       if (isdigit(serv[0]) && hintsp->ai_socktype != 0) {
+               port = htons(atoi(serv));
+               if ( (rc = ga_port(aihead, port, hintsp->ai_socktype)) == 0)
+                       return(EAI_NONAME);
+               else if (rc < 0)
+                       return(EAI_MEMORY);
+               else
+                       return(0);
+       }
+
+               /* 4try TCP first */
+       nfound = 0;
+       if (hintsp->ai_socktype == 0 || hintsp->ai_socktype == SOCK_STREAM) {
+               if ( (sptr = getservbyname(serv, "tcp")) != NULL) {
+                       if ( (rc = ga_port(aihead, sptr->s_port, SOCK_STREAM)) < 0)
+                               return(EAI_MEMORY);
+                       nfound += rc;
+               }
+       }
+
+               /* 4try UDP */
+       if (hintsp->ai_socktype == 0 || hintsp->ai_socktype == SOCK_DGRAM) {
+               if ( (sptr = getservbyname(serv, "udp")) != NULL) {
+                       if ( (rc = ga_port(aihead, sptr->s_port, SOCK_DGRAM)) < 0)
+                               return(EAI_MEMORY);
+                       nfound += rc;
+               }
+       }
+
+       if (nfound == 0) {
+               if (hintsp->ai_socktype == 0)
+                       return(EAI_NONAME);     /* all calls to getservbyname() failed */
+               else
+                       return(EAI_SERVICE);/* service not supported for socket type */
+       }
+       return(0);
+}
+
+/*
+ * Go through all the addrinfo structures, checking for a match of the
+ * socket type and filling in the socket type, and then the port number
+ * in the corresponding socket address structures.
+ *
+ * The AI_CLONE flag works as follows.  Consider a multihomed host with
+ * two IP addresses and no socket type specified by the caller.  After
+ * the "host" search there are two addrinfo structures, one per IP address.
+ * Assuming a service supported by both TCP and UDP (say the daytime
+ * service) we need to return *four* addrinfo structures:
+ *             IP#1, SOCK_STREAM, TCP port,
+ *             IP#1, SOCK_DGRAM, UDP port,
+ *             IP#2, SOCK_STREAM, TCP port,
+ *             IP#2, SOCK_DGRAM, UDP port.
+ * To do this, when the "host" loop creates an addrinfo structure, if the
+ * caller has not specified a socket type (hintsp->ai_socktype == 0), the
+ * AI_CLONE flag is set.  When the following function finds an entry like
+ * this it is handled as follows: If the entry's ai_socktype is still 0,
+ * this is the first use of the structure, and the ai_socktype field is set.
+ * But, if the entry's ai_socktype is nonzero, then we clone a new addrinfo
+ * structure and set it's ai_socktype to the new value.  Although we only
+ * need two socket types today (SOCK_STREAM and SOCK_DGRAM) this algorithm
+ * will handle any number.  Also notice that Posix.1g requires all socket
+ * types to be nonzero.
+ */
+
+static int
+ga_port(struct addrinfo *aihead, int port, int socktype)
+               /* port must be in network byte order */
+{
+       int                             nfound = 0;
+       struct addrinfo *ai;
+
+       for (ai = aihead; ai != NULL; ai = ai->ai_next) {
+               if (ai->ai_flags & AI_CLONE) {
+                       if (ai->ai_socktype != 0) {
+                               if ( (ai = ga_clone(ai)) == NULL)
+                                       return(-1);             /* memory allocation error */
+                               /* ai points to newly cloned entry, which is what we want */
+                       }
+               } else if (ai->ai_socktype != socktype)
+                       continue;               /* ignore if mismatch on socket type */
+
+               ai->ai_socktype = socktype;
+
+               switch (ai->ai_family) {
+#ifdef IPV4
+                       case AF_INET:
+                               ((struct sockaddr_in *) ai->ai_addr)->sin_port = port;
+                               nfound++;
+                               break;
+#endif
+#ifdef IPV6
+                       case AF_INET6:
+                               ((struct sockaddr_in6 *) ai->ai_addr)->sin6_port = port;
+                               nfound++;
+                               break;
+#endif
+               }
+       }
+       return(nfound);
+}
+
+/*
+ * Clone a new addrinfo structure from an existing one.
+ */
+
+static struct addrinfo *
+ga_clone(struct addrinfo *ai)
+{
+       struct addrinfo *new;
+
+       if ( (new = calloc(1, sizeof(struct addrinfo))) == NULL)
+               return(NULL);
+
+       new->ai_next = ai->ai_next;
+       ai->ai_next = new;
+
+       new->ai_flags = 0;                              /* make sure AI_CLONE is off */
+       new->ai_family = ai->ai_family;
+       new->ai_socktype = ai->ai_socktype;
+       new->ai_protocol = ai->ai_protocol;
+       new->ai_canonname = NULL;
+       new->ai_addrlen = ai->ai_addrlen;
+       if ( (new->ai_addr = malloc(ai->ai_addrlen)) == NULL)
+               return(NULL);
+       memcpy(new->ai_addr, ai->ai_addr, ai->ai_addrlen);
+
+       return(new);
+}
+
+#ifdef UNIXDOMAIN
+/*
+ * Do everything for a Unix domain socket.
+ * Only one addrinfo{} is returned.
+ */
+
+static int
+ga_unix(const char *path, struct addrinfo *hintsp, struct addrinfo **result)
+{
+       struct addrinfo         *ai;
+       struct sockaddr_un      *unp;
+
+       if (hintsp->ai_socktype == 0)
+               return(EAI_SOCKTYPE);   /* we cannot tell socket type from service */
+
+       if ( (ai = calloc(1, sizeof(struct addrinfo))) == NULL)
+               return(NULL);
+
+       ai->ai_flags = 0;
+       ai->ai_family = AF_LOCAL;
+       ai->ai_socktype = hintsp->ai_socktype;
+       ai->ai_protocol = 0;
+
+               /* allocate and fill in a socket address structure */
+       ai->ai_addrlen = sizeof(struct sockaddr_un);
+       if ( (ai->ai_addr = malloc(ai->ai_addrlen)) == NULL)
+               return(EAI_MEMORY);
+       unp = (struct sockaddr_un *) ai->ai_addr;
+       unp->sun_family = AF_UNIX;
+       strncpy(unp->sun_path, path, sizeof(unp->sun_path));
+
+       ai->ai_canonname = NULL;        /* maybe return the i-node number :-) */
+       ai->ai_next = NULL;
+       *result = ai;
+
+       if (hintsp->ai_flags & AI_PASSIVE)
+               unlink(path);           /* OK if this fails */
+
+       return(0);              /* success */
+}
+#endif /* UNIXDOMAIN */
+
+void
+freeaddrinfo(struct addrinfo *aihead)
+{
+       struct addrinfo *ai, *ainext;
+
+       for (ai = aihead; ai != NULL; ai = ainext) {
+               if (ai->ai_addr != NULL)
+                       free(ai->ai_addr);              /* the socket address structure */
+               if (ai->ai_canonname != NULL)
+                       free(ai->ai_canonname); /* the canonical name */
+               ainext = ai->ai_next;           /* can't fetch ai_next after free() */
+               free(ai);                                       /* the addrinfo{} itself */
+       }
+}
diff --git a/libgai/test1.c b/libgai/test1.c
new file mode 100644 (file)
index 0000000..8d35c55
--- /dev/null
@@ -0,0 +1,28 @@
+#include       "unp.h"
+
+/*
+ * See that gethostbyname2() with an address string as the first argument
+ * is broken in BIND-8.1-REL.
+ * gethostbyname2("127.0.0.1", AF_INET6) -> OK!
+ */
+
+int
+main(int argc, char **argv)
+{
+       struct hostent  *hptr;
+
+       if (argc != 2)
+               err_quit("usage: test2 <IPaddress>");
+
+       printf("gethostbyname2(%s, AF_INET): ", argv[1]);
+       hptr = gethostbyname2(argv[1], AF_INET);
+       printf("%s\n", (hptr == NULL) ? "failed" : "OK");
+
+#ifdef IPv6
+       printf("gethostbyname2(%s, AF_INET6): ", argv[1]);
+       hptr = gethostbyname2(argv[1], AF_INET6);
+       printf("%s\n", (hptr == NULL) ? "failed" : "OK");
+#endif
+
+       exit(0);
+}
diff --git a/libgai/testga.c b/libgai/testga.c
new file mode 100644 (file)
index 0000000..b363f67
--- /dev/null
@@ -0,0 +1,357 @@
+#include       "unp.h"
+
+/*
+ * Test program for getaddrinfo() and getnameinfo().
+ */
+
+                       /* function prototypes for internal functions */
+static void    do_errtest(void);
+static void    do_funccall(const char *, const char *, int, int, int, int, int);
+static int     do_onetest(char *, char *, struct addrinfo *, int);
+static const char *str_fam(int);
+static const char *str_sock(int);
+static void    usage(const char *);
+
+                       /* globals */
+int            vflag;
+
+int
+main(int argc, char **argv)
+{
+       int                             doerrtest = 0;
+       int                             loopcount = 1;
+       int                             c, i;
+       char                    *host = NULL;
+       char                    hostbuf[NI_MAXHOST];
+       char                    *serv = NULL;
+       char                    servbuf[NI_MAXSERV];
+       struct protoent *proto;
+       struct addrinfo hints;          /* set by command-line options */
+
+       if (argc < 2)
+               usage("");
+
+       memset(&hints, 0, sizeof(struct addrinfo));
+
+       opterr = 0;             /* don't want getopt() writing to stderr */
+       while ( (c = getopt(argc, argv, "cef:h:l:pr:s:t:v")) != -1) {
+               switch (c) {
+               case 'c':
+                       hints.ai_flags |= AI_CANONNAME;
+                       break;
+
+               case 'e':
+                       doerrtest = 1;
+                       break;
+
+               case 'f':                       /* address family */
+#ifdef IPv4
+                       if (strcmp(optarg, "inet") == 0) {
+                               hints.ai_family = AF_INET;
+                               break;
+                       }
+#endif
+#ifdef IPv6
+                       if (strcmp(optarg, "inet6") == 0) {
+                               hints.ai_family = AF_INET6;
+                               break;
+                       }
+#endif
+#ifdef UNIXdomain
+                       if (strcmp(optarg, "unix") == 0) {
+                               hints.ai_family = AF_LOCAL;
+                               break;
+                       }
+#endif
+                       usage("invalid -f option");
+
+               case 'h':                       /* host */
+                       strncpy(hostbuf, optarg, NI_MAXHOST-1);
+                       host = hostbuf;
+                       break;
+
+               case 'l':                       /* loop count */
+                       loopcount = atoi(optarg);
+                       break;
+
+               case 'p':
+                       hints.ai_flags |= AI_PASSIVE;
+                       break;
+
+               case 'r':                       /* protocol */
+                       if ((proto = getprotobyname(optarg)) == NULL) {
+                               hints.ai_protocol = atoi(optarg);
+                       } else {
+                               hints.ai_protocol = proto->p_proto;
+                       }
+                       break;
+
+               case 's':
+                       strncpy(servbuf, optarg, NI_MAXSERV-1);
+                       serv = servbuf;
+                       break;
+
+               case 't':                       /* socket type */
+                       if (strcmp(optarg, "stream") == 0) {
+                               hints.ai_socktype = SOCK_STREAM;
+                               break;
+                       }
+
+                       if (strcmp(optarg, "dgram") == 0) {
+                               hints.ai_socktype = SOCK_DGRAM;
+                               break;
+                       }
+
+                       if (strcmp(optarg, "raw") == 0) {
+                               hints.ai_socktype = SOCK_RAW;
+                               break;
+                       }
+
+#ifdef SOCK_RDM
+                       if (strcmp(optarg, "rdm") == 0) {
+                               hints.ai_socktype = SOCK_RDM;
+                               break;
+                       }
+#endif
+
+#ifdef SOCK_SEQPACKET
+                       if (strcmp(optarg, "seqpacket") == 0) {
+                               hints.ai_socktype = SOCK_SEQPACKET;
+                               break;
+                       }
+#endif
+                       usage("invalid -t option");
+
+               case 'v':
+                       vflag = 1;
+                       break;
+
+               case '?':
+                       usage("unrecognized option");
+               }
+       }
+       if (optind < argc) {
+               usage("extra args");
+       }
+
+       if (doerrtest) {
+               do_errtest();
+               exit(0);
+       }
+
+       for (i = 1; i <= loopcount; i++) {
+               if (do_onetest(host, serv, &hints, i) > 0)
+                       exit(1);
+
+               if (i % 1000 == 0) {
+                       printf(" %d", i);
+                       fflush(stdout);
+               }
+       }
+
+       exit(0);
+}
+
+/*
+ * Check that the right error codes are returned for invalid input.
+ * Test all the errors that are easy to test for.
+ */
+
+static void
+do_errtest(void)
+{
+               /* passive open with no hostname and no address family */
+       do_funccall(NULL, "ftp", AI_PASSIVE, 0, 0, 0, 0);
+
+               /* kind of hard to automatically test EAI_AGAIN ??? */
+
+               /* invalid flags */
+       do_funccall("localhost", NULL, 999999, 0, 0, 0, EAI_BADFLAGS);
+
+               /* how to test EAI_FAIL ??? */
+
+               /* invalid address family */
+       do_funccall("localhost", NULL, 0, AF_SNA, 0, 0, EAI_FAMILY);
+
+               /* hard to test for EAI_MEMORY: would have to malloc() until
+                  failure, then give some back, then call getaddrinfo and
+                  hope that its memory requests would not be satisfied. */
+
+               /* to test for EAI_NODATA: would have to know of a host with
+                  no A record in the DNS */
+
+#ifdef notdef  /* following depends on resolver, sigh */
+               /* believe it or not, there is a registered domain "bar.com",
+                  so the following should generate NO_DATA from the DNS */
+       do_funccall("foo.bar.foo.bar.foo.bar.com", NULL, 0, 0, 0, 0, EAI_NODATA);
+#endif
+
+               /* no hostname, no service name */
+       do_funccall(NULL, NULL, 0, 0, 0, 0, EAI_NONAME);
+
+               /* invalid hostname (should be interpreted in local default domain) */
+       do_funccall("lkjjkhjhghgfgfd", NULL, 0, 0, 0, 0, EAI_NONAME);
+
+               /* invalid service name */
+       do_funccall(NULL, "nosuchservice", 0, 0, 0, 0, EAI_NONAME);
+
+               /* service valid but not supported for socket type */
+       do_funccall("localhost", "telnet", 0, 0, SOCK_DGRAM, 0, EAI_SERVICE);
+
+               /* service valid but not supported for socket type */
+       do_funccall("localhost", "tftp", 0, 0, SOCK_STREAM, 0, EAI_SERVICE);
+
+               /* invalid socket type */
+       do_funccall("localhost", NULL, 0, AF_INET, SOCK_SEQPACKET, 0, EAI_SOCKTYPE);
+
+               /* EAI_SYSTEM not generated by my implementation */
+}
+
+static void
+do_funccall(const char *host, const char *serv,
+                       int flags, int family, int socktype, int protocol, int exprc)
+{
+       int                             rc;
+       struct addrinfo hints, *res;
+
+       memset(&hints, 0, sizeof(struct addrinfo));
+       hints.ai_flags = flags;
+       hints.ai_family = family;
+       hints.ai_socktype = socktype;
+       hints.ai_protocol = protocol;
+
+       rc = getaddrinfo(host, serv, &hints, &res);
+       if (rc != exprc) {
+               printf("expected return = %d (%s),\nactual return = %d (%s)\n",
+                               exprc, gai_strerror(exprc), rc, gai_strerror(rc));
+               if (host != NULL)
+                       printf("  host = %s\n", host);
+               if (serv != NULL)
+                       printf("  serv = %s\n", serv);
+               printf("  flags = %d, family = %s, socktype = %s, protocol = %d\n",
+                               flags, str_fam(family), str_sock(socktype), protocol);
+               exit(2);
+       }
+}
+
+static int
+do_onetest(char *host, char *serv, struct addrinfo *hints, int iteration)
+{
+       int                             rc, fd, verbose;
+       struct addrinfo *res, *rescopy;
+       char                    rhost[NI_MAXHOST], rserv[NI_MAXSERV];
+
+       verbose = vflag && (iteration == 1);    /* only first time */
+
+       if (host != NULL && verbose)
+               printf("host = %s\n", host);
+       if (serv != NULL && verbose)
+               printf("serv = %s\n", serv);
+
+       rc = getaddrinfo(host, serv, hints, &res);
+       if (rc != 0) {
+               printf("getaddrinfo return code = %d (%s)\n", rc, gai_strerror(rc));
+               return(1);
+       }
+
+       rescopy = res;
+       do {
+               if (iteration == 1) {   /* always print results first time */
+                       printf("\nsocket(%s, %s, %d)", str_fam(res->ai_family),
+                                       str_sock(res->ai_socktype), res->ai_protocol);
+
+                               /* canonname should be set only in first addrinfo{} */
+                       if (hints->ai_flags & AI_CANONNAME) {
+                               if (res->ai_canonname)
+                                       printf(", ai_canonname = %s", res->ai_canonname);
+                       }
+                       printf("\n");
+
+                       printf("\taddress: %s\n",
+                                  Sock_ntop(res->ai_addr, res->ai_addrlen));
+               }
+
+                       /* Call socket() to make sure return values are valid */
+               fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+               if (fd < 0)
+                       printf("call to socket() failed!\n");
+               else
+                       close(fd);
+
+               /*
+                * Call getnameinfo() to check the reverse mapping.
+                */
+
+               rc = getnameinfo(res->ai_addr, res->ai_addrlen,
+                                                rhost, NI_MAXHOST, rserv, NI_MAXSERV,
+                                                (res->ai_socktype == SOCK_DGRAM) ? NI_DGRAM: 0);
+               if (rc == 0) {
+                       if (verbose)
+                               printf("\tgetnameinfo: host = %s, serv = %s\n",
+                                          rhost, rserv);
+               } else
+                       printf("getnameinfo returned %d (%s)\n", rc, gai_strerror(rc));
+
+       } while ( (res = res->ai_next) != NULL);
+
+       freeaddrinfo(rescopy);
+       return(0);
+}
+
+static void
+usage(const char *msg)
+{
+       printf(
+"usage: testaddrinfo [ options ]\n"
+"options: -h <host>    (can be hostname or address string)\n"
+"         -s <service> (can be service name or decimal port number)\n"
+"         -c    AI_CANONICAL flag\n"
+"         -p    AI_PASSIVE flag\n"
+"         -l N  loop N times (check for memory leaks with ps)\n"
+"         -f X  address family, X = inet, inet6, unix\n"
+"         -r X  protocol, X = tcp, udp, ... or number e.g. 6, 17, ...\n"
+"         -t X  socket type, X = stream, dgram, raw, rdm, seqpacket\n"
+"         -v    verbose\n"
+"         -e    only do test of error returns (no options required)\n"
+"  without -e, one or both of <host> and <service> must be specified.\n"
+);
+
+       if (msg[0] != 0)
+               printf("%s\n", msg);
+       exit(1);
+}
+
+static const char *
+str_fam(int family)
+{
+#ifdef IPv4
+       if (family == AF_INET)
+               return("AF_INET");
+#endif
+#ifdef IPv6
+       if (family == AF_INET6)
+               return("AF_INET6");
+#endif
+#ifdef UNIXdomain
+       if (family == AF_LOCAL)
+               return("AF_LOCAL");
+#endif
+       return("<unknown family>");
+}
+
+static const char *
+str_sock(int socktype)
+{
+       switch(socktype) {
+       case SOCK_STREAM:       return "SOCK_STREAM";
+       case SOCK_DGRAM:        return "SOCK_DGRAM";
+       case SOCK_RAW:          return "SOCK_RAW";
+#ifdef SOCK_RDM
+       case SOCK_RDM:          return "SOCK_RDM";
+#endif
+#ifdef SOCK_SEQPACKET
+       case SOCK_SEQPACKET:return "SOCK_SEQPACKET";
+#endif
+       default:                return "<unknown socktype>";
+       }
+}
diff --git a/libroute/Makefile b/libroute/Makefile
new file mode 100644 (file)
index 0000000..d5b5220
--- /dev/null
@@ -0,0 +1,8 @@
+include ../Make.defines
+
+all:   ${LIBROUTE_OBJS}
+               ar rv ${LIBUNP_NAME} $?
+               ${RANLIB} ${LIBUNP_NAME}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/libroute/get_rtaddrs.c b/libroute/get_rtaddrs.c
new file mode 100644 (file)
index 0000000..203fefe
--- /dev/null
@@ -0,0 +1,28 @@
+#include       "unproute.h"
+
+/*
+ * Round up 'a' to next multiple of 'size', which must be a power of 2
+ */
+#define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
+
+/*
+ * Step to next socket address structure;
+ * if sa_len is 0, assume it is sizeof(u_long).
+ */
+#define NEXT_SA(ap)    ap = (SA *) \
+       ((caddr_t) ap + (ap->sa_len ? ROUNDUP(ap->sa_len, sizeof (u_long)) : \
+                                                                       sizeof(u_long)))
+
+void
+get_rtaddrs(int addrs, SA *sa, SA **rti_info)
+{
+       int             i;
+
+       for (i = 0; i < RTAX_MAX; i++) {
+               if (addrs & (1 << i)) {
+                       rti_info[i] = sa;
+                       NEXT_SA(sa);
+               } else
+                       rti_info[i] = NULL;
+       }
+}
diff --git a/libroute/get_rtaddrs.lc b/libroute/get_rtaddrs.lc
new file mode 100644 (file)
index 0000000..54e5d87
--- /dev/null
@@ -0,0 +1,28 @@
+#include    "unproute.h"##  1 ##src/libroute/get_rtaddrs.c##
+
+/*##  2 ##src/libroute/get_rtaddrs.c##
+ * Round up 'a' to next multiple of 'size'##  3 ##src/libroute/get_rtaddrs.c##
+ */##  4 ##src/libroute/get_rtaddrs.c##
+#define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))##  5 ##src/libroute/get_rtaddrs.c##
+
+/*##  6 ##src/libroute/get_rtaddrs.c##
+ * Step to next socket address structure;##  7 ##src/libroute/get_rtaddrs.c##
+ * if sa_len is 0, assume it is sizeof(u_long).##  8 ##src/libroute/get_rtaddrs.c##
+ */##  9 ##src/libroute/get_rtaddrs.c##
+#define NEXT_SA(ap) ap = (SA *) \## 10 ##src/libroute/get_rtaddrs.c##
+    ((caddr_t) ap + (ap->sa_len ? ROUNDUP(ap->sa_len, sizeof (u_long)) : \## 11 ##src/libroute/get_rtaddrs.c##
+                                    sizeof(u_long)))## 12 ##src/libroute/get_rtaddrs.c##
+
+void## 13 ##src/libroute/get_rtaddrs.c##
+get_rtaddrs(int addrs, SA *sa, SA **rti_info)## 14 ##src/libroute/get_rtaddrs.c##
+{## 15 ##src/libroute/get_rtaddrs.c##
+    int     i;## 16 ##src/libroute/get_rtaddrs.c##
+
+    for (i = 0; i < RTAX_MAX; i++) {## 17 ##src/libroute/get_rtaddrs.c##
+        if (addrs & (1 << i)) {## 18 ##src/libroute/get_rtaddrs.c##
+            rti_info[i] = sa;## 19 ##src/libroute/get_rtaddrs.c##
+            NEXT_SA(sa);## 20 ##src/libroute/get_rtaddrs.c##
+        } else## 21 ##src/libroute/get_rtaddrs.c##
+            rti_info[i] = NULL;## 22 ##src/libroute/get_rtaddrs.c##
+    }## 23 ##src/libroute/get_rtaddrs.c##
+}## 24 ##src/libroute/get_rtaddrs.c##
diff --git a/libroute/if_indextoname.c b/libroute/if_indextoname.c
new file mode 100644 (file)
index 0000000..357c11b
--- /dev/null
@@ -0,0 +1,51 @@
+/* include if_indextoname */
+#include       "unpifi.h"
+#include       "unproute.h"
+
+char *
+if_indextoname(unsigned int idx, char *name)
+{
+       char                            *buf, *next, *lim;
+       size_t                          len;
+       struct if_msghdr        *ifm;
+       struct sockaddr         *sa, *rti_info[RTAX_MAX];
+       struct sockaddr_dl      *sdl;
+
+       if ( (buf = net_rt_iflist(0, idx, &len)) == NULL)
+               return(NULL);
+
+       lim = buf + len;
+       for (next = buf; next < lim; next += ifm->ifm_msglen) {
+               ifm = (struct if_msghdr *) next;
+               if (ifm->ifm_type == RTM_IFINFO) {
+                       sa = (struct sockaddr *) (ifm + 1);
+                       get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
+                       if ( (sa = rti_info[RTAX_IFP]) != NULL) {
+                               if (sa->sa_family == AF_LINK) {
+                                       sdl = (struct sockaddr_dl *) sa;
+                                       if (sdl->sdl_index == idx) {
+                                               int slen = min(IFNAMSIZ - 1, sdl->sdl_nlen);
+                                               strncpy(name, sdl->sdl_data, slen);
+                                               name[slen] = 0; /* null terminate */
+                                               free(buf);
+                                               return(name);
+                                       }
+                               }
+                       }
+
+               }
+       }
+       free(buf);
+       return(NULL);           /* no match for index */
+}
+/* end if_indextoname */
+
+char *
+If_indextoname(unsigned int idx, char *name)
+{
+       char    *ptr;
+
+       if ( (ptr = if_indextoname(idx, name)) == NULL)
+               err_quit("if_indextoname error for %d", idx);
+       return(ptr);
+}
diff --git a/libroute/if_indextoname.lc b/libroute/if_indextoname.lc
new file mode 100644 (file)
index 0000000..1023b26
--- /dev/null
@@ -0,0 +1,50 @@
+/* include if_indextoname */
+#include    "unpifi.h"##  1 ##src/libroute/if_indextoname.c##
+#include    "unproute.h"##  2 ##src/libroute/if_indextoname.c##
+
+char   *##  3 ##src/libroute/if_indextoname.c##
+if_indextoname(unsigned int index, char *name)##  4 ##src/libroute/if_indextoname.c##
+{##  5 ##src/libroute/if_indextoname.c##
+    char   *buf, *next, *lim;##  6 ##src/libroute/if_indextoname.c##
+    size_t  len;##  7 ##src/libroute/if_indextoname.c##
+    struct if_msghdr *ifm;##  8 ##src/libroute/if_indextoname.c##
+    struct sockaddr *sa, *rti_info[RTAX_MAX];##  9 ##src/libroute/if_indextoname.c##
+    struct sockaddr_dl *sdl;## 10 ##src/libroute/if_indextoname.c##
+
+    if ((buf = net_rt_iflist(0, index, &len)) == NULL)## 11 ##src/libroute/if_indextoname.c##
+        return (NULL);## 12 ##src/libroute/if_indextoname.c##
+
+    lim = buf + len;## 13 ##src/libroute/if_indextoname.c##
+    for (next = buf; next < lim; next += ifm->ifm_msglen) {## 14 ##src/libroute/if_indextoname.c##
+        ifm = (struct if_msghdr *) next;## 15 ##src/libroute/if_indextoname.c##
+        if (ifm->ifm_type == RTM_IFINFO) {## 16 ##src/libroute/if_indextoname.c##
+            sa = (struct sockaddr *) (ifm + 1);## 17 ##src/libroute/if_indextoname.c##
+            get_rtaddrs(ifm->ifm_addrs, sa, rti_info);## 18 ##src/libroute/if_indextoname.c##
+            if ((sa = rti_info[RTAX_IFP]) != NULL) {## 19 ##src/libroute/if_indextoname.c##
+                if (sa->sa_family == AF_LINK) {## 20 ##src/libroute/if_indextoname.c##
+                    sdl = (struct sockaddr_dl *) sa;## 21 ##src/libroute/if_indextoname.c##
+                    if (sdl->sdl_index == index) {## 22 ##src/libroute/if_indextoname.c##
+                        strncpy(name, sdl->sdl_data, sdl->sdl_nlen);## 23 ##src/libroute/if_indextoname.c##
+                        name[sdl->sdl_nlen] = 0;    /* null terminate */## 24 ##src/libroute/if_indextoname.c##
+                        free(buf);## 25 ##src/libroute/if_indextoname.c##
+                        return (name);## 26 ##src/libroute/if_indextoname.c##
+                    }## 27 ##src/libroute/if_indextoname.c##
+                }## 28 ##src/libroute/if_indextoname.c##
+            }## 29 ##src/libroute/if_indextoname.c##
+
+        }## 30 ##src/libroute/if_indextoname.c##
+    }## 31 ##src/libroute/if_indextoname.c##
+    free(buf);## 32 ##src/libroute/if_indextoname.c##
+    return (NULL);              /* no match for index */## 33 ##src/libroute/if_indextoname.c##
+}## 34 ##src/libroute/if_indextoname.c##
+/* end if_indextoname */
+
+char   *## 35 ##src/libroute/if_indextoname.c##
+If_indextoname(unsigned int index, char *name)## 36 ##src/libroute/if_indextoname.c##
+{## 37 ##src/libroute/if_indextoname.c##
+    char   *ptr;## 38 ##src/libroute/if_indextoname.c##
+
+    if ((ptr = if_indextoname(index, name)) == NULL)## 39 ##src/libroute/if_indextoname.c##
+        err_quit("if_indextoname error for %d", index);## 40 ##src/libroute/if_indextoname.c##
+    return (ptr);## 41 ##src/libroute/if_indextoname.c##
+}## 42 ##src/libroute/if_indextoname.c##
diff --git a/libroute/if_nameindex.c b/libroute/if_nameindex.c
new file mode 100644 (file)
index 0000000..cf97c96
--- /dev/null
@@ -0,0 +1,67 @@
+/* include if_nameindex */
+#include       "unpifi.h"
+#include       "unproute.h"
+
+struct if_nameindex *
+if_nameindex(void)
+{
+       char                            *buf, *next, *lim;
+       size_t                          len;
+       struct if_msghdr        *ifm;
+       struct sockaddr         *sa, *rti_info[RTAX_MAX];
+       struct sockaddr_dl      *sdl;
+       struct if_nameindex     *result, *ifptr;
+       char                            *namptr;
+
+       if ( (buf = net_rt_iflist(0, 0, &len)) == NULL)
+               return(NULL);
+
+       if ( (result = malloc(len)) == NULL)    /* overestimate */
+               return(NULL);
+       ifptr = result;
+       namptr = (char *) result + len; /* names start at end of buffer */
+
+       lim = buf + len;
+       for (next = buf; next < lim; next += ifm->ifm_msglen) {
+               ifm = (struct if_msghdr *) next;
+               if (ifm->ifm_type == RTM_IFINFO) {
+                       sa = (struct sockaddr *) (ifm + 1);
+                       get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
+                       if ( (sa = rti_info[RTAX_IFP]) != NULL) {
+                               if (sa->sa_family == AF_LINK) {
+                                       sdl = (struct sockaddr_dl *) sa;
+                                       namptr -= sdl->sdl_nlen + 1;
+                                       strncpy(namptr, &sdl->sdl_data[0], sdl->sdl_nlen);
+                                       namptr[sdl->sdl_nlen] = 0;      /* null terminate */
+                                       ifptr->if_name = namptr;
+                                       ifptr->if_index = sdl->sdl_index;
+                                       ifptr++;
+                               }
+                       }
+
+               }
+       }
+       ifptr->if_name = NULL;  /* mark end of array of structs */
+       ifptr->if_index = 0;
+       free(buf);
+       return(result);                 /* caller must free() this when done */
+}
+/* end if_nameindex */
+
+/* include if_freenameindex */
+void
+if_freenameindex(struct if_nameindex *ptr)
+{
+       free(ptr);
+}
+/* end if_freenameindex */
+
+struct if_nameindex *
+If_nameindex(void)
+{
+       struct if_nameindex     *ifptr;
+
+       if ( (ifptr = if_nameindex()) == NULL)
+               err_quit("if_nameindex error");
+       return(ifptr);
+}
diff --git a/libroute/if_nameindex.lc b/libroute/if_nameindex.lc
new file mode 100644 (file)
index 0000000..cc1b684
--- /dev/null
@@ -0,0 +1,67 @@
+/* include if_nameindex */
+#include    "unpifi.h"##  1 ##src/libroute/if_nameindex.c##
+#include    "unproute.h"##  2 ##src/libroute/if_nameindex.c##
+
+struct if_nameindex *##  3 ##src/libroute/if_nameindex.c##
+if_nameindex(void)##  4 ##src/libroute/if_nameindex.c##
+{##  5 ##src/libroute/if_nameindex.c##
+    char   *buf, *next, *lim;##  6 ##src/libroute/if_nameindex.c##
+    size_t  len;##  7 ##src/libroute/if_nameindex.c##
+    struct if_msghdr *ifm;##  8 ##src/libroute/if_nameindex.c##
+    struct sockaddr *sa, *rti_info[RTAX_MAX];##  9 ##src/libroute/if_nameindex.c##
+    struct sockaddr_dl *sdl;## 10 ##src/libroute/if_nameindex.c##
+    struct if_nameindex *result, *ifptr;## 11 ##src/libroute/if_nameindex.c##
+    char   *namptr;## 12 ##src/libroute/if_nameindex.c##
+
+    if ((buf = net_rt_iflist(0, 0, &len)) == NULL)## 13 ##src/libroute/if_nameindex.c##
+        return (NULL);## 14 ##src/libroute/if_nameindex.c##
+
+    if ((result = malloc(len)) == NULL) /* overestimate */## 15 ##src/libroute/if_nameindex.c##
+        return (NULL);## 16 ##src/libroute/if_nameindex.c##
+    ifptr = result;## 17 ##src/libroute/if_nameindex.c##
+    namptr = (char *) result + len; /* names start at end of buffer */## 18 ##src/libroute/if_nameindex.c##
+
+    lim = buf + len;## 19 ##src/libroute/if_nameindex.c##
+    for (next = buf; next < lim; next += ifm->ifm_msglen) {## 20 ##src/libroute/if_nameindex.c##
+        ifm = (struct if_msghdr *) next;## 21 ##src/libroute/if_nameindex.c##
+        if (ifm->ifm_type == RTM_IFINFO) {## 22 ##src/libroute/if_nameindex.c##
+            sa = (struct sockaddr *) (ifm + 1);## 23 ##src/libroute/if_nameindex.c##
+            get_rtaddrs(ifm->ifm_addrs, sa, rti_info);## 24 ##src/libroute/if_nameindex.c##
+            if ((sa = rti_info[RTAX_IFP]) != NULL) {## 25 ##src/libroute/if_nameindex.c##
+                if (sa->sa_family == AF_LINK) {## 26 ##src/libroute/if_nameindex.c##
+                    sdl = (struct sockaddr_dl *) sa;## 27 ##src/libroute/if_nameindex.c##
+                    namptr -= sdl->sdl_nlen + 1;## 28 ##src/libroute/if_nameindex.c##
+                    strncpy(namptr, &sdl->sdl_data[0], sdl->sdl_nlen);## 29 ##src/libroute/if_nameindex.c##
+                    namptr[sdl->sdl_nlen] = 0;  /* null terminate */## 30 ##src/libroute/if_nameindex.c##
+                    ifptr->if_name = namptr;## 31 ##src/libroute/if_nameindex.c##
+                    ifptr->if_index = sdl->sdl_index;## 32 ##src/libroute/if_nameindex.c##
+                    ifptr++;## 33 ##src/libroute/if_nameindex.c##
+                }## 34 ##src/libroute/if_nameindex.c##
+            }## 35 ##src/libroute/if_nameindex.c##
+
+        }## 36 ##src/libroute/if_nameindex.c##
+    }## 37 ##src/libroute/if_nameindex.c##
+    ifptr->if_name = NULL;      /* mark end of array of structs */## 38 ##src/libroute/if_nameindex.c##
+    ifptr->if_index = 0;## 39 ##src/libroute/if_nameindex.c##
+    free(buf);## 40 ##src/libroute/if_nameindex.c##
+    return (result);            /* caller must free() this when done */## 41 ##src/libroute/if_nameindex.c##
+}## 42 ##src/libroute/if_nameindex.c##
+/* end if_nameindex */
+
+/* include if_freenameindex */
+void## 43 ##src/libroute/if_nameindex.c##
+if_freenameindex(struct if_nameindex *ptr)## 44 ##src/libroute/if_nameindex.c##
+{## 45 ##src/libroute/if_nameindex.c##
+    free(ptr);## 46 ##src/libroute/if_nameindex.c##
+}## 47 ##src/libroute/if_nameindex.c##
+/* end if_freenameindex */
+
+struct if_nameindex *## 48 ##src/libroute/if_nameindex.c##
+If_nameindex(void)## 49 ##src/libroute/if_nameindex.c##
+{## 50 ##src/libroute/if_nameindex.c##
+    struct if_nameindex *ifptr;## 51 ##src/libroute/if_nameindex.c##
+
+    if ((ifptr = if_nameindex()) == NULL)## 52 ##src/libroute/if_nameindex.c##
+        err_quit("if_nameindex error");## 53 ##src/libroute/if_nameindex.c##
+    return (ifptr);## 54 ##src/libroute/if_nameindex.c##
+}## 55 ##src/libroute/if_nameindex.c##
diff --git a/libroute/if_nametoindex.c b/libroute/if_nametoindex.c
new file mode 100644 (file)
index 0000000..fb13e52
--- /dev/null
@@ -0,0 +1,51 @@
+/* include if_nametoindex */
+#include       "unpifi.h"
+#include       "unproute.h"
+
+unsigned int
+if_nametoindex(const char *name)
+{
+       unsigned int            idx, namelen;
+       char                            *buf, *next, *lim;
+       size_t                          len;
+       struct if_msghdr        *ifm;
+       struct sockaddr         *sa, *rti_info[RTAX_MAX];
+       struct sockaddr_dl      *sdl;
+
+       if ( (buf = net_rt_iflist(0, 0, &len)) == NULL)
+               return(0);
+
+       namelen = strlen(name);
+       lim = buf + len;
+       for (next = buf; next < lim; next += ifm->ifm_msglen) {
+               ifm = (struct if_msghdr *) next;
+               if (ifm->ifm_type == RTM_IFINFO) {
+                       sa = (struct sockaddr *) (ifm + 1);
+                       get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
+                       if ( (sa = rti_info[RTAX_IFP]) != NULL) {
+                               if (sa->sa_family == AF_LINK) {
+                                       sdl = (struct sockaddr_dl *) sa;
+                                       if (sdl->sdl_nlen == namelen && strncmp(&sdl->sdl_data[0], name, sdl->sdl_nlen) == 0) {
+                                               idx = sdl->sdl_index;   /* save before free() */
+                                               free(buf);
+                                               return(idx);
+                                       }
+                               }
+                       }
+
+               }
+       }
+       free(buf);
+       return(0);              /* no match for name */
+}
+/* end if_nametoindex */
+
+unsigned int
+If_nametoindex(const char *name)
+{
+       int             idx;
+
+       if ( (idx = if_nametoindex(name)) == 0)
+               err_quit("if_nametoindex error for %s", name);
+       return(idx);
+}
diff --git a/libroute/if_nametoindex.lc b/libroute/if_nametoindex.lc
new file mode 100644 (file)
index 0000000..eae5d8f
--- /dev/null
@@ -0,0 +1,50 @@
+/* include if_nametoindex */
+#include    "unpifi.h"##  1 ##src/libroute/if_nametoindex.c##
+#include    "unproute.h"##  2 ##src/libroute/if_nametoindex.c##
+
+unsigned int##  3 ##src/libroute/if_nametoindex.c##
+if_nametoindex(const char *name)##  4 ##src/libroute/if_nametoindex.c##
+{##  5 ##src/libroute/if_nametoindex.c##
+    unsigned int index;##  6 ##src/libroute/if_nametoindex.c##
+    char   *buf, *next, *lim;##  7 ##src/libroute/if_nametoindex.c##
+    size_t  len;##  8 ##src/libroute/if_nametoindex.c##
+    struct if_msghdr *ifm;##  9 ##src/libroute/if_nametoindex.c##
+    struct sockaddr *sa, *rti_info[RTAX_MAX];## 10 ##src/libroute/if_nametoindex.c##
+    struct sockaddr_dl *sdl;## 11 ##src/libroute/if_nametoindex.c##
+
+    if ((buf = net_rt_iflist(0, 0, &len)) == NULL)## 12 ##src/libroute/if_nametoindex.c##
+        return (0);## 13 ##src/libroute/if_nametoindex.c##
+
+    lim = buf + len;## 14 ##src/libroute/if_nametoindex.c##
+    for (next = buf; next < lim; next += ifm->ifm_msglen) {## 15 ##src/libroute/if_nametoindex.c##
+        ifm = (struct if_msghdr *) next;## 16 ##src/libroute/if_nametoindex.c##
+        if (ifm->ifm_type == RTM_IFINFO) {## 17 ##src/libroute/if_nametoindex.c##
+            sa = (struct sockaddr *) (ifm + 1);## 18 ##src/libroute/if_nametoindex.c##
+            get_rtaddrs(ifm->ifm_addrs, sa, rti_info);## 19 ##src/libroute/if_nametoindex.c##
+            if ((sa = rti_info[RTAX_IFP]) != NULL) {## 20 ##src/libroute/if_nametoindex.c##
+                if (sa->sa_family == AF_LINK) {## 21 ##src/libroute/if_nametoindex.c##
+                    sdl = (struct sockaddr_dl *) sa;## 22 ##src/libroute/if_nametoindex.c##
+                    if (strncmp(&sdl->sdl_data[0], name, sdl->sdl_nlen) == 0) {## 23 ##src/libroute/if_nametoindex.c##
+                        index = sdl->sdl_index; /* save before free() */## 24 ##src/libroute/if_nametoindex.c##
+                        free(buf);## 25 ##src/libroute/if_nametoindex.c##
+                        return (index);## 26 ##src/libroute/if_nametoindex.c##
+                    }## 27 ##src/libroute/if_nametoindex.c##
+                }## 28 ##src/libroute/if_nametoindex.c##
+            }## 29 ##src/libroute/if_nametoindex.c##
+
+        }## 30 ##src/libroute/if_nametoindex.c##
+    }## 31 ##src/libroute/if_nametoindex.c##
+    free(buf);## 32 ##src/libroute/if_nametoindex.c##
+    return (0);                 /* no match for name */## 33 ##src/libroute/if_nametoindex.c##
+}## 34 ##src/libroute/if_nametoindex.c##
+/* end if_nametoindex */
+
+unsigned int## 35 ##src/libroute/if_nametoindex.c##
+If_nametoindex(const char *name)## 36 ##src/libroute/if_nametoindex.c##
+{## 37 ##src/libroute/if_nametoindex.c##
+    int     index;## 38 ##src/libroute/if_nametoindex.c##
+
+    if ((index = if_nametoindex(name)) == 0)## 39 ##src/libroute/if_nametoindex.c##
+        err_quit("if_nametoindex error for %s", name);## 40 ##src/libroute/if_nametoindex.c##
+    return (index);## 41 ##src/libroute/if_nametoindex.c##
+}## 42 ##src/libroute/if_nametoindex.c##
diff --git a/libroute/net_rt_dump.c b/libroute/net_rt_dump.c
new file mode 100644 (file)
index 0000000..2200131
--- /dev/null
@@ -0,0 +1,36 @@
+/* include net_rt_dump */
+#include       "unproute.h"
+
+char *
+net_rt_dump(int family, int flags, size_t *lenp)
+{
+       int             mib[6];
+       char    *buf;
+
+       mib[0] = CTL_NET;
+       mib[1] = AF_ROUTE;
+       mib[2] = 0;
+       mib[3] = family;                /* only addresses of this family */
+       mib[4] = NET_RT_DUMP;
+       mib[5] = flags;                 /* not looked at with NET_RT_DUMP */
+       if (sysctl(mib, 6, NULL, lenp, NULL, 0) < 0)
+               return(NULL);
+
+       if ( (buf = malloc(*lenp)) == NULL)
+               return(NULL);
+       if (sysctl(mib, 6, buf, lenp, NULL, 0) < 0)
+               return(NULL);
+
+       return(buf);
+}
+/* end net_rt_dump */
+
+char *
+Net_rt_dump(int family, int flags, size_t *lenp)
+{
+       char    *ptr;
+
+       if ( (ptr = net_rt_dump(family, flags, lenp)) == NULL)
+               err_sys("net_rt_dump error");
+       return(ptr);
+}
diff --git a/libroute/net_rt_iflist.c b/libroute/net_rt_iflist.c
new file mode 100644 (file)
index 0000000..c9c1967
--- /dev/null
@@ -0,0 +1,38 @@
+/* include net_rt_iflist */
+#include       "unproute.h"
+
+char *
+net_rt_iflist(int family, int flags, size_t *lenp)
+{
+       int             mib[6];
+       char    *buf;
+
+       mib[0] = CTL_NET;
+       mib[1] = AF_ROUTE;
+       mib[2] = 0;
+       mib[3] = family;                /* only addresses of this family */
+       mib[4] = NET_RT_IFLIST;
+       mib[5] = flags;                 /* interface index or 0 */
+       if (sysctl(mib, 6, NULL, lenp, NULL, 0) < 0)
+               return(NULL);
+
+       if ( (buf = malloc(*lenp)) == NULL)
+               return(NULL);
+       if (sysctl(mib, 6, buf, lenp, NULL, 0) < 0) {
+               free(buf);
+               return(NULL);
+       }
+
+       return(buf);
+}
+/* end net_rt_iflist */
+
+char *
+Net_rt_iflist(int family, int flags, size_t *lenp)
+{
+       char    *ptr;
+
+       if ( (ptr = net_rt_iflist(family, flags, lenp)) == NULL)
+               err_sys("net_rt_iflist error");
+       return(ptr);
+}
diff --git a/libroute/net_rt_iflist.lc b/libroute/net_rt_iflist.lc
new file mode 100644 (file)
index 0000000..b75cd89
--- /dev/null
@@ -0,0 +1,38 @@
+/* include net_rt_iflist */
+#include    "unproute.h"##  1 ##src/libroute/net_rt_iflist.c##
+
+char   *##  2 ##src/libroute/net_rt_iflist.c##
+net_rt_iflist(int family, int flags, size_t *lenp)##  3 ##src/libroute/net_rt_iflist.c##
+{##  4 ##src/libroute/net_rt_iflist.c##
+    int     mib[6];##  5 ##src/libroute/net_rt_iflist.c##
+    char   *buf;##  6 ##src/libroute/net_rt_iflist.c##
+
+    mib[0] = CTL_NET;##  7 ##src/libroute/net_rt_iflist.c##
+    mib[1] = AF_ROUTE;##  8 ##src/libroute/net_rt_iflist.c##
+    mib[2] = 0;##  9 ##src/libroute/net_rt_iflist.c##
+    mib[3] = family;            /* only addresses of this family */## 10 ##src/libroute/net_rt_iflist.c##
+    mib[4] = NET_RT_IFLIST;## 11 ##src/libroute/net_rt_iflist.c##
+    mib[5] = flags;             /* interface index, or 0 */## 12 ##src/libroute/net_rt_iflist.c##
+    if (sysctl(mib, 6, NULL, lenp, NULL, 0) < 0)## 13 ##src/libroute/net_rt_iflist.c##
+        return (NULL);## 14 ##src/libroute/net_rt_iflist.c##
+
+    if ((buf = malloc(*lenp)) == NULL)## 15 ##src/libroute/net_rt_iflist.c##
+        return (NULL);## 16 ##src/libroute/net_rt_iflist.c##
+    if (sysctl(mib, 6, buf, lenp, NULL, 0) < 0) {## 17 ##src/libroute/net_rt_iflist.c##
+        free(buf);## 18 ##src/libroute/net_rt_iflist.c##
+        return (NULL);## 19 ##src/libroute/net_rt_iflist.c##
+    }## 20 ##src/libroute/net_rt_iflist.c##
+
+    return (buf);## 21 ##src/libroute/net_rt_iflist.c##
+}## 22 ##src/libroute/net_rt_iflist.c##
+/* end net_rt_iflist */
+
+char   *## 23 ##src/libroute/net_rt_iflist.c##
+Net_rt_iflist(int family, int flags, size_t *lenp)## 24 ##src/libroute/net_rt_iflist.c##
+{## 25 ##src/libroute/net_rt_iflist.c##
+    char   *ptr;## 26 ##src/libroute/net_rt_iflist.c##
+
+    if ((ptr = net_rt_iflist(family, flags, lenp)) == NULL)## 27 ##src/libroute/net_rt_iflist.c##
+        err_sys("net_rt_iflist error");## 28 ##src/libroute/net_rt_iflist.c##
+    return (ptr);## 29 ##src/libroute/net_rt_iflist.c##
+}## 30 ##src/libroute/net_rt_iflist.c##
diff --git a/libroute/sock_masktop.c b/libroute/sock_masktop.c
new file mode 100644 (file)
index 0000000..3e1c70d
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unproute.h"
+
+const char *
+sock_masktop(SA *sa, socklen_t salen)
+{
+       static char             str[INET6_ADDRSTRLEN];
+       unsigned char   *ptr = &sa->sa_data[2];
+
+       if (sa->sa_len == 0)
+               return("0.0.0.0");
+       else if (sa->sa_len == 5)
+               snprintf(str, sizeof(str), "%d.0.0.0", *ptr);
+       else if (sa->sa_len == 6)
+               snprintf(str, sizeof(str), "%d.%d.0.0", *ptr, *(ptr+1));
+       else if (sa->sa_len == 7)
+               snprintf(str, sizeof(str), "%d.%d.%d.0", *ptr, *(ptr+1), *(ptr+2));
+       else if (sa->sa_len == 8)
+               snprintf(str, sizeof(str), "%d.%d.%d.%d",
+                                *ptr, *(ptr+1), *(ptr+2), *(ptr+3));
+       else
+               snprintf(str, sizeof(str), "(unknown mask, len = %d, family = %d)",
+                                sa->sa_len, sa->sa_family);
+       return(str);
+}
diff --git a/libroute/unproute.h b/libroute/unproute.h
new file mode 100644 (file)
index 0000000..a9ee61d
--- /dev/null
@@ -0,0 +1,20 @@
+#include       "unp.h"
+#include       <net/if.h>                      /* if_msghdr{} */
+#include       <net/if_dl.h>           /* sockaddr_sdl{} */
+#include       <net/route.h>           /* RTA_xxx constants */
+#include       <sys/param.h>
+
+#ifdef HAVE_SYS_SYSCTL_H
+#include       <sys/sysctl.h>          /* sysctl() */
+#endif
+
+                       /* function prototypes */
+void    get_rtaddrs(int, struct sockaddr *, struct sockaddr **);
+char   *net_rt_iflist(int, int, size_t *);
+char   *net_rt_dump(int, int, size_t *);
+const char     *sock_masktop(struct sockaddr *, socklen_t);
+
+                       /* wrapper functions */
+char   *Net_rt_iflist(int, int, size_t *);
+char   *Net_rt_dump(int, int, size_t *);
+#define        Sock_masktop(a,b)               sock_masktop((a), (b))
diff --git a/mcast/Makefile b/mcast/Makefile
new file mode 100644 (file)
index 0000000..273bc5e
--- /dev/null
@@ -0,0 +1,26 @@
+include ../Make.defines
+
+PROGS =        sendrecv udpcli05 udpcli06 udpserv01
+
+all:   ${PROGS}
+
+sendrecv:      main.o send.o recv.o
+               ${CC} ${CFLAGS} -o $@ main.o send.o recv.o ${LIBS}
+
+# Version in book.
+udpcli01:      udpcli01.o dgclibcast1.o
+               ${CC} ${CFLAGS} -o $@ udpcli01.o dgclibcast1.o ${LIBS}
+
+# Correct version using sigsetjmp()/siglongjmp().
+udpcli05:      udpcli05.o dgclimcast5.o
+               ${CC} ${CFLAGS} -o $@ udpcli05.o dgclimcast5.o ${LIBS}
+
+# Try to bind multicast address and send.
+udpcli06:      udpcli06.o dgclimcast6.o
+               ${CC} ${CFLAGS} -o $@ udpcli06.o dgclimcast6.o ${LIBS}
+
+udpserv01:     udpserv01.o
+               ${CC} ${CFLAGS} -o $@ udpserv01.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/mcast/dgclibcast1.c b/mcast/dgclibcast1.c
new file mode 100644 (file)
index 0000000..feff0e3
--- /dev/null
@@ -0,0 +1,43 @@
+#include       "unp.h"
+
+static void    recvfrom_alarm(int);
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                             n;
+       char                    sendline[MAXLINE], recvline[MAXLINE + 1];
+       socklen_t               len;
+       struct sockaddr *preply_addr;
+       preply_addr = Malloc(servlen);
+
+       Signal(SIGALRM, recvfrom_alarm);
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               alarm(5);
+               for ( ; ; ) {
+                       len = servlen;
+                       n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
+                       if (n == -1) {
+                               if (errno == EINTR)
+                                       break;          /* waited long enough for replies */
+                               else
+                                       err_sys("recvfrom error");
+                       } else {
+                               recvline[n] = 0;        /* null terminate */
+                               printf("from %s: %s",
+                                               Sock_ntop_host(preply_addr, servlen), recvline);
+                       }
+               }
+       }
+}
+
+static void
+recvfrom_alarm(int signo)
+{
+       return;         /* just interrupt the recvfrom() */
+}
diff --git a/mcast/dgclimcast5.c b/mcast/dgclimcast5.c
new file mode 100644 (file)
index 0000000..54c3f71
--- /dev/null
@@ -0,0 +1,40 @@
+#include       "unp.h"
+#include       <setjmp.h>
+
+static void                    recvfrom_alarm(int);
+static sigjmp_buf      jmpbuf;
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                             n;
+       char                    sendline[MAXLINE], recvline[MAXLINE + 1];
+       socklen_t               len;
+       struct sockaddr *preply_addr;
+       preply_addr = Malloc(servlen);
+
+       Signal(SIGALRM, recvfrom_alarm);
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               alarm(5);
+               for ( ; ; ) {
+                       if (sigsetjmp(jmpbuf, 1) != 0)
+                               break;
+                       len = servlen;
+                       n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
+                       recvline[n] = 0;        /* null terminate */
+                       printf("from %s: %s",
+                                       Sock_ntop_host(preply_addr, servlen), recvline);
+               }
+       }
+}
+
+static void
+recvfrom_alarm(int signo)
+{
+       siglongjmp(jmpbuf, 1);
+}
diff --git a/mcast/dgclimcast6.c b/mcast/dgclimcast6.c
new file mode 100644 (file)
index 0000000..54c3f71
--- /dev/null
@@ -0,0 +1,40 @@
+#include       "unp.h"
+#include       <setjmp.h>
+
+static void                    recvfrom_alarm(int);
+static sigjmp_buf      jmpbuf;
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                             n;
+       char                    sendline[MAXLINE], recvline[MAXLINE + 1];
+       socklen_t               len;
+       struct sockaddr *preply_addr;
+       preply_addr = Malloc(servlen);
+
+       Signal(SIGALRM, recvfrom_alarm);
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               alarm(5);
+               for ( ; ; ) {
+                       if (sigsetjmp(jmpbuf, 1) != 0)
+                               break;
+                       len = servlen;
+                       n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
+                       recvline[n] = 0;        /* null terminate */
+                       printf("from %s: %s",
+                                       Sock_ntop_host(preply_addr, servlen), recvline);
+               }
+       }
+}
+
+static void
+recvfrom_alarm(int signo)
+{
+       siglongjmp(jmpbuf, 1);
+}
diff --git a/mcast/main.c b/mcast/main.c
new file mode 100644 (file)
index 0000000..129fd0a
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unp.h"
+
+void   recv_all(int, socklen_t);
+void   send_all(int, SA *, socklen_t);
+
+int
+main(int argc, char **argv)
+{
+       int                                     sendfd, recvfd;
+       const int                       on = 1;
+       socklen_t                       salen;
+       struct sockaddr         *sasend, *sarecv;
+
+       if (argc != 3)
+               err_quit("usage: sendrecv <IP-multicast-address> <port#>");
+
+       sendfd = Udp_client(argv[1], argv[2], (void **) &sasend, &salen);
+
+       recvfd = Socket(sasend->sa_family, SOCK_DGRAM, 0);
+
+       Setsockopt(recvfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+       sarecv = Malloc(salen);
+       memcpy(sarecv, sasend, salen);
+       Bind(recvfd, sarecv, salen);
+
+       Mcast_join(recvfd, sasend, salen, NULL, 0);
+       Mcast_set_loop(sendfd, 0);
+
+       if (Fork() == 0)
+               recv_all(recvfd, salen);                /* child -> receives */
+
+       send_all(sendfd, sasend, salen);        /* parent -> sends */
+}
diff --git a/mcast/recv.c b/mcast/recv.c
new file mode 100644 (file)
index 0000000..b9933c4
--- /dev/null
@@ -0,0 +1,20 @@
+#include       "unp.h"
+
+void
+recv_all(int recvfd, socklen_t salen)
+{
+       int                                     n;
+       char                            line[MAXLINE+1];
+       socklen_t                       len;
+       struct sockaddr         *safrom;
+
+       safrom = Malloc(salen);
+
+       for ( ; ; ) {
+               len = salen;
+               n = Recvfrom(recvfd, line, MAXLINE, 0, safrom, &len);
+
+               line[n] = 0;    /* null terminate */
+               printf("from %s: %s", Sock_ntop(safrom, len), line);
+       }
+}
diff --git a/mcast/send.c b/mcast/send.c
new file mode 100644 (file)
index 0000000..6b1a796
--- /dev/null
@@ -0,0 +1,21 @@
+#include       "unp.h"
+#include       <sys/utsname.h>
+
+#define        SENDRATE        5               /* send one datagram every five seconds */
+
+void
+send_all(int sendfd, SA *sadest, socklen_t salen)
+{
+       char            line[MAXLINE];          /* hostname and process ID */
+       struct utsname  myname;
+
+       if (uname(&myname) < 0)
+               err_sys("uname error");;
+       snprintf(line, sizeof(line), "%s, %d\n", myname.nodename, getpid());
+
+       for ( ; ; ) {
+               Sendto(sendfd, line, strlen(line), 0, sadest, salen);
+
+               sleep(SENDRATE);
+       }
+}
diff --git a/mcast/udpcli01.c b/mcast/udpcli01.c
new file mode 100644 (file)
index 0000000..24ce753
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli01 <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/mcast/udpcli05.c b/mcast/udpcli05.c
new file mode 100644 (file)
index 0000000..dd0cad3
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli05 <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(13);          /* standard daytime server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/mcast/udpcli06.c b/mcast/udpcli06.c
new file mode 100644 (file)
index 0000000..e77401c
--- /dev/null
@@ -0,0 +1,23 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                             sockfd;
+       socklen_t               salen;
+       struct sockaddr *cli, *serv;
+
+       if (argc != 2)
+               err_quit("usage: udpcli06 <IPaddress>");
+
+       sockfd = Udp_client(argv[1], "daytime", (void **) &serv, &salen);
+
+       cli = Malloc(salen);
+       memcpy(cli, serv, salen);               /* copy socket address struct */
+       sock_set_port(cli, salen, 0);   /* and set port to 0 */
+       Bind(sockfd, cli, salen);
+
+       dg_cli(stdin, sockfd, serv, salen);
+
+       exit(0);
+}
diff --git a/mcast/udpserv01.c b/mcast/udpserv01.c
new file mode 100644 (file)
index 0000000..817ae6c
--- /dev/null
@@ -0,0 +1,25 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr, grpaddr, cliaddr;
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       bzero(&grpaddr, sizeof(servaddr));
+       grpaddr.sin_family      = AF_INET;
+       grpaddr.sin_addr.s_addr = inet_addr("224.0.0.1");
+
+       mcast_join(sockfd, &grpaddr, sizeof(grpaddr), NULL, 0);
+
+       dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
+}
diff --git a/mysdr/Makefile b/mysdr/Makefile
new file mode 100644 (file)
index 0000000..b09a494
--- /dev/null
@@ -0,0 +1,11 @@
+include ../Make.defines
+
+PROGS =        mysdr
+
+all:   ${PROGS}
+
+mysdr: main.o loop.o
+               ${CC} ${CFLAGS} -o $@ main.o loop.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/mysdr/loop.c b/mysdr/loop.c
new file mode 100644 (file)
index 0000000..b68f7fc
--- /dev/null
@@ -0,0 +1,44 @@
+#include       "mysdr.h"
+
+void
+loop(int sockfd, socklen_t salen)
+{
+       socklen_t               len;
+       ssize_t                 n;
+       char                    *p;
+       struct sockaddr *sa;
+       struct sap_packet {
+         uint32_t      sap_header;
+         uint32_t      sap_src;
+         char          sap_data[BUFFSIZE];
+       } buf;
+
+       sa = Malloc(salen);
+
+       for ( ; ; ) {
+               len = salen;
+               n = Recvfrom(sockfd, &buf, sizeof(buf) - 1, 0, sa, &len);
+               ((char *)&buf)[n] = 0;                  /* null terminate */
+               buf.sap_header = ntohl(buf.sap_header);
+
+               printf("From %s hash 0x%04x\n", Sock_ntop(sa, len),
+                               buf.sap_header & SAP_HASH_MASK);
+               if (((buf.sap_header & SAP_VERSION_MASK) >> SAP_VERSION_SHIFT) > 1) {
+                       err_msg("... version field not 1 (0x%08x)", buf.sap_header);
+                       continue;
+               }
+               if (buf.sap_header & SAP_IPV6) {
+                       err_msg("... IPv6");
+                       continue;
+               }
+               if (buf.sap_header & (SAP_DELETE|SAP_ENCRYPTED|SAP_COMPRESSED)) {
+                       err_msg("... can't parse this packet type (0x%08x)", buf.sap_header);
+                       continue;
+               }
+               p = buf.sap_data + ((buf.sap_header & SAP_AUTHLEN_MASK)
+                                                       >> SAP_AUTHLEN_SHIFT);
+               if (strcmp(p, "application/sdp") == 0)
+                       p += 16;
+               printf("%s\n", p);
+       }
+}
diff --git a/mysdr/loop.lc b/mysdr/loop.lc
new file mode 100644 (file)
index 0000000..05d8262
--- /dev/null
@@ -0,0 +1,28 @@
+#include    "unp.h"##  1 ##src/mysdr/loop.c##
+
+void##  2 ##src/mysdr/loop.c##
+loop(int sockfd, socklen_t salen)##  3 ##src/mysdr/loop.c##
+{##  4 ##src/mysdr/loop.c##
+    char    buf[MAXLINE + 1];##  5 ##src/mysdr/loop.c##
+    socklen_t len;##  6 ##src/mysdr/loop.c##
+    ssize_t n;##  7 ##src/mysdr/loop.c##
+    struct sockaddr *sa;##  8 ##src/mysdr/loop.c##
+    struct sap_packet {##  9 ##src/mysdr/loop.c##
+        uint32_t sap_header;## 10 ##src/mysdr/loop.c##
+        uint32_t sap_src;## 11 ##src/mysdr/loop.c##
+        char    sap_data[1];## 12 ##src/mysdr/loop.c##
+    }      *sapptr;## 13 ##src/mysdr/loop.c##
+
+    sa = Malloc(salen);## 14 ##src/mysdr/loop.c##
+
+    for (;;) {## 15 ##src/mysdr/loop.c##
+        len = salen;## 16 ##src/mysdr/loop.c##
+        n = Recvfrom(sockfd, buf, MAXLINE, 0, sa, &len);## 17 ##src/mysdr/loop.c##
+        buf[n] = 0;             /* null terminate */## 18 ##src/mysdr/loop.c##
+
+        sapptr = (struct sap_packet *) buf;## 19 ##src/mysdr/loop.c##
+        if ((n -= 2 * sizeof(uint32_t)) <= 0)## 20 ##src/mysdr/loop.c##
+            err_quit("n = %d", n);## 21 ##src/mysdr/loop.c##
+        printf("From %s\n%s\n", Sock_ntop(sa, len), sapptr->sap_data);## 22 ##src/mysdr/loop.c##
+    }## 23 ##src/mysdr/loop.c##
+}## 24 ##src/mysdr/loop.c##
diff --git a/mysdr/main.c b/mysdr/main.c
new file mode 100644 (file)
index 0000000..adfc34b
--- /dev/null
@@ -0,0 +1,31 @@
+#include       "unp.h"
+
+#define        SAP_NAME        "sap.mcast.net" /* default group name and port */
+#define        SAP_PORT        "9875"
+
+void   loop(int, socklen_t);
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       const int                       on = 1;
+       socklen_t                       salen;
+       struct sockaddr         *sa;
+
+       if (argc == 1)
+               sockfd = Udp_client(SAP_NAME, SAP_PORT, (void **) &sa, &salen);
+       else if (argc == 4)
+               sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);
+       else
+               err_quit("usage: mysdr <mcast-addr> <port#> <interface-name>");
+
+       Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+       Bind(sockfd, sa, salen);
+
+       Mcast_join(sockfd, sa, salen, (argc == 4) ? argv[3] : NULL, 0);
+
+       loop(sockfd, salen);    /* receive and print */
+
+       exit(0);
+}
diff --git a/mysdr/main.lc b/mysdr/main.lc
new file mode 100644 (file)
index 0000000..8f725cb
--- /dev/null
@@ -0,0 +1,31 @@
+#include    "unp.h"##  1 ##src/mysdr/main.c##
+
+#define SAP_NAME    "sap.mcast.net" /* default group name and port */##  2 ##src/mysdr/main.c##
+#define SAP_PORT    "9875"##  3 ##src/mysdr/main.c##
+
+void    loop(int, socklen_t);##  4 ##src/mysdr/main.c##
+
+int##  5 ##src/mysdr/main.c##
+main(int argc, char **argv)##  6 ##src/mysdr/main.c##
+{##  7 ##src/mysdr/main.c##
+    int     sockfd;##  8 ##src/mysdr/main.c##
+    const int on = 1;##  9 ##src/mysdr/main.c##
+    socklen_t salen;## 10 ##src/mysdr/main.c##
+    struct sockaddr *sa;## 11 ##src/mysdr/main.c##
+
+    if (argc == 1)## 12 ##src/mysdr/main.c##
+        sockfd = Udp_client(SAP_NAME, SAP_PORT, (void **) &sa, &salen);## 13 ##src/mysdr/main.c##
+    else if (argc == 4)## 14 ##src/mysdr/main.c##
+        sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);## 15 ##src/mysdr/main.c##
+    else## 16 ##src/mysdr/main.c##
+        err_quit("usage: mysdr <mcast-addr> <port#> <interface-name>");## 17 ##src/mysdr/main.c##
+
+    Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 18 ##src/mysdr/main.c##
+    Bind(sockfd, sa, salen);## 19 ##src/mysdr/main.c##
+
+    Mcast_join(sockfd, sa, salen, (argc == 4) ? argv[3] : NULL, 0);## 20 ##src/mysdr/main.c##
+
+    loop(sockfd, salen);        /* receive and print */## 21 ##src/mysdr/main.c##
+
+    exit(0);## 22 ##src/mysdr/main.c##
+}## 23 ##src/mysdr/main.c##
diff --git a/mysdr/mysdr.h b/mysdr/mysdr.h
new file mode 100644 (file)
index 0000000..dcb1d3b
--- /dev/null
@@ -0,0 +1,12 @@
+#include       "unp.h"
+
+#define        SAP_VERSION                     1
+#define SAP_VERSION_MASK       0xe0000000
+#define        SAP_VERSION_SHIFT       29
+#define        SAP_IPV6                        0x10000000
+#define        SAP_DELETE                      0x04000000
+#define        SAP_ENCRYPTED           0x02000000
+#define        SAP_COMPRESSED          0x01000000
+#define        SAP_AUTHLEN_MASK        0x00ff0000
+#define        SAP_AUTHLEN_SHIFT       16
+#define        SAP_HASH_MASK           0x0000ffff
diff --git a/mysdr/script.1 b/mysdr/script.1
new file mode 100644 (file)
index 0000000..87cceea
--- /dev/null
@@ -0,0 +1,45 @@
+kohala % ./sdr
+From 128.102.84.134/2840
+v=0
+o=shuttle 3050400397 3051818822 IN IP4 128.102.84.134
+s=NASA - Shuttle STS-79 Mission Coverage
+i=Pre-launch and mission coverage of    Shuttle Mission STS-79.  Launch    expected 9/16/96 with a mission    duration anticipated of 9-10 days.       STS-79 is the 4th in a series of joint   docking missions between the Shuttle   and the MIR Space Station.  This   session is being offered by NASA - Ames  Research Center as a public service to   the MBone community.
+u=http://www-pao.ksc.nasa.gov/kscpao/kscpao.htm
+p=NASA ARC Digital Video Lab (415) 604-6145
+e=NASA ARC Digital Video Lab <mallard@mail.arc.nasa.gov>
+c=IN IP4 224.2.86.28/127
+t=3051608400 3052472400
+m=audio 19432 RTP/AVP 0
+m=video 61192 RTP/AVP 31
+From 143.106.13.10/1119
+v=0
+o=vazquez 3051812968 3051813242 IN IP4 143.106.13.10
+s=Test IQ/Unicamp
+i=Video Test/IQ Unic
+p=Pedro A M Vazquez +55 019 239 7253
+e=Pedro A M Vazquez <vazquez@kalypso.iqm.unicamp.br>
+t=3051811800 3052416600
+m=video 58960 rtp nv
+c=IN IP4 224.2.60.105/127
+m=whiteboard 43591 udp wb
+c=IN IP4 224.2.29.88/127
+From 131.202.70.81/47880
+v=0
+o=spencer 3050069099 3050069347 IN IP4 131.202.70.81
+s=UNB / CSpace
+i=This is a low rate video transmission sent from the University of New Brunswick, in Fredericton, New Brunswick, from CSpace, offices for the Community Access Program.  Video is sent at ~20kbps, and audio is (usually) monitored as well.  This feed is coming through from the host breakers.educ.unb.ca.  If this is interferring with a scheduled broadcast, please let me know, and I will stop the transmission.  dwight (spencer@unb.ca)
+u=http://cspace.unb.ca/~spencer/
+e=Dwight E. Spencer <spencer@unb.ca>
+p=Dwight E. Spencer +1 (506) 447 3153
+c=IN IP4 224.2.246.116/127
+t=3050019000 3052524600
+r=86400 86400 0
+m=audio 22378 RTP/AVP 5
+c=IN IP4 224.2.246.116/127
+m=video 61338 RTP/AVP 31
+c=IN IP4 224.2.210.189/127
+m=text 61044 udp nt
+c=IN IP4 224.2.147.133/127
diff --git a/mysdr/script.2 b/mysdr/script.2
new file mode 100644 (file)
index 0000000..44ae715
--- /dev/null
@@ -0,0 +1,1679 @@
+Script started on Sat Jul 12 15:51:28 1997
+kohala % ./mysdr\r
+From 140.247.157.193.1047\r
+v=0\r
+o=karp 3077576976 3077577964 IN IP4 140.247.157.193\r
+s=Harvard's Aiken Computation Lab DEMOLITION\r
+i=Live broadcast of the demolition of Harvard University's Aiken Computation Lab, to make way for the new Computer Science building, Maxwell-Dworkin. Broadcast will include commentary on the event by Harvard faculty, administrators, and students. Filmed in Destruct-O-Vision, from an unmanned camera INSIDE Aiken.\r
+u=http://www.eecs.harvard.edu/aiken-go-boom\r
+e=Brad Karp <karp@eecs.harvard.edu>\r
+p=Brad Karp +1 617-661-4979\r
+c=IN IP4 224.2.156.29/127\r
+t=3078820800 3080030400\r
+a=tool:sdr v2.4a6\r
+a=type:broadcast\r
+m=audio 21226 RTP/AVP 5\r
+c=IN IP4 224.2.156.29/127\r
+a=ptime:40\r
+m=video 49998 RTP/AVP 31\r
+c=IN IP4 224.2.237.48/127\r
+\r
+From 140.247.157.193.1047\r
+v=0\r
+o=karp 3077576976 3077577964 IN IP4 140.247.157.193\r
+s=Harvard's Aiken Computation Lab DEMOLITION\r
+i=Live broadcast of the demolition of Harvard University's Aiken Computation Lab, to make way for the new Computer Science building, Maxwell-Dworkin. Broadcast will include commentary on the event by Harvard faculty, administrators, and students. Filmed in Destruct-O-Vision, from an unmanned camera INSIDE Aiken.\r
+u=http://www.eecs.harvard.edu/aiken-go-boom\r
+e=Brad Karp <karp@eecs.harvard.edu>\r
+p=Brad Karp +1 617-661-4979\r
+c=IN IP4 224.2.156.29/127\r
+t=3078820800 3080030400\r
+a=tool:sdr v2.4a6\r
+a=type:broadcast\r
+m=audio 21226 RTP/AVP 5\r
+c=IN IP4 224.2.156.29/127\r
+a=ptime:40\r
+m=video 49998 RTP/AVP 31\r
+c=IN IP4 224.2.237.48/127\r
+\r
+From 128.223.32.151.40710\r
+v=0\r
+o=llynch 3073936480 3075057183 IN IP4 128.223.32.151\r
+s=UO Presents KWVA Campus Radio\r
+i=University of Oregon alternative radio\r
+u=http://gladstone.uoregon.edu/~kwva/\r
+e=Lucy Lynch (University of Oregon) <llynch@darkwing.uoregon.edu>\r
+p=Lucy Lynch (University of Oregon) (541) 346-1774\r
+c=IN IP4 224.2.240.123/127\r
+t=0 0\r
+a=tool:sdr v2.3a1\r
+a=type:test\r
+m=audio 24676 RTP/AVP 0\r
+c=IN IP4 224.2.240.123/127\r
+a=ptime:40\r
+\r
+From 130.240.64.67.32877\r
+v=0\r
+o=demo 3066564173 3066564269 IN IP4 130.240.64.67\r
+s=Places all over the world\r
+i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams).  Audio is primarily for feedback for the senders of video.\r
+e=Hakan Lennestal <hakanl@cdt.luth.se>\r
+c=IN IP4 224.2.172.238/127\r
+t=0 0\r
+a=tool:CDT mAnnouncer 1.1.1\r
+a=type:broadcast\r
+m=video 51482 RTP/AVP 31\r
+c=IN IP4 224.2.172.238/127\r
+m=audio 20154 RTP/AVP 121\r
+c=IN IP4 224.2.213.113/127\r
+a=rtpred1:5\r
+a=ptime:40\r
+a=rtpred2:5\r
+a=rtpmap:121 red/8000\r
+\r
+From 130.240.64.67.32877\r
+v=0\r
+o=demo 3066564173 3066564269 IN IP4 130.240.64.67\r
+s=Places all over the world\r
+i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams).  Audio is primarily for feedback for the senders of video.\r
+e=Hakan Lennestal <hakanl@cdt.luth.se>\r
+c=IN IP4 224.2.172.238/127\r
+t=0 0\r
+a=tool:CDT mAnnouncer 1.1.1\r
+a=type:broadcast\r
+m=video 51482 RTP/AVP 31\r
+c=IN IP4 224.2.172.238/127\r
+m=audio 20154 RTP/AVP 121\r
+c=IN IP4 224.2.213.113/127\r
+a=rtpred1:5\r
+a=ptime:40\r
+a=rtpred2:5\r
+a=rtpmap:121 red/8000\r
+\r
+From 141.213.8.193.32800\r
+v=0\r
+o=sugih 3066072073 3066072112 IN IP4 141.213.8.193\r
+s=UMich IRL (private)\r
+i=UMich private use\r
+u=http://irl.eecs.umich.edu/jamin/\r
+e=UMich IRL <jamin@eecs.umich.edu>\r
+p=UMich IRL +1 313 763 1583\r
+c=IN IP4 224.2.143.56/127\r
+t=0 0\r
+a=tool:sdr v2.3a1\r
+a=type:test\r
+m=audio 21690 RTP/AVP 0\r
+c=IN IP4 224.2.143.56/127\r
+a=ptime:40\r
+m=video 51990 RTP/AVP 31\r
+c=IN IP4 224.2.200.96/127\r
+m=whiteboard 47284 udp wb\r
+c=IN IP4 224.2.239.141/127\r
+m=text 54906 udp nt\r
+c=IN IP4 224.2.242.3/127\r
+\r
+From 141.213.8.193.32800\r
+v=0\r
+o=sugih 3066072073 3066072112 IN IP4 141.213.8.193\r
+s=UMich IRL (private)\r
+i=UMich private use\r
+u=http://irl.eecs.umich.edu/jamin/\r
+e=UMich IRL <jamin@eecs.umich.edu>\r
+p=UMich IRL +1 313 763 1583\r
+c=IN IP4 224.2.143.56/127\r
+t=0 0\r
+a=tool:sdr v2.3a1\r
+a=type:test\r
+m=audio 21690 RTP/AVP 0\r
+c=IN IP4 224.2.143.56/127\r
+a=ptime:40\r
+m=video 51990 RTP/AVP 31\r
+c=IN IP4 224.2.200.96/127\r
+m=whiteboard 47284 udp wb\r
+c=IN IP4 224.2.239.141/127\r
+m=text 54906 udp nt\r
+c=IN IP4 224.2.242.3/127\r
+\r
+From 146.246.238.52.33095\r
+v=0\r
+o=dgomes 3076197571 3076936543 IN IP4 146.246.238.52\r
+s=Diesel Combustion Collaboratory\r
+i=This is a research MBone session initiated from the Sandia National Laboratory, California site.  This session will facilitate collaboration among the participants in a distributed research project, specifically the Heavy Duty Diesel Combustion CRADA using standard MBone A/V tools. For more information, http://www-collab.ca.sandia.gov/\r
+u=www-collab.ca.sandia.gov/\r
+e=Diesel Combustion Collaboratory <dgomes@ca.sandia.gov>\r
+p=Diesel Combustion Collaboratory 510-294-1479\r
+c=IN IP4 239.32.1.200/127\r
+t=3076142400 3078648000\r
+r=86400 86400 0\r
+a=tool:sdr v2.3a1\r
+a=type:meeting\r
+m=audio 23164 RTP/AVP 0\r
+c=IN IP4 239.32.1.200/127\r
+a=ptime:40\r
+m=video 53626 RTP/AVP 31\r
+c=IN IP4 239.32.1.200/127\r
+m=whiteboard 33870 udp wb\r
+c=IN IP4 239.32.1.200/127\r
+a=orient:portrait\r
+\r
+From 209.1.118.230.9875\r
+v=0\r
+o=Administrator 868490998 868548530 IN IP4 209.1.118.230 \r
+s=Ginacarlo's TV\r
+i=Giancarlo's TV Feed from ICAST in Los Gatos\r
+u=http://www.icast.com/\r
+e=sales@icast.com\r
+p=+01 408 8740700\r
+t=3080337120 3080689920\r
+r=79200 7200 0\r
+a=recvonly\r
+a=tool:ICAST TCC Server V1.0/Build 1-1010\r
+m=audio 4640 RTP/AVP 0\r
+c=IN IP4 224.2.100.120/127\r
+m=video 4920 RTP/AVP 31\r
+c=IN IP4 224.2.100.120/127\r
+b=AS:123\r
+a=framerate:20\r
+a=quality:7\r
+a=grayed:0\r
+\r
+From 209.1.118.230.9875\r
+v=0\r
+o=Administrator 868490998 868548530 IN IP4 209.1.118.230 \r
+s=Ginacarlo's TV\r
+i=Giancarlo's TV Feed from ICAST in Los Gatos\r
+u=http://www.icast.com/\r
+e=sales@icast.com\r
+p=+01 408 8740700\r
+t=3080337120 3080689920\r
+r=79200 7200 0\r
+a=recvonly\r
+a=tool:ICAST TCC Server V1.0/Build 1-1010\r
+m=audio 4640 RTP/AVP 0\r
+c=IN IP4 224.2.100.120/127\r
+m=video 4920 RTP/AVP 31\r
+c=IN IP4 224.2.100.120/127\r
+b=AS:123\r
+a=framerate:20\r
+a=quality:7\r
+a=grayed:0\r
+\r
+From 128.146.222.100.32915\r
+v=0\r
+o=maf 3076346251 3077639429 IN IP4 128.146.222.100\r
+s=Recent Advances in Networking Seminar at OSU\r
+i=Live Transmission of Professor Raj Jain's class CIS788.08q:  Recent Advances in Networking every Tuesday and Thursday at 17:30 to 18:45 EDT, Open to public.  E-mail questions to mbone@netlab.ohio-state.edu.  See URL for list of topics. \r
+u=http://www.cis.ohio-state.edu/~jain/cis788-97/schedule.htm\r
+p=Mark Fullmer (Ohio State) 614-292-6159\r
+e=Mark Fullmer (Ohio State) <maf@net.ohio-state.edu>\r
+t=3078163800 3079380600\r
+r=604800 7200 0\r
+a=tool:sdr v2.3a1\r
+a=type:broadcast\r
+m=audio 19922 RTP/AVP 0\r
+c=IN IP4 224.2.232.28/127\r
+a=ptime:40\r
+m=video 60266 RTP/AVP 31\r
+c=IN IP4 224.2.159.63/127\r
+\r
+From 128.146.222.100.32915\r
+v=0\r
+o=maf 3076346251 3077639429 IN IP4 128.146.222.100\r
+s=Recent Advances in Networking Seminar at OSU\r
+i=Live Transmission of Professor Raj Jain's class CIS788.08q:  Recent Advances in Networking every Tuesday and Thursday at 17:30 to 18:45 EDT, Open to public.  E-mail questions to mbone@netlab.ohio-state.edu.  See URL for list of topics. \r
+u=http://www.cis.ohio-state.edu/~jain/cis788-97/schedule.htm\r
+p=Mark Fullmer (Ohio State) 614-292-6159\r
+e=Mark Fullmer (Ohio State) <maf@net.ohio-state.edu>\r
+t=3078163800 3079380600\r
+r=604800 7200 0\r
+a=tool:sdr v2.3a1\r
+a=type:broadcast\r
+m=audio 19922 RTP/AVP 0\r
+c=IN IP4 224.2.232.28/127\r
+a=ptime:40\r
+m=video 60266 RTP/AVP 31\r
+c=IN IP4 224.2.159.63/127\r
+\r
+From 128.93.25.32.9875\r
+v=0\r
+o=mbone 1782678111 3077454111 IN IP4 128.93.25.32\r
+s=WebCanal Test Channel\r
+i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/\r
+u=http://webcanal.inria.fr/\r
+e=mbone@monet.inria.fr\r
+t=0 0\r
+a=tool:WCaster1.0b\r
+a=pub:mbone\r
+a=logo:http://webcanal.inria.fr/icons/webcanal.gif\r
+a=cat:Test\r
+a=aud:All\r
+a=subs:Public Free\r
+m=midp 47130/2 MIDP/LRMP 0\r
+c=IN IP4 224.3.88.205/127/2\r
+b=AS:64\r
+\r
+From 128.93.25.32.9875\r
+v=0\r
+o=mbone 1782678111 3077454111 IN IP4 128.93.25.32\r
+s=WebCanal Test Channel\r
+i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/\r
+u=http://webcanal.inria.fr/\r
+e=mbone@monet.inria.fr\r
+t=0 0\r
+a=tool:WCaster1.0b\r
+a=pub:mbone\r
+a=logo:http://webcanal.inria.fr/icons/webcanal.gif\r
+a=cat:Test\r
+a=aud:All\r
+a=subs:Public Free\r
+m=midp 47130/2 MIDP/LRMP 0\r
+c=IN IP4 224.3.88.205/127/2\r
+b=AS:64\r
+\r
+From 36.24.0.23.35912\r
+v=0\r
+o=- 19357 1 IN IP4 171.64.2.89\r
+s=The Stanford Channel\r
+i=In order to support testing and to provide a consistent source of audio and video material, Stanford University is transmitting the Stanford Channel, M-F, 1-5p PDT. \r
+u=http://tsc.stanford.edu/tsc/\r
+a=admin:Jim Knox\r
+e=Jim Knox <mbone-support@lists.stanford.edu>\r
+p=Jim Knox <415-723-5100>\r
+t=3076084800 3084048000\r
+r=7d 4h 0 1d 2d 3d 4d\r
+a=type:broadcast\r
+a=live\r
+a=channel:External Stanford Channel\r
+a=tool:IP/TV Program Guide 1.5.97\r
+m=video 62970 RTP/AVP 31 32 96\r
+c=IN IP4 224.2.205.145/127\r
+b=AS:2500\r
+a=quality:7\r
+a=framerate:15\r
+a=rtpmap:96 WBIH/90000\r
+m=audio 17754 RTP/AVP 3\r
+c=IN IP4 224.2.170.73/127\r
+\r
+From 210.115.193.22.32819\r
+v=0\r
+o=root 3076799605 3076799657 IN IP4 210.115.193.22\r
+s=KBS 1 TV\r
+i=Korean Broadcasting System TV\r
+u=www.kbs.co.kr\r
+p=KBS 1 TV 82-2-781-2562\r
+e=KBS 1 TV <webmaster@kbsnt.kbs.co.kr>\r
+t=3076799400 3079225800\r
+r=1209600 7200 0\r
+m=audio 20698 RTP/AVP 0\r
+c=IN IP4 224.2.235.192/127\r
+m=video 58150 RTP/AVP 31\r
+c=IN IP4 224.2.202.109/127\r
+\r
+From 36.24.0.23.35912\r
+v=0\r
+o=- 9787 3 IN IP4 36.85.0.135\r
+s=45th Annual SIAM Meeting\r
+i=MSRI, with the cooperation of Stanford University and SIAM, will broadcast six of the principal lectures from the 45th annual SIAM meeting. Notes available at http://www.msri.org/lecturenotes/97/SIAM/ \r
+u=http://www.siam.org\r
+a=admin:David Hoffman\r
+e=David Hoffman <mbone@msri.org>\r
+p=David Hoffman <510-643-6071>\r
+t=3077967600 3078183600\r
+r=7d 12h 0 1d 2d\r
+a=type:broadcast\r
+a=live\r
+a=channel:MSRI Channel\r
+a=tool:IP/TV Program Guide 1.5.97\r
+m=video 52704 RTP/AVP 31 32 96\r
+c=IN IP4 224.2.220.253/127\r
+b=AS:128\r
+a=quality:7\r
+a=framerate:15\r
+a=rtpmap:96 WBIH/90000\r
+m=audio 30372 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103\r
+c=IN IP4 224.2.141.197/127\r
+a=rtpmap:96 L8/22050/2\r
+a=rtpmap:97 L8/22050\r
+a=rtpmap:98 L8/11025/2\r
+a=rtpmap:99 L8/11025\r
+a=rtpmap:100 L16/22050/2\r
+a=rtpmap:101 L16/22050\r
+a=rtpmap:102 L16/11025/2\r
+a=rtpmap:103 L16/11025\r
+\r
+From 146.139.72.5.32924\r
+v=0\r
+o=root 3077452673 3077455201 IN IP4 146.139.72.5\r
+s=ANL TelePresence Microscopy Site/Materials MicroCharacterization Collaboratory\r
+i=This is  ANL TelePresence Microscopy Site which is  part of the DoE 2000 Materials Microcharacterization Collaboratory. It facilitates  on-line access to unique resourses at the ANL AAEM and through the MMC, other resources in the Collaboratory at member sites (ORNL, LBNL, Univ. of Illinois and NIST).  More information about the TPM and the MMC can be found at http://tpm.amc.anl.gov/mmc\r
+u=http://tpm.amc.anl.gov\r
+p=Nestor J. Zaluzec 630-252-7901\r
+e=Nestor J. Zaluzec <Zaluzec@aaem.amc.anl.gov>\r
+t=3077445600 3079900800\r
+r=86400 36000 0\r
+a=tool:sdr v2.3a1\r
+a=type:meeting\r
+m=audio 27028 RTP/AVP 0\r
+c=IN IP4 224.2.222.131/127\r
+a=ptime:40\r
+m=video 58800 RTP/AVP 31\r
+c=IN IP4 224.2.141.204/127\r
+\r
+From 146.139.72.5.32924\r
+v=0\r
+o=root 3077452673 3077455201 IN IP4 146.139.72.5\r
+s=ANL TelePresence Microscopy Site/Materials MicroCharacterization Collaboratory\r
+i=This is  ANL TelePresence Microscopy Site which is  part of the DoE 2000 Materials Microcharacterization Collaboratory. It facilitates  on-line access to unique resourses at the ANL AAEM and through the MMC, other resources in the Collaboratory at member sites (ORNL, LBNL, Univ. of Illinois and NIST).  More information about the TPM and the MMC can be found at http://tpm.amc.anl.gov/mmc\r
+u=http://tpm.amc.anl.gov\r
+p=Nestor J. Zaluzec 630-252-7901\r
+e=Nestor J. Zaluzec <Zaluzec@aaem.amc.anl.gov>\r
+t=3077445600 3079900800\r
+r=86400 36000 0\r
+a=tool:sdr v2.3a1\r
+a=type:meeting\r
+m=audio 27028 RTP/AVP 0\r
+c=IN IP4 224.2.222.131/127\r
+a=ptime:40\r
+m=video 58800 RTP/AVP 31\r
+c=IN IP4 224.2.141.204/127\r
+\r
+From 128.102.84.134.1085\r
+v=0\r
+o=shuttle 3075630923 3075633526 IN IP4 128.102.84.134\r
+s=NASA Space Shuttle STS-94\r
+i=Video/Audio broadcast of NASA space shuttle mission STS-94, Microgravity Science Laboratory-1.  This session is being broadcast as a service to the MBONE community by NASA-Ames Reseach Center.\r
+u=http://www-pao.ksc.nasa.gov/kscpao/kscpao.htm\r
+e=NASA - ARC Digital Video Lab <mallard@mail.arc.nasa.gov\r
+e=Brian Tonner (UWM) <tonner@csd.uwm.edu>\r
+e=Referenzzentrum __ <mmt-ref@tu-dresden.de>       \r
+e=IN IP4 224.2.212.30/75\r
+p=NASA - ARC Digital Video Lab (415) 604-6145\r
+p=Brian Tonner (at LBL) 510-486-5590\r
+p=Brian Tonner (at UWM) 414-229-4626\r
+c=IN IP4 224.2.210.20/127\r
+t=3076354800 3078774000\r
+m=audio 24680 RTP/AVP 0\r
+c=IN IP4 224.2.210.20/127\r
+m=video 56062 RTP/AVP 31\r
+c=IN IP4 224.2.210.20/127\r
+\r
+From 129.89.142.50.1175\r
+v=0\r
+o=james 3054298051 3054298223 IN IP4 129.89.142.50\r
+s=FreeBSD Lounge\r
+i=Channel to discuss FreeBSD related issues.  Please keep video bandwidth below 64kbps.\r
+e=Jim Lowe <james@cs.uwm.edu>\r
+p=Jim Lowe (414) 229-6634\r
+c=IN IP4 224.2.100.100/127\r
+t=0 0\r
+a=tool:sdr v2.2a23\r
+a=type:test\r
+m=audio 16400 RTP/AVP 0\r
+c=IN IP4 224.2.100.100/127\r
+a=ptime:40\r
+m=video 49200 RTP/AVP 31\r
+c=IN IP4 224.2.100.102/127\r
+m=whiteboard 32800 udp wb\r
+c=IN IP4 224.2.100.101/127\r
+a=orient:portrait\r
+m=text 32900 udp nt\r
+c=IN IP4 224.2.100.103/127\r
+\r
+From 129.89.142.50.1175\r
+v=0\r
+o=james 3054298051 3054298223 IN IP4 129.89.142.50\r
+s=FreeBSD Lounge\r
+i=Channel to discuss FreeBSD related issues.  Please keep video bandwidth below 64kbps.\r
+e=Jim Lowe <james@cs.uwm.edu>\r
+p=Jim Lowe (414) 229-6634\r
+c=IN IP4 224.2.100.100/127\r
+t=0 0\r
+a=tool:sdr v2.2a23\r
+a=type:test\r
+m=audio 16400 RTP/AVP 0\r
+c=IN IP4 224.2.100.100/127\r
+a=ptime:40\r
+m=video 49200 RTP/AVP 31\r
+c=IN IP4 224.2.100.102/127\r
+m=whiteboard 32800 udp wb\r
+c=IN IP4 224.2.100.101/127\r
+a=orient:portrait\r
+m=text 32900 udp nt\r
+c=IN IP4 224.2.100.103/127\r
+\r
+From 209.1.118.230.9875\r
+v=0\r
+o=Administrator 868490998 868548530 IN IP4 209.1.118.230 \r
+s=Ginacarlo's TV\r
+i=Giancarlo's TV Feed from ICAST in Los Gatos\r
+u=http://www.icast.com/\r
+e=sales@icast.com\r
+p=+01 408 8740700\r
+t=3080337120 3080689920\r
+r=79200 7200 0\r
+a=recvonly\r
+a=tool:ICAST TCC Server V1.0/Build 1-1010\r
+m=audio 4640 RTP/AVP 0\r
+c=IN IP4 224.2.100.120/127\r
+m=video 4920 RTP/AVP 31\r
+c=IN IP4 224.2.100.120/127\r
+b=AS:123\r
+a=framerate:20\r
+a=quality:7\r
+a=grayed:0\r
+\r
+From 128.93.25.32.9875\r
+v=0\r
+o=mbone 1782678111 3077454111 IN IP4 128.93.25.32\r
+s=WebCanal Test Channel\r
+i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/\r
+u=http://webcanal.inria.fr/\r
+e=mbone@monet.inria.fr\r
+t=0 0\r
+a=tool:WCaster1.0b\r
+a=pub:mbone\r
+a=logo:http://webcanal.inria.fr/icons/webcanal.gif\r
+a=cat:Test\r
+a=aud:All\r
+a=subs:Public Free\r
+m=midp 47130/2 MIDP/LRMP 0\r
+c=IN IP4 224.3.88.205/127/2\r
+b=AS:64\r
+\r
+From 128.93.25.32.9875\r
+v=0\r
+o=mbone 1782678111 3077454111 IN IP4 128.93.25.32\r
+s=WebCanal Test Channel\r
+i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/\r
+u=http://webcanal.inria.fr/\r
+e=mbone@monet.inria.fr\r
+t=0 0\r
+a=tool:WCaster1.0b\r
+a=pub:mbone\r
+a=logo:http://webcanal.inria.fr/icons/webcanal.gif\r
+a=cat:Test\r
+a=aud:All\r
+a=subs:Public Free\r
+m=midp 47130/2 MIDP/LRMP 0\r
+c=IN IP4 224.3.88.205/127/2\r
+b=AS:64\r
+\r
+From 198.147.175.43.5434\r
+v=0\r
+o=- 53099 27 IN IP4 198.147.175.59\r
+s=The World\r
+i=live feed of daily global radio news show \r
+a=admin:Bob Lyons\r
+e=Bob Lyons <feedback@wgbh.org>\r
+t=3076945200 3079465200\r
+r=1d 4h 0\r
+a=type:broadcast\r
+a=live\r
+a=channel:WGBH\r
+a=tool:IP/TV Program Guide 1.5.93\r
+m=video 65036 RTP/AVP 31 32 96\r
+c=IN IP4 224.2.227.248/127\r
+b=AS:100\r
+a=quality:7\r
+a=framerate:15\r
+a=rtpmap:96 WBIH/90000\r
+m=audio 30970 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103\r
+c=IN IP4 224.2.140.132/127\r
+a=rtpmap:96 L8/22050/2\r
+a=rtpmap:97 L8/22050\r
+a=rtpmap:98 L8/11025/2\r
+a=rtpmap:99 L8/11025\r
+a=rtpmap:100 L16/22050/2\r
+a=rtpmap:101 L16/22050\r
+a=rtpmap:102 L16/11025/2\r
+a=rtpmap:103 L16/11025\r
+\r
+From 198.147.175.43.5434\r
+v=0\r
+o=- 53099 27 IN IP4 198.147.175.59\r
+s=The World\r
+i=live feed of daily global radio news show \r
+a=admin:Bob Lyons\r
+e=Bob Lyons <feedback@wgbh.org>\r
+t=3076945200 3079465200\r
+r=1d 4h 0\r
+a=type:broadcast\r
+a=live\r
+a=channel:WGBH\r
+a=tool:IP/TV Program Guide 1.5.93\r
+m=video 65036 RTP/AVP 31 32 96\r
+c=IN IP4 224.2.227.248/127\r
+b=AS:100\r
+a=quality:7\r
+a=framerate:15\r
+a=rtpmap:96 WBIH/90000\r
+m=audio 30970 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103\r
+c=IN IP4 224.2.140.132/127\r
+a=rtpmap:96 L8/22050/2\r
+a=rtpmap:97 L8/22050\r
+a=rtpmap:98 L8/11025/2\r
+a=rtpmap:99 L8/11025\r
+a=rtpmap:100 L16/22050/2\r
+a=rtpmap:101 L16/22050\r
+a=rtpmap:102 L16/11025/2\r
+a=rtpmap:103 L16/11025\r
+\r
+From 128.223.32.151.40710\r
+v=0\r
+o=llynch 3075129061 3075129246 IN IP4 128.223.32.151\r
+s=UO Presents KWAX Classical Radio\r
+i=University of Oregon sponsored classical radio station KWAX-FM\r
+u=http://darkwing.uoregon.edu/~uocomm/\r
+e=Lucy Lynch (University of Oregon) <llynch@darkwing.uoegon.edu>\r
+p=Lucy Lynch (University of Oregon) (541) 346-1774\r
+c=IN IP4 224.2.246.13/127\r
+t=0 0\r
+a=tool:sdr v2.3a1\r
+a=type:test\r
+m=audio 30554 RTP/AVP 0\r
+c=IN IP4 224.2.246.13/127\r
+a=ptime:40\r
+\r
+From 130.240.64.67.32877\r
+v=0\r
+o=demo 3066564173 3066564269 IN IP4 130.240.64.67\r
+s=Places all over the world\r
+i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams).  Audio is primarily for feedback for the senders of video.\r
+e=Hakan Lennestal <hakanl@cdt.luth.se>\r
+c=IN IP4 224.2.172.238/127\r
+t=0 0\r
+a=tool:CDT mAnnouncer 1.1.1\r
+a=type:broadcast\r
+m=video 51482 RTP/AVP 31\r
+c=IN IP4 224.2.172.238/127\r
+m=audio 20154 RTP/AVP 121\r
+c=IN IP4 224.2.213.113/127\r
+a=rtpred1:5\r
+a=ptime:40\r
+a=rtpred2:5\r
+a=rtpmap:121 red/8000\r
+\r
+From 130.240.64.67.32877\r
+v=0\r
+o=demo 3066564173 3066564269 IN IP4 130.240.64.67\r
+s=Places all over the world\r
+i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams).  Audio is primarily for feedback for the senders of video.\r
+e=Hakan Lennestal <hakanl@cdt.luth.se>\r
+c=IN IP4 224.2.172.238/127\r
+t=0 0\r
+a=tool:CDT mAnnouncer 1.1.1\r
+a=type:broadcast\r
+m=video 51482 RTP/AVP 31\r
+c=IN IP4 224.2.172.238/127\r
+m=audio 20154 RTP/AVP 121\r
+c=IN IP4 224.2.213.113/127\r
+a=rtpred1:5\r
+a=ptime:40\r
+a=rtpred2:5\r
+a=rtpmap:121 red/8000\r
+\r
+From 199.94.220.184.1277\r
+v=0\r
+o=jhawk 3048365419 3049230379 IN IP4 199.94.220.184\r
+s=MBone RTP Audio\r
+i=Audio conference on vat's former default multicast address. This replaces sd's "MBone Audio".\r
+e=John Hawkinson <jhawk@bbnplanet.com>\r
+p=John Hawkinson +1 617 873 3180\r
+c=IN IP4 224.2.0.1/191\r
+t=3048724800 3082593600\r
+a=tool:sdr v2.3a1+jhawk's gdb script\r
+a=type:meeting\r
+m=audio 23456 RTP/AVP 0\r
+c=IN IP4 224.2.0.1/191\r
+a=ptime:40\r
+\r
+From 199.94.220.184.1277\r
+v=0\r
+o=jhawk 3048365419 3049230379 IN IP4 199.94.220.184\r
+s=MBone RTP Audio\r
+i=Audio conference on vat's former default multicast address. This replaces sd's "MBone Audio".\r
+e=John Hawkinson <jhawk@bbnplanet.com>\r
+p=John Hawkinson +1 617 873 3180\r
+c=IN IP4 224.2.0.1/191\r
+t=3048724800 3082593600\r
+a=tool:sdr v2.3a1+jhawk's gdb script\r
+a=type:meeting\r
+m=audio 23456 RTP/AVP 0\r
+c=IN IP4 224.2.0.1/191\r
+a=ptime:40\r
+\r
+From 36.24.0.23.35920\r
+v=0\r
+o=- 19357 1 IN IP4 171.64.2.89\r
+s=The Stanford Channel\r
+i=In order to support testing and to provide a consistent source of audio and video material, Stanford University is transmitting the Stanford Channel, M-F, 1-5p PDT. \r
+u=http://tsc.stanford.edu/tsc/\r
+a=admin:Jim Knox\r
+e=Jim Knox <mbone-support@lists.stanford.edu>\r
+p=Jim Knox <415-723-5100>\r
+t=3076084800 3084048000\r
+r=7d 4h 0 1d 2d 3d 4d\r
+a=type:broadcast\r
+a=live\r
+a=channel:External Stanford Channel\r
+a=tool:IP/TV Program Guide 1.5.97\r
+m=video 62970 RTP/AVP 31 32 96\r
+c=IN IP4 224.2.205.145/127\r
+b=AS:2500\r
+a=quality:7\r
+a=framerate:15\r
+a=rtpmap:96 WBIH/90000\r
+m=audio 17754 RTP/AVP 3\r
+c=IN IP4 224.2.170.73/127\r
+\r
+From 146.246.238.52.33095\r
+v=0\r
+o=dgomes 3076197571 3076936543 IN IP4 146.246.238.52\r
+s=Diesel Combustion Collaboratory\r
+i=This is a research MBone session initiated from the Sandia National Laboratory, California site.  This session will facilitate collaboration among the participants in a distributed research project, specifically the Heavy Duty Diesel Combustion CRADA using standard MBone A/V tools. For more information, http://www-collab.ca.sandia.gov/\r
+u=www-collab.ca.sandia.gov/\r
+e=Diesel Combustion Collaboratory <dgomes@ca.sandia.gov>\r
+p=Diesel Combustion Collaboratory 510-294-1479\r
+c=IN IP4 239.32.1.200/127\r
+t=3076142400 3078648000\r
+r=86400 86400 0\r
+a=tool:sdr v2.3a1\r
+a=type:meeting\r
+m=audio 23164 RTP/AVP 0\r
+c=IN IP4 239.32.1.200/127\r
+a=ptime:40\r
+m=video 53626 RTP/AVP 31\r
+c=IN IP4 239.32.1.200/127\r
+m=whiteboard 33870 udp wb\r
+c=IN IP4 239.32.1.200/127\r
+a=orient:portrait\r
+\r
+From 36.24.0.23.35920\r
+v=0\r
+o=- 9787 3 IN IP4 36.85.0.135\r
+s=45th Annual SIAM Meeting\r
+i=MSRI, with the cooperation of Stanford University and SIAM, will broadcast six of the principal lectures from the 45th annual SIAM meeting. Notes available at http://www.msri.org/lecturenotes/97/SIAM/ \r
+u=http://www.siam.org\r
+a=admin:David Hoffman\r
+e=David Hoffman <mbone@msri.org>\r
+p=David Hoffman <510-643-6071>\r
+t=3077967600 3078183600\r
+r=7d 12h 0 1d 2d\r
+a=type:broadcast\r
+a=live\r
+a=channel:MSRI Channel\r
+a=tool:IP/TV Program Guide 1.5.97\r
+m=video 52704 RTP/AVP 31 32 96\r
+c=IN IP4 224.2.220.253/127\r
+b=AS:128\r
+a=quality:7\r
+a=framerate:15\r
+a=rtpmap:96 WBIH/90000\r
+m=audio 30372 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103\r
+c=IN IP4 224.2.141.197/127\r
+a=rtpmap:96 L8/22050/2\r
+a=rtpmap:97 L8/22050\r
+a=rtpmap:98 L8/11025/2\r
+a=rtpmap:99 L8/11025\r
+a=rtpmap:100 L16/22050/2\r
+a=rtpmap:101 L16/22050\r
+a=rtpmap:102 L16/11025/2\r
+a=rtpmap:103 L16/11025\r
+\r
+From 128.9.160.43.1290\r
+v=0\r
+o=estrin 3077287048 3077287168 IN IP4 128.9.160.43\r
+s=PIM\r
+i=Weekly discussion of PIM and related issues\r
+p=310 822 1511 x253\r
+e=estrin@isi.edu\r
+t=3077287200 3079713600\r
+r=604800 7200 0\r
+a=tool:sdr v2.2a23\r
+a=type:test\r
+m=audio 26446 RTP/AVP 5\r
+c=IN IP4 224.2.237.137/127\r
+a=ptime:40\r
+m=whiteboard 48894 udp wb\r
+c=IN IP4 224.2.213.254/127\r
+m=text 60262 udp nt\r
+c=IN IP4 224.2.186.221/127\r
+\r
+From 210.115.193.22.32819\r
+v=0\r
+o=root 3076799605 3076799657 IN IP4 210.115.193.22\r
+s=KBS 1 TV\r
+i=Korean Broadcasting System TV\r
+u=www.kbs.co.kr\r
+p=KBS 1 TV 82-2-781-2562\r
+e=KBS 1 TV <webmaster@kbsnt.kbs.co.kr>\r
+t=3076799400 3079225800\r
+r=1209600 7200 0\r
+m=audio 20698 RTP/AVP 0\r
+c=IN IP4 224.2.235.192/127\r
+m=video 58150 RTP/AVP 31\r
+c=IN IP4 224.2.202.109/127\r
+\r
+From 141.213.8.193.32800\r
+v=0\r
+o=sugih 3066072073 3066072112 IN IP4 141.213.8.193\r
+s=UMich IRL (private)\r
+i=UMich private use\r
+u=http://irl.eecs.umich.edu/jamin/\r
+e=UMich IRL <jamin@eecs.umich.edu>\r
+p=UMich IRL +1 313 763 1583\r
+c=IN IP4 224.2.143.56/127\r
+t=0 0\r
+a=tool:sdr v2.3a1\r
+a=type:test\r
+m=audio 21690 RTP/AVP 0\r
+c=IN IP4 224.2.143.56/127\r
+a=ptime:40\r
+m=video 51990 RTP/AVP 31\r
+c=IN IP4 224.2.200.96/127\r
+m=whiteboard 47284 udp wb\r
+c=IN IP4 224.2.239.141/127\r
+m=text 54906 udp nt\r
+c=IN IP4 224.2.242.3/127\r
+\r
+From 141.213.8.193.32800\r
+v=0\r
+o=sugih 3066072073 3066072112 IN IP4 141.213.8.193\r
+s=UMich IRL (private)\r
+i=UMich private use\r
+u=http://irl.eecs.umich.edu/jamin/\r
+e=UMich IRL <jamin@eecs.umich.edu>\r
+p=UMich IRL +1 313 763 1583\r
+c=IN IP4 224.2.143.56/127\r
+t=0 0\r
+a=tool:sdr v2.3a1\r
+a=type:test\r
+m=audio 21690 RTP/AVP 0\r
+c=IN IP4 224.2.143.56/127\r
+a=ptime:40\r
+m=video 51990 RTP/AVP 31\r
+c=IN IP4 224.2.200.96/127\r
+m=whiteboard 47284 udp wb\r
+c=IN IP4 224.2.239.141/127\r
+m=text 54906 udp nt\r
+c=IN IP4 224.2.242.3/127\r
+\r
+From 209.1.118.230.9875\r
+v=0\r
+o=Administrator 868490998 868548530 IN IP4 209.1.118.230 \r
+s=Ginacarlo's TV\r
+i=Giancarlo's TV Feed from ICAST in Los Gatos\r
+u=http://www.icast.com/\r
+e=sales@icast.com\r
+p=+01 408 8740700\r
+t=3080337120 3080689920\r
+r=79200 7200 0\r
+a=recvonly\r
+a=tool:ICAST TCC Server V1.0/Build 1-1010\r
+m=audio 4640 RTP/AVP 0\r
+c=IN IP4 224.2.100.120/127\r
+m=video 4920 RTP/AVP 31\r
+c=IN IP4 224.2.100.120/127\r
+b=AS:123\r
+a=framerate:20\r
+a=quality:7\r
+a=grayed:0\r
+\r
+From 128.93.25.32.9875\r
+v=0\r
+o=mbone 1782678111 3077454111 IN IP4 128.93.25.32\r
+s=WebCanal Test Channel\r
+i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/\r
+u=http://webcanal.inria.fr/\r
+e=mbone@monet.inria.fr\r
+t=0 0\r
+a=tool:WCaster1.0b\r
+a=pub:mbone\r
+a=logo:http://webcanal.inria.fr/icons/webcanal.gif\r
+a=cat:Test\r
+a=aud:All\r
+a=subs:Public Free\r
+m=midp 47130/2 MIDP/LRMP 0\r
+c=IN IP4 224.3.88.205/127/2\r
+b=AS:64\r
+\r
+From 128.93.25.32.9875\r
+v=0\r
+o=mbone 1782678111 3077454111 IN IP4 128.93.25.32\r
+s=WebCanal Test Channel\r
+i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/\r
+u=http://webcanal.inria.fr/\r
+e=mbone@monet.inria.fr\r
+t=0 0\r
+a=tool:WCaster1.0b\r
+a=pub:mbone\r
+a=logo:http://webcanal.inria.fr/icons/webcanal.gif\r
+a=cat:Test\r
+a=aud:All\r
+a=subs:Public Free\r
+m=midp 47130/2 MIDP/LRMP 0\r
+c=IN IP4 224.3.88.205/127/2\r
+b=AS:64\r
+\r
+From 128.223.32.151.40710\r
+v=0\r
+o=llynch 3073936480 3075057183 IN IP4 128.223.32.151\r
+s=UO Presents KWVA Campus Radio\r
+i=University of Oregon alternative radio\r
+u=http://gladstone.uoregon.edu/~kwva/\r
+e=Lucy Lynch (University of Oregon) <llynch@darkwing.uoregon.edu>\r
+p=Lucy Lynch (University of Oregon) (541) 346-1774\r
+c=IN IP4 224.2.240.123/127\r
+t=0 0\r
+a=tool:sdr v2.3a1\r
+a=type:test\r
+m=audio 24676 RTP/AVP 0\r
+c=IN IP4 224.2.240.123/127\r
+a=ptime:40\r
+\r
+From 128.102.84.134.1085\r
+v=0\r
+o=shuttle 3075630923 3075633526 IN IP4 128.102.84.134\r
+s=NASA Space Shuttle STS-94\r
+i=Video/Audio broadcast of NASA space shuttle mission STS-94, Microgravity Science Laboratory-1.  This session is being broadcast as a service to the MBONE community by NASA-Ames Reseach Center.\r
+u=http://www-pao.ksc.nasa.gov/kscpao/kscpao.htm\r
+e=NASA - ARC Digital Video Lab <mallard@mail.arc.nasa.gov\r
+e=Brian Tonner (UWM) <tonner@csd.uwm.edu>\r
+e=Referenzzentrum __ <mmt-ref@tu-dresden.de>       \r
+e=IN IP4 224.2.212.30/75\r
+p=NASA - ARC Digital Video Lab (415) 604-6145\r
+p=Brian Tonner (at LBL) 510-486-5590\r
+p=Brian Tonner (at UWM) 414-229-4626\r
+c=IN IP4 224.2.210.20/127\r
+t=3076354800 3078774000\r
+m=audio 24680 RTP/AVP 0\r
+c=IN IP4 224.2.210.20/127\r
+m=video 56062 RTP/AVP 31\r
+c=IN IP4 224.2.210.20/127\r
+\r
+From 134.95.100.200.58695\r
+v=0\r
+o=maho 3077528617 3077529148 IN IP4 134.95.19.9\r
+s=Munich IETF Meeting - 1\r
+c=IN IP4 224.2.224.236/127\r
+i=The thirty-nineth IETF meeting will be held in Munich, Germany, 11-15 August 1997. Channel 1 contains sessions in room Congress AB.\r
+u=http://www.ietf.org/meetings/Munich.html\r
+e=Martin Horneffer (RRZK) <Horneffer@rrz.Uni-Koeln.DE>\r
+p=Martin Horneffer (RRZK) +49-221-4785587\r
+k=\r
+t=3080271600 3080617200\r
+a=tool:CDT sapAnnouncer 1.1\r
+a=type:test\r
+m=audio 30284 RTP/AVP 0\r
+c=IN IP4 224.2.224.236/127\r
+a=ptime:40\r
+m=video 64318 RTP/AVP 31\r
+c=IN IP4 224.2.191.28/127\r
+m=whiteboard 43063 udp wb\r
+c=IN IP4 224.2.164.26/127\r
+m=text 65035 udp nt\r
+c=IN IP4 224.2.148.199/127\r
+\r
+From 134.95.100.200.58695\r
+v=0\r
+o=maho 3077529159 3077529337 IN IP4 134.95.19.9\r
+s=Munich IETF Meeting - 2\r
+c=IN IP4 224.2.128.106/127\r
+i=The thirty-nineth IETF meeting will be held in Munich, Germany, 11-15 August 1997. Channel 1 contains sessions in room Congress 1.\r
+u=http://www.ietf.org/meetings/Munich.html\r
+e=Martin Horneffer (RRZK) <Horneffer@rrz.Uni-Koeln.DE>\r
+p=Martin Horneffer (RRZK) +49-221-4785587\r
+k=\r
+t=3080271600 3080617200\r
+a=tool:CDT sapAnnouncer 1.1\r
+a=type:test\r
+m=audio 25056 RTP/AVP 0\r
+c=IN IP4 224.2.128.106/127\r
+a=ptime:40\r
+m=video 55020 RTP/AVP 31\r
+c=IN IP4 224.2.216.39/127\r
+m=whiteboard 47819 udp wb\r
+c=IN IP4 224.2.139.138/127\r
+m=text 50930 udp nt\r
+c=IN IP4 224.2.161.177/127\r
+\r
+From 134.95.100.200.58695\r
+v=0\r
+o=maho 3077528617 3077529148 IN IP4 134.95.19.9\r
+s=Munich IETF Meeting - 1\r
+c=IN IP4 224.2.224.236/127\r
+i=The thirty-nineth IETF meeting will be held in Munich, Germany, 11-15 August 1997. Channel 1 contains sessions in room Congress AB.\r
+u=http://www.ietf.org/meetings/Munich.html\r
+e=Martin Horneffer (RRZK) <Horneffer@rrz.Uni-Koeln.DE>\r
+p=Martin Horneffer (RRZK) +49-221-4785587\r
+k=\r
+t=3080271600 3080617200\r
+a=tool:CDT sapAnnouncer 1.1\r
+a=type:test\r
+m=audio 30284 RTP/AVP 0\r
+c=IN IP4 224.2.224.236/127\r
+a=ptime:40\r
+m=video 64318 RTP/AVP 31\r
+c=IN IP4 224.2.191.28/127\r
+m=whiteboard 43063 udp wb\r
+c=IN IP4 224.2.164.26/127\r
+m=text 65035 udp nt\r
+c=IN IP4 224.2.148.199/127\r
+\r
+From 128.9.160.67.1286\r
+v=0\r
+o=kannan 3077640111 3077640271 IN IP4 128.9.160.67\r
+s=VINT (private)\r
+i=Virtual conference room for VINT developers\r
+u=http://netweb.usc.edu/vint\r
+e=Kannan Varadhan <kannan@catarina.usc.edu>\r
+p=Kannan Varadhan +1 310 822 1511 x742\r
+c=IN IP4 224.2.211.93/127\r
+t=0 0\r
+a=tool:sdr v2.4a6\r
+a=type:meeting\r
+m=audio 32390 RTP/AVP 5\r
+c=IN IP4 224.2.211.93/127\r
+a=ptime:40\r
+m=whiteboard 44600 udp wb\r
+c=IN IP4 224.2.163.53/127\r
+a=orient:landscape\r
+m=text 51493 udp nt\r
+c=IN IP4 224.2.208.110/127\r
+\r
+From 128.146.222.100.32915\r
+v=0\r
+o=maf 3076346251 3077639429 IN IP4 128.146.222.100\r
+s=Recent Advances in Networking Seminar at OSU\r
+i=Live Transmission of Professor Raj Jain's class CIS788.08q:  Recent Advances in Networking every Tuesday and Thursday at 17:30 to 18:45 EDT, Open to public.  E-mail questions to mbone@netlab.ohio-state.edu.  See URL for list of topics. \r
+u=http://www.cis.ohio-state.edu/~jain/cis788-97/schedule.htm\r
+p=Mark Fullmer (Ohio State) 614-292-6159\r
+e=Mark Fullmer (Ohio State) <maf@net.ohio-state.edu>\r
+t=3078163800 3079380600\r
+r=604800 7200 0\r
+a=tool:sdr v2.3a1\r
+a=type:broadcast\r
+m=audio 19922 RTP/AVP 0\r
+c=IN IP4 224.2.232.28/127\r
+a=ptime:40\r
+m=video 60266 RTP/AVP 31\r
+c=IN IP4 224.2.159.63/127\r
+\r
+From 128.146.222.100.32915\r
+v=0\r
+o=maf 3076346251 3077639429 IN IP4 128.146.222.100\r
+s=Recent Advances in Networking Seminar at OSU\r
+i=Live Transmission of Professor Raj Jain's class CIS788.08q:  Recent Advances in Networking every Tuesday and Thursday at 17:30 to 18:45 EDT, Open to public.  E-mail questions to mbone@netlab.ohio-state.edu.  See URL for list of topics. \r
+u=http://www.cis.ohio-state.edu/~jain/cis788-97/schedule.htm\r
+p=Mark Fullmer (Ohio State) 614-292-6159\r
+e=Mark Fullmer (Ohio State) <maf@net.ohio-state.edu>\r
+t=3078163800 3079380600\r
+r=604800 7200 0\r
+a=tool:sdr v2.3a1\r
+a=type:broadcast\r
+m=audio 19922 RTP/AVP 0\r
+c=IN IP4 224.2.232.28/127\r
+a=ptime:40\r
+m=video 60266 RTP/AVP 31\r
+c=IN IP4 224.2.159.63/127\r
+\r
+From 128.9.160.67.1286\r
+v=0\r
+o=kannan 3076332385 3076332494 IN IP4 128.9.160.67\r
+s=USC-CS dgroup VR conference room (private)\r
+i=Watering hole for the USC-NIL lab members\r
+u=http://netweb.usc.edu/\r
+e=Kannan Varadhan <kannan@catarina.usc.edu>\r
+p=Kannan Varadhan +1 310 822 1511 x742\r
+c=IN IP4 224.2.212.30/75\r
+t=0 0\r
+a=tool:sdr v2.3a1\r
+a=type:meeting\r
+m=audio 45144 RTP/AVP 5\r
+c=IN IP4 224.2.212.30/75\r
+a=ptime:40\r
+m=whiteboard 65304 udp wb\r
+c=IN IP4 224.2.212.30/75\r
+a=orient:landscape\r
+\r
+From 198.147.175.43.5435\r
+v=0\r
+o=- 53099 27 IN IP4 198.147.175.59\r
+s=The World\r
+i=live feed of daily global radio news show \r
+a=admin:Bob Lyons\r
+e=Bob Lyons <feedback@wgbh.org>\r
+t=3076945200 3079465200\r
+r=1d 4h 0\r
+a=type:broadcast\r
+a=live\r
+a=channel:WGBH\r
+a=tool:IP/TV Program Guide 1.5.93\r
+m=video 65036 RTP/AVP 31 32 96\r
+c=IN IP4 224.2.227.248/127\r
+b=AS:100\r
+a=quality:7\r
+a=framerate:15\r
+a=rtpmap:96 WBIH/90000\r
+m=audio 30970 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103\r
+c=IN IP4 224.2.140.132/127\r
+a=rtpmap:96 L8/22050/2\r
+a=rtpmap:97 L8/22050\r
+a=rtpmap:98 L8/11025/2\r
+a=rtpmap:99 L8/11025\r
+a=rtpmap:100 L16/22050/2\r
+a=rtpmap:101 L16/22050\r
+a=rtpmap:102 L16/11025/2\r
+a=rtpmap:103 L16/11025\r
+\r
+From 198.147.175.43.5435\r
+v=0\r
+o=- 53099 27 IN IP4 198.147.175.59\r
+s=The World\r
+i=live feed of daily global radio news show \r
+a=admin:Bob Lyons\r
+e=Bob Lyons <feedback@wgbh.org>\r
+t=3076945200 3079465200\r
+r=1d 4h 0\r
+a=type:broadcast\r
+a=live\r
+a=channel:WGBH\r
+a=tool:IP/TV Program Guide 1.5.93\r
+m=video 65036 RTP/AVP 31 32 96\r
+c=IN IP4 224.2.227.248/127\r
+b=AS:100\r
+a=quality:7\r
+a=framerate:15\r
+a=rtpmap:96 WBIH/90000\r
+m=audio 30970 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103\r
+c=IN IP4 224.2.140.132/127\r
+a=rtpmap:96 L8/22050/2\r
+a=rtpmap:97 L8/22050\r
+a=rtpmap:98 L8/11025/2\r
+a=rtpmap:99 L8/11025\r
+a=rtpmap:100 L16/22050/2\r
+a=rtpmap:101 L16/22050\r
+a=rtpmap:102 L16/11025/2\r
+a=rtpmap:103 L16/11025\r
+\r
+From 146.139.72.5.32924\r
+v=0\r
+o=root 3077452673 3077455201 IN IP4 146.139.72.5\r
+s=ANL TelePresence Microscopy Site/Materials MicroCharacterization Collaboratory\r
+i=This is  ANL TelePresence Microscopy Site which is  part of the DoE 2000 Materials Microcharacterization Collaboratory. It facilitates  on-line access to unique resourses at the ANL AAEM and through the MMC, other resources in the Collaboratory at member sites (ORNL, LBNL, Univ. of Illinois and NIST).  More information about the TPM and the MMC can be found at http://tpm.amc.anl.gov/mmc\r
+u=http://tpm.amc.anl.gov\r
+p=Nestor J. Zaluzec 630-252-7901\r
+e=Nestor J. Zaluzec <Zaluzec@aaem.amc.anl.gov>\r
+t=3077445600 3079900800\r
+r=86400 36000 0\r
+a=tool:sdr v2.3a1\r
+a=type:meeting\r
+m=audio 27028 RTP/AVP 0\r
+c=IN IP4 224.2.222.131/127\r
+a=ptime:40\r
+m=video 58800 RTP/AVP 31\r
+c=IN IP4 224.2.141.204/127\r
+\r
+From 146.139.72.5.32924\r
+v=0\r
+o=root 3077452673 3077455201 IN IP4 146.139.72.5\r
+s=ANL TelePresence Microscopy Site/Materials MicroCharacterization Collaboratory\r
+i=This is  ANL TelePresence Microscopy Site which is  part of the DoE 2000 Materials Microcharacterization Collaboratory. It facilitates  on-line access to unique resourses at the ANL AAEM and through the MMC, other resources in the Collaboratory at member sites (ORNL, LBNL, Univ. of Illinois and NIST).  More information about the TPM and the MMC can be found at http://tpm.amc.anl.gov/mmc\r
+u=http://tpm.amc.anl.gov\r
+p=Nestor J. Zaluzec 630-252-7901\r
+e=Nestor J. Zaluzec <Zaluzec@aaem.amc.anl.gov>\r
+t=3077445600 3079900800\r
+r=86400 36000 0\r
+a=tool:sdr v2.3a1\r
+a=type:meeting\r
+m=audio 27028 RTP/AVP 0\r
+c=IN IP4 224.2.222.131/127\r
+a=ptime:40\r
+m=video 58800 RTP/AVP 31\r
+c=IN IP4 224.2.141.204/127\r
+\r
+From 140.247.157.193.1047\r
+v=0\r
+o=karp 3077576976 3077577964 IN IP4 140.247.157.193\r
+s=Harvard's Aiken Computation Lab DEMOLITION\r
+i=Live broadcast of the demolition of Harvard University's Aiken Computation Lab, to make way for the new Computer Science building, Maxwell-Dworkin. Broadcast will include commentary on the event by Harvard faculty, administrators, and students. Filmed in Destruct-O-Vision, from an unmanned camera INSIDE Aiken.\r
+u=http://www.eecs.harvard.edu/aiken-go-boom\r
+e=Brad Karp <karp@eecs.harvard.edu>\r
+p=Brad Karp +1 617-661-4979\r
+c=IN IP4 224.2.156.29/127\r
+t=3078820800 3080030400\r
+a=tool:sdr v2.4a6\r
+a=type:broadcast\r
+m=audio 21226 RTP/AVP 5\r
+c=IN IP4 224.2.156.29/127\r
+a=ptime:40\r
+m=video 49998 RTP/AVP 31\r
+c=IN IP4 224.2.237.48/127\r
+\r
+From 140.247.157.193.1047\r
+v=0\r
+o=karp 3077576976 3077577964 IN IP4 140.247.157.193\r
+s=Harvard's Aiken Computation Lab DEMOLITION\r
+i=Live broadcast of the demolition of Harvard University's Aiken Computation Lab, to make way for the new Computer Science building, Maxwell-Dworkin. Broadcast will include commentary on the event by Harvard faculty, administrators, and students. Filmed in Destruct-O-Vision, from an unmanned camera INSIDE Aiken.\r
+u=http://www.eecs.harvard.edu/aiken-go-boom\r
+e=Brad Karp <karp@eecs.harvard.edu>\r
+p=Brad Karp +1 617-661-4979\r
+c=IN IP4 224.2.156.29/127\r
+t=3078820800 3080030400\r
+a=tool:sdr v2.4a6\r
+a=type:broadcast\r
+m=audio 21226 RTP/AVP 5\r
+c=IN IP4 224.2.156.29/127\r
+a=ptime:40\r
+m=video 49998 RTP/AVP 31\r
+c=IN IP4 224.2.237.48/127\r
+\r
+From 209.1.118.230.9875\r
+v=0\r
+o=Administrator 868490998 868548530 IN IP4 209.1.118.230 \r
+s=Ginacarlo's TV\r
+i=Giancarlo's TV Feed from ICAST in Los Gatos\r
+u=http://www.icast.com/\r
+e=sales@icast.com\r
+p=+01 408 8740700\r
+t=3080337120 3080689920\r
+r=79200 7200 0\r
+a=recvonly\r
+a=tool:ICAST TCC Server V1.0/Build 1-1010\r
+m=audio 4640 RTP/AVP 0\r
+c=IN IP4 224.2.100.120/127\r
+m=video 4920 RTP/AVP 31\r
+c=IN IP4 224.2.100.120/127\r
+b=AS:123\r
+a=framerate:20\r
+a=quality:7\r
+a=grayed:0\r
+\r
+From 128.93.25.32.9875\r
+v=0\r
+o=mbone 1782678111 3077454111 IN IP4 128.93.25.32\r
+s=WebCanal Test Channel\r
+i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/\r
+u=http://webcanal.inria.fr/\r
+e=mbone@monet.inria.fr\r
+t=0 0\r
+a=tool:WCaster1.0b\r
+a=pub:mbone\r
+a=logo:http://webcanal.inria.fr/icons/webcanal.gif\r
+a=cat:Test\r
+a=aud:All\r
+a=subs:Public Free\r
+m=midp 47130/2 MIDP/LRMP 0\r
+c=IN IP4 224.3.88.205/127/2\r
+b=AS:64\r
+\r
+From 128.93.25.32.9875\r
+v=0\r
+o=mbone 1782678111 3077454111 IN IP4 128.93.25.32\r
+s=WebCanal Test Channel\r
+i=Test of WebCanal push channel. For more information, please refer to http://webcanal.inria.fr/\r
+u=http://webcanal.inria.fr/\r
+e=mbone@monet.inria.fr\r
+t=0 0\r
+a=tool:WCaster1.0b\r
+a=pub:mbone\r
+a=logo:http://webcanal.inria.fr/icons/webcanal.gif\r
+a=cat:Test\r
+a=aud:All\r
+a=subs:Public Free\r
+m=midp 47130/2 MIDP/LRMP 0\r
+c=IN IP4 224.3.88.205/127/2\r
+b=AS:64\r
+\r
+From 130.240.64.67.32877\r
+v=0\r
+o=demo 3066564173 3066564269 IN IP4 130.240.64.67\r
+s=Places all over the world\r
+i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams).  Audio is primarily for feedback for the senders of video.\r
+e=Hakan Lennestal <hakanl@cdt.luth.se>\r
+c=IN IP4 224.2.172.238/127\r
+t=0 0\r
+a=tool:CDT mAnnouncer 1.1.1\r
+a=type:broadcast\r
+m=video 51482 RTP/AVP 31\r
+c=IN IP4 224.2.172.238/127\r
+m=audio 20154 RTP/AVP 121\r
+c=IN IP4 224.2.213.113/127\r
+a=rtpred1:5\r
+a=ptime:40\r
+a=rtpred2:5\r
+a=rtpmap:121 red/8000\r
+\r
+From 130.240.64.67.32877\r
+v=0\r
+o=demo 3066564173 3066564269 IN IP4 130.240.64.67\r
+s=Places all over the world\r
+i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams).  Audio is primarily for feedback for the senders of video.\r
+e=Hakan Lennestal <hakanl@cdt.luth.se>\r
+c=IN IP4 224.2.172.238/127\r
+t=0 0\r
+a=tool:CDT mAnnouncer 1.1.1\r
+a=type:broadcast\r
+m=video 51482 RTP/AVP 31\r
+c=IN IP4 224.2.172.238/127\r
+m=audio 20154 RTP/AVP 121\r
+c=IN IP4 224.2.213.113/127\r
+a=rtpred1:5\r
+a=ptime:40\r
+a=rtpred2:5\r
+a=rtpmap:121 red/8000\r
+\r
+From 129.89.142.50.1175\r
+v=0\r
+o=james 3054298051 3054298223 IN IP4 129.89.142.50\r
+s=FreeBSD Lounge\r
+i=Channel to discuss FreeBSD related issues.  Please keep video bandwidth below 64kbps.\r
+e=Jim Lowe <james@cs.uwm.edu>\r
+p=Jim Lowe (414) 229-6634\r
+c=IN IP4 224.2.100.100/127\r
+t=0 0\r
+a=tool:sdr v2.2a23\r
+a=type:test\r
+m=audio 16400 RTP/AVP 0\r
+c=IN IP4 224.2.100.100/127\r
+a=ptime:40\r
+m=video 49200 RTP/AVP 31\r
+c=IN IP4 224.2.100.102/127\r
+m=whiteboard 32800 udp wb\r
+c=IN IP4 224.2.100.101/127\r
+a=orient:portrait\r
+m=text 32900 udp nt\r
+c=IN IP4 224.2.100.103/127\r
+\r
+From 129.89.142.50.1175\r
+v=0\r
+o=james 3054298051 3054298223 IN IP4 129.89.142.50\r
+s=FreeBSD Lounge\r
+i=Channel to discuss FreeBSD related issues.  Please keep video bandwidth below 64kbps.\r
+e=Jim Lowe <james@cs.uwm.edu>\r
+p=Jim Lowe (414) 229-6634\r
+c=IN IP4 224.2.100.100/127\r
+t=0 0\r
+a=tool:sdr v2.2a23\r
+a=type:test\r
+m=audio 16400 RTP/AVP 0\r
+c=IN IP4 224.2.100.100/127\r
+a=ptime:40\r
+m=video 49200 RTP/AVP 31\r
+c=IN IP4 224.2.100.102/127\r
+m=whiteboard 32800 udp wb\r
+c=IN IP4 224.2.100.101/127\r
+a=orient:portrait\r
+m=text 32900 udp nt\r
+c=IN IP4 224.2.100.103/127\r
+\r
+From 36.24.0.23.35921\r
+v=0\r
+o=- 19357 1 IN IP4 171.64.2.89\r
+s=The Stanford Channel\r
+i=In order to support testing and to provide a consistent source of audio and video material, Stanford University is transmitting the Stanford Channel, M-F, 1-5p PDT. \r
+u=http://tsc.stanford.edu/tsc/\r
+a=admin:Jim Knox\r
+e=Jim Knox <mbone-support@lists.stanford.edu>\r
+p=Jim Knox <415-723-5100>\r
+t=3076084800 3084048000\r
+r=7d 4h 0 1d 2d 3d 4d\r
+a=type:broadcast\r
+a=live\r
+a=channel:External Stanford Channel\r
+a=tool:IP/TV Program Guide 1.5.97\r
+m=video 62970 RTP/AVP 31 32 96\r
+c=IN IP4 224.2.205.145/127\r
+b=AS:2500\r
+a=quality:7\r
+a=framerate:15\r
+a=rtpmap:96 WBIH/90000\r
+m=audio 17754 RTP/AVP 3\r
+c=IN IP4 224.2.170.73/127\r
+\r
+From 36.24.0.23.35921\r
+v=0\r
+o=- 9787 3 IN IP4 36.85.0.135\r
+s=45th Annual SIAM Meeting\r
+i=MSRI, with the cooperation of Stanford University and SIAM, will broadcast six of the principal lectures from the 45th annual SIAM meeting. Notes available at http://www.msri.org/lecturenotes/97/SIAM/ \r
+u=http://www.siam.org\r
+a=admin:David Hoffman\r
+e=David Hoffman <mbone@msri.org>\r
+p=David Hoffman <510-643-6071>\r
+t=3077967600 3078183600\r
+r=7d 12h 0 1d 2d\r
+a=type:broadcast\r
+a=live\r
+a=channel:MSRI Channel\r
+a=tool:IP/TV Program Guide 1.5.97\r
+m=video 52704 RTP/AVP 31 32 96\r
+c=IN IP4 224.2.220.253/127\r
+b=AS:128\r
+a=quality:7\r
+a=framerate:15\r
+a=rtpmap:96 WBIH/90000\r
+m=audio 30372 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103\r
+c=IN IP4 224.2.141.197/127\r
+a=rtpmap:96 L8/22050/2\r
+a=rtpmap:97 L8/22050\r
+a=rtpmap:98 L8/11025/2\r
+a=rtpmap:99 L8/11025\r
+a=rtpmap:100 L16/22050/2\r
+a=rtpmap:101 L16/22050\r
+a=rtpmap:102 L16/11025/2\r
+a=rtpmap:103 L16/11025\r
+\r
+From 128.102.84.134.1085\r
+v=0\r
+o=shuttle 3075630923 3075633526 IN IP4 128.102.84.134\r
+s=NASA Space Shuttle STS-94\r
+i=Video/Audio broadcast of NASA space shuttle mission STS-94, Microgravity Science Laboratory-1.  This session is being broadcast as a service to the MBONE community by NASA-Ames Reseach Center.\r
+u=http://www-pao.ksc.nasa.gov/kscpao/kscpao.htm\r
+e=NASA - ARC Digital Video Lab <mallard@mail.arc.nasa.gov\r
+e=Brian Tonner (UWM) <tonner@csd.uwm.edu>\r
+e=Referenzzentrum __ <mmt-ref@tu-dresden.de>       \r
+e=IN IP4 224.2.212.30/75\r
+p=NASA - ARC Digital Video Lab (415) 604-6145\r
+p=Brian Tonner (at LBL) 510-486-5590\r
+p=Brian Tonner (at UWM) 414-229-4626\r
+c=IN IP4 224.2.210.20/127\r
+t=3076354800 3078774000\r
+m=audio 24680 RTP/AVP 0\r
+c=IN IP4 224.2.210.20/127\r
+m=video 56062 RTP/AVP 31\r
+c=IN IP4 224.2.210.20/127\r
+\r
+From 146.246.238.52.33095\r
+v=0\r
+o=dgomes 3076197571 3076936543 IN IP4 146.246.238.52\r
+s=Diesel Combustion Collaboratory\r
+i=This is a research MBone session initiated from the Sandia National Laboratory, California site.  This session will facilitate collaboration among the participants in a distributed research project, specifically the Heavy Duty Diesel Combustion CRADA using standard MBone A/V tools. For more information, http://www-collab.ca.sandia.gov/\r
+u=www-collab.ca.sandia.gov/\r
+e=Diesel Combustion Collaboratory <dgomes@ca.sandia.gov>\r
+p=Diesel Combustion Collaboratory 510-294-1479\r
+c=IN IP4 239.32.1.200/127\r
+t=3076142400 3078648000\r
+r=86400 86400 0\r
+a=tool:sdr v2.3a1\r
+a=type:meeting\r
+m=audio 23164 RTP/AVP 0\r
+c=IN IP4 239.32.1.200/127\r
+a=ptime:40\r
+m=video 53626 RTP/AVP 31\r
+c=IN IP4 239.32.1.200/127\r
+m=whiteboard 33870 udp wb\r
+c=IN IP4 239.32.1.200/127\r
+a=orient:portrait\r
+\r
+From 210.115.193.22.32819\r
+v=0\r
+o=root 3076799605 3076799657 IN IP4 210.115.193.22\r
+s=KBS 1 TV\r
+i=Korean Broadcasting System TV\r
+u=www.kbs.co.kr\r
+p=KBS 1 TV 82-2-781-2562\r
+e=KBS 1 TV <webmaster@kbsnt.kbs.co.kr>\r
+t=3076799400 3079225800\r
+r=1209600 7200 0\r
+m=audio 20698 RTP/AVP 0\r
+c=IN IP4 224.2.235.192/127\r
+m=video 58150 RTP/AVP 31\r
+c=IN IP4 224.2.202.109/127\r
+\r
+From 199.94.220.184.1277\r
+v=0\r
+o=jhawk 3048365419 3049230379 IN IP4 199.94.220.184\r
+s=MBone RTP Audio\r
+i=Audio conference on vat's former default multicast address. This replaces sd's "MBone Audio".\r
+e=John Hawkinson <jhawk@bbnplanet.com>\r
+p=John Hawkinson +1 617 873 3180\r
+c=IN IP4 224.2.0.1/191\r
+t=3048724800 3082593600\r
+a=tool:sdr v2.3a1+jhawk's gdb script\r
+a=type:meeting\r
+m=audio 23456 RTP/AVP 0\r
+c=IN IP4 224.2.0.1/191\r
+a=ptime:40\r
+\r
+From 199.94.220.184.1277\r
+v=0\r
+o=jhawk 3048365419 3049230379 IN IP4 199.94.220.184\r
+s=MBone RTP Audio\r
+i=Audio conference on vat's former default multicast address. This replaces sd's "MBone Audio".\r
+e=John Hawkinson <jhawk@bbnplanet.com>\r
+p=John Hawkinson +1 617 873 3180\r
+c=IN IP4 224.2.0.1/191\r
+t=3048724800 3082593600\r
+a=tool:sdr v2.3a1+jhawk's gdb script\r
+a=type:meeting\r
+m=audio 23456 RTP/AVP 0\r
+c=IN IP4 224.2.0.1/191\r
+a=ptime:40\r
+\r
+From 128.223.32.151.40710\r
+v=0\r
+o=llynch 3075129061 3075129246 IN IP4 128.223.32.151\r
+s=UO Presents KWAX Classical Radio\r
+i=University of Oregon sponsored classical radio station KWAX-FM\r
+u=http://darkwing.uoregon.edu/~uocomm/\r
+e=Lucy Lynch (University of Oregon) <llynch@darkwing.uoegon.edu>\r
+p=Lucy Lynch (University of Oregon) (541) 346-1774\r
+c=IN IP4 224.2.246.13/127\r
+t=0 0\r
+a=tool:sdr v2.3a1\r
+a=type:test\r
+m=audio 30554 RTP/AVP 0\r
+c=IN IP4 224.2.246.13/127\r
+a=ptime:40\r
+\r
+From 209.1.118.230.9875\r
+v=0\r
+o=Administrator 868490998 868548530 IN IP4 209.1.118.230 \r
+s=Ginacarlo's TV\r
+i=Giancarlo's TV Feed from ICAST in Los Gatos\r
+u=http://www.icast.com/\r
+e=sales@icast.com\r
+p=+01 408 8740700\r
+t=3080337120 3080689920\r
+r=79200 7200 0\r
+a=recvonly\r
+a=tool:ICAST TCC Server V1.0/Build 1-1010\r
+m=audio 4640 RTP/AVP 0\r
+c=IN IP4 224.2.100.120/127\r
+m=video 4920 RTP/AVP 31\r
+c=IN IP4 224.2.100.120/127\r
+b=AS:123\r
+a=framerate:20\r
+a=quality:7\r
+a=grayed:0\r
+\r
+From 198.147.175.43.5436\r
+v=0\r
+o=- 53099 27 IN IP4 198.147.175.59\r
+s=The World\r
+i=live feed of daily global radio news show \r
+a=admin:Bob Lyons\r
+e=Bob Lyons <feedback@wgbh.org>\r
+t=3076945200 3079465200\r
+r=1d 4h 0\r
+a=type:broadcast\r
+a=live\r
+a=channel:WGBH\r
+a=tool:IP/TV Program Guide 1.5.93\r
+m=video 65036 RTP/AVP 31 32 96\r
+c=IN IP4 224.2.227.248/127\r
+b=AS:100\r
+a=quality:7\r
+a=framerate:15\r
+a=rtpmap:96 WBIH/90000\r
+m=audio 30970 RTP/AVP 0 14 3 5 96 97 98 99 100 101 102 103\r
+c=IN IP4 224.2.140.132/127\r
+a=rtpmap:96 L8/22050/2\r
+a=rtpmap:97 L8/22050\r
+a=rtpmap:98 L8/11025/2\r
+a=rtpmap:99 L8/11025\r
+a=rtpmap:100 L16/22050/2\r
+a=rtpmap:101 L16/22050\r
+a=rtpmap:102 L16/11025/2\r
+a=rtpmap:103 L16/11025\r
+\r
+From 141.213.8.193.32800\r
+v=0\r
+o=sugih 3066072073 3066072112 IN IP4 141.213.8.193\r
+s=UMich IRL (private)\r
+i=UMich private use\r
+u=http://irl.eecs.umich.edu/jamin/\r
+e=UMich IRL <jamin@eecs.umich.edu>\r
+p=UMich IRL +1 313 763 1583\r
+c=IN IP4 224.2.143.56/127\r
+t=0 0\r
+a=tool:sdr v2.3a1\r
+a=type:test\r
+m=audio 21690 RTP/AVP 0\r
+c=IN IP4 224.2.143.56/127\r
+a=ptime:40\r
+m=video 51990 RTP/AVP 31\r
+c=IN IP4 224.2.200.96/127\r
+m=whiteboard 47284 udp wb\r
+c=IN IP4 224.2.239.141/127\r
+m=text 54906 udp nt\r
+c=IN IP4 224.2.242.3/127\r
+\r
+From 141.213.8.193.32800\r
+v=0\r
+o=sugih 3066072073 3066072112 IN IP4 141.213.8.193\r
+s=UMich IRL (private)\r
+i=UMich private use\r
+u=http://irl.eecs.umich.edu/jamin/\r
+e=UMich IRL <jamin@eecs.umich.edu>\r
+p=UMich IRL +1 313 763 1583\r
+c=IN IP4 224.2.143.56/127\r
+t=0 0\r
+a=tool:sdr v2.3a1\r
+a=type:test\r
+m=audio 21690 RTP/AVP 0\r
+c=IN IP4 224.2.143.56/127\r
+a=ptime:40\r
+m=video 51990 RTP/AVP 31\r
+c=IN IP4 224.2.200.96/127\r
+m=whiteboard 47284 udp wb\r
+c=IN IP4 224.2.239.141/127\r
+m=text 54906 udp nt\r
+c=IN IP4 224.2.242.3/127\r
+\r
+From 128.9.160.67.1286\r
+v=0\r
+o=kannan 3076332385 3076332494 IN IP4 128.9.160.67\r
+s=USC-CS dgroup VR conference room (private)\r
+i=Watering hole for the USC-NIL lab members\r
+u=http://netweb.usc.edu/\r
+e=Kannan Varadhan <kannan@catarina.usc.edu>\r
+p=Kannan Varadhan +1 310 822 1511 x742\r
+c=IN IP4 224.2.212.30/75\r
+t=0 0\r
+a=tool:sdr v2.3a1\r
+a=type:meeting\r
+m=audio 45144 RTP/AVP 5\r
+c=IN IP4 224.2.212.30/75\r
+a=ptime:40\r
+m=whiteboard 65304 udp wb\r
+c=IN IP4 224.2.212.30/75\r
+a=orient:landscape\r
+\r
+From 146.139.72.5.32924\r
+v=0\r
+o=root 3077452673 3077455201 IN IP4 146.139.72.5\r
+s=ANL TelePresence Microscopy Site/Materials MicroCharacterization Collaboratory\r
+i=This is  ANL TelePresence Microscopy Site which is  part of the DoE 2000 Materials Microcharacterization Collaboratory. It facilitates  on-line access to unique resourses at the ANL AAEM and through the MMC, other resources in the Collaboratory at member sites (ORNL, LBNL, Univ. of Illinois and NIST).  More information about the TPM and the MMC can be found at http://tpm.amc.anl.gov/mmc\r
+u=http://tpm.amc.anl.gov\r
+p=Nestor J. Zaluzec 630-252-7901\r
+e=Nestor J. Zaluzec <Zaluzec@aaem.amc.anl.gov>\r
+t=3077445600 3079900800\r
+r=86400 36000 0\r
+a=tool:sdr v2.3a1\r
+a=type:meeting\r
+m=audio 27028 RTP/AVP 0\r
+c=IN IP4 224.2.222.131/127\r
+a=ptime:40\r
+m=video 58800 RTP/AVP 31\r
+c=IN IP4 224.2.141.204/127\r
+\r
+From 146.139.72.5.32924\r
+v=0\r
+o=root 3077452673 3077455201 IN IP4 146.139.72.5\r
+s=ANL TelePresence Microscopy Site/Materials MicroCharacterization Collaboratory\r
+i=This is  ANL TelePresence Microscopy Site which is  part of the DoE 2000 Materials Microcharacterization Collaboratory. It facilitates  on-line access to unique resourses at the ANL AAEM and through the MMC, other resources in the Collaboratory at member sites (ORNL, LBNL, Univ. of Illinois and NIST).  More information about the TPM and the MMC can be found at http://tpm.amc.anl.gov/mmc\r
+u=http://tpm.amc.anl.gov\r
+p=Nestor J. Zaluzec 630-252-7901\r
+e=Nestor J. Zaluzec <Zaluzec@aaem.amc.anl.gov>\r
+t=3077445600 3079900800\r
+r=86400 36000 0\r
+a=tool:sdr v2.3a1\r
+a=type:meeting\r
+m=audio 27028 RTP/AVP 0\r
+c=IN IP4 224.2.222.131/127\r
+a=ptime:40\r
+m=video 58800 RTP/AVP 31\r
+c=IN IP4 224.2.141.204/127\r
+\r
+From 130.240.64.67.32877\r
+v=0\r
+o=demo 3066564173 3066564269 IN IP4 130.240.64.67\r
+s=Places all over the world\r
+i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams).  Audio is primarily for feedback for the senders of video.\r
+e=Hakan Lennestal <hakanl@cdt.luth.se>\r
+c=IN IP4 224.2.172.238/127\r
+t=0 0\r
+a=tool:CDT mAnnouncer 1.1.1\r
+a=type:broadcast\r
+m=video 51482 RTP/AVP 31\r
+c=IN IP4 224.2.172.238/127\r
+m=audio 20154 RTP/AVP 121\r
+c=IN IP4 224.2.213.113/127\r
+a=rtpred1:5\r
+a=ptime:40\r
+a=rtpred2:5\r
+a=rtpmap:121 red/8000\r
+\r
+From 130.240.64.67.32877\r
+v=0\r
+o=demo 3066564173 3066564269 IN IP4 130.240.64.67\r
+s=Places all over the world\r
+i=Low bandwidth video (10 kb/s) with views from all over the world. It is probably wise to limit the overall bandwidth to 100 kb/s (that is, a maximum of ten 10 kb/s streams).  Audio is primarily for feedback for the senders of video.\r
+e=Hakan Lennestal <hakanl@cdt.luth.se>\r
+c=IN IP4 224.2.172.238/127\r
+t=0 0\r
+a=tool:CDT mAnnouncer 1.1.1\r
+a=type:broadcast\r
+m=video 51482 RTP/AVP 31\r
+c=IN IP4 224.2.172.238/127\r
+m=audio 20154 RTP/AVP 121\r
+c=IN IP4 224.2.213.113/127\r
+a=rtpred1:5\r
+a=ptime:40\r
+a=rtpred2:5\r
+a=rtpmap:121 red/8000\r
+\r
+From 128.102.84.134.1085\r
+v=0\r
+o=shuttle 3075630923 3075633526 IN IP4 128.102.84.134\r
+s=NASA Space Shuttle STS-94\r
+i=Video/Audio broadcast of NASA space shuttle mission STS-94, Microgravity Science Laboratory-1.  This session is being broadcast as a service to the MBONE community by NASA-Ames Reseach Center.\r
+u=http://www-pao.ksc.nasa.gov/kscpao/kscpao.htm\r
+e=NASA - ARC Digital Video Lab <mallard@mail.arc.nasa.gov\r
+e=Brian Tonner (UWM) <tonner@csd.uwm.edu>\r
+e=Referenzzentrum __ <mmt-ref@tu-dresden.de>       \r
+e=IN IP4 224.2.212.30/75\r
+p=NASA - ARC Digital Video Lab (415) 604-6145\r
+p=Brian Tonner (at LBL) 510-486-5590\r
+p=Brian Tonner (at UWM) 414-229-4626\r
+c=IN IP4 224.2.210.20/127\r
+t=3076354800 3078774000\r
+m=audio 24680 RTP/AVP 0\r
+c=IN IP4 224.2.210.20/127\r
+m=video 56062 RTP/AVP 31\r
+c=IN IP4 224.2.210.20/127\r
+\r
+^?kohala % exit\r
+
+script done on Sat Jul 12 16:08:04 1997
diff --git a/names/Makefile b/names/Makefile
new file mode 100644 (file)
index 0000000..f2463a2
--- /dev/null
@@ -0,0 +1,74 @@
+include ../Make.defines
+
+PROGS =        daytimetcpcli daytimetcpcli1 daytimetcpsrv1 daytimetcpsrv2 \
+               daytimetcpsrv3 daytimetcpsrv4 \
+               daytimeudpcli1 daytimetcpcli2 daytimetcpcli3 \
+               daytimeudpcli2 daytimeudpsrv2 daytimeudpsrv3 \
+               hostent hostent2 hostent3 \
+               netent prmyaddrs prmyaddrs1 test1
+
+all:   ${PROGS}
+
+daytimetcpcli: daytimetcpcli.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpcli.o ${LIBS}
+
+daytimetcpcli1:        daytimetcpcli1.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpcli1.o ${LIBS}
+
+daytimetcpcli2:        daytimetcpcli2.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpcli2.o ${LIBS}
+
+daytimetcpcli3:        daytimetcpcli3.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpcli3.o ${LIBS}
+
+daytimetcpsrv1:        daytimetcpsrv1.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpsrv1.o ${LIBS}
+
+daytimetcpsrv2:        daytimetcpsrv2.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpsrv2.o ${LIBS}
+
+daytimetcpsrv3:        daytimetcpsrv3.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpsrv3.o ${LIBS}
+
+daytimetcpsrv4:        daytimetcpsrv4.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpsrv4.o ${LIBS}
+
+daytimeudpcli1:        daytimeudpcli1.o
+               ${CC} ${CFLAGS} -o $@ daytimeudpcli1.o ${LIBS}
+
+daytimeudpcli2:        daytimeudpcli2.o
+               ${CC} ${CFLAGS} -o $@ daytimeudpcli2.o ${LIBS}
+
+daytimeudpsrv2:        daytimeudpsrv2.o
+               ${CC} ${CFLAGS} -o $@ daytimeudpsrv2.o ${LIBS}
+
+daytimeudpsrv3:        daytimeudpsrv3.o udp_server_reuseaddr.o
+               ${CC} ${CFLAGS} -o $@ daytimeudpsrv3.o udp_server_reuseaddr.o \
+                       ${LIBS}
+
+hostent:       hostent.o
+               ${CC} ${CFLAGS} -o $@ hostent.o ${LIBS}
+
+hostent2:      hostent2.o
+               ${CC} ${CFLAGS} -o $@ hostent2.o ${LIBS}
+
+hostent3:      hostent3.o
+               ${CC} ${CFLAGS} -o $@ hostent3.o ${LIBS}
+
+netent:        netent.o
+               ${CC} ${CFLAGS} -o $@ netent.o ${LIBS}
+
+prmyaddrs:     prmyaddrs.o
+               ${CC} ${CFLAGS} -o $@ prmyaddrs.o ${LIBS}
+
+prmyaddrs1:    prmyaddrs1.o myaddrs1.o
+               ${CC} ${CFLAGS} -o $@ prmyaddrs1.o myaddrs1.o ${LIBS}
+
+test1: test1.o
+               ${CC} ${CFLAGS} -o $@ test1.o ${LIBS}
+
+test2: test2.o
+               ${CC} ${CFLAGS} -o $@ test2.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/names/daytimetcpcli.c b/names/daytimetcpcli.c
new file mode 100644 (file)
index 0000000..5c14621
--- /dev/null
@@ -0,0 +1,25 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                             sockfd, n;
+       char                    recvline[MAXLINE + 1];
+       socklen_t               len;
+       struct sockaddr_storage ss;
+
+       if (argc != 3)
+               err_quit("usage: daytimetcpcli <hostname/IPaddress> <service/port#>");
+
+       sockfd = Tcp_connect(argv[1], argv[2]);
+
+       len = sizeof(ss);
+       Getpeername(sockfd, (SA *)&ss, &len);
+       printf("connected to %s\n", Sock_ntop_host((SA *)&ss, len));
+
+       while ( (n = Read(sockfd, recvline, MAXLINE)) > 0) {
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+       exit(0);
+}
diff --git a/names/daytimetcpcli1.c b/names/daytimetcpcli1.c
new file mode 100644 (file)
index 0000000..bc37101
--- /dev/null
@@ -0,0 +1,56 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, n;
+       char                            recvline[MAXLINE + 1];
+       struct sockaddr_in      servaddr;
+       struct in_addr          **pptr;
+       struct in_addr          *inetaddrp[2];
+       struct in_addr          inetaddr;
+       struct hostent          *hp;
+       struct servent          *sp;
+
+       if (argc != 3)
+               err_quit("usage: daytimetcpcli1 <hostname> <service>");
+
+       if ( (hp = gethostbyname(argv[1])) == NULL) {
+               if (inet_aton(argv[1], &inetaddr) == 0) {
+                       err_quit("hostname error for %s: %s", argv[1], hstrerror(h_errno));
+               } else {
+                       inetaddrp[0] = &inetaddr;
+                       inetaddrp[1] = NULL;
+                       pptr = inetaddrp;
+               }
+       } else {
+               pptr = (struct in_addr **) hp->h_addr_list;
+       }
+
+       if ( (sp = getservbyname(argv[2], "tcp")) == NULL)
+               err_quit("getservbyname error for %s", argv[2]);
+
+       for ( ; *pptr != NULL; pptr++) {
+               sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+               bzero(&servaddr, sizeof(servaddr));
+               servaddr.sin_family = AF_INET;
+               servaddr.sin_port = sp->s_port;
+               memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));
+               printf("trying %s\n",
+                          Sock_ntop((SA *) &servaddr, sizeof(servaddr)));
+
+               if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) == 0)
+                       break;          /* success */
+               err_ret("connect error");
+               close(sockfd);
+       }
+       if (*pptr == NULL)
+               err_quit("unable to connect");
+
+       while ( (n = Read(sockfd, recvline, MAXLINE)) > 0) {
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+       exit(0);
+}
diff --git a/names/daytimetcpcli1.lc b/names/daytimetcpcli1.lc
new file mode 100644 (file)
index 0000000..99581c0
--- /dev/null
@@ -0,0 +1,56 @@
+#include    "unp.h"##  1 ##src/names/daytimetcpcli1.c##
+
+int##  2 ##src/names/daytimetcpcli1.c##
+main(int argc, char **argv)##  3 ##src/names/daytimetcpcli1.c##
+{##  4 ##src/names/daytimetcpcli1.c##
+    int     sockfd, n;##  5 ##src/names/daytimetcpcli1.c##
+    char    recvline[MAXLINE + 1];##  6 ##src/names/daytimetcpcli1.c##
+    struct sockaddr_in servaddr;##  7 ##src/names/daytimetcpcli1.c##
+    struct in_addr **pptr;##  8 ##src/names/daytimetcpcli1.c##
+    struct in_addr *inetaddrp[2];##  9 ##src/names/daytimetcpcli1.c##
+    struct in_addr inetaddr;## 10 ##src/names/daytimetcpcli1.c##
+    struct hostent *hp;## 11 ##src/names/daytimetcpcli1.c##
+    struct servent *sp;## 12 ##src/names/daytimetcpcli1.c##
+
+    if (argc != 3)## 13 ##src/names/daytimetcpcli1.c##
+        err_quit("usage: daytimetcpcli1 <hostname> <service>");## 14 ##src/names/daytimetcpcli1.c##
+
+    if ((hp = gethostbyname(argv[1])) == NULL) {## 15 ##src/names/daytimetcpcli1.c##
+        if (inet_aton(argv[1], &inetaddr) == 0) {## 16 ##src/names/daytimetcpcli1.c##
+            err_quit("hostname error for %s: %s", argv[1],## 17 ##src/names/daytimetcpcli1.c##
+                     hstrerror(h_errno));## 18 ##src/names/daytimetcpcli1.c##
+        } else {## 19 ##src/names/daytimetcpcli1.c##
+            inetaddrp[0] = &inetaddr;## 20 ##src/names/daytimetcpcli1.c##
+            inetaddrp[1] = NULL;## 21 ##src/names/daytimetcpcli1.c##
+            pptr = inetaddrp;## 22 ##src/names/daytimetcpcli1.c##
+        }## 23 ##src/names/daytimetcpcli1.c##
+    } else {## 24 ##src/names/daytimetcpcli1.c##
+        pptr = (struct in_addr **) hp->h_addr_list;## 25 ##src/names/daytimetcpcli1.c##
+    }## 26 ##src/names/daytimetcpcli1.c##
+
+    if ((sp = getservbyname(argv[2], "tcp")) == NULL)## 27 ##src/names/daytimetcpcli1.c##
+        err_quit("getservbyname error for %s", argv[2]);## 28 ##src/names/daytimetcpcli1.c##
+
+    for (; *pptr != NULL; pptr++) {## 29 ##src/names/daytimetcpcli1.c##
+        sockfd = Socket(AF_INET, SOCK_STREAM, 0);## 30 ##src/names/daytimetcpcli1.c##
+
+        bzero(&servaddr, sizeof(servaddr));## 31 ##src/names/daytimetcpcli1.c##
+        servaddr.sin_family = AF_INET;## 32 ##src/names/daytimetcpcli1.c##
+        servaddr.sin_port = sp->s_port;## 33 ##src/names/daytimetcpcli1.c##
+        memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));## 34 ##src/names/daytimetcpcli1.c##
+        printf("trying %s\n", Sock_ntop((SA *) &servaddr, sizeof(servaddr)));## 35 ##src/names/daytimetcpcli1.c##
+
+        if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) == 0)## 36 ##src/names/daytimetcpcli1.c##
+            break;              /* success */## 37 ##src/names/daytimetcpcli1.c##
+        err_ret("connect error");## 38 ##src/names/daytimetcpcli1.c##
+        close(sockfd);## 39 ##src/names/daytimetcpcli1.c##
+    }## 40 ##src/names/daytimetcpcli1.c##
+    if (*pptr == NULL)## 41 ##src/names/daytimetcpcli1.c##
+        err_quit("unable to connect");## 42 ##src/names/daytimetcpcli1.c##
+
+    while ((n = Read(sockfd, recvline, MAXLINE)) > 0) {## 43 ##src/names/daytimetcpcli1.c##
+        recvline[n] = 0;        /* null terminate */## 44 ##src/names/daytimetcpcli1.c##
+        Fputs(recvline, stdout);## 45 ##src/names/daytimetcpcli1.c##
+    }## 46 ##src/names/daytimetcpcli1.c##
+    exit(0);## 47 ##src/names/daytimetcpcli1.c##
+}## 48 ##src/names/daytimetcpcli1.c##
diff --git a/names/daytimetcpcli2.c b/names/daytimetcpcli2.c
new file mode 100644 (file)
index 0000000..04e5d76
--- /dev/null
@@ -0,0 +1,55 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, n;
+       char                            recvline[MAXLINE + 1];
+       struct sockaddr_in      servaddr;
+       struct in_addr          **pptr, *addrs[2];
+       struct hostent          *hp;
+       struct servent          *sp;
+
+       if (argc != 3)
+               err_quit("usage: daytimetcpcli2 <hostname> <service>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+
+       if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) == 1) {
+               addrs[0] = &servaddr.sin_addr;
+               addrs[1] = NULL;
+               pptr = &addrs[0];
+       } else if ( (hp = gethostbyname(argv[1])) != NULL) {
+               pptr = (struct in_addr **) hp->h_addr_list;
+       } else
+               err_quit("hostname error for %s: %s", argv[1], hstrerror(h_errno));
+
+       if ( (n = atoi(argv[2])) > 0)
+               servaddr.sin_port = htons(n);
+       else if ( (sp = getservbyname(argv[2], "tcp")) != NULL)
+               servaddr.sin_port = sp->s_port;
+       else
+               err_quit("getservbyname error for %s", argv[2]);
+
+       for ( ; *pptr != NULL; pptr++) {
+               sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+               memmove(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));
+               printf("trying %s\n",
+                          Sock_ntop((SA *) &servaddr, sizeof(servaddr)));
+
+               if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) == 0)
+                       break;          /* success */
+               err_ret("connect error");
+               close(sockfd);
+       }
+       if (*pptr == NULL)
+               err_quit("unable to connect");
+
+       while ( (n = Read(sockfd, recvline, MAXLINE)) > 0) {
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+       exit(0);
+}
diff --git a/names/daytimetcpcli2.lc b/names/daytimetcpcli2.lc
new file mode 100644 (file)
index 0000000..f306b08
--- /dev/null
@@ -0,0 +1,54 @@
+#include    "unp.h"##  1 ##src/names/daytimetcpcli2.c##
+
+int##  2 ##src/names/daytimetcpcli2.c##
+main(int argc, char **argv)##  3 ##src/names/daytimetcpcli2.c##
+{##  4 ##src/names/daytimetcpcli2.c##
+    int     sockfd, n;##  5 ##src/names/daytimetcpcli2.c##
+    char    recvline[MAXLINE + 1];##  6 ##src/names/daytimetcpcli2.c##
+    struct sockaddr_in servaddr;##  7 ##src/names/daytimetcpcli2.c##
+    struct in_addr **pptr, *addrs[2];##  8 ##src/names/daytimetcpcli2.c##
+    struct hostent *hp;##  9 ##src/names/daytimetcpcli2.c##
+    struct servent *sp;## 10 ##src/names/daytimetcpcli2.c##
+
+    if (argc != 3)## 11 ##src/names/daytimetcpcli2.c##
+        err_quit("usage: daytimetcpcli2 <hostname> <service>");## 12 ##src/names/daytimetcpcli2.c##
+
+    bzero(&servaddr, sizeof(servaddr));## 13 ##src/names/daytimetcpcli2.c##
+    servaddr.sin_family = AF_INET;## 14 ##src/names/daytimetcpcli2.c##
+
+    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) == 1) {## 15 ##src/names/daytimetcpcli2.c##
+        addrs[0] = &servaddr.sin_addr;## 16 ##src/names/daytimetcpcli2.c##
+        addrs[1] = NULL;## 17 ##src/names/daytimetcpcli2.c##
+        pptr = &addrs[0];## 18 ##src/names/daytimetcpcli2.c##
+    } else if ((hp = gethostbyname(argv[1])) != NULL) {## 19 ##src/names/daytimetcpcli2.c##
+        pptr = (struct in_addr **) hp->h_addr_list;## 20 ##src/names/daytimetcpcli2.c##
+    } else## 21 ##src/names/daytimetcpcli2.c##
+        err_quit("hostname error for %s: %s", argv[1], hstrerror(h_errno));## 22 ##src/names/daytimetcpcli2.c##
+
+    if ((n = atoi(argv[2])) > 0)## 23 ##src/names/daytimetcpcli2.c##
+        servaddr.sin_port = htons(n);## 24 ##src/names/daytimetcpcli2.c##
+    else if ((sp = getservbyname(argv[2], "tcp")) != NULL)## 25 ##src/names/daytimetcpcli2.c##
+        servaddr.sin_port = sp->s_port;## 26 ##src/names/daytimetcpcli2.c##
+    else## 27 ##src/names/daytimetcpcli2.c##
+        err_quit("getservbyname error for %s", argv[2]);## 28 ##src/names/daytimetcpcli2.c##
+
+    for (; *pptr != NULL; pptr++) {## 29 ##src/names/daytimetcpcli2.c##
+        sockfd = Socket(AF_INET, SOCK_STREAM, 0);## 30 ##src/names/daytimetcpcli2.c##
+
+        memmove(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));## 31 ##src/names/daytimetcpcli2.c##
+        printf("trying %s\n", Sock_ntop((SA *) &servaddr, sizeof(servaddr)));## 32 ##src/names/daytimetcpcli2.c##
+
+        if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) == 0)## 33 ##src/names/daytimetcpcli2.c##
+            break;              /* success */## 34 ##src/names/daytimetcpcli2.c##
+        err_ret("connect error");## 35 ##src/names/daytimetcpcli2.c##
+        close(sockfd);## 36 ##src/names/daytimetcpcli2.c##
+    }## 37 ##src/names/daytimetcpcli2.c##
+    if (*pptr == NULL)## 38 ##src/names/daytimetcpcli2.c##
+        err_quit("unable to connect");## 39 ##src/names/daytimetcpcli2.c##
+
+    while ((n = Read(sockfd, recvline, MAXLINE)) > 0) {## 40 ##src/names/daytimetcpcli2.c##
+        recvline[n] = 0;        /* null terminate */## 41 ##src/names/daytimetcpcli2.c##
+        Fputs(recvline, stdout);## 42 ##src/names/daytimetcpcli2.c##
+    }## 43 ##src/names/daytimetcpcli2.c##
+    exit(0);## 44 ##src/names/daytimetcpcli2.c##
+}## 45 ##src/names/daytimetcpcli2.c##
diff --git a/names/daytimetcpcli3.c b/names/daytimetcpcli3.c
new file mode 100644 (file)
index 0000000..946ef59
--- /dev/null
@@ -0,0 +1,58 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, n;
+       char                            recvline[MAXLINE + 1];
+       struct sockaddr_in      servaddr;
+       struct sockaddr_in6     servaddr6;
+       struct sockaddr         *sa;
+       socklen_t                       salen;
+       struct in_addr          **pptr;
+       struct hostent          *hp;
+       struct servent          *sp;
+
+       if (argc != 3)
+               err_quit("usage: daytimetcpcli3 <hostname> <service>");
+
+       if ( (hp = gethostbyname(argv[1])) == NULL)
+               err_quit("hostname error for %s: %s", argv[1], hstrerror(h_errno));
+
+       if ( (sp = getservbyname(argv[2], "tcp")) == NULL)
+               err_quit("getservbyname error for %s", argv[2]);
+
+       pptr = (struct in_addr **) hp->h_addr_list;
+       for ( ; *pptr != NULL; pptr++) {
+               sockfd = Socket(hp->h_addrtype, SOCK_STREAM, 0);
+
+               if (hp->h_addrtype == AF_INET) {
+                       sa = (SA *) &servaddr;
+                       salen = sizeof(servaddr);
+               } else if (hp->h_addrtype == AF_INET6) {
+                       sa = (SA *) &servaddr6;
+                       salen = sizeof(servaddr6);
+               } else
+                       err_quit("unknown addrtype %d", hp->h_addrtype);
+
+               bzero(sa, salen);
+               sa->sa_family = hp->h_addrtype;
+               sock_set_port(sa, salen, sp->s_port);
+               sock_set_addr(sa, salen, *pptr);
+
+               printf("trying %s\n", Sock_ntop(sa, salen));
+
+               if (connect(sockfd, sa, salen) == 0)
+                       break;          /* success */
+               err_ret("connect error");
+               close(sockfd);
+       }
+       if (*pptr == NULL)
+               err_quit("unable to connect");
+
+       while ( (n = Read(sockfd, recvline, MAXLINE)) > 0) {
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+       exit(0);
+}
diff --git a/names/daytimetcpcli3.lc b/names/daytimetcpcli3.lc
new file mode 100644 (file)
index 0000000..4c4a5d8
--- /dev/null
@@ -0,0 +1,58 @@
+#include    "unp.h"##  1 ##src/names/daytimetcpcli3.c##
+
+int##  2 ##src/names/daytimetcpcli3.c##
+main(int argc, char **argv)##  3 ##src/names/daytimetcpcli3.c##
+{##  4 ##src/names/daytimetcpcli3.c##
+    int     sockfd, n;##  5 ##src/names/daytimetcpcli3.c##
+    char    recvline[MAXLINE + 1];##  6 ##src/names/daytimetcpcli3.c##
+    struct sockaddr_in servaddr;##  7 ##src/names/daytimetcpcli3.c##
+    struct sockaddr_in6 servaddr6;##  8 ##src/names/daytimetcpcli3.c##
+    struct sockaddr *sa;##  9 ##src/names/daytimetcpcli3.c##
+    socklen_t salen;## 10 ##src/names/daytimetcpcli3.c##
+    struct in_addr **pptr;## 11 ##src/names/daytimetcpcli3.c##
+    struct hostent *hp;## 12 ##src/names/daytimetcpcli3.c##
+    struct servent *sp;## 13 ##src/names/daytimetcpcli3.c##
+
+    if (argc != 3)## 14 ##src/names/daytimetcpcli3.c##
+        err_quit("usage: daytimetcpcli3 <hostname> <service>");## 15 ##src/names/daytimetcpcli3.c##
+
+    if ((hp = gethostbyname(argv[1])) == NULL)## 16 ##src/names/daytimetcpcli3.c##
+        err_quit("hostname error for %s: %s", argv[1], hstrerror(h_errno));## 17 ##src/names/daytimetcpcli3.c##
+
+    if ((sp = getservbyname(argv[2], "tcp")) == NULL)## 18 ##src/names/daytimetcpcli3.c##
+        err_quit("getservbyname error for %s", argv[2]);## 19 ##src/names/daytimetcpcli3.c##
+
+    pptr = (struct in_addr **) hp->h_addr_list;## 20 ##src/names/daytimetcpcli3.c##
+    for (; *pptr != NULL; pptr++) {## 21 ##src/names/daytimetcpcli3.c##
+        sockfd = Socket(hp->h_addrtype, SOCK_STREAM, 0);## 22 ##src/names/daytimetcpcli3.c##
+
+        if (hp->h_addrtype == AF_INET) {## 23 ##src/names/daytimetcpcli3.c##
+            sa = (SA *) &servaddr;## 24 ##src/names/daytimetcpcli3.c##
+            salen = sizeof(servaddr);## 25 ##src/names/daytimetcpcli3.c##
+        } else if (hp->h_addrtype == AF_INET6) {## 26 ##src/names/daytimetcpcli3.c##
+            sa = (SA *) &servaddr6;## 27 ##src/names/daytimetcpcli3.c##
+            salen = sizeof(servaddr6);## 28 ##src/names/daytimetcpcli3.c##
+        } else## 29 ##src/names/daytimetcpcli3.c##
+            err_quit("unknown addrtype %d", hp->h_addrtype);## 30 ##src/names/daytimetcpcli3.c##
+
+        bzero(sa, salen);## 31 ##src/names/daytimetcpcli3.c##
+        sa->sa_family = hp->h_addrtype;## 32 ##src/names/daytimetcpcli3.c##
+        sock_set_port(sa, salen, sp->s_port);## 33 ##src/names/daytimetcpcli3.c##
+        sock_set_addr(sa, salen, *pptr);## 34 ##src/names/daytimetcpcli3.c##
+
+        printf("trying %s\n", Sock_ntop(sa, salen));## 35 ##src/names/daytimetcpcli3.c##
+
+        if (connect(sockfd, sa, salen) == 0)## 36 ##src/names/daytimetcpcli3.c##
+            break;              /* success */## 37 ##src/names/daytimetcpcli3.c##
+        err_ret("connect error");## 38 ##src/names/daytimetcpcli3.c##
+        close(sockfd);## 39 ##src/names/daytimetcpcli3.c##
+    }## 40 ##src/names/daytimetcpcli3.c##
+    if (*pptr == NULL)## 41 ##src/names/daytimetcpcli3.c##
+        err_quit("unable to connect");## 42 ##src/names/daytimetcpcli3.c##
+
+    while ((n = Read(sockfd, recvline, MAXLINE)) > 0) {## 43 ##src/names/daytimetcpcli3.c##
+        recvline[n] = 0;        /* null terminate */## 44 ##src/names/daytimetcpcli3.c##
+        Fputs(recvline, stdout);## 45 ##src/names/daytimetcpcli3.c##
+    }## 46 ##src/names/daytimetcpcli3.c##
+    exit(0);## 47 ##src/names/daytimetcpcli3.c##
+}## 48 ##src/names/daytimetcpcli3.c##
diff --git a/names/daytimetcpsrv1.c b/names/daytimetcpsrv1.c
new file mode 100644 (file)
index 0000000..f643413
--- /dev/null
@@ -0,0 +1,29 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       int                             listenfd, connfd;
+       socklen_t               len;
+       char                    buff[MAXLINE];
+       time_t                  ticks;
+       struct sockaddr_storage cliaddr;
+
+       if (argc != 2)
+               err_quit("usage: daytimetcpsrv1 <service or port#>");
+
+       listenfd = Tcp_listen(NULL, argv[1], NULL);
+
+       for ( ; ; ) {
+               len = sizeof(cliaddr);
+               connfd = Accept(listenfd, (SA *)&cliaddr, &len);
+               printf("connection from %s\n", Sock_ntop((SA *)&cliaddr, len));
+
+               ticks = time(NULL);
+               snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+               Write(connfd, buff, strlen(buff));
+
+               Close(connfd);
+       }
+}
diff --git a/names/daytimetcpsrv2.c b/names/daytimetcpsrv2.c
new file mode 100644 (file)
index 0000000..e897643
--- /dev/null
@@ -0,0 +1,31 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       int                             listenfd, connfd;
+       socklen_t               len, addrlen;
+       char                    buff[MAXLINE];
+       time_t                  ticks;
+       struct sockaddr_storage cliaddr;
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: daytimetcpsrv2 [ <host> ] <service or port>");
+
+       for ( ; ; ) {
+               len = sizeof(cliaddr);
+               connfd = Accept(listenfd, (SA *)&cliaddr, &len);
+               printf("connection from %s\n", Sock_ntop((SA *)&cliaddr, len));
+
+               ticks = time(NULL);
+               snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+               Write(connfd, buff, strlen(buff));
+
+               Close(connfd);
+       }
+}
diff --git a/names/daytimetcpsrv3.c b/names/daytimetcpsrv3.c
new file mode 100644 (file)
index 0000000..20c6cc0
--- /dev/null
@@ -0,0 +1,40 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       int                             listenfd, connfd;
+       socklen_t               addrlen, len;
+       struct sockaddr *cliaddr;
+       struct linger   ling;
+       char                    buff[MAXLINE];
+       time_t                  ticks;
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: daytimetcpsrv3 [ <host> ] <service or port>");
+
+       cliaddr = Malloc(addrlen);
+
+       for ( ; ; ) {
+               len = addrlen;
+               connfd = Accept(listenfd, cliaddr, &len);
+               printf("connection from %s\n", Sock_ntop(cliaddr, len));
+
+                       /* force RST instead of FIN after data */
+               ling.l_onoff = 1;
+               ling.l_linger = 0;
+               Setsockopt(connfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
+
+        ticks = time(NULL);
+        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+        Write(connfd, buff, strlen(buff));
+
+               sleep(2);       /* let data get across before RST */
+               Close(connfd);
+       }
+}
diff --git a/names/daytimetcpsrv4.c b/names/daytimetcpsrv4.c
new file mode 100644 (file)
index 0000000..277b17e
--- /dev/null
@@ -0,0 +1,35 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       int                             listenfd, connfd;
+       socklen_t               addrlen, len;
+       struct sockaddr *cliaddr;
+       char                    buff[MAXLINE], host[NI_MAXHOST], serv[NI_MAXSERV];
+       time_t                  ticks;
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: daytimetcpsrv4 [ <host> ] <service or port>");
+
+       cliaddr = Malloc(addrlen);
+
+       for ( ; ; ) {
+               len = addrlen;
+               connfd = Accept(listenfd, cliaddr, &len);
+               if (getnameinfo(cliaddr, len, host, NI_MAXHOST, serv, NI_MAXSERV,
+                                               NI_NUMERICHOST | NI_NUMERICSERV) == 0)
+                       printf("connection from %s.%s\n", host, serv);
+
+        ticks = time(NULL);
+        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+        Write(connfd, buff, strlen(buff));
+
+               Close(connfd);
+       }
+}
diff --git a/names/daytimeudpcli1.c b/names/daytimeudpcli1.c
new file mode 100644 (file)
index 0000000..efca6ec
--- /dev/null
@@ -0,0 +1,25 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                             sockfd, n;
+       char                    recvline[MAXLINE + 1];
+       socklen_t               salen;
+       struct sockaddr *sa;
+
+       if (argc != 3)
+               err_quit("usage: daytimeudpcli1 <hostname/IPaddress> <service/port#>");
+
+       sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);
+
+       printf("sending to %s\n", Sock_ntop_host(sa, salen));
+
+       Sendto(sockfd, "", 1, 0, sa, salen);    /* send 1-byte datagram */
+
+       n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
+       recvline[n] = '\0';     /* null terminate */
+       Fputs(recvline, stdout);
+
+       exit(0);
+}
diff --git a/names/daytimeudpcli1.lc b/names/daytimeudpcli1.lc
new file mode 100644 (file)
index 0000000..4d03bee
--- /dev/null
@@ -0,0 +1,26 @@
+#include    "unp.h"##  1 ##src/names/daytimeudpcli1.c##
+
+int##  2 ##src/names/daytimeudpcli1.c##
+main(int argc, char **argv)##  3 ##src/names/daytimeudpcli1.c##
+{##  4 ##src/names/daytimeudpcli1.c##
+    int     sockfd, n;##  5 ##src/names/daytimeudpcli1.c##
+    char    recvline[MAXLINE + 1];##  6 ##src/names/daytimeudpcli1.c##
+    socklen_t salen;##  7 ##src/names/daytimeudpcli1.c##
+    struct sockaddr *sa;##  8 ##src/names/daytimeudpcli1.c##
+
+    if (argc != 3)##  9 ##src/names/daytimeudpcli1.c##
+        err_quit## 10 ##src/names/daytimeudpcli1.c##
+            ("usage: daytimeudpcli1 <hostname/IPaddress> <service/port#>");## 11 ##src/names/daytimeudpcli1.c##
+
+    sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);## 12 ##src/names/daytimeudpcli1.c##
+
+    printf("sending to %s\n", Sock_ntop_host(sa, salen));## 13 ##src/names/daytimeudpcli1.c##
+
+    Sendto(sockfd, "", 1, 0, sa, salen);    /* send 1-byte datagram */## 14 ##src/names/daytimeudpcli1.c##
+
+    n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);## 15 ##src/names/daytimeudpcli1.c##
+    recvline[n] = '\0';         /* null terminate */## 16 ##src/names/daytimeudpcli1.c##
+    Fputs(recvline, stdout);## 17 ##src/names/daytimeudpcli1.c##
+
+    exit(0);## 18 ##src/names/daytimeudpcli1.c##
+}## 19 ##src/names/daytimeudpcli1.c##
diff --git a/names/daytimeudpcli2.c b/names/daytimeudpcli2.c
new file mode 100644 (file)
index 0000000..a61bf49
--- /dev/null
@@ -0,0 +1,21 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             sockfd, n;
+       char    recvline[MAXLINE + 1];
+
+       if (argc != 3)
+               err_quit("usage: daytimeudpcli2 <hostname/IPaddress> <service/port#>");
+
+       sockfd = Udp_connect(argv[1], argv[2]);
+
+       Write(sockfd, "", 1);   /* send 1-byte datagram */
+
+       n = Read(sockfd, recvline, MAXLINE);
+       recvline[n] = '\0';     /* null terminate */
+       Fputs(recvline, stdout);
+
+       exit(0);
+}
diff --git a/names/daytimeudpsrv2.c b/names/daytimeudpsrv2.c
new file mode 100644 (file)
index 0000000..9d7e8bc
--- /dev/null
@@ -0,0 +1,30 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       int                             sockfd;
+       ssize_t                 n;
+       char                    buff[MAXLINE];
+       time_t                  ticks;
+       socklen_t               len;
+       struct sockaddr_storage cliaddr;
+
+       if (argc == 2)
+               sockfd = Udp_server(NULL, argv[1], NULL);
+       else if (argc == 3)
+               sockfd = Udp_server(argv[1], argv[2], NULL);
+       else
+               err_quit("usage: daytimeudpsrv [ <host> ] <service or port>");
+
+       for ( ; ; ) {
+               len = sizeof(cliaddr);
+               n = Recvfrom(sockfd, buff, MAXLINE, 0, (SA *)&cliaddr, &len);
+               printf("datagram from %s\n", Sock_ntop((SA *)&cliaddr, len));
+
+               ticks = time(NULL);
+               snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+               Sendto(sockfd, buff, strlen(buff), 0, (SA *)&cliaddr, len);
+       }
+}
diff --git a/names/daytimeudpsrv3.c b/names/daytimeudpsrv3.c
new file mode 100644 (file)
index 0000000..41732aa
--- /dev/null
@@ -0,0 +1,30 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       int                             sockfd;
+       ssize_t                 n;
+       char                    buff[MAXLINE];
+       time_t                  ticks;
+       socklen_t               len;
+       struct sockaddr_storage cliaddr;
+
+       if (argc == 2)
+               sockfd = Udp_server_reuseaddr(NULL, argv[1], NULL);
+       else if (argc == 3)
+               sockfd = Udp_server_reuseaddr(argv[1], argv[2], NULL);
+       else
+               err_quit("usage: daytimeudpsrv [ <host> ] <service or port>");
+
+       for ( ; ; ) {
+               len = sizeof(cliaddr);
+               n = Recvfrom(sockfd, buff, MAXLINE, 0, (SA *)&cliaddr, &len);
+               printf("datagram from %s\n", Sock_ntop((SA *)&cliaddr, len));
+
+               ticks = time(NULL);
+               snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+               Sendto(sockfd, buff, strlen(buff), 0, (SA *)&cliaddr, len);
+       }
+}
diff --git a/names/hostent.c b/names/hostent.c
new file mode 100644 (file)
index 0000000..2fdb382
--- /dev/null
@@ -0,0 +1,36 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       char                    *ptr, **pptr;
+       char                    str[INET_ADDRSTRLEN];
+       struct hostent  *hptr;
+
+       while (--argc > 0) {
+               ptr = *++argv;
+               if ( (hptr = gethostbyname(ptr)) == NULL) {
+                       err_msg("gethostbyname error for host: %s: %s",
+                                       ptr, hstrerror(h_errno));
+                       continue;
+               }
+               printf("official hostname: %s\n", hptr->h_name);
+
+               for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
+                       printf("\talias: %s\n", *pptr);
+
+               switch (hptr->h_addrtype) {
+               case AF_INET:
+                       pptr = hptr->h_addr_list;
+                       for ( ; *pptr != NULL; pptr++)
+                               printf("\taddress: %s\n",
+                                       Inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));
+                       break;
+
+               default:
+                       err_ret("unknown address type");
+                       break;
+               }
+       }
+       exit(0);
+}
diff --git a/names/hostent.lc b/names/hostent.lc
new file mode 100644 (file)
index 0000000..57c7759
--- /dev/null
@@ -0,0 +1,36 @@
+#include    "unp.h"##  1 ##src/names/hostent.c##
+
+int##  2 ##src/names/hostent.c##
+main(int argc, char **argv)##  3 ##src/names/hostent.c##
+{##  4 ##src/names/hostent.c##
+    char   *ptr, **pptr;##  5 ##src/names/hostent.c##
+    char    str[INET_ADDRSTRLEN];##  6 ##src/names/hostent.c##
+    struct hostent *hptr;##  7 ##src/names/hostent.c##
+
+    while (--argc > 0) {##  8 ##src/names/hostent.c##
+        ptr = *++argv;##  9 ##src/names/hostent.c##
+        if ((hptr = gethostbyname(ptr)) == NULL) {## 10 ##src/names/hostent.c##
+            err_msg("gethostbyname error for host: %s: %s",## 11 ##src/names/hostent.c##
+                    ptr, hstrerror(h_errno));## 12 ##src/names/hostent.c##
+            continue;## 13 ##src/names/hostent.c##
+        }## 14 ##src/names/hostent.c##
+        printf("official hostname: %s\n", hptr->h_name);## 15 ##src/names/hostent.c##
+
+        for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)## 16 ##src/names/hostent.c##
+            printf("\talias: %s\n", *pptr);## 17 ##src/names/hostent.c##
+
+        switch (hptr->h_addrtype) {## 18 ##src/names/hostent.c##
+        case AF_INET:## 19 ##src/names/hostent.c##
+            pptr = hptr->h_addr_list;## 20 ##src/names/hostent.c##
+            for (; *pptr != NULL; pptr++)## 21 ##src/names/hostent.c##
+                printf("\taddress: %s\n",## 22 ##src/names/hostent.c##
+                       Inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));## 23 ##src/names/hostent.c##
+            break;## 24 ##src/names/hostent.c##
+
+        default:## 25 ##src/names/hostent.c##
+            err_ret("unknown address type");## 26 ##src/names/hostent.c##
+            break;## 27 ##src/names/hostent.c##
+        }## 28 ##src/names/hostent.c##
+    }## 29 ##src/names/hostent.c##
+    exit(0);## 30 ##src/names/hostent.c##
+}## 31 ##src/names/hostent.c##
diff --git a/names/hostent2.c b/names/hostent2.c
new file mode 100644 (file)
index 0000000..df81cb2
--- /dev/null
@@ -0,0 +1,48 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       char                    *ptr, **pptr;
+       char                    str[INET6_ADDRSTRLEN];
+       struct hostent  *hptr;
+
+       while (--argc > 0) {
+               ptr = *++argv;
+               if ( (hptr = gethostbyname(ptr)) == NULL) {
+                       err_msg("gethostbyname error for host: %s: %s",
+                                       ptr, hstrerror(h_errno));
+                       continue;
+               }
+               printf("official hostname: %s\n", hptr->h_name);
+
+               for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
+                       printf("        alias: %s\n", *pptr);
+
+               switch (hptr->h_addrtype) {
+               case AF_INET:
+#ifdef AF_INET6
+               case AF_INET6:
+#endif
+                       pptr = hptr->h_addr_list;
+                       for ( ; *pptr != NULL; pptr++) {
+                               printf("\taddress: %s\n",
+                                       Inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));
+
+                               if ( (hptr = gethostbyaddr(*pptr, hptr->h_length,
+                                                                                  hptr->h_addrtype)) == NULL)
+                                       printf("\t(gethostbyaddr failed)\n");
+                               else if (hptr->h_name != NULL)
+                                       printf("\tname = %s\n", hptr->h_name);
+                               else
+                                       printf("\t(no hostname returned by gethostbyaddr)\n");
+                       }
+                       break;
+
+               default:
+                       err_ret("unknown address type");
+                       break;
+               }
+       }
+       exit(0);
+}
diff --git a/names/hostent2.lc b/names/hostent2.lc
new file mode 100644 (file)
index 0000000..40f9b7e
--- /dev/null
@@ -0,0 +1,48 @@
+#include    "unp.h"##  1 ##src/names/hostent2.c##
+
+int##  2 ##src/names/hostent2.c##
+main(int argc, char **argv)##  3 ##src/names/hostent2.c##
+{##  4 ##src/names/hostent2.c##
+    char   *ptr, **pptr;##  5 ##src/names/hostent2.c##
+    char    str[INET6_ADDRSTRLEN];##  6 ##src/names/hostent2.c##
+    struct hostent *hptr;##  7 ##src/names/hostent2.c##
+
+    while (--argc > 0) {##  8 ##src/names/hostent2.c##
+        ptr = *++argv;##  9 ##src/names/hostent2.c##
+        if ((hptr = gethostbyname(ptr)) == NULL) {## 10 ##src/names/hostent2.c##
+            err_msg("gethostbyname error for host: %s: %s",## 11 ##src/names/hostent2.c##
+                    ptr, hstrerror(h_errno));## 12 ##src/names/hostent2.c##
+            continue;## 13 ##src/names/hostent2.c##
+        }## 14 ##src/names/hostent2.c##
+        printf("official hostname: %s\n", hptr->h_name);## 15 ##src/names/hostent2.c##
+
+        for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)## 16 ##src/names/hostent2.c##
+            printf("    alias: %s\n", *pptr);## 17 ##src/names/hostent2.c##
+
+        switch (hptr->h_addrtype) {## 18 ##src/names/hostent2.c##
+        case AF_INET:## 19 ##src/names/hostent2.c##
+#ifdef  AF_INET6## 20 ##src/names/hostent2.c##
+        case AF_INET6:## 21 ##src/names/hostent2.c##
+#endif## 22 ##src/names/hostent2.c##
+            pptr = hptr->h_addr_list;## 23 ##src/names/hostent2.c##
+            for (; *pptr != NULL; pptr++) {## 24 ##src/names/hostent2.c##
+                printf("\taddress: %s\n",## 25 ##src/names/hostent2.c##
+                       Inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));## 26 ##src/names/hostent2.c##
+
+                if ((hptr = gethostbyaddr(*pptr, hptr->h_length,## 27 ##src/names/hostent2.c##
+                                          hptr->h_addrtype)) == NULL)## 28 ##src/names/hostent2.c##
+                    printf("\t(gethostbyaddr failed)\n");## 29 ##src/names/hostent2.c##
+                else if (hptr->h_name != NULL)## 30 ##src/names/hostent2.c##
+                    printf("\tname = %s\n", hptr->h_name);## 31 ##src/names/hostent2.c##
+                else## 32 ##src/names/hostent2.c##
+                    printf("\t(no hostname returned by gethostbyaddr)\n");## 33 ##src/names/hostent2.c##
+            }## 34 ##src/names/hostent2.c##
+            break;## 35 ##src/names/hostent2.c##
+
+        default:## 36 ##src/names/hostent2.c##
+            err_ret("unknown address type");## 37 ##src/names/hostent2.c##
+            break;## 38 ##src/names/hostent2.c##
+        }## 39 ##src/names/hostent2.c##
+    }## 40 ##src/names/hostent2.c##
+    exit(0);## 41 ##src/names/hostent2.c##
+}## 42 ##src/names/hostent2.c##
diff --git a/names/hostent3.c b/names/hostent3.c
new file mode 100644 (file)
index 0000000..b460dc0
--- /dev/null
@@ -0,0 +1,64 @@
+#include       "unp.h"
+
+void   pr_ipv4(char **);
+
+int
+main(int argc, char **argv)
+{
+       char                    *ptr, **pptr;
+       struct hostent  *hptr;
+
+       while (--argc > 0) {
+               ptr = *++argv;
+               if ( (hptr = gethostbyname(ptr)) == NULL) {
+                       err_msg("gethostbyname error for host: %s: %s",
+                                       ptr, hstrerror(h_errno));
+                       continue;
+               }
+               printf("official host name: %s\n", hptr->h_name);
+
+               for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
+                       printf("        alias: %s\n", *pptr);
+
+               switch (hptr->h_addrtype) {
+               case AF_INET:
+                       pr_ipv4(hptr->h_addr_list);
+                       break;
+
+               default:
+                       err_ret("unknown address type");
+                       break;
+               }
+       }
+       exit(0);
+}
+
+/*
+ * Print the array of IPv4 addresses that is returned.
+ * Also call gethostbyaddr_r() for each IP address and print the name.
+ */
+
+/* begin pr_ipv4 */
+void
+pr_ipv4(char **listptr)
+{
+       struct in_addr  inaddr;
+       struct hostent  *hptr, hent;
+       char                    buf[8192];
+       int                             h_errno;
+
+       for ( ; *listptr != NULL; listptr++) {
+               inaddr = *((struct in_addr *) (*listptr));
+               printf("        IPv4 address: %s", Inet_ntoa(inaddr));
+
+               if ( (hptr = gethostbyaddr_r((char *) &inaddr, sizeof(struct in_addr),
+                                                                        AF_INET, &hent,
+                                                                        buf, sizeof(buf), &h_errno)) == NULL)
+                       printf("    (gethostbyaddr failed: %s)\n", hstrerror(h_errno));
+               else if (hptr->h_name != NULL)
+                       printf("    name = %s\n", hptr->h_name);
+               else
+                       printf("    (no hostname returned by gethostbyaddr)\n");
+       }
+}
+/* end pr_ipv4 */
diff --git a/names/myaddrs1.c b/names/myaddrs1.c
new file mode 100644 (file)
index 0000000..d85d963
--- /dev/null
@@ -0,0 +1,18 @@
+#include       "unp.h"
+#include       <sys/param.h>
+
+char **
+my_addrs(int *addrtype)
+{
+       struct hostent  *hptr;
+       char                    myname[MAXHOSTNAMELEN];
+
+       if (gethostname(myname, sizeof(myname)) < 0)
+               return(NULL);
+
+       if ( (hptr = gethostbyname(myname)) == NULL)
+               return(NULL);
+
+       *addrtype = hptr->h_addrtype;
+       return(hptr->h_addr_list);
+}
diff --git a/names/myaddrs1.lc b/names/myaddrs1.lc
new file mode 100644 (file)
index 0000000..6ca323d
--- /dev/null
@@ -0,0 +1,18 @@
+#include    "unp.h"##  1 ##src/names/myaddrs1.c##
+#include    <sys/param.h>##  2 ##src/names/myaddrs1.c##
+
+char  **##  3 ##src/names/myaddrs1.c##
+my_addrs(int *addrtype)##  4 ##src/names/myaddrs1.c##
+{##  5 ##src/names/myaddrs1.c##
+    struct hostent *hptr;##  6 ##src/names/myaddrs1.c##
+    char    myname[MAXHOSTNAMELEN];##  7 ##src/names/myaddrs1.c##
+
+    if (gethostname(myname, sizeof(myname)) < 0)##  8 ##src/names/myaddrs1.c##
+        return (NULL);##  9 ##src/names/myaddrs1.c##
+
+    if ((hptr = gethostbyname(myname)) == NULL)## 10 ##src/names/myaddrs1.c##
+        return (NULL);## 11 ##src/names/myaddrs1.c##
+
+    *addrtype = hptr->h_addrtype;## 12 ##src/names/myaddrs1.c##
+    return (hptr->h_addr_list);## 13 ##src/names/myaddrs1.c##
+}## 14 ##src/names/myaddrs1.c##
diff --git a/names/netent.c b/names/netent.c
new file mode 100644 (file)
index 0000000..6204737
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       char                    *ptr, **pptr;
+       struct netent   *nptr;
+
+       while (--argc > 0) {
+               ptr = *++argv;
+               if ( (nptr = getnetbyname(ptr)) == NULL) {
+                       err_msg("getnetbyname error for net: %s: %s",
+                                       ptr, hstrerror(h_errno));
+                       continue;
+               }
+               printf("official netname: %s\n", nptr->n_name);
+
+               for (pptr = nptr->n_aliases; *pptr != NULL; pptr++)
+                       printf("        alias: %s\n", *pptr);
+
+               switch (nptr->n_addrtype) {
+               case AF_INET:
+#ifdef AF_INET6
+               case AF_INET6:
+#endif
+                       break;
+
+               default:
+                       err_ret("unknown address type");
+                       break;
+               }
+       }
+       exit(0);
+}
diff --git a/names/prmyaddrs.c b/names/prmyaddrs.c
new file mode 100644 (file)
index 0000000..fc2e0a7
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "unp.h"
+
+char   **my_addrs(int *);
+
+int
+main(int argc, char **argv)
+{
+       int             addrtype;
+       char    **pptr, buf[INET6_ADDRSTRLEN];
+
+       if ( (pptr = my_addrs(&addrtype)) == NULL)
+               err_quit("my_addrs error");
+
+       for ( ; *pptr != NULL; pptr++)
+               printf("\taddress: %s\n",
+                          Inet_ntop(addrtype, *pptr, buf, sizeof(buf)));
+
+       exit(0);
+}
diff --git a/names/prmyaddrs1.c b/names/prmyaddrs1.c
new file mode 100644 (file)
index 0000000..fc2e0a7
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "unp.h"
+
+char   **my_addrs(int *);
+
+int
+main(int argc, char **argv)
+{
+       int             addrtype;
+       char    **pptr, buf[INET6_ADDRSTRLEN];
+
+       if ( (pptr = my_addrs(&addrtype)) == NULL)
+               err_quit("my_addrs error");
+
+       for ( ; *pptr != NULL; pptr++)
+               printf("\taddress: %s\n",
+                          Inet_ntop(addrtype, *pptr, buf, sizeof(buf)));
+
+       exit(0);
+}
diff --git a/names/prmyaddrs1.lc b/names/prmyaddrs1.lc
new file mode 100644 (file)
index 0000000..1b24441
--- /dev/null
@@ -0,0 +1,19 @@
+#include    "unp.h"##  1 ##src/names/prmyaddrs1.c##
+
+char  **my_addrs(int *);##  2 ##src/names/prmyaddrs1.c##
+
+int##  3 ##src/names/prmyaddrs1.c##
+main(int argc, char **argv)##  4 ##src/names/prmyaddrs1.c##
+{##  5 ##src/names/prmyaddrs1.c##
+    int     addrtype;##  6 ##src/names/prmyaddrs1.c##
+    char  **pptr, buf[INET6_ADDRSTRLEN];##  7 ##src/names/prmyaddrs1.c##
+
+    if ((pptr = my_addrs(&addrtype)) == NULL)##  8 ##src/names/prmyaddrs1.c##
+        err_quit("my_addrs error");##  9 ##src/names/prmyaddrs1.c##
+
+    for (; *pptr != NULL; pptr++)## 10 ##src/names/prmyaddrs1.c##
+        printf("\taddress: %s\n",## 11 ##src/names/prmyaddrs1.c##
+               Inet_ntop(addrtype, *pptr, buf, sizeof(buf)));## 12 ##src/names/prmyaddrs1.c##
+
+    exit(0);## 13 ##src/names/prmyaddrs1.c##
+}## 14 ##src/names/prmyaddrs1.c##
diff --git a/names/test1.c b/names/test1.c
new file mode 100644 (file)
index 0000000..c07147d
--- /dev/null
@@ -0,0 +1,50 @@
+#include       "unp.h"
+
+void   pr_ipv4(char **);
+
+int
+main(int argc, char **argv)
+{
+       char                    *ptr, **pptr, **listptr, buf[INET6_ADDRSTRLEN];
+       char                    *list[100];
+       int                             i, addrtype, addrlen;
+       struct hostent  *hptr;
+
+       while (--argc > 0) {
+               ptr = *++argv;
+               if ( (hptr = gethostbyname(ptr)) == NULL) {
+                       err_msg("gethostbyname error for host: %s: %s",
+                                       ptr, hstrerror(h_errno));
+                       continue;
+               }
+               printf("official host name: %s\n", hptr->h_name);
+
+               for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
+                       printf("        alias: %s\n", *pptr);
+               addrtype = hptr->h_addrtype;
+               addrlen = hptr->h_length;
+
+                       /* copy array of pointers, so we can call gethostbyaddr() */
+               for (i = 0, listptr = hptr->h_addr_list; *listptr != NULL; listptr++) {
+                       list[i++] = *listptr;
+               }
+               list[i] = NULL;
+
+               for (listptr = list; *listptr != NULL; listptr++) {
+                       printf("\taddress: %s\n",
+                                  Inet_ntop(addrtype, *listptr, buf, sizeof(buf)));
+
+                       if ( (hptr = gethostbyaddr(*listptr, addrlen, addrtype)) == NULL)
+                               printf("\t\t(gethostbyaddr failed)\n");
+                       else if (hptr->h_name != NULL)
+                               printf("\t\tname = %s\n", hptr->h_name);
+                       else
+                               printf("\t\t(no hostname returned by gethostbyaddr)\n");
+
+                       printf("\t\tofficial host name: %s\n", hptr->h_name);
+
+                       for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
+                               printf("\t\talias: %s\n", *pptr);
+               }
+       }
+}
diff --git a/names/test2.c b/names/test2.c
new file mode 100644 (file)
index 0000000..51aeb4e
--- /dev/null
@@ -0,0 +1,32 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                             sockfd, n;
+       char                    recvline[MAXLINE + 1];
+       socklen_t               salen;
+       struct sockaddr *sa, *sabind;
+
+       if (argc != 3)
+               err_quit("usage: test2 <hostname/IPaddress> <service/port#>");
+
+       sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);
+
+       /* Same as daytimeudpcli1, but we explicitly bind the wildcard */
+       sabind = Malloc(salen);
+       bzero(sabind, salen);
+       sabind->sa_family = sa->sa_family;
+       Bind(sockfd, sabind, salen);
+       printf("bound %s\n", Sock_ntop(sabind, salen));
+
+       printf("sending to %s\n", Sock_ntop_host(sa, salen));
+
+       Sendto(sockfd, "", 1, 0, sa, salen);    /* send 1-byte datagram */
+
+       n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
+       recvline[n] = 0;        /* null terminate */
+       Fputs(recvline, stdout);
+
+       exit(0);
+}
diff --git a/names/udp_server_reuseaddr.c b/names/udp_server_reuseaddr.c
new file mode 100644 (file)
index 0000000..f3cdecb
--- /dev/null
@@ -0,0 +1,49 @@
+/* include udp_server */
+#include       "unp.h"
+
+int
+udp_server_reuseaddr(const char *host, const char *serv, socklen_t *addrlenp)
+{
+       int                             sockfd, n;
+       const int               on = 1;
+       struct addrinfo hints, *res, *ressave;
+
+       bzero(&hints, sizeof(struct addrinfo));
+       hints.ai_flags = AI_PASSIVE;
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_DGRAM;
+
+       if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0)
+               err_quit("udp_server error for %s, %s: %s",
+                                host, serv, gai_strerror(n));
+       ressave = res;
+
+       do {
+               sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+               if (sockfd < 0)
+                       continue;               /* error, try next one */
+
+               Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+               if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0)
+                       break;                  /* success */
+
+               Close(sockfd);          /* bind error, close and try next one */
+       } while ( (res = res->ai_next) != NULL);
+
+       if (res == NULL)        /* errno from final socket() or bind() */
+               err_sys("udp_server error for %s, %s", host, serv);
+
+       if (addrlenp)
+               *addrlenp = res->ai_addrlen;    /* return size of protocol address */
+
+       freeaddrinfo(ressave);
+
+       return(sockfd);
+}
+/* end udp_server */
+
+int
+Udp_server_reuseaddr(const char *host, const char *serv, socklen_t *addrlenp)
+{
+       return(udp_server_reuseaddr(host, serv, addrlenp));
+}
diff --git a/nonblock/Makefile b/nonblock/Makefile
new file mode 100644 (file)
index 0000000..ad39f2f
--- /dev/null
@@ -0,0 +1,30 @@
+include ../Make.defines
+
+PROGS =        daytimetcpcli tcpcli01 tcpcli02 tcpcli03 tcpcli04 tcpservselect02 web
+
+all:   ${PROGS}
+
+daytimetcpcli: daytimetcpcli.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpcli.o ${LIBS}
+
+tcpcli01:      tcpcli01.o strclifork.o
+               ${CC} ${CFLAGS} -o $@ tcpcli01.o strclifork.o ${LIBS}
+
+tcpcli02:      tcpcli02.o strclinonb.o
+               ${CC} ${CFLAGS} -o $@ tcpcli02.o strclinonb.o ${LIBS}
+
+tcpcli03:      tcpcli03.o
+               ${CC} ${CFLAGS} -o $@ tcpcli03.o ${LIBS}
+
+tcpcli04:      tcpcli04.o
+               ${CC} ${CFLAGS} -o $@ tcpcli04.o ${LIBS}
+
+tcpservselect03:       tcpservselect03.o
+               ${CC} ${CFLAGS} -o $@ tcpservselect03.o ${LIBS}
+
+web:   web.o home_page.o start_connect.o write_get_cmd.o
+               ${CC} ${CFLAGS} -o $@ web.o home_page.o start_connect.o \
+                       write_get_cmd.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/nonblock/daytimetcpcli.c b/nonblock/daytimetcpcli.c
new file mode 100644 (file)
index 0000000..fbb1cc7
--- /dev/null
@@ -0,0 +1,32 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, n;
+       struct sockaddr_in      servaddr;
+       char                            recvline[MAXLINE + 1];
+
+       if ( (sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
+               err_sys("socket error");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = inet_addr(argv[1]);
+       servaddr.sin_port        = htons(13);   /* daytime server */
+
+       if (connect_nonb(sockfd, (SA *) &servaddr, sizeof(servaddr), 0) < 0)
+               err_sys("connect error");
+
+       for ( ; ; ) {
+               if ( (n = read(sockfd, recvline, MAXLINE)) <= 0) {
+                       if (n == 0)
+                               break;          /* server closed connection */
+                       else
+                               err_sys("read error");
+               }
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+       exit(0);
+}
diff --git a/nonblock/doit.1 b/nonblock/doit.1
new file mode 100755 (executable)
index 0000000..673bf98
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+case $# in
+1)     break ;;
+*)     echo "one argument (#simultaneous connections) required" 1>&2
+       exit 1 ;;
+esac
+
+time ./web $1 192.207.117.2 / \
+       /img/logo/awl_logo_blue_50x40.gif \
+       /img/a_world_of_learning.gif \
+       /img/toolbar_soptions.gif \
+       /img/toolbar_purchase.gif \
+       /img/toolbar_feedback.gif \
+       /img/toolbar_top_hilite.gif \
+       /img/toolbar_qsearch.gif \
+       /img/blue_dot.gif \
+       /img/logo/pearson_logo_50.gif
diff --git a/nonblock/home_page.c b/nonblock/home_page.c
new file mode 100644 (file)
index 0000000..02d9691
--- /dev/null
@@ -0,0 +1,23 @@
+#include       "web.h"
+
+void
+home_page(const char *host, const char *fname)
+{
+       int             fd, n;
+       char    line[MAXLINE];
+
+       fd = Tcp_connect(host, SERV);   /* blocking connect() */
+
+       n = snprintf(line, sizeof(line), GET_CMD, fname);
+       Writen(fd, line, n);
+
+       for ( ; ; ) {
+               if ( (n = Read(fd, line, MAXLINE)) == 0)
+                       break;          /* server closed connection */
+
+               printf("read %d bytes of home page\n", n);
+               /* do whatever with data */
+       }
+       printf("end-of-file on home page\n");
+       Close(fd);
+}
diff --git a/nonblock/script.1.sh b/nonblock/script.1.sh
new file mode 100644 (file)
index 0000000..a7940aa
--- /dev/null
@@ -0,0 +1,28 @@
+10:18:34.491482: read 4096 bytes from stdin
+10:18:34.519016: wrote 4096 bytes to socket
+10:18:34.544636: read 4096 bytes from stdin
+10:18:34.568505: read 3508 bytes from socket
+10:18:34.593354: wrote 3508 bytes to stdout
+10:18:34.618062: wrote 4096 bytes to socket
+10:18:34.643524: read 4096 bytes from stdin
+10:18:34.667305: read 2636 bytes from socket
+10:18:34.691039: wrote 2636 bytes to stdout
+10:18:34.697238: wrote 4096 bytes to socket
+10:18:34.700582: read 4096 bytes from stdin
+10:18:34.703809: read 2048 bytes from socket
+10:18:34.708440: wrote 2048 bytes to stdout
+10:18:34.712738: wrote 4096 bytes to socket
+10:18:34.716194: read 4096 bytes from stdin
+10:18:34.719832: read 4096 bytes from socket
+10:18:34.724106: wrote 4096 bytes to stdout
+10:18:34.728503: wrote 4096 bytes to socket
+10:18:34.731839: read 3649 bytes from stdin
+10:18:34.735129: read 4096 bytes from socket
+10:18:34.778481: wrote 4096 bytes to stdout
+10:18:34.803742: wrote 3649 bytes to socket
+10:18:34.829483: EOF on stdin
+10:18:34.849752: read 4096 bytes from socket
+10:18:34.874733: wrote 4096 bytes to stdout
+10:18:34.898581: read 3649 bytes from socket
+10:18:34.923059: wrote 3649 bytes to stdout
+10:18:34.946892: EOF on socket
diff --git a/nonblock/script.1.tcpd b/nonblock/script.1.tcpd
new file mode 100644 (file)
index 0000000..407c8e6
--- /dev/null
@@ -0,0 +1,62 @@
+10:18:34.486392 kohala.33621 > kalae.echo: S 1802738644:1802738644(0) win 8760 <mss 1460> (DF)
+10:18:34.488278 kalae.echo > kohala.33621: S 3212986316:3212986316(0) ack 1802738645 win 8760 <mss 1460>
+10:18:34.488490 kohala.33621 > kalae.echo: . ack 1 win 8760 (DF)
+10:18:34.518663 kohala.33621 > kalae.echo: P 1:1461(1460) ack 1 win 8760 (DF)
+10:18:34.528529 kalae.echo > kohala.33621: P 1:1461(1460) ack 1461 win 8760
+10:18:34.528785 kohala.33621 > kalae.echo: . 1461:2921(1460) ack 1461 win 8760 (DF)
+10:18:34.528900 kohala.33621 > kalae.echo: P 2921:4097(1176) ack 1461 win 8760 (DF)
+10:18:34.528958 kohala.33621 > kalae.echo: . ack 1461 win 8760 (DF)
+10:18:34.536193 kalae.echo > kohala.33621: . 1461:2921(1460) ack 4097 win 8760
+10:18:34.536697 kalae.echo > kohala.33621: P 2921:3509(588) ack 4097 win 8760
+10:18:34.580373 kohala.33621 > kalae.echo: . ack 3509 win 8760 (DF)
+10:18:34.582244 kalae.echo > kohala.33621: P 3509:4097(588) ack 4097 win 8760
+10:18:34.617272 kohala.33621 > kalae.echo: P 4097:5557(1460) ack 4097 win 8760 (DF)
+10:18:34.617610 kohala.33621 > kalae.echo: P 5557:7017(1460) ack 4097 win 8760 (DF)
+10:18:34.617908 kohala.33621 > kalae.echo: P 7017:8193(1176) ack 4097 win 8760 (DF)
+10:18:34.623310 kalae.echo > kohala.33621: . ack 8193 win 8760
+10:18:34.626129 kalae.echo > kohala.33621: . 4097:5557(1460) ack 8193 win 8760
+10:18:34.626339 kohala.33621 > kalae.echo: . ack 5557 win 8760 (DF)
+10:18:34.626611 kalae.echo > kohala.33621: P 5557:6145(588) ack 8193 win 8760
+10:18:34.628396 kalae.echo > kohala.33621: . 6145:7605(1460) ack 8193 win 8760
+10:18:34.670324 kohala.33621 > kalae.echo: . ack 7605 win 8760 (DF)
+10:18:34.672221 kalae.echo > kohala.33621: P 7605:8193(588) ack 8193 win 8760
+10:18:34.696426 kohala.33621 > kalae.echo: P 8193:9653(1460) ack 8193 win 8760 (DF)
+10:18:34.696768 kohala.33621 > kalae.echo: P 9653:11113(1460) ack 8193 win 8760 (DF)
+10:18:34.697077 kohala.33621 > kalae.echo: P 11113:12289(1176) ack 8193 win 8760 (DF)
+10:18:34.702449 kalae.echo > kohala.33621: . ack 12289 win 8760
+10:18:34.705393 kalae.echo > kohala.33621: . 8193:9653(1460) ack 12289 win 8760
+10:18:34.705795 kalae.echo > kohala.33621: P 9653:10241(588) ack 12289 win 8760
+10:18:34.705908 kohala.33621 > kalae.echo: . ack 9653 win 8760 (DF)
+10:18:34.707441 kalae.echo > kohala.33621: . 10241:11701(1460) ack 12289 win 8760
+10:18:34.711917 kohala.33621 > kalae.echo: P 12289:13749(1460) ack 11701 win 8760 (DF)
+10:18:34.712264 kohala.33621 > kalae.echo: P 13749:15209(1460) ack 11701 win 8760 (DF)
+10:18:34.712579 kohala.33621 > kalae.echo: P 15209:16385(1176) ack 11701 win 8760 (DF)
+10:18:34.717363 kalae.echo > kohala.33621: P 11701:12289(588) ack 13749 win 7300
+10:18:34.718793 kalae.echo > kohala.33621: . ack 16385 win 8760
+10:18:34.721546 kalae.echo > kohala.33621: . 12289:13749(1460) ack 16385 win 8760
+10:18:34.723149 kalae.echo > kohala.33621: . 13749:15209(1460) ack 16385 win 8760
+10:18:34.723343 kohala.33621 > kalae.echo: . ack 15209 win 8760 (DF)
+10:18:34.726008 kalae.echo > kohala.33621: P 15209:16385(1176) ack 16385 win 8760
+10:18:34.727659 kohala.33621 > kalae.echo: P 16385:17845(1460) ack 16385 win 8760 (DF)
+10:18:34.728011 kohala.33621 > kalae.echo: P 17845:19305(1460) ack 16385 win 8760 (DF)
+10:18:34.728337 kohala.33621 > kalae.echo: P 19305:20481(1176) ack 16385 win 8760 (DF)
+10:18:34.733691 kalae.echo > kohala.33621: . ack 20481 win 8760
+10:18:34.736411 kalae.echo > kohala.33621: . 16385:17845(1460) ack 20481 win 8760
+10:18:34.736942 kalae.echo > kohala.33621: P 17845:18433(588) ack 20481 win 8760
+10:18:34.738753 kalae.echo > kohala.33621: . 18433:19893(1460) ack 20481 win 8760
+10:18:34.738968 kohala.33621 > kalae.echo: . ack 19893 win 8760 (DF)
+10:18:34.740856 kalae.echo > kohala.33621: P 19893:20481(588) ack 20481 win 8760
+10:18:34.790367 kohala.33621 > kalae.echo: . ack 20481 win 8760 (DF)
+10:18:34.802928 kohala.33621 > kalae.echo: P 20481:21941(1460) ack 20481 win 8760 (DF)
+10:18:34.803290 kohala.33621 > kalae.echo: P 21941:23401(1460) ack 20481 win 8760 (DF)
+10:18:34.803575 kohala.33621 > kalae.echo: P 23401:24130(729) ack 20481 win 8760 (DF)
+10:18:34.808732 kalae.echo > kohala.33621: . ack 24130 win 8760
+10:18:34.811468 kalae.echo > kohala.33621: . 20481:21941(1460) ack 24130 win 8760
+10:18:34.811994 kalae.echo > kohala.33621: P 21941:22529(588) ack 24130 win 8760
+10:18:34.813713 kalae.echo > kohala.33621: . 22529:23989(1460) ack 24130 win 8760
+10:18:34.813937 kohala.33621 > kalae.echo: . ack 23989 win 8760 (DF)
+10:18:34.815274 kalae.echo > kohala.33621: P 23989:24130(141) ack 24130 win 8760
+10:18:34.849338 kohala.33621 > kalae.echo: F 24130:24130(0) ack 24130 win 8760 (DF)
+10:18:34.850471 kalae.echo > kohala.33621: . ack 24131 win 8760
+10:18:34.852790 kalae.echo > kohala.33621: F 24130:24130(0) ack 24131 win 8760
+10:18:34.853086 kohala.33621 > kalae.echo: . ack 24131 win 8760 (DF)
diff --git a/nonblock/start_connect.c b/nonblock/start_connect.c
new file mode 100644 (file)
index 0000000..1546f69
--- /dev/null
@@ -0,0 +1,31 @@
+#include       "web.h"
+
+void
+start_connect(struct file *fptr)
+{
+       int                             fd, flags, n;
+       struct addrinfo *ai;
+
+       ai = Host_serv(fptr->f_host, SERV, 0, SOCK_STREAM);
+
+       fd = Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+       fptr->f_fd = fd;
+       printf("start_connect for %s, fd %d\n", fptr->f_name, fd);
+
+               /* 4Set socket nonblocking */
+       flags = Fcntl(fd, F_GETFL, 0);
+       Fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+
+               /* 4Initiate nonblocking connect to the server. */
+       if ( (n = connect(fd, ai->ai_addr, ai->ai_addrlen)) < 0) {
+               if (errno != EINPROGRESS)
+                       err_sys("nonblocking connect error");
+               fptr->f_flags = F_CONNECTING;
+               FD_SET(fd, &rset);                      /* select for reading and writing */
+               FD_SET(fd, &wset);
+               if (fd > maxfd)
+                       maxfd = fd;
+
+       } else if (n >= 0)                              /* connect is already done */
+               write_get_cmd(fptr);    /* write() the GET command */
+}
diff --git a/nonblock/strclifork.c b/nonblock/strclifork.c
new file mode 100644 (file)
index 0000000..2ff702d
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+
+void
+str_cli(FILE *fp, int sockfd)
+{
+       pid_t   pid;
+       char    sendline[MAXLINE], recvline[MAXLINE];
+
+       if ( (pid = Fork()) == 0) {             /* child: server -> stdout */
+               while (Readline(sockfd, recvline, MAXLINE) > 0)
+                       Fputs(recvline, stdout);
+
+               kill(getppid(), SIGTERM);       /* in case parent still running */
+               exit(0);
+       }
+
+               /* parent: stdin -> server */
+       while (Fgets(sendline, MAXLINE, fp) != NULL)
+               Writen(sockfd, sendline, strlen(sendline));
+
+       Shutdown(sockfd, SHUT_WR);      /* EOF on stdin, send FIN */
+       pause();
+       return;
+}
diff --git a/nonblock/strclinonb.c b/nonblock/strclinonb.c
new file mode 100644 (file)
index 0000000..a06e126
--- /dev/null
@@ -0,0 +1,125 @@
+/* include nonb1 */
+#include       "unp.h"
+
+void
+str_cli(FILE *fp, int sockfd)
+{
+       int                     maxfdp1, val, stdineof;
+       ssize_t         n, nwritten;
+       fd_set          rset, wset;
+       char            to[MAXLINE], fr[MAXLINE];
+       char            *toiptr, *tooptr, *friptr, *froptr;
+
+       val = Fcntl(sockfd, F_GETFL, 0);
+       Fcntl(sockfd, F_SETFL, val | O_NONBLOCK);
+
+       val = Fcntl(STDIN_FILENO, F_GETFL, 0);
+       Fcntl(STDIN_FILENO, F_SETFL, val | O_NONBLOCK);
+
+       val = Fcntl(STDOUT_FILENO, F_GETFL, 0);
+       Fcntl(STDOUT_FILENO, F_SETFL, val | O_NONBLOCK);
+
+       toiptr = tooptr = to;   /* initialize buffer pointers */
+       friptr = froptr = fr;
+       stdineof = 0;
+
+       maxfdp1 = max(max(STDIN_FILENO, STDOUT_FILENO), sockfd) + 1;
+       for ( ; ; ) {
+               FD_ZERO(&rset);
+               FD_ZERO(&wset);
+               if (stdineof == 0 && toiptr < &to[MAXLINE])
+                       FD_SET(STDIN_FILENO, &rset);    /* read from stdin */
+               if (friptr < &fr[MAXLINE])
+                       FD_SET(sockfd, &rset);                  /* read from socket */
+               if (tooptr != toiptr)
+                       FD_SET(sockfd, &wset);                  /* data to write to socket */
+               if (froptr != friptr)
+                       FD_SET(STDOUT_FILENO, &wset);   /* data to write to stdout */
+
+               Select(maxfdp1, &rset, &wset, NULL, NULL);
+/* end nonb1 */
+/* include nonb2 */
+               if (FD_ISSET(STDIN_FILENO, &rset)) {
+                       if ( (n = read(STDIN_FILENO, toiptr, &to[MAXLINE] - toiptr)) < 0) {
+                               if (errno != EWOULDBLOCK)
+                                       err_sys("read error on stdin");
+
+                       } else if (n == 0) {
+#ifdef VOL2
+                               fprintf(stderr, "%s: EOF on stdin\n", gf_time());
+#endif
+                               stdineof = 1;                   /* all done with stdin */
+                               if (tooptr == toiptr)
+                                       Shutdown(sockfd, SHUT_WR);/* send FIN */
+
+                       } else {
+#ifdef VOL2
+                               fprintf(stderr, "%s: read %d bytes from stdin\n", gf_time(), n);
+#endif
+                               toiptr += n;                    /* # just read */
+                               FD_SET(sockfd, &wset);  /* try and write to socket below */
+                       }
+               }
+
+               if (FD_ISSET(sockfd, &rset)) {
+                       if ( (n = read(sockfd, friptr, &fr[MAXLINE] - friptr)) < 0) {
+                               if (errno != EWOULDBLOCK)
+                                       err_sys("read error on socket");
+
+                       } else if (n == 0) {
+#ifdef VOL2
+                               fprintf(stderr, "%s: EOF on socket\n", gf_time());
+#endif
+                               if (stdineof)
+                                       return;         /* normal termination */
+                               else
+                                       err_quit("str_cli: server terminated prematurely");
+
+                       } else {
+#ifdef VOL2
+                               fprintf(stderr, "%s: read %d bytes from socket\n",
+                                                               gf_time(), n);
+#endif
+                               friptr += n;            /* # just read */
+                               FD_SET(STDOUT_FILENO, &wset);   /* try and write below */
+                       }
+               }
+/* end nonb2 */
+/* include nonb3 */
+               if (FD_ISSET(STDOUT_FILENO, &wset) && ( (n = friptr - froptr) > 0)) {
+                       if ( (nwritten = write(STDOUT_FILENO, froptr, n)) < 0) {
+                               if (errno != EWOULDBLOCK)
+                                       err_sys("write error to stdout");
+
+                       } else {
+#ifdef VOL2
+                               fprintf(stderr, "%s: wrote %d bytes to stdout\n",
+                                                               gf_time(), nwritten);
+#endif
+                               froptr += nwritten;             /* # just written */
+                               if (froptr == friptr)
+                                       froptr = friptr = fr;   /* back to beginning of buffer */
+                       }
+               }
+
+               if (FD_ISSET(sockfd, &wset) && ( (n = toiptr - tooptr) > 0)) {
+                       if ( (nwritten = write(sockfd, tooptr, n)) < 0) {
+                               if (errno != EWOULDBLOCK)
+                                       err_sys("write error to socket");
+
+                       } else {
+#ifdef VOL2
+                               fprintf(stderr, "%s: wrote %d bytes to socket\n",
+                                                               gf_time(), nwritten);
+#endif
+                               tooptr += nwritten;     /* # just written */
+                               if (tooptr == toiptr) {
+                                       toiptr = tooptr = to;   /* back to beginning of buffer */
+                                       if (stdineof)
+                                               Shutdown(sockfd, SHUT_WR);      /* send FIN */
+                               }
+                       }
+               }
+       }
+}
+/* end nonb3 */
diff --git a/nonblock/strclinonb.lc b/nonblock/strclinonb.lc
new file mode 100644 (file)
index 0000000..3e9631b
--- /dev/null
@@ -0,0 +1,114 @@
+/* include nonb1 */
+#include    "unp.h"##  1 ##src/nonblock/strclinonb.c##
+
+void##  2 ##src/nonblock/strclinonb.c##
+str_cli(FILE *fp, int sockfd)##  3 ##src/nonblock/strclinonb.c##
+{##  4 ##src/nonblock/strclinonb.c##
+    int     maxfdp1, val, stdineof;##  5 ##src/nonblock/strclinonb.c##
+    ssize_t n, nwritten;##  6 ##src/nonblock/strclinonb.c##
+    fd_set  rset, wset;##  7 ##src/nonblock/strclinonb.c##
+    char    to[MAXLINE], fr[MAXLINE];##  8 ##src/nonblock/strclinonb.c##
+    char   *toiptr, *tooptr, *friptr, *froptr;##  9 ##src/nonblock/strclinonb.c##
+
+    val = Fcntl(sockfd, F_GETFL, 0);## 10 ##src/nonblock/strclinonb.c##
+    Fcntl(sockfd, F_SETFL, val | O_NONBLOCK);## 11 ##src/nonblock/strclinonb.c##
+
+    val = Fcntl(STDIN_FILENO, F_GETFL, 0);## 12 ##src/nonblock/strclinonb.c##
+    Fcntl(STDIN_FILENO, F_SETFL, val | O_NONBLOCK);## 13 ##src/nonblock/strclinonb.c##
+
+    val = Fcntl(STDOUT_FILENO, F_GETFL, 0);## 14 ##src/nonblock/strclinonb.c##
+    Fcntl(STDOUT_FILENO, F_SETFL, val | O_NONBLOCK);## 15 ##src/nonblock/strclinonb.c##
+
+    toiptr = tooptr = to;       /* initialize buffer pointers */## 16 ##src/nonblock/strclinonb.c##
+    friptr = froptr = fr;## 17 ##src/nonblock/strclinonb.c##
+    stdineof = 0;## 18 ##src/nonblock/strclinonb.c##
+
+    maxfdp1 = max(max(STDIN_FILENO, STDOUT_FILENO), sockfd) + 1;## 19 ##src/nonblock/strclinonb.c##
+    for (;;) {## 20 ##src/nonblock/strclinonb.c##
+        FD_ZERO(&rset);## 21 ##src/nonblock/strclinonb.c##
+        FD_ZERO(&wset);## 22 ##src/nonblock/strclinonb.c##
+        if (stdineof == 0 && toiptr < &to[MAXLINE])## 23 ##src/nonblock/strclinonb.c##
+            FD_SET(STDIN_FILENO, &rset);    /* read from stdin */## 24 ##src/nonblock/strclinonb.c##
+        if (friptr < &fr[MAXLINE])## 25 ##src/nonblock/strclinonb.c##
+            FD_SET(sockfd, &rset);  /* read from socket */## 26 ##src/nonblock/strclinonb.c##
+        if (tooptr != toiptr)## 27 ##src/nonblock/strclinonb.c##
+            FD_SET(sockfd, &wset);  /* data to write to socket */## 28 ##src/nonblock/strclinonb.c##
+        if (froptr != friptr)## 29 ##src/nonblock/strclinonb.c##
+            FD_SET(STDOUT_FILENO, &wset);   /* data to write to stdout */## 30 ##src/nonblock/strclinonb.c##
+
+        Select(maxfdp1, &rset, &wset, NULL, NULL);## 31 ##src/nonblock/strclinonb.c##
+/* end nonb1 */
+/* include nonb2 */
+        if (FD_ISSET(STDIN_FILENO, &rset)) {## 32 ##src/nonblock/strclinonb.c##
+            if ((n = read(STDIN_FILENO, toiptr, &to[MAXLINE] - toiptr)) < 0) {## 33 ##src/nonblock/strclinonb.c##
+                if (errno != EWOULDBLOCK)## 34 ##src/nonblock/strclinonb.c##
+                    err_sys("read error on stdin");## 35 ##src/nonblock/strclinonb.c##
+
+            } else if (n == 0) {## 36 ##src/nonblock/strclinonb.c##
+                fprintf(stderr, "%s: EOF on stdin\n", gf_time());## 37 ##src/nonblock/strclinonb.c##
+                stdineof = 1;   /* all done with stdin */## 38 ##src/nonblock/strclinonb.c##
+                if (tooptr == toiptr)## 39 ##src/nonblock/strclinonb.c##
+                    Shutdown(sockfd, SHUT_WR);  /* send FIN */## 40 ##src/nonblock/strclinonb.c##
+
+            } else {## 41 ##src/nonblock/strclinonb.c##
+                fprintf(stderr, "%s: read %d bytes from stdin\n", gf_time(),## 42 ##src/nonblock/strclinonb.c##
+                        n);## 43 ##src/nonblock/strclinonb.c##
+                toiptr += n;    /* # just read */## 44 ##src/nonblock/strclinonb.c##
+                FD_SET(sockfd, &wset);  /* try and write to socket below */## 45 ##src/nonblock/strclinonb.c##
+            }## 46 ##src/nonblock/strclinonb.c##
+        }## 47 ##src/nonblock/strclinonb.c##
+
+        if (FD_ISSET(sockfd, &rset)) {## 48 ##src/nonblock/strclinonb.c##
+            if ((n = read(sockfd, friptr, &fr[MAXLINE] - friptr)) < 0) {## 49 ##src/nonblock/strclinonb.c##
+                if (errno != EWOULDBLOCK)## 50 ##src/nonblock/strclinonb.c##
+                    err_sys("read error on socket");## 51 ##src/nonblock/strclinonb.c##
+
+            } else if (n == 0) {## 52 ##src/nonblock/strclinonb.c##
+                fprintf(stderr, "%s: EOF on socket\n", gf_time());## 53 ##src/nonblock/strclinonb.c##
+                if (stdineof)## 54 ##src/nonblock/strclinonb.c##
+                    return;     /* normal termination */## 55 ##src/nonblock/strclinonb.c##
+                else## 56 ##src/nonblock/strclinonb.c##
+                    err_quit("str_cli: server terminated prematurely");## 57 ##src/nonblock/strclinonb.c##
+
+            } else {## 58 ##src/nonblock/strclinonb.c##
+                fprintf(stderr, "%s: read %d bytes from socket\n",## 59 ##src/nonblock/strclinonb.c##
+                        gf_time(), n);## 60 ##src/nonblock/strclinonb.c##
+                friptr += n;    /* # just read */## 61 ##src/nonblock/strclinonb.c##
+                FD_SET(STDOUT_FILENO, &wset);   /* try and write below */## 62 ##src/nonblock/strclinonb.c##
+            }## 63 ##src/nonblock/strclinonb.c##
+        }## 64 ##src/nonblock/strclinonb.c##
+/* end nonb2 */
+/* include nonb3 */
+        if (FD_ISSET(STDOUT_FILENO, &wset) && ((n = friptr - froptr) > 0)) {## 65 ##src/nonblock/strclinonb.c##
+            if ((nwritten = write(STDOUT_FILENO, froptr, n)) < 0) {## 66 ##src/nonblock/strclinonb.c##
+                if (errno != EWOULDBLOCK)## 67 ##src/nonblock/strclinonb.c##
+                    err_sys("write error to stdout");## 68 ##src/nonblock/strclinonb.c##
+
+            } else {## 69 ##src/nonblock/strclinonb.c##
+                fprintf(stderr, "%s: wrote %d bytes to stdout\n",## 70 ##src/nonblock/strclinonb.c##
+                        gf_time(), nwritten);## 71 ##src/nonblock/strclinonb.c##
+                froptr += nwritten; /* # just written */## 72 ##src/nonblock/strclinonb.c##
+                if (froptr == friptr)## 73 ##src/nonblock/strclinonb.c##
+                    froptr = friptr = fr;   /* back to beginning of buffer */## 74 ##src/nonblock/strclinonb.c##
+            }## 75 ##src/nonblock/strclinonb.c##
+        }## 76 ##src/nonblock/strclinonb.c##
+
+        if (FD_ISSET(sockfd, &wset) && ((n = toiptr - tooptr) > 0)) {## 77 ##src/nonblock/strclinonb.c##
+            if ((nwritten = write(sockfd, tooptr, n)) < 0) {## 78 ##src/nonblock/strclinonb.c##
+                if (errno != EWOULDBLOCK)## 79 ##src/nonblock/strclinonb.c##
+                    err_sys("write error to socket");## 80 ##src/nonblock/strclinonb.c##
+
+            } else {## 81 ##src/nonblock/strclinonb.c##
+                fprintf(stderr, "%s: wrote %d bytes to socket\n",## 82 ##src/nonblock/strclinonb.c##
+                        gf_time(), nwritten);## 83 ##src/nonblock/strclinonb.c##
+                tooptr += nwritten; /* # just written */## 84 ##src/nonblock/strclinonb.c##
+                if (tooptr == toiptr) {## 85 ##src/nonblock/strclinonb.c##
+                    toiptr = tooptr = to;   /* back to beginning of buffer */## 86 ##src/nonblock/strclinonb.c##
+                    if (stdineof)## 87 ##src/nonblock/strclinonb.c##
+                        Shutdown(sockfd, SHUT_WR);  /* send FIN */## 88 ##src/nonblock/strclinonb.c##
+                }## 89 ##src/nonblock/strclinonb.c##
+            }## 90 ##src/nonblock/strclinonb.c##
+        }## 91 ##src/nonblock/strclinonb.c##
+    }## 92 ##src/nonblock/strclinonb.c##
+}## 93 ##src/nonblock/strclinonb.c##
+/* end nonb3 */
diff --git a/nonblock/tcpcli01.c b/nonblock/tcpcli01.c
new file mode 100644 (file)
index 0000000..8c62186
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(7);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/nonblock/tcpcli02.c b/nonblock/tcpcli02.c
new file mode 100644 (file)
index 0000000..8c62186
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(7);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/nonblock/tcpcli03.c b/nonblock/tcpcli03.c
new file mode 100644 (file)
index 0000000..749c6eb
--- /dev/null
@@ -0,0 +1,28 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct linger           ling;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       ling.l_onoff = 1;               /* cause RST to be sent on close() */
+       ling.l_linger = 0;
+       Setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
+       Close(sockfd);
+
+       exit(0);
+}
diff --git a/nonblock/tcpcli03.lc b/nonblock/tcpcli03.lc
new file mode 100644 (file)
index 0000000..29a9ecb
--- /dev/null
@@ -0,0 +1,28 @@
+#include    "unp.h"##  1 ##src/nonblock/tcpcli03.c##
+
+int##  2 ##src/nonblock/tcpcli03.c##
+main(int argc, char **argv)##  3 ##src/nonblock/tcpcli03.c##
+{##  4 ##src/nonblock/tcpcli03.c##
+    int     sockfd;##  5 ##src/nonblock/tcpcli03.c##
+    struct linger ling;##  6 ##src/nonblock/tcpcli03.c##
+    struct sockaddr_in servaddr;##  7 ##src/nonblock/tcpcli03.c##
+
+    if (argc != 2)##  8 ##src/nonblock/tcpcli03.c##
+        err_quit("usage: tcpcli <IPaddress>");##  9 ##src/nonblock/tcpcli03.c##
+
+    sockfd = Socket(AF_INET, SOCK_STREAM, 0);## 10 ##src/nonblock/tcpcli03.c##
+
+    bzero(&servaddr, sizeof(servaddr));## 11 ##src/nonblock/tcpcli03.c##
+    servaddr.sin_family = AF_INET;## 12 ##src/nonblock/tcpcli03.c##
+    servaddr.sin_port = htons(SERV_PORT);## 13 ##src/nonblock/tcpcli03.c##
+    Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);## 14 ##src/nonblock/tcpcli03.c##
+
+    Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));## 15 ##src/nonblock/tcpcli03.c##
+
+    ling.l_onoff = 1;           /* cause RST to be sent on close() */## 16 ##src/nonblock/tcpcli03.c##
+    ling.l_linger = 0;## 17 ##src/nonblock/tcpcli03.c##
+    Setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));## 18 ##src/nonblock/tcpcli03.c##
+    Close(sockfd);## 19 ##src/nonblock/tcpcli03.c##
+
+    exit(0);## 20 ##src/nonblock/tcpcli03.c##
+}## 21 ##src/nonblock/tcpcli03.c##
diff --git a/nonblock/tcpcli04.c b/nonblock/tcpcli04.c
new file mode 100644 (file)
index 0000000..ecdb446
--- /dev/null
@@ -0,0 +1,29 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct linger           ling;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       ling.l_onoff = 1;               /* cause RST to be sent on close() */
+       ling.l_linger = 0;
+       Setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/nonblock/tcpservselect03.c b/nonblock/tcpservselect03.c
new file mode 100644 (file)
index 0000000..a530424
--- /dev/null
@@ -0,0 +1,82 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     i, maxi, maxfd, listenfd, connfd, sockfd;
+       int                                     nready, client[FD_SETSIZE];
+       ssize_t                         n;
+       fd_set                          rset, allset;
+       char                            line[MAXLINE];
+       socklen_t                       clilen;
+       struct sockaddr_in      cliaddr, servaddr;
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       maxfd = listenfd;                       /* initialize */
+       maxi = -1;                                      /* index into client[] array */
+       for (i = 0; i < FD_SETSIZE; i++)
+               client[i] = -1;                 /* -1 indicates available entry */
+       FD_ZERO(&allset);
+       FD_SET(listenfd, &allset);
+
+       for ( ; ; ) {
+               rset = allset;
+               nready = Select(maxfd+1, &rset, NULL, NULL, NULL);
+
+               if (FD_ISSET(listenfd, &rset)) {        /* new client connection */
+                       printf("listening socket readable\n");
+                       sleep(5);
+                       clilen = sizeof(cliaddr);
+                       connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
+#ifdef NOTDEF
+                       printf("new client: %s, port %d\n",
+                                       Inet_ntop(AF_INET, &cliaddr.sin_addr, 4, NULL),
+                                       ntohs(cliaddr.sin_port));
+#endif
+
+                       for (i = 0; i < FD_SETSIZE; i++)
+                               if (client[i] < 0) {
+                                       client[i] = connfd;     /* save descriptor */
+                                       break;
+                               }
+                       if (i == FD_SETSIZE)
+                               err_quit("too many clients");
+
+                       FD_SET(connfd, &allset);        /* add new descriptor to set */
+                       if (connfd > maxfd)
+                               maxfd = connfd;                 /* for select */
+                       if (i > maxi)
+                               maxi = i;                               /* max index in client[] array */
+
+                       if (--nready <= 0)
+                               continue;                               /* no more readable descriptors */
+               }
+
+               for (i = 0; i <= maxi; i++) {   /* check all clients for data */
+                       if ( (sockfd = client[i]) < 0)
+                               continue;
+                       if (FD_ISSET(sockfd, &rset)) {
+                               if ( (n = Readline(sockfd, line, MAXLINE)) == 0) {
+                                                /* connection closed by client */
+                                       Close(sockfd);
+                                       FD_CLR(sockfd, &allset);
+                                       client[i] = -1;
+                               }
+                               Writen(sockfd, line, n);
+
+                               if (--nready <= 0)
+                                       break;                          /* no more readable descriptors */
+                       }
+               }
+       }
+}
diff --git a/nonblock/web.c b/nonblock/web.c
new file mode 100644 (file)
index 0000000..637706b
--- /dev/null
@@ -0,0 +1,83 @@
+/* include web1 */
+#include       "web.h"
+
+int
+main(int argc, char **argv)
+{
+       int             i, fd, n, maxnconn, flags, error;
+       char    buf[MAXLINE];
+       fd_set  rs, ws;
+
+       if (argc < 5)
+               err_quit("usage: web <#conns> <hostname> <homepage> <file1> ...");
+       maxnconn = atoi(argv[1]);
+
+       nfiles = min(argc - 4, MAXFILES);
+       for (i = 0; i < nfiles; i++) {
+               file[i].f_name = argv[i + 4];
+               file[i].f_host = argv[2];
+               file[i].f_flags = 0;
+       }
+       printf("nfiles = %d\n", nfiles);
+
+       home_page(argv[2], argv[3]);
+
+       FD_ZERO(&rset);
+       FD_ZERO(&wset);
+       maxfd = -1;
+       nlefttoread = nlefttoconn = nfiles;
+       nconn = 0;
+/* end web1 */
+/* include web2 */
+       while (nlefttoread > 0) {
+               while (nconn < maxnconn && nlefttoconn > 0) {
+                               /* 4find a file to read */
+                       for (i = 0 ; i < nfiles; i++)
+                               if (file[i].f_flags == 0)
+                                       break;
+                       if (i == nfiles)
+                               err_quit("nlefttoconn = %d but nothing found", nlefttoconn);
+                       start_connect(&file[i]);
+                       nconn++;
+                       nlefttoconn--;
+               }
+
+               rs = rset;
+               ws = wset;
+               n = Select(maxfd+1, &rs, &ws, NULL, NULL);
+
+               for (i = 0; i < nfiles; i++) {
+                       flags = file[i].f_flags;
+                       if (flags == 0 || flags & F_DONE)
+                               continue;
+                       fd = file[i].f_fd;
+                       if (flags & F_CONNECTING &&
+                               (FD_ISSET(fd, &rs) || FD_ISSET(fd, &ws))) {
+                               n = sizeof(error);
+                               if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &n) < 0 ||
+                                       error != 0) {
+                                       err_ret("nonblocking connect failed for %s",
+                                                       file[i].f_name);
+                               }
+                                       /* 4connection established */
+                               printf("connection established for %s\n", file[i].f_name);
+                               FD_CLR(fd, &wset);              /* no more writeability test */
+                               write_get_cmd(&file[i]);/* write() the GET command */
+
+                       } else if (flags & F_READING && FD_ISSET(fd, &rs)) {
+                               if ( (n = Read(fd, buf, sizeof(buf))) == 0) {
+                                       printf("end-of-file on %s\n", file[i].f_name);
+                                       Close(fd);
+                                       file[i].f_flags = F_DONE;       /* clears F_READING */
+                                       FD_CLR(fd, &rset);
+                                       nconn--;
+                                       nlefttoread--;
+                               } else {
+                                       printf("read %d bytes from %s\n", n, file[i].f_name);
+                               }
+                       }
+               }
+       }
+       exit(0);
+}
+/* end web2 */
diff --git a/nonblock/web.h b/nonblock/web.h
new file mode 100644 (file)
index 0000000..eeac086
--- /dev/null
@@ -0,0 +1,26 @@
+#include       "unp.h"
+
+#define        MAXFILES        20
+#define        SERV            "80"    /* port number or service name */
+
+struct file {
+  char *f_name;                        /* filename */
+  char *f_host;                        /* hostname or IPv4/IPv6 address */
+  int    f_fd;                         /* descriptor */
+  int   f_flags;                       /* F_xxx below */
+} file[MAXFILES];
+
+#define        F_CONNECTING    1       /* connect() in progress */
+#define        F_READING               2       /* connect() complete; now reading */
+#define        F_DONE                  4       /* all done */
+
+#define        GET_CMD         "GET %s HTTP/1.0\r\n\r\n"
+
+                       /* globals */
+int            nconn, nfiles, nlefttoconn, nlefttoread, maxfd;
+fd_set rset, wset;
+
+                       /* function prototypes */
+void   home_page(const char *, const char *);
+void   start_connect(struct file *);
+void   write_get_cmd(struct file *);
diff --git a/nonblock/web.lc b/nonblock/web.lc
new file mode 100644 (file)
index 0000000..c5141c4
--- /dev/null
@@ -0,0 +1,83 @@
+/* include web1 */
+#include    "web.h"##  1 ##src/nonblock/web.c##
+
+int##  2 ##src/nonblock/web.c##
+main(int argc, char **argv)##  3 ##src/nonblock/web.c##
+{##  4 ##src/nonblock/web.c##
+    int     i, fd, n, maxnconn, flags, error;##  5 ##src/nonblock/web.c##
+    char    buf[MAXLINE];##  6 ##src/nonblock/web.c##
+    fd_set  rs, ws;##  7 ##src/nonblock/web.c##
+
+    if (argc < 5)##  8 ##src/nonblock/web.c##
+        err_quit("usage: web <#conns> <hostname> <homepage> <file1> ...");##  9 ##src/nonblock/web.c##
+    maxnconn = atoi(argv[1]);## 10 ##src/nonblock/web.c##
+
+    nfiles = min(argc - 4, MAXFILES);## 11 ##src/nonblock/web.c##
+    for (i = 0; i < nfiles; i++) {## 12 ##src/nonblock/web.c##
+        file[i].f_name = argv[i + 4];## 13 ##src/nonblock/web.c##
+        file[i].f_host = argv[2];## 14 ##src/nonblock/web.c##
+        file[i].f_flags = 0;## 15 ##src/nonblock/web.c##
+    }## 16 ##src/nonblock/web.c##
+    printf("nfiles = %d\n", nfiles);## 17 ##src/nonblock/web.c##
+
+    home_page(argv[2], argv[3]);## 18 ##src/nonblock/web.c##
+
+    FD_ZERO(&rset);## 19 ##src/nonblock/web.c##
+    FD_ZERO(&wset);## 20 ##src/nonblock/web.c##
+    maxfd = -1;## 21 ##src/nonblock/web.c##
+    nlefttoread = nlefttoconn = nfiles;## 22 ##src/nonblock/web.c##
+    nconn = 0;## 23 ##src/nonblock/web.c##
+/* end web1 */
+/* include web2 */
+    while (nlefttoread > 0) {## 24 ##src/nonblock/web.c##
+        while (nconn < maxnconn && nlefttoconn > 0) {## 25 ##src/nonblock/web.c##
+            /* 4find a file to read */## 26 ##src/nonblock/web.c##
+            for (i = 0; i < nfiles; i++)## 27 ##src/nonblock/web.c##
+                if (file[i].f_flags == 0)## 28 ##src/nonblock/web.c##
+                    break;## 29 ##src/nonblock/web.c##
+            if (i == nfiles)## 30 ##src/nonblock/web.c##
+                err_quit("nlefttoconn = %d but nothing found", nlefttoconn);## 31 ##src/nonblock/web.c##
+            start_connect(&file[i]);## 32 ##src/nonblock/web.c##
+            nconn++;## 33 ##src/nonblock/web.c##
+            nlefttoconn--;## 34 ##src/nonblock/web.c##
+        }## 35 ##src/nonblock/web.c##
+
+        rs = rset;## 36 ##src/nonblock/web.c##
+        ws = wset;## 37 ##src/nonblock/web.c##
+        n = Select(maxfd + 1, &rs, &ws, NULL, NULL);## 38 ##src/nonblock/web.c##
+
+        for (i = 0; i < nfiles; i++) {## 39 ##src/nonblock/web.c##
+            flags = file[i].f_flags;## 40 ##src/nonblock/web.c##
+            if (flags == 0 || flags & F_DONE)## 41 ##src/nonblock/web.c##
+                continue;## 42 ##src/nonblock/web.c##
+            fd = file[i].f_fd;## 43 ##src/nonblock/web.c##
+            if (flags & F_CONNECTING &&## 44 ##src/nonblock/web.c##
+                (FD_ISSET(fd, &rs) || FD_ISSET(fd, &ws))) {## 45 ##src/nonblock/web.c##
+                n = sizeof(error);## 46 ##src/nonblock/web.c##
+                if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &n) < 0 ||## 47 ##src/nonblock/web.c##
+                    error != 0) {## 48 ##src/nonblock/web.c##
+                    err_ret("nonblocking connect failed for %s",## 49 ##src/nonblock/web.c##
+                            file[i].f_name);## 50 ##src/nonblock/web.c##
+                }## 51 ##src/nonblock/web.c##
+                /* 4connection established */## 52 ##src/nonblock/web.c##
+                printf("connection established for %s\n", file[i].f_name);## 53 ##src/nonblock/web.c##
+                FD_CLR(fd, &wset);  /* no more writeability test */## 54 ##src/nonblock/web.c##
+                write_get_cmd(&file[i]);    /* write() the GET command */## 55 ##src/nonblock/web.c##
+
+            } else if (flags & F_READING && FD_ISSET(fd, &rs)) {## 56 ##src/nonblock/web.c##
+                if ((n = Read(fd, buf, sizeof(buf))) == 0) {## 57 ##src/nonblock/web.c##
+                    printf("end-of-file on %s\n", file[i].f_name);## 58 ##src/nonblock/web.c##
+                    Close(fd);## 59 ##src/nonblock/web.c##
+                    file[i].f_flags = F_DONE;   /* clears F_READING */## 60 ##src/nonblock/web.c##
+                    FD_CLR(fd, &rset);## 61 ##src/nonblock/web.c##
+                    nconn--;## 62 ##src/nonblock/web.c##
+                    nlefttoread--;## 63 ##src/nonblock/web.c##
+                } else {## 64 ##src/nonblock/web.c##
+                    printf("read %d bytes from %s\n", n, file[i].f_name);## 65 ##src/nonblock/web.c##
+                }## 66 ##src/nonblock/web.c##
+            }## 67 ##src/nonblock/web.c##
+        }## 68 ##src/nonblock/web.c##
+    }## 69 ##src/nonblock/web.c##
+    exit(0);## 70 ##src/nonblock/web.c##
+}## 71 ##src/nonblock/web.c##
+/* end web2 */
diff --git a/nonblock/write_get_cmd.c b/nonblock/write_get_cmd.c
new file mode 100644 (file)
index 0000000..e93da3f
--- /dev/null
@@ -0,0 +1,18 @@
+#include       "web.h"
+
+void
+write_get_cmd(struct file *fptr)
+{
+       int             n;
+       char    line[MAXLINE];
+
+       n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name);
+       Writen(fptr->f_fd, line, n);
+       printf("wrote %d bytes for %s\n", n, fptr->f_name);
+
+       fptr->f_flags = F_READING;                      /* clears F_CONNECTING */
+
+       FD_SET(fptr->f_fd, &rset);                      /* will read server's reply */
+       if (fptr->f_fd > maxfd)
+               maxfd = fptr->f_fd;
+}
diff --git a/oob/Makefile b/oob/Makefile
new file mode 100644 (file)
index 0000000..7abc621
--- /dev/null
@@ -0,0 +1,56 @@
+include ../Make.defines
+
+# XXX get autoconf to put tcprecv03p in here if the system supports poll
+PROGS =        tcprecv01 tcprecv02 tcprecv03 tcprecv04 tcprecv05 tcprecv06 \
+        tcpsend01 tcpsend02 tcpsend03 tcpsend04 tcpsend05 tcpsend06 \
+        tcpcli02 tcpserv02
+
+all:   ${PROGS}
+
+tcprecv01:     tcprecv01.o
+               ${CC} ${CFLAGS} -o $@ tcprecv01.o ${LIBS}
+
+tcpsend01:     tcpsend01.o
+               ${CC} ${CFLAGS} -o $@ tcpsend01.o ${LIBS}
+
+tcprecv02:     tcprecv02.o
+               ${CC} ${CFLAGS} -o $@ tcprecv02.o ${LIBS}
+
+tcpsend02:     tcpsend02.o
+               ${CC} ${CFLAGS} -o $@ tcpsend02.o ${LIBS}
+
+tcprecv03:     tcprecv03.o
+               ${CC} ${CFLAGS} -o $@ tcprecv03.o ${LIBS}
+
+tcprecv03p:    tcprecv03p.o
+               ${CC} ${CFLAGS} -o $@ tcprecv03p.o ${LIBS}
+
+tcpsend03:     tcpsend03.o
+               ${CC} ${CFLAGS} -o $@ tcpsend03.o ${LIBS}
+
+tcprecv04:     tcprecv04.o
+               ${CC} ${CFLAGS} -o $@ tcprecv04.o ${LIBS}
+
+tcpsend04:     tcpsend04.o
+               ${CC} ${CFLAGS} -o $@ tcpsend04.o ${LIBS}
+
+tcprecv05:     tcprecv05.o
+               ${CC} ${CFLAGS} -o $@ tcprecv05.o ${LIBS}
+
+tcpsend05:     tcpsend05.o
+               ${CC} ${CFLAGS} -o $@ tcpsend05.o ${LIBS}
+
+tcprecv06:     tcprecv06.o
+               ${CC} ${CFLAGS} -o $@ tcprecv06.o ${LIBS}
+
+tcpsend06:     tcpsend06.o
+               ${CC} ${CFLAGS} -o $@ tcpsend06.o ${LIBS}
+
+tcpcli02:      tcpcli02.o strcliselect02.o heartbeatcli.o
+               ${CC} ${CFLAGS} -o $@ tcpcli02.o strcliselect02.o heartbeatcli.o ${LIBS}
+
+tcpserv02:     tcpserv02.o strecho02.o heartbeatserv.o sigchldwaitpid.o
+               ${CC} ${CFLAGS} -o $@ tcpserv02.o strecho02.o heartbeatserv.o sigchldwaitpid.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/oob/heartbeatcli.c b/oob/heartbeatcli.c
new file mode 100644 (file)
index 0000000..d1458b3
--- /dev/null
@@ -0,0 +1,50 @@
+#include       "unp.h"
+
+static int             servfd;
+static int             nsec;                   /* #seconds betweeen each alarm */
+static int             maxnprobes;             /* #probes w/no response before quit */
+static int             nprobes;                /* #probes since last server response */
+static void    sig_urg(int), sig_alrm(int);
+
+void
+heartbeat_cli(int servfd_arg, int nsec_arg, int maxnprobes_arg)
+{
+       servfd = servfd_arg;            /* set globals for signal handlers */
+       if ( (nsec = nsec_arg) < 1)
+               nsec = 1;
+       if ( (maxnprobes = maxnprobes_arg) < nsec)
+               maxnprobes = nsec;
+       nprobes = 0;
+
+       Signal(SIGURG, sig_urg);
+       Fcntl(servfd, F_SETOWN, getpid());
+
+       Signal(SIGALRM, sig_alrm);
+       alarm(nsec);
+}
+
+static void
+sig_urg(int signo)
+{
+       int             n;
+       char    c;
+       if ( (n = recv(servfd, &c, 1, MSG_OOB)) < 0) {
+               if (errno != EWOULDBLOCK)
+                       err_sys("recv error");
+       }
+       nprobes = 0;                    /* reset counter */
+       return;                                 /* may interrupt client code */
+}
+
+static void
+sig_alrm(int signo)
+{
+       if (++nprobes > maxnprobes) {
+               fprintf(stderr, "server is unreachable\n");
+               exit(0);
+       }
+       Send(servfd, "1", 1, MSG_OOB);
+       alarm(nsec);
+       return;                                 /* may interrupt client code */
+}
diff --git a/oob/heartbeatserv.c b/oob/heartbeatserv.c
new file mode 100644 (file)
index 0000000..fc7b2a7
--- /dev/null
@@ -0,0 +1,50 @@
+#include       "unp.h"
+
+static int     servfd;
+static int     nsec;                   /* #seconds between each alarm */
+static int     maxnalarms;             /* #alarms w/no client probe before quit */
+static int     nprobes;                /* #alarms since last client probe */
+static void    sig_urg(int), sig_alrm(int);
+
+void
+heartbeat_serv(int servfd_arg, int nsec_arg, int maxnalarms_arg)
+{
+       servfd = servfd_arg;            /* set globals for signal handlers */
+       if ( (nsec = nsec_arg) < 1)
+               nsec = 1;
+       if ( (maxnalarms = maxnalarms_arg) < nsec)
+               maxnalarms = nsec;
+
+       Signal(SIGURG, sig_urg);
+       Fcntl(servfd, F_SETOWN, getpid());
+
+       Signal(SIGALRM, sig_alrm);
+       alarm(nsec);
+}
+
+static void
+sig_urg(int signo)
+{
+       int             n;
+       char    c;
+       if ( (n = recv(servfd, &c, 1, MSG_OOB)) < 0) {
+               if (errno != EWOULDBLOCK)
+                       err_sys("recv error");
+       }
+       Send(servfd, &c, 1, MSG_OOB);   /* echo back out-of-band byte */
+
+       nprobes = 0;                    /* reset counter */
+       return;                                 /* may interrupt server code */
+}
+
+static void
+sig_alrm(int signo)
+{
+       if (++nprobes > maxnalarms) {
+               printf("no probes from client\n");
+               exit(0);
+       }
+       alarm(nsec);
+       return;                                 /* may interrupt server code */
+}
diff --git a/oob/sigchldwaitpid.c b/oob/sigchldwaitpid.c
new file mode 100644 (file)
index 0000000..5fa9cbf
--- /dev/null
@@ -0,0 +1,13 @@
+#include       "unp.h"
+
+void
+sig_chld(int signo)
+{
+       pid_t   pid;
+       int             stat;
+
+       while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) {
+               printf("child %d terminated\n", pid);
+       }
+       return;
+}
diff --git a/oob/strcliselect02.c b/oob/strcliselect02.c
new file mode 100644 (file)
index 0000000..1b8d9c3
--- /dev/null
@@ -0,0 +1,48 @@
+#include       "unp.h"
+
+void
+str_cli(FILE *fp, int sockfd)
+{
+       int                     maxfdp1, stdineof = 0;
+       fd_set          rset;
+       char            sendline[MAXLINE], recvline[MAXLINE];
+
+       heartbeat_cli(sockfd, 1, 5);
+
+       FD_ZERO(&rset);
+       for ( ; ; ) {
+               if (stdineof == 0)
+                       FD_SET(fileno(fp), &rset);
+               FD_SET(sockfd, &rset);
+               maxfdp1 = max(fileno(fp), sockfd) + 1;
+               if (select(maxfdp1, &rset, NULL, NULL, NULL) < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       else
+                               err_sys("select error");
+               }
+
+               if (FD_ISSET(sockfd, &rset)) {  /* socket is readable */
+                       if (Readline(sockfd, recvline, MAXLINE) == 0) {
+                               if (stdineof == 1)
+                                       return;         /* normal termination */
+                               else
+                                       err_quit("str_cli: server terminated prematurely");
+                       }
+
+                       Writen(STDOUT_FILENO, recvline, strlen(recvline));
+               }
+
+               if (FD_ISSET(fileno(fp), &rset)) {  /* input is readable */
+                       if (Fgets(sendline, MAXLINE, fp) == NULL) {
+                               stdineof = 1;
+                               alarm(0);                       /* turn off heartbeat */
+                               Shutdown(sockfd, SHUT_WR);      /* send FIN */
+                               FD_CLR(fileno(fp), &rset);
+                               continue;
+                       }
+
+                       Writen(sockfd, sendline, strlen(sendline));
+               }
+       }
+}
diff --git a/oob/strecho02.c b/oob/strecho02.c
new file mode 100644 (file)
index 0000000..d3c2b6d
--- /dev/null
@@ -0,0 +1,17 @@
+#include       "unp.h"
+
+void
+str_echo(int sockfd)
+{
+       ssize_t         n;
+       char            line[MAXLINE];
+
+       heartbeat_serv(sockfd, 1, 5);
+
+       for ( ; ; ) {
+               if ( (n = Readline(sockfd, line, MAXLINE)) == 0)
+                       return;         /* connection closed by other end */
+
+               Writen(sockfd, line, n);
+       }
+}
diff --git a/oob/tcpcli02.c b/oob/tcpcli02.c
new file mode 100644 (file)
index 0000000..af1f1bf
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/oob/tcprecv01.c b/oob/tcprecv01.c
new file mode 100644 (file)
index 0000000..f41a0db
--- /dev/null
@@ -0,0 +1,45 @@
+#include       "unp.h"
+
+int            listenfd, connfd;
+
+void   sig_urg(int);
+
+int
+main(int argc, char **argv)
+{
+       int             n;
+       char    buff[100];
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], NULL);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], NULL);
+       else
+               err_quit("usage: tcprecv01 [ <host> ] <port#>");
+
+       connfd = Accept(listenfd, NULL, NULL);
+
+       Signal(SIGURG, sig_urg);
+       Fcntl(connfd, F_SETOWN, getpid());
+
+       for ( ; ; ) {
+               if ( (n = Read(connfd, buff, sizeof(buff)-1)) == 0) {
+                       printf("received EOF\n");
+                       exit(0);
+               }
+               buff[n] = 0;    /* null terminate */
+               printf("read %d bytes: %s\n", n, buff);
+       }
+}
+
+void
+sig_urg(int signo)
+{
+       int             n;
+       char    buff[100];
+
+       printf("SIGURG received\n");
+       n = Recv(connfd, buff, sizeof(buff)-1, MSG_OOB);
+       buff[n] = 0;            /* null terminate */
+       printf("read %d OOB byte: %s\n", n, buff);
+}
diff --git a/oob/tcprecv01.lc b/oob/tcprecv01.lc
new file mode 100644 (file)
index 0000000..ded74d4
--- /dev/null
@@ -0,0 +1,45 @@
+#include    "unp.h"##  1 ##src/oob/tcprecv01.c##
+
+int     listenfd, connfd;##  2 ##src/oob/tcprecv01.c##
+
+void    sig_urg(int);##  3 ##src/oob/tcprecv01.c##
+
+int##  4 ##src/oob/tcprecv01.c##
+main(int argc, char **argv)##  5 ##src/oob/tcprecv01.c##
+{##  6 ##src/oob/tcprecv01.c##
+    int     n;##  7 ##src/oob/tcprecv01.c##
+    char    buff[100];##  8 ##src/oob/tcprecv01.c##
+
+    if (argc == 2)##  9 ##src/oob/tcprecv01.c##
+        listenfd = Tcp_listen(NULL, argv[1], NULL);## 10 ##src/oob/tcprecv01.c##
+    else if (argc == 3)## 11 ##src/oob/tcprecv01.c##
+        listenfd = Tcp_listen(argv[1], argv[2], NULL);## 12 ##src/oob/tcprecv01.c##
+    else## 13 ##src/oob/tcprecv01.c##
+        err_quit("usage: tcprecv01 [ <host> ] <port#>");## 14 ##src/oob/tcprecv01.c##
+
+    connfd = Accept(listenfd, NULL, NULL);## 15 ##src/oob/tcprecv01.c##
+
+    Signal(SIGURG, sig_urg);## 16 ##src/oob/tcprecv01.c##
+    Fcntl(connfd, F_SETOWN, getpid());## 17 ##src/oob/tcprecv01.c##
+
+    for (;;) {## 18 ##src/oob/tcprecv01.c##
+        if ((n = Read(connfd, buff, sizeof(buff) - 1)) == 0) {## 19 ##src/oob/tcprecv01.c##
+            printf("received EOF\n");## 20 ##src/oob/tcprecv01.c##
+            exit(0);## 21 ##src/oob/tcprecv01.c##
+        }## 22 ##src/oob/tcprecv01.c##
+        buff[n] = 0;            /* null terminate */## 23 ##src/oob/tcprecv01.c##
+        printf("read %d bytes: %s\n", n, buff);## 24 ##src/oob/tcprecv01.c##
+    }## 25 ##src/oob/tcprecv01.c##
+}## 26 ##src/oob/tcprecv01.c##
+
+void## 27 ##src/oob/tcprecv01.c##
+sig_urg(int signo)## 28 ##src/oob/tcprecv01.c##
+{## 29 ##src/oob/tcprecv01.c##
+    int     n;## 30 ##src/oob/tcprecv01.c##
+    char    buff[100];## 31 ##src/oob/tcprecv01.c##
+
+    printf("SIGURG received\n");## 32 ##src/oob/tcprecv01.c##
+    n = Recv(connfd, buff, sizeof(buff) - 1, MSG_OOB);## 33 ##src/oob/tcprecv01.c##
+    buff[n] = 0;                /* null terminate */## 34 ##src/oob/tcprecv01.c##
+    printf("read %d OOB byte: %s\n", n, buff);## 35 ##src/oob/tcprecv01.c##
+}## 36 ##src/oob/tcprecv01.c##
diff --git a/oob/tcprecv02.c b/oob/tcprecv02.c
new file mode 100644 (file)
index 0000000..7b18d93
--- /dev/null
@@ -0,0 +1,42 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             listenfd, connfd, n;
+       char    buff[100];
+       fd_set  rset, xset;
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], NULL);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], NULL);
+       else
+               err_quit("usage: tcprecv02 [ <host> ] <port#>");
+
+       connfd = Accept(listenfd, NULL, NULL);
+
+       FD_ZERO(&rset);
+       FD_ZERO(&xset);
+       for ( ; ; ) {
+               FD_SET(connfd, &rset);
+               FD_SET(connfd, &xset);
+
+               Select(connfd + 1, &rset, NULL, &xset, NULL);
+
+               if (FD_ISSET(connfd, &xset)) {
+                       n = Recv(connfd, buff, sizeof(buff)-1, MSG_OOB);
+                       buff[n] = 0;            /* null terminate */
+                       printf("read %d OOB byte: %s\n", n, buff);
+               }
+
+               if (FD_ISSET(connfd, &rset)) {
+                       if ( (n = Read(connfd, buff, sizeof(buff)-1)) == 0) {
+                               printf("received EOF\n");
+                               exit(0);
+                       }
+                       buff[n] = 0;    /* null terminate */
+                       printf("read %d bytes: %s\n", n, buff);
+               }
+       }
+}
diff --git a/oob/tcprecv02.lc b/oob/tcprecv02.lc
new file mode 100644 (file)
index 0000000..c573406
--- /dev/null
@@ -0,0 +1,42 @@
+#include    "unp.h"##  1 ##src/oob/tcprecv02.c##
+
+int##  2 ##src/oob/tcprecv02.c##
+main(int argc, char **argv)##  3 ##src/oob/tcprecv02.c##
+{##  4 ##src/oob/tcprecv02.c##
+    int     listenfd, connfd, n;##  5 ##src/oob/tcprecv02.c##
+    char    buff[100];##  6 ##src/oob/tcprecv02.c##
+    fd_set  rset, xset;##  7 ##src/oob/tcprecv02.c##
+
+    if (argc == 2)##  8 ##src/oob/tcprecv02.c##
+        listenfd = Tcp_listen(NULL, argv[1], NULL);##  9 ##src/oob/tcprecv02.c##
+    else if (argc == 3)## 10 ##src/oob/tcprecv02.c##
+        listenfd = Tcp_listen(argv[1], argv[2], NULL);## 11 ##src/oob/tcprecv02.c##
+    else## 12 ##src/oob/tcprecv02.c##
+        err_quit("usage: tcprecv02 [ <host> ] <port#>");## 13 ##src/oob/tcprecv02.c##
+
+    connfd = Accept(listenfd, NULL, NULL);## 14 ##src/oob/tcprecv02.c##
+
+    FD_ZERO(&rset);## 15 ##src/oob/tcprecv02.c##
+    FD_ZERO(&xset);## 16 ##src/oob/tcprecv02.c##
+    for (;;) {## 17 ##src/oob/tcprecv02.c##
+        FD_SET(connfd, &rset);## 18 ##src/oob/tcprecv02.c##
+        FD_SET(connfd, &xset);## 19 ##src/oob/tcprecv02.c##
+
+        Select(connfd + 1, &rset, NULL, &xset, NULL);## 20 ##src/oob/tcprecv02.c##
+
+        if (FD_ISSET(connfd, &xset)) {## 21 ##src/oob/tcprecv02.c##
+            n = Recv(connfd, buff, sizeof(buff) - 1, MSG_OOB);## 22 ##src/oob/tcprecv02.c##
+            buff[n] = 0;        /* null terminate */## 23 ##src/oob/tcprecv02.c##
+            printf("read %d OOB byte: %s\n", n, buff);## 24 ##src/oob/tcprecv02.c##
+        }## 25 ##src/oob/tcprecv02.c##
+
+        if (FD_ISSET(connfd, &rset)) {## 26 ##src/oob/tcprecv02.c##
+            if ((n = Read(connfd, buff, sizeof(buff) - 1)) == 0) {## 27 ##src/oob/tcprecv02.c##
+                printf("received EOF\n");## 28 ##src/oob/tcprecv02.c##
+                exit(0);## 29 ##src/oob/tcprecv02.c##
+            }## 30 ##src/oob/tcprecv02.c##
+            buff[n] = 0;        /* null terminate */## 31 ##src/oob/tcprecv02.c##
+            printf("read %d bytes: %s\n", n, buff);## 32 ##src/oob/tcprecv02.c##
+        }## 33 ##src/oob/tcprecv02.c##
+    }## 34 ##src/oob/tcprecv02.c##
+}## 35 ##src/oob/tcprecv02.c##
diff --git a/oob/tcprecv03.c b/oob/tcprecv03.c
new file mode 100644 (file)
index 0000000..4a686d4
--- /dev/null
@@ -0,0 +1,46 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             listenfd, connfd, n, justreadoob = 0;
+       char    buff[100];
+       fd_set  rset, xset;
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], NULL);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], NULL);
+       else
+               err_quit("usage: tcprecv03 [ <host> ] <port#>");
+
+       connfd = Accept(listenfd, NULL, NULL);
+
+       FD_ZERO(&rset);
+       FD_ZERO(&xset);
+       for ( ; ; ) {
+               FD_SET(connfd, &rset);
+               if (justreadoob == 0)
+                       FD_SET(connfd, &xset);
+
+               Select(connfd + 1, &rset, NULL, &xset, NULL);
+
+               if (FD_ISSET(connfd, &xset)) {
+                       n = Recv(connfd, buff, sizeof(buff)-1, MSG_OOB);
+                       buff[n] = 0;            /* null terminate */
+                       printf("read %d OOB byte: %s\n", n, buff);
+                       justreadoob = 1;
+                       FD_CLR(connfd, &xset);
+               }
+
+               if (FD_ISSET(connfd, &rset)) {
+                       if ( (n = Read(connfd, buff, sizeof(buff)-1)) == 0) {
+                               printf("received EOF\n");
+                               exit(0);
+                       }
+                       buff[n] = 0;    /* null terminate */
+                       printf("read %d bytes: %s\n", n, buff);
+                       justreadoob = 0;
+               }
+       }
+}
diff --git a/oob/tcprecv03p.c b/oob/tcprecv03p.c
new file mode 100644 (file)
index 0000000..a059947
--- /dev/null
@@ -0,0 +1,45 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             listenfd, connfd, n, justreadoob = 0;
+       char    buff[100];
+       struct pollfd   pollfd[1];
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], NULL);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], NULL);
+       else
+               err_quit("usage: tcprecv03p [ <host> ] <port#>");
+
+       connfd = Accept(listenfd, NULL, NULL);
+
+       pollfd[0].fd = connfd;
+       pollfd[0].events = POLLRDNORM;
+       for ( ; ; ) {
+               if (justreadoob == 0)
+                       pollfd[0].events |= POLLRDBAND;
+
+               Poll(pollfd, 1, INFTIM);
+
+               if (pollfd[0].revents & POLLRDBAND) {
+                       n = Recv(connfd, buff, sizeof(buff)-1, MSG_OOB);
+                       buff[n] = 0;            /* null terminate */
+                       printf("read %d OOB byte: %s\n", n, buff);
+                       justreadoob = 1;
+                       pollfd[0].events &= ~POLLRDBAND;        /* turn bit off */
+               }
+
+               if (pollfd[0].revents & POLLRDNORM) {
+                       if ( (n = Read(connfd, buff, sizeof(buff)-1)) == 0) {
+                               printf("received EOF\n");
+                               exit(0);
+                       }
+                       buff[n] = 0;    /* null terminate */
+                       printf("read %d bytes: %s\n", n, buff);
+                       justreadoob = 0;
+               }
+       }
+}
diff --git a/oob/tcprecv03p.lc b/oob/tcprecv03p.lc
new file mode 100644 (file)
index 0000000..698b47c
--- /dev/null
@@ -0,0 +1,45 @@
+#include    "unp.h"##  1 ##src/oob/tcprecv03p.c##
+
+int##  2 ##src/oob/tcprecv03p.c##
+main(int argc, char **argv)##  3 ##src/oob/tcprecv03p.c##
+{##  4 ##src/oob/tcprecv03p.c##
+    int     listenfd, connfd, n, justreadoob = 0;##  5 ##src/oob/tcprecv03p.c##
+    char    buff[100];##  6 ##src/oob/tcprecv03p.c##
+    struct pollfd pollfd[1];##  7 ##src/oob/tcprecv03p.c##
+
+    if (argc == 2)##  8 ##src/oob/tcprecv03p.c##
+        listenfd = Tcp_listen(NULL, argv[1], NULL);##  9 ##src/oob/tcprecv03p.c##
+    else if (argc == 3)## 10 ##src/oob/tcprecv03p.c##
+        listenfd = Tcp_listen(argv[1], argv[2], NULL);## 11 ##src/oob/tcprecv03p.c##
+    else## 12 ##src/oob/tcprecv03p.c##
+        err_quit("usage: tcprecv03p [ <host> ] <port#>");## 13 ##src/oob/tcprecv03p.c##
+
+    connfd = Accept(listenfd, NULL, NULL);## 14 ##src/oob/tcprecv03p.c##
+
+    pollfd[0].fd = connfd;## 15 ##src/oob/tcprecv03p.c##
+    pollfd[0].events = POLLRDNORM;## 16 ##src/oob/tcprecv03p.c##
+    for (;;) {## 17 ##src/oob/tcprecv03p.c##
+        if (justreadoob == 0)## 18 ##src/oob/tcprecv03p.c##
+            pollfd[0].events |= POLLRDBAND;## 19 ##src/oob/tcprecv03p.c##
+
+        Poll(pollfd, 1, INFTIM);## 20 ##src/oob/tcprecv03p.c##
+
+        if (pollfd[0].revents & POLLRDBAND) {## 21 ##src/oob/tcprecv03p.c##
+            n = Recv(connfd, buff, sizeof(buff) - 1, MSG_OOB);## 22 ##src/oob/tcprecv03p.c##
+            buff[n] = 0;        /* null terminate */## 23 ##src/oob/tcprecv03p.c##
+            printf("read %d OOB byte: %s\n", n, buff);## 24 ##src/oob/tcprecv03p.c##
+            justreadoob = 1;## 25 ##src/oob/tcprecv03p.c##
+            pollfd[0].events &= ~POLLRDBAND;    /* turn bit off */## 26 ##src/oob/tcprecv03p.c##
+        }## 27 ##src/oob/tcprecv03p.c##
+
+        if (pollfd[0].revents & POLLRDNORM) {## 28 ##src/oob/tcprecv03p.c##
+            if ((n = Read(connfd, buff, sizeof(buff) - 1)) == 0) {## 29 ##src/oob/tcprecv03p.c##
+                printf("received EOF\n");## 30 ##src/oob/tcprecv03p.c##
+                exit(0);## 31 ##src/oob/tcprecv03p.c##
+            }## 32 ##src/oob/tcprecv03p.c##
+            buff[n] = 0;        /* null terminate */## 33 ##src/oob/tcprecv03p.c##
+            printf("read %d bytes: %s\n", n, buff);## 34 ##src/oob/tcprecv03p.c##
+            justreadoob = 0;## 35 ##src/oob/tcprecv03p.c##
+        }## 36 ##src/oob/tcprecv03p.c##
+    }## 37 ##src/oob/tcprecv03p.c##
+}## 38 ##src/oob/tcprecv03p.c##
diff --git a/oob/tcprecv04.c b/oob/tcprecv04.c
new file mode 100644 (file)
index 0000000..ac823bf
--- /dev/null
@@ -0,0 +1,32 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             listenfd, connfd, n, on=1;
+       char    buff[100];
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], NULL);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], NULL);
+       else
+               err_quit("usage: tcprecv04 [ <host> ] <port#>");
+
+       Setsockopt(listenfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on));
+
+       connfd = Accept(listenfd, NULL, NULL);
+       sleep(5);
+
+       for ( ; ; ) {
+               if (Sockatmark(connfd))
+                       printf("at OOB mark\n");
+
+               if ( (n = Read(connfd, buff, sizeof(buff)-1)) == 0) {
+                       printf("received EOF\n");
+                       exit(0);
+               }
+               buff[n] = 0;    /* null terminate */
+               printf("read %d bytes: %s\n", n, buff);
+       }
+}
diff --git a/oob/tcprecv04.lc b/oob/tcprecv04.lc
new file mode 100644 (file)
index 0000000..8a879c4
--- /dev/null
@@ -0,0 +1,32 @@
+#include    "unp.h"##  1 ##src/oob/tcprecv04.c##
+
+int##  2 ##src/oob/tcprecv04.c##
+main(int argc, char **argv)##  3 ##src/oob/tcprecv04.c##
+{##  4 ##src/oob/tcprecv04.c##
+    int     listenfd, connfd, n, on = 1;##  5 ##src/oob/tcprecv04.c##
+    char    buff[100];##  6 ##src/oob/tcprecv04.c##
+
+    if (argc == 2)##  7 ##src/oob/tcprecv04.c##
+        listenfd = Tcp_listen(NULL, argv[1], NULL);##  8 ##src/oob/tcprecv04.c##
+    else if (argc == 3)##  9 ##src/oob/tcprecv04.c##
+        listenfd = Tcp_listen(argv[1], argv[2], NULL);## 10 ##src/oob/tcprecv04.c##
+    else## 11 ##src/oob/tcprecv04.c##
+        err_quit("usage: tcprecv04 [ <host> ] <port#>");## 12 ##src/oob/tcprecv04.c##
+
+    Setsockopt(listenfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on));## 13 ##src/oob/tcprecv04.c##
+
+    connfd = Accept(listenfd, NULL, NULL);## 14 ##src/oob/tcprecv04.c##
+    sleep(5);## 15 ##src/oob/tcprecv04.c##
+
+    for (;;) {## 16 ##src/oob/tcprecv04.c##
+        if (Sockatmark(connfd))## 17 ##src/oob/tcprecv04.c##
+            printf("at OOB mark\n");## 18 ##src/oob/tcprecv04.c##
+
+        if ((n = Read(connfd, buff, sizeof(buff) - 1)) == 0) {## 19 ##src/oob/tcprecv04.c##
+            printf("received EOF\n");## 20 ##src/oob/tcprecv04.c##
+            exit(0);## 21 ##src/oob/tcprecv04.c##
+        }## 22 ##src/oob/tcprecv04.c##
+        buff[n] = 0;            /* null terminate */## 23 ##src/oob/tcprecv04.c##
+        printf("read %d bytes: %s\n", n, buff);## 24 ##src/oob/tcprecv04.c##
+    }## 25 ##src/oob/tcprecv04.c##
+}## 26 ##src/oob/tcprecv04.c##
diff --git a/oob/tcprecv05.c b/oob/tcprecv05.c
new file mode 100644 (file)
index 0000000..9dc185f
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unp.h"
+
+int            listenfd, connfd;
+
+void   sig_urg(int);
+
+int
+main(int argc, char **argv)
+{
+       int             size;
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], NULL);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], NULL);
+       else
+               err_quit("usage: tcprecv05 [ <host> ] <port#>");
+
+       size = 4096;
+       Setsockopt(listenfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
+
+       connfd = Accept(listenfd, NULL, NULL);
+
+       Signal(SIGURG, sig_urg);
+       Fcntl(connfd, F_SETOWN, getpid());
+
+       for ( ; ; )
+               pause();
+}
+
+void
+sig_urg(int signo)
+{
+       int             n;
+       char    buff[2048];
+
+       printf("SIGURG received\n");
+       n = Recv(connfd, buff, sizeof(buff)-1, MSG_OOB);
+       buff[n] = 0;            /* null terminate */
+       printf("read %d OOB byte\n", n);
+}
diff --git a/oob/tcprecv06.c b/oob/tcprecv06.c
new file mode 100644 (file)
index 0000000..756223f
--- /dev/null
@@ -0,0 +1,32 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             listenfd, connfd, n, on=1;
+       char    buff[100];
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], NULL);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], NULL);
+       else
+               err_quit("usage: tcprecv06 [ <host> ] <port#>");
+
+       Setsockopt(listenfd, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on));
+
+       connfd = Accept(listenfd, NULL, NULL);
+       sleep(5);
+
+       for ( ; ; ) {
+               if (Sockatmark(connfd))
+                       printf("at OOB mark\n");
+
+               if ( (n = Read(connfd, buff, sizeof(buff)-1)) == 0) {
+                       printf("received EOF\n");
+                       exit(0);
+               }
+               buff[n] = 0;    /* null terminate */
+               printf("read %d bytes: %s\n", n, buff);
+       }
+}
diff --git a/oob/tcpsend01.c b/oob/tcpsend01.c
new file mode 100644 (file)
index 0000000..093c834
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             sockfd;
+
+       if (argc != 3)
+               err_quit("usage: tcpsend01 <host> <port#>");
+
+       sockfd = Tcp_connect(argv[1], argv[2]);
+
+       Write(sockfd, "123", 3);
+       printf("wrote 3 bytes of normal data\n");
+       sleep(1);
+
+       Send(sockfd, "4", 1, MSG_OOB);
+       printf("wrote 1 byte of OOB data\n");
+       sleep(1);
+
+       Write(sockfd, "56", 2);
+       printf("wrote 2 bytes of normal data\n");
+       sleep(1);
+
+       Send(sockfd, "7", 1, MSG_OOB);
+       printf("wrote 1 byte of OOB data\n");
+       sleep(1);
+
+       Write(sockfd, "89", 2);
+       printf("wrote 2 bytes of normal data\n");
+       sleep(1);
+
+       exit(0);
+}
diff --git a/oob/tcpsend01.lc b/oob/tcpsend01.lc
new file mode 100644 (file)
index 0000000..7098715
--- /dev/null
@@ -0,0 +1,34 @@
+#include    "unp.h"##  1 ##src/oob/tcpsend01.c##
+
+int##  2 ##src/oob/tcpsend01.c##
+main(int argc, char **argv)##  3 ##src/oob/tcpsend01.c##
+{##  4 ##src/oob/tcpsend01.c##
+    int     sockfd;##  5 ##src/oob/tcpsend01.c##
+
+    if (argc != 3)##  6 ##src/oob/tcpsend01.c##
+        err_quit("usage: tcpsend01 <host> <port#>");##  7 ##src/oob/tcpsend01.c##
+
+    sockfd = Tcp_connect(argv[1], argv[2]);##  8 ##src/oob/tcpsend01.c##
+
+    Write(sockfd, "123", 3);##  9 ##src/oob/tcpsend01.c##
+    printf("wrote 3 bytes of normal data\n");## 10 ##src/oob/tcpsend01.c##
+    sleep(1);## 11 ##src/oob/tcpsend01.c##
+
+    Send(sockfd, "4", 1, MSG_OOB);## 12 ##src/oob/tcpsend01.c##
+    printf("wrote 1 byte of OOB data\n");## 13 ##src/oob/tcpsend01.c##
+    sleep(1);## 14 ##src/oob/tcpsend01.c##
+
+    Write(sockfd, "56", 2);## 15 ##src/oob/tcpsend01.c##
+    printf("wrote 2 bytes of normal data\n");## 16 ##src/oob/tcpsend01.c##
+    sleep(1);## 17 ##src/oob/tcpsend01.c##
+
+    Send(sockfd, "7", 1, MSG_OOB);## 18 ##src/oob/tcpsend01.c##
+    printf("wrote 1 byte of OOB data\n");## 19 ##src/oob/tcpsend01.c##
+    sleep(1);## 20 ##src/oob/tcpsend01.c##
+
+    Write(sockfd, "89", 2);## 21 ##src/oob/tcpsend01.c##
+    printf("wrote 2 bytes of normal data\n");## 22 ##src/oob/tcpsend01.c##
+    sleep(1);## 23 ##src/oob/tcpsend01.c##
+
+    exit(0);## 24 ##src/oob/tcpsend01.c##
+}## 25 ##src/oob/tcpsend01.c##
diff --git a/oob/tcpsend02.c b/oob/tcpsend02.c
new file mode 100644 (file)
index 0000000..d7857fb
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             sockfd;
+
+       if (argc != 3)
+               err_quit("usage: tcpsend02 <host> <port#>");
+
+       sockfd = Tcp_connect(argv[1], argv[2]);
+
+       Write(sockfd, "123", 3);
+       printf("wrote 3 bytes of normal data\n");
+       sleep(1);
+
+       Send(sockfd, "4", 1, MSG_OOB);
+       printf("wrote 1 byte of OOB data\n");
+       sleep(1);
+
+       Write(sockfd, "56", 2);
+       printf("wrote 2 bytes of normal data\n");
+       sleep(1);
+
+       Send(sockfd, "7", 1, MSG_OOB);
+       printf("wrote 1 byte of OOB data\n");
+       sleep(1);
+
+       Write(sockfd, "89", 2);
+       printf("wrote 2 bytes of normal data\n");
+       sleep(1);
+
+       exit(0);
+}
diff --git a/oob/tcpsend03.c b/oob/tcpsend03.c
new file mode 100644 (file)
index 0000000..8b397f4
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             sockfd;
+
+       if (argc != 3)
+               err_quit("usage: tcpsend03 <host> <port#>");
+
+       sockfd = Tcp_connect(argv[1], argv[2]);
+
+       Write(sockfd, "123", 3);
+       printf("wrote 3 bytes of normal data\n");
+       sleep(1);
+
+       Send(sockfd, "4", 1, MSG_OOB);
+       printf("wrote 1 byte of OOB data\n");
+       sleep(1);
+
+       Write(sockfd, "56", 2);
+       printf("wrote 2 bytes of normal data\n");
+       sleep(1);
+
+       Send(sockfd, "7", 1, MSG_OOB);
+       printf("wrote 1 byte of OOB data\n");
+       sleep(1);
+
+       Write(sockfd, "89", 2);
+       printf("wrote 2 bytes of normal data\n");
+       sleep(1);
+
+       exit(0);
+}
diff --git a/oob/tcpsend04.c b/oob/tcpsend04.c
new file mode 100644 (file)
index 0000000..962b880
--- /dev/null
@@ -0,0 +1,23 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             sockfd;
+
+       if (argc != 3)
+               err_quit("usage: tcpsend04 <host> <port#>");
+
+       sockfd = Tcp_connect(argv[1], argv[2]);
+
+       Write(sockfd, "123", 3);
+       printf("wrote 3 bytes of normal data\n");
+
+       Send(sockfd, "4", 1, MSG_OOB);
+       printf("wrote 1 byte of OOB data\n");
+
+       Write(sockfd, "5", 1);
+       printf("wrote 1 byte of normal data\n");
+
+       exit(0);
+}
diff --git a/oob/tcpsend04.lc b/oob/tcpsend04.lc
new file mode 100644 (file)
index 0000000..e3185c8
--- /dev/null
@@ -0,0 +1,23 @@
+#include    "unp.h"##  1 ##src/oob/tcpsend04.c##
+
+int##  2 ##src/oob/tcpsend04.c##
+main(int argc, char **argv)##  3 ##src/oob/tcpsend04.c##
+{##  4 ##src/oob/tcpsend04.c##
+    int     sockfd;##  5 ##src/oob/tcpsend04.c##
+
+    if (argc != 3)##  6 ##src/oob/tcpsend04.c##
+        err_quit("usage: tcpsend04 <host> <port#>");##  7 ##src/oob/tcpsend04.c##
+
+    sockfd = Tcp_connect(argv[1], argv[2]);##  8 ##src/oob/tcpsend04.c##
+
+    Write(sockfd, "123", 3);##  9 ##src/oob/tcpsend04.c##
+    printf("wrote 3 bytes of normal data\n");## 10 ##src/oob/tcpsend04.c##
+
+    Send(sockfd, "4", 1, MSG_OOB);## 11 ##src/oob/tcpsend04.c##
+    printf("wrote 1 byte of OOB data\n");## 12 ##src/oob/tcpsend04.c##
+
+    Write(sockfd, "5", 1);## 13 ##src/oob/tcpsend04.c##
+    printf("wrote 1 byte of normal data\n");## 14 ##src/oob/tcpsend04.c##
+
+    exit(0);## 15 ##src/oob/tcpsend04.c##
+}## 16 ##src/oob/tcpsend04.c##
diff --git a/oob/tcpsend05.c b/oob/tcpsend05.c
new file mode 100644 (file)
index 0000000..225d886
--- /dev/null
@@ -0,0 +1,28 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             sockfd, size;
+       char    buff[16384];
+
+       if (argc != 3)
+               err_quit("usage: tcpsend05 <host> <port#>");
+
+       sockfd = Tcp_connect(argv[1], argv[2]);
+
+       size = 32768;
+       Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
+
+       Write(sockfd, buff, 16384);
+       printf("wrote 16384 bytes of normal data\n");
+       sleep(5);
+
+       Send(sockfd, "a", 1, MSG_OOB);
+       printf("wrote 1 byte of OOB data\n");
+
+       Write(sockfd, buff, 1024);
+       printf("wrote 1024 bytes of normal data\n");
+
+       exit(0);
+}
diff --git a/oob/tcpsend05.lc b/oob/tcpsend05.lc
new file mode 100644 (file)
index 0000000..deeed32
--- /dev/null
@@ -0,0 +1,28 @@
+#include    "unp.h"##  1 ##src/oob/tcpsend05.c##
+
+int##  2 ##src/oob/tcpsend05.c##
+main(int argc, char **argv)##  3 ##src/oob/tcpsend05.c##
+{##  4 ##src/oob/tcpsend05.c##
+    int     sockfd, size;##  5 ##src/oob/tcpsend05.c##
+    char    buff[16384];##  6 ##src/oob/tcpsend05.c##
+
+    if (argc != 3)##  7 ##src/oob/tcpsend05.c##
+        err_quit("usage: tcpsend05 <host> <port#>");##  8 ##src/oob/tcpsend05.c##
+
+    sockfd = Tcp_connect(argv[1], argv[2]);##  9 ##src/oob/tcpsend05.c##
+
+    size = 32768;## 10 ##src/oob/tcpsend05.c##
+    Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));## 11 ##src/oob/tcpsend05.c##
+
+    Write(sockfd, buff, 16384);## 12 ##src/oob/tcpsend05.c##
+    printf("wrote 16384 bytes of normal data\n");## 13 ##src/oob/tcpsend05.c##
+    sleep(5);## 14 ##src/oob/tcpsend05.c##
+
+    Send(sockfd, "a", 1, MSG_OOB);## 15 ##src/oob/tcpsend05.c##
+    printf("wrote 1 byte of OOB data\n");## 16 ##src/oob/tcpsend05.c##
+
+    Write(sockfd, buff, 1024);## 17 ##src/oob/tcpsend05.c##
+    printf("wrote 1024 bytes of normal data\n");## 18 ##src/oob/tcpsend05.c##
+
+    exit(0);## 19 ##src/oob/tcpsend05.c##
+}## 20 ##src/oob/tcpsend05.c##
diff --git a/oob/tcpsend06.c b/oob/tcpsend06.c
new file mode 100644 (file)
index 0000000..aa04ae4
--- /dev/null
@@ -0,0 +1,29 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             sockfd;
+
+       if (argc != 3)
+               err_quit("usage: tcpsend06 <host> <port#>");
+
+       sockfd = Tcp_connect(argv[1], argv[2]);
+
+       Write(sockfd, "123", 3);
+       printf("wrote 3 bytes of normal data\n");
+
+       Send(sockfd, "4", 1, MSG_OOB);
+       printf("wrote 1 byte of OOB data\n");
+
+       Write(sockfd, "5", 1);
+       printf("wrote 1 byte of normal data\n");
+
+       Send(sockfd, "6", 1, MSG_OOB);
+       printf("wrote 1 byte of OOB data\n");
+
+       Write(sockfd, "7", 1);
+       printf("wrote 1 byte of normal data\n");
+
+       exit(0);
+}
diff --git a/oob/tcpsend06.lc b/oob/tcpsend06.lc
new file mode 100644 (file)
index 0000000..ee9caa7
--- /dev/null
@@ -0,0 +1,29 @@
+#include    "unp.h"##  1 ##src/oob/tcpsend06.c##
+
+int##  2 ##src/oob/tcpsend06.c##
+main(int argc, char **argv)##  3 ##src/oob/tcpsend06.c##
+{##  4 ##src/oob/tcpsend06.c##
+    int     sockfd;##  5 ##src/oob/tcpsend06.c##
+
+    if (argc != 3)##  6 ##src/oob/tcpsend06.c##
+        err_quit("usage: tcpsend06 <host> <port#>");##  7 ##src/oob/tcpsend06.c##
+
+    sockfd = Tcp_connect(argv[1], argv[2]);##  8 ##src/oob/tcpsend06.c##
+
+    Write(sockfd, "123", 3);##  9 ##src/oob/tcpsend06.c##
+    printf("wrote 3 bytes of normal data\n");## 10 ##src/oob/tcpsend06.c##
+
+    Send(sockfd, "4", 1, MSG_OOB);## 11 ##src/oob/tcpsend06.c##
+    printf("wrote 1 byte of OOB data\n");## 12 ##src/oob/tcpsend06.c##
+
+    Write(sockfd, "5", 1);## 13 ##src/oob/tcpsend06.c##
+    printf("wrote 1 byte of normal data\n");## 14 ##src/oob/tcpsend06.c##
+
+    Send(sockfd, "6", 1, MSG_OOB);## 15 ##src/oob/tcpsend06.c##
+    printf("wrote 1 byte of OOB data\n");## 16 ##src/oob/tcpsend06.c##
+
+    Write(sockfd, "7", 1);## 17 ##src/oob/tcpsend06.c##
+    printf("wrote 1 byte of normal data\n");## 18 ##src/oob/tcpsend06.c##
+
+    exit(0);## 19 ##src/oob/tcpsend06.c##
+}## 20 ##src/oob/tcpsend06.c##
diff --git a/oob/tcpserv02.c b/oob/tcpserv02.c
new file mode 100644 (file)
index 0000000..a964276
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       pid_t                           childpid;
+       socklen_t                       clilen;
+       struct sockaddr_in      cliaddr, servaddr;
+       void                            sig_chld(int);
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       Signal(SIGCHLD, sig_chld);
+
+       for ( ; ; ) {
+               clilen = sizeof(cliaddr);
+               if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
+                       if (errno == EINTR)
+                               continue;               /* back to for() */
+                       else
+                               err_sys("accept error");
+               }
+
+               if ( (childpid = Fork()) == 0) {        /* child process */
+                       Close(listenfd);        /* close listening socket */
+                       str_echo(connfd);       /* process the request */
+                       exit(0);
+               }
+               Close(connfd);                  /* parent closes connected socket */
+       }
+}
diff --git a/ping/Makefile b/ping/Makefile
new file mode 100644 (file)
index 0000000..bf630c8
--- /dev/null
@@ -0,0 +1,13 @@
+include ../Make.defines
+
+OBJS = init_v6.o main.o proc_v4.o proc_v6.o readloop.o \
+               send_v4.o send_v6.o sig_alrm.o tv_sub.o
+PROGS =        ping
+
+all:   ${PROGS}
+
+ping:  ${OBJS}
+               ${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/ping/bsdping.c b/ping/bsdping.c
new file mode 100644 (file)
index 0000000..04d1848
--- /dev/null
@@ -0,0 +1,1009 @@
+/*     BSDI    ping.c,v 2.3 1996/01/21 17:56:50 jch Exp        */
+
+/*
+ * Copyright (c) 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Muuss.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1989, 1993\n\
+       The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)ping.c     8.1 (Berkeley) 6/5/93";
+#endif /* not lint */
+
+/*
+ * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility,
+ * measure round-trip-delays and packet loss across network paths.
+ *
+ * Author -
+ *     Mike Muuss
+ *     U. S. Army Ballistic Research Laboratory
+ *     December, 1983
+ *
+ * Status -
+ *     Public Domain.  Distribution Unlimited.
+ * Bugs -
+ *     More statistics could always be gathered.
+ *     This program has to run SUID to ROOT to access the ICMP socket.
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ip_var.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define        DEFDATALEN      (64 - 8)        /* default data length */
+#define        MAXIPLEN        60
+#define        MAXICMPLEN      76
+#define        MAXPACKET       (65536 - 60 - 8)/* max packet size */
+#define        NROUTES         9               /* number of record route slots */
+
+#define        A(bit)          rcvd_tbl[(bit)>>3]      /* identify byte in array */
+#define        B(bit)          (1 << ((bit) & 0x07))   /* identify bit in byte */
+#define        SET(bit)        (A(bit) |= B(bit))
+#define        CLR(bit)        (A(bit) &= (~B(bit)))
+#define        TST(bit)        (A(bit) & B(bit))
+
+#define        F_FLOOD         0x0001
+#define        F_INTERVAL      0x0002
+#define        F_NUMERIC       0x0004
+#define        F_PINGFILLED    0x0008
+#define        F_QUIET         0x0010
+#define        F_RROUTE        0x0020
+#define        F_SO_DEBUG      0x0040
+#define        F_SO_DONTROUTE  0x0080
+#define        F_VERBOSE       0x0100
+u_int options;
+
+/*
+ * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
+ * number of received sequence numbers we can keep track of.  Change 128
+ * to 8192 for complete accuracy...
+ */
+#define        MAX_DUP_CHK     (8 * 8192)
+int mx_dup_ck = MAX_DUP_CHK;
+char rcvd_tbl[MAX_DUP_CHK / 8];
+
+struct sockaddr whereto;       /* who to ping */
+int datalen = DEFDATALEN;
+int s;                         /* socket file descriptor */
+u_char outpack[MAXPACKET];
+char BSPACE = '\b';            /* characters written for flood */
+char DOT = '.';
+char *hostname;
+int ident;                     /* process id to identify our packets */
+
+/* counters */
+long npackets;                 /* max packets to transmit */
+long nreceived;                        /* # of packets we got back */
+long nrepeats;                 /* number of duplicates */
+long ntransmitted;             /* sequence # for outbound packets = #sent */
+int interval = 1;              /* interval between packets */
+
+/* timing */
+int timing;                    /* flag to do timing */
+double tmin = 999999999.0;     /* minimum round trip time */
+double tmax = 0.0;             /* maximum round trip time */
+double tsum = 0.0;             /* sum of all times, for doing average */
+
+void    fill __P((char *, char *));
+u_short         in_cksum __P((u_short *, int));
+void    onalrm __P((int));
+void    oninfo __P((int));
+void    onint __P((int));
+void    pinger __P((void));
+char   *pr_addr __P((u_long));
+void    pr_icmph __P((struct icmp *));
+void    pr_iph __P((struct ip *));
+void    pr_pack __P((char *, int, struct sockaddr_in *));
+void    pr_retip __P((struct ip *));
+void    summary __P((void));
+void    tvsub __P((struct timeval *, struct timeval *));
+void    usage __P((void));
+
+int
+main(argc, argv)
+       int argc;
+       char *argv[];
+{
+       extern int errno, optind;
+       extern char *optarg;
+       struct hostent *hp;
+       struct itimerval itimer;
+       struct protoent *proto;
+       struct sockaddr_in *to, from;
+       struct timeval timeout;
+       fd_set fdset;
+       register int cc, i;
+       int ch, fromlen, hold, packlen, preload;
+       u_char *datap, *packet;
+       char *e, *target, hnamebuf[MAXHOSTNAMELEN];
+#ifdef IP_OPTIONS
+       char rspace[3 + 4 * NROUTES + 1];       /* record route space */
+#endif
+
+       preload = 0;
+       datap = &outpack[8 + sizeof(struct timeval)];
+       while ((ch = getopt(argc, argv, "c:dfi:l:np:qRrs:v")) != -1)
+               switch(ch) {
+               case 'c':
+                       npackets = strtol(optarg, &e, 10);
+                       if (npackets <= 0 || *optarg == '\0' || *e != '\0')
+                               errx(1,
+                                   "illegal number of packets -- %s", optarg);
+                       break;
+               case 'd':
+                       options |= F_SO_DEBUG;
+                       break;
+               case 'f':
+                       if (getuid()) {
+                               errno = EPERM;
+                               err(1, NULL);
+                       }
+                       options |= F_FLOOD;
+                       setbuf(stdout, (char *)NULL);
+                       break;
+               case 'i':               /* wait between sending packets */
+                       interval = strtol(optarg, &e, 10);
+                       if (interval <= 0 || *optarg == '\0' || *e != '\0')
+                               errx(1,
+                                   "illegal timing interval -- %s", optarg);
+                       options |= F_INTERVAL;
+                       break;
+               case 'l':
+                       preload = strtol(optarg, &e, 10);
+                       if (preload < 0 || *optarg == '\0' || *e != '\0')
+                               errx(1, "illegal preload value -- %s", optarg);
+                       break;
+               case 'n':
+                       options |= F_NUMERIC;
+                       break;
+               case 'p':               /* fill buffer with user pattern */
+                       options |= F_PINGFILLED;
+                       fill((char *)datap, optarg);
+                               break;
+               case 'q':
+                       options |= F_QUIET;
+                       break;
+               case 'R':
+                       options |= F_RROUTE;
+                       break;
+               case 'r':
+                       options |= F_SO_DONTROUTE;
+                       break;
+               case 's':               /* size of packet to send */
+                       datalen = strtol(optarg, &e, 10);
+                       if (datalen <= 0 || *optarg == '\0' || *e != '\0')
+                               errx(1, "illegal datalen value -- %s", optarg);
+                       if (datalen > MAXPACKET)
+                               errx(1,
+                                   "datalen value too large, maximum is %d",
+                                   MAXPACKET);
+                       break;
+               case 'v':
+                       options |= F_VERBOSE;
+                       break;
+               default:
+                       usage();
+               }
+       argc -= optind;
+       argv += optind;
+
+       if (argc != 1)
+               usage();
+       target = *argv;
+
+       memset(&whereto, 0, sizeof(struct sockaddr));
+       to = (struct sockaddr_in *)&whereto;
+       to->sin_family = AF_INET;
+       to->sin_addr.s_addr = inet_addr(target);
+       if (to->sin_addr.s_addr != (u_int)-1)
+               hostname = target;
+       else {
+               hp = gethostbyname(target);
+               if (!hp)
+                       errx(1, "unknown host %s", target);
+               to->sin_family = hp->h_addrtype;
+               memmove(&to->sin_addr, hp->h_addr, hp->h_length);
+               (void)strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1);
+               hostname = hnamebuf;
+       }
+
+       if (options & F_FLOOD && options & F_INTERVAL)
+               errx(1, "-f and -i incompatible options");
+
+       if (datalen >= sizeof(struct timeval))  /* can we time transfer */
+               timing = 1;
+       packlen = datalen + MAXIPLEN + MAXICMPLEN;
+       if (!(packet = (u_char *)malloc((u_int)packlen)))
+               err(1, NULL);
+       if (!(options & F_PINGFILLED))
+               for (i = 8; i < datalen; ++i)
+                       *datap++ = i;
+
+       ident = getpid() & 0xFFFF;
+
+       if (!(proto = getprotobyname("icmp")))
+               errx(1, "unknown protocol icmp");
+       if ((s = socket(AF_INET, SOCK_RAW, proto->p_proto)) < 0)
+               err(1, "socket");
+       hold = 1;
+       if (options & F_SO_DEBUG)
+               (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold,
+                   sizeof(hold));
+       if (options & F_SO_DONTROUTE)
+               (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&hold,
+                   sizeof(hold));
+
+       /* record route option */
+       if (options & F_RROUTE) {
+#ifdef IP_OPTIONS
+               rspace[IPOPT_OPTVAL] = IPOPT_RR;
+               rspace[IPOPT_OLEN] = sizeof(rspace)-1;
+               rspace[IPOPT_OFFSET] = IPOPT_MINOFF;
+               if (setsockopt(s, IPPROTO_IP, IP_OPTIONS, rspace,
+                   sizeof(rspace)) < 0)
+                       err(1, "record route");
+#else
+               errx(1, "record route not available in this implementation");
+#endif
+       }
+
+       /*
+        * When pinging the broadcast address, you can get a lot of answers.
+        * Doing something so evil is useful if you are trying to stress the
+        * ethernet, or just want to fill the arp cache to get some stuff for
+        * /etc/ethers.
+        */
+       hold = 48 * 1024;
+       (void)setsockopt(s,
+           SOL_SOCKET, SO_RCVBUF, (char *)&hold, sizeof(hold));
+
+       if (to->sin_family == AF_INET)
+               (void)printf("PING %s (%s): %d data bytes\n", hostname,
+                   inet_ntoa(*(struct in_addr *)&to->sin_addr.s_addr),
+                   datalen);
+       else
+               (void)printf("PING %s: %d data bytes\n", hostname, datalen);
+
+       while (preload--)               /* Fire off them quickies. */
+               pinger();
+
+       (void)signal(SIGINT, onint);
+       (void)signal(SIGINFO, oninfo);
+
+       if ((options & F_FLOOD) == 0) {
+               (void)signal(SIGALRM, onalrm);
+               itimer.it_interval.tv_sec = interval;
+               itimer.it_interval.tv_usec = 0;
+               itimer.it_value.tv_sec = 0;
+               itimer.it_value.tv_usec = 1;
+               (void)setitimer(ITIMER_REAL, &itimer, NULL);
+       }
+
+       FD_ZERO(&fdset);
+       timeout.tv_sec = 0;
+       timeout.tv_usec = 10000;
+       for (;;) {
+               if (options & F_FLOOD) {
+                       pinger();
+                       FD_SET(s, &fdset);
+                       if (select(s + 1, &fdset, NULL, NULL, &timeout) < 1)
+                               continue;
+               }
+               fromlen = sizeof(from);
+               if ((cc = recvfrom(s, (char *)packet, packlen, 0,
+                   (struct sockaddr *)&from, &fromlen)) < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       warn("recvfrom");
+                       continue;
+               }
+               pr_pack((char *)packet, cc, &from);
+               if (npackets && nreceived >= npackets)
+                       break;
+       }
+       summary();
+       exit(nreceived == 0);
+}
+
+/*
+ * onalrm --
+ *     This routine transmits another ping.
+ */
+void
+onalrm(signo)
+       int signo;
+{
+       struct itimerval itimer;
+
+       if (!npackets || ntransmitted < npackets) {
+               pinger();
+               return;
+       }
+
+       /*
+        * If we're not transmitting any more packets, change the timer
+        * to wait two round-trip times if we've received any packets or
+        * ten seconds if we haven't.
+        */
+#define        MAXWAIT         10
+       if (nreceived) {
+               itimer.it_value.tv_sec =  2 * tmax / 1000;
+               if (itimer.it_value.tv_sec == 0)
+                       itimer.it_value.tv_sec = 1;
+       } else
+               itimer.it_value.tv_sec = MAXWAIT;
+       itimer.it_interval.tv_sec = 0;
+       itimer.it_interval.tv_usec = 0;
+       itimer.it_value.tv_usec = 0;
+
+       (void)signal(SIGALRM, onint);
+       (void)setitimer(ITIMER_REAL, &itimer, NULL);
+}
+
+/*
+ * pinger --
+ *     Compose and transmit an ICMP ECHO REQUEST packet.  The IP packet
+ * will be added on by the kernel.  The ID field is our UNIX process ID,
+ * and the sequence number is an ascending integer.  The first 8 bytes
+ * of the data portion are used to hold a UNIX "timeval" struct in VAX
+ * byte-order, to compute the round-trip time.
+ */
+void
+pinger()
+{
+       register struct icmp *icp;
+       register int cc;
+       int i;
+
+       icp = (struct icmp *)outpack;
+       icp->icmp_type = ICMP_ECHO;
+       icp->icmp_code = 0;
+       icp->icmp_cksum = 0;
+       icp->icmp_seq = ntransmitted++;
+       icp->icmp_id = ident;                   /* ID */
+
+       CLR(icp->icmp_seq % mx_dup_ck);
+
+       if (timing)
+               (void)gettimeofday((struct timeval *)&outpack[8], NULL);
+
+       cc = datalen + 8;                       /* skips ICMP portion */
+
+       /* compute ICMP checksum here */
+       icp->icmp_cksum = in_cksum((u_short *)icp, cc);
+
+       i = sendto(s, (char *)outpack, cc, 0, &whereto,
+           sizeof(struct sockaddr));
+
+       if (i < 0 || i != cc)  {
+               if (i < 0)
+                       warn("sendto");
+               (void)printf("ping: wrote %s %d chars, ret=%d\n",
+                   hostname, cc, i);
+       }
+       if (!(options & F_QUIET) && options & F_FLOOD)
+               (void)write(STDOUT_FILENO, &DOT, 1);
+}
+
+/*
+ * pr_pack --
+ *     Print out the packet, if it came from us.  This logic is necessary
+ * because ALL readers of the ICMP socket get a copy of ALL ICMP packets
+ * which arrive ('tis only fair).  This permits multiple copies of this
+ * program to be run without having intermingled output (or statistics!).
+ */
+void
+pr_pack(buf, cc, from)
+       char *buf;
+       int cc;
+       struct sockaddr_in *from;
+{
+       register struct icmp *icp;
+       register u_long l;
+       register int i, j;
+       register u_char *cp,*dp;
+       static int old_rrlen;
+       static char old_rr[MAX_IPOPTLEN];
+       struct ip *ip;
+       struct timeval tv, *tp;
+       double triptime;
+       int hlen, dupflag;
+
+       (void)gettimeofday(&tv, NULL);
+
+       /* Check the IP header */
+       ip = (struct ip *)buf;
+       hlen = ip->ip_hl << 2;
+       if (cc < hlen + ICMP_MINLEN) {
+               if (options & F_VERBOSE)
+                       warnx("packet too short (%d bytes) from %s\n", cc,
+                         inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr));
+               return;
+       }
+
+       /* Now the ICMP part */
+       cc -= hlen;
+       icp = (struct icmp *)(buf + hlen);
+       if (icp->icmp_type == ICMP_ECHOREPLY) {
+               if (icp->icmp_id != ident)
+                       return;                 /* 'Twas not our ECHO */
+               ++nreceived;
+               if (timing) {
+#ifndef icmp_data
+                       tp = (struct timeval *)&icp->icmp_ip;
+#else
+                       tp = (struct timeval *)icp->icmp_data;
+#endif
+                       tvsub(&tv, tp);
+                       triptime = ((double)tv.tv_sec) * 1000.0 +
+                           ((double)tv.tv_usec) / 1000.0;
+                       tsum += triptime;
+                       if (triptime < tmin)
+                               tmin = triptime;
+                       if (triptime > tmax)
+                               tmax = triptime;
+               }
+
+               if (TST(icp->icmp_seq % mx_dup_ck)) {
+                       ++nrepeats;
+                       --nreceived;
+                       dupflag = 1;
+               } else {
+                       SET(icp->icmp_seq % mx_dup_ck);
+                       dupflag = 0;
+               }
+
+               if (options & F_QUIET)
+                       return;
+
+               if (options & F_FLOOD)
+                       (void)write(STDOUT_FILENO, &BSPACE, 1);
+               else {
+                       (void)printf("%d bytes from %s: icmp_seq=%u", cc,
+                          inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr),
+                          icp->icmp_seq);
+                       (void)printf(" ttl=%d", ip->ip_ttl);
+                       if (timing)
+                               (void)printf(" time=%g ms", triptime);
+                       if (dupflag)
+                               (void)printf(" (DUP!)");
+                       /* check the data */
+                       cp = (u_char*)&icp->icmp_data[8];
+                       dp = &outpack[8 + sizeof(struct timeval)];
+                       for (i = 8; i < datalen; ++i, ++cp, ++dp) {
+                               if (*cp != *dp) {
+       (void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x",
+           i, *dp, *cp);
+                                       cp = (u_char*)&icp->icmp_data[0];
+                                       for (i = 8; i < datalen; ++i, ++cp) {
+                                               if ((i % 32) == 8)
+                                                       (void)printf("\n\t");
+                                               (void)printf("%x ", *cp);
+                                       }
+                                       break;
+                               }
+                       }
+               }
+       } else {
+               /* We've got something other than an ECHOREPLY */
+               if (!(options & F_VERBOSE))
+                       return;
+               (void)printf("%d bytes from %s: ", cc,
+                   pr_addr(from->sin_addr.s_addr));
+               pr_icmph(icp);
+       }
+
+       /* Display any IP options */
+       cp = (u_char *)buf + sizeof(struct ip);
+
+       for (; hlen > (int)sizeof(struct ip); --hlen, ++cp)
+               switch (*cp) {
+               case IPOPT_EOL:
+                       hlen = 0;
+                       break;
+               case IPOPT_LSRR:
+                       (void)printf("\nLSRR: ");
+                       hlen -= 2;
+                       j = *++cp;
+                       ++cp;
+                       if (j > IPOPT_MINOFF)
+                               for (;;) {
+                                       l = *++cp;
+                                       l = (l<<8) + *++cp;
+                                       l = (l<<8) + *++cp;
+                                       l = (l<<8) + *++cp;
+                                       if (l == 0)
+                                               (void)printf("\t0.0.0.0");
+                               else
+                                       (void)printf("\t%s", pr_addr(ntohl(l)));
+                               hlen -= 4;
+                               j -= 4;
+                               if (j <= IPOPT_MINOFF)
+                                       break;
+                               (void)putchar('\n');
+                       }
+                       break;
+               case IPOPT_RR:
+                       j = *++cp;              /* get length */
+                       i = *++cp;              /* and pointer */
+                       hlen -= 2;
+                       if (i > j)
+                               i = j;
+                       i -= IPOPT_MINOFF;
+                       if (i <= 0)
+                               continue;
+                       if (i == old_rrlen
+                           && cp == (u_char *)buf + sizeof(struct ip) + 2
+                           && !memcmp((char *)cp, old_rr, i)
+                           && !(options & F_FLOOD)) {
+                               (void)printf("\t(same route)");
+                               i = ((i + 3) / 4) * 4;
+                               hlen -= i;
+                               cp += i;
+                               break;
+                       }
+                       old_rrlen = i;
+                       memmove(old_rr, cp, i);
+                       (void)printf("\nRR: ");
+                       for (;;) {
+                               l = *++cp;
+                               l = (l<<8) + *++cp;
+                               l = (l<<8) + *++cp;
+                               l = (l<<8) + *++cp;
+                               if (l == 0)
+                                       (void)printf("\t0.0.0.0");
+                               else
+                                       (void)printf("\t%s", pr_addr(ntohl(l)));
+                               hlen -= 4;
+                               i -= 4;
+                               if (i <= 0)
+                                       break;
+                               (void)putchar('\n');
+                       }
+                       break;
+               case IPOPT_NOP:
+                       (void)printf("\nNOP");
+                       break;
+               default:
+                       (void)printf("\nunknown option %x", *cp);
+                       break;
+               }
+       if (!(options & F_FLOOD)) {
+               (void)putchar('\n');
+               (void)fflush(stdout);
+       }
+}
+
+/*
+ * in_cksum --
+ *     Checksum routine for Internet Protocol family headers (C Version)
+ */
+u_short
+in_cksum(addr, len)
+       u_short *addr;
+       int len;
+{
+       register int nleft = len;
+       register u_short *w = addr;
+       register int sum = 0;
+       u_short answer = 0;
+
+       /*
+        * Our algorithm is simple, using a 32 bit accumulator (sum), we add
+        * sequential 16 bit words to it, and at the end, fold back all the
+        * carry bits from the top 16 bits into the lower 16 bits.
+        */
+       while (nleft > 1)  {
+               sum += *w++;
+               nleft -= 2;
+       }
+
+       /* mop up an odd byte, if necessary */
+       if (nleft == 1) {
+               *(u_char *)(&answer) = *(u_char *)w ;
+               sum += answer;
+       }
+
+       /* add back carry outs from top 16 bits to low 16 bits */
+       sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
+       sum += (sum >> 16);                     /* add carry */
+       answer = ~sum;                          /* truncate to 16 bits */
+       return (answer);
+}
+
+/*
+ * tvsub --
+ *     Subtract 2 timeval structs:  out = out - in.  Out is assumed to
+ * be >= in.
+ */
+void
+tvsub(out, in)
+       register struct timeval *out, *in;
+{
+       if ((out->tv_usec -= in->tv_usec) < 0) {
+               --out->tv_sec;
+               out->tv_usec += 1000000;
+       }
+       out->tv_sec -= in->tv_sec;
+}
+
+/*
+ * oninfo --
+ *     SIGINFO handler.
+ */
+void
+oninfo(notused)
+       int notused;
+{
+       summary();
+}
+
+/*
+ * onint --
+ *     SIGINT handler.
+ */
+void
+onint(notused)
+       int notused;
+{
+       summary();
+
+       (void)signal(SIGINT, SIG_DFL);
+       (void)kill(getpid(), SIGINT);
+
+       /* NOTREACHED */
+       exit(1);
+}
+
+/*
+ * summary --
+ *     Print out statistics.
+ */
+void
+summary()
+{
+       register int i;
+
+       (void)printf("\n--- %s ping statistics ---\n", hostname);
+       (void)printf("%ld packets transmitted, ", ntransmitted);
+       (void)printf("%ld packets received, ", nreceived);
+       if (nrepeats)
+               (void)printf("+%ld duplicates, ", nrepeats);
+       if (ntransmitted)
+               if (nreceived > ntransmitted)
+                       (void)printf("-- somebody's printing up packets!");
+               else
+                       (void)printf("%d%% packet loss",
+                           (int) (((ntransmitted - nreceived) * 100) /
+                           ntransmitted));
+       (void)putchar('\n');
+       if (nreceived && timing) {
+               /* Only display average to microseconds */
+               i = 1000.0 * tsum / (nreceived + nrepeats);
+               (void)printf("round-trip min/avg/max = %g/%g/%g ms\n",
+                   tmin, ((double)i) / 1000.0, tmax);
+       }
+}
+
+#ifdef notdef
+static char *ttab[] = {
+       "Echo Reply",           /* ip + seq + udata */
+       "Dest Unreachable",     /* net, host, proto, port, frag, sr + IP */
+       "Source Quench",        /* IP */
+       "Redirect",             /* redirect type, gateway, + IP  */
+       "Echo",
+       "Time Exceeded",        /* transit, frag reassem + IP */
+       "Parameter Problem",    /* pointer + IP */
+       "Timestamp",            /* id + seq + three timestamps */
+       "Timestamp Reply",      /* " */
+       "Info Request",         /* id + sq */
+       "Info Reply"            /* " */
+};
+#endif
+
+/*
+ * pr_icmph --
+ *     Print a descriptive string about an ICMP header.
+ */
+void
+pr_icmph(icp)
+       struct icmp *icp;
+{
+       switch(icp->icmp_type) {
+       case ICMP_ECHOREPLY:
+               (void)printf("Echo Reply\n");
+               /* XXX ID + Seq + Data */
+               break;
+       case ICMP_UNREACH:
+               switch(icp->icmp_code) {
+               case ICMP_UNREACH_NET:
+                       (void)printf("Destination Net Unreachable\n");
+                       break;
+               case ICMP_UNREACH_HOST:
+                       (void)printf("Destination Host Unreachable\n");
+                       break;
+               case ICMP_UNREACH_PROTOCOL:
+                       (void)printf("Destination Protocol Unreachable\n");
+                       break;
+               case ICMP_UNREACH_PORT:
+                       (void)printf("Destination Port Unreachable\n");
+                       break;
+               case ICMP_UNREACH_NEEDFRAG:
+                       (void)printf("frag needed and DF set\n");
+                       break;
+               case ICMP_UNREACH_SRCFAIL:
+                       (void)printf("Source Route Failed\n");
+                       break;
+               default:
+                       (void)printf("Dest Unreachable, Bad Code: %d\n",
+                           icp->icmp_code);
+                       break;
+               }
+               /* Print returned IP header information */
+#ifndef icmp_data
+               pr_retip(&icp->icmp_ip);
+#else
+               pr_retip((struct ip *)icp->icmp_data);
+#endif
+               break;
+       case ICMP_SOURCEQUENCH:
+               (void)printf("Source Quench\n");
+#ifndef icmp_data
+               pr_retip(&icp->icmp_ip);
+#else
+               pr_retip((struct ip *)icp->icmp_data);
+#endif
+               break;
+       case ICMP_REDIRECT:
+               switch(icp->icmp_code) {
+               case ICMP_REDIRECT_NET:
+                       (void)printf("Redirect Network");
+                       break;
+               case ICMP_REDIRECT_HOST:
+                       (void)printf("Redirect Host");
+                       break;
+               case ICMP_REDIRECT_TOSNET:
+                       (void)printf("Redirect Type of Service and Network");
+                       break;
+               case ICMP_REDIRECT_TOSHOST:
+                       (void)printf("Redirect Type of Service and Host");
+                       break;
+               default:
+                       (void)printf("Redirect, Bad Code: %d", icp->icmp_code);
+                       break;
+               }
+               (void)printf("(New addr: 0x%08lx)\n", icp->icmp_gwaddr.s_addr);
+#ifndef icmp_data
+               pr_retip(&icp->icmp_ip);
+#else
+               pr_retip((struct ip *)icp->icmp_data);
+#endif
+               break;
+       case ICMP_ECHO:
+               (void)printf("Echo Request\n");
+               /* XXX ID + Seq + Data */
+               break;
+       case ICMP_TIMXCEED:
+               switch(icp->icmp_code) {
+               case ICMP_TIMXCEED_INTRANS:
+                       (void)printf("Time to live exceeded\n");
+                       break;
+               case ICMP_TIMXCEED_REASS:
+                       (void)printf("Frag reassembly time exceeded\n");
+                       break;
+               default:
+                       (void)printf("Time exceeded, Bad Code: %d\n",
+                           icp->icmp_code);
+                       break;
+               }
+#ifndef icmp_data
+               pr_retip(&icp->icmp_ip);
+#else
+               pr_retip((struct ip *)icp->icmp_data);
+#endif
+               break;
+       case ICMP_PARAMPROB:
+               (void)printf("Parameter problem: pointer = 0x%02x\n",
+                   icp->icmp_hun.ih_pptr);
+#ifndef icmp_data
+               pr_retip(&icp->icmp_ip);
+#else
+               pr_retip((struct ip *)icp->icmp_data);
+#endif
+               break;
+       case ICMP_TSTAMP:
+               (void)printf("Timestamp\n");
+               /* XXX ID + Seq + 3 timestamps */
+               break;
+       case ICMP_TSTAMPREPLY:
+               (void)printf("Timestamp Reply\n");
+               /* XXX ID + Seq + 3 timestamps */
+               break;
+       case ICMP_IREQ:
+               (void)printf("Information Request\n");
+               /* XXX ID + Seq */
+               break;
+       case ICMP_IREQREPLY:
+               (void)printf("Information Reply\n");
+               /* XXX ID + Seq */
+               break;
+#ifdef ICMP_MASKREQ
+       case ICMP_MASKREQ:
+               (void)printf("Address Mask Request\n");
+               break;
+#endif
+#ifdef ICMP_MASKREPLY
+       case ICMP_MASKREPLY:
+               (void)printf("Address Mask Reply\n");
+               break;
+#endif
+       default:
+               (void)printf("Bad ICMP type: %d\n", icp->icmp_type);
+       }
+}
+
+/*
+ * pr_iph --
+ *     Print an IP header with options.
+ */
+void
+pr_iph(ip)
+       struct ip *ip;
+{
+       int hlen;
+       u_char *cp;
+
+       hlen = ip->ip_hl << 2;
+       cp = (u_char *)ip + 20;         /* point to options */
+
+       (void)printf("Vr HL TOS  Len   ID Flg  off TTL Pro  cks      Src      Dst Data\n");
+       (void)printf(" %1x  %1x  %02x %04x %04x",
+           ip->ip_v, ip->ip_hl, ip->ip_tos, ip->ip_len, ip->ip_id);
+       (void)printf("   %1x %04x", ((ip->ip_off) & 0xe000) >> 13,
+           (ip->ip_off) & 0x1fff);
+       (void)printf("  %02x  %02x %04x", ip->ip_ttl, ip->ip_p, ip->ip_sum);
+       (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_src.s_addr));
+       (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_dst.s_addr));
+       /* dump and option bytes */
+       while (hlen-- > 20)
+               (void)printf("%02x", *cp++);
+       (void)putchar('\n');
+}
+
+/*
+ * pr_addr --
+ *     Return an ascii host address as a dotted quad and optionally with
+ * a hostname.
+ */
+char *
+pr_addr(l)
+       u_long l;
+{
+       struct hostent *hp;
+       static char buf[80];
+
+       if ((options & F_NUMERIC) ||
+           !(hp = gethostbyaddr((char *)&l, 4, AF_INET)))
+               (void)sprintf(buf, "%s", inet_ntoa(*(struct in_addr *)&l));
+       else
+               (void)snprintf(buf, sizeof(buf),
+                   "%s (%s)", hp->h_name, inet_ntoa(*(struct in_addr *)&l));
+       return (buf);
+}
+
+/*
+ * pr_retip --
+ *     Dump some info on a returned (via ICMP) IP packet.
+ */
+void
+pr_retip(ip)
+       struct ip *ip;
+{
+       int hlen;
+       u_char *cp;
+
+       pr_iph(ip);
+       hlen = ip->ip_hl << 2;
+       cp = (u_char *)ip + hlen;
+
+       if (ip->ip_p == 6)
+               (void)printf("TCP: from port %u, to port %u (decimal)\n",
+                   (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));
+       else if (ip->ip_p == 17)
+               (void)printf("UDP: from port %u, to port %u (decimal)\n",
+                       (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));
+}
+
+void
+fill(bp, patp)
+       char *bp, *patp;
+{
+       register int ii, jj, kk;
+       int pat[16];
+       char *cp;
+
+       for (cp = patp; *cp; cp++)
+               if (!isxdigit(*cp))
+                       errx(1, "patterns must be specified as hex digits");
+       ii = sscanf(patp,
+           "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
+           &pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6],
+           &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12],
+           &pat[13], &pat[14], &pat[15]);
+
+       if (ii > 0)
+               for (kk = 0;
+                   kk <= MAXPACKET - (8 + sizeof(struct timeval) + ii);
+                   kk += ii)
+                       for (jj = 0; jj < ii; ++jj)
+                               bp[jj + kk] = pat[jj];
+       if (!(options & F_QUIET)) {
+               (void)printf("PATTERN: 0x");
+               for (jj = 0; jj < ii; ++jj)
+                       (void)printf("%02x", bp[jj] & 0xFF);
+               (void)printf("\n");
+       }
+}
+
+void
+usage()
+{
+       (void)fprintf(stderr,
+"usage: ping [-dfnqRrv] [-c count] [-i wait] [-l preload] [-p pattern]\n\
+            [-s packetsize] host\n");
+       exit(1);
+}
diff --git a/ping/init_v6.c b/ping/init_v6.c
new file mode 100644 (file)
index 0000000..bb7c63d
--- /dev/null
@@ -0,0 +1,27 @@
+#include "ping.h"
+
+void
+init_v6()
+{
+#ifdef IPV6
+       int on = 1;
+
+       if (verbose == 0) {
+               /* install a filter that only passes ICMP6_ECHO_REPLY unless verbose */
+               struct icmp6_filter myfilt;
+               ICMP6_FILTER_SETBLOCKALL(&myfilt);
+               ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &myfilt);
+               setsockopt(sockfd, IPPROTO_IPV6, ICMP6_FILTER, &myfilt, sizeof(myfilt));
+               /* ignore error return; the filter is an optimization */
+       }
+
+       /* ignore error returned below; we just won't receive the hop limit */
+#ifdef IPV6_RECVHOPLIMIT
+       /* RFC 3542 */
+       setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on));
+#else
+       /* RFC 2292 */
+       setsockopt(sockfd, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on));
+#endif
+#endif
+}
diff --git a/ping/main.c b/ping/main.c
new file mode 100644 (file)
index 0000000..34aab8b
--- /dev/null
@@ -0,0 +1,64 @@
+#include       "ping.h"
+
+struct proto   proto_v4 = { proc_v4, send_v4, NULL, NULL, NULL, 0, IPPROTO_ICMP };
+
+#ifdef IPV6
+struct proto   proto_v6 = { proc_v6, send_v6, init_v6, NULL, NULL, 0, IPPROTO_ICMPV6 };
+#endif
+
+int    datalen = 56;           /* data that goes with ICMP echo request */
+
+int
+main(int argc, char **argv)
+{
+       int                             c;
+       struct addrinfo *ai;
+       char *h;
+
+       opterr = 0;             /* don't want getopt() writing to stderr */
+       while ( (c = getopt(argc, argv, "v")) != -1) {
+               switch (c) {
+               case 'v':
+                       verbose++;
+                       break;
+
+               case '?':
+                       err_quit("unrecognized option: %c", c);
+               }
+       }
+
+       if (optind != argc-1)
+               err_quit("usage: ping [ -v ] <hostname>");
+       host = argv[optind];
+
+       pid = getpid() & 0xffff;        /* ICMP ID field is 16 bits */
+       Signal(SIGALRM, sig_alrm);
+
+       ai = Host_serv(host, NULL, 0, 0);
+
+       h = Sock_ntop_host(ai->ai_addr, ai->ai_addrlen);
+       printf("PING %s (%s): %d data bytes\n",
+                       ai->ai_canonname ? ai->ai_canonname : h,
+                       h, datalen);
+
+               /* 4initialize according to protocol */
+       if (ai->ai_family == AF_INET) {
+               pr = &proto_v4;
+#ifdef IPV6
+       } else if (ai->ai_family == AF_INET6) {
+               pr = &proto_v6;
+               if (IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *)
+                                                                ai->ai_addr)->sin6_addr)))
+                       err_quit("cannot ping IPv4-mapped IPv6 address");
+#endif
+       } else
+               err_quit("unknown address family %d", ai->ai_family);
+
+       pr->sasend = ai->ai_addr;
+       pr->sarecv = Calloc(1, ai->ai_addrlen);
+       pr->salen = ai->ai_addrlen;
+
+       readloop();
+
+       exit(0);
+}
diff --git a/ping/main.lc b/ping/main.lc
new file mode 100644 (file)
index 0000000..08b91e2
--- /dev/null
@@ -0,0 +1,61 @@
+#include    "ping.h"##  1 ##src/ping/main.c##
+
+struct proto proto_v4 = { proc_v4, send_v4, NULL, NULL, 0, IPPROTO_ICMP };##  2 ##src/ping/main.c##
+
+#ifdef  IPV6##  3 ##src/ping/main.c##
+struct proto proto_v6 = { proc_v6, send_v6, NULL, NULL, 0, IPPROTO_ICMPV6 };##  4 ##src/ping/main.c##
+#endif##  5 ##src/ping/main.c##
+
+int     datalen = 56;           /* data that goes with ICMP echo request */##  6 ##src/ping/main.c##
+
+int##  7 ##src/ping/main.c##
+main(int argc, char **argv)##  8 ##src/ping/main.c##
+{##  9 ##src/ping/main.c##
+    int     c;## 10 ##src/ping/main.c##
+    struct addrinfo *ai;## 11 ##src/ping/main.c##
+
+    opterr = 0;                 /* don't want getopt() writing to stderr */## 12 ##src/ping/main.c##
+    while ((c = getopt(argc, argv, "v")) != -1) {## 13 ##src/ping/main.c##
+        switch (c) {## 14 ##src/ping/main.c##
+        case 'v':## 15 ##src/ping/main.c##
+            verbose++;## 16 ##src/ping/main.c##
+            break;## 17 ##src/ping/main.c##
+
+        case '?':## 18 ##src/ping/main.c##
+            err_quit("unrecognized option: %c", c);## 19 ##src/ping/main.c##
+        }## 20 ##src/ping/main.c##
+    }## 21 ##src/ping/main.c##
+
+    if (optind != argc - 1)## 22 ##src/ping/main.c##
+        err_quit("usage: ping [ -v ] <hostname>");## 23 ##src/ping/main.c##
+    host = argv[optind];## 24 ##src/ping/main.c##
+
+    pid = getpid();## 25 ##src/ping/main.c##
+    Signal(SIGALRM, sig_alrm);## 26 ##src/ping/main.c##
+
+    ai = Host_serv(host, NULL, 0, 0);## 27 ##src/ping/main.c##
+
+    printf("PING %s (%s): %d data bytes\n", ai->ai_canonname,## 28 ##src/ping/main.c##
+           Sock_ntop_host(ai->ai_addr, ai->ai_addrlen), datalen);## 29 ##src/ping/main.c##
+
+    /* 4initialize according to protocol */## 30 ##src/ping/main.c##
+    if (ai->ai_family == AF_INET) {## 31 ##src/ping/main.c##
+        pr = &proto_v4;## 32 ##src/ping/main.c##
+#ifdef  IPV6## 33 ##src/ping/main.c##
+    } else if (ai->ai_family == AF_INET6) {## 34 ##src/ping/main.c##
+        pr = &proto_v6;## 35 ##src/ping/main.c##
+        if (IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *)## 36 ##src/ping/main.c##
+                                    ai->ai_addr)->sin6_addr)))## 37 ##src/ping/main.c##
+            err_quit("cannot ping IPv4-mapped IPv6 address");## 38 ##src/ping/main.c##
+#endif## 39 ##src/ping/main.c##
+    } else## 40 ##src/ping/main.c##
+        err_quit("unknown address family %d", ai->ai_family);## 41 ##src/ping/main.c##
+
+    pr->sasend = ai->ai_addr;## 42 ##src/ping/main.c##
+    pr->sarecv = Calloc(1, ai->ai_addrlen);## 43 ##src/ping/main.c##
+    pr->salen = ai->ai_addrlen;## 44 ##src/ping/main.c##
+
+    readloop();## 45 ##src/ping/main.c##
+
+    exit(0);## 46 ##src/ping/main.c##
+}## 47 ##src/ping/main.c##
diff --git a/ping/old/icmp6.h b/ping/old/icmp6.h
new file mode 100644 (file)
index 0000000..b3d8929
--- /dev/null
@@ -0,0 +1,46 @@
+struct icmp6hdr {
+    u_int8_t   icmp6_type;             /* Type field */
+    u_int8_t   icmp6_code;             /* Code field */
+    u_int16_t  icmp6_cksum;            /* Checksum field */
+    union {
+       u_int32_t       un_data32[1];   /* Type-specific field */
+       u_int16_t       un_data16[2];   /* Type-specific field */
+       u_int8_t        un_data8[4];    /* Type-specific field */
+    } icmp6_dataun;
+};
+
+#define        icmp6_data32    icmp6_dataun.un_data32
+#define        icmp6_data16    icmp6_dataun.un_data16
+#define        icmp6_data8     icmp6_dataun.un_data8
+#define        icmp6_pptr      icmp6_data32[0]         /* PARAMPROB */
+#define        icmp6_mtu       icmp6_data32[0]         /* PKT_TOOBIG */
+#define        icmp6_id        icmp6_data16[0]         /* ECHO */
+#define        icmp6_seq       icmp6_data16[1]         /* ECHO */
+#define        icmp6_maxdelay  icmp6_data16[0]         /* MGM_xxx */
+
+#define        ICMPV6_DEST_UNREACH     1
+#define        ICMPV6_PKT_TOOBIG       2
+#define        ICMPV6_TIME_EXCEED      3
+#define        ICMPV6_PARAMPROB        4
+
+#define        ICMPV6_INFOMSG_MASK     0x80    /* all informational messages */
+
+#define        ICMPV6_ECHORQST         128
+#define        ICMPV6_ECHORPLY         129
+#define        ICMPV6_MGM_QUERY        130
+#define        ICMPV6_MGM_REPORT       131
+#define        ICMPV6_MGM_REDUCTION    132
+
+#define        ICMPV6_DEST_UNREACH_NOROUTE     0 /* no route to destination */
+#define        ICMPV6_DEST_UNREACH_ADMIN       1 /* communication with destination */
+                                         /*  administratively prohibited */
+#define        ICMPV6_DEST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor */
+#define        ICMPV6_DEST_UNREACH_ADDR        3 /* address unreachable */
+#define        ICMPV6_DEST_UNREACH_NOPORT      4 /* bad port */
+
+#define        ICMPV6_TIME_EXCEED_HOPS         0 /* Hop Limit == 0 in transit */
+#define        ICMPV6_TIME_EXCEED_REASSEMBLY   1 /* Reassembly time out */
+
+#define        ICMPV6_PARAMPROB_HDR            0 /* erroneous header field */
+#define        ICMPV6_PARAMPROB_NXT_HDR        1 /* unrecognized Next Header */
+#define        ICMPV6_PARAMPROB_OPTS           2 /* unrecognized IPv6 option */
diff --git a/ping/old/ip6.h b/ping/old/ip6.h
new file mode 100644 (file)
index 0000000..1c23950
--- /dev/null
@@ -0,0 +1,20 @@
+struct ip6hdr {
+    union {
+       struct ip6hdrctl {
+           u_int32_t ctl6_flow;        /* 24 bits of flow-ID */
+           u_int16_t ctl6_plen;        /* payload length */
+           u_int8_t  ctl6_nxt;         /* next header */
+           u_int8_t  ctl6_hlim;        /* hop limit */
+       } un_ctl6;
+       u_int8_t un_vfc;                /* 4 bits version, 4 bits reserved */
+    } ip6_ctlun;
+    struct in6_addr ip6_src;           /* source address */
+    struct in6_addr ip6_dst;           /* destination address */
+};
+
+#define ip6_vfc                ip6_ctlun.un_vfc
+#define ip6_flow       ip6_ctlun.un_ctl6.ctl6_flow
+#define        ip6_plen        ip6_ctlun.un_ctl6.ctl6_plen
+#define        ip6_nxt         ip6_ctlun.un_ctl6.ctl6_nxt
+#define        ip6_hlim        ip6_ctlun.un_ctl6.ctl6_hlim
+#define        ip6_hops        ip6_ctlun.un_ctl6.ctl6_hlim
diff --git a/ping/ping.h b/ping/ping.h
new file mode 100644 (file)
index 0000000..062b87a
--- /dev/null
@@ -0,0 +1,43 @@
+#include       "unp.h"
+#include       <netinet/in_systm.h>
+#include       <netinet/ip.h>
+#include       <netinet/ip_icmp.h>
+
+#define        BUFSIZE         1500
+
+                       /* globals */
+char    sendbuf[BUFSIZE];
+
+int             datalen;                       /* # bytes of data following ICMP header */
+char   *host;
+int             nsent;                         /* add 1 for each sendto() */
+pid_t   pid;                           /* our PID */
+int             sockfd;
+int             verbose;
+
+                       /* function prototypes */
+void    init_v6(void);
+void    proc_v4(char *, ssize_t, struct msghdr *, struct timeval *);
+void    proc_v6(char *, ssize_t, struct msghdr *, struct timeval *);
+void    send_v4(void);
+void    send_v6(void);
+void    readloop(void);
+void    sig_alrm(int);
+void    tv_sub(struct timeval *, struct timeval *);
+
+struct proto {
+  void  (*fproc)(char *, ssize_t, struct msghdr *, struct timeval *);
+  void  (*fsend)(void);
+  void  (*finit)(void);
+  struct sockaddr  *sasend;    /* sockaddr{} for send, from getaddrinfo */
+  struct sockaddr  *sarecv;    /* sockaddr{} for receiving */
+  socklen_t        salen;              /* length of sockaddr{}s */
+  int              icmpproto;  /* IPPROTO_xxx value for ICMP */
+} *pr;
+
+#ifdef IPV6
+
+#include       <netinet/ip6.h>
+#include       <netinet/icmp6.h>
+
+#endif
diff --git a/ping/ping_v4.c b/ping/ping_v4.c
new file mode 100644 (file)
index 0000000..3bd7cdf
--- /dev/null
@@ -0,0 +1,33 @@
+#include       "ping.h"
+
+void
+ping_v4(struct hostent *hptr)
+{
+       int                             size;
+       char                    recvbuf[BUFSIZE];
+       socklen_t               len;
+       ssize_t                 n;
+       struct timeval  tval;
+
+       setuid(getuid());               /* don't need special permissions any more */
+
+       size = 60 * 1024;               /* OK if setsockopt fails */
+       setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
+
+
+       sig_alrm(SIGALRM);              /* send first packet */
+
+       for ( ; ; ) {
+               len = salen;
+               n = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, sarecv, &len);
+               if (n < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       else
+                               err_sys("recvfrom error");
+               }
+
+               Gettimeofday(&tval, NULL);
+               (*fptrs.proc_f)(recvbuf, n, &tval);
+       }
+}
diff --git a/ping/proc_v4.c b/ping/proc_v4.c
new file mode 100644 (file)
index 0000000..6b175ce
--- /dev/null
@@ -0,0 +1,40 @@
+#include       "ping.h"
+
+void
+proc_v4(char *ptr, ssize_t len, struct msghdr *msg, struct timeval *tvrecv)
+{
+       int                             hlen1, icmplen;
+       double                  rtt;
+       struct ip               *ip;
+       struct icmp             *icmp;
+       struct timeval  *tvsend;
+
+       ip = (struct ip *) ptr;         /* start of IP header */
+       hlen1 = ip->ip_hl << 2;         /* length of IP header */
+       if (ip->ip_p != IPPROTO_ICMP)
+               return;                         /* not ICMP */
+
+       icmp = (struct icmp *) (ptr + hlen1);   /* start of ICMP header */
+       if ( (icmplen = len - hlen1) < 8)
+               return;                         /* malformed packet */
+
+       if (icmp->icmp_type == ICMP_ECHOREPLY) {
+               if (icmp->icmp_id != pid)
+                       return;                 /* not a response to our ECHO_REQUEST */
+               if (icmplen < 16)
+                       return;                 /* not enough data to use */
+
+               tvsend = (struct timeval *) icmp->icmp_data;
+               tv_sub(tvrecv, tvsend);
+               rtt = tvrecv->tv_sec * 1000.0 + tvrecv->tv_usec / 1000.0;
+
+               printf("%d bytes from %s: seq=%u, ttl=%d, rtt=%.3f ms\n",
+                               icmplen, Sock_ntop_host(pr->sarecv, pr->salen),
+                               icmp->icmp_seq, ip->ip_ttl, rtt);
+
+       } else if (verbose) {
+               printf("  %d bytes from %s: type = %d, code = %d\n",
+                               icmplen, Sock_ntop_host(pr->sarecv, pr->salen),
+                               icmp->icmp_type, icmp->icmp_code);
+       }
+}
diff --git a/ping/proc_v4.lc b/ping/proc_v4.lc
new file mode 100644 (file)
index 0000000..1ec03fa
--- /dev/null
@@ -0,0 +1,38 @@
+#include    "ping.h"##  1 ##src/ping/proc_v4.c##
+
+void##  2 ##src/ping/proc_v4.c##
+proc_v4(char *ptr, ssize_t len, struct timeval *tvrecv)##  3 ##src/ping/proc_v4.c##
+{##  4 ##src/ping/proc_v4.c##
+    int     hlen1, icmplen;##  5 ##src/ping/proc_v4.c##
+    double  rtt;##  6 ##src/ping/proc_v4.c##
+    struct ip *ip;##  7 ##src/ping/proc_v4.c##
+    struct icmp *icmp;##  8 ##src/ping/proc_v4.c##
+    struct timeval *tvsend;##  9 ##src/ping/proc_v4.c##
+
+    ip = (struct ip *) ptr;     /* start of IP header */## 10 ##src/ping/proc_v4.c##
+    hlen1 = ip->ip_hl << 2;     /* length of IP header */## 11 ##src/ping/proc_v4.c##
+
+    icmp = (struct icmp *) (ptr + hlen1);   /* start of ICMP header */## 12 ##src/ping/proc_v4.c##
+    if ((icmplen = len - hlen1) < 8)## 13 ##src/ping/proc_v4.c##
+        err_quit("icmplen (%d) < 8", icmplen);## 14 ##src/ping/proc_v4.c##
+
+    if (icmp->icmp_type == ICMP_ECHOREPLY) {## 15 ##src/ping/proc_v4.c##
+        if (icmp->icmp_id != pid)## 16 ##src/ping/proc_v4.c##
+            return;             /* not a response to our ECHO_REQUEST */## 17 ##src/ping/proc_v4.c##
+        if (icmplen < 16)## 18 ##src/ping/proc_v4.c##
+            err_quit("icmplen (%d) < 16", icmplen);## 19 ##src/ping/proc_v4.c##
+
+        tvsend = (struct timeval *) icmp->icmp_data;## 20 ##src/ping/proc_v4.c##
+        tv_sub(tvrecv, tvsend);## 21 ##src/ping/proc_v4.c##
+        rtt = tvrecv->tv_sec * 1000.0 + tvrecv->tv_usec / 1000.0;## 22 ##src/ping/proc_v4.c##
+
+        printf("%d bytes from %s: seq=%u, ttl=%d, rtt=%.3f ms\n",## 23 ##src/ping/proc_v4.c##
+               icmplen, Sock_ntop_host(pr->sarecv, pr->salen),## 24 ##src/ping/proc_v4.c##
+               icmp->icmp_seq, ip->ip_ttl, rtt);## 25 ##src/ping/proc_v4.c##
+
+    } else if (verbose) {## 26 ##src/ping/proc_v4.c##
+        printf("  %d bytes from %s: type = %d, code = %d\n",## 27 ##src/ping/proc_v4.c##
+               icmplen, Sock_ntop_host(pr->sarecv, pr->salen),## 28 ##src/ping/proc_v4.c##
+               icmp->icmp_type, icmp->icmp_code);## 29 ##src/ping/proc_v4.c##
+    }## 30 ##src/ping/proc_v4.c##
+}## 31 ##src/ping/proc_v4.c##
diff --git a/ping/proc_v6.c b/ping/proc_v6.c
new file mode 100644 (file)
index 0000000..3609bf0
--- /dev/null
@@ -0,0 +1,49 @@
+#include       "ping.h"
+
+void
+proc_v6(char *ptr, ssize_t len, struct msghdr *msg, struct timeval* tvrecv)
+{
+#ifdef IPV6
+       double                          rtt;
+       struct icmp6_hdr        *icmp6;
+       struct timeval          *tvsend;
+       struct cmsghdr          *cmsg;
+       int                                     hlim;
+
+       icmp6 = (struct icmp6_hdr *) ptr;
+       if (len < 8)
+               return;                         /* malformed packet */
+
+       if (icmp6->icmp6_type == ICMP6_ECHO_REPLY) {
+               if (icmp6->icmp6_id != pid)
+                       return;                 /* not a response to our ECHO_REQUEST */
+               if (len < 16)
+                       return;                 /* not enough data to use */
+
+               tvsend = (struct timeval *) (icmp6 + 1);
+               tv_sub(tvrecv, tvsend);
+               rtt = tvrecv->tv_sec * 1000.0 + tvrecv->tv_usec / 1000.0;
+
+               hlim = -1;
+               for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
+                       if (cmsg->cmsg_level == IPPROTO_IPV6 &&
+                               cmsg->cmsg_type == IPV6_HOPLIMIT) {
+                               hlim = *(u_int32_t *)CMSG_DATA(cmsg);
+                               break;
+                       }
+               }
+               printf("%d bytes from %s: seq=%u, hlim=",
+                               len, Sock_ntop_host(pr->sarecv, pr->salen),
+                               icmp6->icmp6_seq);
+               if (hlim == -1)
+                       printf("???");  /* ancillary data missing */
+               else
+                       printf("%d", hlim);
+               printf(", rtt=%.3f ms\n", rtt);
+       } else if (verbose) {
+               printf("  %d bytes from %s: type = %d, code = %d\n",
+                               len, Sock_ntop_host(pr->sarecv, pr->salen),
+                               icmp6->icmp6_type, icmp6->icmp6_code);
+       }
+#endif /* IPV6 */
+}
diff --git a/ping/proc_v6.lc b/ping/proc_v6.lc
new file mode 100644 (file)
index 0000000..4885cc3
--- /dev/null
@@ -0,0 +1,42 @@
+#include    "ping.h"##  1 ##src/ping/proc_v6.c##
+
+void##  2 ##src/ping/proc_v6.c##
+proc_v6(char *ptr, ssize_t len, struct timeval *tvrecv)##  3 ##src/ping/proc_v6.c##
+{##  4 ##src/ping/proc_v6.c##
+#ifdef  IPV6##  5 ##src/ping/proc_v6.c##
+    int     hlen1, icmp6len;##  6 ##src/ping/proc_v6.c##
+    double  rtt;##  7 ##src/ping/proc_v6.c##
+    struct ip6_hdr *ip6;##  8 ##src/ping/proc_v6.c##
+    struct icmp6_hdr *icmp6;##  9 ##src/ping/proc_v6.c##
+    struct timeval *tvsend;## 10 ##src/ping/proc_v6.c##
+
+    ip6 = (struct ip6_hdr *) ptr;   /* start of IPv6 header */## 11 ##src/ping/proc_v6.c##
+    hlen1 = sizeof(struct ip6_hdr);## 12 ##src/ping/proc_v6.c##
+    if (ip6->ip6_nxt != IPPROTO_ICMPV6)## 13 ##src/ping/proc_v6.c##
+        err_quit("next header not IPPROTO_ICMPV6");## 14 ##src/ping/proc_v6.c##
+
+    icmp6 = (struct icmp6_hdr *) (ptr + hlen1);## 15 ##src/ping/proc_v6.c##
+    if ((icmp6len = len - hlen1) < 8)## 16 ##src/ping/proc_v6.c##
+        err_quit("icmp6len (%d) < 8", icmp6len);## 17 ##src/ping/proc_v6.c##
+
+    if (icmp6->icmp6_type == ICMP6_ECHO_REPLY) {## 18 ##src/ping/proc_v6.c##
+        if (icmp6->icmp6_id != pid)## 19 ##src/ping/proc_v6.c##
+            return;             /* not a response to our ECHO_REQUEST */## 20 ##src/ping/proc_v6.c##
+        if (icmp6len < 16)## 21 ##src/ping/proc_v6.c##
+            err_quit("icmp6len (%d) < 16", icmp6len);## 22 ##src/ping/proc_v6.c##
+
+        tvsend = (struct timeval *) (icmp6 + 1);## 23 ##src/ping/proc_v6.c##
+        tv_sub(tvrecv, tvsend);## 24 ##src/ping/proc_v6.c##
+        rtt = tvrecv->tv_sec * 1000.0 + tvrecv->tv_usec / 1000.0;## 25 ##src/ping/proc_v6.c##
+
+        printf("%d bytes from %s: seq=%u, hlim=%d, rtt=%.3f ms\n",## 26 ##src/ping/proc_v6.c##
+               icmp6len, Sock_ntop_host(pr->sarecv, pr->salen),## 27 ##src/ping/proc_v6.c##
+               icmp6->icmp6_seq, ip6->ip6_hlim, rtt);## 28 ##src/ping/proc_v6.c##
+
+    } else if (verbose) {## 29 ##src/ping/proc_v6.c##
+        printf("  %d bytes from %s: type = %d, code = %d\n",## 30 ##src/ping/proc_v6.c##
+               icmp6len, Sock_ntop_host(pr->sarecv, pr->salen),## 31 ##src/ping/proc_v6.c##
+               icmp6->icmp6_type, icmp6->icmp6_code);## 32 ##src/ping/proc_v6.c##
+    }## 33 ##src/ping/proc_v6.c##
+#endif  /* IPV6 */## 34 ##src/ping/proc_v6.c##
+}## 35 ##src/ping/proc_v6.c##
diff --git a/ping/readloop.c b/ping/readloop.c
new file mode 100644 (file)
index 0000000..dc6f483
--- /dev/null
@@ -0,0 +1,44 @@
+#include       "ping.h"
+
+void
+readloop(void)
+{
+       int                             size;
+       char                    recvbuf[BUFSIZE];
+       char                    controlbuf[BUFSIZE];
+       struct msghdr   msg;
+       struct iovec    iov;
+       ssize_t                 n;
+       struct timeval  tval;
+
+       sockfd = Socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto);
+       setuid(getuid());               /* don't need special permissions any more */
+       if (pr->finit)
+               (*pr->finit)();
+
+       size = 60 * 1024;               /* OK if setsockopt fails */
+       setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
+
+       sig_alrm(SIGALRM);              /* send first packet */
+
+       iov.iov_base = recvbuf;
+       iov.iov_len = sizeof(recvbuf);
+       msg.msg_name = pr->sarecv;
+       msg.msg_iov = &iov;
+       msg.msg_iovlen = 1;
+       msg.msg_control = controlbuf;
+       for ( ; ; ) {
+               msg.msg_namelen = pr->salen;
+               msg.msg_controllen = sizeof(controlbuf);
+               n = recvmsg(sockfd, &msg, 0);
+               if (n < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       else
+                               err_sys("recvmsg error");
+               }
+
+               Gettimeofday(&tval, NULL);
+               (*pr->fproc)(recvbuf, n, &msg, &tval);
+       }
+}
diff --git a/ping/send_v4.c b/ping/send_v4.c
new file mode 100644 (file)
index 0000000..455f95a
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "ping.h"
+
+void
+send_v4(void)
+{
+       int                     len;
+       struct icmp     *icmp;
+
+       icmp = (struct icmp *) sendbuf;
+       icmp->icmp_type = ICMP_ECHO;
+       icmp->icmp_code = 0;
+       icmp->icmp_id = pid;
+       icmp->icmp_seq = nsent++;
+       memset(icmp->icmp_data, 0xa5, datalen); /* fill with pattern */
+       Gettimeofday((struct timeval *) icmp->icmp_data, NULL);
+
+       len = 8 + datalen;              /* checksum ICMP header and data */
+       icmp->icmp_cksum = 0;
+       icmp->icmp_cksum = in_cksum((u_short *) icmp, len);
+
+       Sendto(sockfd, sendbuf, len, 0, pr->sasend, pr->salen);
+}
diff --git a/ping/send_v6.c b/ping/send_v6.c
new file mode 100644 (file)
index 0000000..c76e12d
--- /dev/null
@@ -0,0 +1,23 @@
+#include       "ping.h"
+
+void
+send_v6()
+{
+#ifdef IPV6
+       int                                     len;
+       struct icmp6_hdr        *icmp6;
+
+       icmp6 = (struct icmp6_hdr *) sendbuf;
+       icmp6->icmp6_type = ICMP6_ECHO_REQUEST;
+       icmp6->icmp6_code = 0;
+       icmp6->icmp6_id = pid;
+       icmp6->icmp6_seq = nsent++;
+       memset((icmp6 + 1), 0xa5, datalen);     /* fill with pattern */
+       Gettimeofday((struct timeval *) (icmp6 + 1), NULL);
+
+       len = 8 + datalen;              /* 8-byte ICMPv6 header */
+
+       Sendto(sockfd, sendbuf, len, 0, pr->sasend, pr->salen);
+               /* 4kernel calculates and stores checksum for us */
+#endif /* IPV6 */
+}
diff --git a/ping/sig_alrm.c b/ping/sig_alrm.c
new file mode 100644 (file)
index 0000000..f32e803
--- /dev/null
@@ -0,0 +1,10 @@
+#include       "ping.h"
+
+void
+sig_alrm(int signo)
+{
+       (*pr->fsend)();
+
+       alarm(1);
+       return;
+}
diff --git a/ping/sig_alrm.lc b/ping/sig_alrm.lc
new file mode 100644 (file)
index 0000000..e13c21e
--- /dev/null
@@ -0,0 +1,10 @@
+#include    "ping.h"##  1 ##src/ping/sig_alrm.c##
+
+void##  2 ##src/ping/sig_alrm.c##
+sig_alrm(int signo)##  3 ##src/ping/sig_alrm.c##
+{##  4 ##src/ping/sig_alrm.c##
+    (*pr->fsend) ();##  5 ##src/ping/sig_alrm.c##
+
+    alarm(1);##  6 ##src/ping/sig_alrm.c##
+    return;                     /* probably interrupts recvfrom() */##  7 ##src/ping/sig_alrm.c##
+}##  8 ##src/ping/sig_alrm.c##
diff --git a/ping/tv_sub.c b/ping/tv_sub.c
new file mode 100644 (file)
index 0000000..7ad7830
--- /dev/null
@@ -0,0 +1,11 @@
+#include       "unp.h"
+
+void
+tv_sub(struct timeval *out, struct timeval *in)
+{
+       if ( (out->tv_usec -= in->tv_usec) < 0) {       /* out -= in */
+               --out->tv_sec;
+               out->tv_usec += 1000000;
+       }
+       out->tv_sec -= in->tv_sec;
+}
diff --git a/route/Makefile b/route/Makefile
new file mode 100644 (file)
index 0000000..cb9cab5
--- /dev/null
@@ -0,0 +1,30 @@
+include ../Make.defines
+
+PROGS =        checkudpsum getrt mynetstat \
+               prifinfo prifindex prifname prifnameindex
+
+all:   ${PROGS}
+
+checkudpsum:   checkudpsum.o
+               ${CC} ${CFLAGS} -o $@ checkudpsum.o ${LIBS}
+
+getrt: getrt.o
+               ${CC} ${CFLAGS} -o $@ getrt.o ${LIBS}
+
+prifinfo:      prifinfo.o get_ifi_info.o
+               ${CC} ${CFLAGS} -o $@ prifinfo.o get_ifi_info.o ${LIBS}
+
+prifindex:     prifindex.o
+               ${CC} ${CFLAGS} -o $@ prifindex.o ${LIBS}
+
+prifname:      prifname.o
+               ${CC} ${CFLAGS} -o $@ prifname.o ${LIBS}
+
+prifnameindex: prifnameindex.o
+               ${CC} ${CFLAGS} -o $@ prifnameindex.o ${LIBS}
+
+mynetstat:     mynetstat.o
+               ${CC} ${CFLAGS} -o $@ mynetstat.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/route/checkudpsum.c b/route/checkudpsum.c
new file mode 100644 (file)
index 0000000..e0360e1
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unproute.h"
+#include       <netinet/udp.h>
+#include       <netinet/ip_var.h>
+#include       <netinet/udp_var.h>             /* for UDPCTL_xxx constants */
+
+int
+main(int argc, char **argv)
+{
+       int             mib[4], val;
+       size_t  len;
+
+       mib[0] = CTL_NET;
+       mib[1] = AF_INET;
+       mib[2] = IPPROTO_UDP;
+       mib[3] = UDPCTL_CHECKSUM;
+
+       len = sizeof(val);
+       Sysctl(mib, 4, &val, &len, NULL, 0);
+       printf("udp checksum flag: %d\n", val);
+
+       exit(0);
+}
diff --git a/route/get_ifi_info.c b/route/get_ifi_info.c
new file mode 100644 (file)
index 0000000..f96ab78
--- /dev/null
@@ -0,0 +1,126 @@
+#include       "unpifi.h"
+#include       "unproute.h"
+
+/* include get_ifi_info1 */
+struct ifi_info *
+get_ifi_info(int family, int doaliases)
+{
+       int                             flags;
+       char                            *buf, *next, *lim;
+       size_t                          len;
+       struct if_msghdr        *ifm;
+       struct ifa_msghdr       *ifam;
+       struct sockaddr         *sa, *rti_info[RTAX_MAX];
+       struct sockaddr_dl      *sdl;
+       struct ifi_info         *ifi, *ifisave, *ifihead, **ifipnext;
+
+       buf = Net_rt_iflist(family, 0, &len);
+
+       ifihead = NULL;
+       ifipnext = &ifihead;
+
+       lim = buf + len;
+       for (next = buf; next < lim; next += ifm->ifm_msglen) {
+               ifm = (struct if_msghdr *) next;
+               if (ifm->ifm_type == RTM_IFINFO) {
+                       if ( ((flags = ifm->ifm_flags) & IFF_UP) == 0)
+                               continue;       /* ignore if interface not up */
+
+                       sa = (struct sockaddr *) (ifm + 1);
+                       get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
+                       if ( (sa = rti_info[RTAX_IFP]) != NULL) {
+                               ifi = Calloc(1, sizeof(struct ifi_info));
+                               *ifipnext = ifi;                        /* prev points to this new one */
+                               ifipnext = &ifi->ifi_next;      /* ptr to next one goes here */
+
+                               ifi->ifi_flags = flags;
+                               if (sa->sa_family == AF_LINK) {
+                                       sdl = (struct sockaddr_dl *) sa;
+                                       ifi->ifi_index = sdl->sdl_index;
+                                       if (sdl->sdl_nlen > 0)
+                                               snprintf(ifi->ifi_name, IFI_NAME, "%*s",
+                                                                sdl->sdl_nlen, &sdl->sdl_data[0]);
+                                       else
+                                               snprintf(ifi->ifi_name, IFI_NAME, "index %d",
+                                                                sdl->sdl_index);
+
+                                       if ( (ifi->ifi_hlen = sdl->sdl_alen) > 0)
+                                               memcpy(ifi->ifi_haddr, LLADDR(sdl),
+                                                          min(IFI_HADDR, sdl->sdl_alen));
+                               }
+                       }
+/* end get_ifi_info1 */
+
+/* include get_ifi_info3 */
+               } else if (ifm->ifm_type == RTM_NEWADDR) {
+                       if (ifi->ifi_addr) {    /* already have an IP addr for i/f */
+                               if (doaliases == 0)
+                                       continue;
+
+                                       /* 4we have a new IP addr for existing interface */
+                               ifisave = ifi;
+                               ifi = Calloc(1, sizeof(struct ifi_info));
+                               *ifipnext = ifi;                        /* prev points to this new one */
+                               ifipnext = &ifi->ifi_next;      /* ptr to next one goes here */
+                               ifi->ifi_flags = ifisave->ifi_flags;
+                               ifi->ifi_index = ifisave->ifi_index;
+                               ifi->ifi_hlen = ifisave->ifi_hlen;
+                               memcpy(ifi->ifi_name, ifisave->ifi_name, IFI_NAME);
+                               memcpy(ifi->ifi_haddr, ifisave->ifi_haddr, IFI_HADDR);
+                       }
+
+                       ifam = (struct ifa_msghdr *) next;
+                       sa = (struct sockaddr *) (ifam + 1);
+                       get_rtaddrs(ifam->ifam_addrs, sa, rti_info);
+
+                       if ( (sa = rti_info[RTAX_IFA]) != NULL) {
+                               ifi->ifi_addr = Calloc(1, sa->sa_len);
+                               memcpy(ifi->ifi_addr, sa, sa->sa_len);
+                       }
+
+                       if ((flags & IFF_BROADCAST) &&
+                               (sa = rti_info[RTAX_BRD]) != NULL) {
+                               ifi->ifi_brdaddr = Calloc(1, sa->sa_len);
+                               memcpy(ifi->ifi_brdaddr, sa, sa->sa_len);
+                       }
+
+                       if ((flags & IFF_POINTOPOINT) &&
+                               (sa = rti_info[RTAX_BRD]) != NULL) {
+                               ifi->ifi_dstaddr = Calloc(1, sa->sa_len);
+                               memcpy(ifi->ifi_dstaddr, sa, sa->sa_len);
+                       }
+
+               } else
+                       err_quit("unexpected message type %d", ifm->ifm_type);
+       }
+       /* "ifihead" points to the first structure in the linked list */
+       return(ifihead);        /* ptr to first structure in linked list */
+}
+/* end get_ifi_info3 */
+
+void
+free_ifi_info(struct ifi_info *ifihead)
+{
+       struct ifi_info *ifi, *ifinext;
+
+       for (ifi = ifihead; ifi != NULL; ifi = ifinext) {
+               if (ifi->ifi_addr != NULL)
+                       free(ifi->ifi_addr);
+               if (ifi->ifi_brdaddr != NULL)
+                       free(ifi->ifi_brdaddr);
+               if (ifi->ifi_dstaddr != NULL)
+                       free(ifi->ifi_dstaddr);
+               ifinext = ifi->ifi_next;                /* can't fetch ifi_next after free() */
+               free(ifi);                                      /* the ifi_info{} itself */
+       }
+}
+
+struct ifi_info *
+Get_ifi_info(int family, int doaliases)
+{
+       struct ifi_info *ifi;
+
+       if ( (ifi = get_ifi_info(family, doaliases)) == NULL)
+               err_quit("get_ifi_info error");
+       return(ifi);
+}
diff --git a/route/get_ifi_info.lc b/route/get_ifi_info.lc
new file mode 100644 (file)
index 0000000..c02f2f5
--- /dev/null
@@ -0,0 +1,123 @@
+#include    "unpifi.h"##  1 ##src/route/get_ifi_info.c##
+#include    "unproute.h"##  2 ##src/route/get_ifi_info.c##
+
+/* include get_ifi_info1 */
+struct ifi_info *##  3 ##src/route/get_ifi_info.c##
+get_ifi_info(int family, int doaliases)##  4 ##src/route/get_ifi_info.c##
+{##  5 ##src/route/get_ifi_info.c##
+    int     flags;##  6 ##src/route/get_ifi_info.c##
+    char   *buf, *next, *lim;##  7 ##src/route/get_ifi_info.c##
+    size_t  len;##  8 ##src/route/get_ifi_info.c##
+    struct if_msghdr *ifm;##  9 ##src/route/get_ifi_info.c##
+    struct ifa_msghdr *ifam;## 10 ##src/route/get_ifi_info.c##
+    struct sockaddr *sa, *rti_info[RTAX_MAX];## 11 ##src/route/get_ifi_info.c##
+    struct sockaddr_dl *sdl;## 12 ##src/route/get_ifi_info.c##
+    struct ifi_info *ifi, *ifisave, *ifihead, **ifipnext;## 13 ##src/route/get_ifi_info.c##
+
+    buf = Net_rt_iflist(family, 0, &len);## 14 ##src/route/get_ifi_info.c##
+
+    ifihead = NULL;## 15 ##src/route/get_ifi_info.c##
+    ifipnext = &ifihead;## 16 ##src/route/get_ifi_info.c##
+
+    lim = buf + len;## 17 ##src/route/get_ifi_info.c##
+    for (next = buf; next < lim; next += ifm->ifm_msglen) {## 18 ##src/route/get_ifi_info.c##
+        ifm = (struct if_msghdr *) next;## 19 ##src/route/get_ifi_info.c##
+        if (ifm->ifm_type == RTM_IFINFO) {## 20 ##src/route/get_ifi_info.c##
+            if (((flags = ifm->ifm_flags) & IFF_UP) == 0)## 21 ##src/route/get_ifi_info.c##
+                continue;       /* ignore if interface not up */## 22 ##src/route/get_ifi_info.c##
+
+            sa = (struct sockaddr *) (ifm + 1);## 23 ##src/route/get_ifi_info.c##
+            get_rtaddrs(ifm->ifm_addrs, sa, rti_info);## 24 ##src/route/get_ifi_info.c##
+            if ((sa = rti_info[RTAX_IFP]) != NULL) {## 25 ##src/route/get_ifi_info.c##
+                ifi = Calloc(1, sizeof(struct ifi_info));## 26 ##src/route/get_ifi_info.c##
+                *ifipnext = ifi;    /* prev points to this new one */## 27 ##src/route/get_ifi_info.c##
+                ifipnext = &ifi->ifi_next;  /* ptr to next one goes here */## 28 ##src/route/get_ifi_info.c##
+
+                ifi->ifi_flags = flags;## 29 ##src/route/get_ifi_info.c##
+                if (sa->sa_family == AF_LINK) {## 30 ##src/route/get_ifi_info.c##
+                    sdl = (struct sockaddr_dl *) sa;## 31 ##src/route/get_ifi_info.c##
+                    if (sdl->sdl_nlen > 0)## 32 ##src/route/get_ifi_info.c##
+                        snprintf(ifi->ifi_name, IFI_NAME, "%*s",## 33 ##src/route/get_ifi_info.c##
+                                 sdl->sdl_nlen, &sdl->sdl_data[0]);## 34 ##src/route/get_ifi_info.c##
+                    else## 35 ##src/route/get_ifi_info.c##
+                        snprintf(ifi->ifi_name, IFI_NAME, "index %d",## 36 ##src/route/get_ifi_info.c##
+                                 sdl->sdl_index);## 37 ##src/route/get_ifi_info.c##
+
+                    if ((ifi->ifi_hlen = sdl->sdl_alen) > 0)## 38 ##src/route/get_ifi_info.c##
+                        memcpy(ifi->ifi_haddr, LLADDR(sdl),## 39 ##src/route/get_ifi_info.c##
+                               min(IFI_HADDR, sdl->sdl_alen));## 40 ##src/route/get_ifi_info.c##
+                }## 41 ##src/route/get_ifi_info.c##
+            }## 42 ##src/route/get_ifi_info.c##
+/* end get_ifi_info1 */
+
+/* include get_ifi_info3 */
+        } else if (ifm->ifm_type == RTM_NEWADDR) {## 43 ##src/route/get_ifi_info.c##
+            if (ifi->ifi_addr) {    /* already have an IP addr for i/f */## 44 ##src/route/get_ifi_info.c##
+                if (doaliases == 0)## 45 ##src/route/get_ifi_info.c##
+                    continue;## 46 ##src/route/get_ifi_info.c##
+
+                /* 4we have a new IP addr for existing interface */## 47 ##src/route/get_ifi_info.c##
+                ifisave = ifi;## 48 ##src/route/get_ifi_info.c##
+                ifi = Calloc(1, sizeof(struct ifi_info));## 49 ##src/route/get_ifi_info.c##
+                *ifipnext = ifi;    /* prev points to this new one */## 50 ##src/route/get_ifi_info.c##
+                ifipnext = &ifi->ifi_next;  /* ptr to next one goes here */## 51 ##src/route/get_ifi_info.c##
+                ifi->ifi_flags = ifisave->ifi_flags;## 52 ##src/route/get_ifi_info.c##
+                ifi->ifi_hlen = ifisave->ifi_hlen;## 53 ##src/route/get_ifi_info.c##
+                memcpy(ifi->ifi_name, ifisave->ifi_name, IFI_NAME);## 54 ##src/route/get_ifi_info.c##
+                memcpy(ifi->ifi_haddr, ifisave->ifi_haddr, IFI_HADDR);## 55 ##src/route/get_ifi_info.c##
+            }## 56 ##src/route/get_ifi_info.c##
+
+            ifam = (struct ifa_msghdr *) next;## 57 ##src/route/get_ifi_info.c##
+            sa = (struct sockaddr *) (ifam + 1);## 58 ##src/route/get_ifi_info.c##
+            get_rtaddrs(ifam->ifam_addrs, sa, rti_info);## 59 ##src/route/get_ifi_info.c##
+
+            if ((sa = rti_info[RTAX_IFA]) != NULL) {## 60 ##src/route/get_ifi_info.c##
+                ifi->ifi_addr = Calloc(1, sa->sa_len);## 61 ##src/route/get_ifi_info.c##
+                memcpy(ifi->ifi_addr, sa, sa->sa_len);## 62 ##src/route/get_ifi_info.c##
+            }## 63 ##src/route/get_ifi_info.c##
+
+            if ((flags & IFF_BROADCAST) && (sa = rti_info[RTAX_BRD]) != NULL) {## 64 ##src/route/get_ifi_info.c##
+                ifi->ifi_brdaddr = Calloc(1, sa->sa_len);## 65 ##src/route/get_ifi_info.c##
+                memcpy(ifi->ifi_brdaddr, sa, sa->sa_len);## 66 ##src/route/get_ifi_info.c##
+            }## 67 ##src/route/get_ifi_info.c##
+
+            if ((flags & IFF_POINTOPOINT) &&## 68 ##src/route/get_ifi_info.c##
+                (sa = rti_info[RTAX_BRD]) != NULL) {## 69 ##src/route/get_ifi_info.c##
+                ifi->ifi_dstaddr = Calloc(1, sa->sa_len);## 70 ##src/route/get_ifi_info.c##
+                memcpy(ifi->ifi_dstaddr, sa, sa->sa_len);## 71 ##src/route/get_ifi_info.c##
+            }## 72 ##src/route/get_ifi_info.c##
+
+        } else## 73 ##src/route/get_ifi_info.c##
+            err_quit("unexpected message type %d", ifm->ifm_type);## 74 ##src/route/get_ifi_info.c##
+    }## 75 ##src/route/get_ifi_info.c##
+    /* "ifihead" points to the first structure in the linked list */## 76 ##src/route/get_ifi_info.c##
+    return (ifihead);           /* ptr to first structure in linked list */## 77 ##src/route/get_ifi_info.c##
+}## 78 ##src/route/get_ifi_info.c##
+/* end get_ifi_info3 */
+
+void## 79 ##src/route/get_ifi_info.c##
+free_ifi_info(struct ifi_info *ifihead)## 80 ##src/route/get_ifi_info.c##
+{## 81 ##src/route/get_ifi_info.c##
+    struct ifi_info *ifi, *ifinext;## 82 ##src/route/get_ifi_info.c##
+
+    for (ifi = ifihead; ifi != NULL; ifi = ifinext) {## 83 ##src/route/get_ifi_info.c##
+        if (ifi->ifi_addr != NULL)## 84 ##src/route/get_ifi_info.c##
+            free(ifi->ifi_addr);## 85 ##src/route/get_ifi_info.c##
+        if (ifi->ifi_brdaddr != NULL)## 86 ##src/route/get_ifi_info.c##
+            free(ifi->ifi_brdaddr);## 87 ##src/route/get_ifi_info.c##
+        if (ifi->ifi_dstaddr != NULL)## 88 ##src/route/get_ifi_info.c##
+            free(ifi->ifi_dstaddr);## 89 ##src/route/get_ifi_info.c##
+        ifinext = ifi->ifi_next;    /* can't fetch ifi_next after free() */## 90 ##src/route/get_ifi_info.c##
+        free(ifi);              /* the ifi_info{} itself */## 91 ##src/route/get_ifi_info.c##
+    }## 92 ##src/route/get_ifi_info.c##
+}## 93 ##src/route/get_ifi_info.c##
+
+struct ifi_info *## 94 ##src/route/get_ifi_info.c##
+Get_ifi_info(int family, int doaliases)## 95 ##src/route/get_ifi_info.c##
+{## 96 ##src/route/get_ifi_info.c##
+    struct ifi_info *ifi;## 97 ##src/route/get_ifi_info.c##
+
+    if ((ifi = get_ifi_info(family, doaliases)) == NULL)## 98 ##src/route/get_ifi_info.c##
+        err_quit("get_ifi_info error");## 99 ##src/route/get_ifi_info.c##
+    return (ifi);##100 ##src/route/get_ifi_info.c##
+}##101 ##src/route/get_ifi_info.c##
diff --git a/route/getrt.c b/route/getrt.c
new file mode 100644 (file)
index 0000000..4d2143a
--- /dev/null
@@ -0,0 +1,65 @@
+/* include getrt1 */
+#include       "unproute.h"
+
+#define        BUFLEN  (sizeof(struct rt_msghdr) + 512)
+                                       /* sizeof(struct sockaddr_in6) * 8 = 192 */
+#define        SEQ             9999
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       char                            *buf;
+       pid_t                           pid;
+       ssize_t                         n;
+       struct rt_msghdr        *rtm;
+       struct sockaddr         *sa, *rti_info[RTAX_MAX];
+       struct sockaddr_in      *sin;
+
+       if (argc != 2)
+               err_quit("usage: getrt <IPaddress>");
+
+       sockfd = Socket(AF_ROUTE, SOCK_RAW, 0); /* need superuser privileges */
+
+       buf = Calloc(1, BUFLEN);        /* and initialized to 0 */
+
+       rtm = (struct rt_msghdr *) buf;
+       rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);
+       rtm->rtm_version = RTM_VERSION;
+       rtm->rtm_type = RTM_GET;
+       rtm->rtm_addrs = RTA_DST;
+       rtm->rtm_pid = pid = getpid();
+       rtm->rtm_seq = SEQ;
+
+       sin = (struct sockaddr_in *) (rtm + 1);
+       sin->sin_len = sizeof(struct sockaddr_in);
+       sin->sin_family = AF_INET;
+    Inet_pton(AF_INET, argv[1], &sin->sin_addr);
+
+       Write(sockfd, rtm, rtm->rtm_msglen);
+
+       do {
+               n = Read(sockfd, rtm, BUFLEN);
+       } while (rtm->rtm_type != RTM_GET || rtm->rtm_seq != SEQ ||
+                        rtm->rtm_pid != pid);
+/* end getrt1 */
+
+/* include getrt2 */
+       rtm = (struct rt_msghdr *) buf;
+       sa = (struct sockaddr *) (rtm + 1);
+       get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
+       if ( (sa = rti_info[RTAX_DST]) != NULL)
+               printf("dest: %s\n", Sock_ntop_host(sa, sa->sa_len));
+
+       if ( (sa = rti_info[RTAX_GATEWAY]) != NULL)
+               printf("gateway: %s\n", Sock_ntop_host(sa, sa->sa_len));
+
+       if ( (sa = rti_info[RTAX_NETMASK]) != NULL)
+               printf("netmask: %s\n", Sock_masktop(sa, sa->sa_len));
+
+       if ( (sa = rti_info[RTAX_GENMASK]) != NULL)
+               printf("genmask: %s\n", Sock_masktop(sa, sa->sa_len));
+
+       exit(0);
+}
+/* end getrt2 */
diff --git a/route/getrt.lc b/route/getrt.lc
new file mode 100644 (file)
index 0000000..6fe6e4d
--- /dev/null
@@ -0,0 +1,65 @@
+/* include getrt1 */
+#include    "unproute.h"##  1 ##src/route/getrt.c##
+
+#define BUFLEN  (sizeof(struct rt_msghdr) + 512)##  2 ##src/route/getrt.c##
+                    /* sizeof(struct sockaddr_in6) * 8 = 192 */##  3 ##src/route/getrt.c##
+#define SEQ     9999##  4 ##src/route/getrt.c##
+
+int##  5 ##src/route/getrt.c##
+main(int argc, char **argv)##  6 ##src/route/getrt.c##
+{##  7 ##src/route/getrt.c##
+    int     sockfd;##  8 ##src/route/getrt.c##
+    char   *buf;##  9 ##src/route/getrt.c##
+    pid_t   pid;## 10 ##src/route/getrt.c##
+    ssize_t n;## 11 ##src/route/getrt.c##
+    struct rt_msghdr *rtm;## 12 ##src/route/getrt.c##
+    struct sockaddr *sa, *rti_info[RTAX_MAX];## 13 ##src/route/getrt.c##
+    struct sockaddr_in *sin;## 14 ##src/route/getrt.c##
+
+    if (argc != 2)## 15 ##src/route/getrt.c##
+        err_quit("usage: getrt <IPaddress>");## 16 ##src/route/getrt.c##
+
+    sockfd = Socket(AF_ROUTE, SOCK_RAW, 0); /* need superuser privileges */## 17 ##src/route/getrt.c##
+
+    buf = Calloc(1, BUFLEN);    /* and initialized to 0 */## 18 ##src/route/getrt.c##
+
+    rtm = (struct rt_msghdr *) buf;## 19 ##src/route/getrt.c##
+    rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);## 20 ##src/route/getrt.c##
+    rtm->rtm_version = RTM_VERSION;## 21 ##src/route/getrt.c##
+    rtm->rtm_type = RTM_GET;## 22 ##src/route/getrt.c##
+    rtm->rtm_addrs = RTA_DST;## 23 ##src/route/getrt.c##
+    rtm->rtm_pid = pid = getpid();## 24 ##src/route/getrt.c##
+    rtm->rtm_seq = SEQ;## 25 ##src/route/getrt.c##
+
+    sin = (struct sockaddr_in *) (rtm + 1);## 26 ##src/route/getrt.c##
+    sin->sin_len = sizeof(struct sockaddr_in);## 27 ##src/route/getrt.c##
+    sin->sin_family = AF_INET;## 28 ##src/route/getrt.c##
+    Inet_pton(AF_INET, argv[1], &sin->sin_addr);## 29 ##src/route/getrt.c##
+
+    Write(sockfd, rtm, rtm->rtm_msglen);## 30 ##src/route/getrt.c##
+
+    do {## 31 ##src/route/getrt.c##
+        n = Read(sockfd, rtm, BUFLEN);## 32 ##src/route/getrt.c##
+    } while (rtm->rtm_type != RTM_GET || rtm->rtm_seq != SEQ ||## 33 ##src/route/getrt.c##
+             rtm->rtm_pid != pid);## 34 ##src/route/getrt.c##
+/* end getrt1 */
+
+/* include getrt2 */
+    rtm = (struct rt_msghdr *) buf;## 35 ##src/route/getrt.c##
+    sa = (struct sockaddr *) (rtm + 1);## 36 ##src/route/getrt.c##
+    get_rtaddrs(rtm->rtm_addrs, sa, rti_info);## 37 ##src/route/getrt.c##
+    if ((sa = rti_info[RTAX_DST]) != NULL)## 38 ##src/route/getrt.c##
+        printf("dest: %s\n", Sock_ntop_host(sa, sa->sa_len));## 39 ##src/route/getrt.c##
+
+    if ((sa = rti_info[RTAX_GATEWAY]) != NULL)## 40 ##src/route/getrt.c##
+        printf("gateway: %s\n", Sock_ntop_host(sa, sa->sa_len));## 41 ##src/route/getrt.c##
+
+    if ((sa = rti_info[RTAX_NETMASK]) != NULL)## 42 ##src/route/getrt.c##
+        printf("netmask: %s\n", Sock_masktop(sa, sa->sa_len));## 43 ##src/route/getrt.c##
+
+    if ((sa = rti_info[RTAX_GENMASK]) != NULL)## 44 ##src/route/getrt.c##
+        printf("genmask: %s\n", Sock_masktop(sa, sa->sa_len));## 45 ##src/route/getrt.c##
+
+    exit(0);## 46 ##src/route/getrt.c##
+}## 47 ##src/route/getrt.c##
+/* end getrt2 */
diff --git a/route/mynetstat.c b/route/mynetstat.c
new file mode 100644 (file)
index 0000000..acb1357
--- /dev/null
@@ -0,0 +1,108 @@
+#include       "unproute.h"
+
+void   pr_rtable(int);
+void   pr_iflist(int);
+
+int
+main(int argc, char **argv)
+{
+       int family;
+
+       if (argc != 2)
+               err_quit("usage: mynetstat <inet4|inet6|all>");
+       if (strcmp(argv[1], "inet4") == 0)
+               family = AF_INET;
+#ifdef AF_INET6
+       else if (strcmp(argv[1], "inet6") == 0)
+               family = AF_INET6;
+#endif
+       else if (strcmp(argv[1], "all") == 0)
+               family = 0;
+       else
+               err_quit("invalid <address-family>");
+
+       pr_rtable(family);
+
+       pr_iflist(family);
+
+       exit(0);
+}
+
+void
+pr_rtable(int family)
+{
+       char                            *buf, *next, *lim;
+       size_t                          len;
+       struct rt_msghdr        *rtm;
+       struct sockaddr         *sa, *rti_info[RTAX_MAX];
+
+       buf = Net_rt_dump(family, 0, &len);
+
+       lim = buf + len;
+       for (next = buf; next < lim; next += rtm->rtm_msglen) {
+               rtm = (struct rt_msghdr *) next;
+               sa = (struct sockaddr *)(rtm + 1);
+               get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
+               if ( (sa = rti_info[RTAX_DST]) != NULL)
+                       printf("dest: %s", sock_ntop(sa, sa->sa_len));
+
+               if ( (sa = rti_info[RTAX_GATEWAY]) != NULL)
+                       printf(", gateway: %s", sock_ntop(sa, sa->sa_len));
+
+               printf("\n");
+       }
+}
+
+void
+pr_iflist(int family)
+{
+       int                             flags;
+       char                            *buf, *next, *lim;
+       u_char                          *ptr;
+       size_t                          len;
+       struct if_msghdr        *ifm;
+       struct ifa_msghdr       *ifam;
+       struct sockaddr         *sa, *rti_info[RTAX_MAX];
+       struct sockaddr_dl      *sdl;
+
+       buf = Net_rt_iflist(family, 0, &len);
+
+       lim = buf + len;
+       for (next = buf; next < lim; next += ifm->ifm_msglen) {
+               ifm = (struct if_msghdr *) next;
+               if (ifm->ifm_type == RTM_IFINFO) {
+                       sa = (struct sockaddr *)(ifm + 1);
+                       get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
+                       if ( (sa = rti_info[RTAX_IFP]) != NULL) {
+                               if (((flags = ifm->ifm_flags) & IFF_UP) == 0)
+                                       continue;
+                               printf("interface: %s: <", Sock_ntop(sa, sa->sa_len));
+                               if (flags & IFF_UP)                             printf("UP ");
+                               if (flags & IFF_BROADCAST)              printf("BCAST ");
+                               if (flags & IFF_MULTICAST)              printf("MCAST ");
+                               if (flags & IFF_LOOPBACK)               printf("LOOP ");
+                               if (flags & IFF_POINTOPOINT)    printf("P2P ");
+                               printf(">\n");
+
+                               if (sa->sa_family == AF_LINK &&
+                                       (sdl = (struct sockaddr_dl *) sa) &&
+                                       (sdl->sdl_alen > 0)) {
+                                       ptr = (u_char *) &sdl->sdl_data[sdl->sdl_nlen];
+                                       printf("  %x:%x:%x:%x:%x:%x\n", *ptr, *(ptr+1),
+                                                       *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5));
+                               }
+                       }
+
+               } else if (ifm->ifm_type == RTM_NEWADDR) {
+                       ifam = (struct ifa_msghdr *) next;
+                       sa = (struct sockaddr *)(ifam + 1);
+                       get_rtaddrs(ifam->ifam_addrs, sa, rti_info);
+                       if ( (sa = rti_info[RTAX_IFA]) != NULL)
+                               printf("  IP addr: %s\n", Sock_ntop(sa, sa->sa_len));
+                       if ((flags & IFF_BROADCAST) && (sa = rti_info[RTAX_BRD]))
+                               printf("  bcast addr: %s\n", Sock_ntop(sa, sa->sa_len));
+
+               } else
+                       err_quit("unexpected message type %d", ifm->ifm_type);
+       }
+}
diff --git a/route/prifindex.c b/route/prifindex.c
new file mode 100644 (file)
index 0000000..0b8e565
--- /dev/null
@@ -0,0 +1,11 @@
+#include       "unpifi.h"
+
+int
+main(int argc, char **argv)
+{
+       if (argc != 2)
+               err_quit("usage: prifname <interface-name>");
+
+       printf("interface index = %d\n", If_nametoindex(argv[1]));
+       exit(0);
+}
diff --git a/route/prifinfo.c b/route/prifinfo.c
new file mode 100644 (file)
index 0000000..767fc4b
--- /dev/null
@@ -0,0 +1,50 @@
+#include       "unpifi.h"
+
+int
+main(int argc, char **argv)
+{
+       struct ifi_info *ifi, *ifihead;
+       struct sockaddr *sa;
+       u_char                  *ptr;
+       int                             i, family, doaliases;
+
+       if (argc != 3)
+               err_quit("usage: prifinfo <inet4|inet6> <doaliases>");
+       if (strcmp(argv[1], "inet4") == 0)
+               family = AF_INET;
+#ifdef AF_INET6
+       else if (strcmp(argv[1], "inet6") == 0)
+               family = AF_INET6;
+#endif
+       else
+               err_quit("invalid <address-family>");
+       doaliases = atoi(argv[2]);
+
+       for (ifihead = ifi = Get_ifi_info(family, doaliases);
+                ifi != NULL; ifi = ifi->ifi_next) {
+               printf("%s: <", ifi->ifi_name);
+               if (ifi->ifi_flags & IFF_UP)                    printf("UP ");
+               if (ifi->ifi_flags & IFF_BROADCAST)             printf("BCAST ");
+               if (ifi->ifi_flags & IFF_MULTICAST)             printf("MCAST ");
+               if (ifi->ifi_flags & IFF_LOOPBACK)              printf("LOOP ");
+               if (ifi->ifi_flags & IFF_POINTOPOINT)   printf("P2P ");
+               printf(">\n");
+
+               if ( (i = ifi->ifi_hlen) > 0) {
+                       ptr = ifi->ifi_haddr;
+                       do {
+                               printf("%s%x", (i == ifi->ifi_hlen) ? "  " : ":", *ptr++);
+                       } while (--i > 0);
+                       printf("\n");
+               }
+
+               if ( (sa = ifi->ifi_addr) != NULL)
+                       printf("  IP addr: %s\n", Sock_ntop(sa, sa->sa_len));
+               if ( (sa = ifi->ifi_brdaddr) != NULL)
+                       printf("  broadcast addr: %s\n", Sock_ntop(sa, sa->sa_len));
+               if ( (sa = ifi->ifi_dstaddr) != NULL)
+                       printf("  destination addr: %s\n", Sock_ntop(sa, sa->sa_len));
+       }
+       free_ifi_info(ifihead);
+       exit(0);
+}
diff --git a/route/prifname.c b/route/prifname.c
new file mode 100644 (file)
index 0000000..3cfd820
--- /dev/null
@@ -0,0 +1,13 @@
+#include       "unpifi.h"
+
+int
+main(int argc, char **argv)
+{
+       char    name[16];
+
+       if (argc != 2)
+               err_quit("usage: prifname <interface-index>");
+
+       printf("interface name = %s\n", If_indextoname(atoi(argv[1]), name));
+       exit(0);
+}
diff --git a/route/prifnameindex.c b/route/prifnameindex.c
new file mode 100644 (file)
index 0000000..f67a0e1
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unpifi.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     n;
+       char                            ifname[IFNAMSIZ];
+       struct if_nameindex     *ifptr, *save;
+
+       if (argc != 1)
+               err_quit("usage: prifnameindex");
+
+               /* print all the interface names and indexes */
+       for (save = ifptr = If_nameindex(); ifptr->if_index > 0; ifptr++) {
+               printf("name = %s, index = %d\n", ifptr->if_name, ifptr->if_index);;
+
+               if ( (n = If_nametoindex(ifptr->if_name)) != ifptr->if_index)
+                       err_quit("if_nametoindex returned %d, expected %d, for %s",
+                                        n, ifptr->if_index, ifptr->if_name);
+
+               If_indextoname(ifptr->if_index, ifname);
+               if (strcmp(ifname, ifptr->if_name) != 0)
+                       err_quit("if_indextoname returned %s, expected %s, for %d",
+                                        ifname, ifptr->if_name, ifptr->if_index);
+       }
+
+       n = if_nametoindex("fkjhkjhgjhgjhgdjhguyetiuyiuyhkjhkjdh");
+       if (n != 0)
+               err_quit("if_nametoindex returned %d for fkjh...", n);
+       n = if_nametoindex("");
+       if (n != 0)
+               err_quit("if_nametoindex returned %d for (null)", n);
+
+       if (if_indextoname(0, ifname) != NULL)
+               err_quit("if_indextoname error for 0");
+       if (if_indextoname(888888, ifname) != NULL)
+               err_quit("if_indextoname error for 888888");
+
+       if_freenameindex(save);
+       exit(0);
+}
diff --git a/route/unproute.h b/route/unproute.h
new file mode 100644 (file)
index 0000000..3043c63
--- /dev/null
@@ -0,0 +1,20 @@
+#include       "unp.h"
+#include       <net/if.h>                      /* if_msghdr{} */
+#include       <net/if_dl.h>           /* sockaddr_sdl{} */
+#include       <net/route.h>           /* RTA_xxx constants */
+#include       <sys/param.h>
+
+#ifdef HAVE_SYS_SYSCTL_H
+#include       <sys/sysctl.h>          /* sysctl() */
+#endif
+
+                       /* function prototypes */
+void    get_rtaddrs(int, struct sockaddr *, struct sockaddr **);
+char   *net_rt_iflist(int, int, size_t *);
+char   *net_rt_dump(int, int, size_t *);
+char   *sock_masktop(struct sockaddr *, socklen_t);
+
+                       /* wrapper functions */
+char   *Net_rt_iflist(int, int, size_t *);
+char   *Net_rt_dump(int, int, size_t *);
+#define        Sock_masktop(a,b)               sock_masktop((a), (b))
diff --git a/rtt/Makefile b/rtt/Makefile
new file mode 100644 (file)
index 0000000..9a4d923
--- /dev/null
@@ -0,0 +1,11 @@
+include ../Make.defines
+
+PROGS =        udpcli01
+
+all:   ${PROGS}
+
+udpcli01:      udpcli01.o dg_cli.o dg_send_recv.o
+               ${CC} ${CFLAGS} -o $@ udpcli01.o dg_cli.o dg_send_recv.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/rtt/dg_cli.c b/rtt/dg_cli.c
new file mode 100644 (file)
index 0000000..4088036
--- /dev/null
@@ -0,0 +1,20 @@
+#include       "unp.h"
+
+ssize_t        Dg_send_recv(int, const void *, size_t, void *, size_t,
+                                  const SA *, socklen_t);
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       ssize_t n;
+       char    sendline[MAXLINE], recvline[MAXLINE + 1];
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               n = Dg_send_recv(sockfd, sendline, strlen(sendline),
+                                                recvline, MAXLINE, pservaddr, servlen);
+
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+}
diff --git a/rtt/dg_cli.lc b/rtt/dg_cli.lc
new file mode 100644 (file)
index 0000000..f279a61
--- /dev/null
@@ -0,0 +1,20 @@
+#include    "unp.h"##  1 ##src/rtt/dg_cli.c##
+
+ssize_t Dg_send_recv(int, const void *, size_t, void *, size_t,##  2 ##src/rtt/dg_cli.c##
+                     const SA *, socklen_t);##  3 ##src/rtt/dg_cli.c##
+
+void##  4 ##src/rtt/dg_cli.c##
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)##  5 ##src/rtt/dg_cli.c##
+{##  6 ##src/rtt/dg_cli.c##
+    ssize_t n;##  7 ##src/rtt/dg_cli.c##
+    char    sendline[MAXLINE], recvline[MAXLINE + 1];##  8 ##src/rtt/dg_cli.c##
+
+    while (Fgets(sendline, MAXLINE, fp) != NULL) {##  9 ##src/rtt/dg_cli.c##
+
+        n = Dg_send_recv(sockfd, sendline, strlen(sendline),## 10 ##src/rtt/dg_cli.c##
+                         recvline, MAXLINE, pservaddr, servlen);## 11 ##src/rtt/dg_cli.c##
+
+        recvline[n] = 0;        /* null terminate */## 12 ##src/rtt/dg_cli.c##
+        Fputs(recvline, stdout);## 13 ##src/rtt/dg_cli.c##
+    }## 14 ##src/rtt/dg_cli.c##
+}## 15 ##src/rtt/dg_cli.c##
diff --git a/rtt/dg_echo.c b/rtt/dg_echo.c
new file mode 100644 (file)
index 0000000..1a92230
--- /dev/null
@@ -0,0 +1,16 @@
+#include       "unp.h"
+
+void
+dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
+{
+       int                     n;
+       socklen_t       len;
+       char            mesg[MAXLINE];
+
+       for ( ; ; ) {
+               len = clilen;
+               n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
+
+               Sendto(sockfd, mesg, n, 0, pcliaddr, clilen);
+       }
+}
diff --git a/rtt/dg_send_recv.c b/rtt/dg_send_recv.c
new file mode 100644 (file)
index 0000000..2a2e914
--- /dev/null
@@ -0,0 +1,115 @@
+/* include dgsendrecv1 */
+#include       "unprtt.h"
+#include       <setjmp.h>
+
+#define        RTT_DEBUG
+
+static struct rtt_info   rttinfo;
+static int     rttinit = 0;
+static struct msghdr   msgsend, msgrecv;       /* assumed init to 0 */
+static struct hdr {
+  uint32_t     seq;    /* sequence # */
+  uint32_t     ts;             /* timestamp when sent */
+} sendhdr, recvhdr;
+
+static void    sig_alrm(int signo);
+static sigjmp_buf      jmpbuf;
+
+ssize_t
+dg_send_recv(int fd, const void *outbuff, size_t outbytes,
+                        void *inbuff, size_t inbytes,
+                        const SA *destaddr, socklen_t destlen)
+{
+       ssize_t                 n;
+       struct iovec    iovsend[2], iovrecv[2];
+
+       if (rttinit == 0) {
+               rtt_init(&rttinfo);             /* first time we're called */
+               rttinit = 1;
+               rtt_d_flag = 1;
+       }
+
+       sendhdr.seq++;
+       msgsend.msg_name = destaddr;
+       msgsend.msg_namelen = destlen;
+       msgsend.msg_iov = iovsend;
+       msgsend.msg_iovlen = 2;
+       iovsend[0].iov_base = &sendhdr;
+       iovsend[0].iov_len = sizeof(struct hdr);
+       iovsend[1].iov_base = outbuff;
+       iovsend[1].iov_len = outbytes;
+
+       msgrecv.msg_name = NULL;
+       msgrecv.msg_namelen = 0;
+       msgrecv.msg_iov = iovrecv;
+       msgrecv.msg_iovlen = 2;
+       iovrecv[0].iov_base = &recvhdr;
+       iovrecv[0].iov_len = sizeof(struct hdr);
+       iovrecv[1].iov_base = inbuff;
+       iovrecv[1].iov_len = inbytes;
+/* end dgsendrecv1 */
+
+/* include dgsendrecv2 */
+       Signal(SIGALRM, sig_alrm);
+       rtt_newpack(&rttinfo);          /* initialize for this packet */
+
+sendagain:
+#ifdef RTT_DEBUG
+       fprintf(stderr, "send %4d: ", sendhdr.seq);
+#endif
+       sendhdr.ts = rtt_ts(&rttinfo);
+       Sendmsg(fd, &msgsend, 0);
+
+       alarm(rtt_start(&rttinfo));     /* calc timeout value & start timer */
+#ifdef RTT_DEBUG
+       rtt_debug(&rttinfo);
+#endif
+
+       if (sigsetjmp(jmpbuf, 1) != 0) {
+               if (rtt_timeout(&rttinfo) < 0) {
+                       err_msg("dg_send_recv: no response from server, giving up");
+                       rttinit = 0;    /* reinit in case we're called again */
+                       errno = ETIMEDOUT;
+                       return(-1);
+               }
+#ifdef RTT_DEBUG
+               err_msg("dg_send_recv: timeout, retransmitting");
+#endif
+               goto sendagain;
+       }
+
+       do {
+               n = Recvmsg(fd, &msgrecv, 0);
+#ifdef RTT_DEBUG
+               fprintf(stderr, "recv %4d\n", recvhdr.seq);
+#endif
+       } while (n < sizeof(struct hdr) || recvhdr.seq != sendhdr.seq);
+
+       alarm(0);                       /* stop SIGALRM timer */
+               /* 4calculate & store new RTT estimator values */
+       rtt_stop(&rttinfo, rtt_ts(&rttinfo) - recvhdr.ts);
+
+       return(n - sizeof(struct hdr)); /* return size of received datagram */
+}
+
+static void
+sig_alrm(int signo)
+{
+       siglongjmp(jmpbuf, 1);
+}
+/* end dgsendrecv2 */
+
+ssize_t
+Dg_send_recv(int fd, const void *outbuff, size_t outbytes,
+                        void *inbuff, size_t inbytes,
+                        const SA *destaddr, socklen_t destlen)
+{
+       ssize_t n;
+
+       n = dg_send_recv(fd, outbuff, outbytes, inbuff, inbytes,
+                                        destaddr, destlen);
+       if (n < 0)
+               err_quit("dg_send_recv error");
+
+       return(n);
+}
diff --git a/rtt/dg_send_recv.lc b/rtt/dg_send_recv.lc
new file mode 100644 (file)
index 0000000..281277a
--- /dev/null
@@ -0,0 +1,103 @@
+/* include dgsendrecv1 */
+#include    "unprtt.h"##  1 ##src/rtt/dg_send_recv.c##
+#include    <setjmp.h>##  2 ##src/rtt/dg_send_recv.c##
+
+#define RTT_DEBUG##  3 ##src/rtt/dg_send_recv.c##
+
+static struct rtt_info rttinfo;##  4 ##src/rtt/dg_send_recv.c##
+static int rttinit = 0;##  5 ##src/rtt/dg_send_recv.c##
+static struct msghdr msgsend, msgrecv;  /* assumed init to 0 */##  6 ##src/rtt/dg_send_recv.c##
+static struct hdr {##  7 ##src/rtt/dg_send_recv.c##
+    uint32_t seq;               /* sequence # */##  8 ##src/rtt/dg_send_recv.c##
+    uint32_t ts;                /* timestamp when sent */##  9 ##src/rtt/dg_send_recv.c##
+} sendhdr, recvhdr;## 10 ##src/rtt/dg_send_recv.c##
+
+static void sig_alrm(int signo);## 11 ##src/rtt/dg_send_recv.c##
+static sigjmp_buf jmpbuf;## 12 ##src/rtt/dg_send_recv.c##
+
+ssize_t## 13 ##src/rtt/dg_send_recv.c##
+dg_send_recv(int fd, const void *outbuff, size_t outbytes,## 14 ##src/rtt/dg_send_recv.c##
+             void *inbuff, size_t inbytes,## 15 ##src/rtt/dg_send_recv.c##
+             const SA *destaddr, socklen_t destlen)## 16 ##src/rtt/dg_send_recv.c##
+{## 17 ##src/rtt/dg_send_recv.c##
+    ssize_t n;## 18 ##src/rtt/dg_send_recv.c##
+    struct iovec iovsend[2], iovrecv[2];## 19 ##src/rtt/dg_send_recv.c##
+
+    if (rttinit == 0) {## 20 ##src/rtt/dg_send_recv.c##
+        rtt_init(&rttinfo);     /* first time we're called */## 21 ##src/rtt/dg_send_recv.c##
+        rttinit = 1;## 22 ##src/rtt/dg_send_recv.c##
+        rtt_d_flag = 1;## 23 ##src/rtt/dg_send_recv.c##
+    }## 24 ##src/rtt/dg_send_recv.c##
+
+    sendhdr.seq++;## 25 ##src/rtt/dg_send_recv.c##
+    msgsend.msg_name = destaddr;## 26 ##src/rtt/dg_send_recv.c##
+    msgsend.msg_namelen = destlen;## 27 ##src/rtt/dg_send_recv.c##
+    msgsend.msg_iov = iovsend;## 28 ##src/rtt/dg_send_recv.c##
+    msgsend.msg_iovlen = 2;## 29 ##src/rtt/dg_send_recv.c##
+    iovsend[0].iov_base = &sendhdr;## 30 ##src/rtt/dg_send_recv.c##
+    iovsend[0].iov_len = sizeof(struct hdr);## 31 ##src/rtt/dg_send_recv.c##
+    iovsend[1].iov_base = outbuff;## 32 ##src/rtt/dg_send_recv.c##
+    iovsend[1].iov_len = outbytes;## 33 ##src/rtt/dg_send_recv.c##
+
+    msgrecv.msg_name = NULL;## 34 ##src/rtt/dg_send_recv.c##
+    msgrecv.msg_namelen = 0;## 35 ##src/rtt/dg_send_recv.c##
+    msgrecv.msg_iov = iovrecv;## 36 ##src/rtt/dg_send_recv.c##
+    msgrecv.msg_iovlen = 2;## 37 ##src/rtt/dg_send_recv.c##
+    iovrecv[0].iov_base = &recvhdr;## 38 ##src/rtt/dg_send_recv.c##
+    iovrecv[0].iov_len = sizeof(struct hdr);## 39 ##src/rtt/dg_send_recv.c##
+    iovrecv[1].iov_base = inbuff;## 40 ##src/rtt/dg_send_recv.c##
+    iovrecv[1].iov_len = inbytes;## 41 ##src/rtt/dg_send_recv.c##
+/* end dgsendrecv1 */
+
+/* include dgsendrecv2 */
+    Signal(SIGALRM, sig_alrm);## 42 ##src/rtt/dg_send_recv.c##
+    rtt_newpack(&rttinfo);      /* initialize for this packet */## 43 ##src/rtt/dg_send_recv.c##
+
+  sendagain:## 44 ##src/rtt/dg_send_recv.c##
+    sendhdr.ts = rtt_ts(&rttinfo);## 45 ##src/rtt/dg_send_recv.c##
+    Sendmsg(fd, &msgsend, 0);## 46 ##src/rtt/dg_send_recv.c##
+
+    alarm(rtt_start(&rttinfo)); /* calc timeout value & start timer */## 47 ##src/rtt/dg_send_recv.c##
+
+    if (sigsetjmp(jmpbuf, 1) != 0) {## 48 ##src/rtt/dg_send_recv.c##
+        if (rtt_timeout(&rttinfo) < 0) {## 49 ##src/rtt/dg_send_recv.c##
+            err_msg("dg_send_recv: no response from server, giving up");## 50 ##src/rtt/dg_send_recv.c##
+            rttinit = 0;        /* reinit in case we're called again */## 51 ##src/rtt/dg_send_recv.c##
+            errno = ETIMEDOUT;## 52 ##src/rtt/dg_send_recv.c##
+            return (-1);## 53 ##src/rtt/dg_send_recv.c##
+        }## 54 ##src/rtt/dg_send_recv.c##
+        goto sendagain;## 55 ##src/rtt/dg_send_recv.c##
+    }## 56 ##src/rtt/dg_send_recv.c##
+
+    do {## 57 ##src/rtt/dg_send_recv.c##
+        n = Recvmsg(fd, &msgrecv, 0);## 58 ##src/rtt/dg_send_recv.c##
+    } while (n < sizeof(struct hdr) || recvhdr.seq != sendhdr.seq);## 59 ##src/rtt/dg_send_recv.c##
+
+    alarm(0);                   /* stop SIGALRM timer */## 60 ##src/rtt/dg_send_recv.c##
+    /* 4calculate & store new RTT estimator values */## 61 ##src/rtt/dg_send_recv.c##
+    rtt_stop(&rttinfo, rtt_ts(&rttinfo) - recvhdr.ts);## 62 ##src/rtt/dg_send_recv.c##
+
+    return (n - sizeof(struct hdr));    /* return size of received datagram */## 63 ##src/rtt/dg_send_recv.c##
+}## 64 ##src/rtt/dg_send_recv.c##
+
+static void## 65 ##src/rtt/dg_send_recv.c##
+sig_alrm(int signo)## 66 ##src/rtt/dg_send_recv.c##
+{## 67 ##src/rtt/dg_send_recv.c##
+    siglongjmp(jmpbuf, 1);## 68 ##src/rtt/dg_send_recv.c##
+}## 69 ##src/rtt/dg_send_recv.c##
+/* end dgsendrecv2 */
+
+ssize_t## 70 ##src/rtt/dg_send_recv.c##
+Dg_send_recv(int fd, const void *outbuff, size_t outbytes,## 71 ##src/rtt/dg_send_recv.c##
+             void *inbuff, size_t inbytes,## 72 ##src/rtt/dg_send_recv.c##
+             const SA *destaddr, socklen_t destlen)## 73 ##src/rtt/dg_send_recv.c##
+{## 74 ##src/rtt/dg_send_recv.c##
+    ssize_t n;## 75 ##src/rtt/dg_send_recv.c##
+
+    n = dg_send_recv(fd, outbuff, outbytes, inbuff, inbytes,## 76 ##src/rtt/dg_send_recv.c##
+                     destaddr, destlen);## 77 ##src/rtt/dg_send_recv.c##
+    if (n < 0)## 78 ##src/rtt/dg_send_recv.c##
+        err_quit("dg_send_recv error");## 79 ##src/rtt/dg_send_recv.c##
+
+    return (n);## 80 ##src/rtt/dg_send_recv.c##
+}## 81 ##src/rtt/dg_send_recv.c##
diff --git a/rtt/rtt.out.kumba.1 b/rtt/rtt.out.kumba.1
new file mode 100644 (file)
index 0000000..1d65120
--- /dev/null
@@ -0,0 +1,1516 @@
+send    1: rtt = 0.000, srtt = 0.000, rttvar = 0.750, rto = 3.000
+recv    1
+updated rto
+send    2: rtt = 0.366, srtt = 0.046, rttvar = 0.654, rto = 2.662
+recv    2
+updated rto
+send    3: rtt = 0.309, srtt = 0.079, rttvar = 0.556, rto = 2.304
+recv    3
+updated rto
+send    4: rtt = 0.298, srtt = 0.106, rttvar = 0.472, rto = 2.000
+recv    4
+updated rto
+send    5: rtt = 0.360, srtt = 0.138, rttvar = 0.418, rto = 2.000
+recv    5
+updated rto
+send    6: rtt = 0.360, srtt = 0.166, rttvar = 0.369, rto = 2.000
+recv    6
+updated rto
+send    7: rtt = 0.320, srtt = 0.185, rttvar = 0.315, rto = 2.000
+recv    7
+updated rto
+send    8: rtt = 0.340, srtt = 0.204, rttvar = 0.275, rto = 2.000
+recv    8
+updated rto
+send    9: rtt = 0.330, srtt = 0.220, rttvar = 0.238, rto = 2.000
+recv    9
+updated rto
+send   10: rtt = 0.350, srtt = 0.236, rttvar = 0.211, rto = 2.000
+recv   10
+updated rto
+send   11: rtt = 0.349, srtt = 0.250, rttvar = 0.186, rto = 2.000
+recv   11
+updated rto
+send   12: rtt = 0.380, srtt = 0.267, rttvar = 0.172, rto = 2.000
+recv   12
+updated rto
+send   13: rtt = 0.349, srtt = 0.277, rttvar = 0.150, rto = 2.000
+recv   13
+updated rto
+send   14: rtt = 0.340, srtt = 0.285, rttvar = 0.128, rto = 2.000
+recv   14
+updated rto
+send   15: rtt = 0.280, srtt = 0.284, rttvar = 0.097, rto = 2.000
+recv   15
+updated rto
+send   16: rtt = 0.330, srtt = 0.290, rttvar = 0.084, rto = 2.000
+recv   16
+updated rto
+send   17: rtt = 0.340, srtt = 0.296, rttvar = 0.076, rto = 2.000
+recv   17
+updated rto
+send   18: rtt = 0.340, srtt = 0.302, rttvar = 0.068, rto = 2.000
+recv   18
+updated rto
+send   19: rtt = 0.349, srtt = 0.308, rttvar = 0.063, rto = 2.000
+recv   19
+updated rto
+send   20: rtt = 0.310, srtt = 0.308, rttvar = 0.048, rto = 2.000
+recv   20
+updated rto
+send   21: rtt = 0.350, srtt = 0.313, rttvar = 0.046, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send   21: rtt = 0.350, srtt = 0.313, rttvar = 0.046, rto = 4.000
+recv   21
+updated rto
+send   22: rtt = 0.340, srtt = 0.316, rttvar = 0.041, rto = 2.000
+recv   22
+updated rto
+send   23: rtt = 0.350, srtt = 0.321, rttvar = 0.039, rto = 2.000
+recv   23
+updated rto
+send   24: rtt = 0.319, srtt = 0.320, rttvar = 0.030, rto = 2.000
+recv   24
+updated rto
+send   25: rtt = 0.360, srtt = 0.325, rttvar = 0.032, rto = 2.000
+recv   25
+updated rto
+send   26: rtt = 0.290, srtt = 0.321, rttvar = 0.033, rto = 2.000
+recv   26
+updated rto
+send   27: rtt = 0.310, srtt = 0.320, rttvar = 0.028, rto = 2.000
+recv   27
+updated rto
+send   28: rtt = 0.340, srtt = 0.322, rttvar = 0.026, rto = 2.000
+recv   28
+updated rto
+send   29: rtt = 0.371, srtt = 0.328, rttvar = 0.032, rto = 2.000
+recv   29
+updated rto
+send   30: rtt = 0.368, srtt = 0.333, rttvar = 0.034, rto = 2.000
+recv   30
+updated rto
+send   31: rtt = 0.350, srtt = 0.335, rttvar = 0.029, rto = 2.000
+recv   31
+updated rto
+send   32: rtt = 0.364, srtt = 0.339, rttvar = 0.029, rto = 2.000
+recv   32
+updated rto
+send   33: rtt = 0.335, srtt = 0.338, rttvar = 0.023, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send   33: rtt = 0.335, srtt = 0.338, rttvar = 0.023, rto = 4.000
+recv   33
+updated rto
+send   34: rtt = 0.330, srtt = 0.337, rttvar = 0.019, rto = 2.000
+recv   34
+updated rto
+send   35: rtt = 0.290, srtt = 0.331, rttvar = 0.026, rto = 2.000
+recv   35
+updated rto
+send   36: rtt = 0.390, srtt = 0.339, rttvar = 0.034, rto = 2.000
+recv   36
+updated rto
+send   37: rtt = 0.355, srtt = 0.341, rttvar = 0.030, rto = 2.000
+recv   37
+updated rto
+send   38: rtt = 0.334, srtt = 0.340, rttvar = 0.024, rto = 2.000
+recv   38
+updated rto
+send   39: rtt = 0.320, srtt = 0.337, rttvar = 0.023, rto = 2.000
+recv   39
+updated rto
+send   40: rtt = 0.344, srtt = 0.338, rttvar = 0.019, rto = 2.000
+recv   40
+updated rto
+send   41: rtt = 0.345, srtt = 0.339, rttvar = 0.016, rto = 2.000
+recv   41
+updated rto
+send   42: rtt = 0.349, srtt = 0.340, rttvar = 0.014, rto = 2.000
+recv   42
+updated rto
+send   43: rtt = 0.305, srtt = 0.336, rttvar = 0.020, rto = 2.000
+recv   43
+updated rto
+send   44: rtt = 0.284, srtt = 0.329, rttvar = 0.028, rto = 2.000
+recv   44
+updated rto
+send   45: rtt = 0.320, srtt = 0.328, rttvar = 0.023, rto = 2.000
+recv   45
+updated rto
+send   46: rtt = 0.320, srtt = 0.327, rttvar = 0.019, rto = 2.000
+recv   46
+updated rto
+send   47: rtt = 0.340, srtt = 0.329, rttvar = 0.018, rto = 2.000
+recv   47
+updated rto
+send   48: rtt = 0.309, srtt = 0.326, rttvar = 0.018, rto = 2.000
+recv   48
+updated rto
+send   49: rtt = 0.310, srtt = 0.324, rttvar = 0.018, rto = 2.000
+recv   49
+updated rto
+send   50: rtt = 0.320, srtt = 0.324, rttvar = 0.014, rto = 2.000
+recv   50
+updated rto
+send   51: rtt = 0.320, srtt = 0.323, rttvar = 0.012, rto = 2.000
+recv   51
+updated rto
+send   52: rtt = 0.300, srtt = 0.320, rttvar = 0.015, rto = 2.000
+recv   52
+updated rto
+send   53: rtt = 0.320, srtt = 0.320, rttvar = 0.011, rto = 2.000
+recv   53
+updated rto
+send   54: rtt = 0.350, srtt = 0.324, rttvar = 0.016, rto = 2.000
+recv   54
+updated rto
+send   55: rtt = 0.349, srtt = 0.327, rttvar = 0.018, rto = 2.000
+recv   55
+updated rto
+send   56: rtt = 0.339, srtt = 0.329, rttvar = 0.016, rto = 2.000
+recv   56
+updated rto
+send   57: rtt = 0.350, srtt = 0.331, rttvar = 0.018, rto = 2.000
+recv   57
+updated rto
+send   58: rtt = 0.319, srtt = 0.330, rttvar = 0.016, rto = 2.000
+recv   58
+updated rto
+send   59: rtt = 0.309, srtt = 0.327, rttvar = 0.017, rto = 2.000
+recv   59
+updated rto
+send   60: rtt = 0.310, srtt = 0.325, rttvar = 0.017, rto = 2.000
+recv   60
+updated rto
+send   61: rtt = 0.320, srtt = 0.324, rttvar = 0.014, rto = 2.000
+recv   61
+updated rto
+send   62: rtt = 0.300, srtt = 0.321, rttvar = 0.017, rto = 2.000
+recv   62
+updated rto
+send   63: rtt = 0.309, srtt = 0.320, rttvar = 0.016, rto = 2.000
+recv   63
+updated rto
+send   64: rtt = 0.290, srtt = 0.316, rttvar = 0.019, rto = 2.000
+recv   64
+updated rto
+send   65: rtt = 0.320, srtt = 0.317, rttvar = 0.015, rto = 2.000
+recv   65
+updated rto
+send   66: rtt = 0.280, srtt = 0.312, rttvar = 0.021, rto = 2.000
+recv   66
+updated rto
+send   67: rtt = 0.339, srtt = 0.315, rttvar = 0.022, rto = 2.000
+recv   67
+updated rto
+send   68: rtt = 0.330, srtt = 0.317, rttvar = 0.020, rto = 2.000
+recv   68
+updated rto
+send   69: rtt = 0.320, srtt = 0.318, rttvar = 0.016, rto = 2.000
+recv   69
+updated rto
+send   70: rtt = 0.280, srtt = 0.313, rttvar = 0.021, rto = 2.000
+recv   70
+updated rto
+send   71: rtt = 0.319, srtt = 0.314, rttvar = 0.018, rto = 2.000
+recv   71
+updated rto
+send   72: rtt = 0.339, srtt = 0.317, rttvar = 0.020, rto = 2.000
+recv   72
+updated rto
+send   73: rtt = 0.309, srtt = 0.316, rttvar = 0.017, rto = 2.000
+recv   73
+updated rto
+send   74: rtt = 0.340, srtt = 0.319, rttvar = 0.018, rto = 2.000
+recv   74
+updated rto
+send   75: rtt = 0.330, srtt = 0.320, rttvar = 0.017, rto = 2.000
+recv   75
+updated rto
+send   76: rtt = 0.280, srtt = 0.315, rttvar = 0.023, rto = 2.000
+recv   76
+updated rto
+send   77: rtt = 0.320, srtt = 0.316, rttvar = 0.018, rto = 2.000
+recv   77
+updated rto
+send   78: rtt = 0.280, srtt = 0.311, rttvar = 0.023, rto = 2.000
+recv   78
+updated rto
+send   79: rtt = 0.330, srtt = 0.314, rttvar = 0.022, rto = 2.000
+recv   79
+updated rto
+send   80: rtt = 0.349, srtt = 0.318, rttvar = 0.025, rto = 2.000
+recv   80
+updated rto
+send   81: rtt = 0.320, srtt = 0.318, rttvar = 0.019, rto = 2.000
+recv   81
+updated rto
+send   82: rtt = 0.320, srtt = 0.319, rttvar = 0.015, rto = 2.000
+recv   82
+updated rto
+send   83: rtt = 0.329, srtt = 0.320, rttvar = 0.014, rto = 2.000
+recv   83
+updated rto
+send   84: rtt = 0.320, srtt = 0.320, rttvar = 0.010, rto = 2.000
+recv   84
+updated rto
+send   85: rtt = 0.329, srtt = 0.321, rttvar = 0.010, rto = 2.000
+recv   85
+updated rto
+send   86: rtt = 0.330, srtt = 0.322, rttvar = 0.010, rto = 2.000
+recv   86
+updated rto
+send   87: rtt = 0.339, srtt = 0.324, rttvar = 0.012, rto = 2.000
+recv   87
+updated rto
+send   88: rtt = 0.360, srtt = 0.329, rttvar = 0.018, rto = 2.000
+recv   88
+updated rto
+send   89: rtt = 0.320, srtt = 0.328, rttvar = 0.015, rto = 2.000
+recv   89
+updated rto
+send   90: rtt = 0.319, srtt = 0.327, rttvar = 0.014, rto = 2.000
+recv   90
+updated rto
+send   91: rtt = 0.330, srtt = 0.327, rttvar = 0.011, rto = 2.000
+recv   91
+updated rto
+send   92: rtt = 0.304, srtt = 0.324, rttvar = 0.014, rto = 2.000
+recv   92
+updated rto
+send   93: rtt = 0.316, srtt = 0.323, rttvar = 0.013, rto = 2.000
+recv   93
+updated rto
+send   94: rtt = 0.319, srtt = 0.323, rttvar = 0.010, rto = 2.000
+recv   94
+updated rto
+send   95: rtt = 0.360, srtt = 0.327, rttvar = 0.017, rto = 2.000
+recv   95
+updated rto
+send   96: rtt = 0.316, srtt = 0.326, rttvar = 0.016, rto = 2.000
+recv   96
+updated rto
+send   97: rtt = 0.314, srtt = 0.324, rttvar = 0.015, rto = 2.000
+recv   97
+updated rto
+send   98: rtt = 0.330, srtt = 0.325, rttvar = 0.012, rto = 2.000
+recv   98
+updated rto
+send   99: rtt = 0.330, srtt = 0.326, rttvar = 0.011, rto = 2.000
+recv   99
+updated rto
+send  100: rtt = 0.360, srtt = 0.330, rttvar = 0.017, rto = 2.000
+recv  100
+updated rto
+send  101: rtt = 0.330, srtt = 0.330, rttvar = 0.012, rto = 2.000
+recv  101
+updated rto
+send  102: rtt = 0.350, srtt = 0.332, rttvar = 0.014, rto = 2.000
+recv  102
+updated rto
+send  103: rtt = 0.320, srtt = 0.331, rttvar = 0.014, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  103: rtt = 0.320, srtt = 0.331, rttvar = 0.014, rto = 4.000
+recv  103
+updated rto
+send  104: rtt = 0.340, srtt = 0.332, rttvar = 0.013, rto = 2.000
+recv  104
+updated rto
+send  105: rtt = 0.340, srtt = 0.333, rttvar = 0.011, rto = 2.000
+recv  105
+updated rto
+send  106: rtt = 0.320, srtt = 0.331, rttvar = 0.012, rto = 2.000
+recv  106
+updated rto
+send  107: rtt = 0.340, srtt = 0.332, rttvar = 0.011, rto = 2.000
+recv  107
+updated rto
+send  108: rtt = 0.340, srtt = 0.333, rttvar = 0.010, rto = 2.000
+recv  108
+updated rto
+send  109: rtt = 0.340, srtt = 0.334, rttvar = 0.009, rto = 2.000
+recv  109
+updated rto
+send  110: rtt = 0.369, srtt = 0.339, rttvar = 0.016, rto = 2.000
+recv  110
+updated rto
+send  111: rtt = 0.350, srtt = 0.340, rttvar = 0.015, rto = 2.000
+recv  111
+updated rto
+send  112: rtt = 0.369, srtt = 0.344, rttvar = 0.018, rto = 2.000
+recv  112
+updated rto
+send  113: rtt = 0.339, srtt = 0.343, rttvar = 0.015, rto = 2.000
+recv  113
+updated rto
+send  114: rtt = 0.349, srtt = 0.344, rttvar = 0.013, rto = 2.000
+recv  114
+updated rto
+send  115: rtt = 0.319, srtt = 0.341, rttvar = 0.016, rto = 2.000
+recv  115
+updated rto
+send  116: rtt = 0.340, srtt = 0.341, rttvar = 0.012, rto = 2.000
+recv  116
+updated rto
+send  117: rtt = 0.319, srtt = 0.338, rttvar = 0.014, rto = 2.000
+recv  117
+updated rto
+send  118: rtt = 0.340, srtt = 0.338, rttvar = 0.011, rto = 2.000
+recv  118
+updated rto
+send  119: rtt = 0.380, srtt = 0.343, rttvar = 0.019, rto = 2.000
+recv  119
+updated rto
+send  120: rtt = 0.340, srtt = 0.343, rttvar = 0.015, rto = 2.000
+recv  120
+updated rto
+send  121: rtt = 0.320, srtt = 0.340, rttvar = 0.017, rto = 2.000
+recv  121
+updated rto
+send  122: rtt = 0.340, srtt = 0.340, rttvar = 0.013, rto = 2.000
+recv  122
+updated rto
+send  123: rtt = 0.360, srtt = 0.343, rttvar = 0.015, rto = 2.000
+recv  123
+updated rto
+send  124: rtt = 0.359, srtt = 0.345, rttvar = 0.015, rto = 2.000
+recv  124
+updated rto
+send  125: rtt = 0.330, srtt = 0.343, rttvar = 0.015, rto = 2.000
+recv  125
+updated rto
+send  126: rtt = 0.329, srtt = 0.341, rttvar = 0.015, rto = 2.000
+recv  126
+updated rto
+send  127: rtt = 0.340, srtt = 0.341, rttvar = 0.011, rto = 2.000
+recv  127
+updated rto
+send  128: rtt = 0.360, srtt = 0.343, rttvar = 0.013, rto = 2.000
+recv  128
+updated rto
+send  129: rtt = 0.320, srtt = 0.340, rttvar = 0.016, rto = 2.000
+recv  129
+updated rto
+send  130: rtt = 0.340, srtt = 0.340, rttvar = 0.012, rto = 2.000
+recv  130
+updated rto
+send  131: rtt = 0.350, srtt = 0.342, rttvar = 0.011, rto = 2.000
+recv  131
+updated rto
+send  132: rtt = 0.340, srtt = 0.341, rttvar = 0.009, rto = 2.000
+recv  132
+updated rto
+send  133: rtt = 0.370, srtt = 0.345, rttvar = 0.014, rto = 2.000
+recv  133
+updated rto
+send  134: rtt = 0.339, srtt = 0.344, rttvar = 0.012, rto = 2.000
+recv  134
+updated rto
+send  135: rtt = 0.330, srtt = 0.342, rttvar = 0.012, rto = 2.000
+recv  135
+updated rto
+send  136: rtt = 0.340, srtt = 0.342, rttvar = 0.010, rto = 2.000
+recv  136
+updated rto
+send  137: rtt = 0.300, srtt = 0.337, rttvar = 0.018, rto = 2.000
+recv  137
+updated rto
+send  138: rtt = 0.340, srtt = 0.337, rttvar = 0.014, rto = 2.000
+recv  138
+updated rto
+send  139: rtt = 0.340, srtt = 0.338, rttvar = 0.011, rto = 2.000
+recv  139
+updated rto
+send  140: rtt = 0.380, srtt = 0.343, rttvar = 0.019, rto = 2.000
+recv  140
+updated rto
+send  141: rtt = 0.450, srtt = 0.356, rttvar = 0.041, rto = 2.000
+recv  141
+updated rto
+send  142: rtt = 0.370, srtt = 0.358, rttvar = 0.034, rto = 2.000
+recv  142
+updated rto
+send  143: rtt = 0.309, srtt = 0.352, rttvar = 0.038, rto = 2.000
+recv  143
+updated rto
+send  144: rtt = 0.290, srtt = 0.344, rttvar = 0.044, rto = 2.000
+recv  144
+updated rto
+send  145: rtt = 0.390, srtt = 0.350, rttvar = 0.044, rto = 2.000
+recv  145
+updated rto
+send  146: rtt = 0.329, srtt = 0.347, rttvar = 0.039, rto = 2.000
+recv  146
+updated rto
+send  147: rtt = 0.330, srtt = 0.345, rttvar = 0.033, rto = 2.000
+recv  147
+updated rto
+send  148: rtt = 0.320, srtt = 0.342, rttvar = 0.031, rto = 2.000
+recv  148
+updated rto
+send  149: rtt = 0.340, srtt = 0.342, rttvar = 0.024, rto = 2.000
+recv  149
+updated rto
+send  150: rtt = 0.359, srtt = 0.344, rttvar = 0.022, rto = 2.000
+recv  150
+updated rto
+send  151: rtt = 0.350, srtt = 0.345, rttvar = 0.018, rto = 2.000
+recv  151
+updated rto
+send  152: rtt = 0.349, srtt = 0.345, rttvar = 0.015, rto = 2.000
+recv  152
+updated rto
+send  153: rtt = 0.400, srtt = 0.352, rttvar = 0.025, rto = 2.000
+recv  153
+updated rto
+send  154: rtt = 0.350, srtt = 0.352, rttvar = 0.019, rto = 2.000
+recv  154
+updated rto
+send  155: rtt = 0.370, srtt = 0.354, rttvar = 0.019, rto = 2.000
+recv  155
+updated rto
+send  156: rtt = 0.359, srtt = 0.355, rttvar = 0.015, rto = 2.000
+recv  156
+updated rto
+send  157: rtt = 0.349, srtt = 0.354, rttvar = 0.013, rto = 2.000
+recv  157
+updated rto
+send  158: rtt = 0.360, srtt = 0.355, rttvar = 0.011, rto = 2.000
+recv  158
+updated rto
+send  159: rtt = 0.319, srtt = 0.350, rttvar = 0.017, rto = 2.000
+recv  159
+updated rto
+send  160: rtt = 0.320, srtt = 0.346, rttvar = 0.021, rto = 2.000
+recv  160
+updated rto
+send  161: rtt = 0.330, srtt = 0.344, rttvar = 0.020, rto = 2.000
+recv  161
+updated rto
+send  162: rtt = 0.340, srtt = 0.344, rttvar = 0.016, rto = 2.000
+recv  162
+updated rto
+send  163: rtt = 0.350, srtt = 0.345, rttvar = 0.013, rto = 2.000
+recv  163
+updated rto
+send  164: rtt = 0.350, srtt = 0.345, rttvar = 0.011, rto = 2.000
+recv  164
+updated rto
+send  165: rtt = 0.339, srtt = 0.345, rttvar = 0.010, rto = 2.000
+recv  165
+updated rto
+send  166: rtt = 0.339, srtt = 0.344, rttvar = 0.009, rto = 2.000
+recv  166
+updated rto
+send  167: rtt = 0.330, srtt = 0.342, rttvar = 0.010, rto = 2.000
+recv  167
+updated rto
+send  168: rtt = 0.310, srtt = 0.338, rttvar = 0.016, rto = 2.000
+recv  168
+updated rto
+send  169: rtt = 0.310, srtt = 0.335, rttvar = 0.019, rto = 2.000
+recv  169
+updated rto
+send  170: rtt = 0.320, srtt = 0.333, rttvar = 0.018, rto = 2.000
+recv  170
+updated rto
+send  171: rtt = 0.339, srtt = 0.334, rttvar = 0.015, rto = 2.000
+recv  171
+updated rto
+send  172: rtt = 0.320, srtt = 0.332, rttvar = 0.015, rto = 2.000
+recv  172
+updated rto
+send  173: rtt = 0.319, srtt = 0.330, rttvar = 0.014, rto = 2.000
+recv  173
+updated rto
+send  174: rtt = 0.320, srtt = 0.329, rttvar = 0.013, rto = 2.000
+recv  174
+updated rto
+send  175: rtt = 0.319, srtt = 0.328, rttvar = 0.012, rto = 2.000
+recv  175
+updated rto
+send  176: rtt = 0.309, srtt = 0.325, rttvar = 0.014, rto = 2.000
+recv  176
+updated rto
+send  177: rtt = 0.340, srtt = 0.327, rttvar = 0.014, rto = 2.000
+recv  177
+updated rto
+send  178: rtt = 0.334, srtt = 0.328, rttvar = 0.012, rto = 2.000
+recv  178
+updated rto
+send  179: rtt = 0.315, srtt = 0.326, rttvar = 0.012, rto = 2.000
+recv  179
+updated rto
+send  180: rtt = 0.309, srtt = 0.324, rttvar = 0.014, rto = 2.000
+recv  180
+updated rto
+send  181: rtt = 0.309, srtt = 0.322, rttvar = 0.014, rto = 2.000
+recv  181
+updated rto
+send  182: rtt = 0.330, srtt = 0.323, rttvar = 0.012, rto = 2.000
+recv  182
+updated rto
+send  183: rtt = 0.370, srtt = 0.329, rttvar = 0.021, rto = 2.000
+recv  183
+updated rto
+send  184: rtt = 0.320, srtt = 0.328, rttvar = 0.018, rto = 2.000
+recv  184
+updated rto
+send  185: rtt = 0.380, srtt = 0.334, rttvar = 0.027, rto = 2.000
+recv  185
+updated rto
+send  186: rtt = 0.350, srtt = 0.336, rttvar = 0.024, rto = 2.000
+recv  186
+updated rto
+send  187: rtt = 0.309, srtt = 0.333, rttvar = 0.025, rto = 2.000
+recv  187
+updated rto
+send  188: rtt = 0.330, srtt = 0.333, rttvar = 0.019, rto = 2.000
+recv  188
+updated rto
+send  189: rtt = 0.320, srtt = 0.331, rttvar = 0.018, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  189: rtt = 0.320, srtt = 0.331, rttvar = 0.018, rto = 4.000
+recv  189
+updated rto
+send  190: rtt = 0.329, srtt = 0.331, rttvar = 0.014, rto = 2.000
+recv  190
+updated rto
+send  191: rtt = 0.310, srtt = 0.328, rttvar = 0.015, rto = 2.000
+recv  191
+updated rto
+send  192: rtt = 0.319, srtt = 0.327, rttvar = 0.014, rto = 2.000
+recv  192
+updated rto
+send  193: rtt = 0.310, srtt = 0.325, rttvar = 0.015, rto = 2.000
+recv  193
+updated rto
+send  194: rtt = 0.300, srtt = 0.322, rttvar = 0.017, rto = 2.000
+recv  194
+updated rto
+send  195: rtt = 0.309, srtt = 0.320, rttvar = 0.016, rto = 2.000
+recv  195
+updated rto
+send  196: rtt = 0.319, srtt = 0.320, rttvar = 0.012, rto = 2.000
+recv  196
+updated rto
+send  197: rtt = 0.310, srtt = 0.319, rttvar = 0.012, rto = 2.000
+recv  197
+updated rto
+send  198: rtt = 0.309, srtt = 0.318, rttvar = 0.011, rto = 2.000
+recv  198
+updated rto
+send  199: rtt = 0.330, srtt = 0.319, rttvar = 0.012, rto = 2.000
+recv  199
+updated rto
+send  200: rtt = 0.299, srtt = 0.317, rttvar = 0.014, rto = 2.000
+recv  200
+updated rto
+send  201: rtt = 0.310, srtt = 0.316, rttvar = 0.012, rto = 2.000
+recv  201
+updated rto
+send  202: rtt = 0.354, srtt = 0.321, rttvar = 0.019, rto = 2.000
+recv  202
+updated rto
+send  203: rtt = 0.312, srtt = 0.319, rttvar = 0.016, rto = 2.000
+recv  203
+updated rto
+send  204: rtt = 0.303, srtt = 0.317, rttvar = 0.016, rto = 2.000
+recv  204
+updated rto
+send  205: rtt = 0.329, srtt = 0.319, rttvar = 0.015, rto = 2.000
+recv  205
+updated rto
+send  206: rtt = 0.319, srtt = 0.319, rttvar = 0.011, rto = 2.000
+recv  206
+updated rto
+send  207: rtt = 0.339, srtt = 0.321, rttvar = 0.013, rto = 2.000
+recv  207
+updated rto
+send  208: rtt = 0.310, srtt = 0.320, rttvar = 0.013, rto = 2.000
+recv  208
+updated rto
+send  209: rtt = 0.321, srtt = 0.320, rttvar = 0.010, rto = 2.000
+recv  209
+updated rto
+send  210: rtt = 0.308, srtt = 0.319, rttvar = 0.011, rto = 2.000
+recv  210
+updated rto
+send  211: rtt = 0.350, srtt = 0.323, rttvar = 0.016, rto = 2.000
+recv  211
+updated rto
+send  212: rtt = 0.359, srtt = 0.327, rttvar = 0.021, rto = 2.000
+recv  212
+updated rto
+send  213: rtt = 0.310, srtt = 0.325, rttvar = 0.020, rto = 2.000
+recv  213
+updated rto
+send  214: rtt = 0.329, srtt = 0.325, rttvar = 0.016, rto = 2.000
+recv  214
+updated rto
+send  215: rtt = 0.310, srtt = 0.324, rttvar = 0.016, rto = 2.000
+recv  215
+updated rto
+send  216: rtt = 0.772, srtt = 0.380, rttvar = 0.124, rto = 2.000
+recv  216
+updated rto
+send  217: rtt = 0.317, srtt = 0.372, rttvar = 0.109, rto = 2.000
+recv  217
+updated rto
+send  218: rtt = 0.379, srtt = 0.373, rttvar = 0.083, rto = 2.000
+recv  218
+updated rto
+send  219: rtt = 0.310, srtt = 0.365, rttvar = 0.078, rto = 2.000
+recv  219
+updated rto
+send  220: rtt = 0.304, srtt = 0.357, rttvar = 0.074, rto = 2.000
+recv  220
+updated rto
+send  221: rtt = 0.315, srtt = 0.352, rttvar = 0.066, rto = 2.000
+recv  221
+updated rto
+send  222: rtt = 0.340, srtt = 0.350, rttvar = 0.052, rto = 2.000
+recv  222
+updated rto
+send  223: rtt = 0.329, srtt = 0.348, rttvar = 0.045, rto = 2.000
+recv  223
+updated rto
+send  224: rtt = 0.349, srtt = 0.348, rttvar = 0.034, rto = 2.000
+recv  224
+updated rto
+send  225: rtt = 0.350, srtt = 0.348, rttvar = 0.026, rto = 2.000
+recv  225
+updated rto
+send  226: rtt = 0.360, srtt = 0.350, rttvar = 0.022, rto = 2.000
+recv  226
+updated rto
+send  227: rtt = 0.380, srtt = 0.353, rttvar = 0.024, rto = 2.000
+recv  227
+updated rto
+send  228: rtt = 0.320, srtt = 0.349, rttvar = 0.027, rto = 2.000
+recv  228
+updated rto
+send  229: rtt = 0.319, srtt = 0.345, rttvar = 0.028, rto = 2.000
+recv  229
+updated rto
+send  230: rtt = 0.370, srtt = 0.349, rttvar = 0.027, rto = 2.000
+recv  230
+updated rto
+send  231: rtt = 0.358, srtt = 0.350, rttvar = 0.022, rto = 2.000
+recv  231
+updated rto
+send  232: rtt = 0.340, srtt = 0.349, rttvar = 0.019, rto = 2.000
+recv  232
+updated rto
+send  233: rtt = 0.360, srtt = 0.350, rttvar = 0.017, rto = 2.000
+recv  233
+updated rto
+send  234: rtt = 0.289, srtt = 0.342, rttvar = 0.028, rto = 2.000
+recv  234
+updated rto
+send  235: rtt = 0.350, srtt = 0.343, rttvar = 0.023, rto = 2.000
+recv  235
+updated rto
+send  236: rtt = 0.310, srtt = 0.339, rttvar = 0.026, rto = 2.000
+recv  236
+updated rto
+send  237: rtt = 0.319, srtt = 0.337, rttvar = 0.024, rto = 2.000
+recv  237
+updated rto
+send  238: rtt = 0.330, srtt = 0.336, rttvar = 0.020, rto = 2.000
+recv  238
+updated rto
+send  239: rtt = 0.308, srtt = 0.332, rttvar = 0.022, rto = 2.000
+recv  239
+updated rto
+send  240: rtt = 0.320, srtt = 0.331, rttvar = 0.019, rto = 2.000
+recv  240
+updated rto
+send  241: rtt = 0.290, srtt = 0.326, rttvar = 0.025, rto = 2.000
+recv  241
+updated rto
+send  242: rtt = 0.360, srtt = 0.330, rttvar = 0.027, rto = 2.000
+recv  242
+updated rto
+send  243: rtt = 0.330, srtt = 0.330, rttvar = 0.020, rto = 2.000
+recv  243
+updated rto
+send  244: rtt = 0.339, srtt = 0.331, rttvar = 0.018, rto = 2.000
+recv  244
+updated rto
+send  245: rtt = 0.350, srtt = 0.333, rttvar = 0.018, rto = 2.000
+recv  245
+updated rto
+send  246: rtt = 0.330, srtt = 0.333, rttvar = 0.014, rto = 2.000
+recv  246
+updated rto
+send  247: rtt = 0.309, srtt = 0.330, rttvar = 0.017, rto = 2.000
+recv  247
+updated rto
+send  248: rtt = 0.329, srtt = 0.330, rttvar = 0.013, rto = 2.000
+recv  248
+updated rto
+send  249: rtt = 0.360, srtt = 0.334, rttvar = 0.017, rto = 2.000
+recv  249
+updated rto
+send  250: rtt = 0.350, srtt = 0.336, rttvar = 0.017, rto = 2.000
+recv  250
+updated rto
+send  251: rtt = 0.340, srtt = 0.336, rttvar = 0.014, rto = 2.000
+recv  251
+updated rto
+send  252: rtt = 0.410, srtt = 0.345, rttvar = 0.029, rto = 2.000
+recv  252
+updated rto
+send  253: rtt = 0.339, srtt = 0.345, rttvar = 0.023, rto = 2.000
+recv  253
+updated rto
+send  254: rtt = 0.335, srtt = 0.343, rttvar = 0.020, rto = 2.000
+recv  254
+updated rto
+send  255: rtt = 0.335, srtt = 0.342, rttvar = 0.017, rto = 2.000
+recv  255
+updated rto
+send  256: rtt = 0.319, srtt = 0.339, rttvar = 0.019, rto = 2.000
+recv  256
+updated rto
+send  257: rtt = 0.350, srtt = 0.341, rttvar = 0.017, rto = 2.000
+recv  257
+updated rto
+send  258: rtt = 0.310, srtt = 0.337, rttvar = 0.020, rto = 2.000
+recv  258
+updated rto
+send  259: rtt = 0.320, srtt = 0.335, rttvar = 0.019, rto = 2.000
+recv  259
+updated rto
+send  260: rtt = 0.319, srtt = 0.333, rttvar = 0.018, rto = 2.000
+recv  260
+updated rto
+send  261: rtt = 0.300, srtt = 0.329, rttvar = 0.022, rto = 2.000
+recv  261
+updated rto
+send  262: rtt = 0.389, srtt = 0.336, rttvar = 0.032, rto = 2.000
+recv  262
+updated rto
+send  263: rtt = 1.259, srtt = 0.452, rttvar = 0.254, rto = 2.000
+recv  263
+updated rto
+send  264: rtt = 0.819, srtt = 0.498, rttvar = 0.283, rto = 2.000
+recv  264
+updated rto
+send  265: rtt = 0.809, srtt = 0.536, rttvar = 0.290, rto = 2.000
+recv  265
+updated rto
+send  266: rtt = 0.809, srtt = 0.571, rttvar = 0.286, rto = 2.000
+recv  266
+updated rto
+send  267: rtt = 0.819, srtt = 0.602, rttvar = 0.276, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  267: rtt = 0.819, srtt = 0.602, rttvar = 0.276, rto = 4.000
+recv  267
+updated rto
+send  268: rtt = 0.748, srtt = 0.620, rttvar = 0.244, rto = 2.000
+recv  268
+updated rto
+send  269: rtt = 0.819, srtt = 0.645, rttvar = 0.233, rto = 2.000
+recv  269
+updated rto
+send  270: rtt = 0.819, srtt = 0.667, rttvar = 0.218, rto = 2.000
+recv  270
+updated rto
+send  271: rtt = 0.819, srtt = 0.686, rttvar = 0.202, rto = 2.000
+recv  271
+updated rto
+send  272: rtt = 0.799, srtt = 0.700, rttvar = 0.180, rto = 2.000
+recv  272
+updated rto
+send  273: rtt = 1.059, srtt = 0.745, rttvar = 0.224, rto = 2.000
+recv  273
+updated rto
+send  274: rtt = 0.370, srtt = 0.698, rttvar = 0.262, rto = 2.000
+recv  274
+updated rto
+send  275: rtt = 0.370, srtt = 0.657, rttvar = 0.278, rto = 2.000
+recv  275
+updated rto
+send  276: rtt = 0.380, srtt = 0.622, rttvar = 0.278, rto = 2.000
+recv  276
+updated rto
+send  277: rtt = 0.340, srtt = 0.587, rttvar = 0.279, rto = 2.000
+recv  277
+updated rto
+send  278: rtt = 0.400, srtt = 0.564, rttvar = 0.256, rto = 2.000
+recv  278
+updated rto
+send  279: rtt = 0.350, srtt = 0.537, rttvar = 0.245, rto = 2.000
+recv  279
+updated rto
+send  280: rtt = 0.320, srtt = 0.510, rttvar = 0.238, rto = 2.000
+recv  280
+updated rto
+send  281: rtt = 0.390, srtt = 0.495, rttvar = 0.209, rto = 2.000
+recv  281
+updated rto
+send  282: rtt = 0.329, srtt = 0.474, rttvar = 0.198, rto = 2.000
+recv  282
+updated rto
+send  283: rtt = 0.280, srtt = 0.450, rttvar = 0.197, rto = 2.000
+recv  283
+updated rto
+send  284: rtt = 0.330, srtt = 0.435, rttvar = 0.178, rto = 2.000
+recv  284
+updated rto
+send  285: rtt = 0.310, srtt = 0.419, rttvar = 0.164, rto = 2.000
+recv  285
+updated rto
+send  286: rtt = 0.370, srtt = 0.413, rttvar = 0.136, rto = 2.000
+recv  286
+updated rto
+send  287: rtt = 0.379, srtt = 0.409, rttvar = 0.110, rto = 2.000
+recv  287
+updated rto
+send  288: rtt = 0.329, srtt = 0.399, rttvar = 0.103, rto = 2.000
+recv  288
+updated rto
+send  289: rtt = 0.320, srtt = 0.389, rttvar = 0.097, rto = 2.000
+recv  289
+updated rto
+send  290: rtt = 0.410, srtt = 0.392, rttvar = 0.078, rto = 2.000
+recv  290
+updated rto
+send  291: rtt = 0.340, srtt = 0.385, rttvar = 0.071, rto = 2.000
+recv  291
+updated rto
+send  292: rtt = 0.360, srtt = 0.382, rttvar = 0.060, rto = 2.000
+recv  292
+updated rto
+send  293: rtt = 0.349, srtt = 0.378, rttvar = 0.053, rto = 2.000
+recv  293
+updated rto
+send  294: rtt = 0.360, srtt = 0.376, rttvar = 0.044, rto = 2.000
+recv  294
+updated rto
+send  295: rtt = 0.360, srtt = 0.374, rttvar = 0.037, rto = 2.000
+recv  295
+updated rto
+send  296: rtt = 0.329, srtt = 0.368, rttvar = 0.039, rto = 2.000
+recv  296
+updated rto
+send  297: rtt = 0.360, srtt = 0.367, rttvar = 0.031, rto = 2.000
+recv  297
+updated rto
+send  298: rtt = 0.340, srtt = 0.364, rttvar = 0.030, rto = 2.000
+recv  298
+updated rto
+send  299: rtt = 0.359, srtt = 0.363, rttvar = 0.024, rto = 2.000
+recv  299
+updated rto
+send  300: rtt = 0.369, srtt = 0.364, rttvar = 0.019, rto = 2.000
+recv  300
+updated rto
+send  301: rtt = 0.330, srtt = 0.360, rttvar = 0.023, rto = 2.000
+recv  301
+updated rto
+send  302: rtt = 0.320, srtt = 0.355, rttvar = 0.027, rto = 2.000
+recv  302
+updated rto
+send  303: rtt = 0.320, srtt = 0.350, rttvar = 0.029, rto = 2.000
+recv  303
+updated rto
+send  304: rtt = 0.313, srtt = 0.346, rttvar = 0.031, rto = 2.000
+recv  304
+updated rto
+send  305: rtt = 0.337, srtt = 0.345, rttvar = 0.025, rto = 2.000
+recv  305
+updated rto
+send  306: rtt = 0.320, srtt = 0.342, rttvar = 0.025, rto = 2.000
+recv  306
+updated rto
+send  307: rtt = 0.319, srtt = 0.339, rttvar = 0.025, rto = 2.000
+recv  307
+updated rto
+send  308: rtt = 0.680, srtt = 0.381, rttvar = 0.104, rto = 2.000
+recv  308
+updated rto
+send  309: rtt = 0.380, srtt = 0.381, rttvar = 0.078, rto = 2.000
+recv  309
+updated rto
+send  310: rtt = 0.319, srtt = 0.373, rttvar = 0.074, rto = 2.000
+recv  310
+updated rto
+send  311: rtt = 0.330, srtt = 0.368, rttvar = 0.066, rto = 2.000
+recv  311
+updated rto
+send  312: rtt = 0.330, srtt = 0.363, rttvar = 0.059, rto = 2.000
+recv  312
+updated rto
+send  313: rtt = 0.310, srtt = 0.357, rttvar = 0.058, rto = 2.000
+recv  313
+updated rto
+send  314: rtt = 0.300, srtt = 0.350, rttvar = 0.058, rto = 2.000
+recv  314
+updated rto
+send  315: rtt = 0.340, srtt = 0.348, rttvar = 0.046, rto = 2.000
+recv  315
+updated rto
+send  316: rtt = 0.350, srtt = 0.349, rttvar = 0.035, rto = 2.000
+recv  316
+updated rto
+send  317: rtt = 0.350, srtt = 0.349, rttvar = 0.026, rto = 2.000
+recv  317
+updated rto
+send  318: rtt = 0.340, srtt = 0.348, rttvar = 0.022, rto = 2.000
+recv  318
+updated rto
+send  319: rtt = 0.309, srtt = 0.343, rttvar = 0.026, rto = 2.000
+recv  319
+updated rto
+send  320: rtt = 0.343, srtt = 0.343, rttvar = 0.020, rto = 2.000
+recv  320
+updated rto
+send  321: rtt = 0.326, srtt = 0.341, rttvar = 0.019, rto = 2.000
+recv  321
+updated rto
+send  322: rtt = 0.319, srtt = 0.338, rttvar = 0.020, rto = 2.000
+recv  322
+updated rto
+send  323: rtt = 1.178, srtt = 0.443, rttvar = 0.225, rto = 2.000
+recv  323
+updated rto
+send  324: rtt = 0.320, srtt = 0.428, rttvar = 0.199, rto = 2.000
+recv  324
+updated rto
+send  325: rtt = 0.309, srtt = 0.413, rttvar = 0.179, rto = 2.000
+recv  325
+updated rto
+send  326: rtt = 0.330, srtt = 0.402, rttvar = 0.155, rto = 2.000
+recv  326
+updated rto
+send  327: rtt = 0.300, srtt = 0.390, rttvar = 0.142, rto = 2.000
+recv  327
+updated rto
+send  328: rtt = 0.300, srtt = 0.378, rttvar = 0.129, rto = 2.000
+recv  328
+updated rto
+send  329: rtt = 0.310, srtt = 0.370, rttvar = 0.114, rto = 2.000
+recv  329
+updated rto
+send  330: rtt = 0.290, srtt = 0.360, rttvar = 0.105, rto = 2.000
+recv  330
+updated rto
+send  331: rtt = 0.310, srtt = 0.354, rttvar = 0.091, rto = 2.000
+recv  331
+updated rto
+send  332: rtt = 0.300, srtt = 0.347, rttvar = 0.082, rto = 2.000
+recv  332
+updated rto
+send  333: rtt = 0.300, srtt = 0.341, rttvar = 0.073, rto = 2.000
+recv  333
+updated rto
+send  334: rtt = 0.340, srtt = 0.341, rttvar = 0.055, rto = 2.000
+recv  334
+updated rto
+send  335: rtt = 0.339, srtt = 0.341, rttvar = 0.042, rto = 2.000
+recv  335
+updated rto
+send  336: rtt = 0.310, srtt = 0.337, rttvar = 0.039, rto = 2.000
+recv  336
+updated rto
+send  337: rtt = 0.320, srtt = 0.335, rttvar = 0.034, rto = 2.000
+recv  337
+updated rto
+send  338: rtt = 0.330, srtt = 0.334, rttvar = 0.026, rto = 2.000
+recv  338
+updated rto
+send  339: rtt = 0.320, srtt = 0.332, rttvar = 0.023, rto = 2.000
+recv  339
+updated rto
+send  340: rtt = 0.315, srtt = 0.330, rttvar = 0.022, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  340: rtt = 0.315, srtt = 0.330, rttvar = 0.022, rto = 4.000
+recv  340
+updated rto
+send  341: rtt = 0.338, srtt = 0.331, rttvar = 0.018, rto = 2.000
+recv  341
+updated rto
+send  342: rtt = 0.320, srtt = 0.330, rttvar = 0.017, rto = 2.000
+recv  342
+updated rto
+send  343: rtt = 0.309, srtt = 0.327, rttvar = 0.018, rto = 2.000
+recv  343
+updated rto
+send  344: rtt = 0.320, srtt = 0.326, rttvar = 0.015, rto = 2.000
+recv  344
+updated rto
+send  345: rtt = 0.349, srtt = 0.329, rttvar = 0.017, rto = 2.000
+recv  345
+updated rto
+send  346: rtt = 0.339, srtt = 0.330, rttvar = 0.015, rto = 2.000
+recv  346
+updated rto
+send  347: rtt = 0.300, srtt = 0.327, rttvar = 0.019, rto = 2.000
+recv  347
+updated rto
+send  348: rtt = 0.300, srtt = 0.323, rttvar = 0.021, rto = 2.000
+recv  348
+updated rto
+send  349: rtt = 0.289, srtt = 0.319, rttvar = 0.024, rto = 2.000
+recv  349
+updated rto
+send  350: rtt = 0.329, srtt = 0.320, rttvar = 0.021, rto = 2.000
+recv  350
+updated rto
+send  351: rtt = 0.340, srtt = 0.323, rttvar = 0.020, rto = 2.000
+recv  351
+updated rto
+send  352: rtt = 0.329, srtt = 0.323, rttvar = 0.017, rto = 2.000
+recv  352
+updated rto
+send  353: rtt = 0.320, srtt = 0.323, rttvar = 0.014, rto = 2.000
+recv  353
+updated rto
+send  354: rtt = 0.410, srtt = 0.334, rttvar = 0.032, rto = 2.000
+recv  354
+updated rto
+send  355: rtt = 0.300, srtt = 0.330, rttvar = 0.032, rto = 2.000
+recv  355
+updated rto
+send  356: rtt = 0.389, srtt = 0.337, rttvar = 0.039, rto = 2.000
+recv  356
+updated rto
+send  357: rtt = 0.299, srtt = 0.332, rttvar = 0.039, rto = 2.000
+recv  357
+updated rto
+send  358: rtt = 1.280, srtt = 0.451, rttvar = 0.266, rto = 2.000
+recv  358
+updated rto
+send  359: rtt = 0.809, srtt = 0.496, rttvar = 0.289, rto = 2.000
+recv  359
+updated rto
+send  360: rtt = 0.818, srtt = 0.536, rttvar = 0.297, rto = 2.000
+recv  360
+updated rto
+send  361: rtt = 0.819, srtt = 0.571, rttvar = 0.294, rto = 2.000
+recv  361
+updated rto
+send  362: rtt = 0.829, srtt = 0.603, rttvar = 0.285, rto = 2.000
+recv  362
+updated rto
+send  363: rtt = 0.819, srtt = 0.630, rttvar = 0.268, rto = 2.000
+recv  363
+updated rto
+send  364: rtt = 0.809, srtt = 0.653, rttvar = 0.245, rto = 2.000
+recv  364
+updated rto
+send  365: rtt = 0.819, srtt = 0.674, rttvar = 0.226, rto = 2.000
+recv  365
+updated rto
+send  366: rtt = 0.999, srtt = 0.714, rttvar = 0.251, rto = 2.000
+recv  366
+updated rto
+send  367: rtt = 0.999, srtt = 0.750, rttvar = 0.259, rto = 2.000
+recv  367
+updated rto
+send  368: rtt = 1.479, srtt = 0.841, rttvar = 0.377, rto = 2.347
+recv  368
+updated rto
+send  369: rtt = 1.010, srtt = 0.862, rttvar = 0.325, rto = 2.161
+recv  369
+updated rto
+send  370: rtt = 0.998, srtt = 0.879, rttvar = 0.278, rto = 2.000
+recv  370
+updated rto
+send  371: rtt = 0.999, srtt = 0.894, rttvar = 0.238, rto = 2.000
+recv  371
+updated rto
+send  372: rtt = 0.999, srtt = 0.907, rttvar = 0.205, rto = 2.000
+recv  372
+updated rto
+send  373: rtt = 0.999, srtt = 0.919, rttvar = 0.177, rto = 2.000
+recv  373
+updated rto
+send  374: rtt = 0.989, srtt = 0.927, rttvar = 0.150, rto = 2.000
+recv  374
+updated rto
+send  375: rtt = 0.989, srtt = 0.935, rttvar = 0.128, rto = 2.000
+recv  375
+updated rto
+send  376: rtt = 1.009, srtt = 0.944, rttvar = 0.114, rto = 2.000
+recv  376
+updated rto
+send  377: rtt = 0.999, srtt = 0.951, rttvar = 0.099, rto = 2.000
+recv  377
+updated rto
+send  378: rtt = 1.009, srtt = 0.958, rttvar = 0.089, rto = 2.000
+recv  378
+updated rto
+send  379: rtt = 0.939, srtt = 0.956, rttvar = 0.072, rto = 2.000
+recv  379
+updated rto
+send  380: rtt = 0.809, srtt = 0.938, rttvar = 0.090, rto = 2.000
+recv  380
+updated rto
+send  381: rtt = 0.821, srtt = 0.923, rttvar = 0.097, rto = 2.000
+recv  381
+updated rto
+send  382: rtt = 0.827, srtt = 0.911, rttvar = 0.097, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  382: rtt = 0.827, srtt = 0.911, rttvar = 0.097, rto = 4.000
+recv  382
+updated rto
+send  383: rtt = 0.809, srtt = 0.898, rttvar = 0.098, rto = 2.000
+recv  383
+updated rto
+send  384: rtt = 0.839, srtt = 0.891, rttvar = 0.088, rto = 2.000
+recv  384
+updated rto
+send  385: rtt = 0.819, srtt = 0.882, rttvar = 0.084, rto = 2.000
+recv  385
+updated rto
+send  386: rtt = 0.809, srtt = 0.873, rttvar = 0.081, rto = 2.000
+recv  386
+updated rto
+send  387: rtt = 0.819, srtt = 0.866, rttvar = 0.075, rto = 2.000
+recv  387
+updated rto
+send  388: rtt = 0.819, srtt = 0.860, rttvar = 0.068, rto = 2.000
+recv  388
+updated rto
+send  389: rtt = 0.809, srtt = 0.854, rttvar = 0.064, rto = 2.000
+recv  389
+updated rto
+send  390: rtt = 0.811, srtt = 0.848, rttvar = 0.058, rto = 2.000
+recv  390
+updated rto
+send  391: rtt = 0.827, srtt = 0.846, rttvar = 0.049, rto = 2.000
+recv  391
+updated rto
+send  392: rtt = 0.813, srtt = 0.842, rttvar = 0.045, rto = 2.000
+recv  392
+updated rto
+send  393: rtt = 1.205, srtt = 0.887, rttvar = 0.125, rto = 2.000
+recv  393
+updated rto
+send  394: rtt = 0.829, srtt = 0.880, rttvar = 0.108, rto = 2.000
+recv  394
+updated rto
+send  395: rtt = 0.819, srtt = 0.872, rttvar = 0.096, rto = 2.000
+recv  395
+updated rto
+send  396: rtt = 0.819, srtt = 0.866, rttvar = 0.085, rto = 2.000
+recv  396
+updated rto
+send  397: rtt = 0.819, srtt = 0.860, rttvar = 0.076, rto = 2.000
+recv  397
+updated rto
+send  398: rtt = 0.819, srtt = 0.855, rttvar = 0.067, rto = 2.000
+recv  398
+updated rto
+send  399: rtt = 0.819, srtt = 0.850, rttvar = 0.059, rto = 2.000
+recv  399
+updated rto
+send  400: rtt = 0.819, srtt = 0.846, rttvar = 0.052, rto = 2.000
+recv  400
+updated rto
+send  401: rtt = 0.829, srtt = 0.844, rttvar = 0.043, rto = 2.000
+recv  401
+updated rto
+send  402: rtt = 0.819, srtt = 0.841, rttvar = 0.039, rto = 2.000
+recv  402
+updated rto
+send  403: rtt = 0.809, srtt = 0.837, rttvar = 0.037, rto = 2.000
+recv  403
+updated rto
+send  404: rtt = 0.819, srtt = 0.835, rttvar = 0.032, rto = 2.000
+recv  404
+updated rto
+send  405: rtt = 0.809, srtt = 0.832, rttvar = 0.031, rto = 2.000
+recv  405
+updated rto
+send  406: rtt = 0.819, srtt = 0.830, rttvar = 0.026, rto = 2.000
+recv  406
+updated rto
+send  407: rtt = 0.819, srtt = 0.829, rttvar = 0.022, rto = 2.000
+recv  407
+updated rto
+send  408: rtt = 0.799, srtt = 0.825, rttvar = 0.024, rto = 2.000
+recv  408
+updated rto
+send  409: rtt = 0.819, srtt = 0.824, rttvar = 0.020, rto = 2.000
+recv  409
+updated rto
+send  410: rtt = 0.819, srtt = 0.824, rttvar = 0.016, rto = 2.000
+recv  410
+updated rto
+send  411: rtt = 0.829, srtt = 0.824, rttvar = 0.013, rto = 2.000
+recv  411
+updated rto
+send  412: rtt = 0.820, srtt = 0.824, rttvar = 0.011, rto = 2.000
+recv  412
+updated rto
+send  413: rtt = 0.809, srtt = 0.822, rttvar = 0.012, rto = 2.000
+recv  413
+updated rto
+send  414: rtt = 0.819, srtt = 0.821, rttvar = 0.010, rto = 2.000
+recv  414
+updated rto
+send  415: rtt = 1.209, srtt = 0.870, rttvar = 0.104, rto = 2.000
+recv  415
+updated rto
+send  416: rtt = 0.809, srtt = 0.862, rttvar = 0.093, rto = 2.000
+recv  416
+updated rto
+send  417: rtt = 0.824, srtt = 0.858, rttvar = 0.080, rto = 2.000
+recv  417
+updated rto
+send  418: rtt = 0.814, srtt = 0.852, rttvar = 0.071, rto = 2.000
+recv  418
+updated rto
+send  419: rtt = 0.809, srtt = 0.847, rttvar = 0.064, rto = 2.000
+recv  419
+updated rto
+send  420: rtt = 0.819, srtt = 0.843, rttvar = 0.055, rto = 2.000
+recv  420
+updated rto
+send  421: rtt = 0.819, srtt = 0.840, rttvar = 0.047, rto = 2.000
+recv  421
+updated rto
+send  422: rtt = 0.809, srtt = 0.836, rttvar = 0.043, rto = 2.000
+recv  422
+updated rto
+send  423: rtt = 0.819, srtt = 0.834, rttvar = 0.037, rto = 2.000
+recv  423
+updated rto
+send  424: rtt = 0.821, srtt = 0.832, rttvar = 0.031, rto = 2.000
+recv  424
+updated rto
+send  425: rtt = 0.808, srtt = 0.829, rttvar = 0.029, rto = 2.000
+recv  425
+updated rto
+send  426: rtt = 0.819, srtt = 0.828, rttvar = 0.025, rto = 2.000
+recv  426
+updated rto
+send  427: rtt = 0.819, srtt = 0.827, rttvar = 0.021, rto = 2.000
+recv  427
+updated rto
+send  428: rtt = 0.819, srtt = 0.826, rttvar = 0.017, rto = 2.000
+recv  428
+updated rto
+send  429: rtt = 0.819, srtt = 0.825, rttvar = 0.015, rto = 2.000
+recv  429
+updated rto
+send  430: rtt = 0.819, srtt = 0.824, rttvar = 0.013, rto = 2.000
+recv  430
+updated rto
+send  431: rtt = 0.819, srtt = 0.824, rttvar = 0.011, rto = 2.000
+recv  431
+updated rto
+send  432: rtt = 0.609, srtt = 0.797, rttvar = 0.062, rto = 2.000
+recv  432
+updated rto
+send  433: rtt = 0.309, srtt = 0.736, rttvar = 0.168, rto = 2.000
+recv  433
+updated rto
+send  434: rtt = 0.330, srtt = 0.685, rttvar = 0.228, rto = 2.000
+recv  434
+updated rto
+send  435: rtt = 0.300, srtt = 0.637, rttvar = 0.267, rto = 2.000
+recv  435
+updated rto
+send  436: rtt = 0.319, srtt = 0.597, rttvar = 0.280, rto = 2.000
+recv  436
+updated rto
+send  437: rtt = 0.310, srtt = 0.561, rttvar = 0.282, rto = 2.000
+recv  437
+updated rto
+send  438: rtt = 0.320, srtt = 0.531, rttvar = 0.272, rto = 2.000
+recv  438
+updated rto
+send  439: rtt = 0.350, srtt = 0.509, rttvar = 0.249, rto = 2.000
+recv  439
+updated rto
+send  440: rtt = 0.290, srtt = 0.481, rttvar = 0.241, rto = 2.000
+recv  440
+updated rto
+send  441: rtt = 0.290, srtt = 0.457, rttvar = 0.229, rto = 2.000
+recv  441
+updated rto
+send  442: rtt = 0.300, srtt = 0.438, rttvar = 0.211, rto = 2.000
+recv  442
+updated rto
+send  443: rtt = 0.360, srtt = 0.428, rttvar = 0.178, rto = 2.000
+recv  443
+updated rto
+send  444: rtt = 0.310, srtt = 0.413, rttvar = 0.163, rto = 2.000
+recv  444
+updated rto
+send  445: rtt = 0.360, srtt = 0.407, rttvar = 0.135, rto = 2.000
+recv  445
+updated rto
+send  446: rtt = 0.319, srtt = 0.396, rttvar = 0.123, rto = 2.000
+recv  446
+updated rto
+send  447: rtt = 0.320, srtt = 0.386, rttvar = 0.111, rto = 2.000
+recv  447
+updated rto
+send  448: rtt = 0.330, srtt = 0.379, rttvar = 0.098, rto = 2.000
+recv  448
+updated rto
+send  449: rtt = 0.329, srtt = 0.373, rttvar = 0.086, rto = 2.000
+recv  449
+updated rto
+send  450: rtt = 0.370, srtt = 0.373, rttvar = 0.065, rto = 2.000
+recv  450
+updated rto
+send  451: rtt = 0.340, srtt = 0.368, rttvar = 0.057, rto = 2.000
+recv  451
+updated rto
+send  452: rtt = 0.340, srtt = 0.365, rttvar = 0.050, rto = 2.000
+recv  452
+updated rto
+send  453: rtt = 0.719, srtt = 0.409, rttvar = 0.126, rto = 2.000
+recv  453
+updated rto
+send  454: rtt = 0.339, srtt = 0.400, rttvar = 0.112, rto = 2.000
+recv  454
+updated rto
+send  455: rtt = 0.320, srtt = 0.390, rttvar = 0.104, rto = 2.000
+recv  455
+updated rto
+send  456: rtt = 0.310, srtt = 0.380, rttvar = 0.098, rto = 2.000
+recv  456
+updated rto
+send  457: rtt = 0.320, srtt = 0.373, rttvar = 0.089, rto = 2.000
+recv  457
+updated rto
+send  458: rtt = 0.330, srtt = 0.367, rttvar = 0.077, rto = 2.000
+recv  458
+updated rto
+send  459: rtt = 0.313, srtt = 0.361, rttvar = 0.071, rto = 2.000
+recv  459
+updated rto
+send  460: rtt = 0.377, srtt = 0.363, rttvar = 0.058, rto = 2.000
+recv  460
+updated rto
+send  461: rtt = 0.440, srtt = 0.372, rttvar = 0.063, rto = 2.000
+recv  461
+updated rto
+send  462: rtt = 0.340, srtt = 0.368, rttvar = 0.055, rto = 2.000
+recv  462
+updated rto
+send  463: rtt = 0.330, srtt = 0.364, rttvar = 0.051, rto = 2.000
+recv  463
+updated rto
+send  464: rtt = 0.360, srtt = 0.363, rttvar = 0.039, rto = 2.000
+recv  464
+updated rto
+send  465: rtt = 0.380, srtt = 0.365, rttvar = 0.033, rto = 2.000
+recv  465
+updated rto
+send  466: rtt = 0.320, srtt = 0.360, rttvar = 0.036, rto = 2.000
+recv  466
+updated rto
+send  467: rtt = 0.309, srtt = 0.353, rttvar = 0.040, rto = 2.000
+recv  467
+updated rto
+send  468: rtt = 0.360, srtt = 0.354, rttvar = 0.032, rto = 2.000
+recv  468
+updated rto
+send  469: rtt = 0.330, srtt = 0.351, rttvar = 0.030, rto = 2.000
+recv  469
+updated rto
+send  470: rtt = 0.290, srtt = 0.343, rttvar = 0.038, rto = 2.000
+recv  470
+updated rto
+send  471: rtt = 0.329, srtt = 0.342, rttvar = 0.032, rto = 2.000
+recv  471
+updated rto
+send  472: rtt = 0.319, srtt = 0.339, rttvar = 0.030, rto = 2.000
+recv  472
+updated rto
+send  473: rtt = 0.320, srtt = 0.336, rttvar = 0.027, rto = 2.000
+recv  473
+updated rto
+send  474: rtt = 0.349, srtt = 0.338, rttvar = 0.023, rto = 2.000
+recv  474
+updated rto
+send  475: rtt = 0.330, srtt = 0.337, rttvar = 0.019, rto = 2.000
+recv  475
+updated rto
+send  476: rtt = 0.360, srtt = 0.340, rttvar = 0.020, rto = 2.000
+recv  476
+updated rto
+send  477: rtt = 0.310, srtt = 0.336, rttvar = 0.023, rto = 2.000
+recv  477
+updated rto
+send  478: rtt = 0.320, srtt = 0.334, rttvar = 0.021, rto = 2.000
+recv  478
+updated rto
+send  479: rtt = 0.320, srtt = 0.332, rttvar = 0.019, rto = 2.000
+recv  479
+updated rto
+send  480: rtt = 0.410, srtt = 0.342, rttvar = 0.034, rto = 2.000
+recv  480
+updated rto
+send  481: rtt = 0.340, srtt = 0.342, rttvar = 0.026, rto = 2.000
+recv  481
+updated rto
+send  482: rtt = 0.409, srtt = 0.350, rttvar = 0.036, rto = 2.000
+recv  482
+updated rto
+send  483: rtt = 0.330, srtt = 0.348, rttvar = 0.032, rto = 2.000
+recv  483
+updated rto
+send  484: rtt = 0.280, srtt = 0.339, rttvar = 0.041, rto = 2.000
+recv  484
+updated rto
+send  485: rtt = 0.320, srtt = 0.337, rttvar = 0.036, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  485: rtt = 0.320, srtt = 0.337, rttvar = 0.036, rto = 4.000
+recv  485
+updated rto
+send  486: rtt = 0.339, srtt = 0.337, rttvar = 0.027, rto = 2.000
+recv  486
+updated rto
+send  487: rtt = 0.360, srtt = 0.340, rttvar = 0.026, rto = 2.000
+recv  487
+updated rto
+send  488: rtt = 0.300, srtt = 0.335, rttvar = 0.030, rto = 2.000
+recv  488
+updated rto
+send  489: rtt = 0.320, srtt = 0.333, rttvar = 0.026, rto = 2.000
+recv  489
+updated rto
+send  490: rtt = 0.410, srtt = 0.343, rttvar = 0.039, rto = 2.000
+recv  490
+updated rto
+send  491: rtt = 0.320, srtt = 0.340, rttvar = 0.035, rto = 2.000
+recv  491
+updated rto
+send  492: rtt = 0.320, srtt = 0.337, rttvar = 0.031, rto = 2.000
+recv  492
+updated rto
+send  493: rtt = 0.319, srtt = 0.335, rttvar = 0.028, rto = 2.000
+recv  493
+updated rto
+send  494: rtt = 0.330, srtt = 0.334, rttvar = 0.022, rto = 2.000
+recv  494
+updated rto
+send  495: rtt = 0.320, srtt = 0.333, rttvar = 0.020, rto = 2.000
+recv  495
+updated rto
+send  496: rtt = 0.314, srtt = 0.330, rttvar = 0.020, rto = 2.000
+recv  496
+updated rto
+send  497: rtt = 0.325, srtt = 0.330, rttvar = 0.016, rto = 2.000
+recv  497
+updated rto
+send  498: rtt = 0.330, srtt = 0.330, rttvar = 0.012, rto = 2.000
+recv  498
+updated rto
+send  499: rtt = 0.290, srtt = 0.325, rttvar = 0.019, rto = 2.000
+recv  499
+updated rto
+send  500: rtt = 0.340, srtt = 0.327, rttvar = 0.018, rto = 2.000
+recv  500
+updated rto
diff --git a/rtt/rtt.out.kumba.2 b/rtt/rtt.out.kumba.2
new file mode 100644 (file)
index 0000000..17fe181
--- /dev/null
@@ -0,0 +1,1500 @@
+send    1: rtt = 0.000, srtt = 0.000, rttvar = 0.750, rto = 3.000
+recv    1
+updated rto
+send    2: rtt = 0.369, srtt = 0.046, rttvar = 0.655, rto = 2.665
+recv    2
+updated rto
+send    3: rtt = 0.318, srtt = 0.080, rttvar = 0.559, rto = 2.316
+recv    3
+updated rto
+send    4: rtt = 0.300, srtt = 0.108, rttvar = 0.474, rto = 2.005
+recv    4
+updated rto
+send    5: rtt = 0.360, srtt = 0.139, rttvar = 0.419, rto = 2.000
+recv    5
+updated rto
+send    6: rtt = 0.298, srtt = 0.159, rttvar = 0.354, rto = 2.000
+recv    6
+updated rto
+send    7: rtt = 0.300, srtt = 0.177, rttvar = 0.301, rto = 2.000
+recv    7
+updated rto
+send    8: rtt = 0.315, srtt = 0.194, rttvar = 0.260, rto = 2.000
+recv    8
+updated rto
+send    9: rtt = 0.285, srtt = 0.205, rttvar = 0.218, rto = 2.000
+recv    9
+updated rto
+send   10: rtt = 0.349, srtt = 0.223, rttvar = 0.199, rto = 2.000
+recv   10
+updated rto
+send   11: rtt = 0.309, srtt = 0.234, rttvar = 0.171, rto = 2.000
+recv   11
+updated rto
+send   12: rtt = 0.330, srtt = 0.246, rttvar = 0.152, rto = 2.000
+recv   12
+updated rto
+send   13: rtt = 0.350, srtt = 0.259, rttvar = 0.140, rto = 2.000
+recv   13
+updated rto
+send   14: rtt = 0.320, srtt = 0.267, rttvar = 0.120, rto = 2.000
+recv   14
+updated rto
+send   15: rtt = 0.320, srtt = 0.273, rttvar = 0.104, rto = 2.000
+recv   15
+updated rto
+send   16: rtt = 0.340, srtt = 0.282, rttvar = 0.094, rto = 2.000
+recv   16
+updated rto
+send   17: rtt = 0.439, srtt = 0.301, rttvar = 0.110, rto = 2.000
+recv   17
+updated rto
+send   18: rtt = 0.340, srtt = 0.306, rttvar = 0.092, rto = 2.000
+recv   18
+updated rto
+send   19: rtt = 0.350, srtt = 0.312, rttvar = 0.080, rto = 2.000
+recv   19
+updated rto
+send   20: rtt = 0.300, srtt = 0.310, rttvar = 0.063, rto = 2.000
+recv   20
+updated rto
+send   21: rtt = 0.320, srtt = 0.311, rttvar = 0.050, rto = 2.000
+recv   21
+updated rto
+send   22: rtt = 0.319, srtt = 0.312, rttvar = 0.039, rto = 2.000
+recv   22
+updated rto
+send   23: rtt = 0.349, srtt = 0.317, rttvar = 0.039, rto = 2.000
+recv   23
+updated rto
+send   24: rtt = 0.320, srtt = 0.317, rttvar = 0.030, rto = 2.000
+recv   24
+updated rto
+send   25: rtt = 0.330, srtt = 0.319, rttvar = 0.025, rto = 2.000
+recv   25
+updated rto
+send   26: rtt = 0.299, srtt = 0.316, rttvar = 0.024, rto = 2.000
+recv   26
+updated rto
+send   27: rtt = 0.310, srtt = 0.316, rttvar = 0.020, rto = 2.000
+recv   27
+updated rto
+send   28: rtt = 0.320, srtt = 0.316, rttvar = 0.016, rto = 2.000
+recv   28
+updated rto
+send   29: rtt = 0.320, srtt = 0.317, rttvar = 0.013, rto = 2.000
+recv   29
+updated rto
+send   30: rtt = 0.329, srtt = 0.318, rttvar = 0.013, rto = 2.000
+recv   30
+updated rto
+send   31: rtt = 0.340, srtt = 0.321, rttvar = 0.015, rto = 2.000
+recv   31
+updated rto
+send   32: rtt = 0.320, srtt = 0.321, rttvar = 0.011, rto = 2.000
+recv   32
+updated rto
+send   33: rtt = 0.320, srtt = 0.321, rttvar = 0.009, rto = 2.000
+recv   33
+updated rto
+send   34: rtt = 0.310, srtt = 0.319, rttvar = 0.009, rto = 2.000
+recv   34
+updated rto
+send   35: rtt = 0.300, srtt = 0.317, rttvar = 0.012, rto = 2.000
+recv   35
+updated rto
+send   36: rtt = 0.330, srtt = 0.319, rttvar = 0.012, rto = 2.000
+recv   36
+updated rto
+send   37: rtt = 0.429, srtt = 0.332, rttvar = 0.037, rto = 2.000
+recv   37
+updated rto
+send   38: rtt = 0.330, srtt = 0.332, rttvar = 0.028, rto = 2.000
+recv   38
+updated rto
+send   39: rtt = 0.310, srtt = 0.329, rttvar = 0.027, rto = 2.000
+recv   39
+updated rto
+send   40: rtt = 0.310, srtt = 0.327, rttvar = 0.025, rto = 2.000
+recv   40
+updated rto
+send   41: rtt = 0.390, srtt = 0.335, rttvar = 0.034, rto = 2.000
+recv   41
+updated rto
+send   42: rtt = 0.319, srtt = 0.333, rttvar = 0.030, rto = 2.000
+recv   42
+updated rto
+send   43: rtt = 0.300, srtt = 0.329, rttvar = 0.030, rto = 2.000
+recv   43
+updated rto
+send   44: rtt = 0.270, srtt = 0.321, rttvar = 0.038, rto = 2.000
+recv   44
+updated rto
+send   45: rtt = 0.370, srtt = 0.327, rttvar = 0.040, rto = 2.000
+recv   45
+updated rto
+send   46: rtt = 0.329, srtt = 0.328, rttvar = 0.031, rto = 2.000
+recv   46
+updated rto
+send   47: rtt = 0.329, srtt = 0.328, rttvar = 0.023, rto = 2.000
+recv   47
+updated rto
+send   48: rtt = 0.320, srtt = 0.327, rttvar = 0.019, rto = 2.000
+recv   48
+updated rto
+send   49: rtt = 0.330, srtt = 0.327, rttvar = 0.015, rto = 2.000
+recv   49
+updated rto
+send   50: rtt = 0.319, srtt = 0.326, rttvar = 0.014, rto = 2.000
+recv   50
+updated rto
+send   51: rtt = 0.320, srtt = 0.325, rttvar = 0.012, rto = 2.000
+recv   51
+updated rto
+send   52: rtt = 0.300, srtt = 0.322, rttvar = 0.015, rto = 2.000
+recv   52
+updated rto
+send   53: rtt = 0.340, srtt = 0.324, rttvar = 0.016, rto = 2.000
+recv   53
+updated rto
+send   54: rtt = 0.330, srtt = 0.325, rttvar = 0.013, rto = 2.000
+recv   54
+updated rto
+send   55: rtt = 0.339, srtt = 0.327, rttvar = 0.013, rto = 2.000
+recv   55
+updated rto
+send   56: rtt = 0.340, srtt = 0.329, rttvar = 0.013, rto = 2.000
+recv   56
+updated rto
+send   57: rtt = 0.359, srtt = 0.332, rttvar = 0.018, rto = 2.000
+recv   57
+updated rto
+send   58: rtt = 0.309, srtt = 0.329, rttvar = 0.019, rto = 2.000
+recv   58
+updated rto
+send   59: rtt = 0.340, srtt = 0.331, rttvar = 0.017, rto = 2.000
+recv   59
+updated rto
+send   60: rtt = 0.300, srtt = 0.327, rttvar = 0.020, rto = 2.000
+recv   60
+updated rto
+send   61: rtt = 0.300, srtt = 0.324, rttvar = 0.022, rto = 2.000
+recv   61
+updated rto
+send   62: rtt = 0.330, srtt = 0.324, rttvar = 0.018, rto = 2.000
+recv   62
+updated rto
+send   63: rtt = 0.329, srtt = 0.325, rttvar = 0.015, rto = 2.000
+recv   63
+updated rto
+send   64: rtt = 0.290, srtt = 0.321, rttvar = 0.020, rto = 2.000
+recv   64
+updated rto
+send   65: rtt = 0.300, srtt = 0.318, rttvar = 0.020, rto = 2.000
+recv   65
+updated rto
+send   66: rtt = 0.290, srtt = 0.314, rttvar = 0.022, rto = 2.000
+recv   66
+updated rto
+send   67: rtt = 0.350, srtt = 0.319, rttvar = 0.025, rto = 2.000
+recv   67
+updated rto
+send   68: rtt = 0.320, srtt = 0.319, rttvar = 0.019, rto = 2.000
+recv   68
+updated rto
+send   69: rtt = 0.340, srtt = 0.322, rttvar = 0.020, rto = 2.000
+recv   69
+updated rto
+send   70: rtt = 0.299, srtt = 0.319, rttvar = 0.020, rto = 2.000
+recv   70
+updated rto
+send   71: rtt = 0.320, srtt = 0.319, rttvar = 0.016, rto = 2.000
+recv   71
+updated rto
+send   72: rtt = 0.359, srtt = 0.324, rttvar = 0.022, rto = 2.000
+recv   72
+updated rto
+send   73: rtt = 0.330, srtt = 0.325, rttvar = 0.018, rto = 2.000
+recv   73
+updated rto
+send   74: rtt = 0.300, srtt = 0.322, rttvar = 0.020, rto = 2.000
+recv   74
+updated rto
+send   75: rtt = 0.370, srtt = 0.328, rttvar = 0.027, rto = 2.000
+recv   75
+updated rto
+send   76: rtt = 0.300, srtt = 0.324, rttvar = 0.027, rto = 2.000
+recv   76
+updated rto
+send   77: rtt = 0.330, srtt = 0.325, rttvar = 0.022, rto = 2.000
+recv   77
+updated rto
+send   78: rtt = 0.270, srtt = 0.318, rttvar = 0.030, rto = 2.000
+recv   78
+updated rto
+send   79: rtt = 0.350, srtt = 0.322, rttvar = 0.030, rto = 2.000
+recv   79
+updated rto
+send   80: rtt = 0.329, srtt = 0.323, rttvar = 0.025, rto = 2.000
+recv   80
+updated rto
+send   81: rtt = 0.320, srtt = 0.323, rttvar = 0.019, rto = 2.000
+recv   81
+updated rto
+send   82: rtt = 0.329, srtt = 0.323, rttvar = 0.016, rto = 2.000
+recv   82
+updated rto
+send   83: rtt = 0.330, srtt = 0.324, rttvar = 0.014, rto = 2.000
+recv   83
+updated rto
+send   84: rtt = 0.309, srtt = 0.322, rttvar = 0.014, rto = 2.000
+recv   84
+updated rto
+send   85: rtt = 0.350, srtt = 0.326, rttvar = 0.017, rto = 2.000
+recv   85
+updated rto
+send   86: rtt = 0.350, srtt = 0.329, rttvar = 0.019, rto = 2.000
+recv   86
+updated rto
+send   87: rtt = 0.330, srtt = 0.329, rttvar = 0.015, rto = 2.000
+recv   87
+updated rto
+send   88: rtt = 0.310, srtt = 0.327, rttvar = 0.016, rto = 2.000
+recv   88
+updated rto
+send   89: rtt = 0.330, srtt = 0.327, rttvar = 0.013, rto = 2.000
+recv   89
+updated rto
+send   90: rtt = 0.350, srtt = 0.330, rttvar = 0.015, rto = 2.000
+recv   90
+updated rto
+send   91: rtt = 0.300, srtt = 0.326, rttvar = 0.019, rto = 2.000
+recv   91
+updated rto
+send   92: rtt = 0.310, srtt = 0.324, rttvar = 0.018, rto = 2.000
+recv   92
+updated rto
+send   93: rtt = 0.290, srtt = 0.320, rttvar = 0.022, rto = 2.000
+recv   93
+updated rto
+send   94: rtt = 0.319, srtt = 0.320, rttvar = 0.017, rto = 2.000
+recv   94
+updated rto
+send   95: rtt = 0.319, srtt = 0.320, rttvar = 0.013, rto = 2.000
+recv   95
+updated rto
+send   96: rtt = 0.330, srtt = 0.321, rttvar = 0.012, rto = 2.000
+recv   96
+updated rto
+send   97: rtt = 0.310, srtt = 0.320, rttvar = 0.012, rto = 2.000
+recv   97
+updated rto
+send   98: rtt = 0.289, srtt = 0.316, rttvar = 0.017, rto = 2.000
+recv   98
+updated rto
+send   99: rtt = 0.310, srtt = 0.315, rttvar = 0.014, rto = 2.000
+recv   99
+updated rto
+send  100: rtt = 0.340, srtt = 0.318, rttvar = 0.017, rto = 2.000
+recv  100
+updated rto
+send  101: rtt = 0.340, srtt = 0.321, rttvar = 0.018, rto = 2.000
+recv  101
+updated rto
+send  102: rtt = 0.320, srtt = 0.321, rttvar = 0.014, rto = 2.000
+recv  102
+updated rto
+send  103: rtt = 0.310, srtt = 0.319, rttvar = 0.013, rto = 2.000
+recv  103
+updated rto
+send  104: rtt = 0.430, srtt = 0.333, rttvar = 0.037, rto = 2.000
+recv  104
+updated rto
+send  105: rtt = 0.329, srtt = 0.333, rttvar = 0.029, rto = 2.000
+recv  105
+updated rto
+send  106: rtt = 0.330, srtt = 0.332, rttvar = 0.022, rto = 2.000
+recv  106
+updated rto
+send  107: rtt = 0.430, srtt = 0.345, rttvar = 0.041, rto = 2.000
+recv  107
+updated rto
+send  108: rtt = 0.350, srtt = 0.345, rttvar = 0.032, rto = 2.000
+recv  108
+updated rto
+send  109: rtt = 0.339, srtt = 0.344, rttvar = 0.026, rto = 2.000
+recv  109
+updated rto
+send  110: rtt = 0.350, srtt = 0.345, rttvar = 0.021, rto = 2.000
+recv  110
+updated rto
+send  111: rtt = 0.370, srtt = 0.348, rttvar = 0.022, rto = 2.000
+recv  111
+updated rto
+send  112: rtt = 0.329, srtt = 0.346, rttvar = 0.021, rto = 2.000
+recv  112
+updated rto
+send  113: rtt = 0.340, srtt = 0.345, rttvar = 0.017, rto = 2.000
+recv  113
+updated rto
+send  114: rtt = 0.330, srtt = 0.343, rttvar = 0.017, rto = 2.000
+recv  114
+updated rto
+send  115: rtt = 0.290, srtt = 0.337, rttvar = 0.026, rto = 2.000
+recv  115
+updated rto
+send  116: rtt = 0.329, srtt = 0.336, rttvar = 0.021, rto = 2.000
+recv  116
+updated rto
+send  117: rtt = 0.300, srtt = 0.331, rttvar = 0.025, rto = 2.000
+recv  117
+updated rto
+send  118: rtt = 0.339, srtt = 0.332, rttvar = 0.021, rto = 2.000
+recv  118
+updated rto
+send  119: rtt = 0.350, srtt = 0.334, rttvar = 0.020, rto = 2.000
+recv  119
+updated rto
+send  120: rtt = 0.330, srtt = 0.334, rttvar = 0.016, rto = 2.000
+recv  120
+updated rto
+send  121: rtt = 0.329, srtt = 0.333, rttvar = 0.013, rto = 2.000
+recv  121
+updated rto
+send  122: rtt = 0.310, srtt = 0.330, rttvar = 0.016, rto = 2.000
+recv  122
+updated rto
+send  123: rtt = 0.320, srtt = 0.329, rttvar = 0.014, rto = 2.000
+recv  123
+updated rto
+send  124: rtt = 0.289, srtt = 0.324, rttvar = 0.021, rto = 2.000
+recv  124
+updated rto
+send  125: rtt = 0.320, srtt = 0.324, rttvar = 0.017, rto = 2.000
+recv  125
+updated rto
+send  126: rtt = 0.300, srtt = 0.321, rttvar = 0.018, rto = 2.000
+recv  126
+updated rto
+send  127: rtt = 0.336, srtt = 0.323, rttvar = 0.018, rto = 2.000
+recv  127
+updated rto
+send  128: rtt = 0.334, srtt = 0.324, rttvar = 0.016, rto = 2.000
+recv  128
+updated rto
+send  129: rtt = 0.290, srtt = 0.320, rttvar = 0.021, rto = 2.000
+recv  129
+updated rto
+send  130: rtt = 0.319, srtt = 0.320, rttvar = 0.016, rto = 2.000
+recv  130
+updated rto
+send  131: rtt = 0.410, srtt = 0.331, rttvar = 0.034, rto = 2.000
+recv  131
+updated rto
+send  132: rtt = 0.320, srtt = 0.330, rttvar = 0.028, rto = 2.000
+recv  132
+updated rto
+send  133: rtt = 0.349, srtt = 0.332, rttvar = 0.026, rto = 2.000
+recv  133
+updated rto
+send  134: rtt = 0.370, srtt = 0.337, rttvar = 0.029, rto = 2.000
+recv  134
+updated rto
+send  135: rtt = 0.359, srtt = 0.340, rttvar = 0.027, rto = 2.000
+recv  135
+updated rto
+send  136: rtt = 0.320, srtt = 0.337, rttvar = 0.025, rto = 2.000
+recv  136
+updated rto
+send  137: rtt = 0.290, srtt = 0.331, rttvar = 0.031, rto = 2.000
+recv  137
+updated rto
+send  138: rtt = 0.330, srtt = 0.331, rttvar = 0.023, rto = 2.000
+recv  138
+updated rto
+send  139: rtt = 0.330, srtt = 0.331, rttvar = 0.018, rto = 2.000
+recv  139
+updated rto
+send  140: rtt = 0.310, srtt = 0.328, rttvar = 0.019, rto = 2.000
+recv  140
+updated rto
+send  141: rtt = 0.320, srtt = 0.327, rttvar = 0.016, rto = 2.000
+recv  141
+updated rto
+send  142: rtt = 0.289, srtt = 0.322, rttvar = 0.022, rto = 2.000
+recv  142
+updated rto
+send  143: rtt = 0.299, srtt = 0.320, rttvar = 0.022, rto = 2.000
+recv  143
+updated rto
+send  144: rtt = 0.329, srtt = 0.321, rttvar = 0.019, rto = 2.000
+recv  144
+updated rto
+send  145: rtt = 0.310, srtt = 0.319, rttvar = 0.017, rto = 2.000
+recv  145
+updated rto
+send  146: rtt = 0.290, srtt = 0.316, rttvar = 0.020, rto = 2.000
+recv  146
+updated rto
+send  147: rtt = 0.310, srtt = 0.315, rttvar = 0.016, rto = 2.000
+recv  147
+updated rto
+send  148: rtt = 0.310, srtt = 0.314, rttvar = 0.014, rto = 2.000
+recv  148
+updated rto
+send  149: rtt = 0.319, srtt = 0.315, rttvar = 0.011, rto = 2.000
+recv  149
+updated rto
+send  150: rtt = 0.339, srtt = 0.318, rttvar = 0.015, rto = 2.000
+recv  150
+updated rto
+send  151: rtt = 0.309, srtt = 0.317, rttvar = 0.013, rto = 2.000
+recv  151
+updated rto
+send  152: rtt = 0.299, srtt = 0.315, rttvar = 0.014, rto = 2.000
+recv  152
+updated rto
+send  153: rtt = 0.410, srtt = 0.327, rttvar = 0.035, rto = 2.000
+recv  153
+updated rto
+send  154: rtt = 0.340, srtt = 0.328, rttvar = 0.029, rto = 2.000
+recv  154
+updated rto
+send  155: rtt = 0.330, srtt = 0.328, rttvar = 0.022, rto = 2.000
+recv  155
+updated rto
+send  156: rtt = 0.369, srtt = 0.334, rttvar = 0.027, rto = 2.000
+recv  156
+updated rto
+send  157: rtt = 0.320, srtt = 0.332, rttvar = 0.024, rto = 2.000
+recv  157
+updated rto
+send  158: rtt = 0.350, srtt = 0.334, rttvar = 0.022, rto = 2.000
+recv  158
+updated rto
+send  159: rtt = 0.360, srtt = 0.337, rttvar = 0.023, rto = 2.000
+recv  159
+updated rto
+send  160: rtt = 0.290, srtt = 0.331, rttvar = 0.029, rto = 2.000
+recv  160
+updated rto
+send  161: rtt = 0.360, srtt = 0.335, rttvar = 0.029, rto = 2.000
+recv  161
+updated rto
+send  162: rtt = 0.310, srtt = 0.332, rttvar = 0.028, rto = 2.000
+recv  162
+updated rto
+send  163: rtt = 0.309, srtt = 0.329, rttvar = 0.027, rto = 2.000
+recv  163
+updated rto
+send  164: rtt = 0.320, srtt = 0.328, rttvar = 0.022, rto = 2.000
+recv  164
+updated rto
+send  165: rtt = 0.319, srtt = 0.327, rttvar = 0.019, rto = 2.000
+recv  165
+updated rto
+send  166: rtt = 0.309, srtt = 0.325, rttvar = 0.019, rto = 2.000
+recv  166
+updated rto
+send  167: rtt = 0.329, srtt = 0.325, rttvar = 0.015, rto = 2.000
+recv  167
+updated rto
+send  168: rtt = 0.688, srtt = 0.370, rttvar = 0.102, rto = 2.000
+recv  168
+updated rto
+send  169: rtt = 0.322, srtt = 0.364, rttvar = 0.089, rto = 2.000
+recv  169
+updated rto
+send  170: rtt = 0.310, srtt = 0.358, rttvar = 0.080, rto = 2.000
+recv  170
+updated rto
+send  171: rtt = 0.299, srtt = 0.350, rttvar = 0.075, rto = 2.000
+recv  171
+updated rto
+send  172: rtt = 0.339, srtt = 0.349, rttvar = 0.059, rto = 2.000
+recv  172
+updated rto
+send  173: rtt = 0.329, srtt = 0.346, rttvar = 0.049, rto = 2.000
+recv  173
+updated rto
+send  174: rtt = 0.309, srtt = 0.342, rttvar = 0.046, rto = 2.000
+recv  174
+updated rto
+send  175: rtt = 0.308, srtt = 0.337, rttvar = 0.043, rto = 2.000
+recv  175
+updated rto
+send  176: rtt = 0.299, srtt = 0.333, rttvar = 0.042, rto = 2.000
+recv  176
+updated rto
+send  177: rtt = 0.349, srtt = 0.335, rttvar = 0.036, rto = 2.000
+recv  177
+updated rto
+send  178: rtt = 0.346, srtt = 0.336, rttvar = 0.029, rto = 2.000
+recv  178
+updated rto
+send  179: rtt = 0.333, srtt = 0.336, rttvar = 0.023, rto = 2.000
+recv  179
+updated rto
+send  180: rtt = 0.370, srtt = 0.340, rttvar = 0.026, rto = 2.000
+recv  180
+updated rto
+send  181: rtt = 0.300, srtt = 0.335, rttvar = 0.029, rto = 2.000
+recv  181
+updated rto
+send  182: rtt = 0.329, srtt = 0.334, rttvar = 0.023, rto = 2.000
+recv  182
+updated rto
+send  183: rtt = 0.309, srtt = 0.331, rttvar = 0.024, rto = 2.000
+recv  183
+updated rto
+send  184: rtt = 0.330, srtt = 0.331, rttvar = 0.018, rto = 2.000
+recv  184
+updated rto
+send  185: rtt = 0.330, srtt = 0.331, rttvar = 0.014, rto = 2.000
+recv  185
+updated rto
+send  186: rtt = 0.340, srtt = 0.332, rttvar = 0.013, rto = 2.000
+recv  186
+updated rto
+send  187: rtt = 0.353, srtt = 0.335, rttvar = 0.015, rto = 2.000
+recv  187
+updated rto
+send  188: rtt = 0.415, srtt = 0.345, rttvar = 0.031, rto = 2.000
+recv  188
+updated rto
+send  189: rtt = 0.329, srtt = 0.343, rttvar = 0.027, rto = 2.000
+recv  189
+updated rto
+send  190: rtt = 0.334, srtt = 0.342, rttvar = 0.023, rto = 2.000
+recv  190
+updated rto
+send  191: rtt = 0.335, srtt = 0.341, rttvar = 0.019, rto = 2.000
+recv  191
+updated rto
+send  192: rtt = 0.310, srtt = 0.337, rttvar = 0.022, rto = 2.000
+recv  192
+updated rto
+send  193: rtt = 0.350, srtt = 0.339, rttvar = 0.020, rto = 2.000
+recv  193
+updated rto
+send  194: rtt = 0.320, srtt = 0.336, rttvar = 0.019, rto = 2.000
+recv  194
+updated rto
+send  195: rtt = 0.360, srtt = 0.339, rttvar = 0.020, rto = 2.000
+recv  195
+updated rto
+send  196: rtt = 0.320, srtt = 0.337, rttvar = 0.020, rto = 2.000
+recv  196
+updated rto
+send  197: rtt = 0.310, srtt = 0.333, rttvar = 0.022, rto = 2.000
+recv  197
+updated rto
+send  198: rtt = 0.350, srtt = 0.336, rttvar = 0.020, rto = 2.000
+recv  198
+updated rto
+send  199: rtt = 0.370, srtt = 0.340, rttvar = 0.024, rto = 2.000
+recv  199
+updated rto
+send  200: rtt = 0.309, srtt = 0.336, rttvar = 0.026, rto = 2.000
+recv  200
+updated rto
+send  201: rtt = 0.329, srtt = 0.335, rttvar = 0.021, rto = 2.000
+recv  201
+updated rto
+send  202: rtt = 0.322, srtt = 0.333, rttvar = 0.019, rto = 2.000
+recv  202
+updated rto
+send  203: rtt = 0.287, srtt = 0.328, rttvar = 0.026, rto = 2.000
+recv  203
+updated rto
+send  204: rtt = 0.290, srtt = 0.323, rttvar = 0.029, rto = 2.000
+recv  204
+updated rto
+send  205: rtt = 0.284, srtt = 0.318, rttvar = 0.031, rto = 2.000
+recv  205
+updated rto
+send  206: rtt = 0.335, srtt = 0.320, rttvar = 0.028, rto = 2.000
+recv  206
+updated rto
+send  207: rtt = 0.331, srtt = 0.322, rttvar = 0.024, rto = 2.000
+recv  207
+updated rto
+send  208: rtt = 0.338, srtt = 0.324, rttvar = 0.022, rto = 2.000
+recv  208
+updated rto
+send  209: rtt = 0.320, srtt = 0.323, rttvar = 0.017, rto = 2.000
+recv  209
+updated rto
+send  210: rtt = 0.349, srtt = 0.326, rttvar = 0.019, rto = 2.000
+recv  210
+updated rto
+send  211: rtt = 0.339, srtt = 0.328, rttvar = 0.018, rto = 2.000
+recv  211
+updated rto
+send  212: rtt = 0.379, srtt = 0.334, rttvar = 0.026, rto = 2.000
+recv  212
+updated rto
+send  213: rtt = 0.380, srtt = 0.340, rttvar = 0.031, rto = 2.000
+recv  213
+updated rto
+send  214: rtt = 0.400, srtt = 0.348, rttvar = 0.038, rto = 2.000
+recv  214
+updated rto
+send  215: rtt = 0.329, srtt = 0.345, rttvar = 0.033, rto = 2.000
+recv  215
+updated rto
+send  216: rtt = 0.360, srtt = 0.347, rttvar = 0.029, rto = 2.000
+recv  216
+updated rto
+send  217: rtt = 0.329, srtt = 0.345, rttvar = 0.026, rto = 2.000
+recv  217
+updated rto
+send  218: rtt = 0.350, srtt = 0.345, rttvar = 0.021, rto = 2.000
+recv  218
+updated rto
+send  219: rtt = 0.352, srtt = 0.346, rttvar = 0.017, rto = 2.000
+recv  219
+updated rto
+send  220: rtt = 0.321, srtt = 0.343, rttvar = 0.019, rto = 2.000
+recv  220
+updated rto
+send  221: rtt = 0.306, srtt = 0.338, rttvar = 0.024, rto = 2.000
+recv  221
+updated rto
+send  222: rtt = 0.339, srtt = 0.339, rttvar = 0.018, rto = 2.000
+recv  222
+updated rto
+send  223: rtt = 0.319, srtt = 0.336, rttvar = 0.018, rto = 2.000
+recv  223
+updated rto
+send  224: rtt = 0.320, srtt = 0.334, rttvar = 0.018, rto = 2.000
+recv  224
+updated rto
+send  225: rtt = 0.320, srtt = 0.332, rttvar = 0.017, rto = 2.000
+recv  225
+updated rto
+send  226: rtt = 0.339, srtt = 0.333, rttvar = 0.014, rto = 2.000
+recv  226
+updated rto
+send  227: rtt = 0.380, srtt = 0.339, rttvar = 0.022, rto = 2.000
+recv  227
+updated rto
+send  228: rtt = 0.309, srtt = 0.335, rttvar = 0.024, rto = 2.000
+recv  228
+updated rto
+send  229: rtt = 0.319, srtt = 0.333, rttvar = 0.022, rto = 2.000
+recv  229
+updated rto
+send  230: rtt = 0.342, srtt = 0.334, rttvar = 0.019, rto = 2.000
+recv  230
+updated rto
+send  231: rtt = 0.346, srtt = 0.336, rttvar = 0.017, rto = 2.000
+recv  231
+updated rto
+send  232: rtt = 0.339, srtt = 0.336, rttvar = 0.014, rto = 2.000
+recv  232
+updated rto
+send  233: rtt = 0.350, srtt = 0.338, rttvar = 0.014, rto = 2.000
+recv  233
+updated rto
+send  234: rtt = 0.292, srtt = 0.332, rttvar = 0.022, rto = 2.000
+recv  234
+updated rto
+send  235: rtt = 0.336, srtt = 0.333, rttvar = 0.017, rto = 2.000
+recv  235
+updated rto
+send  236: rtt = 0.310, srtt = 0.330, rttvar = 0.019, rto = 2.000
+recv  236
+updated rto
+send  237: rtt = 0.319, srtt = 0.328, rttvar = 0.017, rto = 2.000
+recv  237
+updated rto
+send  238: rtt = 0.323, srtt = 0.328, rttvar = 0.014, rto = 2.000
+recv  238
+updated rto
+send  239: rtt = 0.286, srtt = 0.323, rttvar = 0.021, rto = 2.000
+recv  239
+updated rto
+send  240: rtt = 0.290, srtt = 0.318, rttvar = 0.024, rto = 2.000
+recv  240
+updated rto
+send  241: rtt = 0.280, srtt = 0.314, rttvar = 0.027, rto = 2.000
+recv  241
+updated rto
+send  242: rtt = 0.330, srtt = 0.316, rttvar = 0.025, rto = 2.000
+recv  242
+updated rto
+send  243: rtt = 0.354, srtt = 0.321, rttvar = 0.028, rto = 2.000
+recv  243
+updated rto
+send  244: rtt = 0.315, srtt = 0.320, rttvar = 0.022, rto = 2.000
+recv  244
+updated rto
+send  245: rtt = 0.349, srtt = 0.323, rttvar = 0.024, rto = 2.000
+recv  245
+updated rto
+send  246: rtt = 0.420, srtt = 0.336, rttvar = 0.042, rto = 2.000
+recv  246
+updated rto
+send  247: rtt = 0.309, srtt = 0.332, rttvar = 0.038, rto = 2.000
+recv  247
+updated rto
+send  248: rtt = 0.309, srtt = 0.329, rttvar = 0.035, rto = 2.000
+recv  248
+updated rto
+send  249: rtt = 0.322, srtt = 0.328, rttvar = 0.028, rto = 2.000
+recv  249
+updated rto
+send  250: rtt = 0.327, srtt = 0.328, rttvar = 0.021, rto = 2.000
+recv  250
+updated rto
+send  251: rtt = 0.309, srtt = 0.326, rttvar = 0.021, rto = 2.000
+recv  251
+updated rto
+send  252: rtt = 0.300, srtt = 0.323, rttvar = 0.022, rto = 2.000
+recv  252
+updated rto
+send  253: rtt = 0.309, srtt = 0.321, rttvar = 0.020, rto = 2.000
+recv  253
+updated rto
+send  254: rtt = 0.310, srtt = 0.320, rttvar = 0.018, rto = 2.000
+recv  254
+updated rto
+send  255: rtt = 0.310, srtt = 0.318, rttvar = 0.016, rto = 2.000
+recv  255
+updated rto
+send  256: rtt = 0.309, srtt = 0.317, rttvar = 0.014, rto = 2.000
+recv  256
+updated rto
+send  257: rtt = 0.340, srtt = 0.320, rttvar = 0.016, rto = 2.000
+recv  257
+updated rto
+send  258: rtt = 0.322, srtt = 0.320, rttvar = 0.013, rto = 2.000
+recv  258
+updated rto
+send  259: rtt = 0.377, srtt = 0.327, rttvar = 0.024, rto = 2.000
+recv  259
+updated rto
+send  260: rtt = 0.363, srtt = 0.332, rttvar = 0.027, rto = 2.000
+recv  260
+updated rto
+send  261: rtt = 0.367, srtt = 0.336, rttvar = 0.029, rto = 2.000
+recv  261
+updated rto
+send  262: rtt = 0.360, srtt = 0.339, rttvar = 0.028, rto = 2.000
+recv  262
+updated rto
+send  263: rtt = 0.321, srtt = 0.337, rttvar = 0.025, rto = 2.000
+recv  263
+updated rto
+send  264: rtt = 0.308, srtt = 0.333, rttvar = 0.026, rto = 2.000
+recv  264
+updated rto
+send  265: rtt = 0.280, srtt = 0.327, rttvar = 0.033, rto = 2.000
+recv  265
+updated rto
+send  266: rtt = 0.319, srtt = 0.326, rttvar = 0.027, rto = 2.000
+recv  266
+updated rto
+send  267: rtt = 0.322, srtt = 0.325, rttvar = 0.021, rto = 2.000
+recv  267
+updated rto
+send  268: rtt = 0.297, srtt = 0.322, rttvar = 0.023, rto = 2.000
+recv  268
+updated rto
+send  269: rtt = 0.319, srtt = 0.321, rttvar = 0.018, rto = 2.000
+recv  269
+updated rto
+send  270: rtt = 0.340, srtt = 0.324, rttvar = 0.018, rto = 2.000
+recv  270
+updated rto
+send  271: rtt = 0.370, srtt = 0.329, rttvar = 0.025, rto = 2.000
+recv  271
+updated rto
+send  272: rtt = 0.310, srtt = 0.327, rttvar = 0.024, rto = 2.000
+recv  272
+updated rto
+send  273: rtt = 0.310, srtt = 0.325, rttvar = 0.022, rto = 2.000
+recv  273
+updated rto
+send  274: rtt = 0.309, srtt = 0.323, rttvar = 0.020, rto = 2.000
+recv  274
+updated rto
+send  275: rtt = 0.370, srtt = 0.329, rttvar = 0.027, rto = 2.000
+recv  275
+updated rto
+send  276: rtt = 0.320, srtt = 0.328, rttvar = 0.023, rto = 2.000
+recv  276
+updated rto
+send  277: rtt = 0.332, srtt = 0.328, rttvar = 0.018, rto = 2.000
+recv  277
+updated rto
+send  278: rtt = 0.337, srtt = 0.329, rttvar = 0.016, rto = 2.000
+recv  278
+updated rto
+send  279: rtt = 0.309, srtt = 0.327, rttvar = 0.017, rto = 2.000
+recv  279
+updated rto
+send  280: rtt = 0.310, srtt = 0.325, rttvar = 0.017, rto = 2.000
+recv  280
+updated rto
+send  281: rtt = 0.289, srtt = 0.320, rttvar = 0.022, rto = 2.000
+recv  281
+updated rto
+send  282: rtt = 0.300, srtt = 0.318, rttvar = 0.021, rto = 2.000
+recv  282
+updated rto
+send  283: rtt = 0.279, srtt = 0.313, rttvar = 0.026, rto = 2.000
+recv  283
+updated rto
+send  284: rtt = 0.339, srtt = 0.316, rttvar = 0.026, rto = 2.000
+recv  284
+updated rto
+send  285: rtt = 0.303, srtt = 0.314, rttvar = 0.023, rto = 2.000
+recv  285
+updated rto
+send  286: rtt = 0.335, srtt = 0.317, rttvar = 0.022, rto = 2.000
+recv  286
+updated rto
+send  287: rtt = 0.322, srtt = 0.318, rttvar = 0.018, rto = 2.000
+recv  287
+updated rto
+send  288: rtt = 0.327, srtt = 0.319, rttvar = 0.016, rto = 2.000
+recv  288
+updated rto
+send  289: rtt = 0.309, srtt = 0.318, rttvar = 0.014, rto = 2.000
+recv  289
+updated rto
+send  290: rtt = 0.320, srtt = 0.318, rttvar = 0.011, rto = 2.000
+recv  290
+updated rto
+send  291: rtt = 0.329, srtt = 0.319, rttvar = 0.011, rto = 2.000
+recv  291
+updated rto
+send  292: rtt = 0.320, srtt = 0.319, rttvar = 0.009, rto = 2.000
+recv  292
+updated rto
+send  293: rtt = 0.309, srtt = 0.318, rttvar = 0.009, rto = 2.000
+recv  293
+updated rto
+send  294: rtt = 0.314, srtt = 0.318, rttvar = 0.008, rto = 2.000
+recv  294
+updated rto
+send  295: rtt = 0.315, srtt = 0.317, rttvar = 0.006, rto = 2.000
+recv  295
+updated rto
+send  296: rtt = 0.300, srtt = 0.315, rttvar = 0.009, rto = 2.000
+recv  296
+updated rto
+send  297: rtt = 0.314, srtt = 0.315, rttvar = 0.007, rto = 2.000
+recv  297
+updated rto
+send  298: rtt = 0.327, srtt = 0.316, rttvar = 0.008, rto = 2.000
+recv  298
+updated rto
+send  299: rtt = 0.307, srtt = 0.315, rttvar = 0.009, rto = 2.000
+recv  299
+updated rto
+send  300: rtt = 0.370, srtt = 0.322, rttvar = 0.020, rto = 2.000
+recv  300
+updated rto
+send  301: rtt = 0.368, srtt = 0.328, rttvar = 0.027, rto = 2.000
+recv  301
+updated rto
+send  302: rtt = 0.330, srtt = 0.328, rttvar = 0.020, rto = 2.000
+recv  302
+updated rto
+send  303: rtt = 0.310, srtt = 0.326, rttvar = 0.020, rto = 2.000
+recv  303
+updated rto
+send  304: rtt = 0.319, srtt = 0.325, rttvar = 0.017, rto = 2.000
+recv  304
+updated rto
+send  305: rtt = 0.339, srtt = 0.327, rttvar = 0.016, rto = 2.000
+recv  305
+updated rto
+send  306: rtt = 0.320, srtt = 0.326, rttvar = 0.014, rto = 2.000
+recv  306
+updated rto
+send  307: rtt = 0.330, srtt = 0.326, rttvar = 0.011, rto = 2.000
+recv  307
+updated rto
+send  308: rtt = 0.350, srtt = 0.329, rttvar = 0.014, rto = 2.000
+recv  308
+updated rto
+send  309: rtt = 0.320, srtt = 0.328, rttvar = 0.013, rto = 2.000
+recv  309
+updated rto
+send  310: rtt = 0.340, srtt = 0.330, rttvar = 0.013, rto = 2.000
+recv  310
+updated rto
+send  311: rtt = 0.320, srtt = 0.328, rttvar = 0.012, rto = 2.000
+recv  311
+updated rto
+send  312: rtt = 0.310, srtt = 0.326, rttvar = 0.014, rto = 2.000
+recv  312
+updated rto
+send  313: rtt = 0.320, srtt = 0.325, rttvar = 0.012, rto = 2.000
+recv  313
+updated rto
+send  314: rtt = 0.340, srtt = 0.327, rttvar = 0.012, rto = 2.000
+recv  314
+updated rto
+send  315: rtt = 0.304, srtt = 0.324, rttvar = 0.015, rto = 2.000
+recv  315
+updated rto
+send  316: rtt = 0.324, srtt = 0.324, rttvar = 0.011, rto = 2.000
+recv  316
+updated rto
+send  317: rtt = 0.330, srtt = 0.325, rttvar = 0.010, rto = 2.000
+recv  317
+updated rto
+send  318: rtt = 0.344, srtt = 0.327, rttvar = 0.012, rto = 2.000
+recv  318
+updated rto
+send  319: rtt = 0.305, srtt = 0.325, rttvar = 0.015, rto = 2.000
+recv  319
+updated rto
+send  320: rtt = 0.299, srtt = 0.321, rttvar = 0.017, rto = 2.000
+recv  320
+updated rto
+send  321: rtt = 0.320, srtt = 0.321, rttvar = 0.013, rto = 2.000
+recv  321
+updated rto
+send  322: rtt = 0.319, srtt = 0.321, rttvar = 0.011, rto = 2.000
+recv  322
+updated rto
+send  323: rtt = 0.320, srtt = 0.321, rttvar = 0.008, rto = 2.000
+recv  323
+updated rto
+send  324: rtt = 0.320, srtt = 0.321, rttvar = 0.006, rto = 2.000
+recv  324
+updated rto
+send  325: rtt = 0.320, srtt = 0.321, rttvar = 0.005, rto = 2.000
+recv  325
+updated rto
+send  326: rtt = 0.329, srtt = 0.322, rttvar = 0.006, rto = 2.000
+recv  326
+updated rto
+send  327: rtt = 0.340, srtt = 0.324, rttvar = 0.009, rto = 2.000
+recv  327
+updated rto
+send  328: rtt = 0.289, srtt = 0.320, rttvar = 0.015, rto = 2.000
+recv  328
+updated rto
+send  329: rtt = 0.329, srtt = 0.321, rttvar = 0.014, rto = 2.000
+recv  329
+updated rto
+send  330: rtt = 0.310, srtt = 0.319, rttvar = 0.013, rto = 2.000
+recv  330
+updated rto
+send  331: rtt = 0.330, srtt = 0.321, rttvar = 0.013, rto = 2.000
+recv  331
+updated rto
+send  332: rtt = 0.290, srtt = 0.317, rttvar = 0.017, rto = 2.000
+recv  332
+updated rto
+send  333: rtt = 0.293, srtt = 0.314, rttvar = 0.019, rto = 2.000
+recv  333
+updated rto
+send  334: rtt = 0.317, srtt = 0.314, rttvar = 0.015, rto = 2.000
+recv  334
+updated rto
+send  335: rtt = 0.332, srtt = 0.317, rttvar = 0.016, rto = 2.000
+recv  335
+updated rto
+send  336: rtt = 0.307, srtt = 0.315, rttvar = 0.014, rto = 2.000
+recv  336
+updated rto
+send  337: rtt = 0.299, srtt = 0.313, rttvar = 0.015, rto = 2.000
+recv  337
+updated rto
+send  338: rtt = 0.313, srtt = 0.313, rttvar = 0.011, rto = 2.000
+recv  338
+updated rto
+send  339: rtt = 0.326, srtt = 0.315, rttvar = 0.011, rto = 2.000
+recv  339
+updated rto
+send  340: rtt = 0.303, srtt = 0.313, rttvar = 0.012, rto = 2.000
+recv  340
+updated rto
+send  341: rtt = 0.297, srtt = 0.311, rttvar = 0.013, rto = 2.000
+recv  341
+updated rto
+send  342: rtt = 0.309, srtt = 0.311, rttvar = 0.010, rto = 2.000
+recv  342
+updated rto
+send  343: rtt = 0.310, srtt = 0.311, rttvar = 0.008, rto = 2.000
+recv  343
+updated rto
+send  344: rtt = 0.329, srtt = 0.313, rttvar = 0.010, rto = 2.000
+recv  344
+updated rto
+send  345: rtt = 0.310, srtt = 0.313, rttvar = 0.009, rto = 2.000
+recv  345
+updated rto
+send  346: rtt = 0.299, srtt = 0.311, rttvar = 0.010, rto = 2.000
+recv  346
+updated rto
+send  347: rtt = 0.350, srtt = 0.316, rttvar = 0.017, rto = 2.000
+recv  347
+updated rto
+send  348: rtt = 0.299, srtt = 0.314, rttvar = 0.017, rto = 2.000
+recv  348
+updated rto
+send  349: rtt = 0.329, srtt = 0.316, rttvar = 0.017, rto = 2.000
+recv  349
+updated rto
+send  350: rtt = 0.430, srtt = 0.330, rttvar = 0.041, rto = 2.000
+recv  350
+updated rto
+send  351: rtt = 0.319, srtt = 0.329, rttvar = 0.034, rto = 2.000
+recv  351
+updated rto
+send  352: rtt = 0.340, srtt = 0.330, rttvar = 0.028, rto = 2.000
+recv  352
+updated rto
+send  353: rtt = 0.300, srtt = 0.326, rttvar = 0.029, rto = 2.000
+recv  353
+updated rto
+send  354: rtt = 0.323, srtt = 0.326, rttvar = 0.022, rto = 2.000
+recv  354
+updated rto
+send  355: rtt = 0.295, srtt = 0.322, rttvar = 0.024, rto = 2.000
+recv  355
+updated rto
+send  356: rtt = 0.346, srtt = 0.325, rttvar = 0.024, rto = 2.000
+recv  356
+updated rto
+send  357: rtt = 0.366, srtt = 0.330, rttvar = 0.028, rto = 2.000
+recv  357
+updated rto
+send  358: rtt = 0.400, srtt = 0.339, rttvar = 0.039, rto = 2.000
+recv  358
+updated rto
+send  359: rtt = 0.316, srtt = 0.336, rttvar = 0.035, rto = 2.000
+recv  359
+updated rto
+send  360: rtt = 0.341, srtt = 0.337, rttvar = 0.027, rto = 2.000
+recv  360
+updated rto
+send  361: rtt = 0.305, srtt = 0.333, rttvar = 0.028, rto = 2.000
+recv  361
+updated rto
+send  362: rtt = 0.310, srtt = 0.330, rttvar = 0.027, rto = 2.000
+recv  362
+updated rto
+send  363: rtt = 0.319, srtt = 0.328, rttvar = 0.023, rto = 2.000
+recv  363
+updated rto
+send  364: rtt = 0.320, srtt = 0.327, rttvar = 0.019, rto = 2.000
+recv  364
+updated rto
+send  365: rtt = 0.340, srtt = 0.329, rttvar = 0.018, rto = 2.000
+recv  365
+updated rto
+send  366: rtt = 0.318, srtt = 0.328, rttvar = 0.016, rto = 2.000
+recv  366
+updated rto
+send  367: rtt = 0.330, srtt = 0.328, rttvar = 0.013, rto = 2.000
+recv  367
+updated rto
+send  368: rtt = 0.319, srtt = 0.327, rttvar = 0.012, rto = 2.000
+recv  368
+updated rto
+send  369: rtt = 0.329, srtt = 0.327, rttvar = 0.009, rto = 2.000
+recv  369
+updated rto
+send  370: rtt = 0.320, srtt = 0.326, rttvar = 0.009, rto = 2.000
+recv  370
+updated rto
+send  371: rtt = 0.288, srtt = 0.321, rttvar = 0.016, rto = 2.000
+recv  371
+updated rto
+send  372: rtt = 0.340, srtt = 0.324, rttvar = 0.017, rto = 2.000
+recv  372
+updated rto
+send  373: rtt = 0.290, srtt = 0.320, rttvar = 0.021, rto = 2.000
+recv  373
+updated rto
+send  374: rtt = 0.324, srtt = 0.320, rttvar = 0.017, rto = 2.000
+recv  374
+updated rto
+send  375: rtt = 0.294, srtt = 0.317, rttvar = 0.019, rto = 2.000
+recv  375
+updated rto
+send  376: rtt = 0.329, srtt = 0.318, rttvar = 0.017, rto = 2.000
+recv  376
+updated rto
+send  377: rtt = 0.339, srtt = 0.321, rttvar = 0.018, rto = 2.000
+recv  377
+updated rto
+send  378: rtt = 0.329, srtt = 0.322, rttvar = 0.016, rto = 2.000
+recv  378
+updated rto
+send  379: rtt = 0.309, srtt = 0.320, rttvar = 0.015, rto = 2.000
+recv  379
+updated rto
+send  380: rtt = 0.320, srtt = 0.320, rttvar = 0.011, rto = 2.000
+recv  380
+updated rto
+send  381: rtt = 0.310, srtt = 0.319, rttvar = 0.011, rto = 2.000
+recv  381
+updated rto
+send  382: rtt = 0.340, srtt = 0.322, rttvar = 0.014, rto = 2.000
+recv  382
+updated rto
+send  383: rtt = 0.329, srtt = 0.323, rttvar = 0.012, rto = 2.000
+recv  383
+updated rto
+send  384: rtt = 0.320, srtt = 0.322, rttvar = 0.010, rto = 2.000
+recv  384
+updated rto
+send  385: rtt = 0.330, srtt = 0.323, rttvar = 0.009, rto = 2.000
+recv  385
+updated rto
+send  386: rtt = 0.320, srtt = 0.323, rttvar = 0.008, rto = 2.000
+recv  386
+updated rto
+send  387: rtt = 0.339, srtt = 0.325, rttvar = 0.010, rto = 2.000
+recv  387
+updated rto
+send  388: rtt = 0.306, srtt = 0.322, rttvar = 0.012, rto = 2.000
+recv  388
+updated rto
+send  389: rtt = 0.313, srtt = 0.321, rttvar = 0.011, rto = 2.000
+recv  389
+updated rto
+send  390: rtt = 0.289, srtt = 0.317, rttvar = 0.017, rto = 2.000
+recv  390
+updated rto
+send  391: rtt = 0.360, srtt = 0.323, rttvar = 0.023, rto = 2.000
+recv  391
+updated rto
+send  392: rtt = 0.329, srtt = 0.323, rttvar = 0.019, rto = 2.000
+recv  392
+updated rto
+send  393: rtt = 0.402, srtt = 0.333, rttvar = 0.034, rto = 2.000
+recv  393
+updated rto
+send  394: rtt = 0.327, srtt = 0.332, rttvar = 0.027, rto = 2.000
+recv  394
+updated rto
+send  395: rtt = 0.340, srtt = 0.333, rttvar = 0.022, rto = 2.000
+recv  395
+updated rto
+send  396: rtt = 0.330, srtt = 0.333, rttvar = 0.017, rto = 2.000
+recv  396
+updated rto
+send  397: rtt = 0.344, srtt = 0.334, rttvar = 0.016, rto = 2.000
+recv  397
+updated rto
+send  398: rtt = 0.345, srtt = 0.336, rttvar = 0.015, rto = 2.000
+recv  398
+updated rto
+send  399: rtt = 0.379, srtt = 0.341, rttvar = 0.022, rto = 2.000
+recv  399
+updated rto
+send  400: rtt = 0.349, srtt = 0.342, rttvar = 0.018, rto = 2.000
+recv  400
+updated rto
+send  401: rtt = 0.339, srtt = 0.342, rttvar = 0.014, rto = 2.000
+recv  401
+updated rto
+send  402: rtt = 0.329, srtt = 0.340, rttvar = 0.014, rto = 2.000
+recv  402
+updated rto
+send  403: rtt = 0.320, srtt = 0.338, rttvar = 0.016, rto = 2.000
+recv  403
+updated rto
+send  404: rtt = 0.374, srtt = 0.342, rttvar = 0.021, rto = 2.000
+recv  404
+updated rto
+send  405: rtt = 0.337, srtt = 0.342, rttvar = 0.017, rto = 2.000
+recv  405
+updated rto
+send  406: rtt = 0.347, srtt = 0.342, rttvar = 0.014, rto = 2.000
+recv  406
+updated rto
+send  407: rtt = 0.339, srtt = 0.342, rttvar = 0.011, rto = 2.000
+recv  407
+updated rto
+send  408: rtt = 0.340, srtt = 0.342, rttvar = 0.009, rto = 2.000
+recv  408
+updated rto
+send  409: rtt = 0.410, srtt = 0.350, rttvar = 0.024, rto = 2.000
+recv  409
+updated rto
+send  410: rtt = 0.339, srtt = 0.349, rttvar = 0.021, rto = 2.000
+recv  410
+updated rto
+send  411: rtt = 0.430, srtt = 0.359, rttvar = 0.036, rto = 2.000
+recv  411
+updated rto
+send  412: rtt = 0.380, srtt = 0.362, rttvar = 0.032, rto = 2.000
+recv  412
+updated rto
+send  413: rtt = 0.310, srtt = 0.355, rttvar = 0.037, rto = 2.000
+recv  413
+updated rto
+send  414: rtt = 0.319, srtt = 0.351, rttvar = 0.037, rto = 2.000
+recv  414
+updated rto
+send  415: rtt = 0.319, srtt = 0.347, rttvar = 0.035, rto = 2.000
+recv  415
+updated rto
+send  416: rtt = 0.309, srtt = 0.342, rttvar = 0.036, rto = 2.000
+recv  416
+updated rto
+send  417: rtt = 0.320, srtt = 0.339, rttvar = 0.032, rto = 2.000
+recv  417
+updated rto
+send  418: rtt = 0.320, srtt = 0.337, rttvar = 0.029, rto = 2.000
+recv  418
+updated rto
+send  419: rtt = 0.329, srtt = 0.336, rttvar = 0.024, rto = 2.000
+recv  419
+updated rto
+send  420: rtt = 0.349, srtt = 0.337, rttvar = 0.021, rto = 2.000
+recv  420
+updated rto
+send  421: rtt = 0.309, srtt = 0.334, rttvar = 0.023, rto = 2.000
+recv  421
+updated rto
+send  422: rtt = 0.309, srtt = 0.331, rttvar = 0.023, rto = 2.000
+recv  422
+updated rto
+send  423: rtt = 0.319, srtt = 0.329, rttvar = 0.021, rto = 2.000
+recv  423
+updated rto
+send  424: rtt = 0.380, srtt = 0.336, rttvar = 0.028, rto = 2.000
+recv  424
+updated rto
+send  425: rtt = 0.302, srtt = 0.331, rttvar = 0.029, rto = 2.000
+recv  425
+updated rto
+send  426: rtt = 0.347, srtt = 0.333, rttvar = 0.026, rto = 2.000
+recv  426
+updated rto
+send  427: rtt = 0.340, srtt = 0.334, rttvar = 0.021, rto = 2.000
+recv  427
+updated rto
+send  428: rtt = 0.350, srtt = 0.336, rttvar = 0.020, rto = 2.000
+recv  428
+updated rto
+send  429: rtt = 0.336, srtt = 0.336, rttvar = 0.015, rto = 2.000
+recv  429
+updated rto
+send  430: rtt = 0.324, srtt = 0.335, rttvar = 0.014, rto = 2.000
+recv  430
+updated rto
+send  431: rtt = 0.328, srtt = 0.334, rttvar = 0.012, rto = 2.000
+recv  431
+updated rto
+send  432: rtt = 0.320, srtt = 0.332, rttvar = 0.013, rto = 2.000
+recv  432
+updated rto
+send  433: rtt = 0.301, srtt = 0.328, rttvar = 0.017, rto = 2.000
+recv  433
+updated rto
+send  434: rtt = 0.317, srtt = 0.327, rttvar = 0.016, rto = 2.000
+recv  434
+updated rto
+send  435: rtt = 0.309, srtt = 0.325, rttvar = 0.016, rto = 2.000
+recv  435
+updated rto
+send  436: rtt = 0.330, srtt = 0.325, rttvar = 0.014, rto = 2.000
+recv  436
+updated rto
+send  437: rtt = 0.300, srtt = 0.322, rttvar = 0.016, rto = 2.000
+recv  437
+updated rto
+send  438: rtt = 0.320, srtt = 0.322, rttvar = 0.013, rto = 2.000
+recv  438
+updated rto
+send  439: rtt = 0.319, srtt = 0.321, rttvar = 0.010, rto = 2.000
+recv  439
+updated rto
+send  440: rtt = 0.323, srtt = 0.322, rttvar = 0.008, rto = 2.000
+recv  440
+updated rto
+send  441: rtt = 0.295, srtt = 0.318, rttvar = 0.013, rto = 2.000
+recv  441
+updated rto
+send  442: rtt = 0.340, srtt = 0.321, rttvar = 0.015, rto = 2.000
+recv  442
+updated rto
+send  443: rtt = 0.340, srtt = 0.323, rttvar = 0.016, rto = 2.000
+recv  443
+updated rto
+send  444: rtt = 0.310, srtt = 0.322, rttvar = 0.015, rto = 2.000
+recv  444
+updated rto
+send  445: rtt = 0.300, srtt = 0.319, rttvar = 0.017, rto = 2.000
+recv  445
+updated rto
+send  446: rtt = 0.349, srtt = 0.323, rttvar = 0.020, rto = 2.000
+recv  446
+updated rto
+send  447: rtt = 0.409, srtt = 0.334, rttvar = 0.037, rto = 2.000
+recv  447
+updated rto
+send  448: rtt = 0.360, srtt = 0.337, rttvar = 0.034, rto = 2.000
+recv  448
+updated rto
+send  449: rtt = 0.300, srtt = 0.332, rttvar = 0.035, rto = 2.000
+recv  449
+updated rto
+send  450: rtt = 0.323, srtt = 0.331, rttvar = 0.028, rto = 2.000
+recv  450
+updated rto
+send  451: rtt = 0.326, srtt = 0.330, rttvar = 0.023, rto = 2.000
+recv  451
+updated rto
+send  452: rtt = 0.348, srtt = 0.333, rttvar = 0.021, rto = 2.000
+recv  452
+updated rto
+send  453: rtt = 0.672, srtt = 0.375, rttvar = 0.101, rto = 2.000
+recv  453
+updated rto
+send  454: rtt = 0.337, srtt = 0.370, rttvar = 0.085, rto = 2.000
+recv  454
+updated rto
+send  455: rtt = 0.298, srtt = 0.361, rttvar = 0.082, rto = 2.000
+recv  455
+updated rto
+send  456: rtt = 0.335, srtt = 0.358, rttvar = 0.068, rto = 2.000
+recv  456
+updated rto
+send  457: rtt = 0.334, srtt = 0.355, rttvar = 0.057, rto = 2.000
+recv  457
+updated rto
+send  458: rtt = 0.329, srtt = 0.352, rttvar = 0.049, rto = 2.000
+recv  458
+updated rto
+send  459: rtt = 0.343, srtt = 0.351, rttvar = 0.039, rto = 2.000
+recv  459
+updated rto
+send  460: rtt = 0.325, srtt = 0.347, rttvar = 0.036, rto = 2.000
+recv  460
+updated rto
+send  461: rtt = 0.309, srtt = 0.343, rttvar = 0.036, rto = 2.000
+recv  461
+updated rto
+send  462: rtt = 0.459, srtt = 0.357, rttvar = 0.056, rto = 2.000
+recv  462
+updated rto
+send  463: rtt = 0.350, srtt = 0.356, rttvar = 0.044, rto = 2.000
+recv  463
+updated rto
+send  464: rtt = 0.350, srtt = 0.355, rttvar = 0.035, rto = 2.000
+recv  464
+updated rto
+send  465: rtt = 0.352, srtt = 0.355, rttvar = 0.027, rto = 2.000
+recv  465
+updated rto
+send  466: rtt = 0.327, srtt = 0.352, rttvar = 0.027, rto = 2.000
+recv  466
+updated rto
+send  467: rtt = 0.320, srtt = 0.348, rttvar = 0.028, rto = 2.000
+recv  467
+updated rto
+send  468: rtt = 0.340, srtt = 0.347, rttvar = 0.023, rto = 2.000
+recv  468
+updated rto
+send  469: rtt = 0.357, srtt = 0.348, rttvar = 0.020, rto = 2.000
+recv  469
+updated rto
+send  470: rtt = 0.301, srtt = 0.342, rttvar = 0.027, rto = 2.000
+recv  470
+updated rto
+send  471: rtt = 0.410, srtt = 0.351, rttvar = 0.037, rto = 2.000
+recv  471
+updated rto
+send  472: rtt = 0.360, srtt = 0.352, rttvar = 0.030, rto = 2.000
+recv  472
+updated rto
+send  473: rtt = 0.350, srtt = 0.352, rttvar = 0.023, rto = 2.000
+recv  473
+updated rto
+send  474: rtt = 0.329, srtt = 0.349, rttvar = 0.023, rto = 2.000
+recv  474
+updated rto
+send  475: rtt = 0.359, srtt = 0.350, rttvar = 0.020, rto = 2.000
+recv  475
+updated rto
+send  476: rtt = 0.330, srtt = 0.348, rttvar = 0.020, rto = 2.000
+recv  476
+updated rto
+send  477: rtt = 0.300, srtt = 0.342, rttvar = 0.027, rto = 2.000
+recv  477
+updated rto
+send  478: rtt = 0.339, srtt = 0.341, rttvar = 0.021, rto = 2.000
+recv  478
+updated rto
+send  479: rtt = 0.319, srtt = 0.338, rttvar = 0.021, rto = 2.000
+recv  479
+updated rto
+send  480: rtt = 0.310, srtt = 0.335, rttvar = 0.023, rto = 2.000
+recv  480
+updated rto
+send  481: rtt = 0.330, srtt = 0.334, rttvar = 0.018, rto = 2.000
+recv  481
+updated rto
+send  482: rtt = 0.379, srtt = 0.340, rttvar = 0.025, rto = 2.000
+recv  482
+updated rto
+send  483: rtt = 0.360, srtt = 0.342, rttvar = 0.024, rto = 2.000
+recv  483
+updated rto
+send  484: rtt = 0.310, srtt = 0.338, rttvar = 0.026, rto = 2.000
+recv  484
+updated rto
+send  485: rtt = 0.330, srtt = 0.337, rttvar = 0.022, rto = 2.000
+recv  485
+updated rto
+send  486: rtt = 0.340, srtt = 0.338, rttvar = 0.017, rto = 2.000
+recv  486
+updated rto
+send  487: rtt = 0.311, srtt = 0.334, rttvar = 0.019, rto = 2.000
+recv  487
+updated rto
+send  488: rtt = 0.308, srtt = 0.331, rttvar = 0.021, rto = 2.000
+recv  488
+updated rto
+send  489: rtt = 0.390, srtt = 0.338, rttvar = 0.031, rto = 2.000
+recv  489
+updated rto
+send  490: rtt = 0.389, srtt = 0.345, rttvar = 0.036, rto = 2.000
+recv  490
+updated rto
+send  491: rtt = 0.300, srtt = 0.339, rttvar = 0.038, rto = 2.000
+recv  491
+updated rto
+send  492: rtt = 0.300, srtt = 0.334, rttvar = 0.038, rto = 2.000
+recv  492
+updated rto
+send  493: rtt = 0.319, srtt = 0.332, rttvar = 0.032, rto = 2.000
+recv  493
+updated rto
+send  494: rtt = 0.323, srtt = 0.331, rttvar = 0.027, rto = 2.000
+recv  494
+updated rto
+send  495: rtt = 0.337, srtt = 0.332, rttvar = 0.021, rto = 2.000
+recv  495
+updated rto
+send  496: rtt = 0.320, srtt = 0.330, rttvar = 0.019, rto = 2.000
+recv  496
+updated rto
+send  497: rtt = 0.320, srtt = 0.329, rttvar = 0.017, rto = 2.000
+recv  497
+updated rto
+send  498: rtt = 0.319, srtt = 0.328, rttvar = 0.015, rto = 2.000
+recv  498
+updated rto
+send  499: rtt = 0.300, srtt = 0.324, rttvar = 0.018, rto = 2.000
+recv  499
+updated rto
+send  500: rtt = 0.339, srtt = 0.326, rttvar = 0.017, rto = 2.000
+recv  500
+updated rto
diff --git a/rtt/rtt.out.vangogh.1 b/rtt/rtt.out.vangogh.1
new file mode 100644 (file)
index 0000000..b2f830a
--- /dev/null
@@ -0,0 +1,1532 @@
+send    1: rtt = 0.000, srtt = 0.000, rttvar = 0.750, rto = 3.000
+recv    1
+updated rto
+send    2: rtt = 0.316, srtt = 0.040, rttvar = 0.641, rto = 2.605
+recv    2
+updated rto
+send    3: rtt = 0.218, srtt = 0.062, rttvar = 0.526, rto = 2.165
+recv    3
+updated rto
+send    4: rtt = 0.225, srtt = 0.082, rttvar = 0.435, rto = 2.000
+recv    4
+updated rto
+send    5: rtt = 0.264, srtt = 0.105, rttvar = 0.372, rto = 2.000
+recv    5
+updated rto
+send    6: rtt = 0.228, srtt = 0.120, rttvar = 0.310, rto = 2.000
+recv    6
+updated rto
+send    7: rtt = 0.221, srtt = 0.133, rttvar = 0.257, rto = 2.000
+recv    7
+updated rto
+send    8: rtt = 0.228, srtt = 0.145, rttvar = 0.217, rto = 2.000
+recv    8
+updated rto
+send    9: rtt = 0.200, srtt = 0.152, rttvar = 0.176, rto = 2.000
+recv    9
+updated rto
+send   10: rtt = 0.240, srtt = 0.163, rttvar = 0.154, rto = 2.000
+recv   10
+updated rto
+send   11: rtt = 0.210, srtt = 0.169, rttvar = 0.128, rto = 2.000
+recv   11
+updated rto
+send   12: rtt = 0.249, srtt = 0.179, rttvar = 0.116, rto = 2.000
+recv   12
+updated rto
+send   13: rtt = 0.240, srtt = 0.186, rttvar = 0.102, rto = 2.000
+recv   13
+updated rto
+send   14: rtt = 0.260, srtt = 0.196, rttvar = 0.095, rto = 2.000
+recv   14
+updated rto
+send   15: rtt = 0.201, srtt = 0.196, rttvar = 0.073, rto = 2.000
+recv   15
+updated rto
+send   16: rtt = 0.248, srtt = 0.203, rttvar = 0.067, rto = 2.000
+recv   16
+updated rto
+send   17: rtt = 0.261, srtt = 0.210, rttvar = 0.065, rto = 2.000
+recv   17
+updated rto
+send   18: rtt = 0.248, srtt = 0.215, rttvar = 0.058, rto = 2.000
+recv   18
+updated rto
+send   19: rtt = 0.260, srtt = 0.220, rttvar = 0.055, rto = 2.000
+recv   19
+updated rto
+send   20: rtt = 0.210, srtt = 0.219, rttvar = 0.044, rto = 2.000
+recv   20
+updated rto
+send   21: rtt = 0.240, srtt = 0.222, rttvar = 0.038, rto = 2.000
+recv   21
+updated rto
+send   22: rtt = 0.240, srtt = 0.224, rttvar = 0.033, rto = 2.000
+recv   22
+updated rto
+send   23: rtt = 0.249, srtt = 0.227, rttvar = 0.031, rto = 2.000
+recv   23
+updated rto
+send   24: rtt = 0.230, srtt = 0.227, rttvar = 0.024, rto = 2.000
+recv   24
+updated rto
+send   25: rtt = 0.240, srtt = 0.229, rttvar = 0.021, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send   25: rtt = 0.240, srtt = 0.229, rttvar = 0.021, rto = 4.000
+recv   25
+updated rto
+send   26: rtt = 0.190, srtt = 0.224, rttvar = 0.026, rto = 2.000
+recv   26
+updated rto
+send   27: rtt = 0.220, srtt = 0.224, rttvar = 0.020, rto = 2.000
+recv   27
+updated rto
+send   28: rtt = 0.259, srtt = 0.228, rttvar = 0.024, rto = 2.000
+recv   28
+updated rto
+send   29: rtt = 0.243, srtt = 0.230, rttvar = 0.022, rto = 2.000
+recv   29
+updated rto
+send   30: rtt = 0.257, srtt = 0.233, rttvar = 0.023, rto = 2.000
+recv   30
+updated rto
+send   31: rtt = 0.260, srtt = 0.237, rttvar = 0.024, rto = 2.000
+recv   31
+updated rto
+send   32: rtt = 0.240, srtt = 0.237, rttvar = 0.019, rto = 2.000
+recv   32
+updated rto
+send   33: rtt = 0.240, srtt = 0.237, rttvar = 0.015, rto = 2.000
+recv   33
+updated rto
+send   34: rtt = 0.249, srtt = 0.239, rttvar = 0.014, rto = 2.000
+recv   34
+updated rto
+send   35: rtt = 0.210, srtt = 0.235, rttvar = 0.018, rto = 2.000
+recv   35
+updated rto
+send   36: rtt = 0.239, srtt = 0.236, rttvar = 0.014, rto = 2.000
+recv   36
+updated rto
+send   37: rtt = 0.240, srtt = 0.236, rttvar = 0.012, rto = 2.000
+recv   37
+updated rto
+send   38: rtt = 0.260, srtt = 0.239, rttvar = 0.015, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send   38: rtt = 0.260, srtt = 0.239, rttvar = 0.015, rto = 4.000
+recv   38
+updated rto
+send   39: rtt = 0.220, srtt = 0.237, rttvar = 0.016, rto = 2.000
+recv   39
+updated rto
+send   40: rtt = 0.230, srtt = 0.236, rttvar = 0.014, rto = 2.000
+recv   40
+updated rto
+send   41: rtt = 0.250, srtt = 0.238, rttvar = 0.014, rto = 2.000
+recv   41
+updated rto
+send   42: rtt = 0.240, srtt = 0.238, rttvar = 0.011, rto = 2.000
+recv   42
+updated rto
+send   43: rtt = 0.240, srtt = 0.238, rttvar = 0.009, rto = 2.000
+recv   43
+updated rto
+send   44: rtt = 0.210, srtt = 0.235, rttvar = 0.014, rto = 2.000
+recv   44
+updated rto
+send   45: rtt = 0.240, srtt = 0.235, rttvar = 0.011, rto = 2.000
+recv   45
+updated rto
+send   46: rtt = 0.239, srtt = 0.236, rttvar = 0.010, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send   46: rtt = 0.239, srtt = 0.236, rttvar = 0.010, rto = 4.000
+recv   46
+updated rto
+send   47: rtt = 0.240, srtt = 0.236, rttvar = 0.008, rto = 2.000
+recv   47
+updated rto
+send   48: rtt = 0.250, srtt = 0.238, rttvar = 0.010, rto = 2.000
+recv   48
+updated rto
+send   49: rtt = 0.239, srtt = 0.238, rttvar = 0.007, rto = 2.000
+recv   49
+updated rto
+send   50: rtt = 0.220, srtt = 0.236, rttvar = 0.010, rto = 2.000
+recv   50
+updated rto
+send   51: rtt = 0.229, srtt = 0.235, rttvar = 0.009, rto = 2.000
+recv   51
+updated rto
+send   52: rtt = 0.210, srtt = 0.232, rttvar = 0.013, rto = 2.000
+recv   52
+updated rto
+send   53: rtt = 0.259, srtt = 0.235, rttvar = 0.017, rto = 2.000
+recv   53
+updated rto
+send   54: rtt = 0.240, srtt = 0.236, rttvar = 0.014, rto = 2.000
+recv   54
+updated rto
+send   55: rtt = 0.260, srtt = 0.239, rttvar = 0.016, rto = 2.000
+recv   55
+updated rto
+send   56: rtt = 0.249, srtt = 0.240, rttvar = 0.015, rto = 2.000
+recv   56
+updated rto
+send   57: rtt = 0.249, srtt = 0.241, rttvar = 0.013, rto = 2.000
+recv   57
+updated rto
+send   58: rtt = 0.240, srtt = 0.241, rttvar = 0.010, rto = 2.000
+recv   58
+updated rto
+send   59: rtt = 0.209, srtt = 0.237, rttvar = 0.016, rto = 2.000
+recv   59
+updated rto
+send   60: rtt = 0.190, srtt = 0.231, rttvar = 0.024, rto = 2.000
+recv   60
+updated rto
+send   61: rtt = 0.230, srtt = 0.231, rttvar = 0.018, rto = 2.000
+recv   61
+updated rto
+send   62: rtt = 0.229, srtt = 0.231, rttvar = 0.014, rto = 2.000
+recv   62
+updated rto
+send   63: rtt = 0.229, srtt = 0.231, rttvar = 0.011, rto = 2.000
+recv   63
+updated rto
+send   64: rtt = 0.210, srtt = 0.228, rttvar = 0.013, rto = 2.000
+recv   64
+updated rto
+send   65: rtt = 0.230, srtt = 0.228, rttvar = 0.011, rto = 2.000
+recv   65
+updated rto
+send   66: rtt = 0.200, srtt = 0.225, rttvar = 0.015, rto = 2.000
+recv   66
+updated rto
+send   67: rtt = 0.240, srtt = 0.227, rttvar = 0.015, rto = 2.000
+recv   67
+updated rto
+send   68: rtt = 0.260, srtt = 0.231, rttvar = 0.020, rto = 2.000
+recv   68
+updated rto
+send   69: rtt = 0.240, srtt = 0.232, rttvar = 0.017, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send   69: rtt = 0.240, srtt = 0.232, rttvar = 0.017, rto = 4.000
+recv   69
+updated rto
+send   70: rtt = 0.200, srtt = 0.228, rttvar = 0.021, rto = 2.000
+recv   70
+updated rto
+send   71: rtt = 0.250, srtt = 0.231, rttvar = 0.021, rto = 2.000
+recv   71
+updated rto
+send   72: rtt = 0.220, srtt = 0.229, rttvar = 0.018, rto = 2.000
+recv   72
+updated rto
+send   73: rtt = 0.239, srtt = 0.231, rttvar = 0.016, rto = 2.000
+recv   73
+updated rto
+send   74: rtt = 0.229, srtt = 0.230, rttvar = 0.013, rto = 2.000
+recv   74
+updated rto
+send   75: rtt = 0.210, srtt = 0.228, rttvar = 0.015, rto = 2.000
+recv   75
+updated rto
+send   76: rtt = 0.199, srtt = 0.224, rttvar = 0.018, rto = 2.000
+recv   76
+updated rto
+send   77: rtt = 0.250, srtt = 0.227, rttvar = 0.020, rto = 2.000
+recv   77
+updated rto
+send   78: rtt = 0.199, srtt = 0.224, rttvar = 0.022, rto = 2.000
+recv   78
+updated rto
+send   79: rtt = 0.249, srtt = 0.227, rttvar = 0.023, rto = 2.000
+recv   79
+updated rto
+send   80: rtt = 0.239, srtt = 0.229, rttvar = 0.020, rto = 2.000
+recv   80
+updated rto
+send   81: rtt = 0.230, srtt = 0.229, rttvar = 0.015, rto = 2.000
+recv   81
+updated rto
+send   82: rtt = 0.259, srtt = 0.232, rttvar = 0.019, rto = 2.000
+recv   82
+updated rto
+send   83: rtt = 0.240, srtt = 0.233, rttvar = 0.016, rto = 2.000
+recv   83
+updated rto
+send   84: rtt = 0.240, srtt = 0.234, rttvar = 0.014, rto = 2.000
+recv   84
+updated rto
+send   85: rtt = 0.250, srtt = 0.236, rttvar = 0.014, rto = 2.000
+recv   85
+updated rto
+send   86: rtt = 0.230, srtt = 0.235, rttvar = 0.012, rto = 2.000
+recv   86
+updated rto
+send   87: rtt = 0.259, srtt = 0.238, rttvar = 0.015, rto = 2.000
+recv   87
+updated rto
+send   88: rtt = 0.220, srtt = 0.236, rttvar = 0.016, rto = 2.000
+recv   88
+updated rto
+send   89: rtt = 0.239, srtt = 0.236, rttvar = 0.013, rto = 2.000
+recv   89
+updated rto
+send   90: rtt = 0.250, srtt = 0.238, rttvar = 0.013, rto = 2.000
+recv   90
+updated rto
+send   91: rtt = 0.230, srtt = 0.237, rttvar = 0.012, rto = 2.000
+recv   91
+updated rto
+send   92: rtt = 0.219, srtt = 0.235, rttvar = 0.013, rto = 2.000
+recv   92
+updated rto
+send   93: rtt = 0.220, srtt = 0.233, rttvar = 0.014, rto = 2.000
+recv   93
+updated rto
+send   94: rtt = 0.229, srtt = 0.233, rttvar = 0.011, rto = 2.000
+recv   94
+updated rto
+send   95: rtt = 0.239, srtt = 0.233, rttvar = 0.010, rto = 2.000
+recv   95
+updated rto
+send   96: rtt = 0.250, srtt = 0.235, rttvar = 0.012, rto = 2.000
+recv   96
+updated rto
+send   97: rtt = 0.250, srtt = 0.237, rttvar = 0.012, rto = 2.000
+recv   97
+updated rto
+send   98: rtt = 0.220, srtt = 0.235, rttvar = 0.014, rto = 2.000
+recv   98
+updated rto
+send   99: rtt = 0.230, srtt = 0.234, rttvar = 0.012, rto = 2.000
+recv   99
+updated rto
+send  100: rtt = 0.249, srtt = 0.236, rttvar = 0.012, rto = 2.000
+recv  100
+updated rto
+send  101: rtt = 0.240, srtt = 0.237, rttvar = 0.010, rto = 2.000
+recv  101
+updated rto
+send  102: rtt = 0.239, srtt = 0.237, rttvar = 0.008, rto = 2.000
+recv  102
+updated rto
+send  103: rtt = 0.249, srtt = 0.239, rttvar = 0.009, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  103: rtt = 0.249, srtt = 0.239, rttvar = 0.009, rto = 4.000
+recv  103
+updated rto
+send  104: rtt = 0.250, srtt = 0.240, rttvar = 0.010, rto = 2.000
+recv  104
+updated rto
+send  105: rtt = 0.260, srtt = 0.242, rttvar = 0.012, rto = 2.000
+recv  105
+updated rto
+send  106: rtt = 0.250, srtt = 0.243, rttvar = 0.011, rto = 2.000
+recv  106
+updated rto
+send  107: rtt = 0.241, srtt = 0.243, rttvar = 0.009, rto = 2.000
+recv  107
+updated rto
+send  108: rtt = 0.248, srtt = 0.244, rttvar = 0.008, rto = 2.000
+recv  108
+updated rto
+send  109: rtt = 0.249, srtt = 0.244, rttvar = 0.007, rto = 2.000
+recv  109
+updated rto
+send  110: rtt = 0.240, srtt = 0.244, rttvar = 0.007, rto = 2.000
+recv  110
+updated rto
+send  111: rtt = 0.259, srtt = 0.246, rttvar = 0.009, rto = 2.000
+recv  111
+updated rto
+send  112: rtt = 0.310, srtt = 0.254, rttvar = 0.023, rto = 2.000
+recv  112
+updated rto
+send  113: rtt = 0.250, srtt = 0.253, rttvar = 0.018, rto = 2.000
+recv  113
+updated rto
+send  114: rtt = 0.250, srtt = 0.253, rttvar = 0.014, rto = 2.000
+recv  114
+updated rto
+send  115: rtt = 0.230, srtt = 0.250, rttvar = 0.016, rto = 2.000
+recv  115
+updated rto
+send  116: rtt = 0.220, srtt = 0.246, rttvar = 0.020, rto = 2.000
+recv  116
+updated rto
+send  117: rtt = 0.230, srtt = 0.244, rttvar = 0.019, rto = 2.000
+recv  117
+updated rto
+send  118: rtt = 0.240, srtt = 0.244, rttvar = 0.015, rto = 2.000
+recv  118
+updated rto
+send  119: rtt = 0.240, srtt = 0.243, rttvar = 0.012, rto = 2.000
+recv  119
+updated rto
+send  120: rtt = 0.250, srtt = 0.244, rttvar = 0.011, rto = 2.000
+recv  120
+updated rto
+send  121: rtt = 0.250, srtt = 0.245, rttvar = 0.010, rto = 2.000
+recv  121
+updated rto
+send  122: rtt = 0.220, srtt = 0.242, rttvar = 0.013, rto = 2.000
+recv  122
+updated rto
+send  123: rtt = 0.219, srtt = 0.239, rttvar = 0.016, rto = 2.000
+recv  123
+updated rto
+send  124: rtt = 0.219, srtt = 0.236, rttvar = 0.017, rto = 2.000
+recv  124
+updated rto
+send  125: rtt = 0.240, srtt = 0.237, rttvar = 0.014, rto = 2.000
+recv  125
+updated rto
+send  126: rtt = 0.220, srtt = 0.235, rttvar = 0.014, rto = 2.000
+recv  126
+updated rto
+send  127: rtt = 0.230, srtt = 0.234, rttvar = 0.012, rto = 2.000
+recv  127
+updated rto
+send  128: rtt = 0.229, srtt = 0.234, rttvar = 0.010, rto = 2.000
+recv  128
+updated rto
+send  129: rtt = 0.239, srtt = 0.234, rttvar = 0.009, rto = 2.000
+recv  129
+updated rto
+send  130: rtt = 0.230, srtt = 0.234, rttvar = 0.008, rto = 2.000
+recv  130
+updated rto
+send  131: rtt = 0.259, srtt = 0.237, rttvar = 0.012, rto = 2.000
+recv  131
+updated rto
+send  132: rtt = 0.230, srtt = 0.236, rttvar = 0.011, rto = 2.000
+recv  132
+updated rto
+send  133: rtt = 0.249, srtt = 0.238, rttvar = 0.011, rto = 2.000
+recv  133
+updated rto
+send  134: rtt = 0.250, srtt = 0.239, rttvar = 0.012, rto = 2.000
+recv  134
+updated rto
+send  135: rtt = 0.240, srtt = 0.239, rttvar = 0.009, rto = 2.000
+recv  135
+updated rto
+send  136: rtt = 0.248, srtt = 0.240, rttvar = 0.009, rto = 2.000
+recv  136
+updated rto
+send  137: rtt = 0.200, srtt = 0.235, rttvar = 0.017, rto = 2.000
+recv  137
+updated rto
+send  138: rtt = 0.260, srtt = 0.238, rttvar = 0.019, rto = 2.000
+recv  138
+updated rto
+send  139: rtt = 0.230, srtt = 0.237, rttvar = 0.016, rto = 2.000
+recv  139
+updated rto
+send  140: rtt = 0.230, srtt = 0.236, rttvar = 0.014, rto = 2.000
+recv  140
+updated rto
+send  141: rtt = 0.230, srtt = 0.236, rttvar = 0.012, rto = 2.000
+recv  141
+updated rto
+send  142: rtt = 0.349, srtt = 0.250, rttvar = 0.037, rto = 2.000
+recv  142
+updated rto
+send  143: rtt = 0.230, srtt = 0.247, rttvar = 0.033, rto = 2.000
+recv  143
+updated rto
+send  144: rtt = 0.230, srtt = 0.245, rttvar = 0.029, rto = 2.000
+recv  144
+updated rto
+send  145: rtt = 0.250, srtt = 0.246, rttvar = 0.023, rto = 2.000
+recv  145
+updated rto
+send  146: rtt = 0.239, srtt = 0.245, rttvar = 0.019, rto = 2.000
+recv  146
+updated rto
+send  147: rtt = 0.220, srtt = 0.242, rttvar = 0.020, rto = 2.000
+recv  147
+updated rto
+send  148: rtt = 0.240, srtt = 0.242, rttvar = 0.016, rto = 2.000
+recv  148
+updated rto
+send  149: rtt = 0.240, srtt = 0.241, rttvar = 0.012, rto = 2.000
+recv  149
+updated rto
+send  150: rtt = 0.249, srtt = 0.242, rttvar = 0.011, rto = 2.000
+recv  150
+updated rto
+send  151: rtt = 0.219, srtt = 0.239, rttvar = 0.014, rto = 2.000
+recv  151
+updated rto
+send  152: rtt = 0.220, srtt = 0.237, rttvar = 0.015, rto = 2.000
+recv  152
+updated rto
+send  153: rtt = 0.229, srtt = 0.236, rttvar = 0.014, rto = 2.000
+recv  153
+updated rto
+send  154: rtt = 0.260, srtt = 0.239, rttvar = 0.016, rto = 2.000
+recv  154
+updated rto
+send  155: rtt = 0.259, srtt = 0.241, rttvar = 0.017, rto = 2.000
+recv  155
+updated rto
+send  156: rtt = 0.260, srtt = 0.244, rttvar = 0.017, rto = 2.000
+recv  156
+updated rto
+send  157: rtt = 0.239, srtt = 0.243, rttvar = 0.014, rto = 2.000
+recv  157
+updated rto
+send  158: rtt = 0.249, srtt = 0.244, rttvar = 0.012, rto = 2.000
+recv  158
+updated rto
+send  159: rtt = 0.229, srtt = 0.242, rttvar = 0.013, rto = 2.000
+recv  159
+updated rto
+send  160: rtt = 0.220, srtt = 0.239, rttvar = 0.015, rto = 2.000
+recv  160
+updated rto
+send  161: rtt = 0.240, srtt = 0.239, rttvar = 0.012, rto = 2.000
+recv  161
+updated rto
+send  162: rtt = 0.230, srtt = 0.238, rttvar = 0.011, rto = 2.000
+recv  162
+updated rto
+send  163: rtt = 0.230, srtt = 0.237, rttvar = 0.010, rto = 2.000
+recv  163
+updated rto
+send  164: rtt = 0.239, srtt = 0.237, rttvar = 0.008, rto = 2.000
+recv  164
+updated rto
+send  165: rtt = 0.269, srtt = 0.241, rttvar = 0.014, rto = 2.000
+recv  165
+updated rto
+send  166: rtt = 0.220, srtt = 0.239, rttvar = 0.016, rto = 2.000
+recv  166
+updated rto
+send  167: rtt = 0.219, srtt = 0.236, rttvar = 0.017, rto = 2.000
+recv  167
+updated rto
+send  168: rtt = 0.220, srtt = 0.234, rttvar = 0.017, rto = 2.000
+recv  168
+updated rto
+send  169: rtt = 0.220, srtt = 0.232, rttvar = 0.016, rto = 2.000
+recv  169
+updated rto
+send  170: rtt = 0.240, srtt = 0.233, rttvar = 0.014, rto = 2.000
+recv  170
+updated rto
+send  171: rtt = 0.239, srtt = 0.234, rttvar = 0.012, rto = 2.000
+recv  171
+updated rto
+send  172: rtt = 0.240, srtt = 0.235, rttvar = 0.010, rto = 2.000
+recv  172
+updated rto
+send  173: rtt = 0.240, srtt = 0.235, rttvar = 0.009, rto = 2.000
+recv  173
+updated rto
+send  174: rtt = 0.240, srtt = 0.236, rttvar = 0.008, rto = 2.000
+recv  174
+updated rto
+send  175: rtt = 0.229, srtt = 0.235, rttvar = 0.008, rto = 2.000
+recv  175
+updated rto
+send  176: rtt = 0.199, srtt = 0.231, rttvar = 0.015, rto = 2.000
+recv  176
+updated rto
+send  177: rtt = 0.249, srtt = 0.233, rttvar = 0.016, rto = 2.000
+recv  177
+updated rto
+send  178: rtt = 0.239, srtt = 0.234, rttvar = 0.013, rto = 2.000
+recv  178
+updated rto
+send  179: rtt = 0.220, srtt = 0.232, rttvar = 0.013, rto = 2.000
+recv  179
+updated rto
+send  180: rtt = 0.240, srtt = 0.233, rttvar = 0.012, rto = 2.000
+recv  180
+updated rto
+send  181: rtt = 0.219, srtt = 0.231, rttvar = 0.013, rto = 2.000
+recv  181
+updated rto
+send  182: rtt = 0.240, srtt = 0.232, rttvar = 0.012, rto = 2.000
+recv  182
+updated rto
+send  183: rtt = 0.240, srtt = 0.233, rttvar = 0.011, rto = 2.000
+recv  183
+updated rto
+send  184: rtt = 0.230, srtt = 0.233, rttvar = 0.009, rto = 2.000
+recv  184
+updated rto
+send  185: rtt = 0.240, srtt = 0.234, rttvar = 0.008, rto = 2.000
+recv  185
+updated rto
+send  186: rtt = 0.230, srtt = 0.233, rttvar = 0.007, rto = 2.000
+recv  186
+updated rto
+send  187: rtt = 0.240, srtt = 0.234, rttvar = 0.007, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  187: rtt = 0.240, srtt = 0.234, rttvar = 0.007, rto = 4.000
+recv  187
+updated rto
+send  188: rtt = 0.229, srtt = 0.233, rttvar = 0.007, rto = 2.000
+recv  188
+updated rto
+send  189: rtt = 0.250, srtt = 0.236, rttvar = 0.009, rto = 2.000
+recv  189
+updated rto
+send  190: rtt = 0.248, srtt = 0.237, rttvar = 0.010, rto = 2.000
+recv  190
+updated rto
+send  191: rtt = 0.230, srtt = 0.236, rttvar = 0.009, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  191: rtt = 0.230, srtt = 0.236, rttvar = 0.009, rto = 4.000
+recv  191
+updated rto
+send  192: rtt = 0.230, srtt = 0.235, rttvar = 0.008, rto = 2.000
+recv  192
+updated rto
+send  193: rtt = 0.230, srtt = 0.235, rttvar = 0.008, rto = 2.000
+recv  193
+updated rto
+send  194: rtt = 0.200, srtt = 0.230, rttvar = 0.014, rto = 2.000
+recv  194
+updated rto
+send  195: rtt = 0.210, srtt = 0.228, rttvar = 0.016, rto = 2.000
+recv  195
+updated rto
+send  196: rtt = 0.200, srtt = 0.224, rttvar = 0.019, rto = 2.000
+recv  196
+updated rto
+send  197: rtt = 0.209, srtt = 0.222, rttvar = 0.018, rto = 2.000
+recv  197
+updated rto
+send  198: rtt = 0.200, srtt = 0.220, rttvar = 0.019, rto = 2.000
+recv  198
+updated rto
+send  199: rtt = 0.231, srtt = 0.221, rttvar = 0.017, rto = 2.000
+recv  199
+updated rto
+send  200: rtt = 0.247, srtt = 0.224, rttvar = 0.019, rto = 2.000
+recv  200
+updated rto
+send  201: rtt = 0.240, srtt = 0.226, rttvar = 0.018, rto = 2.000
+recv  201
+updated rto
+send  202: rtt = 0.220, srtt = 0.225, rttvar = 0.015, rto = 2.000
+recv  202
+updated rto
+send  203: rtt = 0.200, srtt = 0.222, rttvar = 0.018, rto = 2.000
+recv  203
+updated rto
+send  204: rtt = 0.210, srtt = 0.221, rttvar = 0.017, rto = 2.000
+recv  204
+updated rto
+send  205: rtt = 0.200, srtt = 0.218, rttvar = 0.018, rto = 2.000
+recv  205
+updated rto
+send  206: rtt = 0.230, srtt = 0.220, rttvar = 0.016, rto = 2.000
+recv  206
+updated rto
+send  207: rtt = 0.250, srtt = 0.223, rttvar = 0.020, rto = 2.000
+recv  207
+updated rto
+send  208: rtt = 0.239, srtt = 0.225, rttvar = 0.019, rto = 2.000
+recv  208
+updated rto
+send  209: rtt = 0.230, srtt = 0.226, rttvar = 0.015, rto = 2.000
+recv  209
+updated rto
+send  210: rtt = 0.249, srtt = 0.229, rttvar = 0.017, rto = 2.000
+recv  210
+updated rto
+send  211: rtt = 0.230, srtt = 0.229, rttvar = 0.013, rto = 2.000
+recv  211
+updated rto
+send  212: rtt = 0.240, srtt = 0.230, rttvar = 0.013, rto = 2.000
+recv  212
+updated rto
+send  213: rtt = 0.240, srtt = 0.232, rttvar = 0.012, rto = 2.000
+recv  213
+updated rto
+send  214: rtt = 0.218, srtt = 0.230, rttvar = 0.012, rto = 2.000
+recv  214
+updated rto
+send  215: rtt = 0.229, srtt = 0.230, rttvar = 0.009, rto = 2.000
+recv  215
+updated rto
+send  216: rtt = 0.230, srtt = 0.230, rttvar = 0.007, rto = 2.000
+recv  216
+updated rto
+send  217: rtt = 0.250, srtt = 0.232, rttvar = 0.010, rto = 2.000
+recv  217
+updated rto
+send  218: rtt = 0.229, srtt = 0.232, rttvar = 0.009, rto = 2.000
+recv  218
+updated rto
+send  219: rtt = 0.229, srtt = 0.232, rttvar = 0.007, rto = 2.000
+recv  219
+updated rto
+send  220: rtt = 0.220, srtt = 0.230, rttvar = 0.008, rto = 2.000
+recv  220
+updated rto
+send  221: rtt = 0.220, srtt = 0.229, rttvar = 0.009, rto = 2.000
+recv  221
+updated rto
+send  222: rtt = 0.240, srtt = 0.230, rttvar = 0.009, rto = 2.000
+recv  222
+updated rto
+send  223: rtt = 0.240, srtt = 0.231, rttvar = 0.009, rto = 2.000
+recv  223
+updated rto
+send  224: rtt = 0.249, srtt = 0.234, rttvar = 0.011, rto = 2.000
+recv  224
+updated rto
+send  225: rtt = 0.239, srtt = 0.234, rttvar = 0.010, rto = 2.000
+recv  225
+updated rto
+send  226: rtt = 0.240, srtt = 0.235, rttvar = 0.009, rto = 2.000
+recv  226
+updated rto
+send  227: rtt = 0.279, srtt = 0.241, rttvar = 0.018, rto = 2.000
+recv  227
+updated rto
+send  228: rtt = 0.229, srtt = 0.239, rttvar = 0.016, rto = 2.000
+recv  228
+updated rto
+send  229: rtt = 0.229, srtt = 0.238, rttvar = 0.015, rto = 2.000
+recv  229
+updated rto
+send  230: rtt = 0.239, srtt = 0.238, rttvar = 0.011, rto = 2.000
+recv  230
+updated rto
+send  231: rtt = 0.239, srtt = 0.238, rttvar = 0.009, rto = 2.000
+recv  231
+updated rto
+send  232: rtt = 0.250, srtt = 0.240, rttvar = 0.009, rto = 2.000
+recv  232
+updated rto
+send  233: rtt = 0.249, srtt = 0.241, rttvar = 0.009, rto = 2.000
+recv  233
+updated rto
+send  234: rtt = 0.239, srtt = 0.241, rttvar = 0.008, rto = 2.000
+recv  234
+updated rto
+send  235: rtt = 0.240, srtt = 0.240, rttvar = 0.006, rto = 2.000
+recv  235
+updated rto
+send  236: rtt = 0.230, srtt = 0.239, rttvar = 0.007, rto = 2.000
+recv  236
+updated rto
+send  237: rtt = 0.240, srtt = 0.239, rttvar = 0.005, rto = 2.000
+recv  237
+updated rto
+send  238: rtt = 0.219, srtt = 0.237, rttvar = 0.009, rto = 2.000
+recv  238
+updated rto
+send  239: rtt = 0.199, srtt = 0.232, rttvar = 0.016, rto = 2.000
+recv  239
+updated rto
+send  240: rtt = 0.220, srtt = 0.231, rttvar = 0.015, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  240: rtt = 0.220, srtt = 0.231, rttvar = 0.015, rto = 4.000
+dgsendrecv: timeout, retransmitting
+send  240: rtt = 0.220, srtt = 0.231, rttvar = 0.015, rto = 8.000
+recv  240
+updated rto
+send  241: rtt = 0.210, srtt = 0.228, rttvar = 0.017, rto = 2.000
+recv  241
+updated rto
+send  242: rtt = 0.250, srtt = 0.231, rttvar = 0.018, rto = 2.000
+recv  242
+updated rto
+send  243: rtt = 0.240, srtt = 0.232, rttvar = 0.016, rto = 2.000
+recv  243
+updated rto
+send  244: rtt = 0.242, srtt = 0.233, rttvar = 0.014, rto = 2.000
+recv  244
+updated rto
+send  245: rtt = 0.237, srtt = 0.234, rttvar = 0.012, rto = 2.000
+recv  245
+updated rto
+send  246: rtt = 0.250, srtt = 0.236, rttvar = 0.013, rto = 2.000
+recv  246
+updated rto
+send  247: rtt = 0.221, srtt = 0.234, rttvar = 0.013, rto = 2.000
+recv  247
+updated rto
+send  248: rtt = 0.229, srtt = 0.233, rttvar = 0.011, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  248: rtt = 0.229, srtt = 0.233, rttvar = 0.011, rto = 4.000
+recv  248
+updated rto
+send  249: rtt = 0.270, srtt = 0.238, rttvar = 0.018, rto = 2.000
+recv  249
+updated rto
+send  250: rtt = 0.260, srtt = 0.241, rttvar = 0.019, rto = 2.000
+recv  250
+updated rto
+send  251: rtt = 0.240, srtt = 0.241, rttvar = 0.014, rto = 2.000
+recv  251
+updated rto
+send  252: rtt = 0.229, srtt = 0.239, rttvar = 0.014, rto = 2.000
+recv  252
+updated rto
+send  253: rtt = 0.230, srtt = 0.238, rttvar = 0.012, rto = 2.000
+recv  253
+updated rto
+send  254: rtt = 0.240, srtt = 0.238, rttvar = 0.010, rto = 2.000
+recv  254
+updated rto
+send  255: rtt = 0.229, srtt = 0.237, rttvar = 0.010, rto = 2.000
+recv  255
+updated rto
+send  256: rtt = 0.230, srtt = 0.236, rttvar = 0.009, rto = 2.000
+recv  256
+updated rto
+send  257: rtt = 0.269, srtt = 0.240, rttvar = 0.015, rto = 2.000
+recv  257
+updated rto
+send  258: rtt = 0.219, srtt = 0.238, rttvar = 0.017, rto = 2.000
+recv  258
+updated rto
+send  259: rtt = 0.239, srtt = 0.238, rttvar = 0.013, rto = 2.000
+recv  259
+updated rto
+send  260: rtt = 0.229, srtt = 0.237, rttvar = 0.012, rto = 2.000
+recv  260
+updated rto
+send  261: rtt = 0.219, srtt = 0.234, rttvar = 0.013, rto = 2.000
+recv  261
+updated rto
+send  262: rtt = 0.260, srtt = 0.238, rttvar = 0.016, rto = 2.000
+recv  262
+updated rto
+send  263: rtt = 0.260, srtt = 0.240, rttvar = 0.018, rto = 2.000
+recv  263
+updated rto
+send  264: rtt = 0.240, srtt = 0.240, rttvar = 0.013, rto = 2.000
+recv  264
+updated rto
+send  265: rtt = 0.220, srtt = 0.238, rttvar = 0.015, rto = 2.000
+recv  265
+updated rto
+send  266: rtt = 0.250, srtt = 0.239, rttvar = 0.014, rto = 2.000
+recv  266
+updated rto
+send  267: rtt = 0.250, srtt = 0.241, rttvar = 0.013, rto = 2.000
+recv  267
+updated rto
+send  268: rtt = 0.230, srtt = 0.239, rttvar = 0.013, rto = 2.000
+recv  268
+updated rto
+send  269: rtt = 0.249, srtt = 0.241, rttvar = 0.012, rto = 2.000
+recv  269
+updated rto
+send  270: rtt = 0.250, srtt = 0.242, rttvar = 0.011, rto = 2.000
+recv  270
+updated rto
+send  271: rtt = 0.279, srtt = 0.246, rttvar = 0.018, rto = 2.000
+recv  271
+updated rto
+send  272: rtt = 0.220, srtt = 0.243, rttvar = 0.020, rto = 2.000
+recv  272
+updated rto
+send  273: rtt = 0.230, srtt = 0.241, rttvar = 0.018, rto = 2.000
+recv  273
+updated rto
+send  274: rtt = 0.229, srtt = 0.240, rttvar = 0.017, rto = 2.000
+recv  274
+updated rto
+send  275: rtt = 0.270, srtt = 0.244, rttvar = 0.020, rto = 2.000
+recv  275
+updated rto
+send  276: rtt = 0.260, srtt = 0.246, rttvar = 0.019, rto = 2.000
+recv  276
+updated rto
+send  277: rtt = 0.220, srtt = 0.242, rttvar = 0.021, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  277: rtt = 0.220, srtt = 0.242, rttvar = 0.021, rto = 4.000
+recv  277
+updated rto
+send  278: rtt = 0.250, srtt = 0.243, rttvar = 0.017, rto = 2.000
+recv  278
+updated rto
+send  279: rtt = 0.240, srtt = 0.243, rttvar = 0.014, rto = 2.000
+recv  279
+updated rto
+send  280: rtt = 0.249, srtt = 0.244, rttvar = 0.012, rto = 2.000
+recv  280
+updated rto
+send  281: rtt = 0.211, srtt = 0.240, rttvar = 0.017, rto = 2.000
+recv  281
+updated rto
+send  282: rtt = 0.240, srtt = 0.240, rttvar = 0.013, rto = 2.000
+recv  282
+updated rto
+send  283: rtt = 0.210, srtt = 0.236, rttvar = 0.017, rto = 2.000
+recv  283
+updated rto
+send  284: rtt = 0.240, srtt = 0.236, rttvar = 0.014, rto = 2.000
+recv  284
+updated rto
+send  285: rtt = 0.199, srtt = 0.232, rttvar = 0.020, rto = 2.000
+recv  285
+updated rto
+send  286: rtt = 0.239, srtt = 0.233, rttvar = 0.017, rto = 2.000
+recv  286
+updated rto
+send  287: rtt = 0.230, srtt = 0.232, rttvar = 0.013, rto = 2.000
+recv  287
+updated rto
+send  288: rtt = 0.229, srtt = 0.232, rttvar = 0.011, rto = 2.000
+recv  288
+updated rto
+send  289: rtt = 0.250, srtt = 0.234, rttvar = 0.013, rto = 2.000
+recv  289
+updated rto
+send  290: rtt = 0.239, srtt = 0.235, rttvar = 0.011, rto = 2.000
+recv  290
+updated rto
+send  291: rtt = 0.230, srtt = 0.234, rttvar = 0.009, rto = 2.000
+recv  291
+updated rto
+send  292: rtt = 0.239, srtt = 0.235, rttvar = 0.008, rto = 2.000
+recv  292
+updated rto
+send  293: rtt = 0.240, srtt = 0.235, rttvar = 0.007, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  293: rtt = 0.240, srtt = 0.235, rttvar = 0.007, rto = 4.000
+recv  293
+updated rto
+send  294: rtt = 0.220, srtt = 0.234, rttvar = 0.009, rto = 2.000
+recv  294
+updated rto
+send  295: rtt = 0.240, srtt = 0.234, rttvar = 0.009, rto = 2.000
+recv  295
+updated rto
+send  296: rtt = 0.219, srtt = 0.232, rttvar = 0.010, rto = 2.000
+recv  296
+updated rto
+send  297: rtt = 0.230, srtt = 0.232, rttvar = 0.008, rto = 2.000
+recv  297
+updated rto
+send  298: rtt = 0.240, srtt = 0.233, rttvar = 0.008, rto = 2.000
+recv  298
+updated rto
+send  299: rtt = 0.240, srtt = 0.234, rttvar = 0.008, rto = 2.000
+recv  299
+updated rto
+send  300: rtt = 0.259, srtt = 0.237, rttvar = 0.012, rto = 2.000
+recv  300
+updated rto
+send  301: rtt = 0.230, srtt = 0.236, rttvar = 0.011, rto = 2.000
+recv  301
+updated rto
+send  302: rtt = 0.230, srtt = 0.235, rttvar = 0.010, rto = 2.000
+recv  302
+updated rto
+send  303: rtt = 0.240, srtt = 0.236, rttvar = 0.008, rto = 2.000
+recv  303
+updated rto
+send  304: rtt = 0.250, srtt = 0.238, rttvar = 0.010, rto = 2.000
+recv  304
+updated rto
+send  305: rtt = 0.230, srtt = 0.237, rttvar = 0.009, rto = 2.000
+recv  305
+updated rto
+send  306: rtt = 0.230, srtt = 0.236, rttvar = 0.009, rto = 2.000
+recv  306
+updated rto
+send  307: rtt = 0.209, srtt = 0.233, rttvar = 0.013, rto = 2.000
+recv  307
+updated rto
+send  308: rtt = 0.232, srtt = 0.232, rttvar = 0.010, rto = 2.000
+recv  308
+updated rto
+send  309: rtt = 0.247, srtt = 0.234, rttvar = 0.011, rto = 2.000
+recv  309
+updated rto
+send  310: rtt = 0.250, srtt = 0.236, rttvar = 0.012, rto = 2.000
+recv  310
+updated rto
+send  311: rtt = 0.229, srtt = 0.235, rttvar = 0.011, rto = 2.000
+recv  311
+updated rto
+send  312: rtt = 0.230, srtt = 0.235, rttvar = 0.010, rto = 2.000
+recv  312
+updated rto
+send  313: rtt = 0.210, srtt = 0.232, rttvar = 0.013, rto = 2.000
+recv  313
+updated rto
+send  314: rtt = 0.249, srtt = 0.234, rttvar = 0.014, rto = 2.000
+recv  314
+updated rto
+send  315: rtt = 0.220, srtt = 0.232, rttvar = 0.014, rto = 2.000
+recv  315
+updated rto
+send  316: rtt = 0.249, srtt = 0.234, rttvar = 0.015, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  316: rtt = 0.249, srtt = 0.234, rttvar = 0.015, rto = 4.000
+recv  316
+updated rto
+send  317: rtt = 0.230, srtt = 0.234, rttvar = 0.012, rto = 2.000
+recv  317
+updated rto
+send  318: rtt = 0.229, srtt = 0.233, rttvar = 0.010, rto = 2.000
+recv  318
+updated rto
+send  319: rtt = 0.229, srtt = 0.233, rttvar = 0.009, rto = 2.000
+recv  319
+updated rto
+send  320: rtt = 0.230, srtt = 0.232, rttvar = 0.007, rto = 2.000
+recv  320
+updated rto
+send  321: rtt = 0.250, srtt = 0.234, rttvar = 0.010, rto = 2.000
+recv  321
+updated rto
+send  322: rtt = 0.249, srtt = 0.236, rttvar = 0.011, rto = 2.000
+recv  322
+updated rto
+send  323: rtt = 0.230, srtt = 0.235, rttvar = 0.010, rto = 2.000
+recv  323
+updated rto
+send  324: rtt = 0.220, srtt = 0.234, rttvar = 0.011, rto = 2.000
+recv  324
+updated rto
+send  325: rtt = 0.229, srtt = 0.233, rttvar = 0.010, rto = 2.000
+recv  325
+updated rto
+send  326: rtt = 0.250, srtt = 0.235, rttvar = 0.011, rto = 2.000
+recv  326
+updated rto
+send  327: rtt = 0.220, srtt = 0.233, rttvar = 0.012, rto = 2.000
+recv  327
+updated rto
+send  328: rtt = 0.210, srtt = 0.230, rttvar = 0.015, rto = 2.000
+recv  328
+updated rto
+send  329: rtt = 0.229, srtt = 0.230, rttvar = 0.012, rto = 2.000
+recv  329
+updated rto
+send  330: rtt = 0.210, srtt = 0.228, rttvar = 0.014, rto = 2.000
+recv  330
+updated rto
+send  331: rtt = 0.220, srtt = 0.227, rttvar = 0.012, rto = 2.000
+recv  331
+updated rto
+send  332: rtt = 0.220, srtt = 0.226, rttvar = 0.011, rto = 2.000
+recv  332
+updated rto
+send  333: rtt = 0.220, srtt = 0.225, rttvar = 0.010, rto = 2.000
+recv  333
+updated rto
+send  334: rtt = 0.250, srtt = 0.228, rttvar = 0.013, rto = 2.000
+recv  334
+updated rto
+send  335: rtt = 0.250, srtt = 0.231, rttvar = 0.016, rto = 2.000
+recv  335
+updated rto
+send  336: rtt = 0.229, srtt = 0.231, rttvar = 0.012, rto = 2.000
+recv  336
+updated rto
+send  337: rtt = 0.239, srtt = 0.232, rttvar = 0.011, rto = 2.000
+recv  337
+updated rto
+send  338: rtt = 0.230, srtt = 0.232, rttvar = 0.009, rto = 2.000
+recv  338
+updated rto
+send  339: rtt = 0.230, srtt = 0.231, rttvar = 0.007, rto = 2.000
+recv  339
+updated rto
+send  340: rtt = 0.219, srtt = 0.230, rttvar = 0.008, rto = 2.000
+recv  340
+updated rto
+send  341: rtt = 0.240, srtt = 0.231, rttvar = 0.009, rto = 2.000
+recv  341
+updated rto
+send  342: rtt = 0.229, srtt = 0.231, rttvar = 0.007, rto = 2.000
+recv  342
+updated rto
+send  343: rtt = 0.220, srtt = 0.229, rttvar = 0.008, rto = 2.000
+recv  343
+updated rto
+send  344: rtt = 0.259, srtt = 0.233, rttvar = 0.013, rto = 2.000
+recv  344
+updated rto
+send  345: rtt = 0.230, srtt = 0.233, rttvar = 0.011, rto = 2.000
+recv  345
+updated rto
+send  346: rtt = 0.219, srtt = 0.231, rttvar = 0.012, rto = 2.000
+recv  346
+updated rto
+send  347: rtt = 0.219, srtt = 0.230, rttvar = 0.012, rto = 2.000
+recv  347
+updated rto
+send  348: rtt = 0.230, srtt = 0.230, rttvar = 0.009, rto = 2.000
+recv  348
+updated rto
+send  349: rtt = 0.240, srtt = 0.231, rttvar = 0.009, rto = 2.000
+recv  349
+updated rto
+send  350: rtt = 0.239, srtt = 0.232, rttvar = 0.009, rto = 2.000
+recv  350
+updated rto
+send  351: rtt = 0.250, srtt = 0.234, rttvar = 0.011, rto = 2.000
+recv  351
+updated rto
+send  352: rtt = 0.250, srtt = 0.236, rttvar = 0.012, rto = 2.000
+recv  352
+updated rto
+send  353: rtt = 0.220, srtt = 0.234, rttvar = 0.013, rto = 2.000
+recv  353
+updated rto
+send  354: rtt = 0.239, srtt = 0.235, rttvar = 0.011, rto = 2.000
+recv  354
+updated rto
+send  355: rtt = 0.230, srtt = 0.234, rttvar = 0.010, rto = 2.000
+recv  355
+updated rto
+send  356: rtt = 0.240, srtt = 0.235, rttvar = 0.009, rto = 2.000
+recv  356
+updated rto
+send  357: rtt = 0.230, srtt = 0.234, rttvar = 0.008, rto = 2.000
+recv  357
+updated rto
+send  358: rtt = 0.270, srtt = 0.239, rttvar = 0.015, rto = 2.000
+recv  358
+updated rto
+send  359: rtt = 0.240, srtt = 0.239, rttvar = 0.011, rto = 2.000
+recv  359
+updated rto
+send  360: rtt = 0.249, srtt = 0.240, rttvar = 0.011, rto = 2.000
+recv  360
+updated rto
+send  361: rtt = 0.240, srtt = 0.240, rttvar = 0.008, rto = 2.000
+recv  361
+updated rto
+send  362: rtt = 0.220, srtt = 0.238, rttvar = 0.011, rto = 2.000
+recv  362
+updated rto
+send  363: rtt = 0.239, srtt = 0.238, rttvar = 0.009, rto = 2.000
+recv  363
+updated rto
+send  364: rtt = 0.240, srtt = 0.238, rttvar = 0.007, rto = 2.000
+recv  364
+updated rto
+send  365: rtt = 0.259, srtt = 0.241, rttvar = 0.011, rto = 2.000
+recv  365
+updated rto
+send  366: rtt = 0.240, srtt = 0.241, rttvar = 0.008, rto = 2.000
+recv  366
+updated rto
+send  367: rtt = 0.239, srtt = 0.240, rttvar = 0.006, rto = 2.000
+recv  367
+updated rto
+send  368: rtt = 0.249, srtt = 0.241, rttvar = 0.007, rto = 2.000
+recv  368
+updated rto
+send  369: rtt = 0.240, srtt = 0.241, rttvar = 0.006, rto = 2.000
+recv  369
+updated rto
+send  370: rtt = 0.239, srtt = 0.241, rttvar = 0.005, rto = 2.000
+recv  370
+updated rto
+send  371: rtt = 0.229, srtt = 0.240, rttvar = 0.007, rto = 2.000
+recv  371
+updated rto
+send  372: rtt = 0.240, srtt = 0.240, rttvar = 0.005, rto = 2.000
+recv  372
+updated rto
+send  373: rtt = 0.259, srtt = 0.242, rttvar = 0.009, rto = 2.000
+recv  373
+updated rto
+send  374: rtt = 0.229, srtt = 0.240, rttvar = 0.010, rto = 2.000
+recv  374
+updated rto
+send  375: rtt = 0.230, srtt = 0.239, rttvar = 0.010, rto = 2.000
+recv  375
+updated rto
+send  376: rtt = 0.239, srtt = 0.239, rttvar = 0.007, rto = 2.000
+recv  376
+updated rto
+send  377: rtt = 0.259, srtt = 0.242, rttvar = 0.011, rto = 2.000
+recv  377
+updated rto
+send  378: rtt = 0.250, srtt = 0.243, rttvar = 0.010, rto = 2.000
+recv  378
+updated rto
+send  379: rtt = 0.250, srtt = 0.244, rttvar = 0.009, rto = 2.000
+recv  379
+updated rto
+send  380: rtt = 0.230, srtt = 0.242, rttvar = 0.010, rto = 2.000
+recv  380
+updated rto
+send  381: rtt = 0.239, srtt = 0.241, rttvar = 0.009, rto = 2.000
+recv  381
+updated rto
+send  382: rtt = 0.279, srtt = 0.246, rttvar = 0.016, rto = 2.000
+recv  382
+updated rto
+send  383: rtt = 0.259, srtt = 0.248, rttvar = 0.015, rto = 2.000
+recv  383
+updated rto
+send  384: rtt = 0.220, srtt = 0.244, rttvar = 0.018, rto = 2.000
+recv  384
+updated rto
+send  385: rtt = 0.249, srtt = 0.245, rttvar = 0.015, rto = 2.000
+recv  385
+updated rto
+send  386: rtt = 0.249, srtt = 0.245, rttvar = 0.012, rto = 2.000
+recv  386
+updated rto
+send  387: rtt = 0.220, srtt = 0.242, rttvar = 0.015, rto = 2.000
+recv  387
+updated rto
+send  388: rtt = 0.210, srtt = 0.238, rttvar = 0.020, rto = 2.000
+recv  388
+updated rto
+send  389: rtt = 0.230, srtt = 0.237, rttvar = 0.017, rto = 2.000
+recv  389
+updated rto
+send  390: rtt = 0.219, srtt = 0.235, rttvar = 0.017, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  390: rtt = 0.219, srtt = 0.235, rttvar = 0.017, rto = 4.000
+recv  390
+updated rto
+send  391: rtt = 0.229, srtt = 0.234, rttvar = 0.014, rto = 2.000
+recv  391
+updated rto
+send  392: rtt = 0.229, srtt = 0.234, rttvar = 0.012, rto = 2.000
+recv  392
+updated rto
+send  393: rtt = 0.239, srtt = 0.234, rttvar = 0.010, rto = 2.000
+recv  393
+updated rto
+send  394: rtt = 0.240, srtt = 0.235, rttvar = 0.009, rto = 2.000
+recv  394
+updated rto
+send  395: rtt = 0.249, srtt = 0.237, rttvar = 0.010, rto = 2.000
+recv  395
+updated rto
+send  396: rtt = 0.250, srtt = 0.238, rttvar = 0.011, rto = 2.000
+recv  396
+updated rto
+send  397: rtt = 0.230, srtt = 0.237, rttvar = 0.010, rto = 2.000
+recv  397
+updated rto
+send  398: rtt = 0.260, srtt = 0.240, rttvar = 0.014, rto = 2.000
+recv  398
+updated rto
+send  399: rtt = 0.270, srtt = 0.244, rttvar = 0.018, rto = 2.000
+recv  399
+updated rto
+send  400: rtt = 0.240, srtt = 0.243, rttvar = 0.014, rto = 2.000
+recv  400
+updated rto
+send  401: rtt = 0.250, srtt = 0.244, rttvar = 0.012, rto = 2.000
+recv  401
+updated rto
+send  402: rtt = 0.259, srtt = 0.246, rttvar = 0.013, rto = 2.000
+recv  402
+updated rto
+send  403: rtt = 0.229, srtt = 0.244, rttvar = 0.014, rto = 2.000
+recv  403
+updated rto
+send  404: rtt = 0.249, srtt = 0.245, rttvar = 0.012, rto = 2.000
+recv  404
+updated rto
+send  405: rtt = 0.229, srtt = 0.243, rttvar = 0.013, rto = 2.000
+recv  405
+updated rto
+send  406: rtt = 0.250, srtt = 0.244, rttvar = 0.011, rto = 2.000
+recv  406
+updated rto
+send  407: rtt = 0.230, srtt = 0.242, rttvar = 0.012, rto = 2.000
+recv  407
+updated rto
+send  408: rtt = 0.230, srtt = 0.240, rttvar = 0.012, rto = 2.000
+recv  408
+updated rto
+send  409: rtt = 0.220, srtt = 0.238, rttvar = 0.014, rto = 2.000
+recv  409
+updated rto
+send  410: rtt = 0.229, srtt = 0.237, rttvar = 0.013, rto = 2.000
+recv  410
+updated rto
+send  411: rtt = 0.249, srtt = 0.238, rttvar = 0.013, rto = 2.000
+recv  411
+updated rto
+send  412: rtt = 0.249, srtt = 0.240, rttvar = 0.012, rto = 2.000
+recv  412
+updated rto
+send  413: rtt = 0.210, srtt = 0.236, rttvar = 0.017, rto = 2.000
+recv  413
+updated rto
+send  414: rtt = 0.220, srtt = 0.234, rttvar = 0.016, rto = 2.000
+recv  414
+updated rto
+send  415: rtt = 0.220, srtt = 0.232, rttvar = 0.016, rto = 2.000
+recv  415
+updated rto
+send  416: rtt = 0.219, srtt = 0.231, rttvar = 0.015, rto = 2.000
+recv  416
+updated rto
+send  417: rtt = 0.239, srtt = 0.232, rttvar = 0.013, rto = 2.000
+recv  417
+updated rto
+send  418: rtt = 0.260, srtt = 0.235, rttvar = 0.017, rto = 2.000
+recv  418
+updated rto
+send  419: rtt = 0.240, srtt = 0.236, rttvar = 0.014, rto = 2.000
+recv  419
+updated rto
+send  420: rtt = 0.229, srtt = 0.235, rttvar = 0.012, rto = 2.000
+recv  420
+updated rto
+send  421: rtt = 0.220, srtt = 0.233, rttvar = 0.013, rto = 2.000
+recv  421
+updated rto
+send  422: rtt = 0.229, srtt = 0.233, rttvar = 0.011, rto = 2.000
+recv  422
+updated rto
+send  423: rtt = 0.249, srtt = 0.235, rttvar = 0.012, rto = 2.000
+recv  423
+updated rto
+send  424: rtt = 0.260, srtt = 0.238, rttvar = 0.015, rto = 2.000
+recv  424
+updated rto
+send  425: rtt = 0.239, srtt = 0.238, rttvar = 0.012, rto = 2.000
+recv  425
+updated rto
+send  426: rtt = 0.240, srtt = 0.238, rttvar = 0.009, rto = 2.000
+recv  426
+updated rto
+send  427: rtt = 0.230, srtt = 0.237, rttvar = 0.009, rto = 2.000
+recv  427
+updated rto
+send  428: rtt = 0.279, srtt = 0.242, rttvar = 0.017, rto = 2.000
+recv  428
+updated rto
+send  429: rtt = 0.240, srtt = 0.242, rttvar = 0.014, rto = 2.000
+recv  429
+updated rto
+send  430: rtt = 0.249, srtt = 0.243, rttvar = 0.012, rto = 2.000
+recv  430
+updated rto
+send  431: rtt = 0.259, srtt = 0.245, rttvar = 0.013, rto = 2.000
+recv  431
+updated rto
+send  432: rtt = 0.250, srtt = 0.246, rttvar = 0.011, rto = 2.000
+recv  432
+updated rto
+send  433: rtt = 0.229, srtt = 0.244, rttvar = 0.012, rto = 2.000
+recv  433
+updated rto
+send  434: rtt = 0.240, srtt = 0.243, rttvar = 0.010, rto = 2.000
+recv  434
+updated rto
+send  435: rtt = 0.230, srtt = 0.241, rttvar = 0.011, rto = 2.000
+recv  435
+updated rto
+send  436: rtt = 0.249, srtt = 0.242, rttvar = 0.010, rto = 2.000
+recv  436
+updated rto
+send  437: rtt = 0.240, srtt = 0.242, rttvar = 0.008, rto = 2.000
+recv  437
+updated rto
+send  438: rtt = 0.240, srtt = 0.242, rttvar = 0.007, rto = 2.000
+recv  438
+updated rto
+send  439: rtt = 0.249, srtt = 0.243, rttvar = 0.007, rto = 2.000
+recv  439
+updated rto
+send  440: rtt = 0.220, srtt = 0.240, rttvar = 0.011, rto = 2.000
+recv  440
+updated rto
+send  441: rtt = 0.219, srtt = 0.237, rttvar = 0.013, rto = 2.000
+recv  441
+updated rto
+send  442: rtt = 0.239, srtt = 0.237, rttvar = 0.010, rto = 2.000
+recv  442
+updated rto
+send  443: rtt = 0.250, srtt = 0.239, rttvar = 0.011, rto = 2.000
+recv  443
+updated rto
+send  444: rtt = 0.240, srtt = 0.239, rttvar = 0.008, rto = 2.000
+recv  444
+updated rto
+send  445: rtt = 0.230, srtt = 0.238, rttvar = 0.009, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  445: rtt = 0.230, srtt = 0.238, rttvar = 0.009, rto = 4.000
+recv  445
+updated rto
+send  446: rtt = 0.489, srtt = 0.269, rttvar = 0.069, rto = 2.000
+recv  446
+updated rto
+send  447: rtt = 0.230, srtt = 0.264, rttvar = 0.062, rto = 2.000
+recv  447
+updated rto
+send  448: rtt = 0.240, srtt = 0.261, rttvar = 0.052, rto = 2.000
+recv  448
+updated rto
+send  449: rtt = 0.250, srtt = 0.260, rttvar = 0.042, rto = 2.000
+recv  449
+updated rto
+send  450: rtt = 0.239, srtt = 0.257, rttvar = 0.037, rto = 2.000
+recv  450
+updated rto
+send  451: rtt = 0.260, srtt = 0.258, rttvar = 0.028, rto = 2.000
+recv  451
+updated rto
+send  452: rtt = 0.240, srtt = 0.255, rttvar = 0.026, rto = 2.000
+recv  452
+updated rto
+send  453: rtt = 0.599, srtt = 0.298, rttvar = 0.105, rto = 2.000
+recv  453
+updated rto
+send  454: rtt = 0.249, srtt = 0.292, rttvar = 0.091, rto = 2.000
+recv  454
+updated rto
+send  455: rtt = 0.220, srtt = 0.283, rttvar = 0.086, rto = 2.000
+recv  455
+updated rto
+send  456: rtt = 0.230, srtt = 0.277, rttvar = 0.078, rto = 2.000
+recv  456
+updated rto
+send  457: rtt = 0.220, srtt = 0.269, rttvar = 0.073, rto = 2.000
+recv  457
+updated rto
+send  458: rtt = 0.239, srtt = 0.266, rttvar = 0.062, rto = 2.000
+recv  458
+updated rto
+send  459: rtt = 0.230, srtt = 0.261, rttvar = 0.056, rto = 2.000
+recv  459
+updated rto
+send  460: rtt = 0.249, srtt = 0.260, rttvar = 0.045, rto = 2.000
+recv  460
+updated rto
+send  461: rtt = 0.240, srtt = 0.257, rttvar = 0.038, rto = 2.000
+recv  461
+updated rto
+send  462: rtt = 0.230, srtt = 0.254, rttvar = 0.036, rto = 2.000
+recv  462
+updated rto
+send  463: rtt = 0.230, srtt = 0.251, rttvar = 0.033, rto = 2.000
+recv  463
+updated rto
+send  464: rtt = 0.240, srtt = 0.249, rttvar = 0.027, rto = 2.000
+recv  464
+updated rto
+send  465: rtt = 0.249, srtt = 0.249, rttvar = 0.021, rto = 2.000
+recv  465
+updated rto
+send  466: rtt = 0.240, srtt = 0.248, rttvar = 0.018, rto = 2.000
+recv  466
+updated rto
+send  467: rtt = 0.229, srtt = 0.246, rttvar = 0.018, rto = 2.000
+recv  467
+updated rto
+send  468: rtt = 0.249, srtt = 0.246, rttvar = 0.014, rto = 2.000
+recv  468
+updated rto
+send  469: rtt = 0.249, srtt = 0.247, rttvar = 0.011, rto = 2.000
+recv  469
+updated rto
+send  470: rtt = 0.230, srtt = 0.245, rttvar = 0.013, rto = 2.000
+recv  470
+updated rto
+send  471: rtt = 0.250, srtt = 0.245, rttvar = 0.011, rto = 2.000
+recv  471
+updated rto
+send  472: rtt = 0.240, srtt = 0.245, rttvar = 0.010, rto = 2.000
+recv  472
+updated rto
+send  473: rtt = 0.250, srtt = 0.245, rttvar = 0.008, rto = 2.000
+recv  473
+updated rto
+send  474: rtt = 0.250, srtt = 0.246, rttvar = 0.008, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  474: rtt = 0.250, srtt = 0.246, rttvar = 0.008, rto = 4.000
+recv  474
+updated rto
+send  475: rtt = 0.240, srtt = 0.245, rttvar = 0.007, rto = 2.000
+recv  475
+updated rto
+send  476: rtt = 0.250, srtt = 0.246, rttvar = 0.007, rto = 2.000
+recv  476
+updated rto
+send  477: rtt = 0.220, srtt = 0.242, rttvar = 0.011, rto = 2.000
+recv  477
+updated rto
+send  478: rtt = 0.250, srtt = 0.243, rttvar = 0.010, rto = 2.000
+recv  478
+updated rto
+send  479: rtt = 0.250, srtt = 0.244, rttvar = 0.009, rto = 2.000
+recv  479
+updated rto
+send  480: rtt = 0.240, srtt = 0.244, rttvar = 0.008, rto = 2.000
+recv  480
+updated rto
+send  481: rtt = 0.229, srtt = 0.242, rttvar = 0.010, rto = 2.000
+recv  481
+updated rto
+send  482: rtt = 0.279, srtt = 0.247, rttvar = 0.017, rto = 2.000
+recv  482
+updated rto
+send  483: rtt = 0.260, srtt = 0.248, rttvar = 0.016, rto = 2.000
+recv  483
+updated rto
+send  484: rtt = 0.209, srtt = 0.243, rttvar = 0.022, rto = 2.000
+recv  484
+updated rto
+send  485: rtt = 0.229, srtt = 0.242, rttvar = 0.020, rto = 2.000
+recv  485
+updated rto
+send  486: rtt = 0.230, srtt = 0.240, rttvar = 0.018, rto = 2.000
+recv  486
+updated rto
+send  487: rtt = 0.240, srtt = 0.240, rttvar = 0.013, rto = 2.000
+recv  487
+updated rto
+send  488: rtt = 0.220, srtt = 0.238, rttvar = 0.015, rto = 2.000
+recv  488
+updated rto
+send  489: rtt = 0.229, srtt = 0.236, rttvar = 0.013, rto = 2.000
+recv  489
+updated rto
+send  490: rtt = 0.309, srtt = 0.246, rttvar = 0.028, rto = 2.000
+recv  490
+updated rto
+send  491: rtt = 0.219, srtt = 0.242, rttvar = 0.028, rto = 2.000
+recv  491
+updated rto
+send  492: rtt = 0.240, srtt = 0.242, rttvar = 0.021, rto = 2.000
+recv  492
+updated rto
+send  493: rtt = 0.220, srtt = 0.239, rttvar = 0.022, rto = 2.000
+recv  493
+updated rto
+send  494: rtt = 0.239, srtt = 0.239, rttvar = 0.016, rto = 2.000
+recv  494
+updated rto
+send  495: rtt = 0.239, srtt = 0.239, rttvar = 0.012, rto = 2.000
+recv  495
+updated rto
+send  496: rtt = 0.239, srtt = 0.239, rttvar = 0.009, rto = 2.000
+recv  496
+updated rto
+send  497: rtt = 0.240, srtt = 0.239, rttvar = 0.007, rto = 2.000
+recv  497
+updated rto
+send  498: rtt = 0.240, srtt = 0.239, rttvar = 0.006, rto = 2.000
+recv  498
+updated rto
+send  499: rtt = 0.230, srtt = 0.238, rttvar = 0.006, rto = 2.000
+recv  499
+updated rto
+send  500: rtt = 0.250, srtt = 0.240, rttvar = 0.008, rto = 2.000
+recv  500
+updated rto
diff --git a/rtt/rtt.out.vangogh.2 b/rtt/rtt.out.vangogh.2
new file mode 100644 (file)
index 0000000..07a6c98
--- /dev/null
@@ -0,0 +1,1568 @@
+send    1: rtt = 0.000, srtt = 0.000, rttvar = 0.750, rto = 3.000
+recv    1
+updated rto
+send    2: rtt = 0.279, srtt = 0.035, rttvar = 0.632, rto = 2.564
+recv    2
+updated rto
+send    3: rtt = 0.238, srtt = 0.060, rttvar = 0.525, rto = 2.160
+recv    3
+updated rto
+send    4: rtt = 0.229, srtt = 0.081, rttvar = 0.436, rto = 2.000
+recv    4
+updated rto
+send    5: rtt = 0.298, srtt = 0.108, rttvar = 0.381, rto = 2.000
+recv    5
+updated rto
+send    6: rtt = 0.280, srtt = 0.130, rttvar = 0.329, rto = 2.000
+recv    6
+updated rto
+send    7: rtt = 0.230, srtt = 0.142, rttvar = 0.272, rto = 2.000
+recv    7
+updated rto
+send    8: rtt = 0.230, srtt = 0.153, rttvar = 0.226, rto = 2.000
+recv    8
+updated rto
+send    9: rtt = 0.219, srtt = 0.162, rttvar = 0.186, rto = 2.000
+recv    9
+updated rto
+send   10: rtt = 0.255, srtt = 0.173, rttvar = 0.163, rto = 2.000
+recv   10
+updated rto
+send   11: rtt = 0.224, srtt = 0.180, rttvar = 0.135, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send   11: rtt = 0.224, srtt = 0.180, rttvar = 0.135, rto = 4.000
+recv   11
+updated rto
+send   12: rtt = 0.259, srtt = 0.190, rttvar = 0.121, rto = 2.000
+recv   12
+updated rto
+send   13: rtt = 0.249, srtt = 0.197, rttvar = 0.105, rto = 2.000
+recv   13
+updated rto
+send   14: rtt = 0.273, srtt = 0.206, rttvar = 0.098, rto = 2.000
+recv   14
+updated rto
+send   15: rtt = 0.217, srtt = 0.208, rttvar = 0.076, rto = 2.000
+recv   15
+updated rto
+send   16: rtt = 0.260, srtt = 0.214, rttvar = 0.070, rto = 2.000
+recv   16
+updated rto
+send   17: rtt = 0.270, srtt = 0.221, rttvar = 0.067, rto = 2.000
+recv   17
+updated rto
+send   18: rtt = 0.240, srtt = 0.224, rttvar = 0.055, rto = 2.000
+recv   18
+updated rto
+send   19: rtt = 0.250, srtt = 0.227, rttvar = 0.048, rto = 2.000
+recv   19
+updated rto
+send   20: rtt = 0.210, srtt = 0.225, rttvar = 0.040, rto = 2.000
+recv   20
+updated rto
+send   21: rtt = 0.269, srtt = 0.230, rttvar = 0.041, rto = 2.000
+recv   21
+updated rto
+send   22: rtt = 0.260, srtt = 0.234, rttvar = 0.038, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send   22: rtt = 0.260, srtt = 0.234, rttvar = 0.038, rto = 4.000
+recv   22
+updated rto
+send   23: rtt = 0.250, srtt = 0.236, rttvar = 0.033, rto = 2.000
+recv   23
+updated rto
+send   24: rtt = 0.280, srtt = 0.242, rttvar = 0.035, rto = 2.000
+recv   24
+updated rto
+send   25: rtt = 0.250, srtt = 0.243, rttvar = 0.029, rto = 2.000
+recv   25
+updated rto
+send   26: rtt = 0.219, srtt = 0.240, rttvar = 0.027, rto = 2.000
+recv   26
+updated rto
+send   27: rtt = 0.230, srtt = 0.238, rttvar = 0.023, rto = 2.000
+recv   27
+updated rto
+send   28: rtt = 0.249, srtt = 0.240, rttvar = 0.020, rto = 2.000
+recv   28
+updated rto
+send   29: rtt = 0.250, srtt = 0.241, rttvar = 0.017, rto = 2.000
+recv   29
+updated rto
+send   30: rtt = 0.250, srtt = 0.242, rttvar = 0.015, rto = 2.000
+recv   30
+updated rto
+send   31: rtt = 0.271, srtt = 0.246, rttvar = 0.019, rto = 2.000
+recv   31
+updated rto
+send   32: rtt = 0.247, srtt = 0.246, rttvar = 0.014, rto = 2.000
+recv   32
+updated rto
+send   33: rtt = 0.282, srtt = 0.250, rttvar = 0.020, rto = 2.000
+recv   33
+updated rto
+send   34: rtt = 0.249, srtt = 0.250, rttvar = 0.015, rto = 2.000
+recv   34
+updated rto
+send   35: rtt = 0.228, srtt = 0.247, rttvar = 0.017, rto = 2.000
+recv   35
+updated rto
+send   36: rtt = 0.220, srtt = 0.244, rttvar = 0.020, rto = 2.000
+recv   36
+updated rto
+send   37: rtt = 0.239, srtt = 0.243, rttvar = 0.016, rto = 2.000
+recv   37
+updated rto
+send   38: rtt = 0.240, srtt = 0.243, rttvar = 0.013, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send   38: rtt = 0.240, srtt = 0.243, rttvar = 0.013, rto = 4.000
+recv   38
+updated rto
+send   39: rtt = 0.220, srtt = 0.240, rttvar = 0.015, rto = 2.000
+recv   39
+updated rto
+send   40: rtt = 0.230, srtt = 0.239, rttvar = 0.014, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send   40: rtt = 0.230, srtt = 0.239, rttvar = 0.014, rto = 4.000
+recv   40
+updated rto
+send   41: rtt = 0.250, srtt = 0.240, rttvar = 0.013, rto = 2.000
+recv   41
+updated rto
+send   42: rtt = 0.249, srtt = 0.241, rttvar = 0.012, rto = 2.000
+recv   42
+updated rto
+send   43: rtt = 0.230, srtt = 0.240, rttvar = 0.012, rto = 2.000
+recv   43
+updated rto
+send   44: rtt = 0.219, srtt = 0.237, rttvar = 0.014, rto = 2.000
+recv   44
+updated rto
+send   45: rtt = 0.250, srtt = 0.239, rttvar = 0.014, rto = 2.000
+recv   45
+updated rto
+send   46: rtt = 0.250, srtt = 0.240, rttvar = 0.013, rto = 2.000
+recv   46
+updated rto
+send   47: rtt = 0.240, srtt = 0.240, rttvar = 0.010, rto = 2.000
+recv   47
+updated rto
+send   48: rtt = 0.270, srtt = 0.244, rttvar = 0.015, rto = 2.000
+recv   48
+updated rto
+send   49: rtt = 0.249, srtt = 0.245, rttvar = 0.012, rto = 2.000
+recv   49
+updated rto
+send   50: rtt = 0.240, srtt = 0.244, rttvar = 0.010, rto = 2.000
+recv   50
+updated rto
+send   51: rtt = 0.240, srtt = 0.244, rttvar = 0.009, rto = 2.000
+recv   51
+updated rto
+send   52: rtt = 0.230, srtt = 0.242, rttvar = 0.010, rto = 2.000
+recv   52
+updated rto
+send   53: rtt = 0.260, srtt = 0.244, rttvar = 0.012, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send   53: rtt = 0.260, srtt = 0.244, rttvar = 0.012, rto = 4.000
+recv   53
+updated rto
+send   54: rtt = 0.290, srtt = 0.250, rttvar = 0.021, rto = 2.000
+recv   54
+updated rto
+send   55: rtt = 0.260, srtt = 0.251, rttvar = 0.018, rto = 2.000
+recv   55
+updated rto
+send   56: rtt = 0.250, srtt = 0.251, rttvar = 0.014, rto = 2.000
+recv   56
+updated rto
+send   57: rtt = 0.250, srtt = 0.251, rttvar = 0.011, rto = 2.000
+recv   57
+updated rto
+send   58: rtt = 0.339, srtt = 0.262, rttvar = 0.030, rto = 2.000
+recv   58
+updated rto
+send   59: rtt = 0.210, srtt = 0.255, rttvar = 0.035, rto = 2.000
+recv   59
+updated rto
+send   60: rtt = 0.210, srtt = 0.250, rttvar = 0.038, rto = 2.000
+recv   60
+updated rto
+send   61: rtt = 0.240, srtt = 0.248, rttvar = 0.031, rto = 2.000
+recv   61
+updated rto
+send   62: rtt = 0.230, srtt = 0.246, rttvar = 0.028, rto = 2.000
+recv   62
+updated rto
+send   63: rtt = 0.219, srtt = 0.243, rttvar = 0.028, rto = 2.000
+recv   63
+updated rto
+send   64: rtt = 0.230, srtt = 0.241, rttvar = 0.024, rto = 2.000
+recv   64
+updated rto
+send   65: rtt = 0.250, srtt = 0.242, rttvar = 0.020, rto = 2.000
+recv   65
+updated rto
+send   66: rtt = 0.234, srtt = 0.241, rttvar = 0.017, rto = 2.000
+recv   66
+updated rto
+send   67: rtt = 0.255, srtt = 0.243, rttvar = 0.016, rto = 2.000
+recv   67
+updated rto
+send   68: rtt = 0.280, srtt = 0.248, rttvar = 0.021, rto = 2.000
+recv   68
+updated rto
+send   69: rtt = 0.270, srtt = 0.250, rttvar = 0.022, rto = 2.000
+recv   69
+updated rto
+send   70: rtt = 0.210, srtt = 0.245, rttvar = 0.026, rto = 2.000
+recv   70
+updated rto
+send   71: rtt = 0.240, srtt = 0.245, rttvar = 0.021, rto = 2.000
+recv   71
+updated rto
+send   72: rtt = 0.250, srtt = 0.245, rttvar = 0.017, rto = 2.000
+recv   72
+updated rto
+send   73: rtt = 0.260, srtt = 0.247, rttvar = 0.017, rto = 2.000
+recv   73
+updated rto
+send   74: rtt = 0.250, srtt = 0.248, rttvar = 0.013, rto = 2.000
+recv   74
+updated rto
+send   75: rtt = 0.240, srtt = 0.247, rttvar = 0.012, rto = 2.000
+recv   75
+updated rto
+send   76: rtt = 0.210, srtt = 0.242, rttvar = 0.018, rto = 2.000
+recv   76
+updated rto
+send   77: rtt = 0.260, srtt = 0.244, rttvar = 0.018, rto = 2.000
+recv   77
+updated rto
+send   78: rtt = 0.210, srtt = 0.240, rttvar = 0.022, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send   78: rtt = 0.210, srtt = 0.240, rttvar = 0.022, rto = 4.000
+recv   78
+updated rto
+send   79: rtt = 0.259, srtt = 0.242, rttvar = 0.021, rto = 2.000
+recv   79
+updated rto
+send   80: rtt = 0.240, srtt = 0.242, rttvar = 0.017, rto = 2.000
+recv   80
+updated rto
+send   81: rtt = 0.239, srtt = 0.242, rttvar = 0.013, rto = 2.000
+recv   81
+updated rto
+send   82: rtt = 0.250, srtt = 0.243, rttvar = 0.012, rto = 2.000
+recv   82
+updated rto
+send   83: rtt = 0.250, srtt = 0.244, rttvar = 0.011, rto = 2.000
+recv   83
+updated rto
+send   84: rtt = 0.230, srtt = 0.242, rttvar = 0.012, rto = 2.000
+recv   84
+updated rto
+send   85: rtt = 0.239, srtt = 0.242, rttvar = 0.009, rto = 2.000
+recv   85
+updated rto
+send   86: rtt = 0.230, srtt = 0.240, rttvar = 0.010, rto = 2.000
+recv   86
+updated rto
+send   87: rtt = 0.270, srtt = 0.244, rttvar = 0.015, rto = 2.000
+recv   87
+updated rto
+send   88: rtt = 0.240, srtt = 0.243, rttvar = 0.012, rto = 2.000
+recv   88
+updated rto
+send   89: rtt = 0.240, srtt = 0.243, rttvar = 0.010, rto = 2.000
+recv   89
+updated rto
+send   90: rtt = 0.250, srtt = 0.244, rttvar = 0.009, rto = 2.000
+recv   90
+updated rto
+send   91: rtt = 0.250, srtt = 0.245, rttvar = 0.008, rto = 2.000
+recv   91
+updated rto
+send   92: rtt = 0.230, srtt = 0.243, rttvar = 0.010, rto = 2.000
+recv   92
+updated rto
+send   93: rtt = 0.220, srtt = 0.240, rttvar = 0.013, rto = 2.000
+recv   93
+updated rto
+send   94: rtt = 0.240, srtt = 0.240, rttvar = 0.010, rto = 2.000
+recv   94
+updated rto
+send   95: rtt = 0.249, srtt = 0.241, rttvar = 0.010, rto = 2.000
+recv   95
+updated rto
+send   96: rtt = 0.230, srtt = 0.240, rttvar = 0.010, rto = 2.000
+recv   96
+updated rto
+send   97: rtt = 0.253, srtt = 0.241, rttvar = 0.011, rto = 2.000
+recv   97
+updated rto
+send   98: rtt = 0.227, srtt = 0.240, rttvar = 0.012, rto = 2.000
+recv   98
+updated rto
+send   99: rtt = 0.229, srtt = 0.238, rttvar = 0.011, rto = 2.000
+recv   99
+updated rto
+send  100: rtt = 0.259, srtt = 0.241, rttvar = 0.014, rto = 2.000
+recv  100
+updated rto
+send  101: rtt = 0.240, srtt = 0.241, rttvar = 0.011, rto = 2.000
+recv  101
+updated rto
+send  102: rtt = 0.240, srtt = 0.241, rttvar = 0.008, rto = 2.000
+recv  102
+updated rto
+send  103: rtt = 0.240, srtt = 0.241, rttvar = 0.006, rto = 2.000
+recv  103
+updated rto
+send  104: rtt = 0.255, srtt = 0.242, rttvar = 0.008, rto = 2.000
+recv  104
+updated rto
+send  105: rtt = 0.273, srtt = 0.246, rttvar = 0.014, rto = 2.000
+recv  105
+updated rto
+send  106: rtt = 0.260, srtt = 0.248, rttvar = 0.014, rto = 2.000
+recv  106
+updated rto
+send  107: rtt = 0.250, srtt = 0.248, rttvar = 0.011, rto = 2.000
+recv  107
+updated rto
+send  108: rtt = 0.254, srtt = 0.249, rttvar = 0.010, rto = 2.000
+recv  108
+updated rto
+send  109: rtt = 0.269, srtt = 0.251, rttvar = 0.012, rto = 2.000
+recv  109
+updated rto
+send  110: rtt = 0.277, srtt = 0.255, rttvar = 0.016, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  110: rtt = 0.277, srtt = 0.255, rttvar = 0.016, rto = 4.000
+recv  110
+updated rto
+send  111: rtt = 0.250, srtt = 0.254, rttvar = 0.013, rto = 2.000
+recv  111
+updated rto
+send  112: rtt = 0.249, srtt = 0.253, rttvar = 0.011, rto = 2.000
+recv  112
+updated rto
+send  113: rtt = 0.260, srtt = 0.254, rttvar = 0.010, rto = 2.000
+recv  113
+updated rto
+send  114: rtt = 0.260, srtt = 0.255, rttvar = 0.009, rto = 2.000
+recv  114
+updated rto
+send  115: rtt = 0.239, srtt = 0.253, rttvar = 0.011, rto = 2.000
+recv  115
+updated rto
+send  116: rtt = 0.230, srtt = 0.250, rttvar = 0.014, rto = 2.000
+recv  116
+updated rto
+send  117: rtt = 0.230, srtt = 0.248, rttvar = 0.015, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  117: rtt = 0.230, srtt = 0.248, rttvar = 0.015, rto = 4.000
+recv  117
+updated rto
+send  118: rtt = 0.240, srtt = 0.247, rttvar = 0.013, rto = 2.000
+recv  118
+updated rto
+send  119: rtt = 0.260, srtt = 0.248, rttvar = 0.013, rto = 2.000
+recv  119
+updated rto
+send  120: rtt = 0.270, srtt = 0.251, rttvar = 0.015, rto = 2.000
+recv  120
+updated rto
+send  121: rtt = 0.260, srtt = 0.252, rttvar = 0.014, rto = 2.000
+recv  121
+updated rto
+send  122: rtt = 0.230, srtt = 0.249, rttvar = 0.016, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  122: rtt = 0.230, srtt = 0.249, rttvar = 0.016, rto = 4.000
+recv  122
+updated rto
+send  123: rtt = 0.220, srtt = 0.246, rttvar = 0.019, rto = 2.000
+recv  123
+updated rto
+send  124: rtt = 0.220, srtt = 0.242, rttvar = 0.021, rto = 2.000
+recv  124
+updated rto
+send  125: rtt = 0.250, srtt = 0.243, rttvar = 0.018, rto = 2.000
+recv  125
+updated rto
+send  126: rtt = 0.220, srtt = 0.240, rttvar = 0.019, rto = 2.000
+recv  126
+updated rto
+send  127: rtt = 0.229, srtt = 0.239, rttvar = 0.017, rto = 2.000
+recv  127
+updated rto
+send  128: rtt = 0.240, srtt = 0.239, rttvar = 0.013, rto = 2.000
+recv  128
+updated rto
+send  129: rtt = 0.229, srtt = 0.238, rttvar = 0.012, rto = 2.000
+recv  129
+updated rto
+send  130: rtt = 0.233, srtt = 0.237, rttvar = 0.010, rto = 2.000
+recv  130
+updated rto
+send  131: rtt = 0.256, srtt = 0.240, rttvar = 0.013, rto = 2.000
+recv  131
+updated rto
+send  132: rtt = 0.229, srtt = 0.238, rttvar = 0.012, rto = 2.000
+recv  132
+updated rto
+send  133: rtt = 0.229, srtt = 0.237, rttvar = 0.011, rto = 2.000
+recv  133
+updated rto
+send  134: rtt = 0.234, srtt = 0.237, rttvar = 0.009, rto = 2.000
+recv  134
+updated rto
+send  135: rtt = 0.250, srtt = 0.238, rttvar = 0.010, rto = 2.000
+recv  135
+updated rto
+send  136: rtt = 0.216, srtt = 0.236, rttvar = 0.013, rto = 2.000
+recv  136
+updated rto
+send  137: rtt = 0.220, srtt = 0.234, rttvar = 0.014, rto = 2.000
+recv  137
+updated rto
+send  138: rtt = 0.249, srtt = 0.236, rttvar = 0.014, rto = 2.000
+recv  138
+updated rto
+send  139: rtt = 0.229, srtt = 0.235, rttvar = 0.012, rto = 2.000
+recv  139
+updated rto
+send  140: rtt = 0.230, srtt = 0.234, rttvar = 0.010, rto = 2.000
+recv  140
+updated rto
+send  141: rtt = 0.250, srtt = 0.236, rttvar = 0.012, rto = 2.000
+recv  141
+updated rto
+send  142: rtt = 0.230, srtt = 0.235, rttvar = 0.010, rto = 2.000
+recv  142
+updated rto
+send  143: rtt = 0.259, srtt = 0.238, rttvar = 0.014, rto = 2.000
+recv  143
+updated rto
+send  144: rtt = 0.240, srtt = 0.239, rttvar = 0.011, rto = 2.000
+recv  144
+updated rto
+send  145: rtt = 0.250, srtt = 0.240, rttvar = 0.011, rto = 2.000
+recv  145
+updated rto
+send  146: rtt = 0.230, srtt = 0.239, rttvar = 0.011, rto = 2.000
+recv  146
+updated rto
+send  147: rtt = 0.220, srtt = 0.236, rttvar = 0.013, rto = 2.000
+recv  147
+updated rto
+send  148: rtt = 0.239, srtt = 0.237, rttvar = 0.010, rto = 2.000
+recv  148
+updated rto
+send  149: rtt = 0.230, srtt = 0.236, rttvar = 0.009, rto = 2.000
+recv  149
+updated rto
+send  150: rtt = 0.260, srtt = 0.239, rttvar = 0.013, rto = 2.000
+recv  150
+updated rto
+send  151: rtt = 0.230, srtt = 0.238, rttvar = 0.012, rto = 2.000
+recv  151
+updated rto
+send  152: rtt = 0.250, srtt = 0.239, rttvar = 0.012, rto = 2.000
+recv  152
+updated rto
+send  153: rtt = 0.230, srtt = 0.238, rttvar = 0.011, rto = 2.000
+recv  153
+updated rto
+send  154: rtt = 0.280, srtt = 0.243, rttvar = 0.019, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  154: rtt = 0.280, srtt = 0.243, rttvar = 0.019, rto = 4.000
+recv  154
+updated rto
+send  155: rtt = 0.270, srtt = 0.247, rttvar = 0.021, rto = 2.000
+recv  155
+updated rto
+send  156: rtt = 0.260, srtt = 0.248, rttvar = 0.019, rto = 2.000
+recv  156
+updated rto
+send  157: rtt = 0.229, srtt = 0.246, rttvar = 0.019, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  157: rtt = 0.229, srtt = 0.246, rttvar = 0.019, rto = 4.000
+recv  157
+updated rto
+send  158: rtt = 0.250, srtt = 0.246, rttvar = 0.015, rto = 2.000
+recv  158
+updated rto
+send  159: rtt = 0.240, srtt = 0.246, rttvar = 0.013, rto = 2.000
+recv  159
+updated rto
+send  160: rtt = 0.230, srtt = 0.244, rttvar = 0.014, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  160: rtt = 0.230, srtt = 0.244, rttvar = 0.014, rto = 4.000
+recv  160
+updated rto
+send  161: rtt = 0.240, srtt = 0.243, rttvar = 0.011, rto = 2.000
+recv  161
+updated rto
+send  162: rtt = 0.230, srtt = 0.242, rttvar = 0.012, rto = 2.000
+recv  162
+updated rto
+send  163: rtt = 0.239, srtt = 0.241, rttvar = 0.009, rto = 2.000
+recv  163
+updated rto
+send  164: rtt = 0.250, srtt = 0.242, rttvar = 0.009, rto = 2.000
+recv  164
+updated rto
+send  165: rtt = 0.249, srtt = 0.243, rttvar = 0.009, rto = 2.000
+recv  165
+updated rto
+send  166: rtt = 0.245, srtt = 0.243, rttvar = 0.007, rto = 2.000
+recv  166
+updated rto
+send  167: rtt = 0.224, srtt = 0.241, rttvar = 0.010, rto = 2.000
+recv  167
+updated rto
+send  168: rtt = 0.240, srtt = 0.241, rttvar = 0.008, rto = 2.000
+recv  168
+updated rto
+send  169: rtt = 0.230, srtt = 0.240, rttvar = 0.009, rto = 2.000
+recv  169
+updated rto
+send  170: rtt = 0.230, srtt = 0.238, rttvar = 0.009, rto = 2.000
+recv  170
+updated rto
+send  171: rtt = 0.239, srtt = 0.238, rttvar = 0.007, rto = 2.000
+recv  171
+updated rto
+send  172: rtt = 0.260, srtt = 0.241, rttvar = 0.010, rto = 2.000
+recv  172
+updated rto
+send  173: rtt = 0.260, srtt = 0.243, rttvar = 0.013, rto = 2.000
+recv  173
+updated rto
+send  174: rtt = 0.250, srtt = 0.244, rttvar = 0.011, rto = 2.000
+recv  174
+updated rto
+send  175: rtt = 0.239, srtt = 0.244, rttvar = 0.010, rto = 2.000
+recv  175
+updated rto
+send  176: rtt = 0.220, srtt = 0.241, rttvar = 0.013, rto = 2.000
+recv  176
+updated rto
+send  177: rtt = 0.280, srtt = 0.246, rttvar = 0.020, rto = 2.000
+recv  177
+updated rto
+send  178: rtt = 0.230, srtt = 0.244, rttvar = 0.019, rto = 2.000
+recv  178
+updated rto
+send  179: rtt = 0.230, srtt = 0.242, rttvar = 0.017, rto = 2.000
+recv  179
+updated rto
+send  180: rtt = 0.240, srtt = 0.242, rttvar = 0.014, rto = 2.000
+recv  180
+updated rto
+send  181: rtt = 0.230, srtt = 0.240, rttvar = 0.013, rto = 2.000
+recv  181
+updated rto
+send  182: rtt = 0.250, srtt = 0.241, rttvar = 0.012, rto = 2.000
+recv  182
+updated rto
+send  183: rtt = 0.239, srtt = 0.241, rttvar = 0.010, rto = 2.000
+recv  183
+updated rto
+send  184: rtt = 0.260, srtt = 0.244, rttvar = 0.012, rto = 2.000
+recv  184
+updated rto
+send  185: rtt = 0.240, srtt = 0.243, rttvar = 0.010, rto = 2.000
+recv  185
+updated rto
+send  186: rtt = 0.239, srtt = 0.243, rttvar = 0.008, rto = 2.000
+recv  186
+updated rto
+send  187: rtt = 0.245, srtt = 0.243, rttvar = 0.007, rto = 2.000
+recv  187
+updated rto
+send  188: rtt = 0.274, srtt = 0.247, rttvar = 0.013, rto = 2.000
+recv  188
+updated rto
+send  189: rtt = 0.240, srtt = 0.246, rttvar = 0.011, rto = 2.000
+recv  189
+updated rto
+send  190: rtt = 0.239, srtt = 0.245, rttvar = 0.010, rto = 2.000
+recv  190
+updated rto
+send  191: rtt = 0.230, srtt = 0.243, rttvar = 0.011, rto = 2.000
+recv  191
+updated rto
+send  192: rtt = 0.260, srtt = 0.245, rttvar = 0.013, rto = 2.000
+recv  192
+updated rto
+send  193: rtt = 0.240, srtt = 0.245, rttvar = 0.011, rto = 2.000
+recv  193
+updated rto
+send  194: rtt = 0.210, srtt = 0.240, rttvar = 0.017, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  194: rtt = 0.210, srtt = 0.240, rttvar = 0.017, rto = 4.000
+recv  194
+updated rto
+send  195: rtt = 0.230, srtt = 0.239, rttvar = 0.015, rto = 2.000
+recv  195
+updated rto
+send  196: rtt = 0.210, srtt = 0.235, rttvar = 0.019, rto = 2.000
+recv  196
+updated rto
+send  197: rtt = 0.240, srtt = 0.236, rttvar = 0.015, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  197: rtt = 0.240, srtt = 0.236, rttvar = 0.015, rto = 4.000
+recv  197
+updated rto
+send  198: rtt = 0.250, srtt = 0.238, rttvar = 0.015, rto = 2.000
+recv  198
+updated rto
+send  199: rtt = 0.250, srtt = 0.239, rttvar = 0.014, rto = 2.000
+recv  199
+updated rto
+send  200: rtt = 0.210, srtt = 0.236, rttvar = 0.018, rto = 2.000
+recv  200
+updated rto
+send  201: rtt = 0.250, srtt = 0.237, rttvar = 0.017, rto = 2.000
+recv  201
+updated rto
+send  202: rtt = 0.230, srtt = 0.236, rttvar = 0.015, rto = 2.000
+recv  202
+updated rto
+send  203: rtt = 0.220, srtt = 0.234, rttvar = 0.015, rto = 2.000
+recv  203
+updated rto
+send  204: rtt = 0.230, srtt = 0.234, rttvar = 0.012, rto = 2.000
+recv  204
+updated rto
+send  205: rtt = 0.240, srtt = 0.235, rttvar = 0.011, rto = 2.000
+recv  205
+updated rto
+send  206: rtt = 0.240, srtt = 0.235, rttvar = 0.009, rto = 2.000
+recv  206
+updated rto
+send  207: rtt = 0.249, srtt = 0.237, rttvar = 0.011, rto = 2.000
+recv  207
+updated rto
+send  208: rtt = 0.230, srtt = 0.236, rttvar = 0.010, rto = 2.000
+recv  208
+updated rto
+send  209: rtt = 0.250, srtt = 0.238, rttvar = 0.011, rto = 2.000
+recv  209
+updated rto
+send  210: rtt = 0.229, srtt = 0.237, rttvar = 0.010, rto = 2.000
+recv  210
+updated rto
+send  211: rtt = 0.230, srtt = 0.236, rttvar = 0.009, rto = 2.000
+recv  211
+updated rto
+send  212: rtt = 0.230, srtt = 0.235, rttvar = 0.009, rto = 2.000
+recv  212
+updated rto
+send  213: rtt = 0.249, srtt = 0.237, rttvar = 0.010, rto = 2.000
+recv  213
+updated rto
+send  214: rtt = 0.240, srtt = 0.237, rttvar = 0.008, rto = 2.000
+recv  214
+updated rto
+send  215: rtt = 0.230, srtt = 0.236, rttvar = 0.008, rto = 2.000
+recv  215
+updated rto
+send  216: rtt = 0.229, srtt = 0.235, rttvar = 0.008, rto = 2.000
+recv  216
+updated rto
+send  217: rtt = 0.245, srtt = 0.237, rttvar = 0.008, rto = 2.000
+recv  217
+updated rto
+send  218: rtt = 0.254, srtt = 0.239, rttvar = 0.011, rto = 2.000
+recv  218
+updated rto
+send  219: rtt = 0.229, srtt = 0.238, rttvar = 0.010, rto = 2.000
+recv  219
+updated rto
+send  220: rtt = 0.230, srtt = 0.237, rttvar = 0.010, rto = 2.000
+recv  220
+updated rto
+send  221: rtt = 0.220, srtt = 0.235, rttvar = 0.011, rto = 2.000
+recv  221
+updated rto
+send  222: rtt = 0.230, srtt = 0.234, rttvar = 0.010, rto = 2.000
+recv  222
+updated rto
+send  223: rtt = 0.229, srtt = 0.233, rttvar = 0.009, rto = 2.000
+recv  223
+updated rto
+send  224: rtt = 0.240, srtt = 0.234, rttvar = 0.008, rto = 2.000
+recv  224
+updated rto
+send  225: rtt = 0.240, srtt = 0.235, rttvar = 0.007, rto = 2.000
+recv  225
+updated rto
+send  226: rtt = 0.260, srtt = 0.238, rttvar = 0.012, rto = 2.000
+recv  226
+updated rto
+send  227: rtt = 0.280, srtt = 0.243, rttvar = 0.019, rto = 2.000
+recv  227
+updated rto
+send  228: rtt = 0.240, srtt = 0.243, rttvar = 0.015, rto = 2.000
+recv  228
+updated rto
+send  229: rtt = 0.240, srtt = 0.243, rttvar = 0.012, rto = 2.000
+recv  229
+updated rto
+send  230: rtt = 0.250, srtt = 0.243, rttvar = 0.011, rto = 2.000
+recv  230
+updated rto
+send  231: rtt = 0.239, srtt = 0.243, rttvar = 0.009, rto = 2.000
+recv  231
+updated rto
+send  232: rtt = 0.250, srtt = 0.244, rttvar = 0.009, rto = 2.000
+recv  232
+updated rto
+send  233: rtt = 0.260, srtt = 0.246, rttvar = 0.011, rto = 2.000
+recv  233
+updated rto
+send  234: rtt = 0.230, srtt = 0.244, rttvar = 0.012, rto = 2.000
+recv  234
+updated rto
+send  235: rtt = 0.240, srtt = 0.243, rttvar = 0.010, rto = 2.000
+recv  235
+updated rto
+send  236: rtt = 0.230, srtt = 0.242, rttvar = 0.011, rto = 2.000
+recv  236
+updated rto
+send  237: rtt = 0.240, srtt = 0.241, rttvar = 0.009, rto = 2.000
+recv  237
+updated rto
+send  238: rtt = 0.230, srtt = 0.240, rttvar = 0.009, rto = 2.000
+recv  238
+updated rto
+send  239: rtt = 0.199, srtt = 0.235, rttvar = 0.017, rto = 2.000
+recv  239
+updated rto
+send  240: rtt = 0.219, srtt = 0.233, rttvar = 0.017, rto = 2.000
+recv  240
+updated rto
+send  241: rtt = 0.190, srtt = 0.228, rttvar = 0.023, rto = 2.000
+recv  241
+updated rto
+send  242: rtt = 0.239, srtt = 0.229, rttvar = 0.020, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  242: rtt = 0.239, srtt = 0.229, rttvar = 0.020, rto = 4.000
+recv  242
+updated rto
+send  243: rtt = 0.300, srtt = 0.238, rttvar = 0.033, rto = 2.000
+recv  243
+updated rto
+send  244: rtt = 0.320, srtt = 0.248, rttvar = 0.045, rto = 2.000
+recv  244
+updated rto
+send  245: rtt = 0.250, srtt = 0.248, rttvar = 0.034, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  245: rtt = 0.250, srtt = 0.248, rttvar = 0.034, rto = 4.000
+recv  245
+updated rto
+send  246: rtt = 0.240, srtt = 0.247, rttvar = 0.028, rto = 2.000
+recv  246
+updated rto
+send  247: rtt = 0.230, srtt = 0.245, rttvar = 0.025, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  247: rtt = 0.230, srtt = 0.245, rttvar = 0.025, rto = 4.000
+recv  247
+updated rto
+send  248: rtt = 0.267, srtt = 0.248, rttvar = 0.024, rto = 2.000
+recv  248
+updated rto
+send  249: rtt = 0.253, srtt = 0.249, rttvar = 0.020, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  249: rtt = 0.253, srtt = 0.249, rttvar = 0.020, rto = 4.000
+recv  249
+updated rto
+send  250: rtt = 0.260, srtt = 0.250, rttvar = 0.018, rto = 2.000
+recv  250
+updated rto
+send  251: rtt = 0.230, srtt = 0.247, rttvar = 0.018, rto = 2.000
+recv  251
+updated rto
+send  252: rtt = 0.210, srtt = 0.243, rttvar = 0.023, rto = 2.000
+recv  252
+updated rto
+send  253: rtt = 0.239, srtt = 0.242, rttvar = 0.018, rto = 2.000
+recv  253
+updated rto
+send  254: rtt = 0.240, srtt = 0.242, rttvar = 0.014, rto = 2.000
+recv  254
+updated rto
+send  255: rtt = 0.243, srtt = 0.242, rttvar = 0.011, rto = 2.000
+recv  255
+updated rto
+send  256: rtt = 0.217, srtt = 0.239, rttvar = 0.014, rto = 2.000
+recv  256
+updated rto
+send  257: rtt = 0.271, srtt = 0.243, rttvar = 0.019, rto = 2.000
+recv  257
+updated rto
+send  258: rtt = 0.228, srtt = 0.241, rttvar = 0.018, rto = 2.000
+recv  258
+updated rto
+send  259: rtt = 0.250, srtt = 0.242, rttvar = 0.016, rto = 2.000
+recv  259
+updated rto
+send  260: rtt = 0.249, srtt = 0.243, rttvar = 0.013, rto = 2.000
+recv  260
+updated rto
+send  261: rtt = 0.220, srtt = 0.240, rttvar = 0.016, rto = 2.000
+recv  261
+updated rto
+send  262: rtt = 0.279, srtt = 0.245, rttvar = 0.022, rto = 2.000
+recv  262
+updated rto
+send  263: rtt = 0.230, srtt = 0.243, rttvar = 0.020, rto = 2.000
+recv  263
+updated rto
+send  264: rtt = 0.566, srtt = 0.284, rttvar = 0.096, rto = 2.000
+recv  264
+updated rto
+send  265: rtt = 0.223, srtt = 0.276, rttvar = 0.087, rto = 2.000
+recv  265
+updated rto
+send  266: rtt = 0.250, srtt = 0.273, rttvar = 0.072, rto = 2.000
+recv  266
+updated rto
+send  267: rtt = 0.263, srtt = 0.271, rttvar = 0.056, rto = 2.000
+recv  267
+updated rto
+send  268: rtt = 0.217, srtt = 0.265, rttvar = 0.056, rto = 2.000
+recv  268
+updated rto
+send  269: rtt = 0.269, srtt = 0.265, rttvar = 0.043, rto = 2.000
+recv  269
+updated rto
+send  270: rtt = 0.261, srtt = 0.265, rttvar = 0.033, rto = 2.000
+recv  270
+updated rto
+send  271: rtt = 0.258, srtt = 0.264, rttvar = 0.027, rto = 2.000
+recv  271
+updated rto
+send  272: rtt = 0.249, srtt = 0.262, rttvar = 0.024, rto = 2.000
+recv  272
+updated rto
+send  273: rtt = 0.244, srtt = 0.260, rttvar = 0.022, rto = 2.000
+recv  273
+updated rto
+send  274: rtt = 0.225, srtt = 0.255, rttvar = 0.025, rto = 2.000
+recv  274
+updated rto
+send  275: rtt = 0.270, srtt = 0.257, rttvar = 0.023, rto = 2.000
+recv  275
+updated rto
+send  276: rtt = 0.250, srtt = 0.256, rttvar = 0.019, rto = 2.000
+recv  276
+updated rto
+send  277: rtt = 0.219, srtt = 0.252, rttvar = 0.023, rto = 2.000
+recv  277
+updated rto
+send  278: rtt = 0.260, srtt = 0.253, rttvar = 0.020, rto = 2.000
+recv  278
+updated rto
+send  279: rtt = 0.259, srtt = 0.253, rttvar = 0.016, rto = 2.000
+recv  279
+updated rto
+send  280: rtt = 0.249, srtt = 0.253, rttvar = 0.013, rto = 2.000
+recv  280
+updated rto
+send  281: rtt = 0.230, srtt = 0.250, rttvar = 0.016, rto = 2.000
+recv  281
+updated rto
+send  282: rtt = 0.228, srtt = 0.247, rttvar = 0.017, rto = 2.000
+recv  282
+updated rto
+send  283: rtt = 0.209, srtt = 0.243, rttvar = 0.023, rto = 2.000
+recv  283
+updated rto
+send  284: rtt = 0.249, srtt = 0.243, rttvar = 0.019, rto = 2.000
+recv  284
+updated rto
+send  285: rtt = 0.219, srtt = 0.240, rttvar = 0.020, rto = 2.000
+recv  285
+updated rto
+send  286: rtt = 0.250, srtt = 0.242, rttvar = 0.017, rto = 2.000
+recv  286
+updated rto
+send  287: rtt = 0.250, srtt = 0.243, rttvar = 0.015, rto = 2.000
+recv  287
+updated rto
+send  288: rtt = 0.250, srtt = 0.243, rttvar = 0.013, rto = 2.000
+recv  288
+updated rto
+send  289: rtt = 0.250, srtt = 0.244, rttvar = 0.012, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  289: rtt = 0.250, srtt = 0.244, rttvar = 0.012, rto = 4.000
+recv  289
+updated rto
+send  290: rtt = 0.259, srtt = 0.246, rttvar = 0.012, rto = 2.000
+recv  290
+updated rto
+send  291: rtt = 0.250, srtt = 0.247, rttvar = 0.010, rto = 2.000
+recv  291
+updated rto
+send  292: rtt = 0.249, srtt = 0.247, rttvar = 0.008, rto = 2.000
+recv  292
+updated rto
+send  293: rtt = 0.240, srtt = 0.246, rttvar = 0.008, rto = 2.000
+recv  293
+updated rto
+send  294: rtt = 0.229, srtt = 0.244, rttvar = 0.010, rto = 2.000
+recv  294
+updated rto
+send  295: rtt = 0.292, srtt = 0.250, rttvar = 0.020, rto = 2.000
+recv  295
+updated rto
+send  296: rtt = 0.216, srtt = 0.246, rttvar = 0.023, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  296: rtt = 0.216, srtt = 0.246, rttvar = 0.023, rto = 4.000
+recv  296
+updated rto
+send  297: rtt = 0.230, srtt = 0.244, rttvar = 0.021, rto = 2.000
+recv  297
+updated rto
+send  298: rtt = 0.230, srtt = 0.242, rttvar = 0.019, rto = 2.000
+recv  298
+updated rto
+send  299: rtt = 0.219, srtt = 0.239, rttvar = 0.020, rto = 2.000
+recv  299
+updated rto
+send  300: rtt = 0.254, srtt = 0.241, rttvar = 0.019, rto = 2.000
+recv  300
+updated rto
+send  301: rtt = 0.278, srtt = 0.246, rttvar = 0.023, rto = 2.000
+recv  301
+updated rto
+send  302: rtt = 0.256, srtt = 0.247, rttvar = 0.020, rto = 2.000
+recv  302
+updated rto
+send  303: rtt = 0.240, srtt = 0.246, rttvar = 0.017, rto = 2.000
+recv  303
+updated rto
+send  304: rtt = 0.240, srtt = 0.245, rttvar = 0.014, rto = 2.000
+recv  304
+updated rto
+send  305: rtt = 0.250, srtt = 0.246, rttvar = 0.012, rto = 2.000
+recv  305
+updated rto
+send  306: rtt = 0.240, srtt = 0.245, rttvar = 0.010, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  306: rtt = 0.240, srtt = 0.245, rttvar = 0.010, rto = 4.000
+recv  306
+updated rto
+send  307: rtt = 0.220, srtt = 0.242, rttvar = 0.014, rto = 2.000
+recv  307
+updated rto
+send  308: rtt = 0.220, srtt = 0.239, rttvar = 0.016, rto = 2.000
+recv  308
+updated rto
+send  309: rtt = 0.240, srtt = 0.239, rttvar = 0.012, rto = 2.000
+recv  309
+updated rto
+send  310: rtt = 0.249, srtt = 0.241, rttvar = 0.012, rto = 2.000
+recv  310
+updated rto
+send  311: rtt = 0.250, srtt = 0.242, rttvar = 0.011, rto = 2.000
+recv  311
+updated rto
+send  312: rtt = 0.260, srtt = 0.244, rttvar = 0.013, rto = 2.000
+recv  312
+updated rto
+send  313: rtt = 0.230, srtt = 0.242, rttvar = 0.013, rto = 2.000
+recv  313
+updated rto
+send  314: rtt = 0.230, srtt = 0.241, rttvar = 0.013, rto = 2.000
+recv  314
+updated rto
+send  315: rtt = 0.199, srtt = 0.236, rttvar = 0.020, rto = 2.000
+recv  315
+updated rto
+send  316: rtt = 0.230, srtt = 0.235, rttvar = 0.016, rto = 2.000
+recv  316
+updated rto
+send  317: rtt = 0.228, srtt = 0.234, rttvar = 0.014, rto = 2.000
+recv  317
+updated rto
+send  318: rtt = 0.239, srtt = 0.235, rttvar = 0.012, rto = 2.000
+recv  318
+updated rto
+send  319: rtt = 0.230, srtt = 0.234, rttvar = 0.010, rto = 2.000
+recv  319
+updated rto
+send  320: rtt = 0.240, srtt = 0.235, rttvar = 0.009, rto = 2.000
+recv  320
+updated rto
+send  321: rtt = 0.249, srtt = 0.237, rttvar = 0.010, rto = 2.000
+recv  321
+updated rto
+send  322: rtt = 0.250, srtt = 0.238, rttvar = 0.011, rto = 2.000
+recv  322
+updated rto
+send  323: rtt = 0.220, srtt = 0.236, rttvar = 0.013, rto = 2.000
+recv  323
+updated rto
+send  324: rtt = 0.226, srtt = 0.235, rttvar = 0.012, rto = 2.000
+recv  324
+updated rto
+send  325: rtt = 0.234, srtt = 0.235, rttvar = 0.009, rto = 2.000
+recv  325
+updated rto
+send  326: rtt = 0.260, srtt = 0.238, rttvar = 0.013, rto = 2.000
+recv  326
+updated rto
+send  327: rtt = 0.309, srtt = 0.247, rttvar = 0.028, rto = 2.000
+recv  327
+updated rto
+send  328: rtt = 0.220, srtt = 0.243, rttvar = 0.028, rto = 2.000
+recv  328
+updated rto
+send  329: rtt = 0.229, srtt = 0.242, rttvar = 0.024, rto = 2.000
+recv  329
+updated rto
+send  330: rtt = 0.230, srtt = 0.240, rttvar = 0.021, rto = 2.000
+recv  330
+updated rto
+send  331: rtt = 0.240, srtt = 0.240, rttvar = 0.016, rto = 2.000
+recv  331
+updated rto
+send  332: rtt = 0.276, srtt = 0.245, rttvar = 0.021, rto = 2.000
+recv  332
+updated rto
+send  333: rtt = 0.213, srtt = 0.241, rttvar = 0.024, rto = 2.000
+recv  333
+updated rto
+send  334: rtt = 0.251, srtt = 0.242, rttvar = 0.020, rto = 2.000
+recv  334
+updated rto
+send  335: rtt = 0.238, srtt = 0.241, rttvar = 0.016, rto = 2.000
+recv  335
+updated rto
+send  336: rtt = 0.240, srtt = 0.241, rttvar = 0.012, rto = 2.000
+recv  336
+updated rto
+send  337: rtt = 0.230, srtt = 0.240, rttvar = 0.012, rto = 2.000
+recv  337
+updated rto
+send  338: rtt = 0.229, srtt = 0.238, rttvar = 0.012, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  338: rtt = 0.229, srtt = 0.238, rttvar = 0.012, rto = 4.000
+recv  338
+updated rto
+send  339: rtt = 0.250, srtt = 0.240, rttvar = 0.012, rto = 2.000
+recv  339
+updated rto
+send  340: rtt = 0.230, srtt = 0.239, rttvar = 0.011, rto = 2.000
+recv  340
+updated rto
+send  341: rtt = 0.230, srtt = 0.238, rttvar = 0.011, rto = 2.000
+recv  341
+updated rto
+send  342: rtt = 0.290, srtt = 0.244, rttvar = 0.021, rto = 2.000
+recv  342
+updated rto
+send  343: rtt = 0.240, srtt = 0.244, rttvar = 0.017, rto = 2.000
+recv  343
+updated rto
+send  344: rtt = 0.260, srtt = 0.246, rttvar = 0.017, rto = 2.000
+recv  344
+updated rto
+send  345: rtt = 0.230, srtt = 0.244, rttvar = 0.016, rto = 2.000
+recv  345
+updated rto
+send  346: rtt = 0.268, srtt = 0.247, rttvar = 0.018, rto = 2.000
+recv  346
+updated rto
+send  347: rtt = 0.303, srtt = 0.254, rttvar = 0.028, rto = 2.000
+recv  347
+updated rto
+send  348: rtt = 0.237, srtt = 0.252, rttvar = 0.025, rto = 2.000
+recv  348
+updated rto
+send  349: rtt = 0.219, srtt = 0.248, rttvar = 0.027, rto = 2.000
+recv  349
+updated rto
+send  350: rtt = 0.229, srtt = 0.245, rttvar = 0.025, rto = 2.000
+recv  350
+updated rto
+send  351: rtt = 0.250, srtt = 0.246, rttvar = 0.020, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  351: rtt = 0.250, srtt = 0.246, rttvar = 0.020, rto = 4.000
+recv  351
+updated rto
+send  352: rtt = 0.240, srtt = 0.245, rttvar = 0.016, rto = 2.000
+recv  352
+updated rto
+send  353: rtt = 0.230, srtt = 0.243, rttvar = 0.016, rto = 2.000
+recv  353
+updated rto
+send  354: rtt = 0.260, srtt = 0.245, rttvar = 0.016, rto = 2.000
+recv  354
+updated rto
+send  355: rtt = 0.219, srtt = 0.242, rttvar = 0.019, rto = 2.000
+recv  355
+updated rto
+send  356: rtt = 0.240, srtt = 0.242, rttvar = 0.015, rto = 2.000
+recv  356
+updated rto
+send  357: rtt = 0.230, srtt = 0.240, rttvar = 0.014, rto = 2.000
+recv  357
+updated rto
+send  358: rtt = 0.260, srtt = 0.243, rttvar = 0.015, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  358: rtt = 0.260, srtt = 0.243, rttvar = 0.015, rto = 4.000
+recv  358
+updated rto
+send  359: rtt = 0.240, srtt = 0.242, rttvar = 0.012, rto = 2.000
+recv  359
+updated rto
+send  360: rtt = 0.239, srtt = 0.242, rttvar = 0.010, rto = 2.000
+recv  360
+updated rto
+send  361: rtt = 0.240, srtt = 0.242, rttvar = 0.008, rto = 2.000
+recv  361
+updated rto
+send  362: rtt = 0.250, srtt = 0.243, rttvar = 0.008, rto = 2.000
+recv  362
+updated rto
+send  363: rtt = 0.250, srtt = 0.244, rttvar = 0.008, rto = 2.000
+recv  363
+updated rto
+send  364: rtt = 0.299, srtt = 0.251, rttvar = 0.020, rto = 2.000
+recv  364
+updated rto
+send  365: rtt = 0.259, srtt = 0.252, rttvar = 0.017, rto = 2.000
+recv  365
+updated rto
+send  366: rtt = 0.240, srtt = 0.250, rttvar = 0.016, rto = 2.000
+recv  366
+updated rto
+send  367: rtt = 0.260, srtt = 0.251, rttvar = 0.014, rto = 2.000
+recv  367
+updated rto
+send  368: rtt = 0.250, srtt = 0.251, rttvar = 0.011, rto = 2.000
+recv  368
+updated rto
+send  369: rtt = 0.239, srtt = 0.250, rttvar = 0.011, rto = 2.000
+recv  369
+updated rto
+send  370: rtt = 0.249, srtt = 0.250, rttvar = 0.009, rto = 2.000
+recv  370
+updated rto
+send  371: rtt = 0.264, srtt = 0.251, rttvar = 0.010, rto = 2.000
+recv  371
+updated rto
+send  372: rtt = 0.465, srtt = 0.278, rttvar = 0.061, rto = 2.000
+recv  372
+updated rto
+send  373: rtt = 0.259, srtt = 0.276, rttvar = 0.050, rto = 2.000
+recv  373
+updated rto
+send  374: rtt = 0.230, srtt = 0.270, rttvar = 0.049, rto = 2.000
+recv  374
+updated rto
+send  375: rtt = 0.240, srtt = 0.266, rttvar = 0.044, rto = 2.000
+recv  375
+updated rto
+send  376: rtt = 0.250, srtt = 0.264, rttvar = 0.037, rto = 2.000
+recv  376
+updated rto
+send  377: rtt = 0.260, srtt = 0.264, rttvar = 0.029, rto = 2.000
+recv  377
+updated rto
+send  378: rtt = 0.239, srtt = 0.261, rttvar = 0.028, rto = 2.000
+recv  378
+updated rto
+send  379: rtt = 0.229, srtt = 0.257, rttvar = 0.029, rto = 2.000
+recv  379
+updated rto
+send  380: rtt = 0.240, srtt = 0.255, rttvar = 0.026, rto = 2.000
+recv  380
+updated rto
+send  381: rtt = 0.230, srtt = 0.252, rttvar = 0.026, rto = 2.000
+recv  381
+updated rto
+send  382: rtt = 0.250, srtt = 0.251, rttvar = 0.020, rto = 2.000
+recv  382
+updated rto
+send  383: rtt = 0.280, srtt = 0.255, rttvar = 0.022, rto = 2.000
+recv  383
+updated rto
+send  384: rtt = 0.240, srtt = 0.253, rttvar = 0.020, rto = 2.000
+recv  384
+updated rto
+send  385: rtt = 0.250, srtt = 0.253, rttvar = 0.016, rto = 2.000
+recv  385
+updated rto
+send  386: rtt = 0.220, srtt = 0.249, rttvar = 0.020, rto = 2.000
+recv  386
+updated rto
+send  387: rtt = 0.239, srtt = 0.247, rttvar = 0.017, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  387: rtt = 0.239, srtt = 0.247, rttvar = 0.017, rto = 4.000
+recv  387
+updated rto
+send  388: rtt = 0.220, srtt = 0.244, rttvar = 0.020, rto = 2.000
+recv  388
+updated rto
+send  389: rtt = 0.230, srtt = 0.242, rttvar = 0.018, rto = 2.000
+recv  389
+updated rto
+send  390: rtt = 0.220, srtt = 0.239, rttvar = 0.019, rto = 2.000
+recv  390
+updated rto
+send  391: rtt = 0.240, srtt = 0.240, rttvar = 0.015, rto = 2.000
+recv  391
+updated rto
+send  392: rtt = 0.249, srtt = 0.241, rttvar = 0.013, rto = 2.000
+recv  392
+updated rto
+send  393: rtt = 0.260, srtt = 0.243, rttvar = 0.015, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  393: rtt = 0.260, srtt = 0.243, rttvar = 0.015, rto = 4.000
+recv  393
+updated rto
+send  394: rtt = 0.270, srtt = 0.246, rttvar = 0.018, rto = 2.000
+recv  394
+updated rto
+send  395: rtt = 0.250, srtt = 0.247, rttvar = 0.014, rto = 2.000
+recv  395
+updated rto
+send  396: rtt = 0.250, srtt = 0.247, rttvar = 0.011, rto = 2.000
+recv  396
+updated rto
+send  397: rtt = 0.230, srtt = 0.245, rttvar = 0.013, rto = 2.000
+recv  397
+updated rto
+send  398: rtt = 0.259, srtt = 0.247, rttvar = 0.013, rto = 2.000
+recv  398
+updated rto
+send  399: rtt = 0.249, srtt = 0.247, rttvar = 0.010, rto = 2.000
+recv  399
+updated rto
+send  400: rtt = 0.240, srtt = 0.246, rttvar = 0.010, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  400: rtt = 0.240, srtt = 0.246, rttvar = 0.010, rto = 4.000
+recv  400
+updated rto
+send  401: rtt = 0.250, srtt = 0.247, rttvar = 0.008, rto = 2.000
+recv  401
+updated rto
+send  402: rtt = 0.250, srtt = 0.247, rttvar = 0.007, rto = 2.000
+recv  402
+updated rto
+send  403: rtt = 0.230, srtt = 0.245, rttvar = 0.009, rto = 2.000
+recv  403
+updated rto
+send  404: rtt = 0.240, srtt = 0.244, rttvar = 0.008, rto = 2.000
+recv  404
+updated rto
+send  405: rtt = 0.240, srtt = 0.244, rttvar = 0.007, rto = 2.000
+recv  405
+updated rto
+send  406: rtt = 0.260, srtt = 0.246, rttvar = 0.010, rto = 2.000
+recv  406
+updated rto
+send  407: rtt = 0.239, srtt = 0.245, rttvar = 0.009, rto = 2.000
+recv  407
+updated rto
+send  408: rtt = 0.229, srtt = 0.243, rttvar = 0.011, rto = 2.000
+recv  408
+updated rto
+send  409: rtt = 0.240, srtt = 0.243, rttvar = 0.009, rto = 2.000
+recv  409
+updated rto
+send  410: rtt = 0.250, srtt = 0.244, rttvar = 0.008, rto = 2.000
+recv  410
+updated rto
+send  411: rtt = 0.249, srtt = 0.244, rttvar = 0.008, rto = 2.000
+recv  411
+updated rto
+send  412: rtt = 0.270, srtt = 0.247, rttvar = 0.012, rto = 2.000
+recv  412
+updated rto
+send  413: rtt = 0.209, srtt = 0.243, rttvar = 0.019, rto = 2.000
+recv  413
+updated rto
+send  414: rtt = 0.230, srtt = 0.241, rttvar = 0.017, rto = 2.000
+recv  414
+updated rto
+send  415: rtt = 0.229, srtt = 0.240, rttvar = 0.016, rto = 2.000
+recv  415
+updated rto
+send  416: rtt = 0.230, srtt = 0.238, rttvar = 0.014, rto = 2.000
+recv  416
+updated rto
+send  417: rtt = 0.267, srtt = 0.242, rttvar = 0.018, rto = 2.000
+recv  417
+updated rto
+send  418: rtt = 0.262, srtt = 0.244, rttvar = 0.018, rto = 2.000
+recv  418
+updated rto
+send  419: rtt = 0.240, srtt = 0.244, rttvar = 0.015, rto = 2.000
+recv  419
+updated rto
+send  420: rtt = 0.239, srtt = 0.243, rttvar = 0.012, rto = 2.000
+recv  420
+updated rto
+send  421: rtt = 0.242, srtt = 0.243, rttvar = 0.010, rto = 2.000
+recv  421
+updated rto
+send  422: rtt = 0.237, srtt = 0.242, rttvar = 0.009, rto = 2.000
+recv  422
+updated rto
+send  423: rtt = 0.240, srtt = 0.242, rttvar = 0.007, rto = 2.000
+recv  423
+updated rto
+send  424: rtt = 0.250, srtt = 0.243, rttvar = 0.007, rto = 2.000
+recv  424
+updated rto
+send  425: rtt = 0.269, srtt = 0.246, rttvar = 0.012, rto = 2.000
+recv  425
+updated rto
+send  426: rtt = 0.250, srtt = 0.247, rttvar = 0.010, rto = 2.000
+recv  426
+updated rto
+send  427: rtt = 0.230, srtt = 0.245, rttvar = 0.012, rto = 2.000
+recv  427
+updated rto
+send  428: rtt = 0.269, srtt = 0.248, rttvar = 0.015, rto = 2.000
+recv  428
+updated rto
+send  429: rtt = 0.259, srtt = 0.249, rttvar = 0.014, rto = 2.000
+recv  429
+updated rto
+send  430: rtt = 0.270, srtt = 0.252, rttvar = 0.016, rto = 2.000
+recv  430
+updated rto
+send  431: rtt = 0.249, srtt = 0.251, rttvar = 0.012, rto = 2.000
+recv  431
+updated rto
+send  432: rtt = 0.220, srtt = 0.247, rttvar = 0.017, rto = 2.000
+recv  432
+updated rto
+send  433: rtt = 0.260, srtt = 0.249, rttvar = 0.016, rto = 2.000
+recv  433
+updated rto
+send  434: rtt = 0.250, srtt = 0.249, rttvar = 0.012, rto = 2.000
+recv  434
+updated rto
+send  435: rtt = 0.220, srtt = 0.246, rttvar = 0.016, rto = 2.000
+recv  435
+updated rto
+send  436: rtt = 0.230, srtt = 0.244, rttvar = 0.016, rto = 2.000
+recv  436
+updated rto
+send  437: rtt = 0.240, srtt = 0.243, rttvar = 0.013, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  437: rtt = 0.240, srtt = 0.243, rttvar = 0.013, rto = 4.000
+recv  437
+updated rto
+send  438: rtt = 0.250, srtt = 0.244, rttvar = 0.012, rto = 2.000
+recv  438
+updated rto
+send  439: rtt = 0.260, srtt = 0.246, rttvar = 0.013, rto = 2.000
+recv  439
+updated rto
+send  440: rtt = 0.220, srtt = 0.243, rttvar = 0.016, rto = 2.000
+recv  440
+updated rto
+send  441: rtt = 0.210, srtt = 0.239, rttvar = 0.020, rto = 2.000
+recv  441
+updated rto
+send  442: rtt = 0.240, srtt = 0.239, rttvar = 0.015, rto = 2.000
+recv  442
+updated rto
+send  443: rtt = 0.250, srtt = 0.240, rttvar = 0.014, rto = 2.000
+recv  443
+updated rto
+send  444: rtt = 0.241, srtt = 0.240, rttvar = 0.011, rto = 2.000
+recv  444
+updated rto
+send  445: rtt = 0.228, srtt = 0.239, rttvar = 0.011, rto = 2.000
+recv  445
+updated rto
+send  446: rtt = 0.240, srtt = 0.239, rttvar = 0.009, rto = 2.000
+recv  446
+updated rto
+send  447: rtt = 0.230, srtt = 0.238, rttvar = 0.009, rto = 2.000
+recv  447
+updated rto
+send  448: rtt = 0.240, srtt = 0.238, rttvar = 0.007, rto = 2.000
+recv  448
+updated rto
+send  449: rtt = 0.220, srtt = 0.236, rttvar = 0.010, rto = 2.000
+recv  449
+updated rto
+send  450: rtt = 0.260, srtt = 0.239, rttvar = 0.013, rto = 2.000
+recv  450
+updated rto
+send  451: rtt = 0.250, srtt = 0.240, rttvar = 0.013, rto = 2.000
+recv  451
+updated rto
+send  452: rtt = 0.240, srtt = 0.240, rttvar = 0.010, rto = 2.000
+recv  452
+updated rto
+send  453: rtt = 0.589, srtt = 0.284, rttvar = 0.094, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  453: rtt = 0.589, srtt = 0.284, rttvar = 0.094, rto = 4.000
+recv  453
+updated rto
+send  454: rtt = 0.257, srtt = 0.280, rttvar = 0.078, rto = 2.000
+recv  454
+updated rto
+send  455: rtt = 0.230, srtt = 0.274, rttvar = 0.071, rto = 2.000
+recv  455
+updated rto
+send  456: rtt = 0.230, srtt = 0.269, rttvar = 0.064, rto = 2.000
+recv  456
+updated rto
+send  457: rtt = 0.239, srtt = 0.265, rttvar = 0.056, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  457: rtt = 0.239, srtt = 0.265, rttvar = 0.056, rto = 4.000
+recv  457
+updated rto
+send  458: rtt = 0.260, srtt = 0.264, rttvar = 0.043, rto = 2.000
+recv  458
+updated rto
+send  459: rtt = 0.240, srtt = 0.261, rttvar = 0.038, rto = 2.000
+recv  459
+updated rto
+send  460: rtt = 0.260, srtt = 0.261, rttvar = 0.029, rto = 2.000
+recv  460
+updated rto
+send  461: rtt = 0.280, srtt = 0.263, rttvar = 0.026, rto = 2.000
+recv  461
+updated rto
+send  462: rtt = 0.249, srtt = 0.262, rttvar = 0.023, rto = 2.000
+recv  462
+updated rto
+send  463: rtt = 0.240, srtt = 0.259, rttvar = 0.023, rto = 2.000
+recv  463
+updated rto
+send  464: rtt = 0.250, srtt = 0.258, rttvar = 0.020, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  464: rtt = 0.250, srtt = 0.258, rttvar = 0.020, rto = 4.000
+dgsendrecv: timeout, retransmitting
+send  464: rtt = 0.250, srtt = 0.258, rttvar = 0.020, rto = 8.000
+recv  464
+updated rto
+send  465: rtt = 0.260, srtt = 0.258, rttvar = 0.015, rto = 2.000
+recv  465
+updated rto
+send  466: rtt = 0.230, srtt = 0.255, rttvar = 0.018, rto = 2.000
+recv  466
+updated rto
+send  467: rtt = 0.239, srtt = 0.253, rttvar = 0.018, rto = 2.000
+recv  467
+updated rto
+send  468: rtt = 0.280, srtt = 0.256, rttvar = 0.020, rto = 2.000
+recv  468
+updated rto
+send  469: rtt = 0.240, srtt = 0.254, rttvar = 0.019, rto = 2.000
+recv  469
+updated rto
+send  470: rtt = 0.230, srtt = 0.251, rttvar = 0.020, rto = 2.000
+recv  470
+updated rto
+send  471: rtt = 0.250, srtt = 0.251, rttvar = 0.016, rto = 2.000
+recv  471
+updated rto
+send  472: rtt = 0.280, srtt = 0.255, rttvar = 0.019, rto = 2.000
+recv  472
+updated rto
+send  473: rtt = 0.250, srtt = 0.254, rttvar = 0.015, rto = 2.000
+recv  473
+updated rto
+send  474: rtt = 0.270, srtt = 0.256, rttvar = 0.015, rto = 2.000
+recv  474
+updated rto
+send  475: rtt = 0.269, srtt = 0.258, rttvar = 0.015, rto = 2.000
+recv  475
+updated rto
+send  476: rtt = 0.260, srtt = 0.258, rttvar = 0.012, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  476: rtt = 0.260, srtt = 0.258, rttvar = 0.012, rto = 4.000
+recv  476
+updated rto
+send  477: rtt = 0.230, srtt = 0.254, rttvar = 0.016, rto = 2.000
+recv  477
+updated rto
+send  478: rtt = 0.260, srtt = 0.255, rttvar = 0.013, rto = 2.000
+recv  478
+updated rto
+send  479: rtt = 0.240, srtt = 0.253, rttvar = 0.014, rto = 2.000
+recv  479
+updated rto
+send  480: rtt = 0.289, srtt = 0.258, rttvar = 0.019, rto = 2.000
+recv  480
+updated rto
+send  481: rtt = 0.250, srtt = 0.257, rttvar = 0.016, rto = 2.000
+recv  481
+updated rto
+send  482: rtt = 0.290, srtt = 0.261, rttvar = 0.021, rto = 2.000
+dgsendrecv: timeout, retransmitting
+send  482: rtt = 0.290, srtt = 0.261, rttvar = 0.021, rto = 4.000
+recv  482
+updated rto
+send  483: rtt = 0.270, srtt = 0.262, rttvar = 0.018, rto = 2.000
+recv  483
+updated rto
+send  484: rtt = 0.248, srtt = 0.260, rttvar = 0.017, rto = 2.000
+recv  484
+updated rto
+send  485: rtt = 0.291, srtt = 0.264, rttvar = 0.020, rto = 2.000
+recv  485
+updated rto
+send  486: rtt = 0.250, srtt = 0.262, rttvar = 0.019, rto = 2.000
+recv  486
+updated rto
+send  487: rtt = 0.250, srtt = 0.261, rttvar = 0.017, rto = 2.000
+recv  487
+updated rto
+send  488: rtt = 0.230, srtt = 0.257, rttvar = 0.021, rto = 2.000
+recv  488
+updated rto
+send  489: rtt = 0.240, srtt = 0.255, rttvar = 0.020, rto = 2.000
+recv  489
+updated rto
+send  490: rtt = 0.310, srtt = 0.262, rttvar = 0.029, rto = 2.000
+recv  490
+updated rto
+send  491: rtt = 0.220, srtt = 0.257, rttvar = 0.032, rto = 2.000
+recv  491
+updated rto
+send  492: rtt = 0.250, srtt = 0.256, rttvar = 0.026, rto = 2.000
+recv  492
+updated rto
+send  493: rtt = 0.220, srtt = 0.251, rttvar = 0.028, rto = 2.000
+recv  493
+updated rto
+send  494: rtt = 0.260, srtt = 0.252, rttvar = 0.023, rto = 2.000
+recv  494
+updated rto
+send  495: rtt = 0.270, srtt = 0.255, rttvar = 0.022, rto = 2.000
+recv  495
+updated rto
+send  496: rtt = 0.240, srtt = 0.253, rttvar = 0.020, rto = 2.000
+recv  496
+updated rto
+send  497: rtt = 0.239, srtt = 0.251, rttvar = 0.018, rto = 2.000
+recv  497
+updated rto
+send  498: rtt = 0.239, srtt = 0.250, rttvar = 0.017, rto = 2.000
+recv  498
+updated rto
+send  499: rtt = 0.210, srtt = 0.245, rttvar = 0.023, rto = 2.000
+recv  499
+updated rto
+send  500: rtt = 0.278, srtt = 0.249, rttvar = 0.025, rto = 2.000
+recv  500
+updated rto
diff --git a/rtt/rtt.vals.kumba.1 b/rtt/rtt.vals.kumba.1
new file mode 100644 (file)
index 0000000..6f2bd4e
--- /dev/null
@@ -0,0 +1,508 @@
+1 0.000
+2 0.366
+3 0.309
+4 0.298
+5 0.360
+6 0.360
+7 0.320
+8 0.340
+9 0.330
+10 0.350
+11 0.349
+12 0.380
+13 0.349
+14 0.340
+15 0.280
+16 0.330
+17 0.340
+18 0.340
+19 0.349
+20 0.310
+21 0.350
+21 0.350
+22 0.340
+23 0.350
+24 0.319
+25 0.360
+26 0.290
+27 0.310
+28 0.340
+29 0.371
+30 0.368
+31 0.350
+32 0.364
+33 0.335
+33 0.335
+34 0.330
+35 0.290
+36 0.390
+37 0.355
+38 0.334
+39 0.320
+40 0.344
+41 0.345
+42 0.349
+43 0.305
+44 0.284
+45 0.320
+46 0.320
+47 0.340
+48 0.309
+49 0.310
+50 0.320
+51 0.320
+52 0.300
+53 0.320
+54 0.350
+55 0.349
+56 0.339
+57 0.350
+58 0.319
+59 0.309
+60 0.310
+61 0.320
+62 0.300
+63 0.309
+64 0.290
+65 0.320
+66 0.280
+67 0.339
+68 0.330
+69 0.320
+70 0.280
+71 0.319
+72 0.339
+73 0.309
+74 0.340
+75 0.330
+76 0.280
+77 0.320
+78 0.280
+79 0.330
+80 0.349
+81 0.320
+82 0.320
+83 0.329
+84 0.320
+85 0.329
+86 0.330
+87 0.339
+88 0.360
+89 0.320
+90 0.319
+91 0.330
+92 0.304
+93 0.316
+94 0.319
+95 0.360
+96 0.316
+97 0.314
+98 0.330
+99 0.330
+100 0.360
+101 0.330
+102 0.350
+103 0.320
+103 0.320
+104 0.340
+105 0.340
+106 0.320
+107 0.340
+108 0.340
+109 0.340
+110 0.369
+111 0.350
+112 0.369
+113 0.339
+114 0.349
+115 0.319
+116 0.340
+117 0.319
+118 0.340
+119 0.380
+120 0.340
+121 0.320
+122 0.340
+123 0.360
+124 0.359
+125 0.330
+126 0.329
+127 0.340
+128 0.360
+129 0.320
+130 0.340
+131 0.350
+132 0.340
+133 0.370
+134 0.339
+135 0.330
+136 0.340
+137 0.300
+138 0.340
+139 0.340
+140 0.380
+141 0.450
+142 0.370
+143 0.309
+144 0.290
+145 0.390
+146 0.329
+147 0.330
+148 0.320
+149 0.340
+150 0.359
+151 0.350
+152 0.349
+153 0.400
+154 0.350
+155 0.370
+156 0.359
+157 0.349
+158 0.360
+159 0.319
+160 0.320
+161 0.330
+162 0.340
+163 0.350
+164 0.350
+165 0.339
+166 0.339
+167 0.330
+168 0.310
+169 0.310
+170 0.320
+171 0.339
+172 0.320
+173 0.319
+174 0.320
+175 0.319
+176 0.309
+177 0.340
+178 0.334
+179 0.315
+180 0.309
+181 0.309
+182 0.330
+183 0.370
+184 0.320
+185 0.380
+186 0.350
+187 0.309
+188 0.330
+189 0.320
+189 0.320
+190 0.329
+191 0.310
+192 0.319
+193 0.310
+194 0.300
+195 0.309
+196 0.319
+197 0.310
+198 0.309
+199 0.330
+200 0.299
+201 0.310
+202 0.354
+203 0.312
+204 0.303
+205 0.329
+206 0.319
+207 0.339
+208 0.310
+209 0.321
+210 0.308
+211 0.350
+212 0.359
+213 0.310
+214 0.329
+215 0.310
+216 0.772
+217 0.317
+218 0.379
+219 0.310
+220 0.304
+221 0.315
+222 0.340
+223 0.329
+224 0.349
+225 0.350
+226 0.360
+227 0.380
+228 0.320
+229 0.319
+230 0.370
+231 0.358
+232 0.340
+233 0.360
+234 0.289
+235 0.350
+236 0.310
+237 0.319
+238 0.330
+239 0.308
+240 0.320
+241 0.290
+242 0.360
+243 0.330
+244 0.339
+245 0.350
+246 0.330
+247 0.309
+248 0.329
+249 0.360
+250 0.350
+251 0.340
+252 0.410
+253 0.339
+254 0.335
+255 0.335
+256 0.319
+257 0.350
+258 0.310
+259 0.320
+260 0.319
+261 0.300
+262 0.389
+263 1.259
+264 0.819
+265 0.809
+266 0.809
+267 0.819
+267 0.819
+268 0.748
+269 0.819
+270 0.819
+271 0.819
+272 0.799
+273 1.059
+274 0.370
+275 0.370
+276 0.380
+277 0.340
+278 0.400
+279 0.350
+280 0.320
+281 0.390
+282 0.329
+283 0.280
+284 0.330
+285 0.310
+286 0.370
+287 0.379
+288 0.329
+289 0.320
+290 0.410
+291 0.340
+292 0.360
+293 0.349
+294 0.360
+295 0.360
+296 0.329
+297 0.360
+298 0.340
+299 0.359
+300 0.369
+301 0.330
+302 0.320
+303 0.320
+304 0.313
+305 0.337
+306 0.320
+307 0.319
+308 0.680
+309 0.380
+310 0.319
+311 0.330
+312 0.330
+313 0.310
+314 0.300
+315 0.340
+316 0.350
+317 0.350
+318 0.340
+319 0.309
+320 0.343
+321 0.326
+322 0.319
+323 1.178
+324 0.320
+325 0.309
+326 0.330
+327 0.300
+328 0.300
+329 0.310
+330 0.290
+331 0.310
+332 0.300
+333 0.300
+334 0.340
+335 0.339
+336 0.310
+337 0.320
+338 0.330
+339 0.320
+340 0.315
+340 0.315
+341 0.338
+342 0.320
+343 0.309
+344 0.320
+345 0.349
+346 0.339
+347 0.300
+348 0.300
+349 0.289
+350 0.329
+351 0.340
+352 0.329
+353 0.320
+354 0.410
+355 0.300
+356 0.389
+357 0.299
+358 1.280
+359 0.809
+360 0.818
+361 0.819
+362 0.829
+363 0.819
+364 0.809
+365 0.819
+366 0.999
+367 0.999
+368 1.479
+369 1.010
+370 0.998
+371 0.999
+372 0.999
+373 0.999
+374 0.989
+375 0.989
+376 1.009
+377 0.999
+378 1.009
+379 0.939
+380 0.809
+381 0.821
+382 0.827
+382 0.827
+383 0.809
+384 0.839
+385 0.819
+386 0.809
+387 0.819
+388 0.819
+389 0.809
+390 0.811
+391 0.827
+392 0.813
+393 1.205
+394 0.829
+395 0.819
+396 0.819
+397 0.819
+398 0.819
+399 0.819
+400 0.819
+401 0.829
+402 0.819
+403 0.809
+404 0.819
+405 0.809
+406 0.819
+407 0.819
+408 0.799
+409 0.819
+410 0.819
+411 0.829
+412 0.820
+413 0.809
+414 0.819
+415 1.209
+416 0.809
+417 0.824
+418 0.814
+419 0.809
+420 0.819
+421 0.819
+422 0.809
+423 0.819
+424 0.821
+425 0.808
+426 0.819
+427 0.819
+428 0.819
+429 0.819
+430 0.819
+431 0.819
+432 0.609
+433 0.309
+434 0.330
+435 0.300
+436 0.319
+437 0.310
+438 0.320
+439 0.350
+440 0.290
+441 0.290
+442 0.300
+443 0.360
+444 0.310
+445 0.360
+446 0.319
+447 0.320
+448 0.330
+449 0.329
+450 0.370
+451 0.340
+452 0.340
+453 0.719
+454 0.339
+455 0.320
+456 0.310
+457 0.320
+458 0.330
+459 0.313
+460 0.377
+461 0.440
+462 0.340
+463 0.330
+464 0.360
+465 0.380
+466 0.320
+467 0.309
+468 0.360
+469 0.330
+470 0.290
+471 0.329
+472 0.319
+473 0.320
+474 0.349
+475 0.330
+476 0.360
+477 0.310
+478 0.320
+479 0.320
+480 0.410
+481 0.340
+482 0.409
+483 0.330
+484 0.280
+485 0.320
+485 0.320
+486 0.339
+487 0.360
+488 0.300
+489 0.320
+490 0.410
+491 0.320
+492 0.320
+493 0.319
+494 0.330
+495 0.320
+496 0.314
+497 0.325
+498 0.330
+499 0.290
+500 0.340
diff --git a/rtt/rtt.vals.vangogh.1 b/rtt/rtt.vals.vangogh.1
new file mode 100644 (file)
index 0000000..bdb0402
--- /dev/null
@@ -0,0 +1,516 @@
+1 0.000
+2 0.316
+3 0.218
+4 0.225
+5 0.264
+6 0.228
+7 0.221
+8 0.228
+9 0.200
+10 0.240
+11 0.210
+12 0.249
+13 0.240
+14 0.260
+15 0.201
+16 0.248
+17 0.261
+18 0.248
+19 0.260
+20 0.210
+21 0.240
+22 0.240
+23 0.249
+24 0.230
+25 0.240
+25 0.240
+26 0.190
+27 0.220
+28 0.259
+29 0.243
+30 0.257
+31 0.260
+32 0.240
+33 0.240
+34 0.249
+35 0.210
+36 0.239
+37 0.240
+38 0.260
+38 0.260
+39 0.220
+40 0.230
+41 0.250
+42 0.240
+43 0.240
+44 0.210
+45 0.240
+46 0.239
+46 0.239
+47 0.240
+48 0.250
+49 0.239
+50 0.220
+51 0.229
+52 0.210
+53 0.259
+54 0.240
+55 0.260
+56 0.249
+57 0.249
+58 0.240
+59 0.209
+60 0.190
+61 0.230
+62 0.229
+63 0.229
+64 0.210
+65 0.230
+66 0.200
+67 0.240
+68 0.260
+69 0.240
+69 0.240
+70 0.200
+71 0.250
+72 0.220
+73 0.239
+74 0.229
+75 0.210
+76 0.199
+77 0.250
+78 0.199
+79 0.249
+80 0.239
+81 0.230
+82 0.259
+83 0.240
+84 0.240
+85 0.250
+86 0.230
+87 0.259
+88 0.220
+89 0.239
+90 0.250
+91 0.230
+92 0.219
+93 0.220
+94 0.229
+95 0.239
+96 0.250
+97 0.250
+98 0.220
+99 0.230
+100 0.249
+101 0.240
+102 0.239
+103 0.249
+103 0.249
+104 0.250
+105 0.260
+106 0.250
+107 0.241
+108 0.248
+109 0.249
+110 0.240
+111 0.259
+112 0.310
+113 0.250
+114 0.250
+115 0.230
+116 0.220
+117 0.230
+118 0.240
+119 0.240
+120 0.250
+121 0.250
+122 0.220
+123 0.219
+124 0.219
+125 0.240
+126 0.220
+127 0.230
+128 0.229
+129 0.239
+130 0.230
+131 0.259
+132 0.230
+133 0.249
+134 0.250
+135 0.240
+136 0.248
+137 0.200
+138 0.260
+139 0.230
+140 0.230
+141 0.230
+142 0.349
+143 0.230
+144 0.230
+145 0.250
+146 0.239
+147 0.220
+148 0.240
+149 0.240
+150 0.249
+151 0.219
+152 0.220
+153 0.229
+154 0.260
+155 0.259
+156 0.260
+157 0.239
+158 0.249
+159 0.229
+160 0.220
+161 0.240
+162 0.230
+163 0.230
+164 0.239
+165 0.269
+166 0.220
+167 0.219
+168 0.220
+169 0.220
+170 0.240
+171 0.239
+172 0.240
+173 0.240
+174 0.240
+175 0.229
+176 0.199
+177 0.249
+178 0.239
+179 0.220
+180 0.240
+181 0.219
+182 0.240
+183 0.240
+184 0.230
+185 0.240
+186 0.230
+187 0.240
+187 0.240
+188 0.229
+189 0.250
+190 0.248
+191 0.230
+191 0.230
+192 0.230
+193 0.230
+194 0.200
+195 0.210
+196 0.200
+197 0.209
+198 0.200
+199 0.231
+200 0.247
+201 0.240
+202 0.220
+203 0.200
+204 0.210
+205 0.200
+206 0.230
+207 0.250
+208 0.239
+209 0.230
+210 0.249
+211 0.230
+212 0.240
+213 0.240
+214 0.218
+215 0.229
+216 0.230
+217 0.250
+218 0.229
+219 0.229
+220 0.220
+221 0.220
+222 0.240
+223 0.240
+224 0.249
+225 0.239
+226 0.240
+227 0.279
+228 0.229
+229 0.229
+230 0.239
+231 0.239
+232 0.250
+233 0.249
+234 0.239
+235 0.240
+236 0.230
+237 0.240
+238 0.219
+239 0.199
+240 0.220
+240 0.220
+240 0.220
+241 0.210
+242 0.250
+243 0.240
+244 0.242
+245 0.237
+246 0.250
+247 0.221
+248 0.229
+248 0.229
+249 0.270
+250 0.260
+251 0.240
+252 0.229
+253 0.230
+254 0.240
+255 0.229
+256 0.230
+257 0.269
+258 0.219
+259 0.239
+260 0.229
+261 0.219
+262 0.260
+263 0.260
+264 0.240
+265 0.220
+266 0.250
+267 0.250
+268 0.230
+269 0.249
+270 0.250
+271 0.279
+272 0.220
+273 0.230
+274 0.229
+275 0.270
+276 0.260
+277 0.220
+277 0.220
+278 0.250
+279 0.240
+280 0.249
+281 0.211
+282 0.240
+283 0.210
+284 0.240
+285 0.199
+286 0.239
+287 0.230
+288 0.229
+289 0.250
+290 0.239
+291 0.230
+292 0.239
+293 0.240
+293 0.240
+294 0.220
+295 0.240
+296 0.219
+297 0.230
+298 0.240
+299 0.240
+300 0.259
+301 0.230
+302 0.230
+303 0.240
+304 0.250
+305 0.230
+306 0.230
+307 0.209
+308 0.232
+309 0.247
+310 0.250
+311 0.229
+312 0.230
+313 0.210
+314 0.249
+315 0.220
+316 0.249
+316 0.249
+317 0.230
+318 0.229
+319 0.229
+320 0.230
+321 0.250
+322 0.249
+323 0.230
+324 0.220
+325 0.229
+326 0.250
+327 0.220
+328 0.210
+329 0.229
+330 0.210
+331 0.220
+332 0.220
+333 0.220
+334 0.250
+335 0.250
+336 0.229
+337 0.239
+338 0.230
+339 0.230
+340 0.219
+341 0.240
+342 0.229
+343 0.220
+344 0.259
+345 0.230
+346 0.219
+347 0.219
+348 0.230
+349 0.240
+350 0.239
+351 0.250
+352 0.250
+353 0.220
+354 0.239
+355 0.230
+356 0.240
+357 0.230
+358 0.270
+359 0.240
+360 0.249
+361 0.240
+362 0.220
+363 0.239
+364 0.240
+365 0.259
+366 0.240
+367 0.239
+368 0.249
+369 0.240
+370 0.239
+371 0.229
+372 0.240
+373 0.259
+374 0.229
+375 0.230
+376 0.239
+377 0.259
+378 0.250
+379 0.250
+380 0.230
+381 0.239
+382 0.279
+383 0.259
+384 0.220
+385 0.249
+386 0.249
+387 0.220
+388 0.210
+389 0.230
+390 0.219
+390 0.219
+391 0.229
+392 0.229
+393 0.239
+394 0.240
+395 0.249
+396 0.250
+397 0.230
+398 0.260
+399 0.270
+400 0.240
+401 0.250
+402 0.259
+403 0.229
+404 0.249
+405 0.229
+406 0.250
+407 0.230
+408 0.230
+409 0.220
+410 0.229
+411 0.249
+412 0.249
+413 0.210
+414 0.220
+415 0.220
+416 0.219
+417 0.239
+418 0.260
+419 0.240
+420 0.229
+421 0.220
+422 0.229
+423 0.249
+424 0.260
+425 0.239
+426 0.240
+427 0.230
+428 0.279
+429 0.240
+430 0.249
+431 0.259
+432 0.250
+433 0.229
+434 0.240
+435 0.230
+436 0.249
+437 0.240
+438 0.240
+439 0.249
+440 0.220
+441 0.219
+442 0.239
+443 0.250
+444 0.240
+445 0.230
+445 0.230
+446 0.489
+447 0.230
+448 0.240
+449 0.250
+450 0.239
+451 0.260
+452 0.240
+453 0.599
+454 0.249
+455 0.220
+456 0.230
+457 0.220
+458 0.239
+459 0.230
+460 0.249
+461 0.240
+462 0.230
+463 0.230
+464 0.240
+465 0.249
+466 0.240
+467 0.229
+468 0.249
+469 0.249
+470 0.230
+471 0.250
+472 0.240
+473 0.250
+474 0.250
+474 0.250
+475 0.240
+476 0.250
+477 0.220
+478 0.250
+479 0.250
+480 0.240
+481 0.229
+482 0.279
+483 0.260
+484 0.209
+485 0.229
+486 0.230
+487 0.240
+488 0.220
+489 0.229
+490 0.309
+491 0.219
+492 0.240
+493 0.220
+494 0.239
+495 0.239
+496 0.239
+497 0.240
+498 0.240
+499 0.230
+500 0.250
diff --git a/rtt/udpcli01.c b/rtt/udpcli01.c
new file mode 100644 (file)
index 0000000..01beb88
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(7);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/rtt/unprtt.h b/rtt/unprtt.h
new file mode 100644 (file)
index 0000000..6d4fdce
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef        __unp_rtt_h
+#define        __unp_rtt_h
+
+#include       "unp.h"
+
+struct rtt_info {
+  float                rtt_rtt;        /* most recent measured RTT, seconds */
+  float                rtt_srtt;       /* smoothed RTT estimator, seconds */
+  float                rtt_rttvar;     /* smoothed mean deviation, seconds */
+  float                rtt_rto;        /* current RTO to use, seconds */
+  int          rtt_nrexmt;     /* #times retransmitted: 0, 1, 2, ... */
+  uint32_t     rtt_base;       /* #sec since 1/1/1970 at start */
+};
+
+#define        RTT_RXTMIN      2       /* min retransmit timeout value, seconds */
+#define        RTT_RXTMAX     60       /* max retransmit timeout value, seconds */
+#define        RTT_MAXNREXMT   3       /* max #times to retransmit */
+
+                               /* function prototypes */
+void    rtt_debug(struct rtt_info *);
+void    rtt_init(struct rtt_info *);
+void    rtt_newpack(struct rtt_info *);
+int             rtt_start(struct rtt_info *);
+void    rtt_stop(struct rtt_info *, uint32_t);
+int             rtt_timeout(struct rtt_info *);
+uint32_t rtt_ts(struct rtt_info *);
+
+extern int     rtt_d_flag;     /* can be set nonzero for addl info */
+
+#endif /* __unp_rtt_h */
diff --git a/sctp/Makefile b/sctp/Makefile
new file mode 100644 (file)
index 0000000..b6a2339
--- /dev/null
@@ -0,0 +1,56 @@
+include ../Make.defines
+
+PROGS =        sctpserv01 sctpclient01 sctpserv02 sctpserv03 sctpclient02 sctpserv04 \
+sctpserv05 sctpclient03 sctpserv06 sctpserv07 sctpclient04 sctpserv_fork
+
+LIBS+= -L/usr/local/v6/lib -lm -lsctp
+
+.c.lc:
+       ../../troff/fixcode.sh $< > $@
+.h.lh:
+       ../../troff/fixcode.sh $< > $@
+
+CFLAGS+= -g
+all:   ${PROGS}
+
+sctpserv01:    sctpserv01.o 
+               ${CC} ${CFLAGS} -o $@ sctpserv01.o ${LIBS}
+
+
+sctpclient01:   sctpclient01.o sctp_strcli.o sctp_strcliecho.o
+               ${CC} ${CFLAGS} -o $@ sctpclient01.o sctp_strcli.o sctp_strcliecho.o ${LIBS}
+
+
+sctpserv02:    sctpserv02.o 
+               ${CC} ${CFLAGS} -o $@ sctpserv02.o ${LIBS}
+
+sctpserv03:    sctpserv03.o 
+               ${CC} ${CFLAGS} -o $@ sctpserv03.o ${LIBS}
+
+sctpserv04:    sctpserv04.o 
+               ${CC} ${CFLAGS} -o $@ sctpserv04.o ${LIBS}
+
+sctpserv05:    sctpserv05.o sctp_pdapircv.o 
+               ${CC} ${CFLAGS} -o $@ sctpserv05.o sctp_pdapircv.o  ${LIBS}
+
+sctpserv06:    sctpserv06.o sctp_displayevents.o
+               ${CC} ${CFLAGS} -o $@ sctpserv06.o sctp_displayevents.o  ${LIBS}
+
+sctpclient02:  sctpclient02.o sctp_strcli.o sctp_strcliecho.o
+               ${CC} ${CFLAGS} -o $@ sctpclient02.o sctp_strcli.o sctp_strcliecho.o ${LIBS}
+
+sctpclient03:  sctpclient01.o sctp_strcli_un.o sctp_strcliecho.o
+               ${CC} ${CFLAGS} -o $@ sctpclient01.o sctp_strcli_un.o sctp_strcliecho.o ${LIBS}
+
+sctpserv07:    sctpserv07.o sctp_displayevents.o sctp_bindargs.o 
+               ${CC} ${CFLAGS} -o $@ sctpserv07.o sctp_displayevents.o  sctp_bindargs.o ${LIBS}
+
+
+sctpclient04:  sctpclient04.o sctp_strcli1.o sctp_check_notify.o sctp_print_addrs.o sctp_modify_hb.o
+               ${CC} ${CFLAGS} -o $@ sctpclient04.o sctp_strcli1.o sctp_check_notify.o sctp_print_addrs.o ${LIBS}
+
+sctpserv_fork:  sctpserv_fork.o sctp_addr_to_associd.o
+               ${CC} ${CFLAGS} -o $@ sctpserv_fork.o sctp_addr_to_associd.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/sctp/sctp_addr_to_associd.c b/sctp/sctp_addr_to_associd.c
new file mode 100644 (file)
index 0000000..3428a39
--- /dev/null
@@ -0,0 +1,15 @@
+#include       "unp.h"
+
+sctp_assoc_t
+sctp_address_to_associd(int sock_fd, struct sockaddr *sa, socklen_t salen)
+{
+       struct sctp_paddrparams sp;
+       int siz;
+
+       siz = sizeof(struct sctp_paddrparams);
+       bzero(&sp,siz);
+       memcpy(&sp.spp_address,sa,salen);
+       sctp_opt_info(sock_fd,0,
+                  SCTP_PEER_ADDR_PARAMS, &sp, &siz);
+       return(sp.spp_assoc_id);
+}
diff --git a/sctp/sctp_addr_to_associd.lc b/sctp/sctp_addr_to_associd.lc
new file mode 100644 (file)
index 0000000..d401ea3
--- /dev/null
@@ -0,0 +1,13 @@
+
+sctp_assoc_t##  1 ##src/sctp/sctp_addr_to_associd.c##
+sctp_address_to_associd(int sock_fd, struct sockaddr *sa, socklen_t salen)##  2 ##src/sctp/sctp_addr_to_associd.c##
+{##  3 ##src/sctp/sctp_addr_to_associd.c##
+    struct sctp_paddrparams sp;##  4 ##src/sctp/sctp_addr_to_associd.c##
+    int     siz;##  5 ##src/sctp/sctp_addr_to_associd.c##
+
+    siz = sizeof(struct sctp_paddrparams);##  6 ##src/sctp/sctp_addr_to_associd.c##
+    bzero(&sp, siz);##  7 ##src/sctp/sctp_addr_to_associd.c##
+    memcpy(&sp.spp_address, sa, salen);##  8 ##src/sctp/sctp_addr_to_associd.c##
+    sctp_opt_info(sock_fd, 0, SCTP_PEER_ADDR_PARAMS, &sp, &siz);##  9 ##src/sctp/sctp_addr_to_associd.c##
+    return (sp.spp_assoc_id);## 10 ##src/sctp/sctp_addr_to_associd.c##
+}## 11 ##src/sctp/sctp_addr_to_associd.c##
diff --git a/sctp/sctp_bindargs.c b/sctp/sctp_bindargs.c
new file mode 100644 (file)
index 0000000..5c33342
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+
+int
+sctp_bind_arg_list(int sock_fd, char **argv, int argc)
+{
+       struct addrinfo *addr;
+       char *bindbuf, *p, portbuf[10];
+       int addrcnt=0;
+       int i;
+
+       bindbuf = (char *)Calloc(argc, sizeof(struct sockaddr_storage));
+       p = bindbuf;
+       sprintf(portbuf, "%d", SERV_PORT);
+       for( i=0; i<argc; i++ ) {
+               addr = Host_serv(argv[i], portbuf, AF_UNSPEC, SOCK_SEQPACKET);
+               memcpy(p, addr->ai_addr, addr->ai_addrlen);
+               freeaddrinfo(addr);
+               addrcnt++;
+               p += addr->ai_addrlen;
+       }
+       Sctp_bindx(sock_fd,(SA *)bindbuf,addrcnt,SCTP_BINDX_ADD_ADDR);
+       free(bindbuf);
+       return(0);
+}
diff --git a/sctp/sctp_bindargs.lc b/sctp/sctp_bindargs.lc
new file mode 100644 (file)
index 0000000..c4fcd7e
--- /dev/null
@@ -0,0 +1,28 @@
+
+int##  1 ##src/sctp/sctp_bindargs.c##
+sctp_bind_arg_list(int sock_fd, char **argv, int argc)##  2 ##src/sctp/sctp_bindargs.c##
+{##  3 ##src/sctp/sctp_bindargs.c##
+    struct addrinfo *addr;##  4 ##src/sctp/sctp_bindargs.c##
+    struct sockaddr_storage *at;##  5 ##src/sctp/sctp_bindargs.c##
+
+    char   *bindbuf, portbuf[10];##  6 ##src/sctp/sctp_bindargs.c##
+    int     addrcnt = 0;##  7 ##src/sctp/sctp_bindargs.c##
+    int     i, sz;##  8 ##src/sctp/sctp_bindargs.c##
+
+    sz = argc * sizeof(struct sockaddr_storage);##  9 ##src/sctp/sctp_bindargs.c##
+    bindbuf = (char *) Malloc(sz);## 10 ##src/sctp/sctp_bindargs.c##
+    bzero(bindbuf, sz);## 11 ##src/sctp/sctp_bindargs.c##
+    at = (struct sockaddr_storage *) bindbuf;## 12 ##src/sctp/sctp_bindargs.c##
+    sprintf(portbuf, "%d", SERV_PORT);## 13 ##src/sctp/sctp_bindargs.c##
+    for (i = 0; i < argc; i++) {## 14 ##src/sctp/sctp_bindargs.c##
+        addr = Host_serv(argv[i], portbuf, AF_UNSPEC, SOCK_SEQPACKET);## 15 ##src/sctp/sctp_bindargs.c##
+        memcpy(at, addr->ai_addr, addr->ai_addrlen);## 16 ##src/sctp/sctp_bindargs.c##
+        freeaddrinfo(addr);## 17 ##src/sctp/sctp_bindargs.c##
+        addrcnt++;## 18 ##src/sctp/sctp_bindargs.c##
+        at++;## 19 ##src/sctp/sctp_bindargs.c##
+    }## 20 ##src/sctp/sctp_bindargs.c##
+    at = (struct sockaddr_storage *) bindbuf;## 21 ##src/sctp/sctp_bindargs.c##
+    Sctp_bindx(sock_fd, at, addrcnt, SCTP_BINDX_ADD_ADDR);## 22 ##src/sctp/sctp_bindargs.c##
+    free(bindbuf);## 23 ##src/sctp/sctp_bindargs.c##
+    return (0);## 24 ##src/sctp/sctp_bindargs.c##
+}## 25 ##src/sctp/sctp_bindargs.c##
diff --git a/sctp/sctp_check_notify.c b/sctp/sctp_check_notify.c
new file mode 100644 (file)
index 0000000..0543c1c
--- /dev/null
@@ -0,0 +1,30 @@
+#include       "unp.h"
+
+void
+check_notification(int sock_fd,char *recvline,int rd_len)
+{
+       union sctp_notification *snp;
+       struct sctp_assoc_change *sac;
+       struct sockaddr_storage *sal,*sar;
+       int num_rem, num_loc;
+
+       snp = (union sctp_notification *)recvline;
+       if(snp->sn_header.sn_type == SCTP_ASSOC_CHANGE) {
+               sac = &snp->sn_assoc_change;
+               if((sac->sac_state == SCTP_COMM_UP) ||
+                  (sac->sac_state == SCTP_RESTART)) {
+                       num_rem = sctp_getpaddrs(sock_fd,sac->sac_assoc_id,&sar);
+                       printf("There are %d remote addresses and they are:\n",
+                              num_rem);
+                       sctp_print_addresses(sar,num_rem);
+                       sctp_freepaddrs(sar);
+
+                       num_loc = sctp_getladdrs(sock_fd,sac->sac_assoc_id,&sal);
+                       printf("There are %d local addresses and they are:\n",
+                              num_loc);
+                       sctp_print_addresses(sal,num_loc);
+                       sctp_freeladdrs(sal);
+               }
+       }
+
+}
diff --git a/sctp/sctp_check_notify.lc b/sctp/sctp_check_notify.lc
new file mode 100644 (file)
index 0000000..9d6bb56
--- /dev/null
@@ -0,0 +1,27 @@
+
+void##  1 ##src/sctp/sctp_check_notify.c##
+check_notification(int sock_fd, char *recvline, int rd_len)##  2 ##src/sctp/sctp_check_notify.c##
+{##  3 ##src/sctp/sctp_check_notify.c##
+    union sctp_notification *snp;##  4 ##src/sctp/sctp_check_notify.c##
+    struct sctp_assoc_change *sac;##  5 ##src/sctp/sctp_check_notify.c##
+    struct sockaddr_storage *sal, *sar;##  6 ##src/sctp/sctp_check_notify.c##
+    int     num_rem, num_loc;##  7 ##src/sctp/sctp_check_notify.c##
+
+    snp = (union sctp_notification *) recvline;##  8 ##src/sctp/sctp_check_notify.c##
+    if (snp->sn_header.sn_type == SCTP_ASSOC_CHANGE) {##  9 ##src/sctp/sctp_check_notify.c##
+        sac = &snp->sn_assoc_change;## 10 ##src/sctp/sctp_check_notify.c##
+        if ((sac->sac_state == SCTP_COMM_UP) ||## 11 ##src/sctp/sctp_check_notify.c##
+            (sac->sac_state == SCTP_RESTART)) {## 12 ##src/sctp/sctp_check_notify.c##
+            num_rem = sctp_getpaddrs(sock_fd, sac->sac_assoc_id, &sar);## 13 ##src/sctp/sctp_check_notify.c##
+            printf("There are %d remote addresses and they are:\n", num_rem);## 14 ##src/sctp/sctp_check_notify.c##
+            sctp_print_addresses(sar, num_rem);## 15 ##src/sctp/sctp_check_notify.c##
+            sctp_freepaddrs(sar);## 16 ##src/sctp/sctp_check_notify.c##
+
+            num_loc = sctp_getladdrs(sock_fd, sac->sac_assoc_id, &sal);## 17 ##src/sctp/sctp_check_notify.c##
+            printf("There are %d local addresses and they are:\n", num_loc);## 18 ##src/sctp/sctp_check_notify.c##
+            sctp_print_addresses(sal, num_loc);## 19 ##src/sctp/sctp_check_notify.c##
+            sctp_freeladdrs(sal);## 20 ##src/sctp/sctp_check_notify.c##
+        }## 21 ##src/sctp/sctp_check_notify.c##
+    }## 22 ##src/sctp/sctp_check_notify.c##
+
+}## 23 ##src/sctp/sctp_check_notify.c##
diff --git a/sctp/sctp_displayevents.c b/sctp/sctp_displayevents.c
new file mode 100644 (file)
index 0000000..8a816ee
--- /dev/null
@@ -0,0 +1,101 @@
+#include       "unp.h"
+
+void
+print_notification(char *notify_buf)
+{
+       union sctp_notification *snp;
+       struct sctp_assoc_change *sac;
+       struct sctp_paddr_change *spc;
+       struct sctp_remote_error *sre;
+       struct sctp_send_failed *ssf;
+       struct sctp_shutdown_event *sse;
+       struct sctp_adaption_event *ae;
+       struct sctp_pdapi_event *pdapi;
+       const char *str;
+
+       snp = (union sctp_notification *)notify_buf;
+       switch(snp->sn_header.sn_type) {
+       case SCTP_ASSOC_CHANGE:
+               sac = &snp->sn_assoc_change;
+               switch(sac->sac_state) {
+               case SCTP_COMM_UP:
+                       str = "COMMUNICATION UP";
+                       break;
+               case SCTP_COMM_LOST:
+                       str = "COMMUNICATION LOST";
+                       break;
+               case SCTP_RESTART:
+                       str = "RESTART";
+                       break;
+               case SCTP_SHUTDOWN_COMP:
+                       str = "SHUTDOWN COMPLETE";
+                       break;
+               case SCTP_CANT_STR_ASSOC:
+                       str = "CAN'T START ASSOC";
+                       break;
+               default:
+                       str = "UNKNOWN";
+                       break;
+               } /* end switch(sac->sac_state) */
+               printf("SCTP_ASSOC_CHANGE: %s, assoc=0x%x\n", str,
+                      (uint32_t)sac->sac_assoc_id);
+               break;
+       case SCTP_PEER_ADDR_CHANGE:
+               spc = &snp->sn_paddr_change;
+               switch(spc->spc_state) {
+               case SCTP_ADDR_AVAILABLE:
+                       str = "ADDRESS AVAILABLE";
+                       break;
+               case SCTP_ADDR_UNREACHABLE:
+                       str = "ADDRESS UNREACHABLE";
+                       break;
+               case SCTP_ADDR_REMOVED:
+                       str = "ADDRESS REMOVED";
+                       break;
+               case SCTP_ADDR_ADDED:
+                       str = "ADDRESS ADDED";
+                       break;
+               case SCTP_ADDR_MADE_PRIM:
+                       str = "ADDRESS MADE PRIMARY";
+                       break;
+               default:
+                       str = "UNKNOWN";
+                       break;
+               } /* end switch(spc->spc_state) */
+               printf("SCTP_PEER_ADDR_CHANGE: %s, addr=%s, assoc=0x%x\n", str,
+                      Sock_ntop((SA *)&spc->spc_aaddr, sizeof(spc->spc_aaddr)),
+                      (uint32_t)spc->spc_assoc_id);
+               break;
+       case SCTP_REMOTE_ERROR:
+               sre = &snp->sn_remote_error;
+               printf("SCTP_REMOTE_ERROR: assoc=0x%x error=%d\n",
+                      (uint32_t)sre->sre_assoc_id, sre->sre_error);
+               break;
+       case SCTP_SEND_FAILED:
+               ssf = &snp->sn_send_failed;
+               printf("SCTP_SEND_FAILED: assoc=0x%x error=%d\n",
+                      (uint32_t)ssf->ssf_assoc_id, ssf->ssf_error);
+               break;
+       case SCTP_ADAPTION_INDICATION:
+               ae = &snp->sn_adaption_event;
+               printf("SCTP_ADAPTION_INDICATION: 0x%x\n",
+                   (u_int)ae->sai_adaption_ind);
+               break;
+       case SCTP_PARTIAL_DELIVERY_EVENT:
+           pdapi = &snp->sn_pdapi_event;
+           if(pdapi->pdapi_indication == SCTP_PARTIAL_DELIVERY_ABORTED)
+                   printf("SCTP_PARTIAL_DELIEVERY_ABORTED\n");
+           else
+                   printf("Unknown SCTP_PARTIAL_DELIVERY_EVENT 0x%x\n",
+                          pdapi->pdapi_indication);
+           break;
+       case SCTP_SHUTDOWN_EVENT:
+               sse = &snp->sn_shutdown_event;
+               printf("SCTP_SHUTDOWN_EVENT: assoc=0x%x\n",
+                      (uint32_t)sse->sse_assoc_id);
+               break;
+       default:
+               printf("Unknown notification event type=0x%x\n", 
+                      snp->sn_header.sn_type);
+       }
+}
diff --git a/sctp/sctp_displayevents.lc b/sctp/sctp_displayevents.lc
new file mode 100644 (file)
index 0000000..0c7235e
--- /dev/null
@@ -0,0 +1,100 @@
+
+void##  1 ##src/sctp/sctp_displayevents.c##
+print_notification(char *notify_buf)##  2 ##src/sctp/sctp_displayevents.c##
+{##  3 ##src/sctp/sctp_displayevents.c##
+    union sctp_notification *snp;##  4 ##src/sctp/sctp_displayevents.c##
+    struct sctp_assoc_change *sac;##  5 ##src/sctp/sctp_displayevents.c##
+    struct sctp_paddr_change *spc;##  6 ##src/sctp/sctp_displayevents.c##
+    struct sctp_remote_error *sre;##  7 ##src/sctp/sctp_displayevents.c##
+    struct sctp_send_failed *ssf;##  8 ##src/sctp/sctp_displayevents.c##
+    struct sctp_shutdown_event *sse;##  9 ##src/sctp/sctp_displayevents.c##
+    struct sctp_adaption_event *ae;## 10 ##src/sctp/sctp_displayevents.c##
+    struct sctp_pdapi_event *pdapi;## 11 ##src/sctp/sctp_displayevents.c##
+    const char *str;## 12 ##src/sctp/sctp_displayevents.c##
+
+    snp = (union sctp_notification *) notify_buf;## 13 ##src/sctp/sctp_displayevents.c##
+    switch (snp->sn_header.sn_type) {## 14 ##src/sctp/sctp_displayevents.c##
+    case SCTP_ASSOC_CHANGE:## 15 ##src/sctp/sctp_displayevents.c##
+        sac = &snp->sn_assoc_change;## 16 ##src/sctp/sctp_displayevents.c##
+        switch (sac->sac_state) {## 17 ##src/sctp/sctp_displayevents.c##
+        case SCTP_COMM_UP:## 18 ##src/sctp/sctp_displayevents.c##
+            str = "COMMUNICATION UP";## 19 ##src/sctp/sctp_displayevents.c##
+            break;## 20 ##src/sctp/sctp_displayevents.c##
+        case SCTP_COMM_LOST:## 21 ##src/sctp/sctp_displayevents.c##
+            str = "COMMUNICATION LOST";## 22 ##src/sctp/sctp_displayevents.c##
+            break;## 23 ##src/sctp/sctp_displayevents.c##
+        case SCTP_RESTART:## 24 ##src/sctp/sctp_displayevents.c##
+            str = "RESTART";## 25 ##src/sctp/sctp_displayevents.c##
+            break;## 26 ##src/sctp/sctp_displayevents.c##
+        case SCTP_SHUTDOWN_COMP:## 27 ##src/sctp/sctp_displayevents.c##
+            str = "SHUTDOWN COMPLETE";## 28 ##src/sctp/sctp_displayevents.c##
+            break;## 29 ##src/sctp/sctp_displayevents.c##
+        case SCTP_CANT_STR_ASSOC:## 30 ##src/sctp/sctp_displayevents.c##
+            str = "CANT START ASSOC";## 31 ##src/sctp/sctp_displayevents.c##
+            break;## 32 ##src/sctp/sctp_displayevents.c##
+        default:## 33 ##src/sctp/sctp_displayevents.c##
+            str = "UNKNOWN";## 34 ##src/sctp/sctp_displayevents.c##
+            break;## 35 ##src/sctp/sctp_displayevents.c##
+        }                       /* end switch(sac->sac_state) */## 36 ##src/sctp/sctp_displayevents.c##
+        printf("SCTP_ASSOC_CHANGE: %s, assoc=0x%x\n", str,## 37 ##src/sctp/sctp_displayevents.c##
+               (uint32_t) sac->sac_assoc_id);## 38 ##src/sctp/sctp_displayevents.c##
+        break;## 39 ##src/sctp/sctp_displayevents.c##
+    case SCTP_PEER_ADDR_CHANGE:## 40 ##src/sctp/sctp_displayevents.c##
+        spc = &snp->sn_paddr_change;## 41 ##src/sctp/sctp_displayevents.c##
+        switch (spc->spc_state) {## 42 ##src/sctp/sctp_displayevents.c##
+        case SCTP_ADDR_AVAILABLE:## 43 ##src/sctp/sctp_displayevents.c##
+            str = "ADDRESS AVAILABLE";## 44 ##src/sctp/sctp_displayevents.c##
+            break;## 45 ##src/sctp/sctp_displayevents.c##
+        case SCTP_ADDR_UNREACHABLE:## 46 ##src/sctp/sctp_displayevents.c##
+            str = "ADDRESS UNAVAILABLE";## 47 ##src/sctp/sctp_displayevents.c##
+            break;## 48 ##src/sctp/sctp_displayevents.c##
+        case SCTP_ADDR_REMOVED:## 49 ##src/sctp/sctp_displayevents.c##
+            str = "ADDRESS REMOVED";## 50 ##src/sctp/sctp_displayevents.c##
+            break;## 51 ##src/sctp/sctp_displayevents.c##
+        case SCTP_ADDR_ADDED:## 52 ##src/sctp/sctp_displayevents.c##
+            str = "ADDRESS ADDED";## 53 ##src/sctp/sctp_displayevents.c##
+            break;## 54 ##src/sctp/sctp_displayevents.c##
+        case SCTP_ADDR_MADE_PRIM:## 55 ##src/sctp/sctp_displayevents.c##
+            str = "ADDRESS MADE PRIMARY";## 56 ##src/sctp/sctp_displayevents.c##
+            break;## 57 ##src/sctp/sctp_displayevents.c##
+        default:## 58 ##src/sctp/sctp_displayevents.c##
+            str = "UNKNOWN";## 59 ##src/sctp/sctp_displayevents.c##
+            break;## 60 ##src/sctp/sctp_displayevents.c##
+        }                       /* end switch(spc->spc_state) */## 61 ##src/sctp/sctp_displayevents.c##
+        printf("SCTP_PEER_ADDR_CHANGE: %s, addr=%s, assoc=0x%x\n", str,## 62 ##src/sctp/sctp_displayevents.c##
+               Sock_ntop((SA *) &spc->spc_aaddr, sizeof(spc->spc_aaddr)),## 63 ##src/sctp/sctp_displayevents.c##
+               (uint32_t) spc->spc_assoc_id);## 64 ##src/sctp/sctp_displayevents.c##
+        break;## 65 ##src/sctp/sctp_displayevents.c##
+    case SCTP_REMOTE_ERROR:## 66 ##src/sctp/sctp_displayevents.c##
+        sre = &snp->sn_remote_error;## 67 ##src/sctp/sctp_displayevents.c##
+        printf("SCTP_REMOTE_ERROR: assoc=0x%x\n",## 68 ##src/sctp/sctp_displayevents.c##
+               (uint32_t) sre->sre_assoc_id);## 69 ##src/sctp/sctp_displayevents.c##
+        break;## 70 ##src/sctp/sctp_displayevents.c##
+    case SCTP_SEND_FAILED:## 71 ##src/sctp/sctp_displayevents.c##
+        ssf = &snp->sn_send_failed;## 72 ##src/sctp/sctp_displayevents.c##
+        printf("SCTP_SEND_FAILED: assoc=0x%x\n",## 73 ##src/sctp/sctp_displayevents.c##
+               (uint32_t) ssf->ssf_assoc_id);## 74 ##src/sctp/sctp_displayevents.c##
+        break;## 75 ##src/sctp/sctp_displayevents.c##
+    case SCTP_ADAPTION_INDICATION:## 76 ##src/sctp/sctp_displayevents.c##
+        ae = &snp->sn_adaption_event;## 77 ##src/sctp/sctp_displayevents.c##
+        printf("SCTP_adaption_indication:0x%x\n",## 78 ##src/sctp/sctp_displayevents.c##
+               (u_int) ae->sai_adaption_ind);## 79 ##src/sctp/sctp_displayevents.c##
+        break;## 80 ##src/sctp/sctp_displayevents.c##
+    case SCTP_PARTIAL_DELIVERY_EVENT:## 81 ##src/sctp/sctp_displayevents.c##
+        pdapi = &snp->sn_pdapi_event;## 82 ##src/sctp/sctp_displayevents.c##
+        if (pdapi->pdapi_indication == SCTP_PARTIAL_DELIVERY_ABORTED)## 83 ##src/sctp/sctp_displayevents.c##
+            printf("SCTP_PD-API ABORTED\n");## 84 ##src/sctp/sctp_displayevents.c##
+        else## 85 ##src/sctp/sctp_displayevents.c##
+            printf("Unknown SCTP_PD-API EVENT 0x%x\n",## 86 ##src/sctp/sctp_displayevents.c##
+                   pdapi->pdapi_indication);## 87 ##src/sctp/sctp_displayevents.c##
+        break;## 88 ##src/sctp/sctp_displayevents.c##
+    case SCTP_SHUTDOWN_EVENT:## 89 ##src/sctp/sctp_displayevents.c##
+        sse = &snp->sn_shutdown_event;## 90 ##src/sctp/sctp_displayevents.c##
+        printf("SCTP_SHUTDOWN_EVENT: assoc=0x%x\n",## 91 ##src/sctp/sctp_displayevents.c##
+               (uint32_t) sse->sse_assoc_id);## 92 ##src/sctp/sctp_displayevents.c##
+        break;## 93 ##src/sctp/sctp_displayevents.c##
+    default:## 94 ##src/sctp/sctp_displayevents.c##
+        printf("Unknown notification event type=0x%x\n",## 95 ##src/sctp/sctp_displayevents.c##
+               snp->sn_header.sn_type);## 96 ##src/sctp/sctp_displayevents.c##
+    }## 97 ##src/sctp/sctp_displayevents.c##
+}## 98 ##src/sctp/sctp_displayevents.c##
diff --git a/sctp/sctp_getnostrm.c b/sctp/sctp_getnostrm.c
new file mode 100644 (file)
index 0000000..afb045f
--- /dev/null
@@ -0,0 +1,15 @@
+#include       "unp.h"
+
+int 
+sctp_get_no_strms(int sock_fd,struct sockaddr *to, socklen_t tolen)
+{
+       int retsz;
+       struct sctp_status status;
+       retsz = sizeof(status); 
+       bzero(&status,sizeof(status));
+
+       status.sstat_assoc_id = sctp_address_to_associd(sock_fd,to,tolen);
+       Getsockopt(sock_fd,IPPROTO_SCTP, SCTP_STATUS,
+                  &status, &retsz);
+       return(status.sstat_outstrms);
+}
diff --git a/sctp/sctp_modify_hb.c b/sctp/sctp_modify_hb.c
new file mode 100644 (file)
index 0000000..5a424d5
--- /dev/null
@@ -0,0 +1,15 @@
+#include       "unp.h"
+
+int heartbeat_action(int sock_fd, struct sockaddr *sa, socklen_t salen,
+                         u_int value)
+{
+       struct sctp_paddrparams sp;
+       int siz;
+
+       bzero(&sp,sizeof(sp));
+       sp.spp_hbinterval = value;
+       memcpy((caddr_t)&sp.spp_address,sa,salen);
+       Setsockopt(sock_fd,IPPROTO_SCTP,
+                  SCTP_PEER_ADDR_PARAMS, &sp, sizeof(sp));
+       return(0);
+}
diff --git a/sctp/sctp_modify_hb.lc b/sctp/sctp_modify_hb.lc
new file mode 100644 (file)
index 0000000..ff8d2fa
--- /dev/null
@@ -0,0 +1,27 @@
+
+int##  1 ##src/sctp/sctp_modify_hb.c##
+heartbeat_action(int sock_fd, struct sockaddr *sa, socklen_t salen,##  2 ##src/sctp/sctp_modify_hb.c##
+                 int action, u_int value)##  3 ##src/sctp/sctp_modify_hb.c##
+{##  4 ##src/sctp/sctp_modify_hb.c##
+    struct sctp_paddrparams sp;##  5 ##src/sctp/sctp_modify_hb.c##
+    int     siz;##  6 ##src/sctp/sctp_modify_hb.c##
+    bzero(&sp, sizeof(sp));##  7 ##src/sctp/sctp_modify_hb.c##
+    if (action == SCTP_ON_DEMAND_HB) {##  8 ##src/sctp/sctp_modify_hb.c##
+        sp.spp_hbinterval = SCTP_ISSUE_HB;##  9 ##src/sctp/sctp_modify_hb.c##
+    } else if (action == SCTP_SET_HB_INTERVAL) {## 10 ##src/sctp/sctp_modify_hb.c##
+        if ((value == SCTP_NO_HB) || (value == SCTP_ISSUE_HB)) {## 11 ##src/sctp/sctp_modify_hb.c##
+            errno = EINVAL;## 12 ##src/sctp/sctp_modify_hb.c##
+            return (-1);## 13 ##src/sctp/sctp_modify_hb.c##
+        }## 14 ##src/sctp/sctp_modify_hb.c##
+        sp.spp_hbinterval = value;## 15 ##src/sctp/sctp_modify_hb.c##
+    } else if (action == SCTP_DISABLE_HB) {## 16 ##src/sctp/sctp_modify_hb.c##
+        sp.spp_hbinterval = SCTP_NO_HB;## 17 ##src/sctp/sctp_modify_hb.c##
+    } else {## 18 ##src/sctp/sctp_modify_hb.c##
+        errno = EINVAL;## 19 ##src/sctp/sctp_modify_hb.c##
+        return (-1);## 20 ##src/sctp/sctp_modify_hb.c##
+    }## 21 ##src/sctp/sctp_modify_hb.c##
+    siz = sizeof(struct sctp_paddrparams);## 22 ##src/sctp/sctp_modify_hb.c##
+    memcpy((caddr_t) & sp.spp_address, sa, salen);## 23 ##src/sctp/sctp_modify_hb.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &sp, siz);## 24 ##src/sctp/sctp_modify_hb.c##
+    return (0);## 25 ##src/sctp/sctp_modify_hb.c##
+}## 26 ##src/sctp/sctp_modify_hb.c##
diff --git a/sctp/sctp_pdapircv.c b/sctp/sctp_pdapircv.c
new file mode 100644 (file)
index 0000000..2344f03
--- /dev/null
@@ -0,0 +1,45 @@
+#include       "unp.h"
+
+static uint8_t *sctp_pdapi_readbuf=NULL;
+static int sctp_pdapi_rdbuf_sz=0;
+
+
+uint8_t *
+pdapi_recvmsg(int sock_fd,
+             int *rdlen,
+             SA *from,
+             int *from_len,
+             struct sctp_sndrcvinfo *sri,
+             int *msg_flags)
+{
+       int rdsz,left,at_in_buf;
+       int frmlen=0;
+
+       if (sctp_pdapi_readbuf == NULL) {
+               sctp_pdapi_readbuf = (uint8_t *)Malloc(SCTP_PDAPI_INCR_SZ);
+               sctp_pdapi_rdbuf_sz = SCTP_PDAPI_INCR_SZ;
+       }
+       at_in_buf = Sctp_recvmsg(sock_fd, sctp_pdapi_readbuf, sctp_pdapi_rdbuf_sz,
+                                from, from_len,
+                                sri,msg_flags);
+       if(at_in_buf < 1){
+               *rdlen = at_in_buf;
+               return(NULL);
+       }
+       while((*msg_flags & MSG_EOR) == 0) {
+               left = sctp_pdapi_rdbuf_sz - at_in_buf;
+               if(left < SCTP_PDAPI_NEED_MORE_THRESHOLD) {
+                       sctp_pdapi_readbuf = realloc(sctp_pdapi_readbuf, sctp_pdapi_rdbuf_sz+SCTP_PDAPI_INCR_SZ);
+                       if(sctp_pdapi_readbuf == NULL) {
+                               err_quit("sctp_pdapi ran out of memory");
+                       }
+                       sctp_pdapi_rdbuf_sz += SCTP_PDAPI_INCR_SZ;
+                       left = sctp_pdapi_rdbuf_sz - at_in_buf;
+               }
+               rdsz = Sctp_recvmsg(sock_fd, &sctp_pdapi_readbuf[at_in_buf], 
+                            left, NULL, &frmlen, NULL, msg_flags);
+               at_in_buf += rdsz;
+       }
+       *rdlen = at_in_buf;
+       return(sctp_pdapi_readbuf);
+}
diff --git a/sctp/sctp_pdapircv.lc b/sctp/sctp_pdapircv.lc
new file mode 100644 (file)
index 0000000..b874172
--- /dev/null
@@ -0,0 +1,49 @@
+
+static uint8_t *sctp_pdapi_readbuf = NULL;##  1 ##src/sctp/sctp_pdapircv.c##
+static int sctp_pdapi_rdbuf_sz = 0;##  2 ##src/sctp/sctp_pdapircv.c##
+
+uint8_t *##  3 ##src/sctp/sctp_pdapircv.c##
+pdapi_recvmsg(int sock_fd,##  4 ##src/sctp/sctp_pdapircv.c##
+              int *rdlen,##  5 ##src/sctp/sctp_pdapircv.c##
+              SA *from,##  6 ##src/sctp/sctp_pdapircv.c##
+              int *from_len, struct sctp_sndrcvinfo *sri, int *msg_flags)##  7 ##src/sctp/sctp_pdapircv.c##
+{##  8 ##src/sctp/sctp_pdapircv.c##
+    int     rdsz, left, at_in_buf;##  9 ##src/sctp/sctp_pdapircv.c##
+    int     frmlen = 0;## 10 ##src/sctp/sctp_pdapircv.c##
+
+    if (sctp_pdapi_readbuf == NULL) {## 11 ##src/sctp/sctp_pdapircv.c##
+        sctp_pdapi_readbuf = (uint8_t *) Malloc(SCTP_PDAPI_INCR_SZ);## 12 ##src/sctp/sctp_pdapircv.c##
+        sctp_pdapi_rdbuf_sz = SCTP_PDAPI_INCR_SZ;## 13 ##src/sctp/sctp_pdapircv.c##
+    }## 14 ##src/sctp/sctp_pdapircv.c##
+    at_in_buf =## 15 ##src/sctp/sctp_pdapircv.c##
+        Sctp_recvmsg(sock_fd, sctp_pdapi_readbuf, sctp_pdapi_rdbuf_sz, from,## 16 ##src/sctp/sctp_pdapircv.c##
+                     from_len, sri, msg_flags);## 17 ##src/sctp/sctp_pdapircv.c##
+    if (at_in_buf < 1) {## 18 ##src/sctp/sctp_pdapircv.c##
+        *rdlen = at_in_buf;## 19 ##src/sctp/sctp_pdapircv.c##
+        return (NULL);## 20 ##src/sctp/sctp_pdapircv.c##
+    }## 21 ##src/sctp/sctp_pdapircv.c##
+    while ((*msg_flags & MSG_EOR) == 0) {## 22 ##src/sctp/sctp_pdapircv.c##
+        left = sctp_pdapi_rdbuf_sz - at_in_buf;## 23 ##src/sctp/sctp_pdapircv.c##
+        if (left < SCTP_PDAPI_NEED_MORE_THRESHOLD) {## 24 ##src/sctp/sctp_pdapircv.c##
+            uint8_t *more;## 25 ##src/sctp/sctp_pdapircv.c##
+            more =## 26 ##src/sctp/sctp_pdapircv.c##
+                (uint8_t *) malloc(sctp_pdapi_rdbuf_sz + SCTP_PDAPI_INCR_SZ);## 27 ##src/sctp/sctp_pdapircv.c##
+            if (more == NULL) {## 28 ##src/sctp/sctp_pdapircv.c##
+                printf("Warning:memory exhausted - partial message loss\n");## 29 ##src/sctp/sctp_pdapircv.c##
+                left = sctp_pdapi_rdbuf_sz;## 30 ##src/sctp/sctp_pdapircv.c##
+                at_in_buf = 0;## 31 ##src/sctp/sctp_pdapircv.c##
+            } else {## 32 ##src/sctp/sctp_pdapircv.c##
+                memcpy(more, sctp_pdapi_readbuf, at_in_buf);## 33 ##src/sctp/sctp_pdapircv.c##
+                free(sctp_pdapi_readbuf);## 34 ##src/sctp/sctp_pdapircv.c##
+                sctp_pdapi_readbuf = more;## 35 ##src/sctp/sctp_pdapircv.c##
+                sctp_pdapi_rdbuf_sz += SCTP_PDAPI_INCR_SZ;## 36 ##src/sctp/sctp_pdapircv.c##
+                left = sctp_pdapi_rdbuf_sz - at_in_buf;## 37 ##src/sctp/sctp_pdapircv.c##
+            }## 38 ##src/sctp/sctp_pdapircv.c##
+        }## 39 ##src/sctp/sctp_pdapircv.c##
+        rdsz = Sctp_recvmsg(sock_fd, &sctp_pdapi_readbuf[at_in_buf],## 40 ##src/sctp/sctp_pdapircv.c##
+                            left, NULL, &frmlen, NULL, msg_flags);## 41 ##src/sctp/sctp_pdapircv.c##
+        at_in_buf += rdsz;## 42 ##src/sctp/sctp_pdapircv.c##
+    }## 43 ##src/sctp/sctp_pdapircv.c##
+    *rdlen = at_in_buf;## 44 ##src/sctp/sctp_pdapircv.c##
+    return (sctp_pdapi_readbuf);## 45 ##src/sctp/sctp_pdapircv.c##
+}## 46 ##src/sctp/sctp_pdapircv.c##
diff --git a/sctp/sctp_print_addrs.c b/sctp/sctp_print_addrs.c
new file mode 100644 (file)
index 0000000..6454ca1
--- /dev/null
@@ -0,0 +1,31 @@
+#include       "unp.h"
+
+void
+sctp_print_addresses(struct sockaddr_storage *addrs, int num)
+{
+       struct sockaddr_storage *ss;
+       int i,salen;
+
+       ss = addrs;
+       for(i=0; i<num; i++){
+               printf("%s\n", Sock_ntop((SA *)ss, salen));
+#ifdef HAVE_SOCKADDR_SA_LEN
+               salen = ss->ss_len;
+#else
+               switch(ss->ss_family) {
+               case AF_INET:
+                       salen = sizeof(struct sockaddr_in);
+                       break;
+#ifdef IPV6
+               case AF_INET6:
+                       salen = sizeof(struct sockaddr_in6);
+                       break;
+#endif
+               default:
+                       err_quit("sctp_print_addresses: unknown AF");
+                       break;
+               }
+#endif
+               ss = (struct sockaddr_storage *)((char *)ss + salen);
+       }
+}
diff --git a/sctp/sctp_print_addrs.lc b/sctp/sctp_print_addrs.lc
new file mode 100644 (file)
index 0000000..d8aef0e
--- /dev/null
@@ -0,0 +1,31 @@
+#include    "unp.h"##  1 ##src/sctp/sctp_print_addrs.c##
+
+void##  2 ##src/sctp/sctp_print_addrs.c##
+sctp_print_addresses(struct sockaddr_storage *addrs, int num)##  3 ##src/sctp/sctp_print_addrs.c##
+{##  4 ##src/sctp/sctp_print_addrs.c##
+    struct sockaddr_storage *ss;##  5 ##src/sctp/sctp_print_addrs.c##
+    int     i, salen;##  6 ##src/sctp/sctp_print_addrs.c##
+
+    ss = addrs;##  7 ##src/sctp/sctp_print_addrs.c##
+    for (i = 0; i < num; i++) {##  8 ##src/sctp/sctp_print_addrs.c##
+        printf("%s\n", Sock_ntop((SA *) ss, salen));##  9 ##src/sctp/sctp_print_addrs.c##
+#ifdef HAVE_SOCKADDR_SA_LEN## 10 ##src/sctp/sctp_print_addrs.c##
+        salen = ss->ss_len;## 11 ##src/sctp/sctp_print_addrs.c##
+#else## 12 ##src/sctp/sctp_print_addrs.c##
+        switch (ss->ss_family) {## 13 ##src/sctp/sctp_print_addrs.c##
+        case AF_INET:## 14 ##src/sctp/sctp_print_addrs.c##
+            salen = sizeof(struct sockaddr_in);## 15 ##src/sctp/sctp_print_addrs.c##
+            break;## 16 ##src/sctp/sctp_print_addrs.c##
+#ifdef IPV6## 17 ##src/sctp/sctp_print_addrs.c##
+        case AF_INET6:## 18 ##src/sctp/sctp_print_addrs.c##
+            salen = sizeof(struct sockaddr_in6);## 19 ##src/sctp/sctp_print_addrs.c##
+            break;## 20 ##src/sctp/sctp_print_addrs.c##
+#endif## 21 ##src/sctp/sctp_print_addrs.c##
+        default:## 22 ##src/sctp/sctp_print_addrs.c##
+            err_quit("sctp_print_addresses: unknown AF");## 23 ##src/sctp/sctp_print_addrs.c##
+            break;## 24 ##src/sctp/sctp_print_addrs.c##
+        }## 25 ##src/sctp/sctp_print_addrs.c##
+#endif## 26 ##src/sctp/sctp_print_addrs.c##
+        ss = (struct sockaddr_storage *) ((char *) ss + salen);## 27 ##src/sctp/sctp_print_addrs.c##
+    }## 28 ##src/sctp/sctp_print_addrs.c##
+}## 29 ##src/sctp/sctp_print_addrs.c##
diff --git a/sctp/sctp_strcli.c b/sctp/sctp_strcli.c
new file mode 100644 (file)
index 0000000..b3ecfe0
--- /dev/null
@@ -0,0 +1,36 @@
+#include       "unp.h"
+
+void
+sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)
+{
+       struct sockaddr_in peeraddr;
+       struct sctp_sndrcvinfo sri;
+       char sendline[MAXLINE], recvline[MAXLINE];
+       socklen_t len;
+       int out_sz,rd_sz;
+       int msg_flags;
+
+       bzero(&sri,sizeof(sri));
+       while (fgets(sendline, MAXLINE, fp) != NULL) {
+               if(sendline[0] != '[') {
+                       printf("Error, line must be of the form '[streamnum]text'\n");
+                       continue;
+               }
+               sri.sinfo_stream = strtol(&sendline[1],NULL,0);
+               out_sz = strlen(sendline);
+               Sctp_sendmsg(sock_fd, sendline, out_sz, 
+                            to, tolen, 
+                            0, 0,
+                            sri.sinfo_stream,
+                            0, 0);
+
+               len = sizeof(peeraddr);
+               rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),
+                            (SA *)&peeraddr, &len,
+                            &sri,&msg_flags);
+               printf("From str:%d seq:%d (assoc:0x%x):",
+                      sri.sinfo_stream,sri.sinfo_ssn,
+                      (u_int)sri.sinfo_assoc_id);
+               printf("%.*s",rd_sz,recvline);
+       }
+}
diff --git a/sctp/sctp_strcli.lc b/sctp/sctp_strcli.lc
new file mode 100644 (file)
index 0000000..f2c7a63
--- /dev/null
@@ -0,0 +1,31 @@
+#include    "unp.h"##  1 ##src/sctp/sctp_strcli.c##
+
+void##  2 ##src/sctp/sctp_strcli.c##
+sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)##  3 ##src/sctp/sctp_strcli.c##
+{##  4 ##src/sctp/sctp_strcli.c##
+    struct sockaddr_in peeraddr;##  5 ##src/sctp/sctp_strcli.c##
+    struct sctp_sndrcvinfo sri;##  6 ##src/sctp/sctp_strcli.c##
+    char    sendline[MAXLINE], recvline[MAXLINE];##  7 ##src/sctp/sctp_strcli.c##
+    socklen_t len;##  8 ##src/sctp/sctp_strcli.c##
+    int     out_sz, rd_sz;##  9 ##src/sctp/sctp_strcli.c##
+    int     msg_flags;## 10 ##src/sctp/sctp_strcli.c##
+
+    bzero(&sri, sizeof(sri));## 11 ##src/sctp/sctp_strcli.c##
+    while (fgets(sendline, MAXLINE, fp) != NULL) {## 12 ##src/sctp/sctp_strcli.c##
+        if (sendline[0] != '[') {## 13 ##src/sctp/sctp_strcli.c##
+            printf("Error, line must be of the form '[streamnum]text'\n");## 14 ##src/sctp/sctp_strcli.c##
+            continue;## 15 ##src/sctp/sctp_strcli.c##
+        }## 16 ##src/sctp/sctp_strcli.c##
+        sri.sinfo_stream = strtol(&sendline[1], NULL, 0);## 17 ##src/sctp/sctp_strcli.c##
+        out_sz = strlen(sendline);## 18 ##src/sctp/sctp_strcli.c##
+        Sctp_sendmsg(sock_fd, sendline, out_sz,## 19 ##src/sctp/sctp_strcli.c##
+                     to, tolen, 0, 0, sri.sinfo_stream, 0, 0);## 20 ##src/sctp/sctp_strcli.c##
+
+        len = sizeof(peeraddr);## 21 ##src/sctp/sctp_strcli.c##
+        rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),## 22 ##src/sctp/sctp_strcli.c##
+                             (SA *) &peeraddr, &len, &sri, &msg_flags);## 23 ##src/sctp/sctp_strcli.c##
+        printf("From str:%d seq:%d (assoc:0x%x):",## 24 ##src/sctp/sctp_strcli.c##
+               sri.sinfo_stream, sri.sinfo_ssn, (u_int) sri.sinfo_assoc_id);## 25 ##src/sctp/sctp_strcli.c##
+        printf("%.*s", rd_sz, recvline);## 26 ##src/sctp/sctp_strcli.c##
+    }## 27 ##src/sctp/sctp_strcli.c##
+}## 28 ##src/sctp/sctp_strcli.c##
diff --git a/sctp/sctp_strcli1.c b/sctp/sctp_strcli1.c
new file mode 100644 (file)
index 0000000..fd6c56c
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unp.h"
+
+void
+sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)
+{
+       struct sockaddr_in peeraddr;
+       struct sctp_sndrcvinfo sri;
+       char sendline[MAXLINE], recvline[MAXLINE];
+       socklen_t len;
+       int out_sz,rd_sz;
+       int msg_flags;
+
+       bzero(&sri,sizeof(sri));
+       while (fgets(sendline, MAXLINE, fp) != NULL) {
+               if(sendline[0] != '[') {
+                       printf("Error, line must be of the form '[streamnum]text'\n");
+                       continue;
+               }
+               sri.sinfo_stream = strtol(&sendline[1],NULL,0);
+               out_sz = strlen(sendline);
+               Sctp_sendmsg(sock_fd, sendline, out_sz, 
+                            to, tolen, 
+                            0, 0,
+                            sri.sinfo_stream,
+                            0, 0);
+/* include mod_strcli1 */              
+               do {
+                       len = sizeof(peeraddr);
+                       rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),
+                                    (SA *)&peeraddr, &len,
+                                    &sri,&msg_flags);
+                       if(msg_flags & MSG_NOTIFICATION)
+                               check_notification(sock_fd,recvline,rd_sz);
+               } while (msg_flags & MSG_NOTIFICATION);
+               printf("From str:%d seq:%d (assoc:0x%x):",
+                      sri.sinfo_stream,sri.sinfo_ssn,
+                      (u_int)sri.sinfo_assoc_id);
+               printf("%.*s",rd_sz,recvline);
+/* end mod_strcli1 */          
+       }
+}
diff --git a/sctp/sctp_strcli1.lc b/sctp/sctp_strcli1.lc
new file mode 100644 (file)
index 0000000..d6269e1
--- /dev/null
@@ -0,0 +1,36 @@
+#include    "unp.h"##  1 ##src/sctp/sctp_strcli1.c##
+
+void##  2 ##src/sctp/sctp_strcli1.c##
+sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)##  3 ##src/sctp/sctp_strcli1.c##
+{##  4 ##src/sctp/sctp_strcli1.c##
+    struct sockaddr_in peeraddr;##  5 ##src/sctp/sctp_strcli1.c##
+    struct sctp_sndrcvinfo sri;##  6 ##src/sctp/sctp_strcli1.c##
+    char    sendline[MAXLINE], recvline[MAXLINE];##  7 ##src/sctp/sctp_strcli1.c##
+    socklen_t len;##  8 ##src/sctp/sctp_strcli1.c##
+    int     out_sz, rd_sz;##  9 ##src/sctp/sctp_strcli1.c##
+    int     msg_flags;## 10 ##src/sctp/sctp_strcli1.c##
+
+    bzero(&sri, sizeof(sri));## 11 ##src/sctp/sctp_strcli1.c##
+    while (fgets(sendline, MAXLINE, fp) != NULL) {## 12 ##src/sctp/sctp_strcli1.c##
+        if (sendline[0] != '[') {## 13 ##src/sctp/sctp_strcli1.c##
+            printf("Error, line must be of the form '[streamnum]text'\n");## 14 ##src/sctp/sctp_strcli1.c##
+            continue;## 15 ##src/sctp/sctp_strcli1.c##
+        }## 16 ##src/sctp/sctp_strcli1.c##
+        sri.sinfo_stream = strtol(&sendline[1], NULL, 0);## 17 ##src/sctp/sctp_strcli1.c##
+        out_sz = strlen(sendline);## 18 ##src/sctp/sctp_strcli1.c##
+        Sctp_sendmsg(sock_fd, sendline, out_sz,## 19 ##src/sctp/sctp_strcli1.c##
+                     to, tolen, 0, 0, sri.sinfo_stream, 0, 0);## 20 ##src/sctp/sctp_strcli1.c##
+        /* include mod_strcli1 */## 21 ##src/sctp/sctp_strcli1.c##
+        do {## 22 ##src/sctp/sctp_strcli1.c##
+            len = sizeof(peeraddr);## 23 ##src/sctp/sctp_strcli1.c##
+            rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),## 24 ##src/sctp/sctp_strcli1.c##
+                                 (SA *) &peeraddr, &len, &sri, &msg_flags);## 25 ##src/sctp/sctp_strcli1.c##
+            if (msg_flags & MSG_NOTIFICATION)## 26 ##src/sctp/sctp_strcli1.c##
+                check_notification(sock_fd, recvline, rd_sz);## 27 ##src/sctp/sctp_strcli1.c##
+        } while (msg_flags & MSG_NOTIFICATION);## 28 ##src/sctp/sctp_strcli1.c##
+        printf("From str:%d seq:%d (assoc:0x%x):",## 29 ##src/sctp/sctp_strcli1.c##
+               sri.sinfo_stream, sri.sinfo_ssn, (u_int) sri.sinfo_assoc_id);## 30 ##src/sctp/sctp_strcli1.c##
+        printf("%.*s", rd_sz, recvline);## 31 ##src/sctp/sctp_strcli1.c##
+        /* end mod_strcli1 */## 32 ##src/sctp/sctp_strcli1.c##
+    }## 33 ##src/sctp/sctp_strcli1.c##
+}## 34 ##src/sctp/sctp_strcli1.c##
diff --git a/sctp/sctp_strcli_un.c b/sctp/sctp_strcli_un.c
new file mode 100644 (file)
index 0000000..21d685f
--- /dev/null
@@ -0,0 +1,38 @@
+#include       "unp.h"
+
+void
+sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)
+{
+       struct sockaddr_in peeraddr;
+       struct sctp_sndrcvinfo sri;
+       char sendline[MAXLINE], recvline[MAXLINE];
+       socklen_t len;
+       int out_sz,rd_sz;
+       int msg_flags;
+
+       bzero(&sri,sizeof(sri));
+       while (fgets(sendline, MAXLINE, fp) != NULL) {
+               if(sendline[0] != '[') {
+                       printf("Error, line must be of the form '[streamnum]text'\n");
+                       continue;
+               }
+               sri.sinfo_stream = strtol(&sendline[1],NULL,0);
+/* include mod_unordered */
+               out_sz = strlen(sendline);
+               Sctp_sendmsg(sock_fd, sendline, out_sz, 
+                            to, tolen, 
+                            0,
+                            MSG_UNORDERED,
+                            sri.sinfo_stream,
+                            0, 0);
+/* end mod_unordered */
+               len = sizeof(peeraddr);
+               rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),
+                            (SA *)&peeraddr, &len,
+                            &sri,&msg_flags);
+               printf("From str:%d seq:%d (assoc:0x%x):",
+                      sri.sinfo_stream,sri.sinfo_ssn,
+                      (u_int)sri.sinfo_assoc_id);
+               printf("%.*s",rd_sz,recvline);
+       }
+}
diff --git a/sctp/sctp_strcli_un.lc b/sctp/sctp_strcli_un.lc
new file mode 100644 (file)
index 0000000..b30e016
--- /dev/null
@@ -0,0 +1,32 @@
+#include    "unp.h"##  1 ##src/sctp/sctp_strcli_un.c##
+
+void##  2 ##src/sctp/sctp_strcli_un.c##
+sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)##  3 ##src/sctp/sctp_strcli_un.c##
+{##  4 ##src/sctp/sctp_strcli_un.c##
+    struct sockaddr_in peeraddr;##  5 ##src/sctp/sctp_strcli_un.c##
+    struct sctp_sndrcvinfo sri;##  6 ##src/sctp/sctp_strcli_un.c##
+    char    sendline[MAXLINE], recvline[MAXLINE];##  7 ##src/sctp/sctp_strcli_un.c##
+    socklen_t len;##  8 ##src/sctp/sctp_strcli_un.c##
+    int     out_sz, rd_sz;##  9 ##src/sctp/sctp_strcli_un.c##
+    int     msg_flags;## 10 ##src/sctp/sctp_strcli_un.c##
+
+    bzero(&sri, sizeof(sri));## 11 ##src/sctp/sctp_strcli_un.c##
+    while (fgets(sendline, MAXLINE, fp) != NULL) {## 12 ##src/sctp/sctp_strcli_un.c##
+        if (sendline[0] != '[') {## 13 ##src/sctp/sctp_strcli_un.c##
+            printf("Error, line must be of the form '[streamnum]text'\n");## 14 ##src/sctp/sctp_strcli_un.c##
+            continue;## 15 ##src/sctp/sctp_strcli_un.c##
+        }## 16 ##src/sctp/sctp_strcli_un.c##
+        sri.sinfo_stream = strtol(&sendline[1], NULL, 0);## 17 ##src/sctp/sctp_strcli_un.c##
+        /* include mod_unordered */## 18 ##src/sctp/sctp_strcli_un.c##
+        out_sz = strlen(sendline);## 19 ##src/sctp/sctp_strcli_un.c##
+        Sctp_sendmsg(sock_fd, sendline, out_sz,## 20 ##src/sctp/sctp_strcli_un.c##
+                     to, tolen, 0, MSG_UNORDERED, sri.sinfo_stream, 0, 0);## 21 ##src/sctp/sctp_strcli_un.c##
+        /* end mod_unordered */## 22 ##src/sctp/sctp_strcli_un.c##
+        len = sizeof(peeraddr);## 23 ##src/sctp/sctp_strcli_un.c##
+        rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),## 24 ##src/sctp/sctp_strcli_un.c##
+                             (SA *) &peeraddr, &len, &sri, &msg_flags);## 25 ##src/sctp/sctp_strcli_un.c##
+        printf("From str:%d seq:%d (assoc:0x%x):",## 26 ##src/sctp/sctp_strcli_un.c##
+               sri.sinfo_stream, sri.sinfo_ssn, (u_int) sri.sinfo_assoc_id);## 27 ##src/sctp/sctp_strcli_un.c##
+        printf("%.*s", rd_sz, recvline);## 28 ##src/sctp/sctp_strcli_un.c##
+    }## 29 ##src/sctp/sctp_strcli_un.c##
+}## 30 ##src/sctp/sctp_strcli_un.c##
diff --git a/sctp/sctp_strcliecho.c b/sctp/sctp_strcliecho.c
new file mode 100644 (file)
index 0000000..fa015f5
--- /dev/null
@@ -0,0 +1,43 @@
+#include       "unp.h"
+
+#define        SCTP_MAXLINE    800
+
+void
+sctpstr_cli_echoall(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)
+{
+       struct sockaddr_in peeraddr;
+       struct sctp_sndrcvinfo sri;
+       char sendline[SCTP_MAXLINE], recvline[SCTP_MAXLINE];
+       socklen_t len;
+       int rd_sz,i,strsz;
+       int msg_flags;
+
+       bzero(sendline,sizeof(sendline));
+       bzero(&sri,sizeof(sri));
+       while (fgets(sendline, SCTP_MAXLINE - 9, fp) != NULL) {
+               strsz = strlen(sendline);
+               if(sendline[strsz-1] == '\n') {
+                       sendline[strsz-1] = '\0';
+                       strsz--;
+               }
+               for(i=0;i<SERV_MAX_SCTP_STRM;i++) {
+                       snprintf(sendline + strsz, sizeof(sendline) - strsz,
+                               ".msg.%d", i);
+                       Sctp_sendmsg(sock_fd, sendline, sizeof(sendline), 
+                                    to, tolen, 
+                                    0, 0,
+                                    i,
+                                    0, 0);
+               }
+               for(i=0;i<SERV_MAX_SCTP_STRM;i++) {
+                       len = sizeof(peeraddr);
+                       rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),
+                                    (SA *)&peeraddr, &len,
+                                    &sri,&msg_flags);
+                       printf("From str:%d seq:%d (assoc:0x%x):",
+                               sri.sinfo_stream,sri.sinfo_ssn,
+                               (u_int)sri.sinfo_assoc_id);
+                       printf("%.*s\n",rd_sz,recvline);
+               }
+       }
+}
diff --git a/sctp/sctp_strcliecho.lc b/sctp/sctp_strcliecho.lc
new file mode 100644 (file)
index 0000000..fdf1d21
--- /dev/null
@@ -0,0 +1,39 @@
+
+#define SCTP_MAXLINE    800##  1 ##src/sctp/sctp_strcliecho.c##
+
+void##  2 ##src/sctp/sctp_strcliecho.c##
+sctpstr_cli_echoall(FILE *fp, int sock_fd, struct sockaddr *to,##  3 ##src/sctp/sctp_strcliecho.c##
+                    socklen_t tolen)##  4 ##src/sctp/sctp_strcliecho.c##
+{##  5 ##src/sctp/sctp_strcliecho.c##
+    struct sockaddr_in peeraddr;##  6 ##src/sctp/sctp_strcliecho.c##
+    struct sctp_sndrcvinfo sri;##  7 ##src/sctp/sctp_strcliecho.c##
+    char    sendline[SCTP_MAXLINE], recvline[SCTP_MAXLINE];##  8 ##src/sctp/sctp_strcliecho.c##
+    socklen_t len;##  9 ##src/sctp/sctp_strcliecho.c##
+    int     rd_sz, i, strsz;## 10 ##src/sctp/sctp_strcliecho.c##
+    int     msg_flags;## 11 ##src/sctp/sctp_strcliecho.c##
+
+    bzero(sendline, sizeof(sendline));## 12 ##src/sctp/sctp_strcliecho.c##
+    bzero(&sri, sizeof(sri));## 13 ##src/sctp/sctp_strcliecho.c##
+    while (fgets(sendline, SCTP_MAXLINE - 9, fp) != NULL) {## 14 ##src/sctp/sctp_strcliecho.c##
+        strsz = strlen(sendline);## 15 ##src/sctp/sctp_strcliecho.c##
+        if (sendline[strsz - 1] == '\n') {## 16 ##src/sctp/sctp_strcliecho.c##
+            sendline[strsz - 1] = '\0';## 17 ##src/sctp/sctp_strcliecho.c##
+            strsz--;## 18 ##src/sctp/sctp_strcliecho.c##
+        }## 19 ##src/sctp/sctp_strcliecho.c##
+        for (i = 0; i < SERV_MAX_SCTP_STRM; i++) {## 20 ##src/sctp/sctp_strcliecho.c##
+            snprintf(sendline + strsz, sizeof(sendline) - strsz,## 21 ##src/sctp/sctp_strcliecho.c##
+                     ".msg.%d", i);## 22 ##src/sctp/sctp_strcliecho.c##
+            Sctp_sendmsg(sock_fd, sendline, sizeof(sendline),## 23 ##src/sctp/sctp_strcliecho.c##
+                         to, tolen, 0, 0, i, 0, 0);## 24 ##src/sctp/sctp_strcliecho.c##
+        }## 25 ##src/sctp/sctp_strcliecho.c##
+        for (i = 0; i < SERV_MAX_SCTP_STRM; i++) {## 26 ##src/sctp/sctp_strcliecho.c##
+            len = sizeof(peeraddr);## 27 ##src/sctp/sctp_strcliecho.c##
+            rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),## 28 ##src/sctp/sctp_strcliecho.c##
+                                 (SA *) &peeraddr, &len, &sri, &msg_flags);## 29 ##src/sctp/sctp_strcliecho.c##
+            printf("From str:%d seq:%d (assoc:0x%x):",## 30 ##src/sctp/sctp_strcliecho.c##
+                   sri.sinfo_stream, sri.sinfo_ssn,## 31 ##src/sctp/sctp_strcliecho.c##
+                   (u_int) sri.sinfo_assoc_id);## 32 ##src/sctp/sctp_strcliecho.c##
+            printf("%.*s\n", rd_sz, recvline);## 33 ##src/sctp/sctp_strcliecho.c##
+        }## 34 ##src/sctp/sctp_strcliecho.c##
+    }## 35 ##src/sctp/sctp_strcliecho.c##
+}## 36 ##src/sctp/sctp_strcliecho.c##
diff --git a/sctp/sctp_strcliecho2.c b/sctp/sctp_strcliecho2.c
new file mode 100644 (file)
index 0000000..f1d9a4b
--- /dev/null
@@ -0,0 +1,52 @@
+#include       "unp.h"
+
+#define        SCTP_MAXLINE    800
+
+void
+sctpstr_cli_echoall(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen)
+{
+       struct sockaddr_in peeraddr;
+       struct sctp_sndrcvinfo sri;
+       char sendline[SCTP_MAXLINE], recvline[SCTP_MAXLINE];
+       socklen_t len;
+       int rd_sz,i,strsz;
+       int msg_flags;
+
+       bzero(sendline,sizeof(sendline));
+       bzero(&sri,sizeof(sri));
+       while (fgets(sendline, SCTP_MAXLINE - 9, fp) != NULL) {
+               strsz = strlen(sendline);
+               if(sendline[strsz-1] == '\n') {
+                       sendline[strsz-1] = '\0';
+                       strsz--;
+               }
+/* include modified_echo */
+               for(i=0;i<SERV_MAX_SCTP_STRM;i++) {
+                       snprintf(sendline + strsz, sizeof(sendline) - strsz,
+                               ".msg.%d 1", i);
+                       Sctp_sendmsg(sock_fd, sendline, sizeof(sendline), 
+                                    to, tolen, 
+                                    0, 0,
+                                    i,
+                                    0, 0);
+                       snprintf(sendline + strsz, sizeof(sendline) - strsz,
+                               ".msg.%d 2", i);
+                       Sctp_sendmsg(sock_fd, sendline, sizeof(sendline), 
+                                    to, tolen, 
+                                    0, 0,
+                                    i,
+                                    0, 0);
+               }
+               for(i=0;i<SERV_MAX_SCTP_STRM*2;i++) {
+                       len = sizeof(peeraddr);
+/* end modified_echo */
+                       rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),
+                                    (SA *)&peeraddr, &len,
+                                    &sri,&msg_flags);
+                       printf("From str:%d seq:%d (assoc:0x%x):",
+                               sri.sinfo_stream,sri.sinfo_ssn,
+                               (u_int)sri.sinfo_assoc_id);
+                       printf("%.*s\n",rd_sz,recvline);
+               }
+       }
+}
diff --git a/sctp/sctp_strcliecho2.lc b/sctp/sctp_strcliecho2.lc
new file mode 100644 (file)
index 0000000..59a5735
--- /dev/null
@@ -0,0 +1,45 @@
+
+#define SCTP_MAXLINE    800##  1 ##src/sctp/sctp_strcliecho2.c##
+
+void##  2 ##src/sctp/sctp_strcliecho2.c##
+sctpstr_cli_echoall(FILE *fp, int sock_fd, struct sockaddr *to,##  3 ##src/sctp/sctp_strcliecho2.c##
+                    socklen_t tolen)##  4 ##src/sctp/sctp_strcliecho2.c##
+{##  5 ##src/sctp/sctp_strcliecho2.c##
+    struct sockaddr_in peeraddr;##  6 ##src/sctp/sctp_strcliecho2.c##
+    struct sctp_sndrcvinfo sri;##  7 ##src/sctp/sctp_strcliecho2.c##
+    char    sendline[SCTP_MAXLINE], recvline[SCTP_MAXLINE];##  8 ##src/sctp/sctp_strcliecho2.c##
+    socklen_t len;##  9 ##src/sctp/sctp_strcliecho2.c##
+    int     rd_sz, i, strsz;## 10 ##src/sctp/sctp_strcliecho2.c##
+    int     msg_flags;## 11 ##src/sctp/sctp_strcliecho2.c##
+
+    bzero(sendline, sizeof(sendline));## 12 ##src/sctp/sctp_strcliecho2.c##
+    bzero(&sri, sizeof(sri));## 13 ##src/sctp/sctp_strcliecho2.c##
+    while (fgets(sendline, SCTP_MAXLINE - 9, fp) != NULL) {## 14 ##src/sctp/sctp_strcliecho2.c##
+        strsz = strlen(sendline);## 15 ##src/sctp/sctp_strcliecho2.c##
+        if (sendline[strsz - 1] == '\n') {## 16 ##src/sctp/sctp_strcliecho2.c##
+            sendline[strsz - 1] = '\0';## 17 ##src/sctp/sctp_strcliecho2.c##
+            strsz--;## 18 ##src/sctp/sctp_strcliecho2.c##
+        }## 19 ##src/sctp/sctp_strcliecho2.c##
+        /* include modified_echo */## 20 ##src/sctp/sctp_strcliecho2.c##
+        for (i = 0; i < SERV_MAX_SCTP_STRM; i++) {## 21 ##src/sctp/sctp_strcliecho2.c##
+            snprintf(sendline + strsz, sizeof(sendline) - strsz,## 22 ##src/sctp/sctp_strcliecho2.c##
+                     ".msg.%d 1", i);## 23 ##src/sctp/sctp_strcliecho2.c##
+            Sctp_sendmsg(sock_fd, sendline, sizeof(sendline),## 24 ##src/sctp/sctp_strcliecho2.c##
+                         to, tolen, 0, 0, i, 0, 0);## 25 ##src/sctp/sctp_strcliecho2.c##
+            snprintf(sendline + strsz, sizeof(sendline) - strsz,## 26 ##src/sctp/sctp_strcliecho2.c##
+                     ".msg.%d 2", i);## 27 ##src/sctp/sctp_strcliecho2.c##
+            Sctp_sendmsg(sock_fd, sendline, sizeof(sendline),## 28 ##src/sctp/sctp_strcliecho2.c##
+                         to, tolen, 0, 0, i, 0, 0);## 29 ##src/sctp/sctp_strcliecho2.c##
+        }## 30 ##src/sctp/sctp_strcliecho2.c##
+        for (i = 0; i < SERV_MAX_SCTP_STRM * 2; i++) {## 31 ##src/sctp/sctp_strcliecho2.c##
+            len = sizeof(peeraddr);## 32 ##src/sctp/sctp_strcliecho2.c##
+            /* end modified_echo */## 33 ##src/sctp/sctp_strcliecho2.c##
+            rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline),## 34 ##src/sctp/sctp_strcliecho2.c##
+                                 (SA *) &peeraddr, &len, &sri, &msg_flags);## 35 ##src/sctp/sctp_strcliecho2.c##
+            printf("From str:%d seq:%d (assoc:0x%x):",## 36 ##src/sctp/sctp_strcliecho2.c##
+                   sri.sinfo_stream, sri.sinfo_ssn,## 37 ##src/sctp/sctp_strcliecho2.c##
+                   (u_int) sri.sinfo_assoc_id);## 38 ##src/sctp/sctp_strcliecho2.c##
+            printf("%.*s\n", rd_sz, recvline);## 39 ##src/sctp/sctp_strcliecho2.c##
+        }## 40 ##src/sctp/sctp_strcliecho2.c##
+    }## 41 ##src/sctp/sctp_strcliecho2.c##
+}## 42 ##src/sctp/sctp_strcliecho2.c##
diff --git a/sctp/sctp_wrapper.c b/sctp/sctp_wrapper.c
new file mode 100644 (file)
index 0000000..4c9e4c1
--- /dev/null
@@ -0,0 +1,42 @@
+#include       "unp.h"
+
+
+int
+Sctp_recvmsg(int s, void *msg, size_t len,
+            struct sockaddr *from, socklen_t *fromlen,
+            struct sctp_sndrcvinfo *sinfo,
+            int *msg_flags)
+{
+       int ret;
+       ret = sctp_recvmsg(s,msg,len,from,fromlen,sinfo,msg_flags);
+       if(ret < 0){
+               err_sys("sctp_recvmsg error");
+       }
+       return(ret);
+}
+
+
+int
+Sctp_sendmsg (int s, void *data, size_t len, struct sockaddr *to,
+             socklen_t tolen, uint32_t ppid, uint32_t flags,
+             uint16_t stream_no, uint32_t timetolive, uint32_t context)
+{
+       int ret;
+       ret = sctp_sendmsg(s,data,len,to,tolen,ppid,flags,stream_no,
+                         timetolive,context);
+       if(ret < 0){
+               err_sys("sctp_sendmsg error");
+       }
+       return(ret);
+}
+
+int
+Sctp_bindx(int sock_fd,struct sockaddr_storage *at,int num,int op)
+{
+       int ret;
+       ret = sctp_bindx(sock_fd,at,num,op);
+       if(ret < 0){
+               err_sys("sctp_bindx error");
+       }
+       return(ret);
+}
diff --git a/sctp/sctpclient01.c b/sctp/sctpclient01.c
new file mode 100644 (file)
index 0000000..d957aaf
--- /dev/null
@@ -0,0 +1,35 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int sock_fd;
+       struct sockaddr_in servaddr;
+       struct sctp_event_subscribe evnts;
+       int echo_to_all=0;
+
+       if(argc < 2)
+               err_quit("Missing host argument - use '%s host [echo]'\n",
+                      argv[0]);
+       if(argc > 2) {
+               printf("Echoing messages to all streams\n");
+               echo_to_all = 1;
+       }
+        sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       bzero(&evnts, sizeof(evnts));
+       evnts.sctp_data_io_event = 1;
+       Setsockopt(sock_fd,IPPROTO_SCTP, SCTP_EVENTS,
+                  &evnts, sizeof(evnts));
+       if(echo_to_all == 0)
+               sctpstr_cli(stdin,sock_fd,(SA *)&servaddr,sizeof(servaddr));
+       else
+               sctpstr_cli_echoall(stdin,sock_fd,(SA *)&servaddr,sizeof(servaddr));
+       Close(sock_fd);
+       return(0);
+}
diff --git a/sctp/sctpclient01.lc b/sctp/sctpclient01.lc
new file mode 100644 (file)
index 0000000..80c4b99
--- /dev/null
@@ -0,0 +1,37 @@
+#include    "unp.h"##  1 ##src/sctp/sctpclient01.c##
+
+int##  2 ##src/sctp/sctpclient01.c##
+main(int argc, char **argv)##  3 ##src/sctp/sctpclient01.c##
+{##  4 ##src/sctp/sctpclient01.c##
+    int     sock_fd;##  5 ##src/sctp/sctpclient01.c##
+    struct sockaddr_in servaddr;##  6 ##src/sctp/sctpclient01.c##
+    struct sctp_event_subscribe evnts;##  7 ##src/sctp/sctpclient01.c##
+    int     echo_to_all = 0;##  8 ##src/sctp/sctpclient01.c##
+
+    if (argc < 2)##  9 ##src/sctp/sctpclient01.c##
+        err_quit("Missing host argument - use '%s host [echo]'\n", argv[0]);## 10 ##src/sctp/sctpclient01.c##
+    if (argc > 2) {## 11 ##src/sctp/sctpclient01.c##
+        printf("Echoing messages to all streams\n");## 12 ##src/sctp/sctpclient01.c##
+        echo_to_all = 1;## 13 ##src/sctp/sctpclient01.c##
+    }## 14 ##src/sctp/sctpclient01.c##
+    sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 15 ##src/sctp/sctpclient01.c##
+    bzero(&servaddr, sizeof(servaddr));## 16 ##src/sctp/sctpclient01.c##
+    servaddr.sin_family = AF_INET;## 17 ##src/sctp/sctpclient01.c##
+#ifdef HAVE_SOCKADDR_SA_LEN## 18 ##src/sctp/sctpclient01.c##
+    servaddr.sin_len = sizeof(servaddr);## 19 ##src/sctp/sctpclient01.c##
+#endif## 20 ##src/sctp/sctpclient01.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 21 ##src/sctp/sctpclient01.c##
+    servaddr.sin_port = htons(SERV_PORT);## 22 ##src/sctp/sctpclient01.c##
+    Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);## 23 ##src/sctp/sctpclient01.c##
+
+    bzero(&evnts, sizeof(evnts));## 24 ##src/sctp/sctpclient01.c##
+    evnts.sctp_data_io_event = 1;## 25 ##src/sctp/sctpclient01.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 26 ##src/sctp/sctpclient01.c##
+    if (echo_to_all == 0)## 27 ##src/sctp/sctpclient01.c##
+        sctpstr_cli(stdin, sock_fd, (SA *) &servaddr, sizeof(servaddr));## 28 ##src/sctp/sctpclient01.c##
+    else## 29 ##src/sctp/sctpclient01.c##
+        sctpstr_cli_echoall(stdin, sock_fd, (SA *) &servaddr,## 30 ##src/sctp/sctpclient01.c##
+                            sizeof(servaddr));## 31 ##src/sctp/sctpclient01.c##
+    Close(sock_fd);## 32 ##src/sctp/sctpclient01.c##
+    return (0);## 33 ##src/sctp/sctpclient01.c##
+}## 34 ##src/sctp/sctpclient01.c##
diff --git a/sctp/sctpclient02.c b/sctp/sctpclient02.c
new file mode 100644 (file)
index 0000000..b55cd9d
--- /dev/null
@@ -0,0 +1,44 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int sock_fd;
+       struct sockaddr_in servaddr;
+       struct sctp_event_subscribe evnts;
+       int echo_to_all=0;
+       char byemsg[10];
+
+       if(argc < 2)
+               err_quit("Missing host argument - use '%s host [echo]'\n",
+                      argv[0]);
+       if(argc > 2) {
+               printf("Echoing messages to all streams\n");
+               echo_to_all = 1;
+       }
+        sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       bzero(&evnts, sizeof(evnts));
+       evnts.sctp_data_io_event = 1;
+       Setsockopt(sock_fd,IPPROTO_SCTP, SCTP_EVENTS,
+                  &evnts, sizeof(evnts));
+/* include modified_client02 */
+       if(echo_to_all == 0)
+               sctpstr_cli(stdin,sock_fd,(SA *)&servaddr,sizeof(servaddr));
+       else
+               sctpstr_cli_echoall(stdin,sock_fd,(SA *)&servaddr,sizeof(servaddr));
+       strcpy(byemsg,"goodbye");
+       Sctp_sendmsg(sock_fd, byemsg, strlen(byemsg), 
+                    (SA *)&servaddr, sizeof(servaddr), 
+                    0,
+                    MSG_ABORT,
+                    0, 0, 0);
+       Close(sock_fd);
+/* end modified_client02 */
+       return(0);
+}
diff --git a/sctp/sctpclient02.lc b/sctp/sctpclient02.lc
new file mode 100644 (file)
index 0000000..1f50b06
--- /dev/null
@@ -0,0 +1,42 @@
+
+int##  1 ##src/sctp/sctpclient02.c##
+main(int argc, char **argv)##  2 ##src/sctp/sctpclient02.c##
+{##  3 ##src/sctp/sctpclient02.c##
+    int     sock_fd;##  4 ##src/sctp/sctpclient02.c##
+    struct sockaddr_in servaddr;##  5 ##src/sctp/sctpclient02.c##
+    struct sctp_event_subscribe evnts;##  6 ##src/sctp/sctpclient02.c##
+    int     echo_to_all = 0;##  7 ##src/sctp/sctpclient02.c##
+    char    byemsg[10];##  8 ##src/sctp/sctpclient02.c##
+
+    if (argc < 2)##  9 ##src/sctp/sctpclient02.c##
+        err_quit("Missing host argument - use '%s host [echo]'\n", argv[0]);## 10 ##src/sctp/sctpclient02.c##
+    if (argc > 2) {## 11 ##src/sctp/sctpclient02.c##
+        printf("Echoing messages to all streams\n");## 12 ##src/sctp/sctpclient02.c##
+        echo_to_all = 1;## 13 ##src/sctp/sctpclient02.c##
+    }## 14 ##src/sctp/sctpclient02.c##
+    sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 15 ##src/sctp/sctpclient02.c##
+    bzero(&servaddr, sizeof(servaddr));## 16 ##src/sctp/sctpclient02.c##
+    servaddr.sin_family = AF_INET;## 17 ##src/sctp/sctpclient02.c##
+#ifdef HAVE_SOCKADDR_SA_LEN## 18 ##src/sctp/sctpclient02.c##
+    servaddr.sin_len = sizeof(servaddr);## 19 ##src/sctp/sctpclient02.c##
+#endif## 20 ##src/sctp/sctpclient02.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 21 ##src/sctp/sctpclient02.c##
+    servaddr.sin_port = htons(SERV_PORT);## 22 ##src/sctp/sctpclient02.c##
+    Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);## 23 ##src/sctp/sctpclient02.c##
+
+    bzero(&evnts, sizeof(evnts));## 24 ##src/sctp/sctpclient02.c##
+    evnts.sctp_data_io_event = 1;## 25 ##src/sctp/sctpclient02.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 26 ##src/sctp/sctpclient02.c##
+    /* include modified_client02 */## 27 ##src/sctp/sctpclient02.c##
+    if (echo_to_all == 0)## 28 ##src/sctp/sctpclient02.c##
+        sctpstr_cli(stdin, sock_fd, (SA *) &servaddr, sizeof(servaddr));## 29 ##src/sctp/sctpclient02.c##
+    else## 30 ##src/sctp/sctpclient02.c##
+        sctpstr_cli_echoall(stdin, sock_fd, (SA *) &servaddr,## 31 ##src/sctp/sctpclient02.c##
+                            sizeof(servaddr));## 32 ##src/sctp/sctpclient02.c##
+    strcpy(byemsg, "goodbye");## 33 ##src/sctp/sctpclient02.c##
+    Sctp_sendmsg(sock_fd, byemsg, strlen(byemsg),## 34 ##src/sctp/sctpclient02.c##
+                 (SA *) &servaddr, sizeof(servaddr), 0, MSG_ABORT, 0, 0, 0);## 35 ##src/sctp/sctpclient02.c##
+    Close(sock_fd);## 36 ##src/sctp/sctpclient02.c##
+    /* end modified_client02 */## 37 ##src/sctp/sctpclient02.c##
+    return (0);## 38 ##src/sctp/sctpclient02.c##
+}## 39 ##src/sctp/sctpclient02.c##
diff --git a/sctp/sctpclient04.c b/sctp/sctpclient04.c
new file mode 100644 (file)
index 0000000..205475f
--- /dev/null
@@ -0,0 +1,30 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int sock_fd;
+       struct sockaddr_in servaddr;
+       struct sctp_event_subscribe evnts;
+
+       if(argc != 2)
+               err_quit("Missing host argument - use '%s host'\n",
+                      argv[0]);
+        sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+/* include mod_client04 */
+       bzero(&evnts, sizeof(evnts));
+       evnts.sctp_data_io_event = 1;
+       evnts.sctp_association_event = 1;
+       Setsockopt(sock_fd,IPPROTO_SCTP, SCTP_EVENTS,
+                  &evnts, sizeof(evnts));
+
+       sctpstr_cli(stdin,sock_fd,(SA *)&servaddr,sizeof(servaddr));
+/* end mod_client04 */
+       close(sock_fd);
+       return(0);
+}
diff --git a/sctp/sctpclient04.lc b/sctp/sctpclient04.lc
new file mode 100644 (file)
index 0000000..282e765
--- /dev/null
@@ -0,0 +1,31 @@
+#include    "unp.h"##  1 ##src/sctp/sctpclient04.c##
+
+int##  2 ##src/sctp/sctpclient04.c##
+main(int argc, char **argv)##  3 ##src/sctp/sctpclient04.c##
+{##  4 ##src/sctp/sctpclient04.c##
+    int     sock_fd;##  5 ##src/sctp/sctpclient04.c##
+    struct sockaddr_in servaddr;##  6 ##src/sctp/sctpclient04.c##
+    struct sctp_event_subscribe evnts;##  7 ##src/sctp/sctpclient04.c##
+
+    if (argc != 2)##  8 ##src/sctp/sctpclient04.c##
+        err_quit("Missing host argument - use '%s host'\n", argv[0]);##  9 ##src/sctp/sctpclient04.c##
+    sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 10 ##src/sctp/sctpclient04.c##
+    bzero(&servaddr, sizeof(servaddr));## 11 ##src/sctp/sctpclient04.c##
+    servaddr.sin_family = AF_INET;## 12 ##src/sctp/sctpclient04.c##
+#ifdef HAVE_SOCKADDR_SA_LEN## 13 ##src/sctp/sctpclient04.c##
+    servaddr.sin_len = sizeof(servaddr);## 14 ##src/sctp/sctpclient04.c##
+#endif## 15 ##src/sctp/sctpclient04.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 16 ##src/sctp/sctpclient04.c##
+    servaddr.sin_port = htons(SERV_PORT);## 17 ##src/sctp/sctpclient04.c##
+    Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);## 18 ##src/sctp/sctpclient04.c##
+    /* include mod_client04 */## 19 ##src/sctp/sctpclient04.c##
+    bzero(&evnts, sizeof(evnts));## 20 ##src/sctp/sctpclient04.c##
+    evnts.sctp_data_io_event = 1;## 21 ##src/sctp/sctpclient04.c##
+    evnts.sctp_association_event = 1;## 22 ##src/sctp/sctpclient04.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 23 ##src/sctp/sctpclient04.c##
+
+    sctpstr_cli(stdin, sock_fd, (SA *) &servaddr, sizeof(servaddr));## 24 ##src/sctp/sctpclient04.c##
+    /* end mod_client04 */## 25 ##src/sctp/sctpclient04.c##
+    close(sock_fd);## 26 ##src/sctp/sctpclient04.c##
+    return (0);## 27 ##src/sctp/sctpclient04.c##
+}## 28 ##src/sctp/sctpclient04.c##
diff --git a/sctp/sctpserv01.c b/sctp/sctpserv01.c
new file mode 100644 (file)
index 0000000..54634e9
--- /dev/null
@@ -0,0 +1,48 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int sock_fd,msg_flags;
+       char readbuf[BUFFSIZE];
+       struct sockaddr_in servaddr, cliaddr;
+       struct sctp_sndrcvinfo sri;
+       struct sctp_event_subscribe evnts;
+       int stream_increment=1;
+       socklen_t len;
+       size_t rd_sz;
+
+       if (argc == 2)
+               stream_increment = atoi(argv[1]);
+        sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port = htons(SERV_PORT);
+
+       Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));
+       
+       bzero(&evnts, sizeof(evnts));
+       evnts.sctp_data_io_event = 1;
+       Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,
+                  &evnts, sizeof(evnts));
+
+       Listen(sock_fd, LISTENQ);
+       for ( ; ; ) {
+               len = sizeof(struct sockaddr_in);
+               rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),
+                            (SA *)&cliaddr, &len,
+                            &sri,&msg_flags);
+               if(stream_increment) {
+                       sri.sinfo_stream++;
+                       if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) 
+                               sri.sinfo_stream = 0;
+               }
+               Sctp_sendmsg(sock_fd, readbuf, rd_sz, 
+                            (SA *)&cliaddr, len,
+                            sri.sinfo_ppid,
+                            sri.sinfo_flags,
+                            sri.sinfo_stream,
+                            0, 0);
+       }
+}
diff --git a/sctp/sctpserv01.lc b/sctp/sctpserv01.lc
new file mode 100644 (file)
index 0000000..9c5a189
--- /dev/null
@@ -0,0 +1,48 @@
+#include    "unp.h"##  1 ##src/sctp/sctpserv01.c##
+
+int##  2 ##src/sctp/sctpserv01.c##
+main(int argc, char **argv)##  3 ##src/sctp/sctpserv01.c##
+{##  4 ##src/sctp/sctpserv01.c##
+    int     sock_fd, msg_flags;##  5 ##src/sctp/sctpserv01.c##
+    char    readbuf[BUFFSIZE];##  6 ##src/sctp/sctpserv01.c##
+    struct sockaddr_in servaddr, cliaddr;##  7 ##src/sctp/sctpserv01.c##
+    struct sctp_sndrcvinfo sri;##  8 ##src/sctp/sctpserv01.c##
+    struct sctp_event_subscribe evnts;##  9 ##src/sctp/sctpserv01.c##
+    int     stream_increment = 1;## 10 ##src/sctp/sctpserv01.c##
+    socklen_t len;## 11 ##src/sctp/sctpserv01.c##
+    size_t  rd_sz;## 12 ##src/sctp/sctpserv01.c##
+
+    if (argc == 2)## 13 ##src/sctp/sctpserv01.c##
+        stream_increment = atoi(argv[1]);## 14 ##src/sctp/sctpserv01.c##
+    sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 15 ##src/sctp/sctpserv01.c##
+    bzero(&servaddr, sizeof(servaddr));## 16 ##src/sctp/sctpserv01.c##
+    servaddr.sin_family = AF_INET;## 17 ##src/sctp/sctpserv01.c##
+#ifdef HAVE_SOCKADDR_SA_LEN## 18 ##src/sctp/sctpserv01.c##
+    servaddr.sin_len = sizeof(servaddr);## 19 ##src/sctp/sctpserv01.c##
+#endif## 20 ##src/sctp/sctpserv01.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 21 ##src/sctp/sctpserv01.c##
+    servaddr.sin_port = htons(SERV_PORT);## 22 ##src/sctp/sctpserv01.c##
+
+    Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 23 ##src/sctp/sctpserv01.c##
+
+    bzero(&evnts, sizeof(evnts));## 24 ##src/sctp/sctpserv01.c##
+    evnts.sctp_data_io_event = 1;## 25 ##src/sctp/sctpserv01.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 26 ##src/sctp/sctpserv01.c##
+
+    Listen(sock_fd, LISTENQ);## 27 ##src/sctp/sctpserv01.c##
+    for (;;) {## 28 ##src/sctp/sctpserv01.c##
+        len = sizeof(struct sockaddr_in);## 29 ##src/sctp/sctpserv01.c##
+        rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 30 ##src/sctp/sctpserv01.c##
+                             (SA *) &cliaddr, &len, &sri, &msg_flags);## 31 ##src/sctp/sctpserv01.c##
+        if (stream_increment) {## 32 ##src/sctp/sctpserv01.c##
+            sri.sinfo_stream++;## 33 ##src/sctp/sctpserv01.c##
+            if (sri.sinfo_stream >=## 34 ##src/sctp/sctpserv01.c##
+                sctp_get_no_strms(sock_fd, (SA *) &cliaddr, len))## 35 ##src/sctp/sctpserv01.c##
+                sri.sinfo_stream = 0;## 36 ##src/sctp/sctpserv01.c##
+        }## 37 ##src/sctp/sctpserv01.c##
+        Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 38 ##src/sctp/sctpserv01.c##
+                     (SA *) &cliaddr, len,## 39 ##src/sctp/sctpserv01.c##
+                     sri.sinfo_ppid,## 40 ##src/sctp/sctpserv01.c##
+                     sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 41 ##src/sctp/sctpserv01.c##
+    }## 42 ##src/sctp/sctpserv01.c##
+}## 43 ##src/sctp/sctpserv01.c##
diff --git a/sctp/sctpserv02.c b/sctp/sctpserv02.c
new file mode 100644 (file)
index 0000000..94b9f90
--- /dev/null
@@ -0,0 +1,55 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int sock_fd,msg_flags;
+       char readbuf[BUFFSIZE];
+       struct sockaddr_in servaddr, cliaddr;
+       struct sctp_sndrcvinfo sri;
+       struct sctp_event_subscribe evnts;
+       int stream_increment=1;
+       socklen_t len;
+       size_t rd_sz;
+       struct sctp_initmsg initm;
+
+/* include modified_sctpserv02 */
+       if (argc == 2)
+               stream_increment = atoi(argv[1]);
+        sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+       bzero(&initm,sizeof(initm));
+       initm.sinit_num_ostreams = SERV_MORE_STRMS_SCTP;
+       Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_INITMSG,
+                  &initm, sizeof(initm));
+/* end modified_sctpserv02 */
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port = htons(SERV_PORT);
+
+       Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));
+       
+       bzero(&evnts, sizeof(evnts));
+       evnts.sctp_data_io_event = 1;
+       Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,
+                  &evnts, sizeof(evnts));
+
+       Listen(sock_fd, LISTENQ);
+       for ( ; ; ) {
+               len = sizeof(struct sockaddr_in);
+               rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),
+                            (SA *)&cliaddr, &len,
+                            &sri,&msg_flags);
+               if(stream_increment) {
+                       sri.sinfo_stream++;
+                       if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) 
+                               sri.sinfo_stream = 0;
+               }
+               Sctp_sendmsg(sock_fd, readbuf, rd_sz, 
+                            (SA *)&cliaddr, len,
+                            sri.sinfo_ppid,
+                            sri.sinfo_flags,
+                            sri.sinfo_stream,
+                            0, 0);
+       }
+}
diff --git a/sctp/sctpserv02.lc b/sctp/sctpserv02.lc
new file mode 100644 (file)
index 0000000..a758cb8
--- /dev/null
@@ -0,0 +1,54 @@
+#include    "unp.h"##  1 ##src/sctp/sctpserv02.c##
+
+int##  2 ##src/sctp/sctpserv02.c##
+main(int argc, char **argv)##  3 ##src/sctp/sctpserv02.c##
+{##  4 ##src/sctp/sctpserv02.c##
+    int     sock_fd, msg_flags;##  5 ##src/sctp/sctpserv02.c##
+    char    readbuf[BUFFSIZE];##  6 ##src/sctp/sctpserv02.c##
+    struct sockaddr_in servaddr, cliaddr;##  7 ##src/sctp/sctpserv02.c##
+    struct sctp_sndrcvinfo sri;##  8 ##src/sctp/sctpserv02.c##
+    struct sctp_event_subscribe evnts;##  9 ##src/sctp/sctpserv02.c##
+    int     stream_increment = 1;## 10 ##src/sctp/sctpserv02.c##
+    socklen_t len;## 11 ##src/sctp/sctpserv02.c##
+    size_t  rd_sz;## 12 ##src/sctp/sctpserv02.c##
+    struct sctp_initmsg initm;## 13 ##src/sctp/sctpserv02.c##
+
+    /* include modified_sctpserv02 */## 14 ##src/sctp/sctpserv02.c##
+    if (argc == 2)## 15 ##src/sctp/sctpserv02.c##
+        stream_increment = atoi(argv[1]);## 16 ##src/sctp/sctpserv02.c##
+    sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 17 ##src/sctp/sctpserv02.c##
+    bzero(&initm, sizeof(initm));## 18 ##src/sctp/sctpserv02.c##
+    initm.sinit_num_ostreams = SERV_MORE_STRMS_SCTP;## 19 ##src/sctp/sctpserv02.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_INITMSG, &initm, sizeof(initm));## 20 ##src/sctp/sctpserv02.c##
+    /* end modified_sctpserv02 */## 21 ##src/sctp/sctpserv02.c##
+    bzero(&servaddr, sizeof(servaddr));## 22 ##src/sctp/sctpserv02.c##
+    servaddr.sin_family = AF_INET;## 23 ##src/sctp/sctpserv02.c##
+#ifdef HAVE_SOCKADDR_SA_LEN## 24 ##src/sctp/sctpserv02.c##
+    servaddr.sin_len = sizeof(servaddr);## 25 ##src/sctp/sctpserv02.c##
+#endif## 26 ##src/sctp/sctpserv02.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 27 ##src/sctp/sctpserv02.c##
+    servaddr.sin_port = htons(SERV_PORT);## 28 ##src/sctp/sctpserv02.c##
+
+    Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 29 ##src/sctp/sctpserv02.c##
+
+    bzero(&evnts, sizeof(evnts));## 30 ##src/sctp/sctpserv02.c##
+    evnts.sctp_data_io_event = 1;## 31 ##src/sctp/sctpserv02.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 32 ##src/sctp/sctpserv02.c##
+
+    Listen(sock_fd, LISTENQ);## 33 ##src/sctp/sctpserv02.c##
+    for (;;) {## 34 ##src/sctp/sctpserv02.c##
+        len = sizeof(struct sockaddr_in);## 35 ##src/sctp/sctpserv02.c##
+        rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 36 ##src/sctp/sctpserv02.c##
+                             (SA *) &cliaddr, &len, &sri, &msg_flags);## 37 ##src/sctp/sctpserv02.c##
+        if (stream_increment) {## 38 ##src/sctp/sctpserv02.c##
+            sri.sinfo_stream++;## 39 ##src/sctp/sctpserv02.c##
+            if (sri.sinfo_stream >=## 40 ##src/sctp/sctpserv02.c##
+                sctp_get_no_strms(sock_fd, (SA *) &cliaddr, len))## 41 ##src/sctp/sctpserv02.c##
+                sri.sinfo_stream = 0;## 42 ##src/sctp/sctpserv02.c##
+        }## 43 ##src/sctp/sctpserv02.c##
+        Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 44 ##src/sctp/sctpserv02.c##
+                     (SA *) &cliaddr, len,## 45 ##src/sctp/sctpserv02.c##
+                     sri.sinfo_ppid,## 46 ##src/sctp/sctpserv02.c##
+                     sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 47 ##src/sctp/sctpserv02.c##
+    }## 48 ##src/sctp/sctpserv02.c##
+}## 49 ##src/sctp/sctpserv02.c##
diff --git a/sctp/sctpserv03.c b/sctp/sctpserv03.c
new file mode 100644 (file)
index 0000000..f799af4
--- /dev/null
@@ -0,0 +1,50 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int sock_fd,msg_flags;
+       char readbuf[BUFFSIZE];
+       struct sockaddr_in servaddr, cliaddr;
+       struct sctp_sndrcvinfo sri;
+       struct sctp_event_subscribe evnts;
+       int stream_increment=1;
+       socklen_t len;
+       size_t rd_sz;
+
+       if (argc == 2)
+               stream_increment = atoi(argv[1]);
+        sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port = htons(SERV_PORT);
+
+       Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));
+       
+       bzero(&evnts, sizeof(evnts));
+       evnts.sctp_data_io_event = 1;
+       Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,
+                  &evnts, sizeof(evnts));
+
+       Listen(sock_fd, LISTENQ);
+/* include modified_sctpserv03 */
+       for ( ; ; ) {
+               len = sizeof(struct sockaddr_in);
+               rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),
+                            (SA *)&cliaddr, &len,
+                            &sri,&msg_flags);
+               if(stream_increment) {
+                       sri.sinfo_stream++;
+                       if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) 
+                               sri.sinfo_stream = 0;
+               }
+               Sctp_sendmsg(sock_fd, readbuf, rd_sz, 
+                            (SA *)&cliaddr, len,
+                            sri.sinfo_ppid,
+                            (sri.sinfo_flags|MSG_EOF),
+                            sri.sinfo_stream,
+                            0, 0);
+       }
+/* end modified_sctpserv03 */
+}
diff --git a/sctp/sctpserv03.lc b/sctp/sctpserv03.lc
new file mode 100644 (file)
index 0000000..e791db1
--- /dev/null
@@ -0,0 +1,50 @@
+#include    "unp.h"##  1 ##src/sctp/sctpserv03.c##
+
+int##  2 ##src/sctp/sctpserv03.c##
+main(int argc, char **argv)##  3 ##src/sctp/sctpserv03.c##
+{##  4 ##src/sctp/sctpserv03.c##
+    int     sock_fd, msg_flags;##  5 ##src/sctp/sctpserv03.c##
+    char    readbuf[BUFFSIZE];##  6 ##src/sctp/sctpserv03.c##
+    struct sockaddr_in servaddr, cliaddr;##  7 ##src/sctp/sctpserv03.c##
+    struct sctp_sndrcvinfo sri;##  8 ##src/sctp/sctpserv03.c##
+    struct sctp_event_subscribe evnts;##  9 ##src/sctp/sctpserv03.c##
+    int     stream_increment = 1;## 10 ##src/sctp/sctpserv03.c##
+    socklen_t len;## 11 ##src/sctp/sctpserv03.c##
+    size_t  rd_sz;## 12 ##src/sctp/sctpserv03.c##
+
+    if (argc == 2)## 13 ##src/sctp/sctpserv03.c##
+        stream_increment = atoi(argv[1]);## 14 ##src/sctp/sctpserv03.c##
+    sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 15 ##src/sctp/sctpserv03.c##
+    bzero(&servaddr, sizeof(servaddr));## 16 ##src/sctp/sctpserv03.c##
+    servaddr.sin_family = AF_INET;## 17 ##src/sctp/sctpserv03.c##
+#ifdef HAVE_SOCKADDR_SA_LEN## 18 ##src/sctp/sctpserv03.c##
+    servaddr.sin_len = sizeof(servaddr);## 19 ##src/sctp/sctpserv03.c##
+#endif## 20 ##src/sctp/sctpserv03.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 21 ##src/sctp/sctpserv03.c##
+    servaddr.sin_port = htons(SERV_PORT);## 22 ##src/sctp/sctpserv03.c##
+
+    Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 23 ##src/sctp/sctpserv03.c##
+
+    bzero(&evnts, sizeof(evnts));## 24 ##src/sctp/sctpserv03.c##
+    evnts.sctp_data_io_event = 1;## 25 ##src/sctp/sctpserv03.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 26 ##src/sctp/sctpserv03.c##
+
+    Listen(sock_fd, LISTENQ);## 27 ##src/sctp/sctpserv03.c##
+    /* include modified_sctpserv03 */## 28 ##src/sctp/sctpserv03.c##
+    for (;;) {## 29 ##src/sctp/sctpserv03.c##
+        len = sizeof(struct sockaddr_in);## 30 ##src/sctp/sctpserv03.c##
+        rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 31 ##src/sctp/sctpserv03.c##
+                             (SA *) &cliaddr, &len, &sri, &msg_flags);## 32 ##src/sctp/sctpserv03.c##
+        if (stream_increment) {## 33 ##src/sctp/sctpserv03.c##
+            sri.sinfo_stream++;## 34 ##src/sctp/sctpserv03.c##
+            if (sri.sinfo_stream >=## 35 ##src/sctp/sctpserv03.c##
+                sctp_get_no_strms(sock_fd, (SA *) &cliaddr, len))## 36 ##src/sctp/sctpserv03.c##
+                sri.sinfo_stream = 0;## 37 ##src/sctp/sctpserv03.c##
+        }## 38 ##src/sctp/sctpserv03.c##
+        Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 39 ##src/sctp/sctpserv03.c##
+                     (SA *) &cliaddr, len,## 40 ##src/sctp/sctpserv03.c##
+                     sri.sinfo_ppid,## 41 ##src/sctp/sctpserv03.c##
+                     (sri.sinfo_flags | MSG_EOF), sri.sinfo_stream, 0, 0);## 42 ##src/sctp/sctpserv03.c##
+    }## 43 ##src/sctp/sctpserv03.c##
+    /* end modified_sctpserv03 */## 44 ##src/sctp/sctpserv03.c##
+}## 45 ##src/sctp/sctpserv03.c##
diff --git a/sctp/sctpserv04.c b/sctp/sctpserv04.c
new file mode 100644 (file)
index 0000000..0439595
--- /dev/null
@@ -0,0 +1,54 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int sock_fd,msg_flags;
+       char readbuf[BUFFSIZE];
+       struct sockaddr_in servaddr, cliaddr;
+       struct sctp_sndrcvinfo sri;
+       struct sctp_event_subscribe evnts;
+       int stream_increment=1;
+       int close_time;
+       socklen_t len;
+       size_t rd_sz;
+
+/* include mod_serv04 */
+       if (argc == 2)
+               stream_increment = atoi(argv[1]);
+        sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+       close_time = 120;
+       Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_AUTOCLOSE,
+                  &close_time, sizeof(close_time));
+       
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port = htons(SERV_PORT);
+/* end mod_serv04 */
+       Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));
+       
+       bzero(&evnts, sizeof(evnts));
+       evnts.sctp_data_io_event = 1;
+       Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,
+                  &evnts, sizeof(evnts));
+
+       Listen(sock_fd, LISTENQ);
+       for ( ; ; ) {
+               len = sizeof(struct sockaddr_in);
+               rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),
+                            (SA *)&cliaddr, &len,
+                            &sri,&msg_flags);
+               if(stream_increment) {
+                       sri.sinfo_stream++;
+                       if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) 
+                               sri.sinfo_stream = 0;
+               }
+               Sctp_sendmsg(sock_fd, readbuf, rd_sz, 
+                            (SA *)&cliaddr, len,
+                            sri.sinfo_ppid,
+                            sri.sinfo_flags,
+                            sri.sinfo_stream,
+                            0, 0);
+       }
+}
diff --git a/sctp/sctpserv04.lc b/sctp/sctpserv04.lc
new file mode 100644 (file)
index 0000000..72a5359
--- /dev/null
@@ -0,0 +1,54 @@
+#include    "unp.h"##  1 ##src/sctp/sctpserv04.c##
+
+int##  2 ##src/sctp/sctpserv04.c##
+main(int argc, char **argv)##  3 ##src/sctp/sctpserv04.c##
+{##  4 ##src/sctp/sctpserv04.c##
+    int     sock_fd, msg_flags;##  5 ##src/sctp/sctpserv04.c##
+    char    readbuf[BUFFSIZE];##  6 ##src/sctp/sctpserv04.c##
+    struct sockaddr_in servaddr, cliaddr;##  7 ##src/sctp/sctpserv04.c##
+    struct sctp_sndrcvinfo sri;##  8 ##src/sctp/sctpserv04.c##
+    struct sctp_event_subscribe evnts;##  9 ##src/sctp/sctpserv04.c##
+    int     stream_increment = 1;## 10 ##src/sctp/sctpserv04.c##
+    int     close_time;## 11 ##src/sctp/sctpserv04.c##
+    socklen_t len;## 12 ##src/sctp/sctpserv04.c##
+    size_t  rd_sz;## 13 ##src/sctp/sctpserv04.c##
+
+    /* include mod_serv04 */## 14 ##src/sctp/sctpserv04.c##
+    if (argc == 2)## 15 ##src/sctp/sctpserv04.c##
+        stream_increment = atoi(argv[1]);## 16 ##src/sctp/sctpserv04.c##
+    sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 17 ##src/sctp/sctpserv04.c##
+    close_time = 120;## 18 ##src/sctp/sctpserv04.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_AUTOCLOSE,## 19 ##src/sctp/sctpserv04.c##
+               &close_time, sizeof(close_time));## 20 ##src/sctp/sctpserv04.c##
+
+    bzero(&servaddr, sizeof(servaddr));## 21 ##src/sctp/sctpserv04.c##
+    servaddr.sin_family = AF_INET;## 22 ##src/sctp/sctpserv04.c##
+#ifdef HAVE_SOCKADDR_SA_LEN## 23 ##src/sctp/sctpserv04.c##
+    servaddr.sin_len = sizeof(servaddr);## 24 ##src/sctp/sctpserv04.c##
+#endif## 25 ##src/sctp/sctpserv04.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 26 ##src/sctp/sctpserv04.c##
+    servaddr.sin_port = htons(SERV_PORT);## 27 ##src/sctp/sctpserv04.c##
+    /* end mod_serv04 */## 28 ##src/sctp/sctpserv04.c##
+    Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 29 ##src/sctp/sctpserv04.c##
+
+    bzero(&evnts, sizeof(evnts));## 30 ##src/sctp/sctpserv04.c##
+    evnts.sctp_data_io_event = 1;## 31 ##src/sctp/sctpserv04.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 32 ##src/sctp/sctpserv04.c##
+
+    Listen(sock_fd, LISTENQ);## 33 ##src/sctp/sctpserv04.c##
+    for (;;) {## 34 ##src/sctp/sctpserv04.c##
+        len = sizeof(struct sockaddr_in);## 35 ##src/sctp/sctpserv04.c##
+        rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 36 ##src/sctp/sctpserv04.c##
+                             (SA *) &cliaddr, &len, &sri, &msg_flags);## 37 ##src/sctp/sctpserv04.c##
+        if (stream_increment) {## 38 ##src/sctp/sctpserv04.c##
+            sri.sinfo_stream++;## 39 ##src/sctp/sctpserv04.c##
+            if (sri.sinfo_stream >=## 40 ##src/sctp/sctpserv04.c##
+                sctp_get_no_strms(sock_fd, (SA *) &cliaddr, len))## 41 ##src/sctp/sctpserv04.c##
+                sri.sinfo_stream = 0;## 42 ##src/sctp/sctpserv04.c##
+        }## 43 ##src/sctp/sctpserv04.c##
+        Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 44 ##src/sctp/sctpserv04.c##
+                     (SA *) &cliaddr, len,## 45 ##src/sctp/sctpserv04.c##
+                     sri.sinfo_ppid,## 46 ##src/sctp/sctpserv04.c##
+                     sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 47 ##src/sctp/sctpserv04.c##
+    }## 48 ##src/sctp/sctpserv04.c##
+}## 49 ##src/sctp/sctpserv04.c##
diff --git a/sctp/sctpserv05.c b/sctp/sctpserv05.c
new file mode 100644 (file)
index 0000000..9ad38b2
--- /dev/null
@@ -0,0 +1,54 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       uint8_t *readbuf;
+       int sock_fd,msg_flags;
+       struct sockaddr_in servaddr, cliaddr;
+       struct sctp_sndrcvinfo sri;
+       struct sctp_event_subscribe evnts;
+       int stream_increment=1;
+       socklen_t len;
+       size_t rd_sz;
+
+       if (argc == 2)
+               stream_increment = atoi(argv[1]);
+        sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port = htons(SERV_PORT);
+
+       Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));
+       
+       bzero(&evnts, sizeof(evnts));
+       evnts.sctp_data_io_event = 1;
+       Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,
+                  &evnts, sizeof(evnts));
+
+       Listen(sock_fd, LISTENQ);
+       rd_sz = 0;
+/* include mod_serv05 */
+       for ( ; ; ) {
+               len = sizeof(struct sockaddr_in);
+               bzero(&sri,sizeof(sri));
+               readbuf = pdapi_recvmsg(sock_fd, &rd_sz,
+                                       (SA *)&cliaddr, &len,
+                                       &sri,&msg_flags);
+               if(readbuf == NULL)
+                  continue;
+/* end mod_serv05 */
+               if(stream_increment) {
+                       sri.sinfo_stream++;
+                       if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) 
+                               sri.sinfo_stream = 0;
+               }
+               Sctp_sendmsg(sock_fd, readbuf, rd_sz, 
+                            (SA *)&cliaddr, len,
+                            sri.sinfo_ppid,
+                            sri.sinfo_flags,
+                            sri.sinfo_stream,
+                            0, 0);
+       }
+}
diff --git a/sctp/sctpserv05.lc b/sctp/sctpserv05.lc
new file mode 100644 (file)
index 0000000..e68f6fb
--- /dev/null
@@ -0,0 +1,54 @@
+#include    "unp.h"##  1 ##src/sctp/sctpserv05.c##
+
+int##  2 ##src/sctp/sctpserv05.c##
+main(int argc, char **argv)##  3 ##src/sctp/sctpserv05.c##
+{##  4 ##src/sctp/sctpserv05.c##
+    uint8_t *readbuf;##  5 ##src/sctp/sctpserv05.c##
+    int     sock_fd, msg_flags;##  6 ##src/sctp/sctpserv05.c##
+    struct sockaddr_in servaddr, cliaddr;##  7 ##src/sctp/sctpserv05.c##
+    struct sctp_sndrcvinfo sri;##  8 ##src/sctp/sctpserv05.c##
+    struct sctp_event_subscribe evnts;##  9 ##src/sctp/sctpserv05.c##
+    int     stream_increment = 1;## 10 ##src/sctp/sctpserv05.c##
+    socklen_t len;## 11 ##src/sctp/sctpserv05.c##
+    size_t  rd_sz;## 12 ##src/sctp/sctpserv05.c##
+
+    if (argc == 2)## 13 ##src/sctp/sctpserv05.c##
+        stream_increment = atoi(argv[1]);## 14 ##src/sctp/sctpserv05.c##
+    sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 15 ##src/sctp/sctpserv05.c##
+    bzero(&servaddr, sizeof(servaddr));## 16 ##src/sctp/sctpserv05.c##
+    servaddr.sin_family = AF_INET;## 17 ##src/sctp/sctpserv05.c##
+#ifdef HAVE_SOCKADDR_SA_LEN## 18 ##src/sctp/sctpserv05.c##
+    servaddr.sin_len = sizeof(servaddr);## 19 ##src/sctp/sctpserv05.c##
+#endif## 20 ##src/sctp/sctpserv05.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 21 ##src/sctp/sctpserv05.c##
+    servaddr.sin_port = htons(SERV_PORT);## 22 ##src/sctp/sctpserv05.c##
+
+    Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 23 ##src/sctp/sctpserv05.c##
+
+    bzero(&evnts, sizeof(evnts));## 24 ##src/sctp/sctpserv05.c##
+    evnts.sctp_data_io_event = 1;## 25 ##src/sctp/sctpserv05.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 26 ##src/sctp/sctpserv05.c##
+
+    Listen(sock_fd, LISTENQ);## 27 ##src/sctp/sctpserv05.c##
+    rd_sz = 0;## 28 ##src/sctp/sctpserv05.c##
+    /* include mod_serv05 */## 29 ##src/sctp/sctpserv05.c##
+    for (;;) {## 30 ##src/sctp/sctpserv05.c##
+        len = sizeof(struct sockaddr_in);## 31 ##src/sctp/sctpserv05.c##
+        bzero(&sri, sizeof(sri));## 32 ##src/sctp/sctpserv05.c##
+        readbuf = pdapi_recvmsg(sock_fd, &rd_sz,## 33 ##src/sctp/sctpserv05.c##
+                                (SA *) &cliaddr, &len, &sri, &msg_flags);## 34 ##src/sctp/sctpserv05.c##
+        if (readbuf == NULL)## 35 ##src/sctp/sctpserv05.c##
+            continue;## 36 ##src/sctp/sctpserv05.c##
+        /* end mod_serv05 */## 37 ##src/sctp/sctpserv05.c##
+        if (stream_increment) {## 38 ##src/sctp/sctpserv05.c##
+            sri.sinfo_stream++;## 39 ##src/sctp/sctpserv05.c##
+            if (sri.sinfo_stream >=## 40 ##src/sctp/sctpserv05.c##
+                sctp_get_no_strms(sock_fd, (SA *) &cliaddr, len))## 41 ##src/sctp/sctpserv05.c##
+                sri.sinfo_stream = 0;## 42 ##src/sctp/sctpserv05.c##
+        }## 43 ##src/sctp/sctpserv05.c##
+        Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 44 ##src/sctp/sctpserv05.c##
+                     (SA *) &cliaddr, len,## 45 ##src/sctp/sctpserv05.c##
+                     sri.sinfo_ppid,## 46 ##src/sctp/sctpserv05.c##
+                     sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 47 ##src/sctp/sctpserv05.c##
+    }## 48 ##src/sctp/sctpserv05.c##
+}## 49 ##src/sctp/sctpserv05.c##
diff --git a/sctp/sctpserv06.c b/sctp/sctpserv06.c
new file mode 100644 (file)
index 0000000..6fe2660
--- /dev/null
@@ -0,0 +1,61 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int sock_fd,msg_flags;
+       char readbuf[BUFFSIZE];
+       struct sockaddr_in servaddr, cliaddr;
+       struct sctp_sndrcvinfo sri;
+       struct sctp_event_subscribe evnts;
+       int stream_increment=1;
+       socklen_t len;
+       size_t rd_sz;
+
+       if (argc == 2)
+               stream_increment = atoi(argv[1]);
+        sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port = htons(SERV_PORT);
+
+       Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));
+       
+/* include mod_serv06 */
+       bzero(&evnts, sizeof(evnts));
+       evnts.sctp_data_io_event = 1;
+       evnts.sctp_association_event = 1;
+       evnts.sctp_address_event = 1;
+       evnts.sctp_send_failure_event = 1;
+       evnts.sctp_peer_error_event = 1;
+       evnts.sctp_shutdown_event = 1;
+       evnts.sctp_partial_delivery_event = 1;
+       evnts.sctp_adaption_layer_event = 1;
+       Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,
+                  &evnts, sizeof(evnts));
+
+       Listen(sock_fd, LISTENQ);
+       for ( ; ; ) {
+               len = sizeof(struct sockaddr_in);
+               rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),
+                            (SA *)&cliaddr, &len,
+                            &sri,&msg_flags);
+               if(msg_flags & MSG_NOTIFICATION) {
+                       print_notification(readbuf);
+                       continue;
+               }
+/* end mod_serv06 */
+               if(stream_increment) {
+                       sri.sinfo_stream++;
+                       if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) 
+                               sri.sinfo_stream = 0;
+               }
+               Sctp_sendmsg(sock_fd, readbuf, rd_sz, 
+                            (SA *)&cliaddr, len,
+                            sri.sinfo_ppid,
+                            sri.sinfo_flags,
+                            sri.sinfo_stream,
+                            0, 0);
+       }
+}
diff --git a/sctp/sctpserv06.lc b/sctp/sctpserv06.lc
new file mode 100644 (file)
index 0000000..c0ec200
--- /dev/null
@@ -0,0 +1,61 @@
+#include    "unp.h"##  1 ##src/sctp/sctpserv06.c##
+
+int##  2 ##src/sctp/sctpserv06.c##
+main(int argc, char **argv)##  3 ##src/sctp/sctpserv06.c##
+{##  4 ##src/sctp/sctpserv06.c##
+    int     sock_fd, msg_flags;##  5 ##src/sctp/sctpserv06.c##
+    char    readbuf[BUFFSIZE];##  6 ##src/sctp/sctpserv06.c##
+    struct sockaddr_in servaddr, cliaddr;##  7 ##src/sctp/sctpserv06.c##
+    struct sctp_sndrcvinfo sri;##  8 ##src/sctp/sctpserv06.c##
+    struct sctp_event_subscribe evnts;##  9 ##src/sctp/sctpserv06.c##
+    int     stream_increment = 1;## 10 ##src/sctp/sctpserv06.c##
+    socklen_t len;## 11 ##src/sctp/sctpserv06.c##
+    size_t  rd_sz;## 12 ##src/sctp/sctpserv06.c##
+
+    if (argc == 2)## 13 ##src/sctp/sctpserv06.c##
+        stream_increment = atoi(argv[1]);## 14 ##src/sctp/sctpserv06.c##
+    sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 15 ##src/sctp/sctpserv06.c##
+    bzero(&servaddr, sizeof(servaddr));## 16 ##src/sctp/sctpserv06.c##
+    servaddr.sin_family = AF_INET;## 17 ##src/sctp/sctpserv06.c##
+#ifdef HAVE_SOCKADDR_SA_LEN## 18 ##src/sctp/sctpserv06.c##
+    servaddr.sin_len = sizeof(servaddr);## 19 ##src/sctp/sctpserv06.c##
+#endif## 20 ##src/sctp/sctpserv06.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 21 ##src/sctp/sctpserv06.c##
+    servaddr.sin_port = htons(SERV_PORT);## 22 ##src/sctp/sctpserv06.c##
+
+    Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 23 ##src/sctp/sctpserv06.c##
+
+    /* include mod_serv06 */## 24 ##src/sctp/sctpserv06.c##
+    bzero(&evnts, sizeof(evnts));## 25 ##src/sctp/sctpserv06.c##
+    evnts.sctp_data_io_event = 1;## 26 ##src/sctp/sctpserv06.c##
+    evnts.sctp_association_event = 1;## 27 ##src/sctp/sctpserv06.c##
+    evnts.sctp_address_event = 1;## 28 ##src/sctp/sctpserv06.c##
+    evnts.sctp_send_failure_event = 1;## 29 ##src/sctp/sctpserv06.c##
+    evnts.sctp_peer_error_event = 1;## 30 ##src/sctp/sctpserv06.c##
+    evnts.sctp_shutdown_event = 1;## 31 ##src/sctp/sctpserv06.c##
+    evnts.sctp_partial_delivery_event = 1;## 32 ##src/sctp/sctpserv06.c##
+    evnts.sctp_adaption_layer_event = 1;## 33 ##src/sctp/sctpserv06.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 34 ##src/sctp/sctpserv06.c##
+
+    Listen(sock_fd, LISTENQ);## 35 ##src/sctp/sctpserv06.c##
+    for (;;) {## 36 ##src/sctp/sctpserv06.c##
+        len = sizeof(struct sockaddr_in);## 37 ##src/sctp/sctpserv06.c##
+        rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 38 ##src/sctp/sctpserv06.c##
+                             (SA *) &cliaddr, &len, &sri, &msg_flags);## 39 ##src/sctp/sctpserv06.c##
+        if (msg_flags & MSG_NOTIFICATION) {## 40 ##src/sctp/sctpserv06.c##
+            print_notification(readbuf);## 41 ##src/sctp/sctpserv06.c##
+            continue;## 42 ##src/sctp/sctpserv06.c##
+        }## 43 ##src/sctp/sctpserv06.c##
+        /* end mod_serv06 */## 44 ##src/sctp/sctpserv06.c##
+        if (stream_increment) {## 45 ##src/sctp/sctpserv06.c##
+            sri.sinfo_stream++;## 46 ##src/sctp/sctpserv06.c##
+            if (sri.sinfo_stream >=## 47 ##src/sctp/sctpserv06.c##
+                sctp_get_no_strms(sock_fd, (SA *) &cliaddr, len))## 48 ##src/sctp/sctpserv06.c##
+                sri.sinfo_stream = 0;## 49 ##src/sctp/sctpserv06.c##
+        }## 50 ##src/sctp/sctpserv06.c##
+        Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 51 ##src/sctp/sctpserv06.c##
+                     (SA *) &cliaddr, len,## 52 ##src/sctp/sctpserv06.c##
+                     sri.sinfo_ppid,## 53 ##src/sctp/sctpserv06.c##
+                     sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 54 ##src/sctp/sctpserv06.c##
+    }## 55 ##src/sctp/sctpserv06.c##
+}## 56 ##src/sctp/sctpserv06.c##
diff --git a/sctp/sctpserv07.c b/sctp/sctpserv07.c
new file mode 100644 (file)
index 0000000..f8bcb69
--- /dev/null
@@ -0,0 +1,54 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int sock_fd,msg_flags;
+       char readbuf[BUFFSIZE];
+       struct sockaddr_in cliaddr;
+       struct sctp_sndrcvinfo sri;
+       struct sctp_event_subscribe evnts;
+       socklen_t len;
+       size_t rd_sz;
+/* include mod_serv07 */
+       if(argc < 2)
+               err_quit("Error, use %s [list of addresses to bind]\n",
+                      argv[0]);
+        sock_fd = Socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP);
+
+       if(sctp_bind_arg_list(sock_fd, argv + 1, argc - 1))
+               err_sys("Can't bind the address set");
+
+       bzero(&evnts, sizeof(evnts));
+       evnts.sctp_data_io_event = 1;
+/* end mod_serv07 */
+       evnts.sctp_association_event = 1;
+       evnts.sctp_address_event = 1;
+       evnts.sctp_send_failure_event = 1;
+       evnts.sctp_peer_error_event = 1;
+       evnts.sctp_shutdown_event = 1;
+       evnts.sctp_partial_delivery_event = 1;
+       evnts.sctp_adaption_layer_event = 1;
+       Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,
+                  &evnts, sizeof(evnts));
+
+       Listen(sock_fd, LISTENQ);
+
+       for ( ; ; ) {
+               len = sizeof(struct sockaddr_in);
+               rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),
+                            (SA *)&cliaddr, &len,
+                            &sri,&msg_flags);
+               if(msg_flags & MSG_NOTIFICATION) {
+                       print_notification(readbuf);
+                       continue;
+               }
+               Sctp_sendmsg(sock_fd, readbuf, rd_sz, 
+                            (SA *)&cliaddr, len,
+                            sri.sinfo_ppid,
+                            sri.sinfo_flags,
+                            sri.sinfo_stream,
+                            0, 0);
+       }
+       
+}
diff --git a/sctp/sctpserv07.lc b/sctp/sctpserv07.lc
new file mode 100644 (file)
index 0000000..d636fa9
--- /dev/null
@@ -0,0 +1,48 @@
+
+int##  1 ##src/sctp/sctpserv07.c##
+main(int argc, char **argv)##  2 ##src/sctp/sctpserv07.c##
+{##  3 ##src/sctp/sctpserv07.c##
+    int     sock_fd, msg_flags;##  4 ##src/sctp/sctpserv07.c##
+    char    readbuf[BUFFSIZE];##  5 ##src/sctp/sctpserv07.c##
+    struct sockaddr_in cliaddr;##  6 ##src/sctp/sctpserv07.c##
+    struct sctp_sndrcvinfo sri;##  7 ##src/sctp/sctpserv07.c##
+    struct sctp_event_subscribe evnts;##  8 ##src/sctp/sctpserv07.c##
+    socklen_t len;##  9 ##src/sctp/sctpserv07.c##
+    size_t  rd_sz;## 10 ##src/sctp/sctpserv07.c##
+    /* include mod_serv07 */## 11 ##src/sctp/sctpserv07.c##
+    if (argc < 2)## 12 ##src/sctp/sctpserv07.c##
+        err_quit("Error, use %s [list of addresses to bind]\n", argv[0]);## 13 ##src/sctp/sctpserv07.c##
+    sock_fd = Socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP);## 14 ##src/sctp/sctpserv07.c##
+
+    if (sctp_bind_arg_list(sock_fd, argv + 1, argc - 1))## 15 ##src/sctp/sctpserv07.c##
+        err_sys("Can't bind the address set");## 16 ##src/sctp/sctpserv07.c##
+
+    bzero(&evnts, sizeof(evnts));## 17 ##src/sctp/sctpserv07.c##
+    evnts.sctp_data_io_event = 1;## 18 ##src/sctp/sctpserv07.c##
+    /* end mod_serv07 */## 19 ##src/sctp/sctpserv07.c##
+    evnts.sctp_association_event = 1;## 20 ##src/sctp/sctpserv07.c##
+    evnts.sctp_address_event = 1;## 21 ##src/sctp/sctpserv07.c##
+    evnts.sctp_send_failure_event = 1;## 22 ##src/sctp/sctpserv07.c##
+    evnts.sctp_peer_error_event = 1;## 23 ##src/sctp/sctpserv07.c##
+    evnts.sctp_shutdown_event = 1;## 24 ##src/sctp/sctpserv07.c##
+    evnts.sctp_partial_delivery_event = 1;## 25 ##src/sctp/sctpserv07.c##
+    evnts.sctp_adaption_layer_event = 1;## 26 ##src/sctp/sctpserv07.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 27 ##src/sctp/sctpserv07.c##
+
+    Listen(sock_fd, LISTENQ);## 28 ##src/sctp/sctpserv07.c##
+
+    for (;;) {## 29 ##src/sctp/sctpserv07.c##
+        len = sizeof(struct sockaddr_in);## 30 ##src/sctp/sctpserv07.c##
+        rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 31 ##src/sctp/sctpserv07.c##
+                             (SA *) &cliaddr, &len, &sri, &msg_flags);## 32 ##src/sctp/sctpserv07.c##
+        if (msg_flags & MSG_NOTIFICATION) {## 33 ##src/sctp/sctpserv07.c##
+            print_notification(readbuf);## 34 ##src/sctp/sctpserv07.c##
+            continue;## 35 ##src/sctp/sctpserv07.c##
+        }## 36 ##src/sctp/sctpserv07.c##
+        Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 37 ##src/sctp/sctpserv07.c##
+                     (SA *) &cliaddr, len,## 38 ##src/sctp/sctpserv07.c##
+                     sri.sinfo_ppid,## 39 ##src/sctp/sctpserv07.c##
+                     sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 40 ##src/sctp/sctpserv07.c##
+    }## 41 ##src/sctp/sctpserv07.c##
+
+}## 42 ##src/sctp/sctpserv07.c##
diff --git a/sctp/sctpserv_fork.c b/sctp/sctpserv_fork.c
new file mode 100644 (file)
index 0000000..58e4b19
--- /dev/null
@@ -0,0 +1,60 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int sock_fd,msg_flags,connfd,childpid;
+       sctp_assoc_t assoc;
+       char readbuf[BUFFSIZE];
+       struct sockaddr_in servaddr, cliaddr;
+       struct sctp_sndrcvinfo sri;
+       struct sctp_event_subscribe evnts;
+       socklen_t len;
+       size_t rd_sz;
+
+        sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port = htons(SERV_PORT);
+
+       Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));
+       
+       bzero(&evnts, sizeof(evnts));
+       evnts.sctp_data_io_event = 1;
+       Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,
+                  &evnts, sizeof(evnts));
+
+       Listen(sock_fd, LISTENQ);
+/* include mod_servfork */
+       for ( ; ; ) {
+               len = sizeof(struct sockaddr_in);
+               rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),
+                            (SA *)&cliaddr, &len,
+                            &sri,&msg_flags);
+               Sctp_sendmsg(sock_fd, readbuf, rd_sz, 
+                            (SA *)&cliaddr, len,
+                            sri.sinfo_ppid,
+                            sri.sinfo_flags,
+                            sri.sinfo_stream,
+                            0, 0);
+               assoc = sctp_address_to_associd(sock_fd,(SA *)&cliaddr,len);
+               if((int)assoc == 0){
+                       err_ret("Can't get association id");
+                       continue;
+               } 
+               connfd = sctp_peeloff(sock_fd,assoc);
+               if(connfd == -1){
+                       err_ret("sctp_peeloff fails");
+                       continue;
+               }
+               if((childpid = fork()) == 0) {
+                       Close(sock_fd);
+                       str_echo(connfd);
+                       exit(0);
+               } else {
+                       Close(connfd);
+               }
+       }
+/* end mod_servfork */
+}
diff --git a/sctp/sctpserv_fork.lc b/sctp/sctpserv_fork.lc
new file mode 100644 (file)
index 0000000..0594b6e
--- /dev/null
@@ -0,0 +1,59 @@
+#include    "unp.h"##  1 ##src/sctp/sctpserv_fork.c##
+
+int##  2 ##src/sctp/sctpserv_fork.c##
+main(int argc, char **argv)##  3 ##src/sctp/sctpserv_fork.c##
+{##  4 ##src/sctp/sctpserv_fork.c##
+    int     sock_fd, msg_flags, connfd, childpid;##  5 ##src/sctp/sctpserv_fork.c##
+    sctp_assoc_t assoc;##  6 ##src/sctp/sctpserv_fork.c##
+    char    readbuf[BUFFSIZE];##  7 ##src/sctp/sctpserv_fork.c##
+    struct sockaddr_in servaddr, cliaddr;##  8 ##src/sctp/sctpserv_fork.c##
+    struct sctp_sndrcvinfo sri;##  9 ##src/sctp/sctpserv_fork.c##
+    struct sctp_event_subscribe evnts;## 10 ##src/sctp/sctpserv_fork.c##
+    socklen_t len;## 11 ##src/sctp/sctpserv_fork.c##
+    size_t  rd_sz;## 12 ##src/sctp/sctpserv_fork.c##
+
+    sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);## 13 ##src/sctp/sctpserv_fork.c##
+    bzero(&servaddr, sizeof(servaddr));## 14 ##src/sctp/sctpserv_fork.c##
+    servaddr.sin_family = AF_INET;## 15 ##src/sctp/sctpserv_fork.c##
+#ifdef HAVE_SOCKADDR_SA_LEN## 16 ##src/sctp/sctpserv_fork.c##
+    servaddr.sin_len = sizeof(servaddr);## 17 ##src/sctp/sctpserv_fork.c##
+#endif## 18 ##src/sctp/sctpserv_fork.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 19 ##src/sctp/sctpserv_fork.c##
+    servaddr.sin_port = htons(SERV_PORT);## 20 ##src/sctp/sctpserv_fork.c##
+
+    Bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));## 21 ##src/sctp/sctpserv_fork.c##
+
+    bzero(&evnts, sizeof(evnts));## 22 ##src/sctp/sctpserv_fork.c##
+    evnts.sctp_data_io_event = 1;## 23 ##src/sctp/sctpserv_fork.c##
+    Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));## 24 ##src/sctp/sctpserv_fork.c##
+
+    Listen(sock_fd, LISTENQ);## 25 ##src/sctp/sctpserv_fork.c##
+    /* include mod_servfork */## 26 ##src/sctp/sctpserv_fork.c##
+    for (;;) {## 27 ##src/sctp/sctpserv_fork.c##
+        len = sizeof(struct sockaddr_in);## 28 ##src/sctp/sctpserv_fork.c##
+        rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),## 29 ##src/sctp/sctpserv_fork.c##
+                             (SA *) &cliaddr, &len, &sri, &msg_flags);## 30 ##src/sctp/sctpserv_fork.c##
+        Sctp_sendmsg(sock_fd, readbuf, rd_sz,## 31 ##src/sctp/sctpserv_fork.c##
+                     (SA *) &cliaddr, len,## 32 ##src/sctp/sctpserv_fork.c##
+                     sri.sinfo_ppid,## 33 ##src/sctp/sctpserv_fork.c##
+                     sri.sinfo_flags, sri.sinfo_stream, 0, 0);## 34 ##src/sctp/sctpserv_fork.c##
+        assoc = sctp_address_to_associd(sock_fd, (SA *) &cliaddr, len);## 35 ##src/sctp/sctpserv_fork.c##
+        if ((int) assoc == 0) {## 36 ##src/sctp/sctpserv_fork.c##
+            err_ret("Can't get association id");## 37 ##src/sctp/sctpserv_fork.c##
+            continue;## 38 ##src/sctp/sctpserv_fork.c##
+        }## 39 ##src/sctp/sctpserv_fork.c##
+        connfd = sctp_peeloff(sock_fd, assoc);## 40 ##src/sctp/sctpserv_fork.c##
+        if (connfd == -1) {## 41 ##src/sctp/sctpserv_fork.c##
+            err_ret("sctp_peeloff fails");## 42 ##src/sctp/sctpserv_fork.c##
+            continue;## 43 ##src/sctp/sctpserv_fork.c##
+        }## 44 ##src/sctp/sctpserv_fork.c##
+        if ((childpid = fork()) == 0) {## 45 ##src/sctp/sctpserv_fork.c##
+            Close(sock_fd);## 46 ##src/sctp/sctpserv_fork.c##
+            str_echo(connfd);## 47 ##src/sctp/sctpserv_fork.c##
+            exit(0);## 48 ##src/sctp/sctpserv_fork.c##
+        } else {## 49 ##src/sctp/sctpserv_fork.c##
+            Close(connfd);## 50 ##src/sctp/sctpserv_fork.c##
+        }## 51 ##src/sctp/sctpserv_fork.c##
+    }## 52 ##src/sctp/sctpserv_fork.c##
+    /* end mod_servfork */## 53 ##src/sctp/sctpserv_fork.c##
+}## 54 ##src/sctp/sctpserv_fork.c##
diff --git a/sctp/unp.h b/sctp/unp.h
new file mode 100644 (file)
index 0000000..0e8a9cc
--- /dev/null
@@ -0,0 +1,471 @@
+/* include unph */
+/* Our own header.  Tabs are set for 4 spaces, not 8 */
+
+#ifndef        __unp_h
+#define        __unp_h
+
+#include       "../config.h"   /* configuration options for current OS */
+                                                       /* "../config.h" is generated by configure */
+
+/* If anything changes in the following list of #includes, must change
+   acsite.m4 also, for configure's tests. */
+
+#include       <sys/types.h>   /* basic system data types */
+#include       <sys/socket.h>  /* basic socket definitions */
+#include       <sys/time.h>    /* timeval{} for select() */
+#include       <time.h>                /* timespec{} for pselect() */
+#include       <netinet/in.h>  /* sockaddr_in{} and other Internet defns */
+#include       <arpa/inet.h>   /* inet(3) functions */
+#include       <netinet/sctp.h> /* note if sctp does not exist we blow up :> */
+#include       <errno.h>
+#include       <fcntl.h>               /* for nonblocking */
+#include       <netdb.h>
+#include       <signal.h>
+#include       <stdio.h>
+#include       <stdlib.h>
+#include       <string.h>
+#include       <sys/stat.h>    /* for S_xxx file mode constants */
+#include       <sys/uio.h>             /* for iovec{} and readv/writev */
+#include       <unistd.h>
+#include       <sys/wait.h>
+#include       <sys/un.h>              /* for Unix domain sockets */
+
+#ifdef HAVE_SYS_SELECT_H
+# include      <sys/select.h>  /* for convenience */
+#endif
+
+#ifdef HAVE_POLL_H
+# include      <poll.h>                /* for convenience */
+#endif
+
+#ifdef HAVE_STRINGS_H
+# include      <strings.h>             /* for convenience */
+#endif
+
+/* Three headers are normally needed for socket/file ioctl's:
+ * <sys/ioctl.h>, <sys/filio.h>, and <sys/sockio.h>.
+ */
+#ifdef HAVE_SYS_IOCTL_H
+# include      <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include      <sys/filio.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+# include      <sys/sockio.h>
+#endif
+
+#ifdef HAVE_PTHREAD_H
+# include      <pthread.h>
+#endif
+
+/* OSF/1 actually disables recv() and send() in <sys/socket.h> */
+#ifdef __osf__
+#undef recv
+#undef send
+#define        recv(a,b,c,d)   recvfrom(a,b,c,d,0,0)
+#define        send(a,b,c,d)   sendto(a,b,c,d,0,0)
+#endif
+
+#ifndef        INADDR_NONE
+/* $$.Ic INADDR_NONE$$ */
+#define        INADDR_NONE     0xffffffff      /* should have been in <netinet/in.h> */
+#endif
+
+#ifndef        SHUT_RD                         /* these three Posix.1g names are quite new */
+#define        SHUT_RD         0       /* shutdown for reading */
+#define        SHUT_WR         1       /* shutdown for writing */
+#define        SHUT_RDWR       2       /* shutdown for reading and writing */
+/* $$.Ic SHUT_RD$$ */
+/* $$.Ic SHUT_WR$$ */
+/* $$.Ic SHUT_RDWR$$ */
+#endif
+
+/* *INDENT-OFF* */
+#ifndef INET_ADDRSTRLEN
+/* $$.Ic INET_ADDRSTRLEN$$ */
+#define        INET_ADDRSTRLEN         16      /* "ddd.ddd.ddd.ddd\0"
+                                                                   1234567890123456 */
+#endif
+
+/* Define following even if IPv6 not supported, so we can always allocate
+   an adequately-sized buffer, without #ifdefs in the code. */
+#ifndef INET6_ADDRSTRLEN
+/* $$.Ic INET6_ADDRSTRLEN$$ */
+#define        INET6_ADDRSTRLEN        46      /* max size of IPv6 address string:
+                                  "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx" or
+                                  "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:ddd.ddd.ddd.ddd\0"
+                                   1234567890123456789012345678901234567890123456 */
+#endif
+/* *INDENT-ON* */
+
+/* Define bzero() as a macro if it's not in standard C library. */
+#ifndef        HAVE_BZERO
+#define        bzero(ptr,n)            memset(ptr, 0, n)
+/* $$.If bzero$$ */
+/* $$.If memset$$ */
+#endif
+
+/* Older resolvers do not have gethostbyname2() */
+#ifndef        HAVE_GETHOSTBYNAME2
+#define        gethostbyname2(host,family)             gethostbyname((host))
+#endif
+
+/* The structure returned by recvfrom_flags() */
+struct in_pktinfo {
+  struct in_addr       ipi_addr;       /* dst IPv4 address */
+  int                          ipi_ifindex;/* received interface index */
+};
+/* $$.It in_pktinfo$$ */
+/* $$.Ib ipi_addr$$ */
+/* $$.Ib ipi_ifindex$$ */
+
+/* We need the newer CMSG_LEN() and CMSG_SPACE() macros, but few
+   implementations support them today.  These two macros really need
+    an ALIGN() macro, but each implementation does this differently. */
+#ifndef        CMSG_LEN
+/* $$.Ic CMSG_LEN$$ */
+#define        CMSG_LEN(size)          (sizeof(struct cmsghdr) + (size))
+#endif
+#ifndef        CMSG_SPACE
+/* $$.Ic CMSG_SPACE$$ */
+#define        CMSG_SPACE(size)        (sizeof(struct cmsghdr) + (size))
+#endif
+
+/* Posix.1g requires the SUN_LEN() macro but not all implementations DefinE
+   it (yet).  Note that this 4.4BSD macro works regardless whether there is
+   a length field or not. */
+#ifndef        SUN_LEN
+/* $$.Im SUN_LEN$$ */
+# define       SUN_LEN(su) \
+       (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
+#endif
+
+/* Posix.1g renames "Unix domain" as "local IPC".
+   But not all systems DefinE AF_LOCAL and PF_LOCAL (yet). */
+#ifndef        AF_LOCAL
+#define AF_LOCAL       AF_UNIX
+#endif
+#ifndef        PF_LOCAL
+#define PF_LOCAL       PF_UNIX
+#endif
+
+/* Posix.1g requires that an #include of <poll.h> DefinE INFTIM, but many
+   systems still DefinE it in <sys/stropts.h>.  We don't want to include
+   all the streams stuff if it's not needed, so we just DefinE INFTIM here.
+   This is the standard value, but there's no guarantee it is -1. */
+#ifndef INFTIM
+#define INFTIM          (-1)    /* infinite poll timeout */
+/* $$.Ic INFTIM$$ */
+#ifdef HAVE_POLL_H
+#define        INFTIM_UNPH                             /* tell unpxti.h we defined it */
+#endif
+#endif
+
+/* Following could be derived from SOMAXCONN in <sys/socket.h>, but many
+   kernels still #define it as 5, while actually supporting many more */
+#define        LISTENQ         1024    /* 2nd argument to listen() */
+
+/* Miscellaneous constants */
+#define        MAXLINE         4096    /* max text line length */
+#define        MAXSOCKADDR  128        /* max socket address structure size */
+#define        BUFFSIZE        8192    /* buffer size for reads and writes */
+
+/* Define some port number that can be used for client-servers */
+#define        SERV_PORT                9877                   /* TCP and UDP client-servers */
+#define        SERV_PORT_STR   "9877"                  /* TCP and UDP client-servers */
+/* Some things for SCTP */
+#define SCTP_PDAPI_INCR_SZ 65535       /* increment size for pdapi when adding buf space */
+#define SCTP_PDAPI_NEED_MORE_THRESHOLD 1024    /* need more space threshold */
+#define SERV_MAX_SCTP_STRM     10      /* normal maximum streams */
+#define SERV_MORE_STRMS_SCTP   20      /* larger number of streams */
+
+
+#define        UNIXSTR_PATH    "/tmp/unix.str" /* Unix domain stream cli-serv */
+#define        UNIXDG_PATH             "/tmp/unix.dg"  /* Unix domain datagram cli-serv */
+/* $$.ix [LISTENQ]~constant,~definition~of$$ */
+/* $$.ix [MAXLINE]~constant,~definition~of$$ */
+/* $$.ix [MAXSOCKADDR]~constant,~definition~of$$ */
+/* $$.ix [BUFFSIZE]~constant,~definition~of$$ */
+/* $$.ix [SERV_PORT]~constant,~definition~of$$ */
+/* $$.ix [UNIXSTR_PATH]~constant,~definition~of$$ */
+/* $$.ix [UNIXDG_PATH]~constant,~definition~of$$ */
+
+/* Following shortens all the type casts of pointer arguments */
+#define        SA      struct sockaddr
+
+#define        FILE_MODE       (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
+                                       /* default file access permissions for new files */
+#define        DIR_MODE        (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)
+                                       /* default permissions for new directories */
+
+typedef        void    Sigfunc(int);   /* for signal handlers */
+
+#define        min(a,b)        ((a) < (b) ? (a) : (b))
+#define        max(a,b)        ((a) > (b) ? (a) : (b))
+
+#ifndef        HAVE_ADDRINFO_STRUCT
+# include      "../lib/addrinfo.h"
+#endif
+
+#ifndef        HAVE_IF_NAMEINDEX_STRUCT
+struct if_nameindex {
+  unsigned int   if_index;  /* 1, 2, ... */
+  char          *if_name;   /* null terminated name: "le0", ... */
+};
+/* $$.It if_nameindex$$ */
+/* $$.Ib if_index$$ */
+/* $$.Ib if_name$$ */
+#endif
+
+#ifndef        HAVE_TIMESPEC_STRUCT
+struct timespec {
+  time_t       tv_sec;         /* seconds */
+  long         tv_nsec;        /* and nanoseconds */
+};
+/* $$.It timespec$$ */
+/* $$.Ib tv_sec$$ */
+/* $$.Ib tv_nsec$$ */
+#endif
+/* end unph */
+
+                       /* prototypes for our own library functions */
+int             connect_nonb(int, const SA *, socklen_t, int);
+int             connect_timeo(int, const SA *, socklen_t, int);
+void    daemon_init(const char *, int);
+void    daemon_inetd(const char *, int);
+void    dg_cli(FILE *, int, const SA *, socklen_t);
+void    dg_echo(int, SA *, socklen_t);
+char   *gf_time(void);
+void    heartbeat_cli(int, int, int);
+void    heartbeat_serv(int, int, int);
+struct addrinfo *host_serv(const char *, const char *, int, int);
+int             inet_srcrt_add(char *, int);
+u_char  *inet_srcrt_init(void);
+void    inet_srcrt_print(u_char *, int);
+char   **my_addrs(int *);
+int             readable_timeo(int, int);
+ssize_t         readline(int, void *, size_t);
+ssize_t         readn(int, void *, size_t);
+ssize_t         read_fd(int, void *, size_t, int *);
+ssize_t         recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *,
+                struct in_pktinfo *);
+Sigfunc *signal_intr(int, Sigfunc *);
+int             sock_bind_wild(int, int);
+int             sock_cmp_addr(const SA *, const SA *, socklen_t);
+int             sock_cmp_port(const SA *, const SA *, socklen_t);
+int             sock_get_port(const SA *, socklen_t);
+void    sock_set_addr(SA *, socklen_t, const void *);
+void    sock_set_port(SA *, socklen_t, int);
+void    sock_set_wild(SA *, socklen_t);
+char   *sock_ntop(const SA *, socklen_t);
+char   *sock_ntop_host(const SA *, socklen_t);
+int             sockfd_to_family(int);
+void    str_echo(int);
+void    str_cli(FILE *, int);
+void     sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen);
+void    sctpstr_cli_echoall(FILE *fp, int sock_fd, struct sockaddr *to, 
+                            socklen_t tolen);
+uint8_t *sctp_pdapi_recvmsg(int sock_fd, int *rdlen, SA *from, int *from_len,
+                           struct sctp_sndrcvinfo *sri, int *msg_flags);
+int      sctp_bind_arg_list(int sock_fd, char **argv, int argc);
+
+void sctp_print_addresses(struct sockaddr_storage *addrs, int num);
+
+void sctp_check_notification(int sock_fd,char *recvlin);
+
+#define SCTP_ON_DEMAND_HB    1
+#define SCTP_SET_HB_INTERVAL 2
+#define SCTP_DISABLE_HB      3
+int sctp_heartbeat_action(int sock_fd, struct sockaddr *sa, 
+                         int action, u_int value);
+
+sctp_assoc_t
+sctp_address_to_associd(int sock_fd, struct sockaddr *sa, socklen_t);
+
+
+void
+sctp_print_notification(char *notify_buf);
+
+int             tcp_connect(const char *, const char *);
+int             tcp_listen(const char *, const char *, socklen_t *);
+void    tv_sub(struct timeval *, struct timeval *);
+int             udp_client(const char *, const char *, void **, socklen_t *);
+int             udp_connect(const char *, const char *);
+int             udp_server(const char *, const char *, socklen_t *);
+int             writable_timeo(int, int);
+ssize_t         writen(int, const void *, size_t);
+ssize_t         write_fd(int, void *, size_t, int);
+
+#ifdef MCAST
+int             mcast_leave(int, const SA *, socklen_t);
+int             mcast_join(int, const SA *, socklen_t, const char *, u_int);
+int             mcast_get_if(int);
+int             mcast_get_loop(int);
+int             mcast_get_ttl(int);
+int             mcast_set_if(int, const char *, u_int);
+int             mcast_set_loop(int, int);
+int             mcast_set_ttl(int, int);
+
+void    Mcast_leave(int, const SA *, socklen_t);
+void    Mcast_join(int, const SA *, socklen_t, const char *, u_int);
+int             Mcast_get_if(int);
+int             Mcast_get_loop(int);
+int             Mcast_get_ttl(int);
+void    Mcast_set_if(int, const char *, u_int);
+void    Mcast_set_loop(int, int);
+void    Mcast_set_ttl(int, int);
+#endif
+
+unsigned short in_cksum(unsigned short *, int);
+
+#ifndef        HAVE_GETADDRINFO_PROTO
+int             getaddrinfo(const char *, const char *, const struct addrinfo *,
+                                        struct addrinfo **);
+void    freeaddrinfo(struct addrinfo *);
+char   *gai_strerror(int);
+#endif
+
+#ifndef        HAVE_GETNAMEINFO_PROTO
+int             getnameinfo(const SA *, socklen_t, char *, size_t, char *, size_t, int);
+#endif
+
+#ifndef        HAVE_GETHOSTNAME_PROTO
+int             gethostname(char *, int);
+#endif
+
+#ifndef        HAVE_HSTRERROR_PROTO
+const char     *hstrerror(int);
+#endif
+
+#ifndef        HAVE_IF_NAMETOINDEX_PROTO
+unsigned int    if_nametoindex(const char *);
+char                   *if_indextoname(unsigned int, char *);
+void                    if_freenameindex(struct if_nameindex *);
+struct if_nameindex *if_nameindex(void);
+#endif
+
+#ifndef        HAVE_INET_PTON_PROTO
+int                     inet_pton(int, const char *, void *);
+const char     *inet_ntop(int, const void *, char *, size_t);
+#endif
+
+#ifndef        HAVE_INET_ATON_PROTO
+int             inet_aton(const char *, struct in_addr *);
+#endif
+
+#ifndef        HAVE_ISFDTYPE_PROTO
+int             isfdtype(int, int);
+#endif
+
+#ifndef        HAVE_PSELECT_PROTO
+int             pselect(int, fd_set *, fd_set *, fd_set *,
+                                const struct timespec *, const sigset_t *);
+#endif
+
+#ifndef        HAVE_SOCKATMARK_PROTO
+int             sockatmark(int);
+#endif
+
+#ifndef        HAVE_SNPRINTF_PROTO
+int             snprintf(char *, size_t, const char *, ...);
+#endif
+
+                       /* prototypes for our own library wrapper functions */
+void    Connect_timeo(int, const SA *, socklen_t, int);
+struct addrinfo *Host_serv(const char *, const char *, int, int);
+const char             *Inet_ntop(int, const void *, char *, size_t);
+void                    Inet_pton(int, const char *, void *);
+char                   *If_indextoname(unsigned int, char *);
+unsigned int            If_nametoindex(const char *);
+struct if_nameindex    *If_nameindex(void);
+char   **My_addrs(int *);
+ssize_t         Read_fd(int, void *, size_t, int *);
+int             Readable_timeo(int, int);
+ssize_t         Recvfrom_flags(int, void *, size_t, int *, SA *, socklen_t *,
+                struct in_pktinfo *);
+Sigfunc *Signal(int, Sigfunc *);
+Sigfunc *Signal_intr(int, Sigfunc *);
+int             Sock_bind_wild(int, int);
+char   *Sock_ntop(const SA *, socklen_t);
+char   *Sock_ntop_host(const SA *, socklen_t);
+int             Sockfd_to_family(int);
+int             Tcp_connect(const char *, const char *);
+int             Tcp_listen(const char *, const char *, socklen_t *);
+int             Udp_client(const char *, const char *, void **, socklen_t *);
+int             Udp_connect(const char *, const char *);
+int             Udp_server(const char *, const char *, socklen_t *);
+ssize_t         Write_fd(int, void *, size_t, int);
+int             Writable_timeo(int, int);
+
+                       /* prototypes for our Unix wrapper functions: see {Sec errors} */
+void   *Calloc(size_t, size_t);
+void    Close(int);
+void    Dup2(int, int);
+int             Fcntl(int, int, int);
+void    Gettimeofday(struct timeval *, void *);
+int             Ioctl(int, int, void *);
+pid_t   Fork(void);
+void   *Malloc(size_t);
+void    Mktemp(char *);
+void   *Mmap(void *, size_t, int, int, int, off_t);
+int             Open(const char *, int, mode_t);
+void    Pipe(int *fds);
+ssize_t         Read(int, void *, size_t);
+void    Sigaddset(sigset_t *, int);
+void    Sigdelset(sigset_t *, int);
+void    Sigemptyset(sigset_t *);
+void    Sigfillset(sigset_t *);
+int             Sigismember(const sigset_t *, int);
+void    Sigpending(sigset_t *);
+void    Sigprocmask(int, const sigset_t *, sigset_t *);
+char   *Strdup(const char *);
+long    Sysconf(int);
+void    Sysctl(int *, u_int, void *, size_t *, void *, size_t);
+void    Unlink(const char *);
+pid_t   Wait(int *);
+pid_t   Waitpid(pid_t, int *, int);
+void    Write(int, void *, size_t);
+
+                       /* prototypes for our stdio wrapper functions: see {Sec errors} */
+void    Fclose(FILE *);
+FILE   *Fdopen(int, const char *);
+char   *Fgets(char *, int, FILE *);
+FILE   *Fopen(const char *, const char *);
+void    Fputs(const char *, FILE *);
+
+                       /* prototypes for our socket wrapper functions: see {Sec errors} */
+int             Accept(int, SA *, socklen_t *);
+void    Bind(int, const SA *, socklen_t);
+void    Connect(int, const SA *, socklen_t);
+void    Getpeername(int, SA *, socklen_t *);
+void    Getsockname(int, SA *, socklen_t *);
+void    Getsockopt(int, int, int, void *, socklen_t *);
+int             Isfdtype(int, int);
+void    Listen(int, int);
+#ifdef HAVE_POLL
+int             Poll(struct pollfd *, unsigned long, int);
+#endif
+ssize_t         Readline(int, void *, size_t);
+ssize_t         Readn(int, void *, size_t);
+ssize_t         Recv(int, void *, size_t, int);
+ssize_t         Recvfrom(int, void *, size_t, int, SA *, socklen_t *);
+ssize_t         Recvmsg(int, struct msghdr *, int);
+int             Select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+void    Send(int, const void *, size_t, int);
+void    Sendto(int, const void *, size_t, int, const SA *, socklen_t);
+void    Sendmsg(int, const struct msghdr *, int);
+void    Setsockopt(int, int, int, const void *, socklen_t);
+void    Shutdown(int, int);
+int             Sockatmark(int);
+int             Socket(int, int, int);
+void    Socketpair(int, int, int, int *);
+void    Writen(int, void *, size_t);
+
+void    err_dump(const char *, ...);
+void    err_msg(const char *, ...);
+void    err_quit(const char *, ...);
+void    err_ret(const char *, ...);
+void    err_sys(const char *, ...);
+
+#endif /* __unp_h */
diff --git a/select/Makefile b/select/Makefile
new file mode 100644 (file)
index 0000000..4ae76eb
--- /dev/null
@@ -0,0 +1,17 @@
+include ../Make.defines
+
+PROGS =        tcpcli01 tcpcli02 tcpcli03
+
+all:   ${PROGS}
+
+tcpcli01:      tcpcli01.o strcliselect01.o
+               ${CC} ${CFLAGS} -o $@ tcpcli01.o strcliselect01.o ${LIBS}
+
+tcpcli02:      tcpcli02.o strcliselect02.o
+               ${CC} ${CFLAGS} -o $@ tcpcli02.o strcliselect02.o ${LIBS}
+
+tcpcli03:      tcpcli03.o
+               ${CC} ${CFLAGS} -o $@ tcpcli03.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/select/strcliselect01.c b/select/strcliselect01.c
new file mode 100644 (file)
index 0000000..a4a1aef
--- /dev/null
@@ -0,0 +1,29 @@
+#include       "unp.h"
+
+void
+str_cli(FILE *fp, int sockfd)
+{
+       int                     maxfdp1;
+       fd_set          rset;
+       char            sendline[MAXLINE], recvline[MAXLINE];
+
+       FD_ZERO(&rset);
+       for ( ; ; ) {
+               FD_SET(fileno(fp), &rset);
+               FD_SET(sockfd, &rset);
+               maxfdp1 = max(fileno(fp), sockfd) + 1;
+               Select(maxfdp1, &rset, NULL, NULL, NULL);
+
+               if (FD_ISSET(sockfd, &rset)) {  /* socket is readable */
+                       if (Readline(sockfd, recvline, MAXLINE) == 0)
+                               err_quit("str_cli: server terminated prematurely");
+                       Fputs(recvline, stdout);
+               }
+
+               if (FD_ISSET(fileno(fp), &rset)) {  /* input is readable */
+                       if (Fgets(sendline, MAXLINE, fp) == NULL)
+                               return;         /* all done */
+                       Writen(sockfd, sendline, strlen(sendline));
+               }
+       }
+}
diff --git a/select/strcliselect02.c b/select/strcliselect02.c
new file mode 100644 (file)
index 0000000..3234fee
--- /dev/null
@@ -0,0 +1,42 @@
+#include       "unp.h"
+
+void
+str_cli(FILE *fp, int sockfd)
+{
+       int                     maxfdp1, stdineof;
+       fd_set          rset;
+       char            buf[MAXLINE];
+       int             n;
+
+       stdineof = 0;
+       FD_ZERO(&rset);
+       for ( ; ; ) {
+               if (stdineof == 0)
+                       FD_SET(fileno(fp), &rset);
+               FD_SET(sockfd, &rset);
+               maxfdp1 = max(fileno(fp), sockfd) + 1;
+               Select(maxfdp1, &rset, NULL, NULL, NULL);
+
+               if (FD_ISSET(sockfd, &rset)) {  /* socket is readable */
+                       if ( (n = Read(sockfd, buf, MAXLINE)) == 0) {
+                               if (stdineof == 1)
+                                       return;         /* normal termination */
+                               else
+                                       err_quit("str_cli: server terminated prematurely");
+                       }
+
+                       Write(fileno(stdout), buf, n);
+               }
+
+               if (FD_ISSET(fileno(fp), &rset)) {  /* input is readable */
+                       if ( (n = Read(fileno(fp), buf, MAXLINE)) == 0) {
+                               stdineof = 1;
+                               Shutdown(sockfd, SHUT_WR);      /* send FIN */
+                               FD_CLR(fileno(fp), &rset);
+                               continue;
+                       }
+
+                       Writen(sockfd, buf, n);
+               }
+       }
+}
diff --git a/select/strcliselect02.lc b/select/strcliselect02.lc
new file mode 100644 (file)
index 0000000..7257daa
--- /dev/null
@@ -0,0 +1,41 @@
+#include    "unp.h"##  1 ##src/select/strcliselect02.c##
+
+void##  2 ##src/select/strcliselect02.c##
+str_cli(FILE *fp, int sockfd)##  3 ##src/select/strcliselect02.c##
+{##  4 ##src/select/strcliselect02.c##
+    int     maxfdp1, stdineof;##  5 ##src/select/strcliselect02.c##
+    fd_set  rset;##  6 ##src/select/strcliselect02.c##
+    char    sendline[MAXLINE], recvline[MAXLINE];##  7 ##src/select/strcliselect02.c##
+
+    stdineof = 0;##  8 ##src/select/strcliselect02.c##
+    FD_ZERO(&rset);##  9 ##src/select/strcliselect02.c##
+    for (;;) {## 10 ##src/select/strcliselect02.c##
+        if (stdineof == 0)## 11 ##src/select/strcliselect02.c##
+            FD_SET(fileno(fp), &rset);## 12 ##src/select/strcliselect02.c##
+        FD_SET(sockfd, &rset);## 13 ##src/select/strcliselect02.c##
+        maxfdp1 = max(fileno(fp), sockfd) + 1;## 14 ##src/select/strcliselect02.c##
+        Select(maxfdp1, &rset, NULL, NULL, NULL);## 15 ##src/select/strcliselect02.c##
+
+        if (FD_ISSET(sockfd, &rset)) {  /* socket is readable */## 16 ##src/select/strcliselect02.c##
+            if (Readline(sockfd, recvline, MAXLINE) == 0) {## 17 ##src/select/strcliselect02.c##
+                if (stdineof == 1)## 18 ##src/select/strcliselect02.c##
+                    return;     /* normal termination */## 19 ##src/select/strcliselect02.c##
+                else## 20 ##src/select/strcliselect02.c##
+                    err_quit("str_cli: server terminated prematurely");## 21 ##src/select/strcliselect02.c##
+            }## 22 ##src/select/strcliselect02.c##
+
+            Fputs(recvline, stdout);## 23 ##src/select/strcliselect02.c##
+        }## 24 ##src/select/strcliselect02.c##
+
+        if (FD_ISSET(fileno(fp), &rset)) {  /* input is readable */## 25 ##src/select/strcliselect02.c##
+            if (Fgets(sendline, MAXLINE, fp) == NULL) {## 26 ##src/select/strcliselect02.c##
+                stdineof = 1;## 27 ##src/select/strcliselect02.c##
+                Shutdown(sockfd, SHUT_WR);  /* send FIN */## 28 ##src/select/strcliselect02.c##
+                FD_CLR(fileno(fp), &rset);## 29 ##src/select/strcliselect02.c##
+                continue;## 30 ##src/select/strcliselect02.c##
+            }## 31 ##src/select/strcliselect02.c##
+
+            Writen(sockfd, sendline, strlen(sendline));## 32 ##src/select/strcliselect02.c##
+        }## 33 ##src/select/strcliselect02.c##
+    }## 34 ##src/select/strcliselect02.c##
+}## 35 ##src/select/strcliselect02.c##
diff --git a/select/tcpcli01.c b/select/tcpcli01.c
new file mode 100644 (file)
index 0000000..c9b4898
--- /dev/null
@@ -0,0 +1,25 @@
+/* Use standard echo server; baseline measurements for nonblocking version */
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(7);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/select/tcpcli02.c b/select/tcpcli02.c
new file mode 100644 (file)
index 0000000..c9b4898
--- /dev/null
@@ -0,0 +1,25 @@
+/* Use standard echo server; baseline measurements for nonblocking version */
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(7);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/select/tcpcli03.c b/select/tcpcli03.c
new file mode 100644 (file)
index 0000000..df9de96
--- /dev/null
@@ -0,0 +1,27 @@
+/* Test shutdown(fd,SHUT_RD) and see what happens */
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli03 <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(19);          /* chargen server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       shutdown(sockfd, SHUT_RD);
+
+       pause();
+
+       exit(0);
+}
diff --git a/server/Makefile b/server/Makefile
new file mode 100644 (file)
index 0000000..c69d6f2
--- /dev/null
@@ -0,0 +1,85 @@
+include ../Make.defines
+
+PROGS =        client clientrst \
+               serv01 serv02 serv03 serv04 serv05 serv06 serv07 serv08
+
+all:   ${PROGS}
+
+# The client to test the various servers.
+client:        client.o pr_cpu_time.o
+               ${CC} ${CFLAGS} -o $@ client.o pr_cpu_time.o ${LIBS}
+
+# A special client that sends an RST occasionally.
+# Used to test the XTI server (should receive disconnect).
+clientrst:     clientrst.o pr_cpu_time.o
+               ${CC} ${CFLAGS} -o $@ clientrst.o pr_cpu_time.o ${LIBS}
+
+# serv00: traditional concurrent server: use as base level
+serv00:        serv00.o web_child.o pr_cpu_time.o
+               ${CC} ${CFLAGS} -o $@ serv00.o web_child.o pr_cpu_time.o ${LIBS}
+
+# serv01: one fork per client (traditional concurrent server).
+serv01:        serv01.o web_child.o sig_chld_waitpid.o pr_cpu_time.o
+               ${CC} ${CFLAGS} -o $@ serv01.o web_child.o sig_chld_waitpid.o \
+                       pr_cpu_time.o ${LIBS}
+
+# serv02: prefork, no locking; works on BSD-derived systems
+#      but not on SVR4-derived systems.
+serv02:        serv02.o child02.o web_child.o pr_cpu_time.o
+               ${CC} ${CFLAGS} -o $@ serv02.o child02.o web_child.o pr_cpu_time.o ${LIBS}
+
+# serv02l: prefork, no locking, block in select instead of accept to see
+#      select collisions; works on BSD-derived systems but not on SVR4.
+serv02l:serv02.o child02l.o web_child.o pr_cpu_time.o
+               ${CC} ${CFLAGS} -o serv02l serv02.o child02l.o web_child.o \
+                       pr_cpu_time.o ${LIBS}
+
+# serv02m: prefork, no locking; works on BSD-derived systems.
+#      This version is "metered" to see #clients/child serviced.
+serv02m:serv02m.o child02m.o web_child.o pr_cpu_time.o meter.o
+               ${CC} ${CFLAGS} -o serv02m serv02m.o child02m.o web_child.o \
+                       pr_cpu_time.o meter.o ${LIBS}
+
+# serv03: prefork, file locking using fcntl().  Similar to Apache server.
+serv03:        serv03.o child03.o lock_fcntl.o web_child.o pr_cpu_time.o
+               ${CC} ${CFLAGS} -o $@ serv03.o child03.o lock_fcntl.o web_child.o \
+                       pr_cpu_time.o ${LIBS}
+
+# serv03m: prefork, file locking using fcntl(), metered.
+serv03m:       serv03m.o child03m.o lock_fcntl.o web_child.o pr_cpu_time.o meter.o
+               ${CC} ${CFLAGS} -o $@ serv03m.o child03m.o lock_fcntl.o web_child.o \
+                       pr_cpu_time.o meter.o ${LIBS}
+
+# serv04: prefork, file locking using pthread locking.
+serv04:        serv04.o child04.o lock_pthread.o web_child.o pr_cpu_time.o
+               ${CC} ${CFLAGS} -o $@ serv04.o child04.o lock_pthread.o \
+                       web_child.o pr_cpu_time.o ${LIBS}
+
+# serv05: prefork, descrptor passing to children.  Similar to NSCA server.
+serv05:        serv05.o child05.o lock_fcntl.o web_child.o pr_cpu_time.o
+               ${CC} ${CFLAGS} -o $@ serv05.o child05.o lock_fcntl.o web_child.o \
+                       pr_cpu_time.o ${LIBS}
+
+# Thread versions must call a reentrant version of readline().
+# serv06: one thread per client.
+serv06:        serv06.o web_child.o pr_cpu_time.o readline.o
+               ${CC} ${CFLAGS} -o $@ serv06.o web_child.o pr_cpu_time.o \
+                       readline.o ${LIBS}
+
+# serv07: prethread with mutex locking around accept().
+serv07:        serv07.o pthread07.o web_child.o pr_cpu_time.o readline.o
+               ${CC} ${CFLAGS} -o $@ serv07.o pthread07.o web_child.o pr_cpu_time.o \
+                       readline.o ${LIBS}
+
+# serv08: prethread with only main thread doing accept().
+serv08:        serv08.o pthread08.o web_child.o pr_cpu_time.o readline.o
+               ${CC} ${CFLAGS} -o $@ serv08.o pthread08.o web_child.o pr_cpu_time.o \
+                       readline.o ${LIBS}
+
+# serv09: prethread with no locking around accept().
+serv09:        serv09.o pthread09.o web_child.o pr_cpu_time.o readline.o
+               ${CC} ${CFLAGS} -o $@ serv09.o pthread09.o web_child.o pr_cpu_time.o \
+                       readline.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/server/child.h b/server/child.h
new file mode 100644 (file)
index 0000000..0f58b5c
--- /dev/null
@@ -0,0 +1,8 @@
+typedef struct {
+  pid_t                child_pid;              /* process ID */
+  int          child_pipefd;   /* parent's stream pipe to/from child */
+  int          child_status;   /* 0 = ready */
+  long         child_count;    /* # connections handled */
+} Child;
+
+Child  *cptr;          /* array of Child structures; calloc'ed */
diff --git a/server/child.lh b/server/child.lh
new file mode 100644 (file)
index 0000000..817e7dc
--- /dev/null
@@ -0,0 +1,8 @@
+typedef struct {##  1 ##src/server/child.h##
+    pid_t   child_pid;          /* process ID */##  2 ##src/server/child.h##
+    int     child_pipefd;       /* parent's stream pipe to/from child */##  3 ##src/server/child.h##
+    int     child_status;       /* 0 = ready */##  4 ##src/server/child.h##
+    long    child_count;        /* #connections handled */##  5 ##src/server/child.h##
+} Child;##  6 ##src/server/child.h##
+
+Child  *cptr;                   /* array of Child structures; calloc'ed */##  7 ##src/server/child.h##
diff --git a/server/child02.c b/server/child02.c
new file mode 100644 (file)
index 0000000..6191c46
--- /dev/null
@@ -0,0 +1,37 @@
+/* include child_make */
+#include       "unp.h"
+
+pid_t
+child_make(int i, int listenfd, int addrlen)
+{
+       pid_t   pid;
+       void    child_main(int, int, int);
+
+       if ( (pid = Fork()) > 0)
+               return(pid);            /* parent */
+
+       child_main(i, listenfd, addrlen);       /* never returns */
+}
+/* end child_make */
+
+/* include child_main */
+void
+child_main(int i, int listenfd, int addrlen)
+{
+       int                             connfd;
+       void                    web_child(int);
+       socklen_t               clilen;
+       struct sockaddr *cliaddr;
+
+       cliaddr = Malloc(addrlen);
+
+       printf("child %ld starting\n", (long) getpid());
+       for ( ; ; ) {
+               clilen = addrlen;
+               connfd = Accept(listenfd, cliaddr, &clilen);
+
+               web_child(connfd);              /* process the request */
+               Close(connfd);
+       }
+}
+/* end child_main */
diff --git a/server/child02.lc b/server/child02.lc
new file mode 100644 (file)
index 0000000..9f06095
--- /dev/null
@@ -0,0 +1,37 @@
+/* include child_make */
+#include    "unp.h"##  1 ##src/server/child02.c##
+
+pid_t##  2 ##src/server/child02.c##
+child_make(int i, int listenfd, int addrlen)##  3 ##src/server/child02.c##
+{##  4 ##src/server/child02.c##
+    pid_t   pid;##  5 ##src/server/child02.c##
+    void    child_main(int, int, int);##  6 ##src/server/child02.c##
+
+    if ((pid = Fork()) > 0)##  7 ##src/server/child02.c##
+        return (pid);           /* parent */##  8 ##src/server/child02.c##
+
+    child_main(i, listenfd, addrlen);   /* never returns */##  9 ##src/server/child02.c##
+}## 10 ##src/server/child02.c##
+/* end child_make */
+
+/* include child_main */
+void## 11 ##src/server/child02.c##
+child_main(int i, int listenfd, int addrlen)## 12 ##src/server/child02.c##
+{## 13 ##src/server/child02.c##
+    int     connfd;## 14 ##src/server/child02.c##
+    void    web_child(int);## 15 ##src/server/child02.c##
+    socklen_t clilen;## 16 ##src/server/child02.c##
+    struct sockaddr *cliaddr;## 17 ##src/server/child02.c##
+
+    cliaddr = Malloc(addrlen);## 18 ##src/server/child02.c##
+
+    printf("child %ld starting\n", (long) getpid());## 19 ##src/server/child02.c##
+    for (;;) {## 20 ##src/server/child02.c##
+        clilen = addrlen;## 21 ##src/server/child02.c##
+        connfd = Accept(listenfd, cliaddr, &clilen);## 22 ##src/server/child02.c##
+
+        web_child(connfd);      /* process the request */## 23 ##src/server/child02.c##
+        Close(connfd);## 24 ##src/server/child02.c##
+    }## 25 ##src/server/child02.c##
+}## 26 ##src/server/child02.c##
+/* end child_main */
diff --git a/server/child02l.c b/server/child02l.c
new file mode 100644 (file)
index 0000000..2b92a71
--- /dev/null
@@ -0,0 +1,40 @@
+#include       "unp.h"
+
+pid_t
+child_make(int i, int listenfd, int addrlen)
+{
+       pid_t   pid;
+       void    child_main(int, int, int);
+
+       if ( (pid = Fork()) > 0)
+               return(pid);            /* parent */
+
+       child_main(i, listenfd, addrlen);       /* never returns */
+}
+
+void
+child_main(int i, int listenfd, int addrlen)
+{
+       int                             connfd;
+       void                    web_child(int);
+       fd_set                  rset;
+       socklen_t               clilen;
+       struct sockaddr *cliaddr;
+
+       cliaddr = Malloc(addrlen);
+
+       printf("child %ld starting\n", (long) getpid());
+       FD_ZERO(&rset);
+       for ( ; ; ) {
+               FD_SET(listenfd, &rset);
+               Select(listenfd+1, &rset, NULL, NULL, NULL);
+               if (FD_ISSET(listenfd, &rset) == 0)
+                       err_quit("listenfd readable");
+
+               clilen = addrlen;
+               connfd = Accept(listenfd, cliaddr, &clilen);
+
+               web_child(connfd);              /* process the request */
+               Close(connfd);
+       }
+}
diff --git a/server/child02m.c b/server/child02m.c
new file mode 100644 (file)
index 0000000..ecd7359
--- /dev/null
@@ -0,0 +1,35 @@
+#include       "unp.h"
+
+pid_t
+child_make(int i, int listenfd, int addrlen)
+{
+       pid_t   pid;
+       void    child_main(int, int, int);
+
+       if ( (pid = Fork()) > 0)
+               return(pid);            /* parent */
+
+       child_main(i, listenfd, addrlen);       /* never returns */
+}
+
+void
+child_main(int i, int listenfd, int addrlen)
+{
+       int                             connfd;
+       void                    web_child(int);
+       socklen_t               clilen;
+       struct sockaddr *cliaddr;
+       extern long             *cptr;
+
+       cliaddr = Malloc(addrlen);
+
+       printf("child %ld starting\n", (long) getpid());
+       for ( ; ; ) {
+               clilen = addrlen;
+               connfd = Accept(listenfd, cliaddr, &clilen);
+               cptr[i]++;
+
+               web_child(connfd);              /* process the request */
+               Close(connfd);
+       }
+}
diff --git a/server/child03.c b/server/child03.c
new file mode 100644 (file)
index 0000000..ab67dc8
--- /dev/null
@@ -0,0 +1,35 @@
+#include       "unp.h"
+
+pid_t
+child_make(int i, int listenfd, int addrlen)
+{
+       pid_t   pid;
+       void    child_main(int, int, int);
+
+       if ( (pid = Fork()) > 0)
+               return(pid);            /* parent */
+
+       child_main(i, listenfd, addrlen);       /* never returns */
+}
+
+void
+child_main(int i, int listenfd, int addrlen)
+{
+       int                             connfd;
+       void                    web_child(int);
+       socklen_t               clilen;
+       struct sockaddr *cliaddr;
+
+       cliaddr = Malloc(addrlen);
+
+       printf("child %ld starting\n", (long) getpid());
+       for ( ; ; ) {
+               clilen = addrlen;
+               my_lock_wait();
+               connfd = Accept(listenfd, cliaddr, &clilen);
+               my_lock_release();
+
+               web_child(connfd);              /* process the request */
+               Close(connfd);
+       }
+}
diff --git a/server/child03m.c b/server/child03m.c
new file mode 100644 (file)
index 0000000..f906073
--- /dev/null
@@ -0,0 +1,37 @@
+#include       "unp.h"
+
+pid_t
+child_make(int i, int listenfd, int addrlen)
+{
+       pid_t   pid;
+       void    child_main(int, int, int);
+
+       if ( (pid = Fork()) > 0)
+               return(pid);            /* parent */
+
+       child_main(i, listenfd, addrlen);       /* never returns */
+}
+
+void
+child_main(int i, int listenfd, int addrlen)
+{
+       int                             connfd;
+       void                    web_child(int);
+       socklen_t               clilen;
+       struct sockaddr *cliaddr;
+       extern long             *cptr;
+
+       cliaddr = Malloc(addrlen);
+
+       printf("child %ld starting\n", (long) getpid());
+       for ( ; ; ) {
+               clilen = addrlen;
+               my_lock_wait();
+               connfd = Accept(listenfd, cliaddr, &clilen);
+               my_lock_release();
+               cptr[i]++;
+
+               web_child(connfd);              /* process the request */
+               Close(connfd);
+       }
+}
diff --git a/server/child04.c b/server/child04.c
new file mode 100644 (file)
index 0000000..ab67dc8
--- /dev/null
@@ -0,0 +1,35 @@
+#include       "unp.h"
+
+pid_t
+child_make(int i, int listenfd, int addrlen)
+{
+       pid_t   pid;
+       void    child_main(int, int, int);
+
+       if ( (pid = Fork()) > 0)
+               return(pid);            /* parent */
+
+       child_main(i, listenfd, addrlen);       /* never returns */
+}
+
+void
+child_main(int i, int listenfd, int addrlen)
+{
+       int                             connfd;
+       void                    web_child(int);
+       socklen_t               clilen;
+       struct sockaddr *cliaddr;
+
+       cliaddr = Malloc(addrlen);
+
+       printf("child %ld starting\n", (long) getpid());
+       for ( ; ; ) {
+               clilen = addrlen;
+               my_lock_wait();
+               connfd = Accept(listenfd, cliaddr, &clilen);
+               my_lock_release();
+
+               web_child(connfd);              /* process the request */
+               Close(connfd);
+       }
+}
diff --git a/server/child05.c b/server/child05.c
new file mode 100644 (file)
index 0000000..a17bf42
--- /dev/null
@@ -0,0 +1,52 @@
+/* include child_make */
+#include       "unp.h"
+#include       "child.h"
+
+pid_t
+child_make(int i, int listenfd, int addrlen)
+{
+       int             sockfd[2];
+       pid_t   pid;
+       void    child_main(int, int, int);
+
+       Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);
+
+       if ( (pid = Fork()) > 0) {
+               Close(sockfd[1]);
+               cptr[i].child_pid = pid;
+               cptr[i].child_pipefd = sockfd[0];
+               cptr[i].child_status = 0;
+               return(pid);            /* parent */
+       }
+
+       Dup2(sockfd[1], STDERR_FILENO);         /* child's stream pipe to parent */
+       Close(sockfd[0]);
+       Close(sockfd[1]);
+       Close(listenfd);                                        /* child does not need this open */
+       child_main(i, listenfd, addrlen);       /* never returns */
+}
+/* end child_make */
+
+/* include child_main */
+void
+child_main(int i, int listenfd, int addrlen)
+{
+       char                    c;
+       int                             connfd;
+       ssize_t                 n;
+       void                    web_child(int);
+
+       printf("child %ld starting\n", (long) getpid());
+       for ( ; ; ) {
+               if ( (n = Read_fd(STDERR_FILENO, &c, 1, &connfd)) == 0)
+                       err_quit("read_fd returned 0");
+               if (connfd < 0)
+                       err_quit("no descriptor from read_fd");
+
+               web_child(connfd);                              /* process request */
+               Close(connfd);
+
+               Write(STDERR_FILENO, "", 1);    /* tell parent we're ready again */
+       }
+}
+/* end child_main */
diff --git a/server/child05.lc b/server/child05.lc
new file mode 100644 (file)
index 0000000..4380ee0
--- /dev/null
@@ -0,0 +1,52 @@
+/* include child_make */
+#include    "unp.h"##  1 ##src/server/child05.c##
+#include    "child.h"##  2 ##src/server/child05.c##
+
+pid_t##  3 ##src/server/child05.c##
+child_make(int i, int listenfd, int addrlen)##  4 ##src/server/child05.c##
+{##  5 ##src/server/child05.c##
+    int     sockfd[2];##  6 ##src/server/child05.c##
+    pid_t   pid;##  7 ##src/server/child05.c##
+    void    child_main(int, int, int);##  8 ##src/server/child05.c##
+
+    Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);##  9 ##src/server/child05.c##
+
+    if ((pid = Fork()) > 0) {## 10 ##src/server/child05.c##
+        Close(sockfd[1]);## 11 ##src/server/child05.c##
+        cptr[i].child_pid = pid;## 12 ##src/server/child05.c##
+        cptr[i].child_pipefd = sockfd[0];## 13 ##src/server/child05.c##
+        cptr[i].child_status = 0;## 14 ##src/server/child05.c##
+        return (pid);           /* parent */## 15 ##src/server/child05.c##
+    }## 16 ##src/server/child05.c##
+
+    Dup2(sockfd[1], STDERR_FILENO); /* child's stream pipe to parent */## 17 ##src/server/child05.c##
+    Close(sockfd[0]);## 18 ##src/server/child05.c##
+    Close(sockfd[1]);## 19 ##src/server/child05.c##
+    Close(listenfd);            /* child does not need this open */## 20 ##src/server/child05.c##
+    child_main(i, listenfd, addrlen);   /* never returns */## 21 ##src/server/child05.c##
+}## 22 ##src/server/child05.c##
+/* end child_make */
+
+/* include child_main */
+void## 23 ##src/server/child05.c##
+child_main(int i, int listenfd, int addrlen)## 24 ##src/server/child05.c##
+{## 25 ##src/server/child05.c##
+    char    c;## 26 ##src/server/child05.c##
+    int     connfd;## 27 ##src/server/child05.c##
+    ssize_t n;## 28 ##src/server/child05.c##
+    void    web_child(int);## 29 ##src/server/child05.c##
+
+    printf("child %ld starting\n", (long) getpid());## 30 ##src/server/child05.c##
+    for (;;) {## 31 ##src/server/child05.c##
+        if ((n = Read_fd(STDERR_FILENO, &c, 1, &connfd)) == 0)## 32 ##src/server/child05.c##
+            err_quit("read_fd returned 0");## 33 ##src/server/child05.c##
+        if (connfd < 0)## 34 ##src/server/child05.c##
+            err_quit("no descriptor from read_fd");## 35 ##src/server/child05.c##
+
+        web_child(connfd);      /* process the request */## 36 ##src/server/child05.c##
+        Close(connfd);## 37 ##src/server/child05.c##
+
+        Write(STDERR_FILENO, "", 1);    /* tell parent we're ready again */## 38 ##src/server/child05.c##
+    }## 39 ##src/server/child05.c##
+}## 40 ##src/server/child05.c##
+/* end child_main */
diff --git a/server/client.c b/server/client.c
new file mode 100644 (file)
index 0000000..33fdf0b
--- /dev/null
@@ -0,0 +1,46 @@
+#include       "unp.h"
+
+#define        MAXN    16384           /* max # bytes to request from server */
+
+int
+main(int argc, char **argv)
+{
+       int             i, j, fd, nchildren, nloops, nbytes;
+       pid_t   pid;
+       ssize_t n;
+       char    request[MAXLINE], reply[MAXN];
+
+       if (argc != 6)
+               err_quit("usage: client <hostname or IPaddr> <port> <#children> "
+                                "<#loops/child> <#bytes/request>");
+
+       nchildren = atoi(argv[3]);
+       nloops = atoi(argv[4]);
+       nbytes = atoi(argv[5]);
+       snprintf(request, sizeof(request), "%d\n", nbytes); /* newline at end */
+
+       for (i = 0; i < nchildren; i++) {
+               if ( (pid = Fork()) == 0) {             /* child */
+                       for (j = 0; j < nloops; j++) {
+                               fd = Tcp_connect(argv[1], argv[2]);
+
+                               Write(fd, request, strlen(request));
+
+                               if ( (n = Readn(fd, reply, nbytes)) != nbytes)
+                                       err_quit("server returned %d bytes", n);
+
+                               Close(fd);              /* TIME_WAIT on client, not server */
+                       }
+                       printf("child %d done\n", i);
+                       exit(0);
+               }
+               /* parent loops around to fork() again */
+       }
+
+       while (wait(NULL) > 0)  /* now parent waits for all children */
+               ;
+       if (errno != ECHILD)
+               err_sys("wait error");
+
+       exit(0);
+}
diff --git a/server/clientrst.c b/server/clientrst.c
new file mode 100644 (file)
index 0000000..9d163e4
--- /dev/null
@@ -0,0 +1,70 @@
+#include       "unp.h"
+
+#define        MAXN    16384           /* max #bytes to request from server */
+
+int
+main(int argc, char **argv)
+{
+       int             i, j, fd, nchildren, nloops, nbytes;
+       pid_t   pid;
+       ssize_t n;
+       char    request[MAXLINE], reply[MAXN];
+
+       if (argc != 6)
+               err_quit("usage: client <hostname or IPaddr> <port> <#children> "
+                                "<#loops/child> <#bytes/request>");
+
+       nchildren = atoi(argv[3]);
+       nloops = atoi(argv[4]);
+       nbytes = atoi(argv[5]);
+       snprintf(request, sizeof(request), "%d\n", nbytes);     /* newline at end */
+
+       for (i = 0; i < nchildren; i++) {
+               if ( (pid = Fork()) == 0) {             /* child */
+                       for (j = 0; j < nloops; j++) {
+                               fd = Tcp_connect(argv[1], argv[2]);
+
+                               /*
+                                * We want to see what happens to the server when it has
+                                * connections outstanding and an RST arrives for one of
+                                * them, before the connection is accepted.
+                                * With the XTI server, this should generate some
+                                * T_DISCONNECT events from t_accept(), which must be
+                                * handled correctly.
+                                *
+                                * We do this for every third connection from the third
+                                * client child.  (Could add more command-line args ...)
+                                */
+
+                               if (i == 2 && (j % 3) == 0) {
+                                       struct linger   ling;
+
+                                       ling.l_onoff = 1;
+                                       ling.l_linger = 0;
+                                       Setsockopt(fd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
+                                       Close(fd);
+
+                                       /* and just continue on for this client connection ... */
+                                       fd = Tcp_connect(argv[1], argv[2]);
+                               }
+
+                               Write(fd, request, strlen(request));
+
+                               if ( (n = Readn(fd, reply, nbytes)) != nbytes)
+                                       err_quit("server returned %d bytes", n);
+
+                               Close(fd);              /* TIME_WAIT on client, not server */
+                       }
+                       printf("child %d done\n", i);
+                       exit(0);
+               }
+               /* parent loops around to fork() again */
+       }
+
+       while (wait(NULL) > 0)  /* now parent waits for all children */
+               ;
+       if (errno != ECHILD)
+               err_sys("wait error");
+
+       exit(0);
+}
diff --git a/server/lock_fcntl.c b/server/lock_fcntl.c
new file mode 100644 (file)
index 0000000..ae513d9
--- /dev/null
@@ -0,0 +1,51 @@
+/* include my_lock_init */
+#include       "unp.h"
+
+static struct flock    lock_it, unlock_it;
+static int                     lock_fd = -1;
+                                       /* fcntl() will fail if my_lock_init() not called */
+
+void
+my_lock_init(char *pathname)
+{
+    char       lock_file[1024];
+
+               /* 4must copy caller's string, in case it's a constant */
+    strncpy(lock_file, pathname, sizeof(lock_file));
+    lock_fd = Mkstemp(lock_file);
+
+    Unlink(lock_file);                 /* but lock_fd remains open */
+
+       lock_it.l_type = F_WRLCK;
+       lock_it.l_whence = SEEK_SET;
+       lock_it.l_start = 0;
+       lock_it.l_len = 0;
+
+       unlock_it.l_type = F_UNLCK;
+       unlock_it.l_whence = SEEK_SET;
+       unlock_it.l_start = 0;
+       unlock_it.l_len = 0;
+}
+/* end my_lock_init */
+
+/* include my_lock_wait */
+void
+my_lock_wait()
+{
+    int                rc;
+    
+    while ( (rc = fcntl(lock_fd, F_SETLKW, &lock_it)) < 0) {
+               if (errno == EINTR)
+                       continue;
+       else
+                       err_sys("fcntl error for my_lock_wait");
+       }
+}
+
+void
+my_lock_release()
+{
+    if (fcntl(lock_fd, F_SETLKW, &unlock_it) < 0)
+               err_sys("fcntl error for my_lock_release");
+}
+/* end my_lock_wait */
diff --git a/server/lock_fcntl.lc b/server/lock_fcntl.lc
new file mode 100644 (file)
index 0000000..0d1c47e
--- /dev/null
@@ -0,0 +1,51 @@
+/* include my_lock_init */
+#include    "unp.h"##  1 ##src/server/lock_fcntl.c##
+
+static struct flock lock_it, unlock_it;##  2 ##src/server/lock_fcntl.c##
+static int lock_fd = -1;##  3 ##src/server/lock_fcntl.c##
+                    /* fcntl() will fail if my_lock_init() not called */##  4 ##src/server/lock_fcntl.c##
+
+void##  5 ##src/server/lock_fcntl.c##
+my_lock_init(char *pathname)##  6 ##src/server/lock_fcntl.c##
+{##  7 ##src/server/lock_fcntl.c##
+    char    lock_file[1024];##  8 ##src/server/lock_fcntl.c##
+
+    /* 4must copy caller's string, in case it's a constant */##  9 ##src/server/lock_fcntl.c##
+    strncpy(lock_file, pathname, sizeof(lock_file));## 10 ##src/server/lock_fcntl.c##
+    lock_fd = Mkstemp(lock_file);## 11 ##src/server/lock_fcntl.c##
+
+    Unlink(lock_file);          /* but lock_fd remains open */## 12 ##src/server/lock_fcntl.c##
+
+    lock_it.l_type = F_WRLCK;## 13 ##src/server/lock_fcntl.c##
+    lock_it.l_whence = SEEK_SET;## 14 ##src/server/lock_fcntl.c##
+    lock_it.l_start = 0;## 15 ##src/server/lock_fcntl.c##
+    lock_it.l_len = 0;## 16 ##src/server/lock_fcntl.c##
+
+    unlock_it.l_type = F_UNLCK;## 17 ##src/server/lock_fcntl.c##
+    unlock_it.l_whence = SEEK_SET;## 18 ##src/server/lock_fcntl.c##
+    unlock_it.l_start = 0;## 19 ##src/server/lock_fcntl.c##
+    unlock_it.l_len = 0;## 20 ##src/server/lock_fcntl.c##
+}## 21 ##src/server/lock_fcntl.c##
+/* end my_lock_init */
+
+/* include my_lock_wait */
+void## 22 ##src/server/lock_fcntl.c##
+my_lock_wait()## 23 ##src/server/lock_fcntl.c##
+{## 24 ##src/server/lock_fcntl.c##
+    int     rc;## 25 ##src/server/lock_fcntl.c##
+
+    while ((rc = fcntl(lock_fd, F_SETLKW, &lock_it)) < 0) {## 26 ##src/server/lock_fcntl.c##
+        if (errno == EINTR)## 27 ##src/server/lock_fcntl.c##
+            continue;## 28 ##src/server/lock_fcntl.c##
+        else## 29 ##src/server/lock_fcntl.c##
+            err_sys("fcntl error for my_lock_wait");## 30 ##src/server/lock_fcntl.c##
+    }## 31 ##src/server/lock_fcntl.c##
+}## 32 ##src/server/lock_fcntl.c##
+
+void## 33 ##src/server/lock_fcntl.c##
+my_lock_release()## 34 ##src/server/lock_fcntl.c##
+{## 35 ##src/server/lock_fcntl.c##
+    if (fcntl(lock_fd, F_SETLKW, &unlock_it) < 0)## 36 ##src/server/lock_fcntl.c##
+        err_sys("fcntl error for my_lock_release");## 37 ##src/server/lock_fcntl.c##
+}## 38 ##src/server/lock_fcntl.c##
+/* end my_lock_wait */
diff --git a/server/lock_pthread.c b/server/lock_pthread.c
new file mode 100644 (file)
index 0000000..7c9de9e
--- /dev/null
@@ -0,0 +1,37 @@
+/* include my_lock_init */
+#include       "unpthread.h"
+#include       <sys/mman.h>
+
+static pthread_mutex_t *mptr;  /* actual mutex will be in shared memory */
+
+void
+my_lock_init(char *pathname)
+{
+       int             fd;
+       pthread_mutexattr_t     mattr;
+
+       fd = Open("/dev/zero", O_RDWR, 0);
+
+       mptr = Mmap(0, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE,
+                               MAP_SHARED, fd, 0);
+       Close(fd);
+
+       Pthread_mutexattr_init(&mattr);
+       Pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
+       Pthread_mutex_init(mptr, &mattr);
+}
+/* end my_lock_init */
+
+/* include my_lock_wait */
+void
+my_lock_wait()
+{
+       Pthread_mutex_lock(mptr);
+}
+
+void
+my_lock_release()
+{
+       Pthread_mutex_unlock(mptr);
+}
+/* end my_lock_wait */
diff --git a/server/lock_pthread.lc b/server/lock_pthread.lc
new file mode 100644 (file)
index 0000000..ac79541
--- /dev/null
@@ -0,0 +1,37 @@
+/* include my_lock_init */
+#include    "unpthread.h"##  1 ##src/server/lock_pthread.c##
+#include    <sys/mman.h>##  2 ##src/server/lock_pthread.c##
+
+static pthread_mutex_t *mptr;   /* actual mutex will be in shared memory */##  3 ##src/server/lock_pthread.c##
+
+void##  4 ##src/server/lock_pthread.c##
+my_lock_init(char *pathname)##  5 ##src/server/lock_pthread.c##
+{##  6 ##src/server/lock_pthread.c##
+    int     fd;##  7 ##src/server/lock_pthread.c##
+    pthread_mutexattr_t mattr;##  8 ##src/server/lock_pthread.c##
+
+    fd = Open("/dev/zero", O_RDWR, 0);##  9 ##src/server/lock_pthread.c##
+
+    mptr = Mmap(0, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE,## 10 ##src/server/lock_pthread.c##
+                MAP_SHARED, fd, 0);## 11 ##src/server/lock_pthread.c##
+    Close(fd);## 12 ##src/server/lock_pthread.c##
+
+    Pthread_mutexattr_init(&mattr);## 13 ##src/server/lock_pthread.c##
+    Pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);## 14 ##src/server/lock_pthread.c##
+    Pthread_mutex_init(mptr, &mattr);## 15 ##src/server/lock_pthread.c##
+}## 16 ##src/server/lock_pthread.c##
+/* end my_lock_init */
+
+/* include my_lock_wait */
+void## 17 ##src/server/lock_pthread.c##
+my_lock_wait()## 18 ##src/server/lock_pthread.c##
+{## 19 ##src/server/lock_pthread.c##
+    Pthread_mutex_lock(mptr);## 20 ##src/server/lock_pthread.c##
+}## 21 ##src/server/lock_pthread.c##
+
+void## 22 ##src/server/lock_pthread.c##
+my_lock_release()## 23 ##src/server/lock_pthread.c##
+{## 24 ##src/server/lock_pthread.c##
+    Pthread_mutex_unlock(mptr);## 25 ##src/server/lock_pthread.c##
+}## 26 ##src/server/lock_pthread.c##
+/* end my_lock_wait */
diff --git a/server/meter.c b/server/meter.c
new file mode 100644 (file)
index 0000000..2f11fbc
--- /dev/null
@@ -0,0 +1,28 @@
+#include       "unp.h"
+#include       <sys/mman.h>
+
+/*
+ * Allocate an array of "nchildren" longs in shared memory that can
+ * be used as a counter by each child of how many clients it services.
+ * See pp. 467-470 of "Advanced Programming in the Unix Environment."
+ */
+
+long *
+meter(int nchildren)
+{
+       int             fd;
+       long    *ptr;
+
+#ifdef MAP_ANON
+       ptr = Mmap(0, nchildren*sizeof(long), PROT_READ | PROT_WRITE,
+                          MAP_ANON | MAP_SHARED, -1, 0);
+#else
+       fd = Open("/dev/zero", O_RDWR, 0);
+
+       ptr = Mmap(0, nchildren*sizeof(long), PROT_READ | PROT_WRITE,
+                          MAP_SHARED, fd, 0);
+       Close(fd);
+#endif
+
+       return(ptr);
+}
diff --git a/server/pr_cpu_time.c b/server/pr_cpu_time.c
new file mode 100644 (file)
index 0000000..8bc8525
--- /dev/null
@@ -0,0 +1,29 @@
+#include       "unp.h"
+#include       <sys/resource.h>
+
+#ifndef        HAVE_GETRUSAGE_PROTO
+int            getrusage(int, struct rusage *);
+#endif
+
+void
+pr_cpu_time(void)
+{
+       double                  user, sys;
+       struct rusage   myusage, childusage;
+
+       if (getrusage(RUSAGE_SELF, &myusage) < 0)
+               err_sys("getrusage error");
+       if (getrusage(RUSAGE_CHILDREN, &childusage) < 0)
+               err_sys("getrusage error");
+
+       user = (double) myusage.ru_utime.tv_sec +
+                                       myusage.ru_utime.tv_usec/1000000.0;
+       user += (double) childusage.ru_utime.tv_sec +
+                                        childusage.ru_utime.tv_usec/1000000.0;
+       sys = (double) myusage.ru_stime.tv_sec +
+                                  myusage.ru_stime.tv_usec/1000000.0;
+       sys += (double) childusage.ru_stime.tv_sec +
+                                       childusage.ru_stime.tv_usec/1000000.0;
+
+       printf("\nuser time = %g, sys time = %g\n", user, sys);
+}
diff --git a/server/pthread07.c b/server/pthread07.c
new file mode 100644 (file)
index 0000000..6b43629
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unpthread.h"
+#include       "pthread07.h"
+
+void
+thread_make(int i)
+{
+       void    *thread_main(void *);
+
+       Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void *) i);
+       return;         /* main thread returns */
+}
+
+void *
+thread_main(void *arg)
+{
+       int                             connfd;
+       void                    web_child(int);
+       socklen_t               clilen;
+       struct sockaddr *cliaddr;
+
+       cliaddr = Malloc(addrlen);
+
+       printf("thread %d starting\n", (int) arg);
+       for ( ; ; ) {
+               clilen = addrlen;
+       Pthread_mutex_lock(&mlock);
+               connfd = Accept(listenfd, cliaddr, &clilen);
+               Pthread_mutex_unlock(&mlock);
+               tptr[(int) arg].thread_count++;
+
+               web_child(connfd);              /* process request */
+               Close(connfd);
+       }
+}
diff --git a/server/pthread07.h b/server/pthread07.h
new file mode 100644 (file)
index 0000000..5ac04f1
--- /dev/null
@@ -0,0 +1,9 @@
+typedef struct {
+  pthread_t            thread_tid;             /* thread ID */
+  long                 thread_count;   /* # connections handled */
+} Thread;
+Thread *tptr;          /* array of Thread structures; calloc'ed */
+
+int                            listenfd, nthreads;
+socklen_t              addrlen;
+pthread_mutex_t        mlock;
diff --git a/server/pthread07.lc b/server/pthread07.lc
new file mode 100644 (file)
index 0000000..406fae0
--- /dev/null
@@ -0,0 +1,34 @@
+#include    "unpthread.h"##  1 ##src/server/pthread07.c##
+#include    "pthread07.h"##  2 ##src/server/pthread07.c##
+
+void##  3 ##src/server/pthread07.c##
+thread_make(int i)##  4 ##src/server/pthread07.c##
+{##  5 ##src/server/pthread07.c##
+    void   *thread_main(void *);##  6 ##src/server/pthread07.c##
+
+    Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void *) i);##  7 ##src/server/pthread07.c##
+    return;                     /* main thread returns */##  8 ##src/server/pthread07.c##
+}##  9 ##src/server/pthread07.c##
+
+void   *## 10 ##src/server/pthread07.c##
+thread_main(void *arg)## 11 ##src/server/pthread07.c##
+{## 12 ##src/server/pthread07.c##
+    int     connfd;## 13 ##src/server/pthread07.c##
+    void    web_child(int);## 14 ##src/server/pthread07.c##
+    socklen_t clilen;## 15 ##src/server/pthread07.c##
+    struct sockaddr *cliaddr;## 16 ##src/server/pthread07.c##
+
+    cliaddr = Malloc(addrlen);## 17 ##src/server/pthread07.c##
+
+    printf("thread %d starting\n", (int) arg);## 18 ##src/server/pthread07.c##
+    for (;;) {## 19 ##src/server/pthread07.c##
+        clilen = addrlen;## 20 ##src/server/pthread07.c##
+        Pthread_mutex_lock(&mlock);## 21 ##src/server/pthread07.c##
+        connfd = Accept(listenfd, cliaddr, &clilen);## 22 ##src/server/pthread07.c##
+        Pthread_mutex_unlock(&mlock);## 23 ##src/server/pthread07.c##
+        tptr[(int) arg].thread_count++;## 24 ##src/server/pthread07.c##
+
+        web_child(connfd);      /* process the request */## 25 ##src/server/pthread07.c##
+        Close(connfd);## 26 ##src/server/pthread07.c##
+    }## 27 ##src/server/pthread07.c##
+}## 28 ##src/server/pthread07.c##
diff --git a/server/pthread08.c b/server/pthread08.c
new file mode 100644 (file)
index 0000000..8177cea
--- /dev/null
@@ -0,0 +1,33 @@
+#include       "unpthread.h"
+#include       "pthread08.h"
+
+void
+thread_make(int i)
+{
+       void    *thread_main(void *);
+
+       Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void *) i);
+       return;         /* main thread returns */
+}
+
+void *
+thread_main(void *arg)
+{
+       int             connfd;
+       void    web_child(int);
+
+       printf("thread %d starting\n", (int) arg);
+       for ( ; ; ) {
+       Pthread_mutex_lock(&clifd_mutex);
+               while (iget == iput)
+                       Pthread_cond_wait(&clifd_cond, &clifd_mutex);
+               connfd = clifd[iget];   /* connected socket to service */
+               if (++iget == MAXNCLI)
+                       iget = 0;
+               Pthread_mutex_unlock(&clifd_mutex);
+               tptr[(int) arg].thread_count++;
+
+               web_child(connfd);              /* process request */
+               Close(connfd);
+       }
+}
diff --git a/server/pthread08.h b/server/pthread08.h
new file mode 100644 (file)
index 0000000..5964553
--- /dev/null
@@ -0,0 +1,10 @@
+typedef struct {
+  pthread_t            thread_tid;             /* thread ID */
+  long                 thread_count;   /* # connections handled */
+} Thread;
+Thread *tptr;          /* array of Thread structures; calloc'ed */
+
+#define        MAXNCLI 32
+int                                    clifd[MAXNCLI], iget, iput;
+pthread_mutex_t                clifd_mutex;
+pthread_cond_t         clifd_cond;
diff --git a/server/pthread08.lc b/server/pthread08.lc
new file mode 100644 (file)
index 0000000..8a57aa0
--- /dev/null
@@ -0,0 +1,33 @@
+#include    "unpthread.h"##  1 ##src/server/pthread08.c##
+#include    "pthread08.h"##  2 ##src/server/pthread08.c##
+
+void##  3 ##src/server/pthread08.c##
+thread_make(int i)##  4 ##src/server/pthread08.c##
+{##  5 ##src/server/pthread08.c##
+    void   *thread_main(void *);##  6 ##src/server/pthread08.c##
+
+    Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void *) i);##  7 ##src/server/pthread08.c##
+    return;                     /* main thread returns */##  8 ##src/server/pthread08.c##
+}##  9 ##src/server/pthread08.c##
+
+void   *## 10 ##src/server/pthread08.c##
+thread_main(void *arg)## 11 ##src/server/pthread08.c##
+{## 12 ##src/server/pthread08.c##
+    int     connfd;## 13 ##src/server/pthread08.c##
+    void    web_child(int);## 14 ##src/server/pthread08.c##
+
+    printf("thread %d starting\n", (int) arg);## 15 ##src/server/pthread08.c##
+    for (;;) {## 16 ##src/server/pthread08.c##
+        Pthread_mutex_lock(&clifd_mutex);## 17 ##src/server/pthread08.c##
+        while (iget == iput)## 18 ##src/server/pthread08.c##
+            Pthread_cond_wait(&clifd_cond, &clifd_mutex);## 19 ##src/server/pthread08.c##
+        connfd = clifd[iget];   /* connected socket to service */## 20 ##src/server/pthread08.c##
+        if (++iget == MAXNCLI)## 21 ##src/server/pthread08.c##
+            iget = 0;## 22 ##src/server/pthread08.c##
+        Pthread_mutex_unlock(&clifd_mutex);## 23 ##src/server/pthread08.c##
+        tptr[(int) arg].thread_count++;## 24 ##src/server/pthread08.c##
+
+        web_child(connfd);      /* process the request */## 25 ##src/server/pthread08.c##
+        Close(connfd);## 26 ##src/server/pthread08.c##
+    }## 27 ##src/server/pthread08.c##
+}## 28 ##src/server/pthread08.c##
diff --git a/server/pthread09.c b/server/pthread09.c
new file mode 100644 (file)
index 0000000..9a2aac1
--- /dev/null
@@ -0,0 +1,32 @@
+#include       "unpthread.h"
+#include       "pthread09.h"
+
+void
+thread_make(int i)
+{
+       void    *thread_main(void *);
+
+       Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void *) i);
+       return;         /* main thread returns */
+}
+
+void *
+thread_main(void *arg)
+{
+       int                             connfd;
+       void                    web_child(int);
+       socklen_t               clilen;
+       struct sockaddr *cliaddr;
+
+       cliaddr = Malloc(addrlen);
+
+       printf("thread %d starting\n", (int) arg);
+       for ( ; ; ) {
+               clilen = addrlen;
+               connfd = Accept(listenfd, cliaddr, &clilen);
+               tptr[(int) arg].thread_count++;
+
+               web_child(connfd);              /* process the request */
+               Close(connfd);
+       }
+}
diff --git a/server/pthread09.h b/server/pthread09.h
new file mode 100644 (file)
index 0000000..1256af8
--- /dev/null
@@ -0,0 +1,8 @@
+typedef struct {
+  pthread_t            thread_tid;             /* thread ID */
+  long                 thread_count;   /* #connections handled */
+} Thread;
+Thread *tptr;          /* array of Thread structures; calloc'ed */
+
+int                            listenfd, nthreads;
+socklen_t              addrlen;
diff --git a/server/readline.c b/server/readline.c
new file mode 100644 (file)
index 0000000..39b5fac
--- /dev/null
@@ -0,0 +1,38 @@
+/* include readline */
+#include       "unp.h"
+
+ssize_t
+readline(int fd, void *vptr, size_t maxlen)
+{
+       ssize_t n, rc;
+       char    c, *ptr;
+
+       ptr = vptr;
+       for (n = 1; n < maxlen; n++) {
+               if ( (rc = read(fd, &c, 1)) == 1) {
+                       *ptr++ = c;
+                       if (c == '\n')
+                               break;
+               } else if (rc == 0) {
+                       if (n == 1)
+                               return(0);      /* EOF, no data read */
+                       else
+                               break;          /* EOF, some data was read */
+               } else
+                       return(-1);     /* error */
+       }
+
+       *ptr = 0;
+       return(n);
+}
+/* end readline */
+
+ssize_t
+Readline(int fd, void *ptr, size_t maxlen)
+{
+       ssize_t         n;
+
+       if ( (n = readline(fd, ptr, maxlen)) == -1)
+               err_sys("readline error");
+       return(n);
+}
diff --git a/server/readline_r.c b/server/readline_r.c
new file mode 100644 (file)
index 0000000..bc22039
--- /dev/null
@@ -0,0 +1,72 @@
+/* include readline */
+#include       "unp.h"
+#include       "readline_r.h"
+
+static ssize_t
+my_read_r(Rline *rptr, char *ptr)
+{
+       if (rptr->rl_cnt <= 0) {
+again:
+               rptr->rl_cnt = read(rptr->read_fd, rptr->rl_buf, sizeof(rptr->rl_buf));
+               if (rptr->rl_cnt < 0) {
+                       if (errno == EINTR)
+                               goto again;
+                       else
+                               return(-1);
+               }
+               else if (rptr->rl_cnt == 0)
+                       return(0);
+               rptr->rl_bufptr = rptr->rl_buf;
+       }
+
+       rptr->rl_cnt--;
+       *ptr = *rptr->rl_bufptr++ & 255;
+       return(1);
+}
+
+void
+readline_rinit(int fd, void *ptr, size_t maxlen, Rline *rptr)
+{
+       rptr->read_fd = fd;                             /* save caller's arguments */
+       rptr->read_ptr = ptr;
+       rptr->read_maxlen = maxlen;
+
+       rptr->rl_cnt = 0;                               /* and init our counter & pointer */
+       rptr->rl_bufptr = rptr->rl_buf;
+}
+
+ssize_t
+readline_r(Rline *rptr)
+{
+       int             n, rc;
+       char    c, *ptr;
+
+       ptr = rptr->read_ptr;
+       for (n = 1; n < rptr->read_maxlen; n++) {
+               if ( (rc = my_read_r(rptr, &c)) == 1) {
+                       *ptr++ = c;
+                       if (c == '\n')
+                               break;
+               } else if (rc == 0) {
+                       if (n == 1)
+                               return(0);      /* EOF, no data read */
+                       else
+                               break;          /* EOF, some data was read */
+               } else
+                       return(-1);     /* error */
+       }
+
+       *ptr = 0;
+       return(n);
+}
+/* end readline */
+
+ssize_t
+Readline_r(Rline *rptr)
+{
+       ssize_t         n;
+
+       if ( (n = readline_r(rptr)) == -1)
+               err_sys("readline_r error");
+       return(n);
+}
diff --git a/server/readline_r.h b/server/readline_r.h
new file mode 100644 (file)
index 0000000..9fe1dbe
--- /dev/null
@@ -0,0 +1,13 @@
+typedef struct {
+  int          read_fd;                /* caller's descriptor to read from */
+  char         *read_ptr;              /* caller's buffer to read into */
+  size_t       read_maxlen;    /* max #bytes to read */
+                               /* next three are used internally by the function */
+  int          rl_cnt;                 /* initialize to 0 */
+  char         *rl_bufptr;             /* initialize to rl_buf */
+  char         rl_buf[MAXLINE];
+} Rline;
+
+void   readline_rinit(int, void *, size_t, Rline *);
+ssize_t        readline_r(Rline *);
+ssize_t        Readline_r(Rline *);
diff --git a/server/serv00.c b/server/serv00.c
new file mode 100644 (file)
index 0000000..6f712ba
--- /dev/null
@@ -0,0 +1,42 @@
+/* include serv00 */
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       void                            sig_int(int), web_child(int);
+       socklen_t                       clilen, addrlen;
+       struct sockaddr         *cliaddr;
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: serv00 [ <host> ] <port#>");
+       cliaddr = Malloc(addrlen);
+
+       Signal(SIGINT, sig_int);
+
+       for ( ; ; ) {
+               clilen = addrlen;
+               connfd = Accept(listenfd, cliaddr, &clilen);
+
+               web_child(connfd);              /* process the request */
+
+               Close(connfd);                  /* parent closes connected socket */
+       }
+}
+/* end serv00 */
+
+/* include sigint */
+void
+sig_int(int signo)
+{
+       void    pr_cpu_time(void);
+
+       pr_cpu_time();
+       exit(0);
+}
+/* end sigint */
diff --git a/server/serv01.c b/server/serv01.c
new file mode 100644 (file)
index 0000000..2d59aa3
--- /dev/null
@@ -0,0 +1,52 @@
+/* include serv01 */
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       pid_t                           childpid;
+       void                            sig_chld(int), sig_int(int), web_child(int);
+       socklen_t                       clilen, addrlen;
+       struct sockaddr         *cliaddr;
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: serv01 [ <host> ] <port#>");
+       cliaddr = Malloc(addrlen);
+
+       Signal(SIGCHLD, sig_chld);
+       Signal(SIGINT, sig_int);
+
+       for ( ; ; ) {
+               clilen = addrlen;
+               if ( (connfd = accept(listenfd, cliaddr, &clilen)) < 0) {
+                       if (errno == EINTR)
+                               continue;               /* back to for() */
+                       else
+                               err_sys("accept error");
+               }
+
+               if ( (childpid = Fork()) == 0) {        /* child process */
+                       Close(listenfd);        /* close listening socket */
+                       web_child(connfd);      /* process request */
+                       exit(0);
+               }
+               Close(connfd);                  /* parent closes connected socket */
+       }
+}
+/* end serv01 */
+
+/* include sigint */
+void
+sig_int(int signo)
+{
+       void    pr_cpu_time(void);
+
+       pr_cpu_time();
+       exit(0);
+}
+/* end sigint */
diff --git a/server/serv01.lc b/server/serv01.lc
new file mode 100644 (file)
index 0000000..ebdf33d
--- /dev/null
@@ -0,0 +1,52 @@
+/* include serv01 */
+#include    "unp.h"##  1 ##src/server/serv01.c##
+
+int##  2 ##src/server/serv01.c##
+main(int argc, char **argv)##  3 ##src/server/serv01.c##
+{##  4 ##src/server/serv01.c##
+    int     listenfd, connfd;##  5 ##src/server/serv01.c##
+    pid_t   childpid;##  6 ##src/server/serv01.c##
+    void    sig_chld(int), sig_int(int), web_child(int);##  7 ##src/server/serv01.c##
+    socklen_t clilen, addrlen;##  8 ##src/server/serv01.c##
+    struct sockaddr *cliaddr;##  9 ##src/server/serv01.c##
+
+    if (argc == 2)## 10 ##src/server/serv01.c##
+        listenfd = Tcp_listen(NULL, argv[1], &addrlen);## 11 ##src/server/serv01.c##
+    else if (argc == 3)## 12 ##src/server/serv01.c##
+        listenfd = Tcp_listen(argv[1], argv[2], &addrlen);## 13 ##src/server/serv01.c##
+    else## 14 ##src/server/serv01.c##
+        err_quit("usage: serv01 [ <host> ] <port#>");## 15 ##src/server/serv01.c##
+    cliaddr = Malloc(addrlen);## 16 ##src/server/serv01.c##
+
+    Signal(SIGCHLD, sig_chld);## 17 ##src/server/serv01.c##
+    Signal(SIGINT, sig_int);## 18 ##src/server/serv01.c##
+
+    for (;;) {## 19 ##src/server/serv01.c##
+        clilen = addrlen;## 20 ##src/server/serv01.c##
+        if ((connfd = accept(listenfd, cliaddr, &clilen)) < 0) {## 21 ##src/server/serv01.c##
+            if (errno == EINTR)## 22 ##src/server/serv01.c##
+                continue;       /* back to for() */## 23 ##src/server/serv01.c##
+            else## 24 ##src/server/serv01.c##
+                err_sys("accept error");## 25 ##src/server/serv01.c##
+        }## 26 ##src/server/serv01.c##
+
+        if ((childpid = Fork()) == 0) { /* child process */## 27 ##src/server/serv01.c##
+            Close(listenfd);    /* close listening socket */## 28 ##src/server/serv01.c##
+            web_child(connfd);  /* process the request */## 29 ##src/server/serv01.c##
+            exit(0);## 30 ##src/server/serv01.c##
+        }## 31 ##src/server/serv01.c##
+        Close(connfd);          /* parent closes connected socket */## 32 ##src/server/serv01.c##
+    }## 33 ##src/server/serv01.c##
+}## 34 ##src/server/serv01.c##
+/* end serv01 */
+
+/* include sigint */
+void## 35 ##src/server/serv01.c##
+sig_int(int signo)## 36 ##src/server/serv01.c##
+{## 37 ##src/server/serv01.c##
+    void    pr_cpu_time(void);## 38 ##src/server/serv01.c##
+
+    pr_cpu_time();## 39 ##src/server/serv01.c##
+    exit(0);## 40 ##src/server/serv01.c##
+}## 41 ##src/server/serv01.c##
+/* end sigint */
diff --git a/server/serv02.c b/server/serv02.c
new file mode 100644 (file)
index 0000000..0afd4a7
--- /dev/null
@@ -0,0 +1,52 @@
+/* include serv02 */
+#include       "unp.h"
+
+static int             nchildren;
+static pid_t   *pids;
+
+int
+main(int argc, char **argv)
+{
+       int                     listenfd, i;
+       socklen_t       addrlen;
+       void            sig_int(int);
+       pid_t           child_make(int, int, int);
+
+       if (argc == 3)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 4)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: serv02 [ <host> ] <port#> <#children>");
+       nchildren = atoi(argv[argc-1]);
+       pids = Calloc(nchildren, sizeof(pid_t));
+
+       for (i = 0; i < nchildren; i++)
+               pids[i] = child_make(i, listenfd, addrlen);     /* parent returns */
+
+       Signal(SIGINT, sig_int);
+
+       for ( ; ; )
+               pause();        /* everything done by children */
+}
+/* end serv02 */
+
+/* include sigint */
+void
+sig_int(int signo)
+{
+       int             i;
+       void    pr_cpu_time(void);
+
+               /* 4terminate all children */
+       for (i = 0; i < nchildren; i++)
+               kill(pids[i], SIGTERM);
+       while (wait(NULL) > 0)          /* wait for all children */
+               ;
+       if (errno != ECHILD)
+               err_sys("wait error");
+
+       pr_cpu_time();
+       exit(0);
+}
+/* end sigint */
diff --git a/server/serv02.lc b/server/serv02.lc
new file mode 100644 (file)
index 0000000..ae2ca82
--- /dev/null
@@ -0,0 +1,52 @@
+/* include serv02 */
+#include    "unp.h"##  1 ##src/server/serv02.c##
+
+static int nchildren;##  2 ##src/server/serv02.c##
+static pid_t *pids;##  3 ##src/server/serv02.c##
+
+int##  4 ##src/server/serv02.c##
+main(int argc, char **argv)##  5 ##src/server/serv02.c##
+{##  6 ##src/server/serv02.c##
+    int     listenfd, i;##  7 ##src/server/serv02.c##
+    socklen_t addrlen;##  8 ##src/server/serv02.c##
+    void    sig_int(int);##  9 ##src/server/serv02.c##
+    pid_t   child_make(int, int, int);## 10 ##src/server/serv02.c##
+
+    if (argc == 3)## 11 ##src/server/serv02.c##
+        listenfd = Tcp_listen(NULL, argv[1], &addrlen);## 12 ##src/server/serv02.c##
+    else if (argc == 4)## 13 ##src/server/serv02.c##
+        listenfd = Tcp_listen(argv[1], argv[2], &addrlen);## 14 ##src/server/serv02.c##
+    else## 15 ##src/server/serv02.c##
+        err_quit("usage: serv02 [ <host> ] <port#> <#children>");## 16 ##src/server/serv02.c##
+    nchildren = atoi(argv[argc - 1]);## 17 ##src/server/serv02.c##
+    pids = Calloc(nchildren, sizeof(pid_t));## 18 ##src/server/serv02.c##
+
+    for (i = 0; i < nchildren; i++)## 19 ##src/server/serv02.c##
+        pids[i] = child_make(i, listenfd, addrlen); /* parent returns */## 20 ##src/server/serv02.c##
+
+    Signal(SIGINT, sig_int);## 21 ##src/server/serv02.c##
+
+    for (;;)## 22 ##src/server/serv02.c##
+        pause();                /* everything done by children */## 23 ##src/server/serv02.c##
+}## 24 ##src/server/serv02.c##
+/* end serv02 */
+
+/* include sigint */
+void## 25 ##src/server/serv02.c##
+sig_int(int signo)## 26 ##src/server/serv02.c##
+{## 27 ##src/server/serv02.c##
+    int     i;## 28 ##src/server/serv02.c##
+    void    pr_cpu_time(void);## 29 ##src/server/serv02.c##
+
+    /* 4terminate all children */## 30 ##src/server/serv02.c##
+    for (i = 0; i < nchildren; i++)## 31 ##src/server/serv02.c##
+        kill(pids[i], SIGTERM);## 32 ##src/server/serv02.c##
+    while (wait(NULL) > 0)      /* wait for all children */## 33 ##src/server/serv02.c##
+        ;## 34 ##src/server/serv02.c##
+    if (errno != ECHILD)## 35 ##src/server/serv02.c##
+        err_sys("wait error");## 36 ##src/server/serv02.c##
+
+    pr_cpu_time();## 37 ##src/server/serv02.c##
+    exit(0);## 38 ##src/server/serv02.c##
+}## 39 ##src/server/serv02.c##
+/* end sigint */
diff --git a/server/serv02m.c b/server/serv02m.c
new file mode 100644 (file)
index 0000000..216a1e2
--- /dev/null
@@ -0,0 +1,54 @@
+#include       "unp.h"
+
+static int             nchildren;
+static pid_t   *pids;
+long                   *cptr, *meter(int);     /* for counting #clients/child */
+
+int
+main(int argc, char **argv)
+{
+       int                     listenfd, i;
+       socklen_t       addrlen;
+       void            sig_int(int);
+       pid_t           child_make(int, int, int);
+
+       if (argc == 3)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 4)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: serv02 [ <host> ] <port#> <#children>");
+       nchildren = atoi(argv[argc-1]);
+       pids = Calloc(nchildren, sizeof(pid_t));
+       cptr = meter(nchildren);
+
+       for (i = 0; i < nchildren; i++)
+               pids[i] = child_make(i, listenfd, addrlen);     /* parent returns */
+
+       Signal(SIGINT, sig_int);
+
+       for ( ; ; )
+               pause();        /* everything done by children */
+}
+
+void
+sig_int(int signo)
+{
+       int             i;
+       void    pr_cpu_time(void);
+
+               /* terminate all children */
+       for (i = 0; i < nchildren; i++)
+               kill(pids[i], SIGTERM);
+       while (wait(NULL) > 0)          /* wait for all children */
+               ;
+       if (errno != ECHILD)
+               err_sys("wait error");
+
+       pr_cpu_time();
+
+       for (i = 0; i < nchildren; i++)
+               printf("child %d, %ld connections\n", i, cptr[i]);
+
+       exit(0);
+}
diff --git a/server/serv03.c b/server/serv03.c
new file mode 100644 (file)
index 0000000..6c033f2
--- /dev/null
@@ -0,0 +1,49 @@
+#include       "unp.h"
+
+static int             nchildren;
+static pid_t   *pids;
+
+int
+main(int argc, char **argv)
+{
+       int                     listenfd, i;
+       socklen_t       addrlen;
+       void            sig_int(int);
+       pid_t           child_make(int, int, int);
+
+       if (argc == 3)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 4)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: serv03 [ <host> ] <port#> <#children>");
+       nchildren = atoi(argv[argc-1]);
+       pids = Calloc(nchildren, sizeof(pid_t));
+
+       my_lock_init("/tmp/lock.XXXXXX"); /* one lock file for all children */
+       for (i = 0; i < nchildren; i++)
+               pids[i] = child_make(i, listenfd, addrlen);     /* parent returns */
+
+       Signal(SIGINT, sig_int);
+
+       for ( ; ; )
+               pause();        /* everything done by children */
+}
+
+void
+sig_int(int signo)
+{
+       int             i;
+       void    pr_cpu_time(void);
+
+               /* terminate all children */
+       for (i = 0; i < nchildren; i++)
+               kill(pids[i], SIGTERM);
+       while (wait(NULL) > 0)          /* wait for all children */
+               ;
+       if (errno != ECHILD)
+               err_sys("wait error");
+
+       pr_cpu_time();
+       exit(0);
+}
diff --git a/server/serv03m.c b/server/serv03m.c
new file mode 100644 (file)
index 0000000..70ebe6b
--- /dev/null
@@ -0,0 +1,55 @@
+#include       "unp.h"
+
+static int             nchildren;
+static pid_t   *pids;
+long                   *cptr, *meter(int);     /* for counting #clients/child */
+
+int
+main(int argc, char **argv)
+{
+       int                     listenfd, i;
+       socklen_t       addrlen;
+       void            sig_int(int);
+       pid_t           child_make(int, int, int);
+
+       if (argc == 3)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 4)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: serv03 [ <host> ] <port#> <#children>");
+       nchildren = atoi(argv[argc-1]);
+       pids = Calloc(nchildren, sizeof(pid_t));
+       cptr = meter(nchildren);
+
+       my_lock_init("/tmp/lock.XXXXXX");       /* one lock file for all children */
+       for (i = 0; i < nchildren; i++)
+               pids[i] = child_make(i, listenfd, addrlen);     /* parent returns */
+
+       Signal(SIGINT, sig_int);
+
+       for ( ; ; )
+               pause();        /* everything done by children */
+}
+
+void
+sig_int(int signo)
+{
+       int             i;
+       void    pr_cpu_time(void);
+
+               /* terminate all children */
+       for (i = 0; i < nchildren; i++)
+               kill(pids[i], SIGTERM);
+       while (wait(NULL) > 0)          /* wait for all children */
+               ;
+       if (errno != ECHILD)
+               err_sys("wait error");
+
+       pr_cpu_time();
+
+       for (i = 0; i < nchildren; i++)
+               printf("child %d, %ld connections\n", i, cptr[i]);
+
+       exit(0);
+}
diff --git a/server/serv04.c b/server/serv04.c
new file mode 100644 (file)
index 0000000..04a86ba
--- /dev/null
@@ -0,0 +1,49 @@
+#include       "unp.h"
+
+static int             nchildren;
+static pid_t   *pids;
+
+int
+main(int argc, char **argv)
+{
+       int                     listenfd, i;
+       socklen_t       addrlen;
+       void            sig_int(int);
+       pid_t           child_make(int, int, int);
+
+       if (argc == 3)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 4)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: serv04 [ <host> ] <port#> <#children>");
+       nchildren = atoi(argv[argc-1]);
+       pids = Calloc(nchildren, sizeof(pid_t));
+
+       my_lock_init(NULL);
+       for (i = 0; i < nchildren; i++)
+               pids[i] = child_make(i, listenfd, addrlen);     /* parent returns */
+
+       Signal(SIGINT, sig_int);
+
+       for ( ; ; )
+               pause();        /* everything done by children */
+}
+
+void
+sig_int(int signo)
+{
+       int             i;
+       void    pr_cpu_time(void);
+
+               /* terminate all children */
+       for (i = 0; i < nchildren; i++)
+               kill(pids[i], SIGTERM);
+       while (wait(NULL) > 0)          /* wait for all children */
+               ;
+       if (errno != ECHILD)
+               err_sys("wait error");
+
+       pr_cpu_time();
+       exit(0);
+}
diff --git a/server/serv05.c b/server/serv05.c
new file mode 100644 (file)
index 0000000..29d3e0d
--- /dev/null
@@ -0,0 +1,105 @@
+/* include serv05a */
+#include       "unp.h"
+#include       "child.h"
+
+static int             nchildren;
+
+int
+main(int argc, char **argv)
+{
+       int                     listenfd, i, navail, maxfd, nsel, connfd, rc;
+       void            sig_int(int);
+       pid_t           child_make(int, int, int);
+       ssize_t         n;
+       fd_set          rset, masterset;
+       socklen_t       addrlen, clilen;
+       struct sockaddr *cliaddr;
+
+       if (argc == 3)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 4)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: serv05 [ <host> ] <port#> <#children>");
+
+       FD_ZERO(&masterset);
+       FD_SET(listenfd, &masterset);
+       maxfd = listenfd;
+       cliaddr = Malloc(addrlen);
+
+       nchildren = atoi(argv[argc-1]);
+       navail = nchildren;
+       cptr = Calloc(nchildren, sizeof(Child));
+
+               /* 4prefork all the children */
+       for (i = 0; i < nchildren; i++) {
+               child_make(i, listenfd, addrlen);       /* parent returns */
+               FD_SET(cptr[i].child_pipefd, &masterset);
+               maxfd = max(maxfd, cptr[i].child_pipefd);
+       }
+
+       Signal(SIGINT, sig_int);
+
+       for ( ; ; ) {
+               rset = masterset;
+               if (navail <= 0)
+                       FD_CLR(listenfd, &rset);        /* turn off if no available children */
+               nsel = Select(maxfd + 1, &rset, NULL, NULL, NULL);
+
+                       /* 4check for new connections */
+               if (FD_ISSET(listenfd, &rset)) {
+                       clilen = addrlen;
+                       connfd = Accept(listenfd, cliaddr, &clilen);
+
+                       for (i = 0; i < nchildren; i++)
+                               if (cptr[i].child_status == 0)
+                                       break;                          /* available */
+
+                       if (i == nchildren)
+                               err_quit("no available children");
+                       cptr[i].child_status = 1;       /* mark child as busy */
+                       cptr[i].child_count++;
+                       navail--;
+
+                       n = Write_fd(cptr[i].child_pipefd, "", 1, connfd);
+                       Close(connfd);
+                       if (--nsel == 0)
+                               continue;       /* all done with select() results */
+               }
+
+                       /* 4find any newly-available children */
+               for (i = 0; i < nchildren; i++) {
+                       if (FD_ISSET(cptr[i].child_pipefd, &rset)) {
+                               if ( (n = Read(cptr[i].child_pipefd, &rc, 1)) == 0)
+                                       err_quit("child %d terminated unexpectedly", i);
+                               cptr[i].child_status = 0;
+                               navail++;
+                               if (--nsel == 0)
+                                       break;  /* all done with select() results */
+                       }
+               }
+       }
+}
+/* end serv05a */
+
+void
+sig_int(int signo)
+{
+       int             i;
+       void    pr_cpu_time(void);
+
+               /* 4terminate all children */
+       for (i = 0; i < nchildren; i++)
+               kill(cptr[i].child_pid, SIGTERM);
+       while (wait(NULL) > 0)          /* wait for all children */
+               ;
+       if (errno != ECHILD)
+               err_sys("wait error");
+
+       pr_cpu_time();
+
+       for (i = 0; i < nchildren; i++)
+               printf("child %d, %ld connections\n", i, cptr[i].child_count);
+
+       exit(0);
+}
diff --git a/server/serv05.lc b/server/serv05.lc
new file mode 100644 (file)
index 0000000..ef959be
--- /dev/null
@@ -0,0 +1,105 @@
+/* include serv05a */
+#include    "unp.h"##  1 ##src/server/serv05.c##
+#include    "child.h"##  2 ##src/server/serv05.c##
+
+static int nchildren;##  3 ##src/server/serv05.c##
+
+int##  4 ##src/server/serv05.c##
+main(int argc, char **argv)##  5 ##src/server/serv05.c##
+{##  6 ##src/server/serv05.c##
+    int     listenfd, i, navail, maxfd, nsel, connfd, rc;##  7 ##src/server/serv05.c##
+    void    sig_int(int);##  8 ##src/server/serv05.c##
+    pid_t   child_make(int, int, int);##  9 ##src/server/serv05.c##
+    ssize_t n;## 10 ##src/server/serv05.c##
+    fd_set  rset, masterset;## 11 ##src/server/serv05.c##
+    socklen_t addrlen, clilen;## 12 ##src/server/serv05.c##
+    struct sockaddr *cliaddr;## 13 ##src/server/serv05.c##
+
+    if (argc == 3)## 14 ##src/server/serv05.c##
+        listenfd = Tcp_listen(NULL, argv[1], &addrlen);## 15 ##src/server/serv05.c##
+    else if (argc == 4)## 16 ##src/server/serv05.c##
+        listenfd = Tcp_listen(argv[1], argv[2], &addrlen);## 17 ##src/server/serv05.c##
+    else## 18 ##src/server/serv05.c##
+        err_quit("usage: serv05 [ <host> ] <port#> <#children>");## 19 ##src/server/serv05.c##
+
+    FD_ZERO(&masterset);## 20 ##src/server/serv05.c##
+    FD_SET(listenfd, &masterset);## 21 ##src/server/serv05.c##
+    maxfd = listenfd;## 22 ##src/server/serv05.c##
+    cliaddr = Malloc(addrlen);## 23 ##src/server/serv05.c##
+
+    nchildren = atoi(argv[argc - 1]);## 24 ##src/server/serv05.c##
+    navail = nchildren;## 25 ##src/server/serv05.c##
+    cptr = Calloc(nchildren, sizeof(Child));## 26 ##src/server/serv05.c##
+
+    /* 4prefork all the children */## 27 ##src/server/serv05.c##
+    for (i = 0; i < nchildren; i++) {## 28 ##src/server/serv05.c##
+        child_make(i, listenfd, addrlen);   /* parent returns */## 29 ##src/server/serv05.c##
+        FD_SET(cptr[i].child_pipefd, &masterset);## 30 ##src/server/serv05.c##
+        maxfd = max(maxfd, cptr[i].child_pipefd);## 31 ##src/server/serv05.c##
+    }## 32 ##src/server/serv05.c##
+
+    Signal(SIGINT, sig_int);## 33 ##src/server/serv05.c##
+
+    for (;;) {## 34 ##src/server/serv05.c##
+        rset = masterset;## 35 ##src/server/serv05.c##
+        if (navail <= 0)## 36 ##src/server/serv05.c##
+            FD_CLR(listenfd, &rset);    /* turn off if no available children */## 37 ##src/server/serv05.c##
+        nsel = Select(maxfd + 1, &rset, NULL, NULL, NULL);## 38 ##src/server/serv05.c##
+
+        /* 4check for new connections */## 39 ##src/server/serv05.c##
+        if (FD_ISSET(listenfd, &rset)) {## 40 ##src/server/serv05.c##
+            clilen = addrlen;## 41 ##src/server/serv05.c##
+            connfd = Accept(listenfd, cliaddr, &clilen);## 42 ##src/server/serv05.c##
+
+            for (i = 0; i < nchildren; i++)## 43 ##src/server/serv05.c##
+                if (cptr[i].child_status == 0)## 44 ##src/server/serv05.c##
+                    break;      /* available */## 45 ##src/server/serv05.c##
+
+            if (i == nchildren)## 46 ##src/server/serv05.c##
+                err_quit("no available children");## 47 ##src/server/serv05.c##
+            cptr[i].child_status = 1;   /* mark child as busy */## 48 ##src/server/serv05.c##
+            cptr[i].child_count++;## 49 ##src/server/serv05.c##
+            navail--;## 50 ##src/server/serv05.c##
+
+            n = Write_fd(cptr[i].child_pipefd, "", 1, connfd);## 51 ##src/server/serv05.c##
+            Close(connfd);## 52 ##src/server/serv05.c##
+            if (--nsel == 0)## 53 ##src/server/serv05.c##
+                continue;       /* all done with select() results */## 54 ##src/server/serv05.c##
+        }## 55 ##src/server/serv05.c##
+
+        /* 4find any newly-available children */## 56 ##src/server/serv05.c##
+        for (i = 0; i < nchildren; i++) {## 57 ##src/server/serv05.c##
+            if (FD_ISSET(cptr[i].child_pipefd, &rset)) {## 58 ##src/server/serv05.c##
+                if ((n = Read(cptr[i].child_pipefd, &rc, 1)) == 0)## 59 ##src/server/serv05.c##
+                    err_quit("child %d terminated unexpectedly", i);## 60 ##src/server/serv05.c##
+                cptr[i].child_status = 0;## 61 ##src/server/serv05.c##
+                navail++;## 62 ##src/server/serv05.c##
+                if (--nsel == 0)## 63 ##src/server/serv05.c##
+                    break;      /* all done with select() results */## 64 ##src/server/serv05.c##
+            }## 65 ##src/server/serv05.c##
+        }## 66 ##src/server/serv05.c##
+    }## 67 ##src/server/serv05.c##
+}## 68 ##src/server/serv05.c##
+/* end serv05a */
+
+void## 69 ##src/server/serv05.c##
+sig_int(int signo)## 70 ##src/server/serv05.c##
+{## 71 ##src/server/serv05.c##
+    int     i;## 72 ##src/server/serv05.c##
+    void    pr_cpu_time(void);## 73 ##src/server/serv05.c##
+
+    /* 4terminate all children */## 74 ##src/server/serv05.c##
+    for (i = 0; i < nchildren; i++)## 75 ##src/server/serv05.c##
+        kill(cptr[i].child_pid, SIGTERM);## 76 ##src/server/serv05.c##
+    while (wait(NULL) > 0)      /* wait for all children */## 77 ##src/server/serv05.c##
+        ;## 78 ##src/server/serv05.c##
+    if (errno != ECHILD)## 79 ##src/server/serv05.c##
+        err_sys("wait error");## 80 ##src/server/serv05.c##
+
+    pr_cpu_time();## 81 ##src/server/serv05.c##
+
+    for (i = 0; i < nchildren; i++)## 82 ##src/server/serv05.c##
+        printf("child %d, %ld connections\n", i, cptr[i].child_count);## 83 ##src/server/serv05.c##
+
+    exit(0);## 84 ##src/server/serv05.c##
+}## 85 ##src/server/serv05.c##
diff --git a/server/serv06.c b/server/serv06.c
new file mode 100644 (file)
index 0000000..d19d41f
--- /dev/null
@@ -0,0 +1,51 @@
+/* include serv06 */
+#include       "unpthread.h"
+
+int
+main(int argc, char **argv)
+{
+       int                             listenfd, connfd;
+       void                    sig_int(int);
+       void                    *doit(void *);
+       pthread_t               tid;
+       socklen_t               clilen, addrlen;
+       struct sockaddr *cliaddr;
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: serv06 [ <host> ] <port#>");
+       cliaddr = Malloc(addrlen);
+
+       Signal(SIGINT, sig_int);
+
+       for ( ; ; ) {
+               clilen = addrlen;
+               connfd = Accept(listenfd, cliaddr, &clilen);
+
+               Pthread_create(&tid, NULL, &doit, (void *) connfd);
+       }
+}
+
+void *
+doit(void *arg)
+{
+       void    web_child(int);
+
+       Pthread_detach(pthread_self());
+       web_child((int) arg);
+       Close((int) arg);
+       return(NULL);
+}
+/* end serv06 */
+
+void
+sig_int(int signo)
+{
+       void    pr_cpu_time(void);
+
+       pr_cpu_time();
+       exit(0);
+}
diff --git a/server/serv06.lc b/server/serv06.lc
new file mode 100644 (file)
index 0000000..4f2b04e
--- /dev/null
@@ -0,0 +1,51 @@
+/* include serv06 */
+#include    "unpthread.h"##  1 ##src/server/serv06.c##
+
+int##  2 ##src/server/serv06.c##
+main(int argc, char **argv)##  3 ##src/server/serv06.c##
+{##  4 ##src/server/serv06.c##
+    int     listenfd, connfd;##  5 ##src/server/serv06.c##
+    void    sig_int(int);##  6 ##src/server/serv06.c##
+    void   *doit(void *);##  7 ##src/server/serv06.c##
+    pthread_t tid;##  8 ##src/server/serv06.c##
+    socklen_t clilen, addrlen;##  9 ##src/server/serv06.c##
+    struct sockaddr *cliaddr;## 10 ##src/server/serv06.c##
+
+    if (argc == 2)## 11 ##src/server/serv06.c##
+        listenfd = Tcp_listen(NULL, argv[1], &addrlen);## 12 ##src/server/serv06.c##
+    else if (argc == 3)## 13 ##src/server/serv06.c##
+        listenfd = Tcp_listen(argv[1], argv[2], &addrlen);## 14 ##src/server/serv06.c##
+    else## 15 ##src/server/serv06.c##
+        err_quit("usage: serv06 [ <host> ] <port#>");## 16 ##src/server/serv06.c##
+    cliaddr = Malloc(addrlen);## 17 ##src/server/serv06.c##
+
+    Signal(SIGINT, sig_int);## 18 ##src/server/serv06.c##
+
+    for (;;) {## 19 ##src/server/serv06.c##
+        clilen = addrlen;## 20 ##src/server/serv06.c##
+        connfd = Accept(listenfd, cliaddr, &clilen);## 21 ##src/server/serv06.c##
+
+        Pthread_create(&tid, NULL, &doit, (void *) connfd);## 22 ##src/server/serv06.c##
+    }## 23 ##src/server/serv06.c##
+}## 24 ##src/server/serv06.c##
+
+void   *## 25 ##src/server/serv06.c##
+doit(void *arg)## 26 ##src/server/serv06.c##
+{## 27 ##src/server/serv06.c##
+    void    web_child(int);## 28 ##src/server/serv06.c##
+
+    Pthread_detach(pthread_self());## 29 ##src/server/serv06.c##
+    web_child((int) arg);## 30 ##src/server/serv06.c##
+    Close((int) arg);## 31 ##src/server/serv06.c##
+    return (NULL);## 32 ##src/server/serv06.c##
+}## 33 ##src/server/serv06.c##
+/* end serv06 */
+
+void## 34 ##src/server/serv06.c##
+sig_int(int signo)## 35 ##src/server/serv06.c##
+{## 36 ##src/server/serv06.c##
+    void    pr_cpu_time(void);## 37 ##src/server/serv06.c##
+
+    pr_cpu_time();## 38 ##src/server/serv06.c##
+    exit(0);## 39 ##src/server/serv06.c##
+}## 40 ##src/server/serv06.c##
diff --git a/server/serv07.c b/server/serv07.c
new file mode 100644 (file)
index 0000000..112738c
--- /dev/null
@@ -0,0 +1,44 @@
+/* include serv07 */
+#include       "unpthread.h"
+#include       "pthread07.h"
+
+pthread_mutex_t        mlock = PTHREAD_MUTEX_INITIALIZER;
+
+int
+main(int argc, char **argv)
+{
+       int             i;
+       void    sig_int(int), thread_make(int);
+
+       if (argc == 3)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 4)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: serv07 [ <host> ] <port#> <#threads>");
+       nthreads = atoi(argv[argc-1]);
+       tptr = Calloc(nthreads, sizeof(Thread));
+
+       for (i = 0; i < nthreads; i++)
+               thread_make(i);                 /* only main thread returns */
+
+       Signal(SIGINT, sig_int);
+
+       for ( ; ; )
+               pause();        /* everything done by threads */
+}
+/* end serv07 */
+
+void
+sig_int(int signo)
+{
+       int             i;
+       void    pr_cpu_time(void);
+
+       pr_cpu_time();
+
+       for (i = 0; i < nthreads; i++)
+               printf("thread %d, %ld connections\n", i, tptr[i].thread_count);
+
+       exit(0);
+}
diff --git a/server/serv07.lc b/server/serv07.lc
new file mode 100644 (file)
index 0000000..2e260a2
--- /dev/null
@@ -0,0 +1,44 @@
+/* include serv07 */
+#include    "unpthread.h"##  1 ##src/server/serv07.c##
+#include    "pthread07.h"##  2 ##src/server/serv07.c##
+
+pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER;##  3 ##src/server/serv07.c##
+
+int##  4 ##src/server/serv07.c##
+main(int argc, char **argv)##  5 ##src/server/serv07.c##
+{##  6 ##src/server/serv07.c##
+    int     i;##  7 ##src/server/serv07.c##
+    void    sig_int(int), thread_make(int);##  8 ##src/server/serv07.c##
+
+    if (argc == 3)##  9 ##src/server/serv07.c##
+        listenfd = Tcp_listen(NULL, argv[1], &addrlen);## 10 ##src/server/serv07.c##
+    else if (argc == 4)## 11 ##src/server/serv07.c##
+        listenfd = Tcp_listen(argv[1], argv[2], &addrlen);## 12 ##src/server/serv07.c##
+    else## 13 ##src/server/serv07.c##
+        err_quit("usage: serv07 [ <host> ] <port#> <#threads>");## 14 ##src/server/serv07.c##
+    nthreads = atoi(argv[argc - 1]);## 15 ##src/server/serv07.c##
+    tptr = Calloc(nthreads, sizeof(Thread));## 16 ##src/server/serv07.c##
+
+    for (i = 0; i < nthreads; i++)## 17 ##src/server/serv07.c##
+        thread_make(i);         /* only main thread returns */## 18 ##src/server/serv07.c##
+
+    Signal(SIGINT, sig_int);## 19 ##src/server/serv07.c##
+
+    for (;;)## 20 ##src/server/serv07.c##
+        pause();                /* everything done by threads */## 21 ##src/server/serv07.c##
+}## 22 ##src/server/serv07.c##
+/* end serv07 */
+
+void## 23 ##src/server/serv07.c##
+sig_int(int signo)## 24 ##src/server/serv07.c##
+{## 25 ##src/server/serv07.c##
+    int     i;## 26 ##src/server/serv07.c##
+    void    pr_cpu_time(void);## 27 ##src/server/serv07.c##
+
+    pr_cpu_time();## 28 ##src/server/serv07.c##
+
+    for (i = 0; i < nthreads; i++)## 29 ##src/server/serv07.c##
+        printf("thread %d, %ld connections\n", i, tptr[i].thread_count);## 30 ##src/server/serv07.c##
+
+    exit(0);## 31 ##src/server/serv07.c##
+}## 32 ##src/server/serv07.c##
diff --git a/server/serv08.c b/server/serv08.c
new file mode 100644 (file)
index 0000000..2ba4723
--- /dev/null
@@ -0,0 +1,63 @@
+/* include serv08 */
+#include       "unpthread.h"
+#include       "pthread08.h"
+
+static int                     nthreads;
+pthread_mutex_t                clifd_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t         clifd_cond = PTHREAD_COND_INITIALIZER;
+
+int
+main(int argc, char **argv)
+{
+       int                     i, listenfd, connfd;
+       void            sig_int(int), thread_make(int);
+       socklen_t       addrlen, clilen;
+       struct sockaddr *cliaddr;
+
+       if (argc == 3)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 4)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: serv08 [ <host> ] <port#> <#threads>");
+       cliaddr = Malloc(addrlen);
+
+       nthreads = atoi(argv[argc-1]);
+       tptr = Calloc(nthreads, sizeof(Thread));
+       iget = iput = 0;
+
+               /* 4create all the threads */
+       for (i = 0; i < nthreads; i++)
+               thread_make(i);         /* only main thread returns */
+
+       Signal(SIGINT, sig_int);
+
+       for ( ; ; ) {
+               clilen = addrlen;
+               connfd = Accept(listenfd, cliaddr, &clilen);
+
+               Pthread_mutex_lock(&clifd_mutex);
+               clifd[iput] = connfd;
+               if (++iput == MAXNCLI)
+                       iput = 0;
+               if (iput == iget)
+                       err_quit("iput = iget = %d", iput);
+               Pthread_cond_signal(&clifd_cond);
+               Pthread_mutex_unlock(&clifd_mutex);
+       }
+}
+/* end serv08 */
+
+void
+sig_int(int signo)
+{
+       int             i;
+       void    pr_cpu_time(void);
+
+       pr_cpu_time();
+
+       for (i = 0; i < nthreads; i++)
+               printf("thread %d, %ld connections\n", i, tptr[i].thread_count);
+
+       exit(0);
+}
diff --git a/server/serv08.lc b/server/serv08.lc
new file mode 100644 (file)
index 0000000..ab4390f
--- /dev/null
@@ -0,0 +1,63 @@
+/* include serv08 */
+#include    "unpthread.h"##  1 ##src/server/serv08.c##
+#include    "pthread08.h"##  2 ##src/server/serv08.c##
+
+static int nthreads;##  3 ##src/server/serv08.c##
+pthread_mutex_t clifd_mutex = PTHREAD_MUTEX_INITIALIZER;##  4 ##src/server/serv08.c##
+pthread_cond_t clifd_cond = PTHREAD_COND_INITIALIZER;##  5 ##src/server/serv08.c##
+
+int##  6 ##src/server/serv08.c##
+main(int argc, char **argv)##  7 ##src/server/serv08.c##
+{##  8 ##src/server/serv08.c##
+    int     i, listenfd, connfd;##  9 ##src/server/serv08.c##
+    void    sig_int(int), thread_make(int);## 10 ##src/server/serv08.c##
+    socklen_t addrlen, clilen;## 11 ##src/server/serv08.c##
+    struct sockaddr *cliaddr;## 12 ##src/server/serv08.c##
+
+    if (argc == 3)## 13 ##src/server/serv08.c##
+        listenfd = Tcp_listen(NULL, argv[1], &addrlen);## 14 ##src/server/serv08.c##
+    else if (argc == 4)## 15 ##src/server/serv08.c##
+        listenfd = Tcp_listen(argv[1], argv[2], &addrlen);## 16 ##src/server/serv08.c##
+    else## 17 ##src/server/serv08.c##
+        err_quit("usage: serv08 [ <host> ] <port#> <#threads>");## 18 ##src/server/serv08.c##
+    cliaddr = Malloc(addrlen);## 19 ##src/server/serv08.c##
+
+    nthreads = atoi(argv[argc - 1]);## 20 ##src/server/serv08.c##
+    tptr = Calloc(nthreads, sizeof(Thread));## 21 ##src/server/serv08.c##
+    iget = iput = 0;## 22 ##src/server/serv08.c##
+
+    /* 4create all the threads */## 23 ##src/server/serv08.c##
+    for (i = 0; i < nthreads; i++)## 24 ##src/server/serv08.c##
+        thread_make(i);         /* only main thread returns */## 25 ##src/server/serv08.c##
+
+    Signal(SIGINT, sig_int);## 26 ##src/server/serv08.c##
+
+    for (;;) {## 27 ##src/server/serv08.c##
+        clilen = addrlen;## 28 ##src/server/serv08.c##
+        connfd = Accept(listenfd, cliaddr, &clilen);## 29 ##src/server/serv08.c##
+
+        Pthread_mutex_lock(&clifd_mutex);## 30 ##src/server/serv08.c##
+        clifd[iput] = connfd;## 31 ##src/server/serv08.c##
+        if (++iput == MAXNCLI)## 32 ##src/server/serv08.c##
+            iput = 0;## 33 ##src/server/serv08.c##
+        if (iput == iget)## 34 ##src/server/serv08.c##
+            err_quit("iput = iget = %d", iput);## 35 ##src/server/serv08.c##
+        Pthread_cond_signal(&clifd_cond);## 36 ##src/server/serv08.c##
+        Pthread_mutex_unlock(&clifd_mutex);## 37 ##src/server/serv08.c##
+    }## 38 ##src/server/serv08.c##
+}## 39 ##src/server/serv08.c##
+/* end serv08 */
+
+void## 40 ##src/server/serv08.c##
+sig_int(int signo)## 41 ##src/server/serv08.c##
+{## 42 ##src/server/serv08.c##
+    int     i;## 43 ##src/server/serv08.c##
+    void    pr_cpu_time(void);## 44 ##src/server/serv08.c##
+
+    pr_cpu_time();## 45 ##src/server/serv08.c##
+
+    for (i = 0; i < nthreads; i++)## 46 ##src/server/serv08.c##
+        printf("thread %d, %ld connections\n", i, tptr[i].thread_count);## 47 ##src/server/serv08.c##
+
+    exit(0);## 48 ##src/server/serv08.c##
+}## 49 ##src/server/serv08.c##
diff --git a/server/serv09.c b/server/serv09.c
new file mode 100644 (file)
index 0000000..9bc0c89
--- /dev/null
@@ -0,0 +1,42 @@
+/* include serv09 */
+#include       "unpthread.h"
+#include       "pthread09.h"
+
+int
+main(int argc, char **argv)
+{
+       int             i;
+       void    sig_int(int), thread_make(int);
+
+       if (argc == 3)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 4)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: serv09 [ <host> ] <port#> <#threads>");
+       nthreads = atoi(argv[argc-1]);
+       tptr = Calloc(nthreads, sizeof(Thread));
+
+       for (i = 0; i < nthreads; i++)
+               thread_make(i);                 /* only main thread returns */
+
+       Signal(SIGINT, sig_int);
+
+       for ( ; ; )
+               pause();        /* everything done by threads */
+}
+/* end serv09 */
+
+void
+sig_int(int signo)
+{
+       int             i;
+       void    pr_cpu_time(void);
+
+       pr_cpu_time();
+
+       for (i = 0; i < nthreads; i++)
+               printf("thread %d, %ld connections\n", i, tptr[i].thread_count);
+
+       exit(0);
+}
diff --git a/server/sig_chld_waitpid.c b/server/sig_chld_waitpid.c
new file mode 100644 (file)
index 0000000..b901f9b
--- /dev/null
@@ -0,0 +1,13 @@
+#include       "unp.h"
+
+void
+sig_chld(int signo)
+{
+       pid_t   pid;
+       int             stat;
+
+       while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) {
+               /* printf("child %d terminated\n", pid); */
+       }
+       return;
+}
diff --git a/server/unpthread.h b/server/unpthread.h
new file mode 100644 (file)
index 0000000..e79b779
--- /dev/null
@@ -0,0 +1,31 @@
+/* Our own header for the programs that use threads.
+   Include this file, instead of "unp.h". */
+
+#ifndef        __unp_pthread_h
+#define        __unp_pthread_h
+
+#include       "unp.h"
+
+void   Pthread_create(pthread_t *, const pthread_attr_t *,
+                                          void * (*)(void *), void *);
+void   Pthread_join(pthread_t, void **);
+void   Pthread_detach(pthread_t);
+void   Pthread_kill(pthread_t, int);
+
+void   Pthread_mutexattr_init(pthread_mutexattr_t *);
+void   Pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
+void   Pthread_mutex_init(pthread_mutex_t *, pthread_mutexattr_t *);
+void   Pthread_mutex_lock(pthread_mutex_t *);
+void   Pthread_mutex_unlock(pthread_mutex_t *);
+
+void   Pthread_cond_broadcast(pthread_cond_t *);
+void   Pthread_cond_signal(pthread_cond_t *);
+void   Pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
+void   Pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *,
+                                                          const struct timespec *);
+
+void   Pthread_key_create(pthread_key_t *, void (*)(void *));
+void   Pthread_setspecific(pthread_key_t, const void *);
+void   Pthread_once(pthread_once_t *, void (*)(void));
+
+#endif /* __unp_pthread_h */
diff --git a/server/web_child.c b/server/web_child.c
new file mode 100644 (file)
index 0000000..c5cc7e1
--- /dev/null
@@ -0,0 +1,23 @@
+#include       "unp.h"
+
+#define        MAXN    16384           /* max # bytes client can request */
+
+void
+web_child(int sockfd)
+{
+       int                     ntowrite;
+       ssize_t         nread;
+       char            line[MAXLINE], result[MAXN];
+
+       for ( ; ; ) {
+               if ( (nread = Readline(sockfd, line, MAXLINE)) == 0)
+                       return;         /* connection closed by other end */
+
+                       /* 4line from client specifies #bytes to write back */
+               ntowrite = atol(line);
+               if ((ntowrite <= 0) || (ntowrite > MAXN))
+                       err_quit("client request for %d bytes", ntowrite);
+
+               Writen(sockfd, result, ntowrite);
+       }
+}
diff --git a/server/web_child_r.c b/server/web_child_r.c
new file mode 100644 (file)
index 0000000..e456fe5
--- /dev/null
@@ -0,0 +1,26 @@
+#include       "unp.h"
+#include       "readline_r.h"
+
+#define        MAXN    16384           /* max #bytes that a client can request */
+
+void
+web_child(int sockfd)
+{
+       int                     ntowrite;
+       ssize_t         nread;
+       char            line[MAXLINE], result[MAXN];
+       Rline           rline;
+
+       readline_rinit(sockfd, line, MAXLINE, &rline);
+       for ( ; ; ) {
+               if ( (nread = Readline_r(&rline)) == 0)
+                       return;         /* connection closed by other end */
+
+                       /* line from client specifies #bytes to write back */
+               ntowrite = atol(line);
+               if ((ntowrite <= 0) || (ntowrite > MAXN))
+                       err_quit("client request for %d bytes", ntowrite);
+
+               Writen(sockfd, result, ntowrite);
+       }
+}
diff --git a/sigio/Makefile b/sigio/Makefile
new file mode 100644 (file)
index 0000000..6e3fa56
--- /dev/null
@@ -0,0 +1,14 @@
+include ../Make.defines
+
+PROGS =        udpcli01 udpserv01
+
+all:   ${PROGS}
+
+udpcli01:      udpcli01.o dgcli01.o
+               ${CC} ${CFLAGS} -o $@ udpcli01.o dgcli01.o ${LIBS}
+
+udpserv01:     udpserv01.o dgecho01.o
+               ${CC} ${CFLAGS} -o $@ udpserv01.o dgecho01.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/sigio/dgcli01.c b/sigio/dgcli01.c
new file mode 100644 (file)
index 0000000..b3e9fbd
--- /dev/null
@@ -0,0 +1,18 @@
+#include       "unp.h"
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int     n;
+       char    sendline[MAXLINE], recvline[MAXLINE + 1];
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
+
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+}
diff --git a/sigio/dgecho01.c b/sigio/dgecho01.c
new file mode 100644 (file)
index 0000000..0dd88c6
--- /dev/null
@@ -0,0 +1,120 @@
+/* include dgecho1 */
+#include       "unp.h"
+
+static int             sockfd;
+
+#define        QSIZE      8            /* size of input queue */
+#define        MAXDG   4096            /* max datagram size */
+
+typedef struct {
+  void         *dg_data;               /* ptr to actual datagram */
+  size_t       dg_len;                 /* length of datagram */
+  struct sockaddr  *dg_sa;     /* ptr to sockaddr{} w/client's address */
+  socklen_t    dg_salen;               /* length of sockaddr{} */
+} DG;
+static DG      dg[QSIZE];                      /* queue of datagrams to process */
+static long    cntread[QSIZE+1];       /* diagnostic counter */
+
+static int     iget;           /* next one for main loop to process */
+static int     iput;           /* next one for signal handler to read into */
+static int     nqueue;         /* # on queue for main loop to process */
+static socklen_t clilen;/* max length of sockaddr{} */
+
+static void    sig_io(int);
+static void    sig_hup(int);
+/* end dgecho1 */
+
+/* include dgecho2 */
+void
+dg_echo(int sockfd_arg, SA *pcliaddr, socklen_t clilen_arg)
+{
+       int                     i;
+       const int       on = 1;
+       sigset_t        zeromask, newmask, oldmask;
+
+       sockfd = sockfd_arg;
+       clilen = clilen_arg;
+
+       for (i = 0; i < QSIZE; i++) {   /* init queue of buffers */
+               dg[i].dg_data = Malloc(MAXDG);
+               dg[i].dg_sa = Malloc(clilen);
+               dg[i].dg_salen = clilen;
+       }
+       iget = iput = nqueue = 0;
+
+       Signal(SIGHUP, sig_hup);
+       Signal(SIGIO, sig_io);
+       Fcntl(sockfd, F_SETOWN, getpid());
+       Ioctl(sockfd, FIOASYNC, &on);
+       Ioctl(sockfd, FIONBIO, &on);
+
+       Sigemptyset(&zeromask);         /* init three signal sets */
+       Sigemptyset(&oldmask);
+       Sigemptyset(&newmask);
+       Sigaddset(&newmask, SIGIO);     /* signal we want to block */
+
+       Sigprocmask(SIG_BLOCK, &newmask, &oldmask);
+       for ( ; ; ) {
+               while (nqueue == 0)
+                       sigsuspend(&zeromask);  /* wait for datagram to process */
+
+                       /* 4unblock SIGIO */
+               Sigprocmask(SIG_SETMASK, &oldmask, NULL);
+
+               Sendto(sockfd, dg[iget].dg_data, dg[iget].dg_len, 0,
+                          dg[iget].dg_sa, dg[iget].dg_salen);
+
+               if (++iget >= QSIZE)
+                       iget = 0;
+
+                       /* 4block SIGIO */
+               Sigprocmask(SIG_BLOCK, &newmask, &oldmask);
+               nqueue--;
+       }
+}
+/* end dgecho2 */
+
+/* include sig_io */
+static void
+sig_io(int signo)
+{
+       ssize_t         len;
+       int                     nread;
+       DG                      *ptr;
+
+       for (nread = 0; ; ) {
+               if (nqueue >= QSIZE)
+                       err_quit("receive overflow");
+
+               ptr = &dg[iput];
+               ptr->dg_salen = clilen;
+               len = recvfrom(sockfd, ptr->dg_data, MAXDG, 0,
+                                          ptr->dg_sa, &ptr->dg_salen);
+               if (len < 0) {
+                       if (errno == EWOULDBLOCK)
+                               break;          /* all done; no more queued to read */
+                       else
+                               err_sys("recvfrom error");
+               }
+               ptr->dg_len = len;
+
+               nread++;
+               nqueue++;
+               if (++iput >= QSIZE)
+                       iput = 0;
+
+       }
+       cntread[nread]++;               /* histogram of # datagrams read per signal */
+}
+/* end sig_io */
+
+/* include sig_hup */
+static void
+sig_hup(int signo)
+{
+       int             i;
+
+       for (i = 0; i <= QSIZE; i++)
+               printf("cntread[%d] = %ld\n", i, cntread[i]);
+}
+/* end sig_hup */
diff --git a/sigio/dgecho01.lc b/sigio/dgecho01.lc
new file mode 100644 (file)
index 0000000..22a2ccf
--- /dev/null
@@ -0,0 +1,120 @@
+/* include dgecho1 */
+#include    "unp.h"##  1 ##src/sigio/dgecho01.c##
+
+static int sockfd;##  2 ##src/sigio/dgecho01.c##
+
+#define QSIZE      8            /* size of input queue */##  3 ##src/sigio/dgecho01.c##
+#define MAXDG   4096            /* maximum datagram size */##  4 ##src/sigio/dgecho01.c##
+
+typedef struct {##  5 ##src/sigio/dgecho01.c##
+    void   *dg_data;            /* ptr to actual datagram */##  6 ##src/sigio/dgecho01.c##
+    size_t  dg_len;             /* length of datagram */##  7 ##src/sigio/dgecho01.c##
+    struct sockaddr *dg_sa;     /* ptr to sockaddr{} w/client's address */##  8 ##src/sigio/dgecho01.c##
+    socklen_t dg_salen;         /* length of sockaddr{} */##  9 ##src/sigio/dgecho01.c##
+} DG;## 10 ##src/sigio/dgecho01.c##
+static DG dg[QSIZE];            /* the queue of datagrams to process */## 11 ##src/sigio/dgecho01.c##
+static long cntread[QSIZE + 1]; /* diagnostic counter */## 12 ##src/sigio/dgecho01.c##
+
+static int iget;                /* next one for main loop to process */## 13 ##src/sigio/dgecho01.c##
+static int iput;                /* next one for signal handler to read into */## 14 ##src/sigio/dgecho01.c##
+static int nqueue;              /* #on queue for main loop to process */## 15 ##src/sigio/dgecho01.c##
+static socklen_t clilen;        /* max length of sockaddr{} */## 16 ##src/sigio/dgecho01.c##
+
+static void sig_io(int);## 17 ##src/sigio/dgecho01.c##
+static void sig_hup(int);## 18 ##src/sigio/dgecho01.c##
+/* end dgecho1 */
+
+/* include dgecho2 */
+void## 19 ##src/sigio/dgecho01.c##
+dg_echo(int sockfd_arg, SA *pcliaddr, socklen_t clilen_arg)## 20 ##src/sigio/dgecho01.c##
+{## 21 ##src/sigio/dgecho01.c##
+    int     i;## 22 ##src/sigio/dgecho01.c##
+    const int on = 1;## 23 ##src/sigio/dgecho01.c##
+    sigset_t zeromask, newmask, oldmask;## 24 ##src/sigio/dgecho01.c##
+
+    sockfd = sockfd_arg;## 25 ##src/sigio/dgecho01.c##
+    clilen = clilen_arg;## 26 ##src/sigio/dgecho01.c##
+
+    for (i = 0; i < QSIZE; i++) {   /* init queue of buffers */## 27 ##src/sigio/dgecho01.c##
+        dg[i].dg_data = Malloc(MAXDG);## 28 ##src/sigio/dgecho01.c##
+        dg[i].dg_sa = Malloc(clilen);## 29 ##src/sigio/dgecho01.c##
+        dg[i].dg_salen = clilen;## 30 ##src/sigio/dgecho01.c##
+    }## 31 ##src/sigio/dgecho01.c##
+    iget = iput = nqueue = 0;## 32 ##src/sigio/dgecho01.c##
+
+    Signal(SIGHUP, sig_hup);## 33 ##src/sigio/dgecho01.c##
+    Signal(SIGIO, sig_io);## 34 ##src/sigio/dgecho01.c##
+    Fcntl(sockfd, F_SETOWN, getpid());## 35 ##src/sigio/dgecho01.c##
+    Ioctl(sockfd, FIOASYNC, &on);## 36 ##src/sigio/dgecho01.c##
+    Ioctl(sockfd, FIONBIO, &on);## 37 ##src/sigio/dgecho01.c##
+
+    Sigemptyset(&zeromask);     /* init three signal sets */## 38 ##src/sigio/dgecho01.c##
+    Sigemptyset(&oldmask);## 39 ##src/sigio/dgecho01.c##
+    Sigemptyset(&newmask);## 40 ##src/sigio/dgecho01.c##
+    Sigaddset(&newmask, SIGIO); /* the signal we want to block */## 41 ##src/sigio/dgecho01.c##
+
+    Sigprocmask(SIG_BLOCK, &newmask, &oldmask);## 42 ##src/sigio/dgecho01.c##
+    for (;;) {## 43 ##src/sigio/dgecho01.c##
+        while (nqueue == 0)## 44 ##src/sigio/dgecho01.c##
+            sigsuspend(&zeromask);  /* wait for a datagram to process */## 45 ##src/sigio/dgecho01.c##
+
+        /* 4unblock SIGIO */## 46 ##src/sigio/dgecho01.c##
+        Sigprocmask(SIG_SETMASK, &oldmask, NULL);## 47 ##src/sigio/dgecho01.c##
+
+        Sendto(sockfd, dg[iget].dg_data, dg[iget].dg_len, 0,## 48 ##src/sigio/dgecho01.c##
+               dg[iget].dg_sa, dg[iget].dg_salen);## 49 ##src/sigio/dgecho01.c##
+
+        if (++iget >= QSIZE)## 50 ##src/sigio/dgecho01.c##
+            iget = 0;## 51 ##src/sigio/dgecho01.c##
+
+        /* 4block SIGIO */## 52 ##src/sigio/dgecho01.c##
+        Sigprocmask(SIG_BLOCK, &newmask, &oldmask);## 53 ##src/sigio/dgecho01.c##
+        nqueue--;## 54 ##src/sigio/dgecho01.c##
+    }## 55 ##src/sigio/dgecho01.c##
+}## 56 ##src/sigio/dgecho01.c##
+/* end dgecho2 */
+
+/* include sig_io */
+static void## 57 ##src/sigio/dgecho01.c##
+sig_io(int signo)## 58 ##src/sigio/dgecho01.c##
+{## 59 ##src/sigio/dgecho01.c##
+    ssize_t len;## 60 ##src/sigio/dgecho01.c##
+    int     nread;## 61 ##src/sigio/dgecho01.c##
+    DG     *ptr;## 62 ##src/sigio/dgecho01.c##
+
+    for (nread = 0;;) {## 63 ##src/sigio/dgecho01.c##
+        if (nqueue >= QSIZE)## 64 ##src/sigio/dgecho01.c##
+            err_quit("receive overflow");## 65 ##src/sigio/dgecho01.c##
+
+        ptr = &dg[iput];## 66 ##src/sigio/dgecho01.c##
+        ptr->dg_salen = clilen;## 67 ##src/sigio/dgecho01.c##
+        len = recvfrom(sockfd, ptr->dg_data, MAXDG, 0,## 68 ##src/sigio/dgecho01.c##
+                       ptr->dg_sa, &ptr->dg_salen);## 69 ##src/sigio/dgecho01.c##
+        if (len < 0) {## 70 ##src/sigio/dgecho01.c##
+            if (errno == EWOULDBLOCK)## 71 ##src/sigio/dgecho01.c##
+                break;          /* all done; no more queued to read */## 72 ##src/sigio/dgecho01.c##
+            else## 73 ##src/sigio/dgecho01.c##
+                err_sys("recvfrom error");## 74 ##src/sigio/dgecho01.c##
+        }## 75 ##src/sigio/dgecho01.c##
+        ptr->dg_len = len;## 76 ##src/sigio/dgecho01.c##
+
+        nread++;## 77 ##src/sigio/dgecho01.c##
+        nqueue++;## 78 ##src/sigio/dgecho01.c##
+        if (++iput >= QSIZE)## 79 ##src/sigio/dgecho01.c##
+            iput = 0;## 80 ##src/sigio/dgecho01.c##
+
+    }## 81 ##src/sigio/dgecho01.c##
+    cntread[nread]++;           /* histogram of #datagrams read per signal */## 82 ##src/sigio/dgecho01.c##
+}## 83 ##src/sigio/dgecho01.c##
+/* end sig_io */
+
+/* include sig_hup */
+static void## 84 ##src/sigio/dgecho01.c##
+sig_hup(int signo)## 85 ##src/sigio/dgecho01.c##
+{## 86 ##src/sigio/dgecho01.c##
+    int     i;## 87 ##src/sigio/dgecho01.c##
+
+    for (i = 0; i <= QSIZE; i++)## 88 ##src/sigio/dgecho01.c##
+        printf("cntread[%d] = %ld\n", i, cntread[i]);## 89 ##src/sigio/dgecho01.c##
+}## 90 ##src/sigio/dgecho01.c##
+/* end sig_hup */
diff --git a/sigio/script.1 b/sigio/script.1
new file mode 100755 (executable)
index 0000000..3e39f49
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+./udpcli01 140.252.13.35 < /usr/share/misc/termcap > /home/rstevens/temp.1 &
+./udpcli01 140.252.13.35 < /usr/share/misc/termcap > /home/rstevens/temp.2 &
+./udpcli01 140.252.13.35 < /usr/share/misc/termcap > /home/rstevens/temp.3 &
+./udpcli01 140.252.13.35 < /usr/share/misc/termcap > /home/rstevens/temp.4 &
+./udpcli01 140.252.13.35 < /usr/share/misc/termcap > /home/rstevens/temp.5 &
+./udpcli01 140.252.13.35 < /usr/share/misc/termcap > /home/rstevens/temp.6 &
+
+wait
diff --git a/sigio/script.2 b/sigio/script.2
new file mode 100755 (executable)
index 0000000..b7a60e6
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+./udpcli01 140.252.13.37 < /usr/share/lib/termcap > /home/rstevens/temp.1 &
+./udpcli01 140.252.13.37 < /usr/share/lib/termcap > /home/rstevens/temp.2 &
+./udpcli01 140.252.13.37 < /usr/share/lib/termcap > /home/rstevens/temp.3 &
+./udpcli01 140.252.13.37 < /usr/share/lib/termcap > /home/rstevens/temp.4 &
+./udpcli01 140.252.13.37 < /usr/share/lib/termcap > /home/rstevens/temp.5 &
+./udpcli01 140.252.13.37 < /usr/share/lib/termcap > /home/rstevens/temp.6 &
+
+wait
diff --git a/sigio/udpcli01.c b/sigio/udpcli01.c
new file mode 100644 (file)
index 0000000..24ce753
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli01 <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/sigio/udpserv01.c b/sigio/udpserv01.c
new file mode 100644 (file)
index 0000000..a21a857
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr, cliaddr;
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
+}
diff --git a/sock/Makefile b/sock/Makefile
new file mode 100644 (file)
index 0000000..b2e3e79
--- /dev/null
@@ -0,0 +1,17 @@
+include ../Make.defines
+
+PROGS =        sock
+OBJS = buffers.o cliopen.o crlf.o error.o looptcp.o loopudp.o \
+          main.o multicast.o pattern.o servopen.o sleepus.o sockopts.o \
+          sourceroute.o sourcetcp.o sourceudp.o sinktcp.o sinkudp.o \
+          tellwait.o write.o
+
+all:   ${PROGS}
+
+${OBJS}: sock.h
+
+sock:  ${OBJS}
+               ${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS}
+
+clean:
+               rm -f ${PROGS} core core.* *.o temp.* *.out typescript*
diff --git a/sock/README b/sock/README
new file mode 100644 (file)
index 0000000..d4ba778
--- /dev/null
@@ -0,0 +1,14 @@
+       The source files in this directory are all copyrighted (c) 1993 by
+W. Richard Stevens.  
+
+       This source files in this directory assume tab stops every 4 positions,
+not every 8 (the default).  Just ":set tabstop=4" in vi, for example.
+
+       If your system doesn't define the POSIX.1 ssize_t data type, then
+delete the appropriate #ifdef/#endif lines at the beginning of "ourhdr.h".
+
+       If your system's <stdlib.h> doesn't define the variables for getopt(),
+then delete the appropriate #ifdef/#endif lines at the beginning of "ourhdr.h".
+
+       If your system doesn't support send() and recv() (e.g., OSF/1) then
+delete the appropriate #ifdef/#endif lines at the beginning of "ourhdr.h".
diff --git a/sock/TODO b/sock/TODO
new file mode 100644 (file)
index 0000000..34b870f
--- /dev/null
+++ b/sock/TODO
@@ -0,0 +1,4 @@
+- With -v print IP address after gethostbyname returns.
+
+- First, option to write() in small chunks.  Then option to use writev()
+  instead of write().  See what happens, with and without TCO_NODELAY.
diff --git a/sock/buffers.c b/sock/buffers.c
new file mode 100644 (file)
index 0000000..8caf351
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+
+void
+buffers(int sockfd)
+{
+       int                     n;
+       socklen_t       optlen;
+
+               /* Allocate the read and write buffers. */
+
+       if (rbuf == NULL) {
+               if ( (rbuf = malloc(readlen)) == NULL)
+                       err_sys("malloc error for read buffer");
+       }
+
+       if (wbuf == NULL) {
+               if ( (wbuf = malloc(writelen)) == NULL)
+                       err_sys("malloc error for write buffer");
+       }
+
+               /* Set the socket send and receive buffer sizes (if specified).
+                  The receive buffer size is tied to TCP's advertised window. */
+
+       if (rcvbuflen) {
+               if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuflen,
+                                                                                                       sizeof(rcvbuflen)) < 0)
+                       err_sys("SO_RCVBUF setsockopt error");
+       
+               optlen = sizeof(n);
+               if (getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &n, &optlen) < 0)
+                       err_sys("SO_RCVBUF getsockopt error");
+               if (n != rcvbuflen)
+                       err_quit("rcvbuflen = %d, SO_RCVBUF = %d", rcvbuflen, n);
+               if (verbose)
+                       fprintf(stderr, "SO_RCVBUF = %d\n", n);
+       }
+
+       if (sndbuflen) {
+               if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sndbuflen,
+                                                                                                       sizeof(sndbuflen)) < 0)
+                       err_sys("SO_SNDBUF setsockopt error");
+       
+               optlen = sizeof(n);
+               if (getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &n, &optlen) < 0)
+                       err_sys("SO_SNDBUF getsockopt error");
+               if (n != sndbuflen)
+                       err_quit("sndbuflen = %d, SO_SNDBUF = %d", sndbuflen, n);
+               if (verbose)
+                       fprintf(stderr, "SO_SNDBUF = %d\n", n);
+       }
+}
diff --git a/sock/cliopen.c b/sock/cliopen.c
new file mode 100644 (file)
index 0000000..e982e01
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+
+int
+cliopen(char *host, char *port)
+{
+       int                                     fd, i, on;
+       const char                      *protocol;
+       struct in_addr          inaddr;
+       struct servent          *sp;
+       struct hostent          *hp;
+
+       protocol = udp ? "udp" : "tcp";
+
+               /* initialize socket address structure */
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+
+               /* see if "port" is a service name or number */
+       if ( (i = atoi(port)) == 0) {
+               if ( (sp = getservbyname(port, protocol)) == NULL)
+                       err_quit("getservbyname() error for: %s/%s", port, protocol);
+
+               servaddr.sin_port = sp->s_port;
+       } else
+               servaddr.sin_port = htons(i);
+
+       /*
+        * First try to convert the host name as a dotted-decimal number.
+        * Only if that fails do we call gethostbyname().
+        */
+
+       if (inet_aton(host, &inaddr) == 1)
+               servaddr.sin_addr = inaddr;     /* it's dotted-decimal */
+       else if ( (hp = gethostbyname(host)) != NULL)
+               memcpy(&servaddr.sin_addr, hp->h_addr, hp->h_length);
+       else
+               err_quit("invalid hostname: %s", host);
+
+       if ( (fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0)
+               err_sys("socket() error");
+
+       if (reuseaddr) {
+               on = 1;
+               if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
+                       err_sys("setsockopt of SO_REUSEADDR error");
+       }
+
+#ifdef SO_REUSEPORT
+       if (reuseport) {
+               on = 1;
+               if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof (on)) < 0)
+                       err_sys("setsockopt of SO_REUSEPORT error");
+       }
+#endif
+
+       /*
+        * User can specify port number for client to bind.  Only real use
+        * is to see a TCP connection initiated by both ends at the same time.
+        * Also, if UDP is being used, we specifically call bind() to assign
+        * an ephemeral port to the socket.
+        * Also, for experimentation, client can also set local IP address
+        * (and port) using -l option.  Allow localip[] to be set but bindport
+        * to be 0.
+        */
+
+       if (bindport != 0 || localip[0] != 0 || udp) {
+               bzero(&cliaddr, sizeof(cliaddr));
+               cliaddr.sin_family      = AF_INET;
+               cliaddr.sin_port        = htons(bindport);                      /* can be 0 */
+               if (localip[0] != 0) {
+                       if (inet_aton(localip, &cliaddr.sin_addr) == 0)
+                               err_quit("invalid IP address: %s", localip);
+               } else
+                       cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);    /* wildcard */
+
+               if (bind(fd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) < 0)
+                       err_sys("bind() error");
+       }
+
+       /* Need to allocate buffers before connect(), since they can affect
+        * TCP options (window scale, etc.).
+        */
+
+       buffers(fd);
+       sockopts(fd, 0);        /* may also want to set SO_DEBUG */
+
+       /*
+        * Connect to the server.  Required for TCP, optional for UDP.
+        */
+
+       if (udp == 0 || connectudp) {
+               for ( ; ; ) {
+                       if (connect(fd, (struct sockaddr *) &servaddr, sizeof(servaddr))
+                                                                                                                                               == 0)
+                               break;          /* all OK */
+                       if (errno == EINTR)             /* can happen with SIGIO */
+                               continue;
+                       if (errno == EISCONN)   /* can happen with SIGIO */
+                               break;
+                       err_sys("connect() error");
+               }
+       }
+
+       if (verbose) {
+                       /* Call getsockname() to find local address bound to socket:
+                          TCP ephemeral port was assigned by connect() or bind();
+                          UDP ephemeral port was assigned by bind(). */
+               i = sizeof(cliaddr);
+               if (getsockname(fd, (struct sockaddr *) &cliaddr, &i) < 0)
+                       err_sys("getsockname() error");
+
+                                       /* Can't do one fprintf() since inet_ntoa() stores
+                                          the result in a static location. */
+               fprintf(stderr, "connected on %s.%d ",
+                                       INET_NTOA(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
+               fprintf(stderr, "to %s.%d\n",
+                                       INET_NTOA(servaddr.sin_addr), ntohs(servaddr.sin_port));
+       }
+
+       sockopts(fd, 1);        /* some options get set after connect() */
+
+       return(fd);
+}
diff --git a/sock/crlf.c b/sock/crlf.c
new file mode 100644 (file)
index 0000000..df71a19
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+
+/* Convert newline to return/newline. */
+
+int
+crlf_add(char *dst, int dstsize, const char *src, int lenin)
+{
+       int     lenout;
+       char    c;
+
+       if ( (lenout = lenin) > dstsize)
+                       err_quit("crlf_add: destination not big enough");
+
+       for ( ; lenin > 0; lenin--) {
+               if ( (c = *src++) == '\n') {
+                       if (++lenout >= dstsize)
+                               err_quit("crlf_add: destination not big enough");
+                       *dst++ = '\r';
+               }
+               *dst++ = c;
+       }
+
+       return(lenout);
+}
+
+int
+crlf_strip(char *dst, int dstsize, const char *src, int lenin)
+{
+       int             lenout;
+       char    c;
+
+       for (lenout = 0; lenin > 0; lenin--) { 
+               if ( (c = *src++) != '\r') {
+                       if (++lenout >= dstsize)
+                               err_quit("crlf_strip: destination not big enough");
+                       *dst++ = c;
+               }
+       }
+
+       return(lenout);
+}
diff --git a/sock/error.c b/sock/error.c
new file mode 100644 (file)
index 0000000..fa26c6f
--- /dev/null
@@ -0,0 +1,103 @@
+#include       <errno.h>               /* for definition of errno */
+#include       <stdarg.h>              /* ANSI C header file */
+#include       "ourhdr.h"
+
+static void    err_doit(int, const char *, va_list);
+
+char   *pname = NULL;          /* caller can set this from argv[0] */
+
+/* Nonfatal error related to a system call.
+ * Print a message and return. */
+
+void
+/* $f err_ret $ */
+err_ret(const char *fmt, ...)
+{
+       va_list         ap;
+
+       va_start(ap, fmt);
+       err_doit(1, fmt, ap);
+       va_end(ap);
+       return;
+}
+
+/* Fatal error related to a system call.
+ * Print a message and terminate. */
+
+void
+/* $f err_sys $ */
+err_sys(const char *fmt, ...)
+{
+       va_list         ap;
+
+       va_start(ap, fmt);
+       err_doit(1, fmt, ap);
+       va_end(ap);
+       exit(1);
+}
+
+/* Fatal error related to a system call.
+ * Print a message, dump core, and terminate. */
+
+void
+/* $f err_dump $ */
+err_dump(const char *fmt, ...)
+{
+       va_list         ap;
+
+       va_start(ap, fmt);
+       err_doit(1, fmt, ap);
+       va_end(ap);
+       abort();                /* dump core and terminate */
+       exit(1);                /* shouldn't get here */
+}
+
+/* Nonfatal error unrelated to a system call.
+ * Print a message and return. */
+
+void
+/* $f err_msg $ */
+err_msg(const char *fmt, ...)
+{
+       va_list         ap;
+
+       va_start(ap, fmt);
+       err_doit(0, fmt, ap);
+       va_end(ap);
+       return;
+}
+
+/* Fatal error unrelated to a system call.
+ * Print a message and terminate. */
+
+void
+/* $f err_quit $ */
+err_quit(const char *fmt, ...)
+{
+       va_list         ap;
+
+       va_start(ap, fmt);
+       err_doit(0, fmt, ap);
+       va_end(ap);
+       exit(1);
+}
+
+/* Print a message and return to caller.
+ * Caller specifies "errnoflag". */
+
+static void
+err_doit(int errnoflag, const char *fmt, va_list ap)
+{
+       int             errno_save;
+       char    buf[MAXLINE];
+
+       errno_save = errno;             /* value caller might want printed */
+       vsprintf(buf, fmt, ap);
+       if (errnoflag)
+               sprintf(buf+strlen(buf), ": %s", strerror(errno_save));
+       strcat(buf, "\n");
+       fflush(stdout);         /* in case stdout and stderr are the same */
+       fputs(buf, stderr);
+       fflush(stderr);         /* SunOS 4.1.* doesn't grok NULL argument */
+       return;
+}
diff --git a/sock/loop.c b/sock/loop.c
new file mode 100644 (file)
index 0000000..c44bfb4
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+
+/* Copy everything from stdin to "sockfd",
+ * and everything from "sockfd" to stdout. */
+
+void   tty_atexit(void);       /* in library */
+void   sig_catch(int);         /* my function */
+
+void
+loop(int sockfd)
+{
+       int                                             maxfdp1, nread, ntowrite, stdineof, clilen;
+       fd_set                                  rset;
+       struct sockaddr_in              cliaddr;                /* for UDP server */
+
+#ifdef MSG_TRUNC                       /* 4.3BSD Reno and later */
+       struct iovec                    iov[1];
+       struct msghdr                   msg;
+
+#ifdef IP_RECVDSTADDR          /* 4.3BSD Reno and later */
+       static struct cmsghdr  *cmptr = NULL;   /* malloc'ed */
+       struct in_addr                  dstinaddr;              /* for UDP server */
+#define        CONTROLLEN      (sizeof(struct cmsghdr) + sizeof(struct in_addr))
+#endif /* IP_RECVDSTADDR */
+
+#endif /* MSG_TRUNC */
+
+#ifdef notdef  /* following doesn't appear to work */
+       /*
+        * This is an attempt to set stdin to cbreak, so that input characters
+        * are delivered one at a time, to see Nagle algorithm in effect
+        * (or disabled).
+        */
+       if (cbreak && isatty(STDIN_FILENO)) {
+               if (tty_cbreak(STDIN_FILENO) < 0)
+                       err_sys("tty_cbreak error");
+               if (atexit(tty_atexit) < 0)
+                       err_sys("tty_atexit error");
+
+               if (signal(SIGINT, sig_catch) == SIG_ERR)
+                       err_sys("signal error");
+               if (signal(SIGQUIT, sig_catch) == SIG_ERR)
+                       err_sys("signal error");
+               if (signal(SIGTERM, sig_catch) == SIG_ERR)
+                       err_sys("signal error");
+       }
+#endif
+
+       if (pauseinit)
+               sleep(pauseinit);       /* intended for server */
+
+       stdineof = 0;
+       FD_ZERO(&rset);
+       maxfdp1 = sockfd + 1;   /* check descriptors [0..sockfd] */
+
+               /* UDP client issues connect(), so read() and write() are used.
+                  Server is harder since cannot issue connect().  We use recvfrom()
+                  or recvmsg(), depending on OS. */
+
+       for ( ; ; ) {
+               if (stdineof == 0)
+                       FD_SET(STDIN_FILENO, &rset);
+               FD_SET(sockfd, &rset);
+
+               if (select(maxfdp1, &rset, NULL, NULL, NULL) < 0)
+                       err_sys("select error");
+
+               if (FD_ISSET(STDIN_FILENO, &rset)) {    /* data to read on stdin */
+                       if ( (nread = read(STDIN_FILENO, rbuf, readlen)) < 0)
+                               err_sys("read error from stdin");
+                       else if (nread == 0) {  /* EOF on stdin */
+                               if (halfclose) {
+                                       if (shutdown(sockfd, 1) < 0)
+                                               err_sys("shutdown() error");
+
+                                       FD_CLR(STDIN_FILENO, &rset);
+                                       stdineof = 1;   /* don't read stdin anymore */
+                                       continue;               /* back to select() */
+                               }
+                               break;          /* default: stdin EOF -> done */
+                       }
+
+                       if (crlf) {
+                               ntowrite = crlf_add(wbuf, writelen, rbuf, nread);
+                               if (write(sockfd, wbuf, ntowrite) != ntowrite)
+                                       err_sys("write error");
+                       } else {
+                               if (write(sockfd, rbuf, nread) != nread)
+                                       err_sys("write error");
+                       }
+               }
+
+               if (FD_ISSET(sockfd, &rset)) {  /* data to read from socket */
+                       if (udp && server) {
+                               clilen = sizeof(cliaddr);
+#ifndef        MSG_TRUNC       /* vanilla BSD sockets */
+                               nread = recvfrom(sockfd, rbuf, readlen, 0,
+                                                                       (struct sockaddr *) &cliaddr, &clilen);
+
+#else  /* 4.3BSD Reno and later; use recvmsg() to get at MSG_TRUNC flag */
+               /* Also lets us get at control information (destination address) */
+
+
+                               iov[0].iov_base = rbuf;
+                               iov[0].iov_len  = readlen;
+                               msg.msg_iov          = iov;
+                               msg.msg_iovlen       = 1;
+                               msg.msg_name         = (caddr_t) &cliaddr;
+                               msg.msg_namelen      = clilen;
+
+#ifdef IP_RECVDSTADDR
+                               if (cmptr == NULL && (cmptr = malloc(CONTROLLEN)) == NULL)
+                                       err_sys("malloc error for control buffer");
+
+                               msg.msg_control      = (caddr_t) cmptr; /* for dest address */
+                               msg.msg_controllen   = CONTROLLEN;
+#else
+                               msg.msg_control      = (caddr_t) 0;     /* no ancillary data */
+                               msg.msg_controllen   = 0;
+#endif /* IP_RECVDSTADDR */
+                               msg.msg_flags        = 0;                       /* flags returned here */
+
+                               nread = recvmsg(sockfd, &msg, 0);
+#endif /* MSG_TRUNC */
+                               if (nread < 0)
+                                       err_sys("datagram receive error");
+
+                               if (verbose) {
+                                       printf("from %s", INET_NTOA(cliaddr.sin_addr));
+#ifdef MSG_TRUNC
+#ifdef IP_RECVDSTADDR
+                                       if (recvdstaddr) {
+                                               if (cmptr->cmsg_level != IPPROTO_IP)
+                                                       err_quit("control level != IPPROTO_IP");
+                                               if (cmptr->cmsg_type != IP_RECVDSTADDR)
+                                                       err_quit("control type != IP_RECVDSTADDR");
+                                               if (cmptr->cmsg_len != CONTROLLEN)
+                                                       err_quit("control length (%d) != %d",
+                                                                        cmptr->cmsg_len, CONTROLLEN);
+                                               memcpy((char *) &dstinaddr, (char *) CMSG_DATA(cmptr),
+                                                         sizeof(struct in_addr));
+
+                                               printf(", to %s", INET_NTOA(dstinaddr));
+                                       }
+#endif /* IP_RECVDSTADDR */
+#endif /* MSG_TRUNC */
+                                       printf(": ");
+                                       fflush(stdout);
+                               }
+
+#ifdef MSG_TRUNC
+                               if (msg.msg_flags & MSG_TRUNC)
+                                       printf("(datagram truncated)\n");
+#endif
+
+                       } else {
+                               if ( (nread = read(sockfd, rbuf, readlen)) < 0)
+                                       err_sys("read error");
+                               else if (nread == 0) {
+                                       if (verbose)
+                                               fprintf(stderr, "connection closed by peer\n");
+                                       break;          /* EOF, terminate */
+                               }
+                       }
+
+                       if (crlf) {
+                               ntowrite = crlf_strip(wbuf, writelen, rbuf, nread);
+                               if (writen(STDOUT_FILENO, wbuf, ntowrite) != ntowrite)
+                                       err_sys("writen error to stdout");
+                       } else {
+                               if (writen(STDOUT_FILENO, rbuf, nread) != nread)
+                                       err_sys("writen error to stdout");
+                       }
+               }
+       }
+
+       if (pauseclose) {
+               if (verbose)
+                               fprintf(stderr, "pausing before close\n");
+               sleep(pauseclose);
+       }
+
+       if (close(sockfd) < 0)
+               err_sys("close error");         /* since SO_LINGER may be set */
+}
+
+void
+sig_catch(int signo)
+{
+       exit(0);        /* exit handler will reset tty state */
+}
diff --git a/sock/looptcp.c b/sock/looptcp.c
new file mode 100644 (file)
index 0000000..cf7b805
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+
+/* Copy everything from stdin to "sockfd",
+ * and everything from "sockfd" to stdout. */
+
+void
+loop_tcp(int sockfd)
+{
+       int             maxfdp1, nread, ntowrite, stdineof, flags;
+       fd_set  rset;
+
+       if (pauseinit)
+               sleep_us(pauseinit*1000);       /* intended for server */
+
+       flags = 0;
+       stdineof = 0;
+       FD_ZERO(&rset);
+       maxfdp1 = sockfd + 1;   /* check descriptors [0..sockfd] */
+
+       for ( ; ; ) {
+               if (stdineof == 0)
+                       FD_SET(STDIN_FILENO, &rset);
+               FD_SET(sockfd, &rset);
+
+               if (select(maxfdp1, &rset, NULL, NULL, NULL) < 0)
+                       err_sys("select error");
+
+               if (FD_ISSET(STDIN_FILENO, &rset)) {    /* data to read on stdin */
+                       if ( (nread = read(STDIN_FILENO, rbuf, readlen)) < 0)
+                               err_sys("read error from stdin");
+                       else if (nread == 0) {  /* EOF on stdin */
+                               if (halfclose) {
+                                       if (shutdown(sockfd, SHUT_WR) < 0)
+                                               err_sys("shutdown() error");
+
+                                       FD_CLR(STDIN_FILENO, &rset);
+                                       stdineof = 1;   /* don't read stdin anymore */
+                                       continue;               /* back to select() */
+                               }
+                               break;          /* default: stdin EOF -> done */
+                       }
+
+                       if (crlf) {
+                               ntowrite = crlf_add(wbuf, writelen, rbuf, nread);
+                               if (dowrite(sockfd, wbuf, ntowrite) != ntowrite)
+                                       err_sys("write error");
+                       } else {
+                               if (dowrite(sockfd, rbuf, nread) != nread)
+                                       err_sys("write error");
+                       }
+               }
+
+               if (FD_ISSET(sockfd, &rset)) {  /* data to read from socket */
+                               /* msgpeek = 0 or MSG_PEEK */
+                       flags = msgpeek;
+               oncemore:
+                       if ( (nread = recv(sockfd, rbuf, readlen, flags)) < 0)
+                               err_sys("recv error");
+                       else if (nread == 0) {
+                               if (verbose)
+                                       fprintf(stderr, "connection closed by peer\n");
+                               break;          /* EOF, terminate */
+                       }
+
+                       if (crlf) {
+                               ntowrite = crlf_strip(wbuf, writelen, rbuf, nread);
+                               if (writen(STDOUT_FILENO, wbuf, ntowrite) != ntowrite)
+                                       err_sys("writen error to stdout");
+                       } else {
+                               if (writen(STDOUT_FILENO, rbuf, nread) != nread)
+                                       err_sys("writen error to stdout");
+                       }
+
+                       if (flags != 0) {
+                               flags = 0;              /* no infinite loop */
+                               goto oncemore;  /* read the message again */
+                       }
+               }
+       }
+
+       if (pauseclose) {
+               if (verbose)
+                               fprintf(stderr, "pausing before close\n");
+               sleep_us(pauseclose*1000);
+       }
+
+       if (close(sockfd) < 0)
+               err_sys("close error");         /* since SO_LINGER may be set */
+}
diff --git a/sock/loopudp.c b/sock/loopudp.c
new file mode 100644 (file)
index 0000000..351f5f0
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+
+/* Copy everything from stdin to "sockfd",
+ * and everything from "sockfd" to stdout. */
+
+void
+loop_udp(int sockfd)
+{
+       int                                             maxfdp1, nread, ntowrite, stdineof,
+                                                       clilen, servlen, flags;
+       fd_set                                  rset;
+       struct sockaddr_in              cliaddr;                /* for UDP server */
+       struct sockaddr_in              servaddr;               /* for UDP client */
+
+#ifdef HAVE_MSGHDR_MSG_CONTROL
+       struct iovec                    iov[1];
+       struct msghdr                   msg;
+
+#ifdef IP_RECVDSTADDR          /* 4.3BSD Reno and later */
+       static struct cmsghdr  *cmptr = NULL;   /* malloc'ed */
+       struct in_addr                  dstinaddr;              /* for UDP server */
+#define        CONTROLLEN      (sizeof(struct cmsghdr) + sizeof(struct in_addr))
+#endif /* IP_RECVDSTADDR */
+
+#endif /* HAVE_MSGHDR_MSG_CONTROL */
+
+       if (pauseinit)
+               sleep_us(pauseinit*1000);       /* intended for server */
+
+       flags = 0;
+       stdineof = 0;
+       FD_ZERO(&rset);
+       maxfdp1 = sockfd + 1;   /* check descriptors [0..sockfd] */
+
+               /* If UDP client issues connect(), recv() and write() are used.
+                  Server is harder since cannot issue connect().  We use recvfrom()
+                  or recvmsg(), depending on OS. */
+
+       for ( ; ; ) {
+               if (stdineof == 0)
+                       FD_SET(STDIN_FILENO, &rset);
+               FD_SET(sockfd, &rset);
+
+               if (select(maxfdp1, &rset, NULL, NULL, NULL) < 0)
+                       err_sys("select error");
+
+               if (FD_ISSET(STDIN_FILENO, &rset)) {    /* data to read on stdin */
+                       if ( (nread = read(STDIN_FILENO, rbuf, readlen)) < 0)
+                               err_sys("read error from stdin");
+                       else if (nread == 0) {  /* EOF on stdin */
+                               if (halfclose) {
+                                       if (shutdown(sockfd, SHUT_WR) < 0)
+                                               err_sys("shutdown() error");
+
+                                       FD_CLR(STDIN_FILENO, &rset);
+                                       stdineof = 1;   /* don't read stdin anymore */
+                                       continue;               /* back to select() */
+                               }
+                               break;          /* default: stdin EOF -> done */
+                       }
+
+                       if (crlf) {
+                               ntowrite = crlf_add(wbuf, writelen, rbuf, nread);
+                               if (connectudp) {
+                                       if (write(sockfd, wbuf, ntowrite) != ntowrite)
+                                               err_sys("write error");
+                               } else {
+                                       if (sendto(sockfd, wbuf, ntowrite, 0,
+                                                 (struct sockaddr *) &servaddr, sizeof(servaddr))
+                                                                                                                                  != ntowrite)
+                                               err_sys("sendto error");
+                               }
+                       } else {
+                               if (connectudp) {
+                                       if (write(sockfd, rbuf, nread) != nread)
+                                               err_sys("write error");
+                               } else {
+                                       if (sendto(sockfd, rbuf, nread, 0,
+                                                 (struct sockaddr *) &servaddr, sizeof(servaddr))
+                                                                                                                                     != nread)
+                                               err_sys("sendto error");
+                               }
+                       }
+               }
+
+               if (FD_ISSET(sockfd, &rset)) {  /* data to read from socket */
+                       if (server) {
+                               clilen = sizeof(cliaddr);
+#ifndef        HAVE_MSGHDR_MSG_CONTROL /* vanilla BSD sockets */
+                               nread = recvfrom(sockfd, rbuf, readlen, 0,
+                                                                       (struct sockaddr *) &cliaddr, &clilen);
+
+#else  /* 4.3BSD Reno and later; use recvmsg() to get at MSG_TRUNC flag */
+               /* Also lets us get at control information (destination address) */
+
+
+                               iov[0].iov_base = rbuf;
+                               iov[0].iov_len  = readlen;
+                               msg.msg_iov          = iov;
+                               msg.msg_iovlen       = 1;
+                               msg.msg_name         = (caddr_t) &cliaddr;
+                               msg.msg_namelen      = clilen;
+
+#ifdef IP_RECVDSTADDR
+                               if (cmptr == NULL && (cmptr = malloc(CONTROLLEN)) == NULL)
+                                       err_sys("malloc error for control buffer");
+
+                               msg.msg_control      = (caddr_t) cmptr; /* for dest address */
+                               msg.msg_controllen   = CONTROLLEN;
+#else
+                               msg.msg_control      = (caddr_t) 0;     /* no ancillary data */
+                               msg.msg_controllen   = 0;
+#endif /* IP_RECVDSTADDR */
+                               msg.msg_flags        = 0;                       /* flags returned here */
+
+                               nread = recvmsg(sockfd, &msg, 0);
+#endif /* HAVE_MSGHDR_MSG_CONTROL */
+                               if (nread < 0)
+                                       err_sys("datagram receive error");
+
+                               if (verbose) {
+                                       printf("from %s", INET_NTOA(cliaddr.sin_addr));
+#ifdef HAVE_MSGHDR_MSG_CONTROL
+#ifdef IP_RECVDSTADDR
+                                       if (recvdstaddr) {
+                                               if (cmptr->cmsg_len != CONTROLLEN)
+                                                       err_quit("control length (%d) != %d",
+                                                                        cmptr->cmsg_len, CONTROLLEN);
+                                               if (cmptr->cmsg_level != IPPROTO_IP)
+                                                       err_quit("control level != IPPROTO_IP");
+                                               if (cmptr->cmsg_type != IP_RECVDSTADDR)
+                                                       err_quit("control type != IP_RECVDSTADDR");
+                                               memcpy(&dstinaddr, CMSG_DATA(cmptr),
+                                                         sizeof(struct in_addr));
+                                               bzero(cmptr, CONTROLLEN);
+
+                                               printf(", to %s", INET_NTOA(dstinaddr));
+                                       }
+#endif /* IP_RECVDSTADDR */
+#endif /* HAVE_MSGHDR_MSG_CONTROL */
+                                       printf(": ");
+                                       fflush(stdout);
+                               }
+
+#ifdef MSG_TRUNC
+                               if (msg.msg_flags & MSG_TRUNC)
+                                       printf("(datagram truncated)\n");
+#endif
+
+                       } else if (connectudp) {
+                                       /* msgpeek = 0 or MSG_PEEK */
+                               flags = msgpeek;
+                       oncemore:
+                               if ( (nread = recv(sockfd, rbuf, readlen, flags)) < 0)
+                                       err_sys("recv error");
+                               else if (nread == 0) {
+                                       if (verbose)
+                                               fprintf(stderr, "connection closed by peer\n");
+                                       break;          /* EOF, terminate */
+                               }
+
+                       } else {
+                               /* Must use recvfrom() for unconnected UDP client */
+                               servlen = sizeof(servaddr);
+                               nread = recvfrom(sockfd, rbuf, readlen, 0,
+                                                                (struct sockaddr *) &servaddr, &servlen);
+                               if (nread < 0)
+                                       err_sys("datagram recvfrom() error");
+
+                               if (verbose) {
+                                       printf("from %s", INET_NTOA(servaddr.sin_addr));
+                                       printf(": ");
+                                       fflush(stdout);
+                               }
+                       }
+
+                       if (crlf) {
+                               ntowrite = crlf_strip(wbuf, writelen, rbuf, nread);
+                               if (writen(STDOUT_FILENO, wbuf, ntowrite) != ntowrite)
+                                       err_sys("writen error to stdout");
+                       } else {
+                               if (writen(STDOUT_FILENO, rbuf, nread) != nread)
+                                       err_sys("writen error to stdout");
+                       }
+
+                       if (flags != 0) {
+                               flags = 0;              /* no infinite loop */
+                               goto oncemore;  /* read the message again */
+                       }
+               }
+       }
+
+       if (pauseclose) {
+               if (verbose)
+                               fprintf(stderr, "pausing before close\n");
+               sleep_us(pauseclose*1000);
+       }
+
+       if (close(sockfd) < 0)
+               err_sys("close error");         /* since SO_LINGER may be set */
+}
diff --git a/sock/main.c b/sock/main.c
new file mode 100644 (file)
index 0000000..dab3d7f
--- /dev/null
@@ -0,0 +1,436 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+
+char   *host;          /* hostname or dotted-decimal string */
+char   *port;
+
+                       /* DefinE global variables */
+int            bindport;                       /* 0 or TCP or UDP port number to bind */
+                                                       /* set by -b or -l options */
+int            broadcast;                      /* SO_BROADCAST */
+int            cbreak;                         /* set terminal to cbreak mode */
+int            chunkwrite;                     /* write in small chunks; not all-at-once */
+int            client = 1;                     /* acting as client is the default */
+int            connectudp = 1;         /* connect UDP client */
+int            crlf;                           /* convert newline to CR/LF & vice versa */
+int            debug;                          /* SO_DEBUG */
+int            dofork;                         /* concurrent server, do a fork() */
+int            dontroute;                      /* SO_DONTROUTE */
+char   foreignip[32];          /* foreign IP address, dotted-decimal string */
+int            foreignport;            /* foreign port number */
+int            halfclose;                      /* TCP half close option */
+int            ignorewerr;                     /* true if write() errors should be ignored */
+int            iptos = -1;                     /* IP_TOS opton */
+int            ipttl = -1;                     /* IP_TTL opton */
+char   joinip[32];                     /* multicast IP address, dotted-decimal string */
+int            keepalive;                      /* SO_KEEPALIVE */
+long   linger = -1;            /* 0 or positive turns on option */
+int            listenq = 5;            /* listen queue for TCP Server */
+char   localip[32];            /* local IP address, dotted-decimal string */
+int            maxseg;                         /* TCP_MAXSEG */
+int            mcastttl;                       /* multicast TTL */
+int            msgpeek;                        /* MSG_PEEK */
+int            nodelay;                        /* TCP_NODELAY (Nagle algorithm) */
+int            nbuf = 1024;            /* number of buffers to write (sink mode) */
+int            onesbcast;                      /* set IP_ONESBCAST for 255.255.255.255 bcasts */
+int            pauseclose;                     /* #ms to sleep after recv FIN, before close */
+int            pauseinit;                      /* #ms to sleep before first read */
+int            pauselisten;            /* #ms to sleep after listen() */
+int            pauserw;                        /* #ms to sleep before each read or write */
+int            reuseaddr;                      /* SO_REUSEADDR */
+int            reuseport;                      /* SO_REUSEPORT */
+int            readlen = 1024;         /* default read length for socket */
+int            writelen = 1024;        /* default write length for socket */
+int            recvdstaddr;            /* IP_RECVDSTADDR option */
+int            rcvbuflen;                      /* size for SO_RCVBUF */
+int            sndbuflen;                      /* size for SO_SNDBUF */
+long   rcvtimeo;                       /* SO_RCVTIMEO */
+long   sndtimeo;                       /* SO_SNDTIMEO */
+int            sroute_cnt;                     /* count of #IP addresses in route */
+char   *rbuf;                          /* pointer that is malloc'ed */
+char   *wbuf;                          /* pointer that is malloc'ed */
+int            server;                         /* to act as server requires -s option */
+int            sigio;                          /* send SIGIO */
+int            sourcesink;                     /* source/sink mode */
+int            udp;                            /* use UDP instead of TCP */
+int            urgwrite;                       /* write urgent byte after this write */
+int            verbose;                        /* each -v increments this by 1 */
+int            usewritev;                      /* use writev() instead of write() */
+
+struct sockaddr_in     cliaddr, servaddr;
+
+static void    usage(const char *);
+
+int
+main(int argc, char *argv[])
+{
+       int             c, fd;
+       char    *ptr;
+
+       if (argc < 2)
+               usage("");
+
+       opterr = 0;             /* don't want getopt() writing to stderr */
+       while ( (c = getopt(argc, argv, "2b:cf:g:hij:kl:n:op:q:r:st:uvw:x:y:ABCDEFG:H:IJ:KL:NO:P:Q:R:S:TU:VWX:YZ")) != -1) {
+               switch (c) {
+#ifdef IP_ONESBCAST
+               case '2':                       /* use 255.255.255.255 as broadcast address */
+                       onesbcast = 1;
+                       break;
+#endif
+
+               case 'b':
+                       bindport = atoi(optarg);
+                       break;
+
+               case 'c':                       /* convert newline to CR/LF & vice versa */
+                       crlf = 1;
+                       break;
+
+               case 'f':                       /* foreign IP address and port#: a.b.c.d.p */
+                       if ( (ptr = strrchr(optarg, '.')) == NULL)
+                               usage("invalid -f option");
+
+                       *ptr++ = 0;                                     /* null replaces final period */
+                       foreignport = atoi(ptr);        /* port number */
+                       strcpy(foreignip, optarg);      /* save dotted-decimal IP */
+                       break;
+
+               case 'g':                       /* loose source route */
+                       sroute_doopt(0, optarg);
+                       break;
+
+               case 'h':                       /* TCP half-close option */
+                       halfclose = 1;
+                       break;
+
+               case 'i':                       /* source/sink option */
+                       sourcesink = 1;
+                       break;
+
+#ifdef IP_ADD_MEMBERSHIP
+               case 'j':                       /* join multicast group a.b.c.d */
+                       strcpy(joinip, optarg); /* save dotted-decimal IP */
+                       break;
+#endif
+
+               case 'k':                       /* chunk-write option */
+                       chunkwrite = 1;
+                       break;
+
+               case 'l':                       /* local IP address and port#: a.b.c.d.p */
+                       if ( (ptr = strrchr(optarg, '.')) == NULL)
+                               usage("invalid -l option");
+
+                       *ptr++ = 0;                                     /* null replaces final period */
+                       bindport = atoi(ptr);           /* port number */
+                       strcpy(localip, optarg);        /* save dotted-decimal IP */
+                       break;
+
+               case 'n':                       /* number of buffers to write */
+                       nbuf = atol(optarg);
+                       break;
+
+               case 'o':                       /* do not connect UDP client */
+                       connectudp = 0;
+                       break;
+
+               case 'p':                       /* pause before each read or write */
+                       pauserw = atoi(optarg);
+                       break;
+
+               case 'q':                       /* listen queue for TCP server */
+                       listenq = atoi(optarg);
+                       break;
+
+               case 'r':                       /* read() length */
+                       readlen = atoi(optarg);
+                       break;
+
+               case 's':                       /* server */
+                       server = 1;
+                       client = 0;
+                       break;
+
+#ifdef IP_MULTICAST_TTL
+               case 't':                       /* IP_MULTICAST_TTL */
+                       mcastttl = atoi(optarg);
+                       break;
+#endif
+
+               case 'u':                       /* use UDP instead of TCP */
+                       udp = 1;
+                       break;
+
+               case 'v':                       /* output what's going on */
+                       verbose++;
+                       break;
+
+               case 'w':                       /* write() length */
+                       writelen = atoi(optarg);
+                       break;
+
+               case 'x':                       /* SO_RCVTIMEO socket option */
+                       rcvtimeo = atol(optarg);
+                       break;
+
+               case 'y':                       /* SO_SNDTIMEO socket option */
+                       sndtimeo = atol(optarg);
+                       break;
+
+               case 'A':                       /* SO_REUSEADDR socket option */
+                       reuseaddr = 1;
+                       break;
+
+               case 'B':                       /* SO_BROADCAST socket option */
+                       broadcast = 1;
+                       break;
+
+               case 'C':                       /* set standard input to cbreak mode */
+                       cbreak = 1;
+                       break;
+
+               case 'D':                       /* SO_DEBUG socket option */
+                       debug = 1;
+                       break;
+
+               case 'E':                       /* IP_RECVDSTADDR socket option */
+                       recvdstaddr = 1;
+                       break;
+
+               case 'F':                       /* concurrent server, do a fork() */
+                       dofork = 1;
+                       break;
+
+               case 'G':                       /* strict source route */
+                       sroute_doopt(1, optarg);
+                       break;
+
+#ifdef IP_TOS
+               case 'H':                       /* IP_TOS socket option */
+                       iptos = atoi(optarg);
+                       break;
+#endif
+
+               case 'I':                       /* SIGIO signal */
+                       sigio = 1;
+                       break;
+
+#ifdef IP_TTL
+               case 'J':                       /* IP_TTL socket option */
+                       ipttl = atoi(optarg);
+                       break;
+#endif
+
+               case 'K':                       /* SO_KEEPALIVE socket option */
+                       keepalive = 1;
+                       break;
+
+               case 'L':                       /* SO_LINGER socket option */
+                       linger = atol(optarg);
+                       break;
+
+               case 'N':                       /* SO_NODELAY socket option */
+                       nodelay = 1;
+                       break;
+
+               case 'O':                       /* pause before listen(), before first accept() */
+                       pauselisten = atoi(optarg);
+                       break;
+
+               case 'P':                       /* pause before first read() */
+                       pauseinit = atoi(optarg);
+                       break;
+
+               case 'Q':                       /* pause after receiving FIN, but before close() */
+                       pauseclose = atoi(optarg);
+                       break;
+
+               case 'R':                       /* SO_RCVBUF socket option */
+                       rcvbuflen = atoi(optarg);
+                       break;
+
+               case 'S':                       /* SO_SNDBUF socket option */
+                       sndbuflen = atoi(optarg);
+                       break;
+
+#ifdef SO_REUSEPORT
+               case 'T':                       /* SO_REUSEPORT socket option */
+                       reuseport = 1;
+                       break;
+#endif
+
+               case 'U':                       /* when to write urgent byte */
+                       urgwrite = atoi(optarg);
+                       break;
+
+               case 'V':                       /* use writev() instead of write() */
+                       usewritev = 1;
+                       chunkwrite = 1; /* implies this option too */
+                       break;
+
+               case 'W':                       /* ignore write errors */
+                       ignorewerr = 1;
+                       break;
+
+               case 'X':                       /* TCP maximum segment size option */
+                       maxseg = atoi(optarg);
+                       break;
+
+               case 'Y':                       /* SO_DONTROUTE socket option */
+                       dontroute = 1;
+                       break;
+
+               case 'Z':                       /* MSG_PEEK option */
+                       msgpeek = MSG_PEEK;
+                       break;
+
+               case '?':
+                       usage("unrecognized option");
+               }
+       }
+
+               /* check for options that don't make sense */
+       if (udp && halfclose)
+               usage("can't specify -h and -u");
+       if (udp && debug)
+               usage("can't specify -D and -u");
+       if (udp && linger >= 0)
+               usage("can't specify -L and -u");
+       if (udp && nodelay)
+               usage("can't specify -N and -u");
+#ifdef notdef
+       if (udp == 0 && broadcast)
+               usage("can't specify -B with TCP");
+#endif
+       if (udp == 0 && foreignip[0] != 0)
+               usage("can't specify -f with TCP");
+
+       if (client) {
+               if (optind != argc-2)
+                       usage("missing <hostname> and/or <port>");
+               host = argv[optind];
+               port = argv[optind+1];
+
+       } else {
+                       /* If server specifies host and port, then local address is
+                          bound to the "host" argument, instead of being wildcarded. */
+               if (optind == argc-2) {
+                       host = argv[optind];
+                       port = argv[optind+1];
+               } else if (optind == argc-1) {
+                       host = NULL;
+                       port = argv[optind];
+               } else
+                       usage("missing <port>");
+       }
+
+       if (client)
+               fd = cliopen(host, port);
+       else
+               fd = servopen(host, port);
+
+       if (sourcesink) {               /* ignore stdin/stdout */
+               if (client) {
+                       if (udp)
+                               source_udp(fd);
+                       else
+                               source_tcp(fd);
+               } else {
+                       if (udp)
+                               sink_udp(fd);
+                       else
+                               sink_tcp(fd);
+               }
+
+       } else {                                /* copy stdin/stdout to/from socket */
+               if (udp)
+                       loop_udp(fd);
+               else
+                       loop_tcp(fd);
+       }
+
+       exit(0);
+}
+
+static void
+usage(const char *msg)
+{
+       err_msg(
+"usage: sock [ options ] <host> <port>              (for client; default)\n"
+"       sock [ options ] -s [ <IPaddr> ] <port>     (for server)\n"
+"       sock [ options ] -i <host> <port>           (for \"source\" client)\n"
+"       sock [ options ] -i -s [ <IPaddr> ] <port>  (for \"sink\" server)\n"
+"options: -b n  bind n as client's local port number\n"
+"         -c    convert newline to CR/LF & vice versa\n"
+"         -f a.b.c.d.p  foreign IP address = a.b.c.d, foreign port # = p\n"
+"         -g a.b.c.d  loose source route\n"
+"         -h    issue TCP half close on standard input EOF\n"
+"         -i    \"source\" data to socket, \"sink\" data from socket (w/-s)\n"
+#ifdef IP_ADD_MEMBERSHIP
+"         -j a.b.c.d  join multicast group\n"
+#endif
+"         -k    write or writev in chunks\n"
+"         -l a.b.c.d.p  client's local IP address = a.b.c.d, local port # = p\n"
+"         -n n  # buffers to write for \"source\" client (default 1024)\n"
+"         -o    do NOT connect UDP client\n"
+"         -p n  # ms to pause before each read or write (source/sink)\n"
+"         -q n  size of listen queue for TCP server (default 5)\n"
+"         -r n  # bytes per read() for \"sink\" server (default 1024)\n"
+"         -s    operate as server instead of client\n"
+#ifdef IP_MULTICAST_TTL
+"         -t n  set multicast ttl\n"
+#endif
+"         -u    use UDP instead of TCP\n"
+"         -v    verbose\n"
+"         -w n  # bytes per write() for \"source\" client (default 1024)\n"
+"         -x n  # ms for SO_RCVTIMEO (receive timeout)\n"
+"         -y n  # ms for SO_SNDTIMEO (send timeout)\n"
+"         -A    SO_REUSEADDR option\n"
+"         -B    SO_BROADCAST option\n"
+"         -C    set terminal to cbreak mode\n"
+"         -D    SO_DEBUG option\n"
+"         -E    IP_RECVDSTADDR option\n"
+"         -F    fork after connection accepted (TCP concurrent server)\n"
+"         -G a.b.c.d  strict source route\n"
+#ifdef IP_TOS
+"         -H n  IP_TOS option (16=min del, 8=max thru, 4=max rel, 2=min$)\n"
+#endif
+"         -I    SIGIO signal\n"
+#ifdef IP_TTL
+"         -J n  IP_TTL option\n"
+#endif
+"         -K    SO_KEEPALIVE option\n"
+"         -L n  SO_LINGER option, n = linger time\n"
+"         -N    TCP_NODELAY option\n"
+"         -O n  # ms to pause after listen, but before first accept\n"
+"         -P n  # ms to pause before first read or write (source/sink)\n"
+"         -Q n  # ms to pause after receiving FIN, but before close\n"
+"         -R n  SO_RCVBUF option\n"
+"         -S n  SO_SNDBUF option\n"
+#ifdef SO_REUSEPORT
+"         -T    SO_REUSEPORT option\n"
+#endif
+"         -U n  enter urgent mode before write number n (source only)\n"
+"         -V    use writev() instead of write(); enables -k too\n"
+"         -W    ignore write errors for sink client\n"
+"         -X n  TCP_MAXSEG option (set MSS)\n"
+"         -Y    SO_DONTROUTE option\n"
+"         -Z    MSG_PEEK\n"
+#ifdef IP_ONESBCAST
+"         -2    IP_ONESBCAST option (255.255.255.255 for broadcast\n"
+#endif
+);
+
+       if (msg[0] != 0)
+               err_quit("%s", msg);
+       exit(1);
+}
diff --git a/sock/multicast.c b/sock/multicast.c
new file mode 100644 (file)
index 0000000..0aa1fb4
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+
+void
+join_mcast(int fd, struct sockaddr_in *sin)
+{
+#ifdef IP_ADD_MEMBERSHIP       /* only include if host supports mcasting */
+       u_long                  inaddr;
+       struct ip_mreq  mreq;
+
+       inaddr = sin->sin_addr.s_addr;
+       if (IN_MULTICAST(inaddr) == 0)
+               return;                 /* not a multicast address */
+
+       mreq.imr_multiaddr.s_addr = inaddr;
+       mreq.imr_interface.s_addr = htonl(INADDR_ANY);  /* need way to change */
+       if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
+                                                                                               sizeof(mreq)) == -1 )
+               err_sys("IP_ADD_MEMBERSHIP error");
+
+       if (verbose)
+                       fprintf(stderr, "multicast group joined\n");
+#endif /* IP_ADD_MEMBERSHIP */
+}
diff --git a/sock/ourhdr.h b/sock/ourhdr.h
new file mode 100644 (file)
index 0000000..358781e
--- /dev/null
@@ -0,0 +1,121 @@
+/* Our own header, to be included *after* all standard system headers */
+
+#ifndef        __ourhdr_h
+#define        __ourhdr_h
+
+#include       <sys/types.h>   /* required for some of our prototypes */
+#include       <stdio.h>               /* for convenience */
+#include       <stdlib.h>              /* for convenience */
+#include       <string.h>              /* for convenience */
+#include       <unistd.h>              /* for convenience */
+
+#ifdef notdef  /* delete for systems that don't define this (SunOS 4.x) */
+typedef        int     ssize_t;
+#endif
+
+#ifdef notdef  /* delete if <stdlib.h> doesn't define these for getopt() */
+extern char    *optarg;
+extern int     optind, opterr, optopt;
+#endif
+
+#ifdef notdef  /* delete if send() not supported (DEC OSF/1) */
+#define        send(a,b,c,d)   sendto((a), (b), (c), (d), (struct sockaddr *) NULL, 0)
+#endif
+
+#define        MAXLINE 4096                    /* max line length */
+
+#define        FILE_MODE       (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
+                                       /* default file access permissions for new files */
+#define        DIR_MODE        (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)
+                                       /* default permissions for new directories */
+
+typedef        void    Sigfunc(int);   /* for signal handlers */
+
+                                       /* 4.3BSD Reno <signal.h> doesn't define SIG_ERR */
+#if    defined(SIG_IGN) && !defined(SIG_ERR)
+#define        SIG_ERR ((Sigfunc *)-1)
+#endif
+
+#define        min(a,b)        ((a) < (b) ? (a) : (b))
+#define        max(a,b)        ((a) > (b) ? (a) : (b))
+
+                                       /* prototypes for our own functions */
+char   *path_alloc(int *);                     /* {Prog pathalloc} */
+int             open_max(void);                        /* {Prog openmax} */
+void    clr_fl(int, int);                      /* {Prog setfl} */
+void    set_fl(int, int);                      /* {Prog setfl} */
+void    pr_exit(int);                          /* {Prog prexit} */
+void    pr_mask(const char *);         /* {Prog prmask} */
+Sigfunc        *signal_intr(int, Sigfunc *);/* {Prog signal_intr_function} */
+
+int             tty_cbreak(int);                       /* {Prog raw} */
+int             tty_raw(int);                          /* {Prog raw} */
+int             tty_reset(int);                        /* {Prog raw} */
+void    tty_atexit(void);                      /* {Prog raw} */
+#ifdef ECHO    /* only if <termios.h> has been included */
+struct termios *tty_termios(void);     /* {Prog raw} */
+#endif
+
+void    sleep_us(unsigned int);        /* {Ex sleepus} */
+ssize_t         readn(int, void *, size_t);/* {Prog readn} */
+ssize_t         writen(int, const void *, size_t);/* {Prog writen} */
+int             daemon_init(void);                     /* {Prog daemoninit} */
+
+int             s_pipe(int *);                         /* {Progs svr4_spipe bsd_spipe} */
+int             recv_fd(int, ssize_t (*func)(int, const void *, size_t));
+                                                                       /* {Progs recvfd_svr4 recvfd_43bsd} */
+int             send_fd(int, int);                     /* {Progs sendfd_svr4 sendfd_43bsd} */
+int             send_err(int, int, const char *);/* {Prog senderr} */
+int             serv_listen(const char *);     /* {Progs servlisten_svr4 servlisten_44bsd} */
+int             serv_accept(int, uid_t *);     /* {Progs servaccept_svr4 servaccept_44bsd} */
+int             cli_conn(const char *);        /* {Progs cliconn_svr4 cliconn_44bsd} */
+int             buf_args(char *, int (*func)(int, char **));
+                                                                       /* {Prog bufargs} */
+
+int             ptym_open(char *);                     /* {Progs ptyopen_svr4 ptyopen_44bsd} */
+int             ptys_open(int, char *);        /* {Progs ptyopen_svr4 ptyopen_44bsd} */
+#ifdef TIOCGWINSZ
+pid_t   pty_fork(int *, char *, const struct termios *,
+                                 const struct winsize *);      /* {Prog ptyfork} */
+#endif
+
+int            lock_reg(int, int, int, off_t, int, off_t);
+                                                                       /* {Prog lockreg} */
+#define        read_lock(fd, offset, whence, len) \
+                       lock_reg(fd, F_SETLK, F_RDLCK, offset, whence, len)
+#define        readw_lock(fd, offset, whence, len) \
+                       lock_reg(fd, F_SETLKW, F_RDLCK, offset, whence, len)
+#define        write_lock(fd, offset, whence, len) \
+                       lock_reg(fd, F_SETLK, F_WRLCK, offset, whence, len)
+#define        writew_lock(fd, offset, whence, len) \
+                       lock_reg(fd, F_SETLKW, F_WRLCK, offset, whence, len)
+#define        un_lock(fd, offset, whence, len) \
+                       lock_reg(fd, F_SETLK, F_UNLCK, offset, whence, len)
+
+pid_t  lock_test(int, int, off_t, int, off_t);
+                                                                       /* {Prog locktest} */
+
+#define        is_readlock(fd, offset, whence, len) \
+                       lock_test(fd, F_RDLCK, offset, whence, len)
+#define        is_writelock(fd, offset, whence, len) \
+                       lock_test(fd, F_WRLCK, offset, whence, len)
+
+void   err_dump(const char *, ...);    /* {App misc_source} */
+void   err_msg(const char *, ...);
+void   err_quit(const char *, ...);
+void   err_ret(const char *, ...);
+void   err_sys(const char *, ...);
+
+void   log_msg(const char *, ...);             /* {App misc_source} */
+void   log_open(const char *, int, int);
+void   log_quit(const char *, ...);
+void   log_ret(const char *, ...);
+void   log_sys(const char *, ...);
+
+void   TELL_WAIT(void);                /* parent/child from {Sec race_conditions} */
+void   TELL_PARENT(pid_t);
+void   TELL_CHILD(pid_t);
+void   WAIT_PARENT(void);
+void   WAIT_CHILD(void);
+
+#endif /* __ourhdr_h */
diff --git a/sock/pattern.c b/sock/pattern.c
new file mode 100644 (file)
index 0000000..e41f5b6
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+#include       <ctype.h>
+
+void
+pattern(char *ptr, int len)
+{
+       char    c;
+
+       c = 0;
+       while(len-- > 0)  {
+               while(isprint((c & 0x7F)) == 0)
+                       c++;    /* skip over nonprinting characters */
+               *ptr++ = (c++ & 0x7F);
+       }
+}
diff --git a/sock/servopen.c b/sock/servopen.c
new file mode 100644 (file)
index 0000000..08a268a
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+
+int
+servopen(char *host, char *port)
+{
+       int                                     fd, newfd, i, on, pid;
+       const char                      *protocol;
+       struct in_addr          inaddr;
+       struct servent          *sp;
+
+       protocol = udp ? "udp" : "tcp";
+
+               /* Initialize the socket address structure */
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+
+               /* Caller normally wildcards the local Internet address, meaning
+                  a connection will be accepted on any connected interface.
+                  We only allow an IP address for the "host", not a name. */
+       if (host == NULL)
+               servaddr.sin_addr.s_addr = htonl(INADDR_ANY);           /* wildcard */
+       else {
+               if (inet_aton(host, &inaddr) == 0)
+                       err_quit("invalid host name for server: %s", host);
+               servaddr.sin_addr = inaddr;
+       }
+
+               /* See if "port" is a service name or number */
+       if ( (i = atoi(port)) == 0) {
+               if ( (sp = getservbyname(port, protocol)) == NULL)
+                       err_ret("getservbyname() error for: %s/%s", port, protocol);
+
+               servaddr.sin_port = sp->s_port;
+       } else
+               servaddr.sin_port = htons(i);
+
+       if ( (fd = socket(AF_INET, udp ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0)
+               err_sys("socket() error");
+
+       if (reuseaddr) {
+               on = 1;
+               if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
+                       err_sys("setsockopt of SO_REUSEADDR error");
+       }
+
+#ifdef SO_REUSEPORT
+       if (reuseport) {
+               on = 1;
+               if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)
+                       err_sys("setsockopt of SO_REUSEPORT error");
+       }
+#endif
+
+               /* Bind our well-known port so the client can connect to us. */
+       if (bind(fd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
+               err_sys("can't bind local address");
+
+       join_mcast(fd, &servaddr);
+
+       if (udp) {
+               buffers(fd);
+
+               if (foreignip[0] != 0) {        /* connect to foreignip/port# */
+                       bzero(&cliaddr, sizeof(cliaddr));
+                       if (inet_aton(foreignip, &cliaddr.sin_addr) == 0)
+                               err_quit("invalid IP address: %s", foreignip);
+                       cliaddr.sin_family = AF_INET;
+                       cliaddr.sin_port   = htons(foreignport);
+                               /* connect() for datagram socket doesn't appear to allow
+                                  wildcarding of either IP address or port number */
+
+                       if (connect(fd, (struct sockaddr *) &cliaddr, sizeof(cliaddr))
+                                                                                                                                                 < 0)
+                               err_sys("connect() error");
+                       
+               }
+
+               sockopts(fd, 1);
+
+               return(fd);             /* nothing else to do */
+       }
+
+       buffers(fd);            /* may set receive buffer size; must do here to get
+                                                  correct window advertised on SYN */
+       sockopts(fd, 0);        /* only set some socket options for fd */
+
+       listen(fd, listenq);
+
+       if (pauselisten)
+               sleep_us(pauselisten*1000);             /* lets connection queue build up */
+
+       if (dofork)
+               TELL_WAIT();                    /* initialize synchronization primitives */
+
+       for ( ; ; ) {
+               i = sizeof(cliaddr);
+               if ( (newfd = accept(fd, (struct sockaddr *) &cliaddr, &i)) < 0)
+                       err_sys("accept() error");
+
+               if (dofork) {
+                       if ( (pid = fork()) < 0)
+                               err_sys("fork error");
+
+                       if (pid > 0) {
+                               close(newfd);   /* parent closes connected socket */
+                               WAIT_CHILD();   /* wait for child to output to terminal */
+                               continue;               /* and back to for(;;) for another accept() */
+                       } else {
+                               close(fd);              /* child closes listening socket */
+                       }
+               }
+
+                       /* child (or iterative server) continues here */
+               if (verbose) {
+                               /* Call getsockname() to find local address bound to socket:
+                                  local internet address is now determined (if multihomed). */
+                       i = sizeof(servaddr);
+                       if (getsockname(newfd, (struct sockaddr *) &servaddr, &i) < 0)
+                               err_sys("getsockname() error");
+
+                                               /* Can't do one fprintf() since inet_ntoa() stores
+                                                  the result in a static location. */
+                       fprintf(stderr, "connection on %s.%d ",
+                                       INET_NTOA(servaddr.sin_addr), ntohs(servaddr.sin_port));
+                       fprintf(stderr, "from %s.%d\n",
+                                       INET_NTOA(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
+               }
+
+               buffers(newfd);         /* setsockopt() again, in case it didn't propagate
+                                                          from listening socket to connected socket */
+               sockopts(newfd, 1);     /* can set all socket options for this socket */
+
+               if (dofork)
+                       TELL_PARENT(getppid()); /* tell parent we're done with terminal */
+
+               return(newfd);
+       }
+}
diff --git a/sock/sinktcp.c b/sock/sinktcp.c
new file mode 100644 (file)
index 0000000..91e88ba
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+
+void
+sink_tcp(int sockfd)
+{
+       int             n, flags;
+
+       if (pauseinit)
+               sleep_us(pauseinit*1000);
+
+       for ( ; ; ) {   /* read until peer closes connection; -n opt ignored */
+                       /* msgpeek = 0 or MSG_PEEK */
+               flags = msgpeek;
+       oncemore:
+               if ( (n = recv(sockfd, rbuf, readlen, flags)) < 0) {
+                       err_sys("recv error");
+
+               } else if (n == 0) {
+                       if (verbose)
+                               fprintf(stderr, "connection closed by peer\n");
+                       break;
+
+#ifdef notdef          /* following not possible with TCP */
+               } else if (n != readlen)
+                       err_quit("read returned %d, expected %d", n, readlen);
+#else
+               }
+#endif
+
+               if (verbose)
+                       fprintf(stderr, "received %d bytes%s\n", n,
+                                       (flags == MSG_PEEK) ? " (MSG_PEEK)" : "");
+
+               if (pauserw)
+                       sleep_us(pauserw*1000);
+
+               if (flags != 0) {
+                       flags = 0;              /* no infinite loop */
+                       goto oncemore;  /* read the message again */
+               }
+       }
+
+       if (pauseclose) {       /* pausing here puts peer into FIN_WAIT_2 */
+               if (verbose)
+                               fprintf(stderr, "pausing before close\n");
+               sleep_us(pauseclose*1000);
+       }
+
+       if (close(sockfd) < 0)
+               err_sys("close error");         /* since SO_LINGER may be set */
+}
diff --git a/sock/sinkudp.c b/sock/sinkudp.c
new file mode 100644 (file)
index 0000000..1a0dae1
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+
+void
+sink_udp(int sockfd)   /* TODO: use recvfrom ?? */
+{
+       int             n, flags;
+
+       if (pauseinit)
+               sleep_us(pauseinit*1000);
+
+       for ( ; ; ) {   /* read until peer closes connection; -n opt ignored */
+                       /* msgpeek = 0 or MSG_PEEK */
+               flags = msgpeek;
+       oncemore:
+               if ( (n = recv(sockfd, rbuf, readlen, flags)) < 0) {
+                       err_sys("recv error");
+
+               } else if (n == 0) {
+                       if (verbose)
+                               fprintf(stderr, "connection closed by peer\n");
+                       break;
+
+#ifdef notdef          /* following not possible with TCP */
+               } else if (n != readlen)
+                       err_quit("read returned %d, expected %d", n, readlen);
+#else
+               }
+#endif
+
+               if (verbose) {
+                       fprintf(stderr, "received %d bytes%s\n", n,
+                                       (flags == MSG_PEEK) ? " (MSG_PEEK)" : "");
+                       if (verbose > 1) {
+       fprintf(stderr, "printing %d bytes\n", n);
+                               rbuf[n] = 0;    /* make certain it's null terminated */
+                               fprintf(stderr, "SDAP header: %lx\n", *((long *) rbuf));
+                               fprintf(stderr, "next long: %lx\n", *((long *) rbuf+4));
+                               fputs(&rbuf[8], stderr);
+                       }
+               }
+
+               if (pauserw)
+                       sleep_us(pauserw*1000);
+
+               if (flags != 0) {
+                       flags = 0;              /* avoid infinite loop */
+                       goto oncemore;  /* read the message again */
+               }
+       }
+
+       if (pauseclose) {
+               if (verbose)
+                               fprintf(stderr, "pausing before close\n");
+               sleep_us(pauseclose*1000);
+       }
+
+       if (close(sockfd) < 0)
+               err_sys("close error");
+}
diff --git a/sock/sleepus.c b/sock/sleepus.c
new file mode 100644 (file)
index 0000000..37eaec2
--- /dev/null
@@ -0,0 +1,29 @@
+#include       <sys/types.h>
+#include       <sys/time.h>
+#include       <errno.h>
+#include       <stddef.h>
+#include       "ourhdr.h"
+
+void
+sleep_us(unsigned int nusecs)
+{
+       struct timeval  tval;
+
+       for ( ; ; ) {
+               tval.tv_sec = nusecs / 1000000;
+               tval.tv_usec = nusecs % 1000000;
+               if (select(0, NULL, NULL, NULL, &tval) == 0)
+                       break;          /* all OK */
+               /*
+                * Note than on an interrupted system call (i.e, SIGIO) there's not
+                * much we can do, since the timeval{} isn't updated with the time
+                * remaining.  We could obtain the clock time before the call, and
+                * then obtain the clock time here, subtracting them to determine
+                * how long select() blocked before it was interrupted, but that
+                * seems like too much work :-)
+                */
+               if (errno == EINTR)
+                       continue;
+               err_sys("sleep_us: select error");
+       }
+}
diff --git a/sock/sock.h b/sock/sock.h
new file mode 100644 (file)
index 0000000..1a7c240
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "unp.h"
+
+#include       <sys/uio.h>
+#ifdef __bsdi__
+#include       <machine/endian.h>      /* required before tcp.h, for BYTE_ORDER */
+#endif
+#include       <netinet/tcp.h>         /* TCP_NODELAY */
+#include       <netdb.h>                       /* getservbyname(), gethostbyname() */
+
+                               /* declare global variables */
+extern int             bindport;
+extern int             broadcast;
+extern int             cbreak;
+extern int             chunkwrite;
+extern int             client;
+extern int             connectudp;
+extern int             crlf;
+extern int             debug;
+extern int             dofork;
+extern int             dontroute;
+extern char            foreignip[];
+extern int             foreignport;
+extern int             halfclose;
+extern int             ignorewerr;
+extern int             iptos;
+extern int             ipttl;
+extern char            joinip[];
+extern int             keepalive;
+extern long            linger;
+extern int             listenq;
+extern char            localip[];
+extern int             maxseg;
+extern int             mcastttl;
+extern int             msgpeek;
+extern int             nodelay;
+extern int             nbuf;
+extern int             onesbcast;
+extern int             pauseclose;
+extern int             pauseinit;
+extern int             pauselisten;
+extern int             pauserw;
+extern int             reuseaddr;
+extern int             reuseport;
+extern int             readlen;
+extern int             writelen;
+extern int             recvdstaddr;
+extern int             rcvbuflen;
+extern int             sndbuflen;
+extern long            rcvtimeo;
+extern long            sndtimeo;
+extern char       *rbuf;
+extern char       *wbuf;
+extern int             server;
+extern int             sigio;
+extern int             sourcesink;
+extern int             sroute_cnt;
+extern int             udp;
+extern int             urgwrite;
+extern int             verbose;
+extern int             usewritev;
+
+extern struct sockaddr_in      cliaddr, servaddr;
+
+/* Earlier versions of gcc under SunOS 4.x have problems passing arguments
+   that are structs (as opposed to pointers to structs).  This shows up
+   with inet_ntoa, whose argument is a "struct in_addr". */
+
+#if    defined(sun) && defined(__GNUC__) && defined(GCC_STRUCT_PROBLEM)
+#define        INET_NTOA(foo)  inet_ntoa(&foo)
+#else
+#define        INET_NTOA(foo)  inet_ntoa(foo)
+#endif
+
+                               /* function prototypes */
+void   buffers(int);
+int            cliopen(char *, char *);
+int            crlf_add(char *, int, const char *, int);
+int            crlf_strip(char *, int, const char *, int);
+void   join_mcast(int, struct sockaddr_in *);
+void   loop_tcp(int);
+void   loop_udp(int);
+void   pattern(char *, int);
+int            servopen(char *, char *);
+void   sink_tcp(int);
+void   sink_udp(int);
+void   source_tcp(int);
+void   source_udp(int);
+void   sroute_doopt(int, char *);
+void   sroute_set(int);
+void   sleep_us(unsigned int);
+void   sockopts(int, int);
+ssize_t        dowrite(int, const void *, size_t);
+
+void   TELL_WAIT(void);
+void   TELL_PARENT(pid_t);
+void   WAIT_PARENT(void);
+void   TELL_CHILD(pid_t);
+void   WAIT_CHILD(void);
diff --git a/sock/sock.in b/sock/sock.in
new file mode 100644 (file)
index 0000000..2d42c2f
--- /dev/null
@@ -0,0 +1 @@
+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
diff --git a/sock/sockopts.c b/sock/sockopts.c
new file mode 100644 (file)
index 0000000..6e276de
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+#include       <fcntl.h>
+#include       <sys/ioctl.h>
+
+void
+sockopts(int sockfd, int doall)
+{
+    int                        option, optlen;
+       struct linger   ling;
+       struct timeval  timer;
+
+       /* "doall" is 0 for a server's listening socket (i.e., before
+          accept() has returned.)  Some socket options such as SO_KEEPALIVE
+          don't make sense at this point, while others like SO_DEBUG do. */
+
+    if (debug) {
+        option = 1;
+        if (setsockopt(sockfd, SOL_SOCKET, SO_DEBUG,
+                                                                               &option, sizeof(option)) < 0)
+            err_sys("SO_DEBUG setsockopt error");
+
+        option = 0;
+               optlen = sizeof(option);
+        if (getsockopt(sockfd, SOL_SOCKET, SO_DEBUG,
+                                                                               &option, &optlen) < 0)
+            err_sys("SO_DEBUG getsockopt error");
+               if (option == 0)
+                       err_quit("SO_DEBUG not set (%d)", option);
+
+               if (verbose)
+                       fprintf(stderr, "SO_DEBUG set\n");
+    }
+
+    if (dontroute) {
+        option = 1;
+        if (setsockopt(sockfd, SOL_SOCKET, SO_DONTROUTE,
+                                                                               &option, sizeof(option)) < 0)
+            err_sys("SO_DONTROUTE setsockopt error");
+
+        option = 0;
+               optlen = sizeof(option);
+        if (getsockopt(sockfd, SOL_SOCKET, SO_DONTROUTE,
+                                                                               &option, &optlen) < 0)
+            err_sys("SO_DONTROUTE getsockopt error");
+               if (option == 0)
+                       err_quit("SO_DONTROUTE not set (%d)", option);
+
+               if (verbose)
+                       fprintf(stderr, "SO_DONTROUTE set\n");
+    }
+
+#ifdef IP_TOS
+    if (iptos != -1 && doall == 0) {
+        if (setsockopt(sockfd, IPPROTO_IP, IP_TOS,
+                                                                               &iptos, sizeof(iptos)) < 0)
+            err_sys("IP_TOS setsockopt error");
+
+        option = 0;
+               optlen = sizeof(option);
+        if (getsockopt(sockfd, IPPROTO_IP, IP_TOS,
+                                                                               &option, &optlen) < 0)
+            err_sys("IP_TOS getsockopt error");
+               if (option != iptos)
+                       err_quit("IP_TOS not set (%d)", option);
+
+               if (verbose)
+                       fprintf(stderr, "IP_TOS set to %d\n", iptos);
+    }
+#endif
+
+#ifdef IP_TTL
+    if (ipttl != -1 && doall == 0) {
+        if (setsockopt(sockfd, IPPROTO_IP, IP_TTL,
+                                                                               &ipttl, sizeof(ipttl)) < 0)
+            err_sys("IP_TTL setsockopt error");
+
+        option = 0;
+               optlen = sizeof(option);
+        if (getsockopt(sockfd, IPPROTO_IP, IP_TTL,
+                                                                               &option, &optlen) < 0)
+            err_sys("IP_TTL getsockopt error");
+               if (option != ipttl)
+                       err_quit("IP_TTL not set (%d)", option);
+
+               if (verbose)
+                       fprintf(stderr, "IP_TTL set to %d\n", ipttl);
+    }
+#endif
+
+    if (maxseg && udp == 0) {
+                       /* Need to set MSS for server before connection established */
+                       /* Beware: some kernels do not let the process set this socket
+                          option; others only let it be decreased. */
+        if (setsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG,
+                                                                               &maxseg, sizeof(maxseg)) < 0)
+            err_sys("TCP_MAXSEG setsockopt error");
+
+        option = 0;
+               optlen = sizeof(option);
+        if (getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG,
+                                                                               &option, &optlen) < 0)
+            err_sys("TCP_MAXSEG getsockopt error");
+
+               if (verbose)
+                       fprintf(stderr, "TCP_MAXSEG = %d\n", option);
+    }
+
+       if (sroute_cnt > 0)
+               sroute_set(sockfd);
+
+    if (broadcast) {
+        option = 1;
+        if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,
+                                                                               &option, sizeof(option)) < 0)
+            err_sys("SO_BROADCAST setsockopt error");
+
+        option = 0;
+               optlen = sizeof(option);
+        if (getsockopt(sockfd, SOL_SOCKET, SO_BROADCAST,
+                                                                               &option, &optlen) < 0)
+            err_sys("SO_BROADCAST getsockopt error");
+               if (option == 0)
+                       err_quit("SO_BROADCAST not set (%d)", option);
+
+               if (verbose)
+                       fprintf(stderr, "SO_BROADCAST set\n");
+
+#ifdef IP_ONESBCAST
+               if (onesbcast) {
+               option = 1;
+               if (setsockopt(sockfd, IPPROTO_IP, IP_ONESBCAST,
+                                                                                       &option, sizeof(option)) < 0)
+                   err_sys("IP_ONESBCAST setsockopt error");
+       
+               option = 0;
+                       optlen = sizeof(option);
+               if (getsockopt(sockfd, IPPROTO_IP, IP_ONESBCAST,
+                                                                                       &option, &optlen) < 0)
+                   err_sys("IP_ONESBCAST getsockopt error");
+                       if (option == 0)
+                               err_quit("IP_ONESBCAST not set (%d)", option);
+       
+                       if (verbose)
+                               fprintf(stderr, "IP_ONESBCAST set\n");
+               }
+#endif
+    }
+
+#ifdef IP_ADD_MEMBERSHIP
+    if (joinip[0]) {
+               struct ip_mreq  join;
+
+               if (inet_aton(joinip, &join.imr_multiaddr) == 0)
+                       err_quit("invalid multicast address: %s", joinip);
+               join.imr_interface.s_addr = htonl(INADDR_ANY);
+        if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+                                                                               &join, sizeof(join)) < 0)
+            err_sys("IP_ADD_MEMBERSHIP setsockopt error");
+
+               if (verbose)
+                       fprintf(stderr, "IP_ADD_MEMBERSHIP set\n");
+    }
+#endif
+
+#ifdef IP_MULTICAST_TTL
+    if (mcastttl) {
+               u_char  ttl = mcastttl;
+
+        if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,
+                                                                               &ttl, sizeof(ttl)) < 0)
+            err_sys("IP_MULTICAST_TTL setsockopt error");
+
+               optlen = sizeof(ttl);
+        if (getsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,
+                                                                               &ttl, &optlen) < 0)
+            err_sys("IP_MULTICAST_TTL getsockopt error");
+               if (ttl != mcastttl)
+                       err_quit("IP_MULTICAST_TTL not set (%d)", ttl);
+
+               if (verbose)
+                       fprintf(stderr, "IP_MULTICAST_TTL set to %d\n", ttl);
+    }
+#endif
+
+    if (keepalive && doall && udp == 0) {
+        option = 1;
+        if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
+                                                                               &option, sizeof(option)) < 0)
+            err_sys("SO_KEEPALIVE setsockopt error");
+
+        option = 0;
+               optlen = sizeof(option);
+        if (getsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
+                                                                               &option, &optlen) < 0)
+            err_sys("SO_KEEPALIVE getsockopt error");
+               if (option == 0)
+                       err_quit("SO_KEEPALIVE not set (%d)", option);
+
+               if (verbose)
+                       fprintf(stderr, "SO_KEEPALIVE set\n");
+    }
+
+    if (nodelay && doall && udp == 0) {
+        option = 1;
+        if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,
+                                                                               &option, sizeof(option)) < 0)
+            err_sys("TCP_NODELAY setsockopt error");
+
+        option = 0;
+               optlen = sizeof(option);
+        if (getsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,
+                                                                               &option, &optlen) < 0)
+            err_sys("TCP_NODELAY getsockopt error");
+               if (option == 0)
+                       err_quit("TCP_NODELAY not set (%d)", option);
+
+               if (verbose)
+                       fprintf(stderr, "TCP_NODELAY set\n");
+    }
+
+    if (doall && verbose && udp == 0) {        /* just print MSS if verbose */
+        option = 0;
+               optlen = sizeof(option);
+        if (getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG,
+                                                                               &option, &optlen) < 0)
+            err_sys("TCP_MAXSEG getsockopt error");
+
+               fprintf(stderr, "TCP_MAXSEG = %d\n", option);
+    }
+
+    if (linger >= 0 && doall && udp == 0) {
+        ling.l_onoff = 1;
+        ling.l_linger = linger;                /* 0 for abortive disconnect */
+        if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER,
+                                                                               &ling, sizeof(ling)) < 0)
+            err_sys("SO_LINGER setsockopt error");
+
+               ling.l_onoff = 0;
+               ling.l_linger = -1;
+        optlen = sizeof(struct linger);
+        if (getsockopt(sockfd, SOL_SOCKET, SO_LINGER,
+                                                                               &ling, &optlen) < 0)
+            err_sys("SO_LINGER getsockopt error");
+               if (ling.l_onoff == 0 || ling.l_linger != linger)
+                       err_quit("SO_LINGER not set (%d, %d)", ling.l_onoff, ling.l_linger);
+
+        if (verbose)
+            fprintf(stderr, "linger %s, time = %d\n",
+                            ling.l_onoff ? "on" : "off", ling.l_linger);
+    }
+
+    if (doall && rcvtimeo) {
+#ifdef SO_RCVTIMEO
+               /* User specifies millisec, must convert to sec/usec */
+               timer.tv_sec  =  rcvtimeo / 1000;
+               timer.tv_usec = (rcvtimeo % 1000) * 1000;
+        if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO,
+                                                                               &timer, sizeof(timer)) < 0)
+            err_sys("SO_RCVTIMEO setsockopt error");
+
+               timer.tv_sec = timer.tv_usec = 0;
+               optlen = sizeof(timer);
+        if (getsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO,
+                                                                               &timer, &optlen) < 0)
+            err_sys("SO_RCVTIMEO getsockopt error");
+
+               if (verbose)
+                       fprintf(stderr, "SO_RCVTIMEO: %ld.%06ld\n",
+                                                                       timer.tv_sec, timer.tv_usec);
+#else
+               fprintf(stderr, "warning: SO_RCVTIMEO not supported by host\n");
+#endif
+    }
+
+    if (doall && sndtimeo) {
+#ifdef SO_SNDTIMEO
+               /* User specifies millisec, must convert to sec/usec */
+               timer.tv_sec  =  sndtimeo / 1000;
+               timer.tv_usec = (sndtimeo % 1000) * 1000;
+        if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO,
+                                                                               &timer, sizeof(timer)) < 0)
+            err_sys("SO_SNDTIMEO setsockopt error");
+
+               timer.tv_sec = timer.tv_usec = 0;
+               optlen = sizeof(timer);
+        if (getsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO,
+                                                                               &timer, &optlen) < 0)
+            err_sys("SO_SNDTIMEO getsockopt error");
+
+               if (verbose)
+                       fprintf(stderr, "SO_SNDTIMEO: %ld.%06ld\n",
+                                                                       timer.tv_sec, timer.tv_usec);
+#else
+               fprintf(stderr, "warning: SO_SNDTIMEO not supported by host\n");
+#endif
+    }
+
+    if (recvdstaddr && udp) {
+#ifdef IP_RECVDSTADDR
+        option = 1;
+        if (setsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR,
+                                                                               &option, sizeof(option)) < 0)
+            err_sys("IP_RECVDSTADDR setsockopt error");
+
+        option = 0;
+               optlen = sizeof(option);
+        if (getsockopt(sockfd, IPPROTO_IP, IP_RECVDSTADDR,
+                                                                               &option, &optlen) < 0)
+            err_sys("IP_RECVDSTADDR getsockopt error");
+               if (option == 0)
+                       err_quit("IP_RECVDSTADDR not set (%d)", option);
+
+               if (verbose)
+                       fprintf(stderr, "IP_RECVDSTADDR set\n");
+#else
+               fprintf(stderr, "warning: IP_RECVDSTADDR not supported by host\n");
+#endif
+    }
+
+    if (sigio) {
+#ifdef FIOASYNC
+               static void sigio_func(int);
+
+               /*
+                * Should be able to set this with fcntl(O_ASYNC) or fcntl(FASYNC),
+                * but some systems (AIX?) only do it with ioctl().
+                *
+                * Need to set this for listening socket and for connected socket.
+                */
+               signal(SIGIO, sigio_func);
+
+               if (fcntl(sockfd, F_SETOWN, getpid()) < 0)
+                       err_sys("fcntl F_SETOWN error");
+
+        option = 1;
+               if (ioctl(sockfd, FIOASYNC, (char *) &option) < 0)
+                       err_sys("ioctl FIOASYNC error");
+
+               if (verbose)
+                       fprintf(stderr, "FIOASYNC set\n");
+#else
+               fprintf(stderr, "warning: FIOASYNC not supported by host\n");
+#endif
+    }
+}
+
+static void
+sigio_func(int signo)
+{
+       fprintf(stderr, "SIGIO\n");
+                               /* shouldn't printf from a signal handler ... */
+}
diff --git a/sock/sourceroute.c b/sock/sourceroute.c
new file mode 100644 (file)
index 0000000..acb393c
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+#include       <netinet/in_systm.h>
+#include       <netinet/ip.h>
+
+/*
+ * There is a fundamental limit of 9 IP addresses in a source route.
+ * But we allocate sroute_opt[44] with room for 10 IP addresses (and
+ * the 3-byte source route type/len/offset) because with the BSD
+ * IP_OPTIONS socket option we can specify up to 9 addresses, followed
+ * by the destination address.  The in_pcbopts() function in the kernel
+ * then takes the final address in the list (the destination) and moves
+ * it to the front, as shown in Figure 9.33 of "TCP/IP Illustrated,
+ * Volume 2".  Also note that this destination address that we pass as
+ * the final IP address in our array overrides the destination address
+ * of the sendto() (Figure 9.28 of Volume 2).
+ */
+
+u_char sroute_opt[44];         /* some implementations require this to be
+                                                          on a 4-byte boundary */
+u_char *optr;                          /* pointer into options being formed */
+
+/*
+ * Process either the -g (loose) or -G (strict) command-line option,
+ * specifying one hop in a source route.
+ * Either option can be specified up to 9 times.
+ * With IPv4 the entire source route is either loose or strict, but we
+ * set the source route type field based on the first option encountered,
+ * either -g or -G.
+ */
+
+void
+sroute_doopt(int strict, char *argptr)
+{
+       struct in_addr  inaddr;
+       struct hostent  *hp;
+
+       if (sroute_cnt >= 9)
+               err_quit("too many source routes with: %s", argptr);
+
+       if (sroute_cnt == 0) {  /* first one */
+               bzero(sroute_opt, sizeof(sroute_opt));
+               optr = sroute_opt;
+               *optr++ = strict ? IPOPT_SSRR : IPOPT_LSRR;
+               optr++;                 /* we fill in the total length later */
+               *optr++ = 4;    /* ptr to first source-route address */
+       }
+
+       if (inet_aton(argptr, &inaddr) == 1) {
+               memcpy(optr, &inaddr, sizeof(u_long));  /* dotted decimal */
+               if (verbose)
+                       fprintf(stderr, "source route to %s\n", inet_ntoa(inaddr));
+       } else if ( (hp = gethostbyname(argptr)) != NULL) {
+               memcpy(optr, hp->h_addr, sizeof(u_long));/* hostname */
+               if (verbose)
+                       fprintf(stderr, "source route to %s\n",
+                                                       inet_ntoa(*((struct in_addr *) hp->h_addr)));
+       } else
+               err_quit("unknown host: %s\n", argptr);
+
+       optr += sizeof(u_long);         /* for next IP addr in list */
+       sroute_cnt++;
+}
+
+/*
+ * Set the actual source route with the IP_OPTIONS socket option.
+ * This function is called if srouce_cnt is nonzero.
+ * The final destination goes at the end of the list of IP addresses.
+ */
+
+void
+sroute_set(int sockfd)
+{
+       sroute_cnt++;                                            /* account for destination */
+       sroute_opt[1] = 3 + (sroute_cnt * 4);/* total length, incl. destination */
+
+               /* destination must be stored as final entry */
+       memcpy(optr, &servaddr.sin_addr, sizeof(u_long));
+       optr += sizeof(u_long);
+       if (verbose) {
+               fprintf(stderr, "source route to %s\n", inet_ntoa(servaddr.sin_addr));
+               fprintf(stderr, "source route size %d bytes\n", sroute_opt[1]);
+       }
+
+       /*
+        * The number of bytes that we pass to setsockopt() must be a multiple
+        * of 4.  Since the buffer was initialized to 0, this leaves an EOL
+        * following the final IP address.
+        * For optimization we could put a NOP before the 3-byte type/len/offset
+        * field, which would then align all the IP addresses on 4-byte boundaries,
+        * but the source routing code is not exactly in the fast path of most
+        * routers.
+        */
+       while ((optr - sroute_opt) & 3)
+               optr++;
+
+       if (setsockopt(sockfd, IPPROTO_IP, IP_OPTIONS,
+                                  sroute_opt, optr - sroute_opt) < 0)
+               err_sys("setsockopt error for IP_OPTIONS");
+
+       sroute_cnt = 0;         /* don't call this function again */
+}
diff --git a/sock/sourcesink.c b/sock/sourcesink.c
new file mode 100644 (file)
index 0000000..0a00845
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+#include       <ctype.h>
+
+void   pattern(char *ptr, int len);
+
+void
+sink(int sockfd)
+{
+       int             i, n;
+       char    oob;
+
+       if (client) {
+               pattern(wbuf, writelen);        /* fill send buffer with a pattern */
+
+               if (pauseinit)
+                       sleep(pauseinit);
+
+               for (i = 1; i <= nbuf; i++) {
+                       if (urgwrite == i) {
+                               oob = urgwrite;
+                               if ( (n = send(sockfd, &oob, 1, MSG_OOB)) != 1)
+                                       err_sys("send of MSG_OOB returned %d, expected %d",
+                                                                                                                               n, writelen);
+                               if (verbose)
+                                       fprintf(stderr, "wrote %d byte of urgent data\n", n);
+                       }
+
+                       if ( (n = write(sockfd, wbuf, writelen)) != writelen)
+                               err_sys("write returned %d, expected %d", n, writelen);
+                       if (verbose)
+                               fprintf(stderr, "wrote %d bytes\n", n);
+
+                       if (pauserw)
+                               sleep(pauserw);
+               }
+
+       } else {
+
+               if (pauseinit)
+                       sleep(pauseinit);
+
+               for ( ; ; ) {
+                       if ( (n = read(sockfd, rbuf, readlen)) < 0) {
+                               err_sys("read error");
+
+                       } else if (n == 0) {
+                               break;          /* connection closed by peer */
+
+                       } else if (n != readlen)
+                               err_quit("read returned %d, expected %d", n, readlen);
+       
+                       if (verbose)
+                               fprintf(stderr, "received %d bytes\n", n);
+
+                       if (pauserw)
+                               sleep(pauserw);
+               }
+       }
+
+       if (pauseclose) {
+               if (verbose)
+                               fprintf(stderr, "pausing before close\n");
+               sleep(pauseclose);
+       }
+
+       if (close(sockfd) < 0)
+               err_sys("close error");         /* since SO_LINGER may be set */
+}
+
+void
+pattern(char *ptr, int len)
+{
+       char    c;
+
+       c = 0;
+       while(len-- > 0)  {
+               while(isprint((c & 0x7F)) == 0)
+                       c++;    /* skip over nonprinting characters */
+               *ptr++ = (c++ & 0x7F);
+       }
+}
diff --git a/sock/sourcetcp.c b/sock/sourcetcp.c
new file mode 100644 (file)
index 0000000..a399594
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+
+void
+source_tcp(int sockfd)
+{
+       int                     i, n, option;
+       socklen_t       optlen;
+       char            oob;
+
+       pattern(wbuf, writelen);        /* fill send buffer with a pattern */
+
+       if (pauseinit)
+               sleep_us(pauseinit*1000);
+
+       for (i = 1; i <= nbuf; i++) {
+               if (urgwrite == i) {
+                       oob = urgwrite;
+                       if ( (n = send(sockfd, &oob, 1, MSG_OOB)) != 1)
+                               err_sys("send of MSG_OOB returned %d, expected %d",
+                                                                                                                       n, writelen);
+                       if (verbose)
+                               fprintf(stderr, "wrote %d byte of urgent data\n", n);
+               }
+
+               if ( (n = write(sockfd, wbuf, writelen)) != writelen) {
+                       if (ignorewerr) {
+                               err_ret("write returned %d, expected %d", n, writelen);
+                                               /* also call getsockopt() to clear so_error */
+                               optlen = sizeof(option);
+                               if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
+                                                                                               &option, &optlen) < 0)
+                               err_sys("SO_ERROR getsockopt error");
+                       } else
+                               err_sys("write returned %d, expected %d", n, writelen);
+
+               } else if (verbose)
+                       fprintf(stderr, "wrote %d bytes\n", n);
+
+               if (pauserw)
+                       sleep_us(pauserw*1000);
+       }
+
+       if (pauseclose) {
+               if (verbose)
+                               fprintf(stderr, "pausing before close\n");
+               sleep_us(pauseclose*1000);
+       }
+
+       if (close(sockfd) < 0)
+               err_sys("close error");         /* since SO_LINGER may be set */
+}
diff --git a/sock/sourceudp.c b/sock/sourceudp.c
new file mode 100644 (file)
index 0000000..b305ca1
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+
+void
+source_udp(int sockfd) /* TODO: use sendto ?? */
+{
+       int                     i, n, option;
+       socklen_t       optlen;
+
+       pattern(wbuf, writelen);        /* fill send buffer with a pattern */
+
+       if (pauseinit)
+               sleep_us(pauseinit*1000);
+
+       for (i = 1; i <= nbuf; i++) {
+               if (connectudp) {
+                       if ( (n = write(sockfd, wbuf, writelen)) != writelen) {
+                               if (ignorewerr) {
+                                       err_ret("write returned %d, expected %d", n, writelen);
+                                               /* also call getsockopt() to clear so_error */
+                                       optlen = sizeof(option);
+                                       if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
+                                                                                               &option, &optlen) < 0)
+                                       err_sys("SO_ERROR getsockopt error");
+                               } else
+                                       err_sys("write returned %d, expected %d", n, writelen);
+                       }
+               } else {
+                       if ( (n = sendto(sockfd, wbuf, writelen, 0,
+                                                    (struct sockaddr *) &servaddr,
+                                                        sizeof(servaddr))) != writelen) {
+                               if (ignorewerr) {
+                                       err_ret("sendto returned %d, expected %d", n, writelen);
+                                               /* also call getsockopt() to clear so_error */
+                                       optlen = sizeof(option);
+                                       if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
+                                                                                               &option, &optlen) < 0)
+                                       err_sys("SO_ERROR getsockopt error");
+                               } else
+                                       err_sys("sendto returned %d, expected %d", n, writelen);
+                       }
+               }
+
+               if (verbose)
+                       fprintf(stderr, "wrote %d bytes\n", n);
+
+               if (pauserw)
+                       sleep_us(pauserw*1000);
+       }
+
+       if (pauseclose) {
+               if (verbose)
+                               fprintf(stderr, "pausing before close\n");
+               sleep_us(pauseclose*1000);
+       }
+
+       if (close(sockfd) < 0)
+               err_sys("close error");         /* since SO_LINGER may be set */
+}
diff --git a/sock/strerror.c b/sock/strerror.c
new file mode 100644 (file)
index 0000000..1c11d9e
--- /dev/null
@@ -0,0 +1,16 @@
+#include       <stdio.h>
+
+extern const char      *const sys_errlist[];
+extern int             sys_nerr;
+
+char *
+strerror(int error)
+{
+       static char     mesg[30];
+
+       if (error >= 0 && error <= sys_nerr)
+               return(sys_errlist[error]);
+
+       snprintf(mesg, sizeof(mesg), "Unknown error (%d)", error);
+       return(mesg);
+}
diff --git a/sock/tellwait.c b/sock/tellwait.c
new file mode 100644 (file)
index 0000000..53f4e9b
--- /dev/null
@@ -0,0 +1,67 @@
+#include       <signal.h>
+#include       "ourhdr.h"
+
+static volatile sig_atomic_t   sigflag;
+                                                               /* set nonzero by signal handler */
+static sigset_t                        newmask, oldmask, zeromask;
+
+static void
+sig_usr(int signo)     /* one signal handler for SIGUSR1 and SIGUSR2 */
+{
+       sigflag = 1;
+       return;
+}
+
+void
+TELL_WAIT()
+{
+       if (signal(SIGUSR1, sig_usr) == SIG_ERR)
+               err_sys("signal(SIGINT) error");
+       if (signal(SIGUSR2, sig_usr) == SIG_ERR)
+               err_sys("signal(SIGQUIT) error");
+
+       sigemptyset(&zeromask);
+
+       sigemptyset(&newmask);
+       sigaddset(&newmask, SIGUSR1);
+       sigaddset(&newmask, SIGUSR2);
+               /* block SIGUSR1 and SIGUSR2, and save current signal mask */
+       if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
+               err_sys("SIG_BLOCK error");
+}
+
+void
+TELL_PARENT(pid_t pid)
+{
+       kill(pid, SIGUSR2);             /* tell parent we're done */
+}
+
+void
+WAIT_PARENT(void)
+{
+       while (sigflag == 0)
+               sigsuspend(&zeromask);  /* and wait for parent */
+
+       sigflag = 0;
+                       /* reset signal mask to original value */
+       if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
+               err_sys("SIG_SETMASK error");
+}
+
+void
+TELL_CHILD(pid_t pid)
+{
+       kill(pid, SIGUSR1);                     /* tell child we're done */
+}
+
+void
+WAIT_CHILD(void)
+{
+       while (sigflag == 0)
+               sigsuspend(&zeromask);  /* and wait for child */
+
+       sigflag = 0;
+                       /* reset signal mask to original value */
+       if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
+               err_sys("SIG_SETMASK error");
+}
diff --git a/sock/write.c b/sock/write.c
new file mode 100644 (file)
index 0000000..205524d
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1993 W. Richard Stevens.  All rights reserved.
+ * Permission to use or modify this software and its documentation only for
+ * educational purposes and without fee is hereby granted, provided that
+ * the above copyright notice appear in all copies.  The author makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#include       "sock.h"
+#include       <sys/uio.h>             /* for writev() */
+
+#ifndef        UIO_MAXIOV
+#define        UIO_MAXIOV      16      /* we assume this; may not be true? */
+#endif
+
+ssize_t
+dowrite(int fd, const void *vptr, size_t nbytes)
+{
+       struct iovec    iov[UIO_MAXIOV];
+       const char              *ptr;
+       int                             chunksize, i, n, nleft, nwritten, ntotal;
+
+       if (chunkwrite == 0 && usewritev == 0)
+               return(write(fd, vptr, nbytes));                /* common case */
+
+       /*
+        * Figure out what sized chunks to write.
+        * Try to use UIO_MAXIOV chunks.
+        */
+
+       chunksize = nbytes / UIO_MAXIOV;
+       if (chunksize <= 0)
+               chunksize = 1;
+       else if ((nbytes % UIO_MAXIOV) != 0)
+               chunksize++;
+
+       ptr = vptr;
+       nleft = nbytes;
+       for (i = 0; i < UIO_MAXIOV; i++) {
+               iov[i].iov_base = ptr;
+               n = (nleft >= chunksize) ? chunksize : nleft;
+               iov[i].iov_len = n;
+               if (verbose)
+                       fprintf(stderr, "iov[%2d].iov_base = %x, iov[%2d].iov_len = %d\n",
+                                               i, iov[i].iov_base, i, iov[i].iov_len);
+               ptr += n;
+               if ((nleft -= n) == 0)
+                       break;
+       }
+       if (i == UIO_MAXIOV)
+               err_quit("i == UIO_MAXIOV");
+
+       if (usewritev)
+               return(writev(fd, iov, i+1));
+       else {
+               ntotal = 0;
+               for (n = 0; n <= i; n++) {
+                       nwritten = write(fd, iov[n].iov_base, iov[n].iov_len);
+                       if (nwritten != iov[n].iov_len)
+                               return(-1);
+                       ntotal += nwritten;
+               }
+               return(ntotal);
+       }
+}
diff --git a/sock/writen.c b/sock/writen.c
new file mode 100644 (file)
index 0000000..bd47da2
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "ourhdr.h"
+
+ssize_t                                                /* Write "n" bytes to a descriptor. */
+writen(int fd, const void *vptr, size_t n)
+{
+       size_t          nleft, nwritten;
+       const char      *ptr;
+
+       ptr = vptr;     /* can't do pointer arithmetic on void* */
+       nleft = n;
+       while (nleft > 0) {
+               if ( (nwritten = write(fd, ptr, nleft)) <= 0)
+                       return(nwritten);               /* error */
+
+               nleft -= nwritten;
+               ptr   += nwritten;
+       }
+       return(n);
+}
diff --git a/sockopt/Makefile b/sockopt/Makefile
new file mode 100644 (file)
index 0000000..a014f97
--- /dev/null
@@ -0,0 +1,23 @@
+include ../Make.defines
+
+PROGS =        checkopts prdefaults rcvbuf rcvbufset sockopt
+
+all:   ${PROGS}
+
+sockopt:       sockopt.o
+               ${CC} ${CFLAGS} -o $@ sockopt.o ${LIBS}
+
+checkopts:     checkopts.o
+               ${CC} ${CFLAGS} -o $@ checkopts.o ${LIBS}
+
+prdefaults:    prdefaults.o
+               ${CC} ${CFLAGS} -o $@ prdefaults.o ${LIBS}
+
+rcvbuf:        rcvbuf.o
+               ${CC} ${CFLAGS} -o $@ rcvbuf.o ${LIBS}
+
+rcvbufset:     rcvbufset.o
+               ${CC} ${CFLAGS} -o $@ rcvbufset.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/sockopt/checkopts.c b/sockopt/checkopts.c
new file mode 100644 (file)
index 0000000..3aa8199
--- /dev/null
@@ -0,0 +1,189 @@
+/* include checkopts1 */
+/* *INDENT-OFF* */
+#include       "unp.h"
+#include       <netinet/tcp.h>         /* for TCP_xxx defines */
+
+union val {
+  int                          i_val;
+  long                         l_val;
+  struct linger                linger_val;
+  struct timeval       timeval_val;
+} val;
+
+static char    *sock_str_flag(union val *, int);
+static char    *sock_str_int(union val *, int);
+static char    *sock_str_linger(union val *, int);
+static char    *sock_str_timeval(union val *, int);
+
+struct sock_opts {
+  const char      *opt_str;
+  int          opt_level;
+  int          opt_name;
+  char   *(*opt_val_str)(union val *, int);
+} sock_opts[] = {
+       { "SO_BROADCAST",               SOL_SOCKET,     SO_BROADCAST,   sock_str_flag },
+       { "SO_DEBUG",                   SOL_SOCKET,     SO_DEBUG,               sock_str_flag },
+       { "SO_DONTROUTE",               SOL_SOCKET,     SO_DONTROUTE,   sock_str_flag },
+       { "SO_ERROR",                   SOL_SOCKET,     SO_ERROR,               sock_str_int },
+       { "SO_KEEPALIVE",               SOL_SOCKET,     SO_KEEPALIVE,   sock_str_flag },
+       { "SO_LINGER",                  SOL_SOCKET,     SO_LINGER,              sock_str_linger },
+       { "SO_OOBINLINE",               SOL_SOCKET,     SO_OOBINLINE,   sock_str_flag },
+       { "SO_RCVBUF",                  SOL_SOCKET,     SO_RCVBUF,              sock_str_int },
+       { "SO_SNDBUF",                  SOL_SOCKET,     SO_SNDBUF,              sock_str_int },
+       { "SO_RCVLOWAT",                SOL_SOCKET,     SO_RCVLOWAT,    sock_str_int },
+       { "SO_SNDLOWAT",                SOL_SOCKET,     SO_SNDLOWAT,    sock_str_int },
+       { "SO_RCVTIMEO",                SOL_SOCKET,     SO_RCVTIMEO,    sock_str_timeval },
+       { "SO_SNDTIMEO",                SOL_SOCKET,     SO_SNDTIMEO,    sock_str_timeval },
+       { "SO_REUSEADDR",               SOL_SOCKET,     SO_REUSEADDR,   sock_str_flag },
+#ifdef SO_REUSEPORT
+       { "SO_REUSEPORT",               SOL_SOCKET,     SO_REUSEPORT,   sock_str_flag },
+#else
+       { "SO_REUSEPORT",               0,                      0,                              NULL },
+#endif
+       { "SO_TYPE",                    SOL_SOCKET,     SO_TYPE,                sock_str_int },
+       { "SO_USELOOPBACK",             SOL_SOCKET,     SO_USELOOPBACK, sock_str_flag },
+       { "IP_TOS",                             IPPROTO_IP,     IP_TOS,                 sock_str_int },
+       { "IP_TTL",                             IPPROTO_IP,     IP_TTL,                 sock_str_int },
+#ifdef IPV6_DONTFRAG
+       { "IPV6_DONTFRAG",              IPPROTO_IPV6,IPV6_DONTFRAG,     sock_str_flag },
+#else
+       { "IPV6_DONTFRAG",              0,                      0,                              NULL },
+#endif
+#ifdef IPV6_UNICAST_HOPS
+       { "IPV6_UNICAST_HOPS",  IPPROTO_IPV6,IPV6_UNICAST_HOPS,sock_str_int },
+#else
+       { "IPV6_UNICAST_HOPS",  0,                      0,                              NULL },
+#endif
+#ifdef IPV6_V6ONLY
+       { "IPV6_V6ONLY",                IPPROTO_IPV6,IPV6_V6ONLY,       sock_str_flag },
+#else
+       { "IPV6_V6ONLY",                0,                      0,                              NULL },
+#endif
+       { "TCP_MAXSEG",                 IPPROTO_TCP,TCP_MAXSEG,         sock_str_int },
+       { "TCP_NODELAY",                IPPROTO_TCP,TCP_NODELAY,        sock_str_flag },
+#ifdef SCTP_AUTOCLOSE
+       { "SCTP_AUTOCLOSE",             IPPROTO_SCTP,SCTP_AUTOCLOSE,sock_str_int },
+#else
+       { "SCTP_AUTOCLOSE",             0,                      0,                              NULL },
+#endif
+#ifdef SCTP_MAXBURST
+       { "SCTP_MAXBURST",              IPPROTO_SCTP,SCTP_MAXBURST,     sock_str_int },
+#else
+       { "SCTP_MAXBURST",              0,                      0,                              NULL },
+#endif
+#ifdef SCTP_MAXSEG
+       { "SCTP_MAXSEG",                IPPROTO_SCTP,SCTP_MAXSEG,       sock_str_int },
+#else
+       { "SCTP_MAXSEG",                0,                      0,                              NULL },
+#endif
+#ifdef SCTP_NODELAY
+       { "SCTP_NODELAY",               IPPROTO_SCTP,SCTP_NODELAY,      sock_str_flag },
+#else
+       { "SCTP_NODELAY",               0,                      0,                              NULL },
+#endif
+       { NULL,                                 0,                      0,                              NULL }
+};
+/* *INDENT-ON* */
+/* end checkopts1 */
+
+/* include checkopts2 */
+int
+main(int argc, char **argv)
+{
+       int                                     fd;
+       socklen_t                       len;
+       struct sock_opts        *ptr;
+
+       for (ptr = sock_opts; ptr->opt_str != NULL; ptr++) {
+               printf("%s: ", ptr->opt_str);
+               if (ptr->opt_val_str == NULL)
+                       printf("(undefined)\n");
+               else {
+                       switch(ptr->opt_level) {
+                       case SOL_SOCKET:
+                       case IPPROTO_IP:
+                       case IPPROTO_TCP:
+                               fd = Socket(AF_INET, SOCK_STREAM, 0);
+                               break;
+#ifdef IPV6
+                       case IPPROTO_IPV6:
+                               fd = Socket(AF_INET6, SOCK_STREAM, 0);
+                               break;
+#endif
+#ifdef IPPROTO_SCTP
+                       case IPPROTO_SCTP:
+                               fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
+                               break;
+#endif
+                       default:
+                               err_quit("Can't create fd for level %d\n", ptr->opt_level);
+                       }
+
+                       len = sizeof(val);
+                       if (getsockopt(fd, ptr->opt_level, ptr->opt_name,
+                                                  &val, &len) == -1) {
+                               err_ret("getsockopt error");
+                       } else {
+                               printf("default = %s\n", (*ptr->opt_val_str)(&val, len));
+                       }
+                       close(fd);
+               }
+       }
+       exit(0);
+}
+/* end checkopts2 */
+
+/* include checkopts3 */
+static char    strres[128];
+
+static char    *
+sock_str_flag(union val *ptr, int len)
+{
+/* *INDENT-OFF* */
+       if (len != sizeof(int))
+               snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);
+       else
+               snprintf(strres, sizeof(strres),
+                                "%s", (ptr->i_val == 0) ? "off" : "on");
+       return(strres);
+/* *INDENT-ON* */
+}
+/* end checkopts3 */
+
+static char    *
+sock_str_int(union val *ptr, int len)
+{
+       if (len != sizeof(int))
+               snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);
+       else
+               snprintf(strres, sizeof(strres), "%d", ptr->i_val);
+       return(strres);
+}
+
+static char    *
+sock_str_linger(union val *ptr, int len)
+{
+       struct linger   *lptr = &ptr->linger_val;
+
+       if (len != sizeof(struct linger))
+               snprintf(strres, sizeof(strres),
+                                "size (%d) not sizeof(struct linger)", len);
+       else
+               snprintf(strres, sizeof(strres), "l_onoff = %d, l_linger = %d",
+                                lptr->l_onoff, lptr->l_linger);
+       return(strres);
+}
+
+static char    *
+sock_str_timeval(union val *ptr, int len)
+{
+       struct timeval  *tvptr = &ptr->timeval_val;
+
+       if (len != sizeof(struct timeval))
+               snprintf(strres, sizeof(strres),
+                                "size (%d) not sizeof(struct timeval)", len);
+       else
+               snprintf(strres, sizeof(strres), "%d sec, %d usec",
+                                tvptr->tv_sec, tvptr->tv_usec);
+       return(strres);
+}
diff --git a/sockopt/checkopts.lc b/sockopt/checkopts.lc
new file mode 100644 (file)
index 0000000..5cb5dbb
--- /dev/null
@@ -0,0 +1,131 @@
+/* include checkopts1 */
+#include    "unp.h"##  1 ##src/sockopt/checkopts.c##
+#include    <netinet/tcp.h>     /* for TCP_xxx defines */##  2 ##src/sockopt/checkopts.c##
+
+union val {##  3 ##src/sockopt/checkopts.c##
+  int               i_val;##  4 ##src/sockopt/checkopts.c##
+  long              l_val;##  5 ##src/sockopt/checkopts.c##
+  char              c_val[10];##  6 ##src/sockopt/checkopts.c##
+  struct linger     linger_val;##  7 ##src/sockopt/checkopts.c##
+  struct timeval    timeval_val;##  8 ##src/sockopt/checkopts.c##
+} val;##  9 ##src/sockopt/checkopts.c##
+
+static char *sock_str_flag(union val *, int);## 10 ##src/sockopt/checkopts.c##
+static char *sock_str_int(union val *, int);## 11 ##src/sockopt/checkopts.c##
+static char *sock_str_linger(union val *, int);## 12 ##src/sockopt/checkopts.c##
+static char *sock_str_timeval(union val *, int);## 13 ##src/sockopt/checkopts.c##
+
+struct sock_opts {## 14 ##src/sockopt/checkopts.c##
+  char     *opt_str;## 15 ##src/sockopt/checkopts.c##
+  int       opt_level;## 16 ##src/sockopt/checkopts.c##
+  int       opt_name;## 17 ##src/sockopt/checkopts.c##
+  char   *(*opt_val_str)(union val *, int);## 18 ##src/sockopt/checkopts.c##
+} sock_opts[] = {## 19 ##src/sockopt/checkopts.c##
+    "SO_BROADCAST",     SOL_SOCKET, SO_BROADCAST,   sock_str_flag,## 20 ##src/sockopt/checkopts.c##
+    "SO_DEBUG",         SOL_SOCKET, SO_DEBUG,       sock_str_flag,## 21 ##src/sockopt/checkopts.c##
+    "SO_DONTROUTE",     SOL_SOCKET, SO_DONTROUTE,   sock_str_flag,## 22 ##src/sockopt/checkopts.c##
+    "SO_ERROR",         SOL_SOCKET, SO_ERROR,       sock_str_int,## 23 ##src/sockopt/checkopts.c##
+    "SO_KEEPALIVE",     SOL_SOCKET, SO_KEEPALIVE,   sock_str_flag,## 24 ##src/sockopt/checkopts.c##
+    "SO_LINGER",        SOL_SOCKET, SO_LINGER,      sock_str_linger,## 25 ##src/sockopt/checkopts.c##
+    "SO_OOBINLINE",     SOL_SOCKET, SO_OOBINLINE,   sock_str_flag,## 26 ##src/sockopt/checkopts.c##
+    "SO_RCVBUF",        SOL_SOCKET, SO_RCVBUF,      sock_str_int,## 27 ##src/sockopt/checkopts.c##
+    "SO_SNDBUF",        SOL_SOCKET, SO_SNDBUF,      sock_str_int,## 28 ##src/sockopt/checkopts.c##
+    "SO_RCVLOWAT",      SOL_SOCKET, SO_RCVLOWAT,    sock_str_int,## 29 ##src/sockopt/checkopts.c##
+    "SO_SNDLOWAT",      SOL_SOCKET, SO_SNDLOWAT,    sock_str_int,## 30 ##src/sockopt/checkopts.c##
+    "SO_RCVTIMEO",      SOL_SOCKET, SO_RCVTIMEO,    sock_str_timeval,## 31 ##src/sockopt/checkopts.c##
+    "SO_SNDTIMEO",      SOL_SOCKET, SO_SNDTIMEO,    sock_str_timeval,## 32 ##src/sockopt/checkopts.c##
+    "SO_REUSEADDR",     SOL_SOCKET, SO_REUSEADDR,   sock_str_flag,## 33 ##src/sockopt/checkopts.c##
+#ifdef  SO_REUSEPORT## 34 ##src/sockopt/checkopts.c##
+    "SO_REUSEPORT",     SOL_SOCKET, SO_REUSEPORT,   sock_str_flag,## 35 ##src/sockopt/checkopts.c##
+#else## 36 ##src/sockopt/checkopts.c##
+    "SO_REUSEPORT",     0,          0,              NULL,## 37 ##src/sockopt/checkopts.c##
+#endif## 38 ##src/sockopt/checkopts.c##
+    "SO_TYPE",          SOL_SOCKET, SO_TYPE,        sock_str_int,## 39 ##src/sockopt/checkopts.c##
+    "SO_USELOOPBACK",   SOL_SOCKET, SO_USELOOPBACK, sock_str_flag,## 40 ##src/sockopt/checkopts.c##
+    "IP_TOS",           IPPROTO_IP, IP_TOS,         sock_str_int,## 41 ##src/sockopt/checkopts.c##
+    "IP_TTL",           IPPROTO_IP, IP_TTL,         sock_str_int,## 42 ##src/sockopt/checkopts.c##
+    "TCP_MAXSEG",       IPPROTO_TCP,TCP_MAXSEG,     sock_str_int,## 43 ##src/sockopt/checkopts.c##
+    "TCP_NODELAY",      IPPROTO_TCP,TCP_NODELAY,    sock_str_flag,## 44 ##src/sockopt/checkopts.c##
+    NULL,               0,          0,              NULL## 45 ##src/sockopt/checkopts.c##
+};## 46 ##src/sockopt/checkopts.c##
+/* end checkopts1 */
+
+/* include checkopts2 */
+int## 47 ##src/sockopt/checkopts.c##
+main(int argc, char **argv)## 48 ##src/sockopt/checkopts.c##
+{## 49 ##src/sockopt/checkopts.c##
+    int     fd, len;## 50 ##src/sockopt/checkopts.c##
+    struct sock_opts *ptr;## 51 ##src/sockopt/checkopts.c##
+
+    fd = Socket(AF_INET, SOCK_STREAM, 0);## 52 ##src/sockopt/checkopts.c##
+
+    for (ptr = sock_opts; ptr->opt_str != NULL; ptr++) {## 53 ##src/sockopt/checkopts.c##
+        printf("%s: ", ptr->opt_str);## 54 ##src/sockopt/checkopts.c##
+        if (ptr->opt_val_str == NULL)## 55 ##src/sockopt/checkopts.c##
+            printf("(undefined)\n");## 56 ##src/sockopt/checkopts.c##
+        else {## 57 ##src/sockopt/checkopts.c##
+            len = sizeof(val);## 58 ##src/sockopt/checkopts.c##
+            if (getsockopt(fd, ptr->opt_level, ptr->opt_name,## 59 ##src/sockopt/checkopts.c##
+                           &val, &len) == -1) {## 60 ##src/sockopt/checkopts.c##
+                err_ret("getsockopt error");## 61 ##src/sockopt/checkopts.c##
+            } else {## 62 ##src/sockopt/checkopts.c##
+                printf("default = %s\n", (*ptr->opt_val_str) (&val, len));## 63 ##src/sockopt/checkopts.c##
+            }## 64 ##src/sockopt/checkopts.c##
+        }## 65 ##src/sockopt/checkopts.c##
+    }## 66 ##src/sockopt/checkopts.c##
+    exit(0);## 67 ##src/sockopt/checkopts.c##
+}## 68 ##src/sockopt/checkopts.c##
+/* end checkopts2 */
+
+/* include checkopts3 */
+static char strres[128];## 69 ##src/sockopt/checkopts.c##
+
+static char *## 70 ##src/sockopt/checkopts.c##
+sock_str_flag(union val *ptr, int len)## 71 ##src/sockopt/checkopts.c##
+{## 72 ##src/sockopt/checkopts.c##
+    if (len != sizeof(int))## 73 ##src/sockopt/checkopts.c##
+        snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);## 74 ##src/sockopt/checkopts.c##
+    else## 75 ##src/sockopt/checkopts.c##
+        snprintf(strres, sizeof(strres),## 76 ##src/sockopt/checkopts.c##
+                 "%s", (ptr->i_val == 0) ? "off" : "on");## 77 ##src/sockopt/checkopts.c##
+    return(strres);## 78 ##src/sockopt/checkopts.c##
+}## 79 ##src/sockopt/checkopts.c##
+/* end checkopts3 */
+
+static char *## 80 ##src/sockopt/checkopts.c##
+sock_str_int(union val *ptr, int len)## 81 ##src/sockopt/checkopts.c##
+{## 82 ##src/sockopt/checkopts.c##
+    if (len != sizeof(int))## 83 ##src/sockopt/checkopts.c##
+        snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len);## 84 ##src/sockopt/checkopts.c##
+    else## 85 ##src/sockopt/checkopts.c##
+        snprintf(strres, sizeof(strres), "%d", ptr->i_val);## 86 ##src/sockopt/checkopts.c##
+    return (strres);## 87 ##src/sockopt/checkopts.c##
+}## 88 ##src/sockopt/checkopts.c##
+
+static char *## 89 ##src/sockopt/checkopts.c##
+sock_str_linger(union val *ptr, int len)## 90 ##src/sockopt/checkopts.c##
+{## 91 ##src/sockopt/checkopts.c##
+    struct linger *lptr = &ptr->linger_val;## 92 ##src/sockopt/checkopts.c##
+
+    if (len != sizeof(struct linger))## 93 ##src/sockopt/checkopts.c##
+        snprintf(strres, sizeof(strres),## 94 ##src/sockopt/checkopts.c##
+                 "size (%d) not sizeof(struct linger)", len);## 95 ##src/sockopt/checkopts.c##
+    else## 96 ##src/sockopt/checkopts.c##
+        snprintf(strres, sizeof(strres), "l_onoff = %d, l_linger = %d",## 97 ##src/sockopt/checkopts.c##
+                 lptr->l_onoff, lptr->l_linger);## 98 ##src/sockopt/checkopts.c##
+    return (strres);## 99 ##src/sockopt/checkopts.c##
+}##100 ##src/sockopt/checkopts.c##
+
+static char *##101 ##src/sockopt/checkopts.c##
+sock_str_timeval(union val *ptr, int len)##102 ##src/sockopt/checkopts.c##
+{##103 ##src/sockopt/checkopts.c##
+    struct timeval *tvptr = &ptr->timeval_val;##104 ##src/sockopt/checkopts.c##
+
+    if (len != sizeof(struct timeval))##105 ##src/sockopt/checkopts.c##
+        snprintf(strres, sizeof(strres),##106 ##src/sockopt/checkopts.c##
+                 "size (%d) not sizeof(struct timeval)", len);##107 ##src/sockopt/checkopts.c##
+    else##108 ##src/sockopt/checkopts.c##
+        snprintf(strres, sizeof(strres), "%d sec, %d usec",##109 ##src/sockopt/checkopts.c##
+                 tvptr->tv_sec, tvptr->tv_usec);##110 ##src/sockopt/checkopts.c##
+    return (strres);##111 ##src/sockopt/checkopts.c##
+}##112 ##src/sockopt/checkopts.c##
diff --git a/sockopt/prdefaults.c b/sockopt/prdefaults.c
new file mode 100644 (file)
index 0000000..46d7369
--- /dev/null
@@ -0,0 +1,59 @@
+#include       "unp.h"
+
+static doit(int, const char *);
+
+void
+main()
+{
+       int             tcpsock, udpsock;
+       struct sockaddr_in      servaddr;
+
+       if ( (tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+               err_sys("TCP socket error");
+
+#ifdef notdef
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_port        = htons(9);
+       if (ascii2addr(AF_INET, "127.0.0.1", &servaddr.sin_addr) != 4)
+               err_quit("ascii2addr error");
+
+       if (connect(tcpsock, (SA *) &servaddr, sizeof(servaddr)) < 0)
+               err_sys("connect error");
+#endif
+
+       doit(tcpsock, "tcp");
+
+       if ( (udpsock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+               err_sys("UDP socket error");
+
+       doit(udpsock, "udp");
+       exit(0);
+}
+
+static
+doit(int fd, const char *name)
+{
+       int                     val;
+       socklen_t       optlen;
+
+       optlen = sizeof(val);
+       if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &optlen) < 0)
+               err_sys("SO_SNDBUF getsockopt error");
+       printf("%s send buffer size = %d\n", name, val);
+
+       optlen = sizeof(val);
+       if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, &optlen) < 0)
+               err_sys("SO_RCVBUF getsockopt error");
+       printf("%s recv buffer size = %d\n", name, val);
+
+       optlen = sizeof(val);
+       if (getsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &val, &optlen) < 0)
+               err_sys("SO_SNDLOWAT getsockopt error");
+       printf("%s send low-water mark = %d\n", name, val);
+
+       optlen = sizeof(val);
+       if (getsockopt(fd, SOL_SOCKET, SO_RCVLOWAT, &val, &optlen) < 0)
+               err_sys("SO_RCVLOWAT getsockopt error");
+       printf("%s receive low-water mark size = %d\n", name, val);
+}
diff --git a/sockopt/rcvbuf.c b/sockopt/rcvbuf.c
new file mode 100644 (file)
index 0000000..af83f30
--- /dev/null
@@ -0,0 +1,36 @@
+#include       "unp.h"
+#include       <netinet/tcp.h>         /* for TCP_MAXSEG */
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, rcvbuf, mss;
+       socklen_t                       len;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: rcvbuf <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       len = sizeof(rcvbuf);
+       Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len);
+       len = sizeof(mss);
+       Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len);
+       printf("defaults: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(13);          /* daytime server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       len = sizeof(rcvbuf);
+       Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len);
+       len = sizeof(mss);
+       Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len);
+       printf("after connect: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss);
+
+       exit(0);
+}
diff --git a/sockopt/rcvbufset.c b/sockopt/rcvbufset.c
new file mode 100644 (file)
index 0000000..8eab891
--- /dev/null
@@ -0,0 +1,43 @@
+#include       "unp.h"
+#include       <netinet/tcp.h>         /* for TCP_MAXSEG */
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd, rcvbuf, mss;
+       socklen_t                       len;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: rcvbufset <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       len = sizeof(rcvbuf);
+       Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len);
+       len = sizeof(mss);
+       Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len);
+       printf("defaults: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss);
+
+       rcvbuf = 9973;          /* a prime number */
+       Setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
+       len = sizeof(rcvbuf);
+       Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len);
+       printf("SO_RCVBUF = %d (after setting it to 9973)\n", rcvbuf);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(13);          /* daytime server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       len = sizeof(rcvbuf);
+       Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len);
+       len = sizeof(mss);
+       Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len);
+       printf("after connect: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss);
+
+
+        exit(0);
+}
diff --git a/sockopt/sockopt.c b/sockopt/sockopt.c
new file mode 100644 (file)
index 0000000..7b0c940
--- /dev/null
@@ -0,0 +1,25 @@
+#include       "unp.h"
+#include       <netinet/tcp.h>         /* for TCP_MAXSEG value */
+
+int
+main(int argc, char **argv)
+{
+       int                     sockfd, mss, sendbuff;
+       socklen_t       optlen;
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+               /* Fetch and print the TCP maximum segment size.  */
+       optlen = sizeof(mss);
+       Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &optlen);
+       printf("TCP mss = %d\n", mss);
+
+               /* Set the send buffer size, then fetch it and print its value.  */
+       sendbuff = 65536;
+       Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff));
+
+       optlen = sizeof(sendbuff);
+       Getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);
+       printf("send buffer size = %d\n", sendbuff);
+       exit(0);
+}
diff --git a/sparc64-unknown-freebsd5.1/config.h b/sparc64-unknown-freebsd5.1/config.h
new file mode 100644 (file)
index 0000000..dac099b
--- /dev/null
@@ -0,0 +1,305 @@
+/* config.h.  Generated automatically by configure.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* CPU, vendor, and operating system */
+#define CPU_VENDOR_OS "sparc64-unknown-freebsd5.1"
+
+/* Define if <netdb.h> defines struct addrinfo */
+#define HAVE_ADDRINFO_STRUCT 1
+
+/* Define if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define if you have the `bzero' function. */
+#define HAVE_BZERO 1
+
+/* Define if the /dev/streams/xtiso/tcp device exists */
+/* #undef HAVE_DEV_STREAMS_XTISO_TCP */
+
+/* Define if the /dev/tcp device exists */
+/* #undef HAVE_DEV_TCP */
+
+/* Define if the /dev/xti/tcp device exists */
+/* #undef HAVE_DEV_XTI_TCP */
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the `getaddrinfo' function. */
+#define HAVE_GETADDRINFO 1
+
+/* define if getaddrinfo prototype is in <netdb.h> */
+#define HAVE_GETADDRINFO_PROTO 1
+
+/* Define if you have the `gethostbyname2' function. */
+#define HAVE_GETHOSTBYNAME2 1
+
+/* Define if you have the `gethostbyname_r' function. */
+/* #undef HAVE_GETHOSTBYNAME_R */
+
+/* Define if you have the `gethostname' function. */
+#define HAVE_GETHOSTNAME 1
+
+/* define if gethostname prototype is in <unistd.h> */
+#define HAVE_GETHOSTNAME_PROTO 1
+
+/* Define if you have the `getnameinfo' function. */
+#define HAVE_GETNAMEINFO 1
+
+/* define if getnameinfo prototype is in <netdb.h> */
+#define HAVE_GETNAMEINFO_PROTO 1
+
+/* define if getrusage prototype is in <sys/resource.h> */
+#define HAVE_GETRUSAGE_PROTO 1
+
+/* Define if you have the `hstrerror' function. */
+#define HAVE_HSTRERROR 1
+
+/* define if hstrerror prototype is in <netdb.h> */
+#define HAVE_HSTRERROR_PROTO 1
+
+/* Define if <net/if.h> defines struct if_nameindex */
+#define HAVE_IF_NAMEINDEX_STRUCT 1
+
+/* Define if you have the `if_nametoindex' function. */
+#define HAVE_IF_NAMETOINDEX 1
+
+/* define if if_nametoindex prototype is in <net/if.h> */
+#define HAVE_IF_NAMETOINDEX_PROTO 1
+
+/* Define if you have the `inet_aton' function. */
+#define HAVE_INET_ATON 1
+
+/* define if inet_aton prototype is in <arpa/inet.h> */
+#define HAVE_INET_ATON_PROTO 1
+
+/* Define if you have the `inet_pton' function. */
+#define HAVE_INET_PTON 1
+
+/* define if inet_pton prototype is in <arpa/inet.h> */
+#define HAVE_INET_PTON_PROTO 1
+
+/* Define if you have the `kevent' function. */
+#define HAVE_KEVENT 1
+
+/* Define if you have the `kqueue' function. */
+#define HAVE_KQUEUE 1
+
+/* Define if you have the `nsl' library (-lnsl). */
+/* #undef HAVE_LIBNSL */
+
+/* Define if you have the `pthread' library (-lpthread). */
+/* #undef HAVE_LIBPTHREAD */
+
+/* Define if you have the `pthreads' library (-lpthreads). */
+/* #undef HAVE_LIBPTHREADS */
+
+/* Define if you have the `resolv' library (-lresolv). */
+/* #undef HAVE_LIBRESOLV */
+
+/* Define if you have the `xti' library (-lxti). */
+/* #undef HAVE_LIBXTI */
+
+/* Define if you have the `mkstemp' function. */
+#define HAVE_MKSTEMP 1
+
+/* define if struct msghdr contains the msg_control element */
+#define HAVE_MSGHDR_MSG_CONTROL 1
+
+/* Define if you have the <netconfig.h> header file. */
+#define HAVE_NETCONFIG_H 1
+
+/* Define if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define if you have the <netdir.h> header file. */
+/* #undef HAVE_NETDIR_H */
+
+/* Define if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define if you have the <net/if_dl.h> header file. */
+#define HAVE_NET_IF_DL_H 1
+
+/* Define if you have the `poll' function. */
+#define HAVE_POLL 1
+
+/* Define if you have the <poll.h> header file. */
+#define HAVE_POLL_H 1
+
+/* Define if you have the `pselect' function. */
+#define HAVE_PSELECT 1
+
+/* define if pselect prototype is in <sys/stat.h> */
+#define HAVE_PSELECT_PROTO 1
+
+/* Define if you have the <pthread.h> header file. */
+#define HAVE_PTHREAD_H 1
+
+/* Define if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* define if snprintf prototype is in <stdio.h> */
+#define HAVE_SNPRINTF_PROTO 1
+
+/* Define if <net/if_dl.h> defines struct sockaddr_dl */
+#define HAVE_SOCKADDR_DL_STRUCT 1
+
+/* define if socket address structures have length fields */
+#define HAVE_SOCKADDR_SA_LEN 1
+
+/* Define if you have the `sockatmark' function. */
+#define HAVE_SOCKATMARK 1
+
+/* define if sockatmark prototype is in <sys/socket.h> */
+#define HAVE_SOCKATMARK_PROTO 1
+
+/* Define if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <stropts.h> header file. */
+/* #undef HAVE_STROPTS_H */
+
+/* Define if `ifr_mtu' is member of `struct ifreq'. */
+#define HAVE_STRUCT_IFREQ_IFR_MTU 1
+
+/* Define if the system has the type `struct sockaddr_storage'. */
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* Define if you have the <sys/event.h> header file. */
+#define HAVE_SYS_EVENT_H 1
+
+/* Define if you have the <sys/filio.h> header file. */
+#define HAVE_SYS_FILIO_H 1
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define if you have the <sys/sockio.h> header file. */
+#define HAVE_SYS_SOCKIO_H 1
+
+/* Define if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define if you have the <sys/sysctl.h> header file. */
+#define HAVE_SYS_SYSCTL_H 1
+
+/* Define if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define if you have the <sys/un.h> header file. */
+#define HAVE_SYS_UN_H 1
+
+/* Define if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define if <time.h> defines struct timespec */
+#define HAVE_TIMESPEC_STRUCT 1
+
+/* Define if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* Define if you have the <xti.h> header file. */
+/* #undef HAVE_XTI_H */
+
+/* Define if you have the <xti_inet.h> header file. */
+/* #undef HAVE_XTI_INET_H */
+
+/* Define if the system supports IPv4 */
+#define IPV4 1
+
+/* Define if the system supports IPv6 */
+#define IPV6 1
+
+/* Define if the system supports IPv4 */
+#define IPv4 1
+
+/* Define if the system supports IPv6 */
+#define IPv6 1
+
+/* Define if the system supports IP Multicast */
+#define MCAST 1
+
+/* the size of the sa_family field in a socket address structure */
+/* #undef SA_FAMILY_T */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if the system supports UNIX domain sockets */
+#define UNIXDOMAIN 1
+
+/* Define if the system supports UNIX domain sockets */
+#define UNIXdomain 1
+
+/* 16 bit signed type */
+/* #undef int16_t */
+
+/* 32 bit signed type */
+/* #undef int32_t */
+
+/* the type of the sa_family struct element */
+/* #undef sa_family_t */
+
+/* unsigned integer type of the result of the sizeof operator */
+/* #undef size_t */
+
+/* a type appropriate for address */
+/* #undef socklen_t */
+
+/* define to __ss_family if sockaddr_storage has that instead of ss_family */
+/* #undef ss_family */
+
+/* a signed type appropriate for a count of bytes or an error indication */
+/* #undef ssize_t */
+
+/* scalar type */
+#define t_scalar_t int32_t
+
+/* unsigned scalar type */
+#define t_uscalar_t uint32_t
+
+/* 16 bit unsigned type */
+/* #undef uint16_t */
+
+/* 32 bit unsigned type */
+/* #undef uint32_t */
+
+/* 8-bit unsigned type */
+/* #undef uint8_t */
diff --git a/ssntp/Makefile b/ssntp/Makefile
new file mode 100644 (file)
index 0000000..7082bce
--- /dev/null
@@ -0,0 +1,11 @@
+include ../Make.defines
+
+PROGS =        ssntp
+
+all:   ${PROGS}
+
+ssntp: main.o sntp_proc.o
+               ${CC} ${CFLAGS} -o $@ main.o sntp_proc.o ${LIBS} 
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/ssntp/main.c b/ssntp/main.c
new file mode 100644 (file)
index 0000000..86a3993
--- /dev/null
@@ -0,0 +1,43 @@
+#include       "sntp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       char                            buf[MAXLINE];
+       ssize_t                         n;
+       socklen_t                       salen, len;
+       struct ifi_info         *ifi;
+       struct sockaddr         *mcastsa, *wild, *from;
+       struct timeval          now;
+
+       if (argc != 2)
+               err_quit("usage: ssntp <IPaddress>");
+
+       sockfd = Udp_client(argv[1], "ntp", (void **) &mcastsa, &salen);
+
+       wild = Malloc(salen);
+       memcpy(wild, mcastsa, salen);   /* copy family and port */
+       sock_set_wild(wild, salen);
+       Bind(sockfd, wild, salen);      /* bind wildcard */
+
+#ifdef MCAST
+               /* 4obtain interface list and process each one */
+       for (ifi = Get_ifi_info(mcastsa->sa_family, 1); ifi != NULL;
+                ifi = ifi->ifi_next) {
+               if (ifi->ifi_flags & IFF_MULTICAST) {
+                       Mcast_join(sockfd, mcastsa, salen, ifi->ifi_name, 0);
+                       printf("joined %s on %s\n",
+                                  Sock_ntop(mcastsa, salen), ifi->ifi_name);
+               }
+       }
+#endif
+
+       from = Malloc(salen);
+       for ( ; ; ) {
+               len = salen;
+               n = Recvfrom(sockfd, buf, sizeof(buf), 0, from, &len);
+               Gettimeofday(&now, NULL);
+               sntp_proc(buf, n, &now);
+       }
+}
diff --git a/ssntp/main.lc b/ssntp/main.lc
new file mode 100644 (file)
index 0000000..8cd65fb
--- /dev/null
@@ -0,0 +1,43 @@
+#include    "sntp.h"##  1 ##src/ssntp/main.c##
+
+int##  2 ##src/ssntp/main.c##
+main(int argc, char **argv)##  3 ##src/ssntp/main.c##
+{##  4 ##src/ssntp/main.c##
+    int     sockfd;##  5 ##src/ssntp/main.c##
+    char    buf[MAXLINE];##  6 ##src/ssntp/main.c##
+    ssize_t n;##  7 ##src/ssntp/main.c##
+    socklen_t salen, len;##  8 ##src/ssntp/main.c##
+    struct ifi_info *ifi;##  9 ##src/ssntp/main.c##
+    struct sockaddr *mcastsa, *wild, *from;## 10 ##src/ssntp/main.c##
+    struct timeval now;## 11 ##src/ssntp/main.c##
+
+    if (argc != 2)## 12 ##src/ssntp/main.c##
+        err_quit("usage: ssntp <IPaddress>");## 13 ##src/ssntp/main.c##
+
+    sockfd = Udp_client(argv[1], "ntp", (void **) &mcastsa, &salen);## 14 ##src/ssntp/main.c##
+
+    wild = Malloc(salen);## 15 ##src/ssntp/main.c##
+    memcpy(wild, mcastsa, salen);   /* copy family and port */## 16 ##src/ssntp/main.c##
+    sock_set_wild(wild, salen);## 17 ##src/ssntp/main.c##
+    Bind(sockfd, wild, salen);  /* bind wildcard */## 18 ##src/ssntp/main.c##
+
+#ifdef  MCAST## 19 ##src/ssntp/main.c##
+    /* 4obtain interface list and process each one */## 20 ##src/ssntp/main.c##
+    for (ifi = Get_ifi_info(mcastsa->sa_family, 1); ifi != NULL;## 21 ##src/ssntp/main.c##
+         ifi = ifi->ifi_next) {## 22 ##src/ssntp/main.c##
+        if (ifi->ifi_flags & IFF_MULTICAST) {## 23 ##src/ssntp/main.c##
+            Mcast_join(sockfd, mcastsa, salen, ifi->ifi_name, 0);## 24 ##src/ssntp/main.c##
+            printf("joined %s on %s\n",## 25 ##src/ssntp/main.c##
+                   Sock_ntop(mcastsa, salen), ifi->ifi_name);## 26 ##src/ssntp/main.c##
+        }## 27 ##src/ssntp/main.c##
+    }## 28 ##src/ssntp/main.c##
+#endif## 29 ##src/ssntp/main.c##
+
+    from = Malloc(salen);## 30 ##src/ssntp/main.c##
+    for (;;) {## 31 ##src/ssntp/main.c##
+        len = salen;## 32 ##src/ssntp/main.c##
+        n = Recvfrom(sockfd, buf, sizeof(buf), 0, from, &len);## 33 ##src/ssntp/main.c##
+        Gettimeofday(&now, NULL);## 34 ##src/ssntp/main.c##
+        sntp_proc(buf, n, &now);## 35 ##src/ssntp/main.c##
+    }## 36 ##src/ssntp/main.c##
+}## 37 ##src/ssntp/main.c##
diff --git a/ssntp/ntp.h b/ssntp/ntp.h
new file mode 100644 (file)
index 0000000..105de53
--- /dev/null
@@ -0,0 +1,32 @@
+#define        JAN_1970        2208988800UL    /* 1970 - 1900 in seconds */
+
+struct l_fixedpt {             /* 64-bit fixed-point */
+  uint32_t     int_part;
+  uint32_t     fraction;
+};
+
+struct s_fixedpt {             /* 32-bit fixed-point */
+  uint16_t     int_part;
+  uint16_t     fraction;
+};
+
+struct ntpdata {               /* NTP header */
+  u_char                       status;
+  u_char                       stratum;
+  u_char                       ppoll;
+  int                          precision:8;
+  struct s_fixedpt     distance;
+  struct s_fixedpt     dispersion;
+  uint32_t                     refid;
+  struct l_fixedpt     reftime;
+  struct l_fixedpt     org;
+  struct l_fixedpt     rec;
+  struct l_fixedpt     xmt;
+};
+
+#define        VERSION_MASK    0x38
+#define        MODE_MASK               0x07
+
+#define        MODE_CLIENT             3
+#define        MODE_SERVER             4
+#define        MODE_BROADCAST  5
diff --git a/ssntp/sntp.h b/ssntp/sntp.h
new file mode 100644 (file)
index 0000000..64200a5
--- /dev/null
@@ -0,0 +1,4 @@
+#include       "unpifi.h"
+#include       "ntp.h"
+
+void    sntp_proc(char *, ssize_t, struct timeval *);
diff --git a/ssntp/sntp_proc.c b/ssntp/sntp_proc.c
new file mode 100644 (file)
index 0000000..192ab45
--- /dev/null
@@ -0,0 +1,39 @@
+#include       "sntp.h"
+
+void
+sntp_proc(char *buf, ssize_t n, struct timeval *nowptr)
+{
+       int                             version, mode;
+       uint32_t                nsec, useci;
+       double                  usecf;
+       struct timeval  diff;
+       struct ntpdata  *ntp;
+
+       if (n < (ssize_t)sizeof(struct ntpdata)) {
+               printf("\npacket too small: %d bytes\n", n);
+               return;
+       }
+
+       ntp = (struct ntpdata *) buf;
+       version = (ntp->status & VERSION_MASK) >> 3;
+       mode = ntp->status & MODE_MASK;
+       printf("\nv%d, mode %d, strat %d, ", version, mode, ntp->stratum);
+       if (mode == MODE_CLIENT) {
+               printf("client\n");
+               return;
+       }
+
+       nsec = ntohl(ntp->xmt.int_part) - JAN_1970;
+       useci = ntohl(ntp->xmt.fraction);       /* 32-bit integer fraction */
+       usecf = useci;                          /* integer fraction -> double */
+       usecf /= 4294967296.0;          /* divide by 2**32 -> [0, 1.0) */
+       useci = usecf * 1000000.0;      /* fraction -> parts per million */
+
+       diff.tv_sec = nowptr->tv_sec - nsec;
+       if ( (diff.tv_usec = nowptr->tv_usec - useci) < 0) {
+               diff.tv_usec += 1000000;
+               diff.tv_sec--;
+       }
+       useci = (diff.tv_sec * 1000000) + diff.tv_usec; /* diff in microsec */
+       printf("clock difference = %d usec\n", useci);
+}
diff --git a/streams/Makefile b/streams/Makefile
new file mode 100644 (file)
index 0000000..7d6fe30
--- /dev/null
@@ -0,0 +1,18 @@
+include ../Make.defines
+
+PROGS =        strlist_sock strlist_xti tpi_daytime
+
+all:   ${PROGS}
+
+strlist_sock:  strlist_sock.o
+               ${CC} ${CFLAGS} -o $@ strlist_sock.o ${LIBS_XTI}
+
+strlist_xti:   strlist_xti.o
+               ${CC} ${CFLAGS} -o $@ strlist_xti.o ${LIBS_XTI}
+
+tpi_daytime:   tpi_daytime.o tpi_bind.o tpi_connect.o tpi_read.o tpi_close.o
+               ${CC} ${CFLAGS} -o $@ tpi_daytime.o tpi_bind.o tpi_connect.o \
+                       tpi_read.o tpi_close.o ${LIBS_XTI}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/streams/stream_dg/Makefile b/streams/stream_dg/Makefile
new file mode 100644 (file)
index 0000000..be1d2b8
--- /dev/null
@@ -0,0 +1,7 @@
+all: client server
+
+client: client.o net_stream.o
+       cc client.o net_stream.o -o client -lnsl
+
+server: server.o net_stream.o
+       cc server.o net_stream.o -o server -lnsl
diff --git a/streams/stream_dg/client.c b/streams/stream_dg/client.c
new file mode 100644 (file)
index 0000000..4fac1f4
--- /dev/null
@@ -0,0 +1,66 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+extern int errno;
+
+#define SERV_HOST_ADDR  "128.220.101.4"
+#define SERV_TCP_PORT   6000
+
+main()
+{
+       int fd;
+       struct sockaddr_in      my_addr;
+       struct sockaddr_in      serv_addr;
+       char buf[128];
+       void echo_driver(int, struct sockaddr_in *);
+
+       if ((fd = net_open ("/dev/udp", O_RDWR)) < 0)
+       {
+               fprintf (stderr, "open failed.\n");
+               exit (-1);
+       }
+       /*
+        * bind any address to us.
+        */
+       bzero((char *) &my_addr, sizeof(my_addr));
+       my_addr.sin_family      = AF_INET;
+       my_addr.sin_addr.s_addr = htonl (INADDR_ANY);
+       my_addr.sin_port        = htons(0);
+
+       fd = net_bind (fd, &my_addr, sizeof (struct sockaddr_in));
+
+       /*
+        * set up server's address
+        */
+       bzero((char *) &serv_addr, sizeof(serv_addr));
+       serv_addr.sin_family      = AF_INET;
+       serv_addr.sin_addr.s_addr = inet_addr (SERV_HOST_ADDR);
+       serv_addr.sin_port        = htons(SERV_TCP_PORT);
+
+       echo_driver (fd, &serv_addr);
+       close (fd);
+
+       exit (0);
+}
+
+void
+echo_driver(int fd, struct sockaddr_in *serv_addr)
+{
+       char buf[512];
+       int n;
+       struct sockaddr_in      fm_addr;
+
+       while ((n = read (0, buf, sizeof (buf))) != 0)
+       {
+               net_send (fd, buf, n, serv_addr, sizeof (struct sockaddr_in));
+
+               n = net_recv (fd, buf, sizeof (buf), &fm_addr, sizeof (struct sockaddr_in));
+
+               write (1, buf, n);
+       }
+       return;
+}
diff --git a/streams/stream_dg/net_stream.c b/streams/stream_dg/net_stream.c
new file mode 100644 (file)
index 0000000..468cc54
--- /dev/null
@@ -0,0 +1,181 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/errno.h>
+
+#include <sys/stream.h>
+#include <sys/stropts.h>
+#include <sys/tihdr.h>
+
+
+extern int errno;
+
+int
+net_open (char *path, int oflags, void *addr, int addrlen)
+{
+       int fd;
+       int flags;
+
+       if ((fd = open (path, oflags)) < 0)
+       {
+               perror ("open");
+               return (-1);
+       }
+       return (fd);
+}
+
+int
+net_bind (int fd, void *addr, int addrlen)
+{
+       struct {
+               struct T_bind_req msg_hdr;
+               char addr[128];
+       } bind_req;
+       struct strbuf ctlbuf;
+       union T_primitives rcvbuf;
+       struct T_error_ack *error_ack;
+       int flags;
+
+       if (addr == NULL || addrlen == 0)
+       {
+               fprintf (stderr, "No address\n");
+               return (-1);
+       }
+
+       bind_req.msg_hdr.PRIM_type = T_BIND_REQ;
+       bind_req.msg_hdr.ADDR_length = addrlen;
+       bind_req.msg_hdr.ADDR_offset = sizeof (struct T_bind_req);
+       bind_req.msg_hdr.CONIND_number = 5;
+       bcopy (addr, bind_req.addr, addrlen);
+
+       ctlbuf.len = sizeof (struct T_bind_req) + addrlen;
+       ctlbuf.buf = (char *) &bind_req;
+
+       if (putmsg (fd, &ctlbuf, NULL, 0) < 0)
+       {
+               return (-1);
+       }
+       /*
+        * Wait for acknowledgement
+        */
+       ctlbuf.maxlen = sizeof (union T_primitives);
+       ctlbuf.len = 0;
+       ctlbuf.buf = (char *) &rcvbuf;
+       flags = RS_HIPRI;
+       if (getmsg (fd, &ctlbuf, NULL, &flags) < 0)
+       {
+               perror ("getmsg");
+               return (-1);
+       }
+
+       if (ctlbuf.len < sizeof (long))
+       {
+               fprintf (stderr, "Bad length from getmsg.\n");
+               errno = EPROTO;
+               return (-1);
+       }
+       switch (rcvbuf.type)
+       {
+           case T_BIND_ACK:
+               return (fd);
+           case T_ERROR_ACK:
+               if (ctlbuf.len < sizeof (struct T_error_ack))
+               {
+                       errno = EPROTO;
+                       return (-1);
+               }
+               error_ack = (struct T_error_ack *) &rcvbuf;
+               fprintf (stderr, "Error ack from bind (%d %d %d)\n",
+                       error_ack->ERROR_prim,
+                       error_ack->TLI_error,
+                       error_ack->UNIX_error);
+               errno = error_ack->UNIX_error;
+               break;
+           default:
+               fprintf (stderr, "No ack from bind?\n");
+               errno = EPROTO;
+               break;
+       }
+       return (-1);
+}
+int
+net_send (int fd, char *buf, int len, char *to_addr, int addrlen)
+{
+       struct strbuf ctlbuf;
+       struct strbuf databuf;
+       struct {
+               struct T_unitdata_req unitdata_req;
+               char buf[128];
+       } netdata;
+
+       bcopy (to_addr, netdata.buf, addrlen);
+       netdata.unitdata_req.PRIM_type = T_UNITDATA_REQ;
+       netdata.unitdata_req.DEST_length = addrlen;
+       netdata.unitdata_req.DEST_offset = sizeof (struct T_unitdata_req);
+       /* 
+        * for now, presume no options.
+        */
+       netdata.unitdata_req.OPT_length = 0;
+       netdata.unitdata_req.OPT_offset = 0;
+
+       ctlbuf.len = sizeof (struct T_unitdata_req) + addrlen;
+       ctlbuf.buf = (char *) &netdata;
+
+       databuf.len = len;
+       databuf.buf = buf;
+
+       if (putmsg (fd, &ctlbuf, &databuf, 0) < 0)
+               return (0);
+       free (netdata.buf);
+       return (len);
+}
+
+int
+net_recv (int fd, char *buf, int len, char *from_addr, int addrlen)
+{
+       struct strbuf ctlbuf;
+       struct strbuf databuf;
+       struct {
+               struct T_unitdata_ind unitdata_ind;
+               char buf[128];
+       } netdata;
+       char *c;
+       int retval;
+       int flags;
+
+       ctlbuf.maxlen = sizeof (netdata);
+       ctlbuf.buf = (char *) &netdata;
+
+       databuf.maxlen = len;
+       databuf.len = 0;
+       databuf.buf = buf;
+
+       flags = 0;
+
+       if ((retval = getmsg (fd, &ctlbuf, &databuf, &flags)) < 0)
+               return (-1);
+
+       if (netdata.unitdata_ind.PRIM_type != T_UNITDATA_IND)
+       {
+               fprintf (stderr, "net_recv: Got %d\n", netdata.unitdata_ind.PRIM_type);
+               errno = EPROTO;
+               return (0);
+       }
+       if (retval)
+       {
+               errno = EIO;
+               return (0);
+       }
+       /*
+        * Copy return address for the user
+        */
+       if (netdata.unitdata_ind.SRC_length < addrlen)
+               addrlen = netdata.unitdata_ind.SRC_length;
+
+       c = (char *) &netdata;
+       bcopy (&(c[netdata.unitdata_ind.SRC_offset]),
+               from_addr,
+               addrlen);
+
+       return (databuf.len);
+}
diff --git a/streams/stream_dg/server.c b/streams/stream_dg/server.c
new file mode 100644 (file)
index 0000000..812fb9a
--- /dev/null
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/errno.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+extern int errno;
+
+#define SERV_TCP_PORT   6000
+
+main()
+{
+       int fd;
+       struct sockaddr_in      my_addr;
+       void                    echo_serv (int);
+
+       bzero((char *) &my_addr, sizeof(my_addr));
+       my_addr.sin_family      = AF_INET;
+       my_addr.sin_addr.s_addr = htonl (INADDR_ANY);
+       my_addr.sin_port        = htons(SERV_TCP_PORT);
+
+       fd = net_open ("/dev/udp", O_RDWR);
+       fd = net_bind (fd, &my_addr, sizeof (struct sockaddr_in));
+
+       echo_serv (fd);
+       exit (0);       /* not reached */
+}
+
+void
+echo_serv (int fd)
+{
+       struct sockaddr_in      fm_addr;
+       char                    buf[512];
+       int                     n;
+
+       while (1)
+       {
+               n = net_recv (fd, buf, sizeof (buf),
+                               &fm_addr, sizeof (struct sockaddr_in));
+
+               net_send (fd, buf, n,
+                               &fm_addr, sizeof (struct sockaddr_in));
+       }
+}
diff --git a/streams/strlist_sock.c b/streams/strlist_sock.c
new file mode 100644 (file)
index 0000000..49a069c
--- /dev/null
@@ -0,0 +1,28 @@
+#include       "unp.h"
+#include       <stropts.h>
+
+int
+main(int argc, char *argv[])
+{
+       int                                     fd, i, nmods;
+       struct str_list         list;
+
+       if (argc != 2)
+               err_quit("usage: a.out { tcp | udp }");
+
+       fd = Socket(AF_INET, (strcmp(argv[1], "tcp") == 0)
+                                                                       ? SOCK_STREAM : SOCK_DGRAM, 0);
+       if (isastream(fd) == 0)
+               err_quit("%s is not a stream", argv[1]);
+
+       list.sl_nmods = nmods = Ioctl(fd, I_LIST, (void *) 0);
+       printf("%d modules\n", nmods);
+       list.sl_modlist = Calloc(nmods, sizeof(struct str_mlist));
+
+       Ioctl(fd, I_LIST, &list);
+
+       for (i = 1; i <= nmods; i++)
+               printf("  %s: %s\n", (i == nmods) ? "driver" : "module",
+                                                               list.sl_modlist++);
+       exit(0);
+}
diff --git a/streams/strlist_xti.c b/streams/strlist_xti.c
new file mode 100644 (file)
index 0000000..b8dc557
--- /dev/null
@@ -0,0 +1,27 @@
+#include       "unpxti.h"
+#include       <stropts.h>
+
+int
+main(int argc, char *argv[])
+{
+       int                                     fd, i, nmods;
+       struct str_list         list;
+
+       if (argc != 2)
+               err_quit("usage: a.out <pathname>");
+
+       fd = T_open(argv[1], O_RDWR, NULL);
+       if (isastream(fd) == 0)
+               err_quit("%s is not a stream", argv[1]);
+
+       list.sl_nmods = nmods = Ioctl(fd, I_LIST, (void *) 0);
+       printf("%d modules\n", nmods);
+       list.sl_modlist = Calloc(nmods, sizeof(struct str_mlist));
+
+       Ioctl(fd, I_LIST, &list);
+
+       for (i = 1; i <= nmods; i++)
+               printf("  %s: %s\n", (i == nmods) ? "driver" : "module",
+                                                               list.sl_modlist++);
+       exit(0);
+}
diff --git a/streams/tpi_bind.c b/streams/tpi_bind.c
new file mode 100644 (file)
index 0000000..386df52
--- /dev/null
@@ -0,0 +1,55 @@
+#include       "tpi_daytime.h"
+
+void
+tpi_bind(int fd, const void *addr, size_t addrlen)
+{
+       struct {
+         struct T_bind_req     msg_hdr;
+         char                          addr[128];
+       } bind_req;
+       struct {
+         struct T_bind_ack     msg_hdr;
+         char                          addr[128];
+       } bind_ack;
+       struct strbuf           ctlbuf;
+       struct T_error_ack      *error_ack;
+       int                                     flags;
+
+       bind_req.msg_hdr.PRIM_type = T_BIND_REQ;
+       bind_req.msg_hdr.ADDR_length = addrlen;
+       bind_req.msg_hdr.ADDR_offset = sizeof(struct T_bind_req);
+       bind_req.msg_hdr.CONIND_number = 0;
+       memcpy(bind_req.addr, addr, addrlen);   /* sockaddr_in{} */
+
+       ctlbuf.len = sizeof(struct T_bind_req) + addrlen;
+       ctlbuf.buf = (char *) &bind_req;
+       Putmsg(fd, &ctlbuf, NULL, 0);
+
+       ctlbuf.maxlen = sizeof(bind_ack);
+       ctlbuf.len = 0;
+       ctlbuf.buf = (char *) &bind_ack;
+       flags = RS_HIPRI;
+       Getmsg(fd, &ctlbuf, NULL, &flags);
+
+/* *INDENT-OFF* */
+       if (ctlbuf.len < (int) sizeof(long))
+               err_quit("bad length from getmsg");
+/* *INDENT-ON* */
+
+       switch(bind_ack.msg_hdr.PRIM_type) {
+    case T_BIND_ACK:
+               return;
+
+    case T_ERROR_ACK:
+/* *INDENT-OFF* */
+               if (ctlbuf.len < (int) sizeof(struct T_error_ack))
+                       err_quit("bad length for T_ERROR_ACK");
+               error_ack = (struct T_error_ack *) &bind_ack.msg_hdr;
+               err_quit("T_ERROR_ACK from bind (%d, %d)",
+                                error_ack->TLI_error, error_ack->UNIX_error);
+/* *INDENT-ON* */
+
+    default:
+               err_quit("unexpected message type: %d", bind_ack.msg_hdr.PRIM_type);
+       }
+}
diff --git a/streams/tpi_close.c b/streams/tpi_close.c
new file mode 100644 (file)
index 0000000..84fd2bb
--- /dev/null
@@ -0,0 +1,16 @@
+#include       "tpi_daytime.h"
+
+void
+tpi_close(int fd)
+{
+       struct T_ordrel_req     ordrel_req;
+       struct strbuf           ctlbuf;
+
+       ordrel_req.PRIM_type = T_ORDREL_REQ;
+
+       ctlbuf.len = sizeof(struct T_ordrel_req);
+       ctlbuf.buf = (char *) &ordrel_req;
+       Putmsg(fd, &ctlbuf, NULL, 0);
+
+       Close(fd);
+}
diff --git a/streams/tpi_close.lc b/streams/tpi_close.lc
new file mode 100644 (file)
index 0000000..d762fe0
--- /dev/null
@@ -0,0 +1,16 @@
+#include    "tpi_daytime.h"##  1 ##src/streams/tpi_close.c##
+
+void##  2 ##src/streams/tpi_close.c##
+tpi_close(int fd)##  3 ##src/streams/tpi_close.c##
+{##  4 ##src/streams/tpi_close.c##
+    struct T_ordrel_req ordrel_req;##  5 ##src/streams/tpi_close.c##
+    struct strbuf ctlbuf;##  6 ##src/streams/tpi_close.c##
+
+    ordrel_req.PRIM_type = T_ORDREL_REQ;##  7 ##src/streams/tpi_close.c##
+
+    ctlbuf.len = sizeof(struct T_ordrel_req);##  8 ##src/streams/tpi_close.c##
+    ctlbuf.buf = (char *) &ordrel_req;##  9 ##src/streams/tpi_close.c##
+    Putmsg(fd, &ctlbuf, NULL, 0);## 10 ##src/streams/tpi_close.c##
+
+    Close(fd);## 11 ##src/streams/tpi_close.c##
+}## 12 ##src/streams/tpi_close.c##
diff --git a/streams/tpi_connect.c b/streams/tpi_connect.c
new file mode 100644 (file)
index 0000000..e5a9b72
--- /dev/null
@@ -0,0 +1,87 @@
+#include       "tpi_daytime.h"
+
+void
+tpi_connect(int fd, const void *addr, size_t addrlen)
+{
+       struct {
+         struct T_conn_req     msg_hdr;
+         char                          addr[128];
+       } conn_req;
+       struct {
+         struct T_conn_con     msg_hdr;
+         char                          addr[128];
+       } conn_con;
+       struct strbuf           ctlbuf;
+       union T_primitives      rcvbuf;
+       struct T_error_ack      *error_ack;
+       struct T_discon_ind     *discon_ind;
+       int                                     flags;
+
+       conn_req.msg_hdr.PRIM_type = T_CONN_REQ;
+       conn_req.msg_hdr.DEST_length = addrlen;
+       conn_req.msg_hdr.DEST_offset = sizeof(struct T_conn_req);
+       conn_req.msg_hdr.OPT_length = 0;
+       conn_req.msg_hdr.OPT_offset = 0;
+       memcpy(conn_req.addr, addr, addrlen);   /* sockaddr_in{} */
+
+       ctlbuf.len = sizeof(struct T_conn_req) + addrlen;
+       ctlbuf.buf = (char *) &conn_req;
+       Putmsg(fd, &ctlbuf, NULL, 0);
+
+       ctlbuf.maxlen = sizeof(union T_primitives);
+       ctlbuf.len = 0;
+       ctlbuf.buf = (char *) &rcvbuf;
+       flags = RS_HIPRI;
+       Getmsg(fd, &ctlbuf, NULL, &flags);
+
+/* *INDENT-OFF* */
+       if (ctlbuf.len < (int) sizeof(long))
+               err_quit("tpi_connect: bad length from getmsg");
+/* *INDENT-ON* */
+
+       switch(rcvbuf.type) {
+    case T_OK_ACK:
+               break;
+
+    case T_ERROR_ACK:
+/* *INDENT-OFF* */
+               if (ctlbuf.len < (int) sizeof(struct T_error_ack))
+                       err_quit("tpi_connect: bad length for T_ERROR_ACK");
+               error_ack = (struct T_error_ack *) &rcvbuf;
+               err_quit("tpi_connect: T_ERROR_ACK from conn (%d, %d)",
+                                error_ack->TLI_error, error_ack->UNIX_error);
+/* *INDENT-ON* */
+
+    default:
+               err_quit("tpi_connect: unexpected message type: %d", rcvbuf.type);
+       }
+
+       ctlbuf.maxlen = sizeof(conn_con);
+       ctlbuf.len = 0;
+       ctlbuf.buf = (char *) &conn_con;
+       flags = 0;
+       Getmsg(fd, &ctlbuf, NULL, &flags);
+
+/* *INDENT-OFF* */
+       if (ctlbuf.len < (int) sizeof(long))
+               err_quit("tpi_connect2: bad length from getmsg");
+/* *INDENT-ON* */
+
+       switch(conn_con.msg_hdr.PRIM_type) {
+    case T_CONN_CON:
+               break;
+
+    case T_DISCON_IND:
+/* *INDENT-OFF* */
+               if (ctlbuf.len < (int) sizeof(struct T_discon_ind))
+                       err_quit("tpi_connect2: bad length for T_DISCON_IND");
+               discon_ind = (struct T_discon_ind *) &conn_con.msg_hdr;
+               err_quit("tpi_connect2: T_DISCON_IND from conn (%d)",
+                                discon_ind->DISCON_reason);
+/* *INDENT-ON* */
+
+    default:
+               err_quit("tpi_connect2: unexpected message type: %d",
+                                conn_con.msg_hdr.PRIM_type);
+       }
+}
diff --git a/streams/tpi_connect.lc b/streams/tpi_connect.lc
new file mode 100644 (file)
index 0000000..93e8d72
--- /dev/null
@@ -0,0 +1,79 @@
+#include    "tpi_daytime.h"##  1 ##src/streams/tpi_connect.c##
+
+void##  2 ##src/streams/tpi_connect.c##
+tpi_connect(int fd, const void *addr, size_t addrlen)##  3 ##src/streams/tpi_connect.c##
+{##  4 ##src/streams/tpi_connect.c##
+    struct {##  5 ##src/streams/tpi_connect.c##
+        struct T_conn_req msg_hdr;##  6 ##src/streams/tpi_connect.c##
+        char    addr[128];##  7 ##src/streams/tpi_connect.c##
+    } conn_req;##  8 ##src/streams/tpi_connect.c##
+    struct {##  9 ##src/streams/tpi_connect.c##
+        struct T_conn_con msg_hdr;## 10 ##src/streams/tpi_connect.c##
+        char    addr[128];## 11 ##src/streams/tpi_connect.c##
+    } conn_con;## 12 ##src/streams/tpi_connect.c##
+    struct strbuf ctlbuf;## 13 ##src/streams/tpi_connect.c##
+    union T_primitives rcvbuf;## 14 ##src/streams/tpi_connect.c##
+    struct T_error_ack *error_ack;## 15 ##src/streams/tpi_connect.c##
+    struct T_discon_ind *discon_ind;## 16 ##src/streams/tpi_connect.c##
+    int     flags;## 17 ##src/streams/tpi_connect.c##
+
+    conn_req.msg_hdr.PRIM_type = T_CONN_REQ;## 18 ##src/streams/tpi_connect.c##
+    conn_req.msg_hdr.DEST_length = addrlen;## 19 ##src/streams/tpi_connect.c##
+    conn_req.msg_hdr.DEST_offset = sizeof(struct T_conn_req);## 20 ##src/streams/tpi_connect.c##
+    conn_req.msg_hdr.OPT_length = 0;## 21 ##src/streams/tpi_connect.c##
+    conn_req.msg_hdr.OPT_offset = 0;## 22 ##src/streams/tpi_connect.c##
+    memcpy(conn_req.addr, addr, addrlen);   /* sockaddr_in{} */## 23 ##src/streams/tpi_connect.c##
+
+    ctlbuf.len = sizeof(struct T_conn_req) + addrlen;## 24 ##src/streams/tpi_connect.c##
+    ctlbuf.buf = (char *) &conn_req;## 25 ##src/streams/tpi_connect.c##
+    Putmsg(fd, &ctlbuf, NULL, 0);## 26 ##src/streams/tpi_connect.c##
+
+    ctlbuf.maxlen = sizeof(union T_primitives);## 27 ##src/streams/tpi_connect.c##
+    ctlbuf.len = 0;## 28 ##src/streams/tpi_connect.c##
+    ctlbuf.buf = (char *) &rcvbuf;## 29 ##src/streams/tpi_connect.c##
+    flags = RS_HIPRI;## 30 ##src/streams/tpi_connect.c##
+    Getmsg(fd, &ctlbuf, NULL, &flags);## 31 ##src/streams/tpi_connect.c##
+
+    if (ctlbuf.len < (int) sizeof(long))## 32 ##src/streams/tpi_connect.c##
+        err_quit("tpi_connect: bad length from getmsg");## 33 ##src/streams/tpi_connect.c##
+
+    switch (rcvbuf.type) {## 34 ##src/streams/tpi_connect.c##
+    case T_OK_ACK:## 35 ##src/streams/tpi_connect.c##
+        break;## 36 ##src/streams/tpi_connect.c##
+
+    case T_ERROR_ACK:## 37 ##src/streams/tpi_connect.c##
+        if (ctlbuf.len < (int) sizeof(struct T_error_ack))## 38 ##src/streams/tpi_connect.c##
+            err_quit("tpi_connect: bad length for T_ERROR_ACK");## 39 ##src/streams/tpi_connect.c##
+        error_ack = (struct T_error_ack *) &rcvbuf;## 40 ##src/streams/tpi_connect.c##
+        err_quit("tpi_connect: T_ERROR_ACK from conn (%d, %d)",## 41 ##src/streams/tpi_connect.c##
+                 error_ack->TLI_error, error_ack->UNIX_error);## 42 ##src/streams/tpi_connect.c##
+
+    default:## 43 ##src/streams/tpi_connect.c##
+        err_quit("tpi_connect: unexpected message type: %d", rcvbuf.type);## 44 ##src/streams/tpi_connect.c##
+    }## 45 ##src/streams/tpi_connect.c##
+
+    ctlbuf.maxlen = sizeof(conn_con);## 46 ##src/streams/tpi_connect.c##
+    ctlbuf.len = 0;## 47 ##src/streams/tpi_connect.c##
+    ctlbuf.buf = (char *) &conn_con;## 48 ##src/streams/tpi_connect.c##
+    flags = 0;## 49 ##src/streams/tpi_connect.c##
+    Getmsg(fd, &ctlbuf, NULL, &flags);## 50 ##src/streams/tpi_connect.c##
+
+    if (ctlbuf.len < (int) sizeof(long))## 51 ##src/streams/tpi_connect.c##
+        err_quit("tpi_connect2: bad length from getmsg");## 52 ##src/streams/tpi_connect.c##
+
+    switch (conn_con.msg_hdr.PRIM_type) {## 53 ##src/streams/tpi_connect.c##
+    case T_CONN_CON:## 54 ##src/streams/tpi_connect.c##
+        break;## 55 ##src/streams/tpi_connect.c##
+
+    case T_DISCON_IND:## 56 ##src/streams/tpi_connect.c##
+        if (ctlbuf.len < (int) sizeof(struct T_discon_ind))## 57 ##src/streams/tpi_connect.c##
+            err_quit("tpi_connect2: bad length for T_DISCON_IND");## 58 ##src/streams/tpi_connect.c##
+        discon_ind = (struct T_discon_ind *) &conn_con.msg_hdr;## 59 ##src/streams/tpi_connect.c##
+        err_quit("tpi_connect2: T_DISCON_IND from conn (%d)",## 60 ##src/streams/tpi_connect.c##
+                 discon_ind->DISCON_reason);## 61 ##src/streams/tpi_connect.c##
+
+    default:## 62 ##src/streams/tpi_connect.c##
+        err_quit("tpi_connect2: unexpected message type: %d",## 63 ##src/streams/tpi_connect.c##
+                 conn_con.msg_hdr.PRIM_type);## 64 ##src/streams/tpi_connect.c##
+    }## 65 ##src/streams/tpi_connect.c##
+}## 66 ##src/streams/tpi_connect.c##
diff --git a/streams/tpi_daytime.c b/streams/tpi_daytime.c
new file mode 100644 (file)
index 0000000..37a8416
--- /dev/null
@@ -0,0 +1,43 @@
+#include       "tpi_daytime.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     fd, n;
+       char                            recvline[MAXLINE + 1];
+       struct sockaddr_in      myaddr, servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tpi_daytime <IPaddress>");
+
+       fd = Open(XTI_TCP, O_RDWR, 0);
+
+               /*4bind any local address */
+       bzero(&myaddr, sizeof(myaddr));
+       myaddr.sin_family = AF_INET;
+       myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       myaddr.sin_port = htons(0);
+
+       tpi_bind(fd, &myaddr, sizeof(struct sockaddr_in));
+
+               /*4fill in server's address */
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port   = htons(13);        /* daytime server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       tpi_connect(fd, &servaddr, sizeof(struct sockaddr_in));
+
+       for ( ; ; ) {
+               if ( (n = tpi_read(fd, recvline, MAXLINE)) <= 0) {
+                       if (n == 0)
+                               break;
+                       else
+                               err_sys("tpi_read error");
+               }
+               recvline[n] = 0;                /* null terminate */
+               fputs(recvline, stdout);
+       }
+       tpi_close(fd);
+       exit(0);
+}
diff --git a/streams/tpi_daytime.h b/streams/tpi_daytime.h
new file mode 100644 (file)
index 0000000..2389cf1
--- /dev/null
@@ -0,0 +1,8 @@
+#include       "unpxti.h"
+#include       <sys/stream.h>
+#include       <sys/tihdr.h>
+
+void   tpi_bind(int, const void *, size_t);
+void   tpi_connect(int, const void *, size_t);
+ssize_t        tpi_read(int, void *, size_t);
+void   tpi_close(int);
diff --git a/streams/tpi_read.c b/streams/tpi_read.c
new file mode 100644 (file)
index 0000000..a163b94
--- /dev/null
@@ -0,0 +1,32 @@
+#include       "tpi_daytime.h"
+
+ssize_t
+tpi_read(int fd, void *buf, size_t len)
+{
+       struct strbuf           ctlbuf;
+       struct strbuf           datbuf;
+       union T_primitives      rcvbuf;
+       int                                     flags;
+
+       ctlbuf.maxlen = sizeof(union T_primitives);
+       ctlbuf.buf = (char *) &rcvbuf;
+
+       datbuf.maxlen = len;
+       datbuf.buf = buf;
+       datbuf.len = 0;
+
+       flags = 0;
+       Getmsg(fd, &ctlbuf, &datbuf, &flags);
+
+       if (ctlbuf.len >= (int) sizeof(long)) {
+               if (rcvbuf.type == T_DATA_IND)
+                       return(datbuf.len);
+               else if (rcvbuf.type == T_ORDREL_IND)
+                       return(0);
+               else
+                       err_quit("tpi_read: unexpected type %d", rcvbuf.type);
+       } else if (ctlbuf.len == -1)
+               return(datbuf.len);
+       else
+               err_quit("tpi_read: bad length from getmsg");
+}
diff --git a/streams/tpi_read.lc b/streams/tpi_read.lc
new file mode 100644 (file)
index 0000000..5ad154c
--- /dev/null
@@ -0,0 +1,32 @@
+#include    "tpi_daytime.h"##  1 ##src/streams/tpi_read.c##
+
+ssize_t##  2 ##src/streams/tpi_read.c##
+tpi_read(int fd, void *buf, size_t len)##  3 ##src/streams/tpi_read.c##
+{##  4 ##src/streams/tpi_read.c##
+    struct strbuf ctlbuf;##  5 ##src/streams/tpi_read.c##
+    struct strbuf datbuf;##  6 ##src/streams/tpi_read.c##
+    union T_primitives rcvbuf;##  7 ##src/streams/tpi_read.c##
+    int     flags;##  8 ##src/streams/tpi_read.c##
+
+    ctlbuf.maxlen = sizeof(union T_primitives);##  9 ##src/streams/tpi_read.c##
+    ctlbuf.buf = (char *) &rcvbuf;## 10 ##src/streams/tpi_read.c##
+
+    datbuf.maxlen = len;## 11 ##src/streams/tpi_read.c##
+    datbuf.buf = buf;## 12 ##src/streams/tpi_read.c##
+    datbuf.len = 0;## 13 ##src/streams/tpi_read.c##
+
+    flags = 0;## 14 ##src/streams/tpi_read.c##
+    Getmsg(fd, &ctlbuf, &datbuf, &flags);## 15 ##src/streams/tpi_read.c##
+
+    if (ctlbuf.len >= (int) sizeof(long)) {## 16 ##src/streams/tpi_read.c##
+        if (rcvbuf.type == T_DATA_IND)## 17 ##src/streams/tpi_read.c##
+            return (datbuf.len);## 18 ##src/streams/tpi_read.c##
+        else if (rcvbuf.type == T_ORDREL_IND)## 19 ##src/streams/tpi_read.c##
+            return (0);## 20 ##src/streams/tpi_read.c##
+        else## 21 ##src/streams/tpi_read.c##
+            err_quit("tpi_read: unexpected type %d", rcvbuf.type);## 22 ##src/streams/tpi_read.c##
+    } else if (ctlbuf.len == -1)## 23 ##src/streams/tpi_read.c##
+        return (datbuf.len);## 24 ##src/streams/tpi_read.c##
+    else## 25 ##src/streams/tpi_read.c##
+        err_quit("tpi_read: bad length from getmsg");## 26 ##src/streams/tpi_read.c##
+}## 27 ##src/streams/tpi_read.c##
diff --git a/streams/unpxti.h b/streams/unpxti.h
new file mode 100644 (file)
index 0000000..6fe4b18
--- /dev/null
@@ -0,0 +1,152 @@
+/* include unpxtih1 */
+#ifndef        __unp_xti_h
+#define        __unp_xti_h
+
+#include       "unp.h"
+
+#include       <xti.h>
+#ifdef HAVE_XTI_INET_H
+# include      <xti_inet.h>
+#endif
+#ifdef HAVE_NETCONFIG_H
+# include      <netconfig.h>
+#endif
+#ifdef HAVE_NETDIR_H
+# include      <netdir.h>
+#endif
+
+#ifdef INFTIM_UNPH
+#undef INFTIM  /* was not in <poll.h>, undef for <stropts.h> */
+#endif
+
+#include       <stropts.h>
+
+/* Provide compatibility with the new names prepended with T_
+   in XNS Issue 5, which are not in Posix.1g. */
+
+#ifndef        T_INET_TCP
+#define        T_INET_TCP              INET_TCP
+/* $$.Ic T_INET_TCP$$ */
+#endif
+/* end unpxtih1 */
+#ifndef        T_INET_UDP
+#define        T_INET_UDP              INET_UDP
+#endif
+#ifndef        T_INET_IP
+#define        T_INET_IP               INET_IP
+#endif
+#ifndef        T_TCP_NODELAY
+#define        T_TCP_NODELAY   TCP_NODELAY
+#endif
+#ifndef        T_TCP_MAXSEG
+#define        T_TCP_MAXSEG    TCP_MAXSEG
+#endif
+#ifndef        T_TCP_KEEPALIVE
+#define        T_TCP_KEEPALIVE TCP_KEEPALIVE
+#endif
+#ifndef        T_UDP_CHECKSUM
+#define        T_UDP_CHECKSUM  UDP_CHECKSUM
+#endif
+#ifndef        T_IP_OPTIONS
+#define        T_IP_OPTIONS    IP_OPTIONS
+#endif
+#ifndef        T_IP_TOS
+#define        T_IP_TOS                IP_TOS
+#endif
+#ifndef        T_IP_TTL
+#define        T_IP_TTL                IP_TTL
+#endif
+#ifndef        T_IP_REUSEADDR
+#define        T_IP_REUSEADDR  IP_REUSEADDR
+#endif
+#ifndef        T_IP_DONTROUTE
+#define        T_IP_DONTROUTE  IP_DONTROUTE
+#endif
+/* include unpxtih2 */
+#ifndef        T_IP_BROADCAST
+#define        T_IP_BROADCAST  IP_BROADCAST
+/* $$.Ic T_IP_BROADCAST$$ */
+#endif
+
+/* Define the appropriate devices for t_open(). */
+#ifdef HAVE_DEV_TCP
+# define       XTI_TCP         "/dev/tcp"
+# define       XTI_UDP         "/dev/udp"
+#endif
+#ifdef HAVE_DEV_XTI_TCP
+# define       XTI_TCP         "/dev/xti/tcp"
+# define       XTI_UDP         "/dev/xti/udp"
+#endif
+#ifdef HAVE_DEV_STREAMS_XTISO_TCP
+# define       XTI_TCP         "/dev/streams/xtiso/tcp+"       /* + for XPG4 */
+# define       XTI_UDP         "/dev/streams/xtiso/udp+"       /* + for XPG4 */
+#endif
+
+       /* 4device to t_open() for t_accept(); set by tcp_listen() */
+/* $$.Id xti_serv_dev$$ */
+extern char    xti_serv_dev[];
+/* end unpxtih2 */
+
+void    err_xti(const char *fmt, ...);
+void    err_xti_ret(const char *fmt, ...);
+
+int             Getmsg(int, struct strbuf *, struct strbuf *, int *);
+void    Putmsg(int, const struct strbuf *, const struct strbuf *, int);
+
+#ifdef HAVE_NETCONFIG_H
+void   *Setnetconfig(void);
+void   *Setnetpath(void);
+#endif
+
+void   *T_alloc(int, int, int);
+int             T_accept(int, int, struct t_call *);
+void    T_bind(int, const struct t_bind *, struct t_bind *);
+void    T_close(int);
+void    T_connect(int, const struct t_call *, struct t_call *);
+void    T_free(void *, int);
+void    T_getprotaddr(int, struct t_bind *, struct t_bind *);
+int             T_getstate(int);
+void    T_listen(int, struct t_call *);
+int             T_look(int);
+int             T_open(const char *, int, struct t_info *);
+void    T_optmgmt(int, const struct t_optmgmt *, struct t_optmgmt *);
+int             T_rcv(int, void *, unsigned int, int *);
+void    T_rcvdis(int, struct t_discon *);
+void    T_rcvrel(int);
+void    T_rcvudata(int, struct t_unitdata *, int *);
+void    T_rcvuderr(int, struct t_uderr *);
+void    T_snd(int, void *, unsigned int, int);
+void    T_sndrel(int);
+void    T_sndudata(int, struct t_unitdata *);
+
+int             xti_accept(int, struct netbuf *, int);
+int             xti_getopt(int, int, int, void *, socklen_t *);
+char   *xti_flags_str(int);
+char   *xti_tlook_str(int);
+char   *xti_ntop(const struct netbuf *);
+char   *xti_ntop_host(const struct netbuf *);
+int             xti_rdwr(int);
+int             xti_setopt(int, int, int, void *, socklen_t);
+
+int             Xti_accept(int, struct netbuf *, int);
+void    Xti_getopt(int, int, int, void *, socklen_t *);
+char   *Xti_flags_str(int);
+char   *Xti_tlook_str(int);
+char   *Xti_ntop(const struct netbuf *);
+char   *Xti_ntop_host(const struct netbuf *);
+void    Xti_rdwr(int);
+void    Xti_setopt(int, int, int, void *, socklen_t);
+
+char   *xti_str_lend(struct t_opthdr *);
+char   *xti_str_uscalard(struct t_opthdr *);
+char   *xti_str_uchard(struct t_opthdr *);
+char   *xti_str_ucharx(struct t_opthdr *);
+char   *xti_str_yn(t_uscalar_t);
+char   *xti_str_syng(t_scalar_t);
+char   *xti_str_uiyn(struct t_opthdr *);
+char   *xti_str_usyn(struct t_opthdr *);
+char   *xti_str_linger(struct t_opthdr *);
+char   *xti_str_kpalive(struct t_opthdr *);
+char   *xti_str_flags(t_scalar_t);
+
+#endif /* __unp_xti_h */
diff --git a/tcpcliserv/Makefile b/tcpcliserv/Makefile
new file mode 100644 (file)
index 0000000..9f114d0
--- /dev/null
@@ -0,0 +1,67 @@
+include ../Make.defines
+
+PROGS =        tcpcli01 tcpcli04 tcpcli05 tcpcli06 \
+               tcpcli07 tcpcli08 tcpcli09 tcpcli10 \
+               tcpserv01 tcpserv02 tcpserv03 tcpserv04 \
+               tcpserv08 tcpserv09 tcpservselect01 tcpservpoll01 tsigpipe
+
+all:   ${PROGS}
+
+tcpcli01:      tcpcli01.o
+               ${CC} ${CFLAGS} -o $@ tcpcli01.o ${LIBS}
+
+tcpcli04:      tcpcli04.o
+               ${CC} ${CFLAGS} -o $@ tcpcli04.o ${LIBS}
+
+tcpcli05:      tcpcli05.o
+               ${CC} ${CFLAGS} -o $@ tcpcli05.o ${LIBS}
+
+tcpcli06:      tcpcli06.o
+               ${CC} ${CFLAGS} -o $@ tcpcli06.o ${LIBS}
+
+tcpcli07:      tcpcli07.o
+               ${CC} ${CFLAGS} -o $@ tcpcli07.o ${LIBS}
+
+tcpcli08:      tcpcli08.o str_cli08.o
+               ${CC} ${CFLAGS} -o $@ tcpcli08.o str_cli08.o ${LIBS}
+
+tcpcli09:      tcpcli09.o str_cli09.o
+               ${CC} ${CFLAGS} -o $@ tcpcli09.o str_cli09.o ${LIBS}
+
+tcpcli10:      tcpcli10.o
+               ${CC} ${CFLAGS} -o $@ tcpcli10.o ${LIBS}
+
+tcpcli11:      tcpcli11.o str_cli11.o
+               ${CC} ${CFLAGS} -o $@ tcpcli11.o str_cli11.o ${LIBS}
+
+tcpserv01:     tcpserv01.o
+               ${CC} ${CFLAGS} -o $@ tcpserv01.o ${LIBS}
+
+tcpserv02:     tcpserv02.o sigchldwait.o
+               ${CC} ${CFLAGS} -o $@ tcpserv02.o sigchldwait.o ${LIBS}
+
+tcpserv03:     tcpserv03.o sigchldwait.o
+               ${CC} ${CFLAGS} -o $@ tcpserv03.o sigchldwait.o ${LIBS}
+
+tcpserv04:     tcpserv04.o sigchldwaitpid.o
+               ${CC} ${CFLAGS} -o $@ tcpserv04.o sigchldwaitpid.o ${LIBS}
+
+tcpserv08:     tcpserv08.o str_echo08.o sigchldwaitpid.o
+               ${CC} ${CFLAGS} -o $@ tcpserv08.o str_echo08.o sigchldwaitpid.o \
+                       ${LIBS}
+
+tcpserv09:     tcpserv09.o str_echo09.o sigchldwaitpid.o
+               ${CC} ${CFLAGS} -o $@ tcpserv09.o str_echo09.o sigchldwaitpid.o \
+                       ${LIBS}
+
+tcpservselect01:       tcpservselect01.o
+               ${CC} ${CFLAGS} -o $@ tcpservselect01.o ${LIBS}
+
+tcpservpoll01: tcpservpoll01.o
+               ${CC} ${CFLAGS} -o $@ tcpservpoll01.o ${LIBS}
+
+tsigpipe:      tsigpipe.o
+               ${CC} ${CFLAGS} -o $@ tsigpipe.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/tcpcliserv/sigchldwait.c b/tcpcliserv/sigchldwait.c
new file mode 100644 (file)
index 0000000..9730af0
--- /dev/null
@@ -0,0 +1,12 @@
+#include       "unp.h"
+
+void
+sig_chld(int signo)
+{
+       pid_t   pid;
+       int             stat;
+
+       pid = wait(&stat);
+       printf("child %d terminated\n", pid);
+       return;
+}
diff --git a/tcpcliserv/sigchldwait.lc b/tcpcliserv/sigchldwait.lc
new file mode 100644 (file)
index 0000000..fd749fe
--- /dev/null
@@ -0,0 +1,12 @@
+#include    "unp.h"##  1 ##src/tcpcliserv/sigchldwait.c##
+
+void##  2 ##src/tcpcliserv/sigchldwait.c##
+sig_chld(int signo)##  3 ##src/tcpcliserv/sigchldwait.c##
+{##  4 ##src/tcpcliserv/sigchldwait.c##
+    pid_t   pid;##  5 ##src/tcpcliserv/sigchldwait.c##
+    int     stat;##  6 ##src/tcpcliserv/sigchldwait.c##
+
+    pid = wait(&stat);##  7 ##src/tcpcliserv/sigchldwait.c##
+    printf("child %d terminated\n", pid);##  8 ##src/tcpcliserv/sigchldwait.c##
+    return;##  9 ##src/tcpcliserv/sigchldwait.c##
+}## 10 ##src/tcpcliserv/sigchldwait.c##
diff --git a/tcpcliserv/sigchldwaitpid.c b/tcpcliserv/sigchldwaitpid.c
new file mode 100644 (file)
index 0000000..12b5ff3
--- /dev/null
@@ -0,0 +1,12 @@
+#include       "unp.h"
+
+void
+sig_chld(int signo)
+{
+       pid_t   pid;
+       int             stat;
+
+       while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
+               printf("child %d terminated\n", pid);
+       return;
+}
diff --git a/tcpcliserv/sigchldwaitpid.lc b/tcpcliserv/sigchldwaitpid.lc
new file mode 100644 (file)
index 0000000..c196fb7
--- /dev/null
@@ -0,0 +1,12 @@
+#include    "unp.h"##  1 ##src/tcpcliserv/sigchldwaitpid.c##
+
+void##  2 ##src/tcpcliserv/sigchldwaitpid.c##
+sig_chld(int signo)##  3 ##src/tcpcliserv/sigchldwaitpid.c##
+{##  4 ##src/tcpcliserv/sigchldwaitpid.c##
+    pid_t   pid;##  5 ##src/tcpcliserv/sigchldwaitpid.c##
+    int     stat;##  6 ##src/tcpcliserv/sigchldwaitpid.c##
+
+    while ((pid = waitpid(-1, &stat, WNOHANG)) > 0)##  7 ##src/tcpcliserv/sigchldwaitpid.c##
+        printf("child %d terminated\n", pid);##  8 ##src/tcpcliserv/sigchldwaitpid.c##
+    return;##  9 ##src/tcpcliserv/sigchldwaitpid.c##
+}## 10 ##src/tcpcliserv/sigchldwaitpid.c##
diff --git a/tcpcliserv/str_cli08.c b/tcpcliserv/str_cli08.c
new file mode 100644 (file)
index 0000000..ea0f9da
--- /dev/null
@@ -0,0 +1,17 @@
+#include       "unp.h"
+
+void
+str_cli(FILE *fp, int sockfd)
+{
+       char    sendline[MAXLINE], recvline[MAXLINE];
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Writen(sockfd, sendline, strlen(sendline));
+
+               if (Readline(sockfd, recvline, MAXLINE) == 0)
+                       err_quit("str_cli: server terminated prematurely");
+
+               Fputs(recvline, stdout);
+       }
+}
diff --git a/tcpcliserv/str_cli09.c b/tcpcliserv/str_cli09.c
new file mode 100644 (file)
index 0000000..ce74d00
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+#include       "sum.h"
+
+void
+str_cli(FILE *fp, int sockfd)
+{
+       char                    sendline[MAXLINE];
+       struct args             args;
+       struct result   result;
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               if (sscanf(sendline, "%ld%ld", &args.arg1, &args.arg2) != 2) {
+                       printf("invalid input: %s", sendline);
+                       continue;
+               }
+               Writen(sockfd, &args, sizeof(args));
+
+               if (Readn(sockfd, &result, sizeof(result)) == 0)
+                       err_quit("str_cli: server terminated prematurely");
+
+               printf("%ld\n", result.sum);
+       }
+}
diff --git a/tcpcliserv/str_cli11.c b/tcpcliserv/str_cli11.c
new file mode 100644 (file)
index 0000000..e5a29e1
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "unp.h"
+
+void
+str_cli(FILE *fp, int sockfd)
+{
+       char    sendline[MAXLINE], recvline[MAXLINE];
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Writen(sockfd, sendline, 1);
+               sleep(1);
+               Writen(sockfd, sendline+1, strlen(sendline)-1);
+
+               if (Readline(sockfd, recvline, MAXLINE) == 0)
+                       err_quit("str_cli: server terminated prematurely");
+
+               Fputs(recvline, stdout);
+       }
+}
diff --git a/tcpcliserv/str_cli11.lc b/tcpcliserv/str_cli11.lc
new file mode 100644 (file)
index 0000000..f02bd61
--- /dev/null
@@ -0,0 +1,19 @@
+#include    "unp.h"##  1 ##src/tcpcliserv/str_cli11.c##
+
+void##  2 ##src/tcpcliserv/str_cli11.c##
+str_cli(FILE *fp, int sockfd)##  3 ##src/tcpcliserv/str_cli11.c##
+{##  4 ##src/tcpcliserv/str_cli11.c##
+    char    sendline[MAXLINE], recvline[MAXLINE];##  5 ##src/tcpcliserv/str_cli11.c##
+
+    while (Fgets(sendline, MAXLINE, fp) != NULL) {##  6 ##src/tcpcliserv/str_cli11.c##
+
+        Writen(sockfd, sendline, 1);##  7 ##src/tcpcliserv/str_cli11.c##
+        sleep(1);##  8 ##src/tcpcliserv/str_cli11.c##
+        Writen(sockfd, sendline + 1, strlen(sendline) - 1);##  9 ##src/tcpcliserv/str_cli11.c##
+
+        if (Readline(sockfd, recvline, MAXLINE) == 0)## 10 ##src/tcpcliserv/str_cli11.c##
+            err_quit("str_cli: server terminated prematurely");## 11 ##src/tcpcliserv/str_cli11.c##
+
+        Fputs(recvline, stdout);## 12 ##src/tcpcliserv/str_cli11.c##
+    }## 13 ##src/tcpcliserv/str_cli11.c##
+}## 14 ##src/tcpcliserv/str_cli11.c##
diff --git a/tcpcliserv/str_echo08.c b/tcpcliserv/str_echo08.c
new file mode 100644 (file)
index 0000000..cd2202e
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+void
+str_echo(int sockfd)
+{
+       long            arg1, arg2;
+       ssize_t         n;
+       char            line[MAXLINE];
+
+       for ( ; ; ) {
+               if ( (n = Readline(sockfd, line, MAXLINE)) == 0)
+                       return;         /* connection closed by other end */
+
+               if (sscanf(line, "%ld%ld", &arg1, &arg2) == 2)
+                       snprintf(line, sizeof(line), "%ld\n", arg1 + arg2);
+               else
+                       snprintf(line, sizeof(line), "input error\n");
+
+               n = strlen(line);
+               Writen(sockfd, line, n);
+       }
+}
diff --git a/tcpcliserv/str_echo08.lc b/tcpcliserv/str_echo08.lc
new file mode 100644 (file)
index 0000000..641cd68
--- /dev/null
@@ -0,0 +1,22 @@
+#include    "unp.h"##  1 ##src/tcpcliserv/str_echo08.c##
+
+void##  2 ##src/tcpcliserv/str_echo08.c##
+str_echo(int sockfd)##  3 ##src/tcpcliserv/str_echo08.c##
+{##  4 ##src/tcpcliserv/str_echo08.c##
+    long    arg1, arg2;##  5 ##src/tcpcliserv/str_echo08.c##
+    ssize_t n;##  6 ##src/tcpcliserv/str_echo08.c##
+    char    line[MAXLINE];##  7 ##src/tcpcliserv/str_echo08.c##
+
+    for (;;) {##  8 ##src/tcpcliserv/str_echo08.c##
+        if ((n = Readline(sockfd, line, MAXLINE)) == 0)##  9 ##src/tcpcliserv/str_echo08.c##
+            return;             /* connection closed by other end */## 10 ##src/tcpcliserv/str_echo08.c##
+
+        if (sscanf(line, "%ld%ld", &arg1, &arg2) == 2)## 11 ##src/tcpcliserv/str_echo08.c##
+            snprintf(line, sizeof(line), "%ld\n", arg1 + arg2);## 12 ##src/tcpcliserv/str_echo08.c##
+        else## 13 ##src/tcpcliserv/str_echo08.c##
+            snprintf(line, sizeof(line), "input error\n");## 14 ##src/tcpcliserv/str_echo08.c##
+
+        n = strlen(line);## 15 ##src/tcpcliserv/str_echo08.c##
+        Writen(sockfd, line, n);## 16 ##src/tcpcliserv/str_echo08.c##
+    }## 17 ##src/tcpcliserv/str_echo08.c##
+}## 18 ##src/tcpcliserv/str_echo08.c##
diff --git a/tcpcliserv/str_echo09.c b/tcpcliserv/str_echo09.c
new file mode 100644 (file)
index 0000000..0face1f
--- /dev/null
@@ -0,0 +1,18 @@
+#include       "unp.h"
+#include       "sum.h"
+
+void
+str_echo(int sockfd)
+{
+       ssize_t                 n;
+       struct args             args;
+       struct result   result;
+
+       for ( ; ; ) {
+               if ( (n = Readn(sockfd, &args, sizeof(args))) == 0)
+                       return;         /* connection closed by other end */
+
+               result.sum = args.arg1 + args.arg2;
+               Writen(sockfd, &result, sizeof(result));
+       }
+}
diff --git a/tcpcliserv/sum.h b/tcpcliserv/sum.h
new file mode 100644 (file)
index 0000000..32e8a3b
--- /dev/null
@@ -0,0 +1,8 @@
+struct args {
+  long arg1;
+  long arg2;
+};
+
+struct result {
+  long sum;
+};
diff --git a/tcpcliserv/tcpcli01.c b/tcpcliserv/tcpcli01.c
new file mode 100644 (file)
index 0000000..af1f1bf
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/tcpcliserv/tcpcli01.lc b/tcpcliserv/tcpcli01.lc
new file mode 100644 (file)
index 0000000..1059abe
--- /dev/null
@@ -0,0 +1,24 @@
+#include    "unp.h"##  1 ##src/tcpcliserv/tcpcli01.c##
+
+int##  2 ##src/tcpcliserv/tcpcli01.c##
+main(int argc, char **argv)##  3 ##src/tcpcliserv/tcpcli01.c##
+{##  4 ##src/tcpcliserv/tcpcli01.c##
+    int     sockfd;##  5 ##src/tcpcliserv/tcpcli01.c##
+    struct sockaddr_in servaddr;##  6 ##src/tcpcliserv/tcpcli01.c##
+
+    if (argc != 2)##  7 ##src/tcpcliserv/tcpcli01.c##
+        err_quit("usage: tcpcli <IPaddress>");##  8 ##src/tcpcliserv/tcpcli01.c##
+
+    sockfd = Socket(AF_INET, SOCK_STREAM, 0);##  9 ##src/tcpcliserv/tcpcli01.c##
+
+    bzero(&servaddr, sizeof(servaddr));## 10 ##src/tcpcliserv/tcpcli01.c##
+    servaddr.sin_family = AF_INET;## 11 ##src/tcpcliserv/tcpcli01.c##
+    servaddr.sin_port = htons(SERV_PORT);## 12 ##src/tcpcliserv/tcpcli01.c##
+    Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);## 13 ##src/tcpcliserv/tcpcli01.c##
+
+    Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));## 14 ##src/tcpcliserv/tcpcli01.c##
+
+    str_cli(stdin, sockfd);     /* do it all */## 15 ##src/tcpcliserv/tcpcli01.c##
+
+    exit(0);## 16 ##src/tcpcliserv/tcpcli01.c##
+}## 17 ##src/tcpcliserv/tcpcli01.c##
diff --git a/tcpcliserv/tcpcli04.c b/tcpcliserv/tcpcli04.c
new file mode 100644 (file)
index 0000000..1f76455
--- /dev/null
@@ -0,0 +1,26 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     i, sockfd[5];
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       for (i = 0; i < 5; i++) {
+               sockfd[i] = Socket(AF_INET, SOCK_STREAM, 0);
+
+               bzero(&servaddr, sizeof(servaddr));
+               servaddr.sin_family = AF_INET;
+               servaddr.sin_port = htons(SERV_PORT);
+               Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+               Connect(sockfd[i], (SA *) &servaddr, sizeof(servaddr));
+       }
+
+       str_cli(stdin, sockfd[0]);              /* do it all */
+
+       exit(0);
+}
diff --git a/tcpcliserv/tcpcli05.c b/tcpcliserv/tcpcli05.c
new file mode 100644 (file)
index 0000000..c9b4898
--- /dev/null
@@ -0,0 +1,25 @@
+/* Use standard echo server; baseline measurements for nonblocking version */
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(7);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/tcpcliserv/tcpcli06.c b/tcpcliserv/tcpcli06.c
new file mode 100644 (file)
index 0000000..5f1c7da
--- /dev/null
@@ -0,0 +1,28 @@
+/* Test version of client that sends one line without a newline,
+   to break tcpservselect01.c */
+
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Writen(sockfd, "foo", 3);       /* no newline */
+       sleep(30);
+
+       exit(0);
+}
diff --git a/tcpcliserv/tcpcli07.c b/tcpcliserv/tcpcli07.c
new file mode 100644 (file)
index 0000000..19dc02e
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       void                            sig_alrm(int);
+       struct itimerval        val;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+               /* Set interval timer to go off before 3WHS completes */
+       Signal(SIGALRM, sig_alrm);
+       val.it_interval.tv_sec  = 0;
+       val.it_interval.tv_usec = 0;
+       val.it_value.tv_sec  = 0;
+       val.it_value.tv_usec = 50000;   /* 50 ms */
+       if (setitimer(ITIMER_REAL, &val, NULL) == -1)
+               err_sys("setitimer error");
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
+
+void
+sig_alrm(int signo)
+{
+       exit(0);
+}
diff --git a/tcpcliserv/tcpcli08.c b/tcpcliserv/tcpcli08.c
new file mode 100644 (file)
index 0000000..af1f1bf
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/tcpcliserv/tcpcli09.c b/tcpcliserv/tcpcli09.c
new file mode 100644 (file)
index 0000000..af1f1bf
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/tcpcliserv/tcpcli10.c b/tcpcliserv/tcpcli10.c
new file mode 100644 (file)
index 0000000..6a0b499
--- /dev/null
@@ -0,0 +1,29 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct linger           ling;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       ling.l_onoff = 1;
+       ling.l_linger = 0;
+       Setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
+
+       exit(0);
+}
diff --git a/tcpcliserv/tcpcli11.c b/tcpcliserv/tcpcli11.c
new file mode 100644 (file)
index 0000000..c9b4898
--- /dev/null
@@ -0,0 +1,25 @@
+/* Use standard echo server; baseline measurements for nonblocking version */
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(7);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/tcpcliserv/tcpserv01.c b/tcpcliserv/tcpserv01.c
new file mode 100644 (file)
index 0000000..1720e83
--- /dev/null
@@ -0,0 +1,33 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       pid_t                           childpid;
+       socklen_t                       clilen;
+       struct sockaddr_in      cliaddr, servaddr;
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       for ( ; ; ) {
+               clilen = sizeof(cliaddr);
+               connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
+
+               if ( (childpid = Fork()) == 0) {        /* child process */
+                       Close(listenfd);        /* close listening socket */
+                       str_echo(connfd);       /* process the request */
+                       exit(0);
+               }
+               Close(connfd);                  /* parent closes connected socket */
+       }
+}
diff --git a/tcpcliserv/tcpserv01.lc b/tcpcliserv/tcpserv01.lc
new file mode 100644 (file)
index 0000000..bd441fb
--- /dev/null
@@ -0,0 +1,33 @@
+#include    "unp.h"##  1 ##src/tcpcliserv/tcpserv01.c##
+
+int##  2 ##src/tcpcliserv/tcpserv01.c##
+main(int argc, char **argv)##  3 ##src/tcpcliserv/tcpserv01.c##
+{##  4 ##src/tcpcliserv/tcpserv01.c##
+    int     listenfd, connfd;##  5 ##src/tcpcliserv/tcpserv01.c##
+    pid_t   childpid;##  6 ##src/tcpcliserv/tcpserv01.c##
+    socklen_t clilen;##  7 ##src/tcpcliserv/tcpserv01.c##
+    struct sockaddr_in cliaddr, servaddr;##  8 ##src/tcpcliserv/tcpserv01.c##
+
+    listenfd = Socket(AF_INET, SOCK_STREAM, 0);##  9 ##src/tcpcliserv/tcpserv01.c##
+
+    bzero(&servaddr, sizeof(servaddr));## 10 ##src/tcpcliserv/tcpserv01.c##
+    servaddr.sin_family = AF_INET;## 11 ##src/tcpcliserv/tcpserv01.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 12 ##src/tcpcliserv/tcpserv01.c##
+    servaddr.sin_port = htons(SERV_PORT);## 13 ##src/tcpcliserv/tcpserv01.c##
+
+    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 14 ##src/tcpcliserv/tcpserv01.c##
+
+    Listen(listenfd, LISTENQ);## 15 ##src/tcpcliserv/tcpserv01.c##
+
+    for (;;) {## 16 ##src/tcpcliserv/tcpserv01.c##
+        clilen = sizeof(cliaddr);## 17 ##src/tcpcliserv/tcpserv01.c##
+        connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);## 18 ##src/tcpcliserv/tcpserv01.c##
+
+        if ((childpid = Fork()) == 0) { /* child process */## 19 ##src/tcpcliserv/tcpserv01.c##
+            Close(listenfd);    /* close listening socket */## 20 ##src/tcpcliserv/tcpserv01.c##
+            str_echo(connfd);   /* process the request */## 21 ##src/tcpcliserv/tcpserv01.c##
+            exit(0);## 22 ##src/tcpcliserv/tcpserv01.c##
+        }## 23 ##src/tcpcliserv/tcpserv01.c##
+        Close(connfd);          /* parent closes connected socket */## 24 ##src/tcpcliserv/tcpserv01.c##
+    }## 25 ##src/tcpcliserv/tcpserv01.c##
+}## 26 ##src/tcpcliserv/tcpserv01.c##
diff --git a/tcpcliserv/tcpserv02.c b/tcpcliserv/tcpserv02.c
new file mode 100644 (file)
index 0000000..9e8b43d
--- /dev/null
@@ -0,0 +1,36 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       pid_t                           childpid;
+       socklen_t                       clilen;
+       struct sockaddr_in      cliaddr, servaddr;
+       void                            sig_chld(int);
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       Signal(SIGCHLD, sig_chld);
+
+       for ( ; ; ) {
+               clilen = sizeof(cliaddr);
+               connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
+
+               if ( (childpid = Fork()) == 0) {        /* child process */
+                       Close(listenfd);        /* close listening socket */
+                       str_echo(connfd);       /* process the request */
+                       exit(0);
+               }
+               Close(connfd);                  /* parent closes connected socket */
+       }
+}
diff --git a/tcpcliserv/tcpserv03.c b/tcpcliserv/tcpserv03.c
new file mode 100644 (file)
index 0000000..a964276
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       pid_t                           childpid;
+       socklen_t                       clilen;
+       struct sockaddr_in      cliaddr, servaddr;
+       void                            sig_chld(int);
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       Signal(SIGCHLD, sig_chld);
+
+       for ( ; ; ) {
+               clilen = sizeof(cliaddr);
+               if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
+                       if (errno == EINTR)
+                               continue;               /* back to for() */
+                       else
+                               err_sys("accept error");
+               }
+
+               if ( (childpid = Fork()) == 0) {        /* child process */
+                       Close(listenfd);        /* close listening socket */
+                       str_echo(connfd);       /* process the request */
+                       exit(0);
+               }
+               Close(connfd);                  /* parent closes connected socket */
+       }
+}
diff --git a/tcpcliserv/tcpserv04.c b/tcpcliserv/tcpserv04.c
new file mode 100644 (file)
index 0000000..9388cee
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       pid_t                           childpid;
+       socklen_t                       clilen;
+       struct sockaddr_in      cliaddr, servaddr;
+       void                            sig_chld(int);
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       Signal(SIGCHLD, sig_chld);      /* must call waitpid() */
+
+       for ( ; ; ) {
+               clilen = sizeof(cliaddr);
+               if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
+                       if (errno == EINTR)
+                               continue;               /* back to for() */
+                       else
+                               err_sys("accept error");
+               }
+
+               if ( (childpid = Fork()) == 0) {        /* child process */
+                       Close(listenfd);        /* close listening socket */
+                       str_echo(connfd);       /* process the request */
+                       exit(0);
+               }
+               Close(connfd);                  /* parent closes connected socket */
+       }
+}
diff --git a/tcpcliserv/tcpserv04.lc b/tcpcliserv/tcpserv04.lc
new file mode 100644 (file)
index 0000000..eb5ee30
--- /dev/null
@@ -0,0 +1,41 @@
+#include    "unp.h"##  1 ##src/tcpcliserv/tcpserv04.c##
+
+int##  2 ##src/tcpcliserv/tcpserv04.c##
+main(int argc, char **argv)##  3 ##src/tcpcliserv/tcpserv04.c##
+{##  4 ##src/tcpcliserv/tcpserv04.c##
+    int     listenfd, connfd;##  5 ##src/tcpcliserv/tcpserv04.c##
+    pid_t   childpid;##  6 ##src/tcpcliserv/tcpserv04.c##
+    socklen_t clilen;##  7 ##src/tcpcliserv/tcpserv04.c##
+    struct sockaddr_in cliaddr, servaddr;##  8 ##src/tcpcliserv/tcpserv04.c##
+    void    sig_chld(int);##  9 ##src/tcpcliserv/tcpserv04.c##
+
+    listenfd = Socket(AF_INET, SOCK_STREAM, 0);## 10 ##src/tcpcliserv/tcpserv04.c##
+
+    bzero(&servaddr, sizeof(servaddr));## 11 ##src/tcpcliserv/tcpserv04.c##
+    servaddr.sin_family = AF_INET;## 12 ##src/tcpcliserv/tcpserv04.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 13 ##src/tcpcliserv/tcpserv04.c##
+    servaddr.sin_port = htons(SERV_PORT);## 14 ##src/tcpcliserv/tcpserv04.c##
+
+    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 15 ##src/tcpcliserv/tcpserv04.c##
+
+    Listen(listenfd, LISTENQ);## 16 ##src/tcpcliserv/tcpserv04.c##
+
+    Signal(SIGCHLD, sig_chld);  /* must call waitpid() */## 17 ##src/tcpcliserv/tcpserv04.c##
+
+    for (;;) {## 18 ##src/tcpcliserv/tcpserv04.c##
+        clilen = sizeof(cliaddr);## 19 ##src/tcpcliserv/tcpserv04.c##
+        if ((connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {## 20 ##src/tcpcliserv/tcpserv04.c##
+            if (errno == EINTR)## 21 ##src/tcpcliserv/tcpserv04.c##
+                continue;       /* back to for() */## 22 ##src/tcpcliserv/tcpserv04.c##
+            else## 23 ##src/tcpcliserv/tcpserv04.c##
+                err_sys("accept error");## 24 ##src/tcpcliserv/tcpserv04.c##
+        }## 25 ##src/tcpcliserv/tcpserv04.c##
+
+        if ((childpid = Fork()) == 0) { /* child process */## 26 ##src/tcpcliserv/tcpserv04.c##
+            Close(listenfd);    /* close listening socket */## 27 ##src/tcpcliserv/tcpserv04.c##
+            str_echo(connfd);   /* process the request */## 28 ##src/tcpcliserv/tcpserv04.c##
+            exit(0);## 29 ##src/tcpcliserv/tcpserv04.c##
+        }## 30 ##src/tcpcliserv/tcpserv04.c##
+        Close(connfd);          /* parent closes connected socket */## 31 ##src/tcpcliserv/tcpserv04.c##
+    }## 32 ##src/tcpcliserv/tcpserv04.c##
+}## 33 ##src/tcpcliserv/tcpserv04.c##
diff --git a/tcpcliserv/tcpserv08.c b/tcpcliserv/tcpserv08.c
new file mode 100644 (file)
index 0000000..a964276
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       pid_t                           childpid;
+       socklen_t                       clilen;
+       struct sockaddr_in      cliaddr, servaddr;
+       void                            sig_chld(int);
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       Signal(SIGCHLD, sig_chld);
+
+       for ( ; ; ) {
+               clilen = sizeof(cliaddr);
+               if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
+                       if (errno == EINTR)
+                               continue;               /* back to for() */
+                       else
+                               err_sys("accept error");
+               }
+
+               if ( (childpid = Fork()) == 0) {        /* child process */
+                       Close(listenfd);        /* close listening socket */
+                       str_echo(connfd);       /* process the request */
+                       exit(0);
+               }
+               Close(connfd);                  /* parent closes connected socket */
+       }
+}
diff --git a/tcpcliserv/tcpserv09.c b/tcpcliserv/tcpserv09.c
new file mode 100644 (file)
index 0000000..a964276
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       pid_t                           childpid;
+       socklen_t                       clilen;
+       struct sockaddr_in      cliaddr, servaddr;
+       void                            sig_chld(int);
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       Signal(SIGCHLD, sig_chld);
+
+       for ( ; ; ) {
+               clilen = sizeof(cliaddr);
+               if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
+                       if (errno == EINTR)
+                               continue;               /* back to for() */
+                       else
+                               err_sys("accept error");
+               }
+
+               if ( (childpid = Fork()) == 0) {        /* child process */
+                       Close(listenfd);        /* close listening socket */
+                       str_echo(connfd);       /* process the request */
+                       exit(0);
+               }
+               Close(connfd);                  /* parent closes connected socket */
+       }
+}
diff --git a/tcpcliserv/tcpservpoll01.c b/tcpcliserv/tcpservpoll01.c
new file mode 100644 (file)
index 0000000..d874dfc
--- /dev/null
@@ -0,0 +1,91 @@
+/* include fig01 */
+#include       "unp.h"
+#include       <limits.h>              /* for OPEN_MAX */
+
+int
+main(int argc, char **argv)
+{
+       int                                     i, maxi, listenfd, connfd, sockfd;
+       int                                     nready;
+       ssize_t                         n;
+       char                            buf[MAXLINE];
+       socklen_t                       clilen;
+       struct pollfd           client[OPEN_MAX];
+       struct sockaddr_in      cliaddr, servaddr;
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       client[0].fd = listenfd;
+       client[0].events = POLLRDNORM;
+       for (i = 1; i < OPEN_MAX; i++)
+               client[i].fd = -1;              /* -1 indicates available entry */
+       maxi = 0;                                       /* max index into client[] array */
+/* end fig01 */
+
+/* include fig02 */
+       for ( ; ; ) {
+               nready = Poll(client, maxi+1, INFTIM);
+
+               if (client[0].revents & POLLRDNORM) {   /* new client connection */
+                       clilen = sizeof(cliaddr);
+                       connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
+#ifdef NOTDEF
+                       printf("new client: %s\n", Sock_ntop((SA *) &cliaddr, clilen));
+#endif
+
+                       for (i = 1; i < OPEN_MAX; i++)
+                               if (client[i].fd < 0) {
+                                       client[i].fd = connfd;  /* save descriptor */
+                                       break;
+                               }
+                       if (i == OPEN_MAX)
+                               err_quit("too many clients");
+
+                       client[i].events = POLLRDNORM;
+                       if (i > maxi)
+                               maxi = i;                               /* max index in client[] array */
+
+                       if (--nready <= 0)
+                               continue;                               /* no more readable descriptors */
+               }
+
+               for (i = 1; i <= maxi; i++) {   /* check all clients for data */
+                       if ( (sockfd = client[i].fd) < 0)
+                               continue;
+                       if (client[i].revents & (POLLRDNORM | POLLERR)) {
+                               if ( (n = read(sockfd, buf, MAXLINE)) < 0) {
+                                       if (errno == ECONNRESET) {
+                                                       /*4connection reset by client */
+#ifdef NOTDEF
+                                               printf("client[%d] aborted connection\n", i);
+#endif
+                                               Close(sockfd);
+                                               client[i].fd = -1;
+                                       } else
+                                               err_sys("read error");
+                               } else if (n == 0) {
+                                               /*4connection closed by client */
+#ifdef NOTDEF
+                                       printf("client[%d] closed connection\n", i);
+#endif
+                                       Close(sockfd);
+                                       client[i].fd = -1;
+                               } else
+                                       Writen(sockfd, buf, n);
+
+                               if (--nready <= 0)
+                                       break;                          /* no more readable descriptors */
+                       }
+               }
+       }
+}
+/* end fig02 */
diff --git a/tcpcliserv/tcpservpoll01.lc b/tcpcliserv/tcpservpoll01.lc
new file mode 100644 (file)
index 0000000..3cc99ad
--- /dev/null
@@ -0,0 +1,82 @@
+/* include fig01 */
+#include    "unp.h"##  1 ##src/tcpcliserv/tcpservpoll01.c##
+#include    <limits.h>          /* for OPEN_MAX */##  2 ##src/tcpcliserv/tcpservpoll01.c##
+
+int##  3 ##src/tcpcliserv/tcpservpoll01.c##
+main(int argc, char **argv)##  4 ##src/tcpcliserv/tcpservpoll01.c##
+{##  5 ##src/tcpcliserv/tcpservpoll01.c##
+    int     i, maxi, listenfd, connfd, sockfd;##  6 ##src/tcpcliserv/tcpservpoll01.c##
+    int     nready;##  7 ##src/tcpcliserv/tcpservpoll01.c##
+    ssize_t n;##  8 ##src/tcpcliserv/tcpservpoll01.c##
+    char    line[MAXLINE];##  9 ##src/tcpcliserv/tcpservpoll01.c##
+    socklen_t clilen;## 10 ##src/tcpcliserv/tcpservpoll01.c##
+    struct pollfd client[OPEN_MAX];## 11 ##src/tcpcliserv/tcpservpoll01.c##
+    struct sockaddr_in cliaddr, servaddr;## 12 ##src/tcpcliserv/tcpservpoll01.c##
+
+    listenfd = Socket(AF_INET, SOCK_STREAM, 0);## 13 ##src/tcpcliserv/tcpservpoll01.c##
+
+    bzero(&servaddr, sizeof(servaddr));## 14 ##src/tcpcliserv/tcpservpoll01.c##
+    servaddr.sin_family = AF_INET;## 15 ##src/tcpcliserv/tcpservpoll01.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 16 ##src/tcpcliserv/tcpservpoll01.c##
+    servaddr.sin_port = htons(SERV_PORT);## 17 ##src/tcpcliserv/tcpservpoll01.c##
+
+    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 18 ##src/tcpcliserv/tcpservpoll01.c##
+
+    Listen(listenfd, LISTENQ);## 19 ##src/tcpcliserv/tcpservpoll01.c##
+
+    client[0].fd = listenfd;## 20 ##src/tcpcliserv/tcpservpoll01.c##
+    client[0].events = POLLRDNORM;## 21 ##src/tcpcliserv/tcpservpoll01.c##
+    for (i = 1; i < OPEN_MAX; i++)## 22 ##src/tcpcliserv/tcpservpoll01.c##
+        client[i].fd = -1;      /* -1 indicates available entry */## 23 ##src/tcpcliserv/tcpservpoll01.c##
+    maxi = 0;                   /* max index into client[] array */## 24 ##src/tcpcliserv/tcpservpoll01.c##
+/* end fig01 */
+
+/* include fig02 */
+    for (;;) {## 25 ##src/tcpcliserv/tcpservpoll01.c##
+        nready = Poll(client, maxi + 1, INFTIM);## 26 ##src/tcpcliserv/tcpservpoll01.c##
+
+        if (client[0].revents & POLLRDNORM) {   /* new client connection */## 27 ##src/tcpcliserv/tcpservpoll01.c##
+            clilen = sizeof(cliaddr);## 28 ##src/tcpcliserv/tcpservpoll01.c##
+            connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);## 29 ##src/tcpcliserv/tcpservpoll01.c##
+
+            for (i = 1; i < OPEN_MAX; i++)## 30 ##src/tcpcliserv/tcpservpoll01.c##
+                if (client[i].fd < 0) {## 31 ##src/tcpcliserv/tcpservpoll01.c##
+                    client[i].fd = connfd;  /* save descriptor */## 32 ##src/tcpcliserv/tcpservpoll01.c##
+                    break;## 33 ##src/tcpcliserv/tcpservpoll01.c##
+                }## 34 ##src/tcpcliserv/tcpservpoll01.c##
+            if (i == OPEN_MAX)## 35 ##src/tcpcliserv/tcpservpoll01.c##
+                err_quit("too many clients");## 36 ##src/tcpcliserv/tcpservpoll01.c##
+
+            client[i].events = POLLRDNORM;## 37 ##src/tcpcliserv/tcpservpoll01.c##
+            if (i > maxi)## 38 ##src/tcpcliserv/tcpservpoll01.c##
+                maxi = i;       /* max index in client[] array */## 39 ##src/tcpcliserv/tcpservpoll01.c##
+
+            if (--nready <= 0)## 40 ##src/tcpcliserv/tcpservpoll01.c##
+                continue;       /* no more readable descriptors */## 41 ##src/tcpcliserv/tcpservpoll01.c##
+        }## 42 ##src/tcpcliserv/tcpservpoll01.c##
+
+        for (i = 1; i <= maxi; i++) {   /* check all clients for data */## 43 ##src/tcpcliserv/tcpservpoll01.c##
+            if ((sockfd = client[i].fd) < 0)## 44 ##src/tcpcliserv/tcpservpoll01.c##
+                continue;## 45 ##src/tcpcliserv/tcpservpoll01.c##
+            if (client[i].revents & (POLLRDNORM | POLLERR)) {## 46 ##src/tcpcliserv/tcpservpoll01.c##
+                if ((n = readline(sockfd, line, MAXLINE)) < 0) {## 47 ##src/tcpcliserv/tcpservpoll01.c##
+                    if (errno == ECONNRESET) {## 48 ##src/tcpcliserv/tcpservpoll01.c##
+                        /* 4connection reset by client */## 49 ##src/tcpcliserv/tcpservpoll01.c##
+                        Close(sockfd);## 50 ##src/tcpcliserv/tcpservpoll01.c##
+                        client[i].fd = -1;## 51 ##src/tcpcliserv/tcpservpoll01.c##
+                    } else## 52 ##src/tcpcliserv/tcpservpoll01.c##
+                        err_sys("readline error");## 53 ##src/tcpcliserv/tcpservpoll01.c##
+                } else if (n == 0) {## 54 ##src/tcpcliserv/tcpservpoll01.c##
+                    /* 4connection closed by client */## 55 ##src/tcpcliserv/tcpservpoll01.c##
+                    Close(sockfd);## 56 ##src/tcpcliserv/tcpservpoll01.c##
+                    client[i].fd = -1;## 57 ##src/tcpcliserv/tcpservpoll01.c##
+                } else## 58 ##src/tcpcliserv/tcpservpoll01.c##
+                    Writen(sockfd, line, n);## 59 ##src/tcpcliserv/tcpservpoll01.c##
+
+                if (--nready <= 0)## 60 ##src/tcpcliserv/tcpservpoll01.c##
+                    break;      /* no more readable descriptors */## 61 ##src/tcpcliserv/tcpservpoll01.c##
+            }## 62 ##src/tcpcliserv/tcpservpoll01.c##
+        }## 63 ##src/tcpcliserv/tcpservpoll01.c##
+    }## 64 ##src/tcpcliserv/tcpservpoll01.c##
+}## 65 ##src/tcpcliserv/tcpservpoll01.c##
+/* end fig02 */
diff --git a/tcpcliserv/tcpservselect01.c b/tcpcliserv/tcpservselect01.c
new file mode 100644 (file)
index 0000000..0aba1b4
--- /dev/null
@@ -0,0 +1,84 @@
+/* include fig01 */
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     i, maxi, maxfd, listenfd, connfd, sockfd;
+       int                                     nready, client[FD_SETSIZE];
+       ssize_t                         n;
+       fd_set                          rset, allset;
+       char                            buf[MAXLINE];
+       socklen_t                       clilen;
+       struct sockaddr_in      cliaddr, servaddr;
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       maxfd = listenfd;                       /* initialize */
+       maxi = -1;                                      /* index into client[] array */
+       for (i = 0; i < FD_SETSIZE; i++)
+               client[i] = -1;                 /* -1 indicates available entry */
+       FD_ZERO(&allset);
+       FD_SET(listenfd, &allset);
+/* end fig01 */
+
+/* include fig02 */
+       for ( ; ; ) {
+               rset = allset;          /* structure assignment */
+               nready = Select(maxfd+1, &rset, NULL, NULL, NULL);
+
+               if (FD_ISSET(listenfd, &rset)) {        /* new client connection */
+                       clilen = sizeof(cliaddr);
+                       connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
+#ifdef NOTDEF
+                       printf("new client: %s, port %d\n",
+                                       Inet_ntop(AF_INET, &cliaddr.sin_addr, 4, NULL),
+                                       ntohs(cliaddr.sin_port));
+#endif
+
+                       for (i = 0; i < FD_SETSIZE; i++)
+                               if (client[i] < 0) {
+                                       client[i] = connfd;     /* save descriptor */
+                                       break;
+                               }
+                       if (i == FD_SETSIZE)
+                               err_quit("too many clients");
+
+                       FD_SET(connfd, &allset);        /* add new descriptor to set */
+                       if (connfd > maxfd)
+                               maxfd = connfd;                 /* for select */
+                       if (i > maxi)
+                               maxi = i;                               /* max index in client[] array */
+
+                       if (--nready <= 0)
+                               continue;                               /* no more readable descriptors */
+               }
+
+               for (i = 0; i <= maxi; i++) {   /* check all clients for data */
+                       if ( (sockfd = client[i]) < 0)
+                               continue;
+                       if (FD_ISSET(sockfd, &rset)) {
+                               if ( (n = Read(sockfd, buf, MAXLINE)) == 0) {
+                                               /*4connection closed by client */
+                                       Close(sockfd);
+                                       FD_CLR(sockfd, &allset);
+                                       client[i] = -1;
+                               } else
+                                       Writen(sockfd, buf, n);
+
+                               if (--nready <= 0)
+                                       break;                          /* no more readable descriptors */
+                       }
+               }
+       }
+}
+/* end fig02 */
diff --git a/tcpcliserv/tcpservselect01.lc b/tcpcliserv/tcpservselect01.lc
new file mode 100644 (file)
index 0000000..7b2fdcf
--- /dev/null
@@ -0,0 +1,79 @@
+/* include fig01 */
+#include    "unp.h"##  1 ##src/tcpcliserv/tcpservselect01.c##
+
+int##  2 ##src/tcpcliserv/tcpservselect01.c##
+main(int argc, char **argv)##  3 ##src/tcpcliserv/tcpservselect01.c##
+{##  4 ##src/tcpcliserv/tcpservselect01.c##
+    int     i, maxi, maxfd, listenfd, connfd, sockfd;##  5 ##src/tcpcliserv/tcpservselect01.c##
+    int     nready, client[FD_SETSIZE];##  6 ##src/tcpcliserv/tcpservselect01.c##
+    ssize_t n;##  7 ##src/tcpcliserv/tcpservselect01.c##
+    fd_set  rset, allset;##  8 ##src/tcpcliserv/tcpservselect01.c##
+    char    line[MAXLINE];##  9 ##src/tcpcliserv/tcpservselect01.c##
+    socklen_t clilen;## 10 ##src/tcpcliserv/tcpservselect01.c##
+    struct sockaddr_in cliaddr, servaddr;## 11 ##src/tcpcliserv/tcpservselect01.c##
+
+    listenfd = Socket(AF_INET, SOCK_STREAM, 0);## 12 ##src/tcpcliserv/tcpservselect01.c##
+
+    bzero(&servaddr, sizeof(servaddr));## 13 ##src/tcpcliserv/tcpservselect01.c##
+    servaddr.sin_family = AF_INET;## 14 ##src/tcpcliserv/tcpservselect01.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 15 ##src/tcpcliserv/tcpservselect01.c##
+    servaddr.sin_port = htons(SERV_PORT);## 16 ##src/tcpcliserv/tcpservselect01.c##
+
+    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 17 ##src/tcpcliserv/tcpservselect01.c##
+
+    Listen(listenfd, LISTENQ);## 18 ##src/tcpcliserv/tcpservselect01.c##
+
+    maxfd = listenfd;           /* initialize */## 19 ##src/tcpcliserv/tcpservselect01.c##
+    maxi = -1;                  /* index into client[] array */## 20 ##src/tcpcliserv/tcpservselect01.c##
+    for (i = 0; i < FD_SETSIZE; i++)## 21 ##src/tcpcliserv/tcpservselect01.c##
+        client[i] = -1;         /* -1 indicates available entry */## 22 ##src/tcpcliserv/tcpservselect01.c##
+    FD_ZERO(&allset);## 23 ##src/tcpcliserv/tcpservselect01.c##
+    FD_SET(listenfd, &allset);## 24 ##src/tcpcliserv/tcpservselect01.c##
+/* end fig01 */
+
+/* include fig02 */
+    for (;;) {## 25 ##src/tcpcliserv/tcpservselect01.c##
+        rset = allset;          /* structure assignment */## 26 ##src/tcpcliserv/tcpservselect01.c##
+        nready = Select(maxfd + 1, &rset, NULL, NULL, NULL);## 27 ##src/tcpcliserv/tcpservselect01.c##
+
+        if (FD_ISSET(listenfd, &rset)) {    /* new client connection */## 28 ##src/tcpcliserv/tcpservselect01.c##
+            clilen = sizeof(cliaddr);## 29 ##src/tcpcliserv/tcpservselect01.c##
+            connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);## 30 ##src/tcpcliserv/tcpservselect01.c##
+
+            for (i = 0; i < FD_SETSIZE; i++)## 31 ##src/tcpcliserv/tcpservselect01.c##
+                if (client[i] < 0) {## 32 ##src/tcpcliserv/tcpservselect01.c##
+                    client[i] = connfd; /* save descriptor */## 33 ##src/tcpcliserv/tcpservselect01.c##
+                    break;## 34 ##src/tcpcliserv/tcpservselect01.c##
+                }## 35 ##src/tcpcliserv/tcpservselect01.c##
+            if (i == FD_SETSIZE)## 36 ##src/tcpcliserv/tcpservselect01.c##
+                err_quit("too many clients");## 37 ##src/tcpcliserv/tcpservselect01.c##
+
+            FD_SET(connfd, &allset);    /* add new descriptor to set */## 38 ##src/tcpcliserv/tcpservselect01.c##
+            if (connfd > maxfd)## 39 ##src/tcpcliserv/tcpservselect01.c##
+                maxfd = connfd; /* for select */## 40 ##src/tcpcliserv/tcpservselect01.c##
+            if (i > maxi)## 41 ##src/tcpcliserv/tcpservselect01.c##
+                maxi = i;       /* max index in client[] array */## 42 ##src/tcpcliserv/tcpservselect01.c##
+
+            if (--nready <= 0)## 43 ##src/tcpcliserv/tcpservselect01.c##
+                continue;       /* no more readable descriptors */## 44 ##src/tcpcliserv/tcpservselect01.c##
+        }## 45 ##src/tcpcliserv/tcpservselect01.c##
+
+        for (i = 0; i <= maxi; i++) {   /* check all clients for data */## 46 ##src/tcpcliserv/tcpservselect01.c##
+            if ((sockfd = client[i]) < 0)## 47 ##src/tcpcliserv/tcpservselect01.c##
+                continue;## 48 ##src/tcpcliserv/tcpservselect01.c##
+            if (FD_ISSET(sockfd, &rset)) {## 49 ##src/tcpcliserv/tcpservselect01.c##
+                if ((n = Readline(sockfd, line, MAXLINE)) == 0) {## 50 ##src/tcpcliserv/tcpservselect01.c##
+                    /* 4connection closed by client */## 51 ##src/tcpcliserv/tcpservselect01.c##
+                    Close(sockfd);## 52 ##src/tcpcliserv/tcpservselect01.c##
+                    FD_CLR(sockfd, &allset);## 53 ##src/tcpcliserv/tcpservselect01.c##
+                    client[i] = -1;## 54 ##src/tcpcliserv/tcpservselect01.c##
+                } else## 55 ##src/tcpcliserv/tcpservselect01.c##
+                    Writen(sockfd, line, n);## 56 ##src/tcpcliserv/tcpservselect01.c##
+
+                if (--nready <= 0)## 57 ##src/tcpcliserv/tcpservselect01.c##
+                    break;      /* no more readable descriptors */## 58 ##src/tcpcliserv/tcpservselect01.c##
+            }## 59 ##src/tcpcliserv/tcpservselect01.c##
+        }## 60 ##src/tcpcliserv/tcpservselect01.c##
+    }## 61 ##src/tcpcliserv/tcpservselect01.c##
+}## 62 ##src/tcpcliserv/tcpservselect01.c##
+/* end fig02 */
diff --git a/tcpcliserv/tsigpipe.c b/tcpcliserv/tsigpipe.c
new file mode 100644 (file)
index 0000000..f4656d8
--- /dev/null
@@ -0,0 +1,36 @@
+#include       "unp.h"
+
+void
+sig_pipe(int signo)
+{
+       printf("SIGPIPE received\n");
+       return;
+}
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: tcpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(13);          /* daytime server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Signal(SIGPIPE, sig_pipe);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       sleep(2);
+       Write(sockfd, "hello", 5);
+       sleep(2);
+       Write(sockfd, "world", 5);
+
+       exit(0);
+}
diff --git a/test/Makefile b/test/Makefile
new file mode 100644 (file)
index 0000000..8b77a58
--- /dev/null
@@ -0,0 +1,38 @@
+include ../Make.defines
+
+PROGS =        accept_eintr test1 treadline1 treadline2 treadline3 \
+               tsnprintf tisfdtype tshutdown
+
+TEST1_OBJS = test1.o funcs.o
+
+all:   ${PROGS}
+
+test1: ${TEST1_OBJS}
+               ${CC} ${CFLAGS} -o $@ ${TEST1_OBJS} ${LIBS}
+
+test2: test2.o
+               ${CC} ${CFLAGS} -o $@ test2.o ${LIBS}
+
+accept_eintr:  accept_eintr.o
+               ${CC} ${CFLAGS} -o $@ accept_eintr.o ${LIBS}
+
+treadline1:    treadline1.o readline1.o
+               ${CC} ${CFLAGS} -o $@ treadline1.o readline1.o ${LIBS}
+
+treadline2:    treadline2.o readline2.o
+               ${CC} ${CFLAGS} -o $@ treadline2.o readline2.o ${LIBS}
+
+treadline3:    treadline3.o readline3.o
+               ${CC} ${CFLAGS} -o $@ treadline3.o readline3.o ${LIBS}
+
+tsnprintf:     tsnprintf.o
+               ${CC} ${CFLAGS} -o $@ tsnprintf.o ${LIBS}
+
+tisfdtype:     tisfdtype.o
+               ${CC} ${CFLAGS} -o $@ tisfdtype.o ${LIBS}
+
+tshutdown:     tshutdown.o
+               ${CC} ${CFLAGS} -o $@ tshutdown.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} core core.* *.o temp.* *.out typescript*
diff --git a/test/accept_eintr.c b/test/accept_eintr.c
new file mode 100644 (file)
index 0000000..af550d2
--- /dev/null
@@ -0,0 +1,37 @@
+#include       "unp.h"
+
+/* Let's see if accept() is automatically restarted by the implementation. */
+
+void
+sig_int(int signo)
+{
+       printf("received SIGINT\n");
+       return;
+}
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       socklen_t                       clilen;
+       struct sockaddr_in      cliaddr, servaddr;
+
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       Signal(SIGINT, sig_int);        /* sets SA_RESTART */
+
+       for ( ; ; ) {
+               clilen = sizeof(cliaddr);
+               connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
+                       /* error from Accept() if not restarted */
+       }
+}
diff --git a/test/funcs.c b/test/funcs.c
new file mode 100644 (file)
index 0000000..8dff9cf
--- /dev/null
@@ -0,0 +1,63 @@
+#include       "test.h"
+
+/*
+ * Fill in the global servaddr{} as a side effect.
+ */
+
+int
+TcpSockByAddr(char *ipaddr, int port /* host byte order */ )
+{
+       int                                     sockfd;
+
+       sockfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(port);
+       Inet_pton(AF_INET, ipaddr, &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       return(sockfd);
+}
+
+/*
+ * Create the default (unconnected) UDP socket.
+ * Fill in the global servaddr{} for the caller to use.
+ */
+
+int
+UdpSockByAddr(char *ipaddr, int port /* host byte order */ )
+{
+       int                                     sockfd;
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(port);
+       Inet_pton(AF_INET, ipaddr, &servaddr.sin_addr);
+
+       return(sockfd);
+}
+
+/*
+ * Create a connected UDP socket.
+ */
+
+int
+UdpConnSockByAddr(char *ipaddr, int port /* host byte order */ )
+{
+       int                                     sockfd;
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(port);
+       Inet_pton(AF_INET, ipaddr, &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       return(sockfd);
+}
diff --git a/test/readline.h b/test/readline.h
new file mode 100644 (file)
index 0000000..badf6cf
--- /dev/null
@@ -0,0 +1,12 @@
+typedef struct {
+  int          read_fd;                /* caller's descriptor to read from */
+  char         *read_ptr;              /* caller's buffer to read into */
+  size_t       read_maxlen;    /* max #bytes to read */
+                               /* next three are used internally by the function */
+  int          rl_cnt;                 /* initialize to 0 */
+  char         *rl_bufptr;             /* initialize to rl_buf */
+  char         rl_buf[MAXLINE];
+} Rline;
+
+void   readline_rinit(int, void *, size_t, Rline *);
+ssize_t        readline_r(Rline *);
diff --git a/test/readline1.c b/test/readline1.c
new file mode 100644 (file)
index 0000000..f264639
--- /dev/null
@@ -0,0 +1,41 @@
+/* include readline */
+#include       "unp.h"
+
+/* PAINFULLY SLOW VERSION -- example only */
+ssize_t
+readline(int fd, void *vptr, size_t maxlen)
+{
+       ssize_t n, rc;
+       char    c, *ptr;
+
+       ptr = vptr;
+       for (n = 1; n < maxlen; n++) {
+again:
+               if ( (rc = read(fd, &c, 1)) == 1) {
+                       *ptr++ = c;
+                       if (c == '\n')
+                               break;  /* newline is stored, like fgets() */
+               } else if (rc == 0) {
+                       *ptr = 0;
+                       return(n - 1);  /* EOF, n - 1 bytes were read */
+               } else {
+                       if (errno == EINTR)
+                               goto again;
+                       return(-1);             /* error, errno set by read() */
+               }
+       }
+
+       *ptr = 0;       /* null terminate like fgets() */
+       return(n);
+}
+/* end readline */
+
+ssize_t
+Readline(int fd, void *ptr, size_t maxlen)
+{
+       ssize_t         n;
+
+       if ( (n = readline(fd, ptr, maxlen)) < 0)
+               err_sys("readline error");
+       return(n);
+}
diff --git a/test/readline1.lc b/test/readline1.lc
new file mode 100644 (file)
index 0000000..a12ac08
--- /dev/null
@@ -0,0 +1,42 @@
+/* include readline */
+#include    "unp.h"##  1 ##src/test/readline1.c##
+
+ssize_t##  2 ##src/test/readline1.c##
+readline(int fd, void *vptr, size_t maxlen)##  3 ##src/test/readline1.c##
+{##  4 ##src/test/readline1.c##
+    ssize_t n, rc;##  5 ##src/test/readline1.c##
+    char    c, *ptr;##  6 ##src/test/readline1.c##
+
+    ptr = vptr;##  7 ##src/test/readline1.c##
+    for (n = 1; n < maxlen; n++) {##  8 ##src/test/readline1.c##
+      again:##  9 ##src/test/readline1.c##
+        if ((rc = read(fd, &c, 1)) == 1) {## 10 ##src/test/readline1.c##
+            *ptr++ = c;## 11 ##src/test/readline1.c##
+            if (c == '\n')## 12 ##src/test/readline1.c##
+                break;          /* newline is stored, like fgets() */## 13 ##src/test/readline1.c##
+        } else if (rc == 0) {## 14 ##src/test/readline1.c##
+            if (n == 1)## 15 ##src/test/readline1.c##
+                return (0);     /* EOF, no data read */## 16 ##src/test/readline1.c##
+            else## 17 ##src/test/readline1.c##
+                break;          /* EOF, some data was read */## 18 ##src/test/readline1.c##
+        } else {## 19 ##src/test/readline1.c##
+            if (errno == EINTR)## 20 ##src/test/readline1.c##
+                goto again;## 21 ##src/test/readline1.c##
+            return (-1);        /* error, errno set by read() */## 22 ##src/test/readline1.c##
+        }## 23 ##src/test/readline1.c##
+    }## 24 ##src/test/readline1.c##
+
+    *ptr = 0;                   /* null terminate like fgets() */## 25 ##src/test/readline1.c##
+    return (n);## 26 ##src/test/readline1.c##
+}## 27 ##src/test/readline1.c##
+/* end readline */
+
+ssize_t## 28 ##src/test/readline1.c##
+Readline(int fd, void *ptr, size_t maxlen)## 29 ##src/test/readline1.c##
+{## 30 ##src/test/readline1.c##
+    ssize_t n;## 31 ##src/test/readline1.c##
+
+    if ((n = readline(fd, ptr, maxlen)) < 0)## 32 ##src/test/readline1.c##
+        err_sys("readline error");## 33 ##src/test/readline1.c##
+    return (n);## 34 ##src/test/readline1.c##
+}## 35 ##src/test/readline1.c##
diff --git a/test/readline2.c b/test/readline2.c
new file mode 100644 (file)
index 0000000..a8de93b
--- /dev/null
@@ -0,0 +1,56 @@
+/* include readline */
+#include       "unp.h"
+
+static ssize_t
+my_read(int fd, char *ptr)
+{
+       static int      read_cnt = 0;
+       static char     *read_ptr;
+       static char     read_buf[MAXLINE];
+
+       if (read_cnt <= 0) {
+               if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0)
+                       err_sys("read error");
+               else if (read_cnt == 0)
+                       return(0);
+               read_ptr = read_buf;
+       }
+
+       read_cnt--;
+       *ptr = *read_ptr++ & 255;
+       return(1);
+}
+
+ssize_t
+readline(int fd, void *vptr, size_t maxlen)
+{
+       int             n, rc;
+       char    c, *ptr;
+
+       ptr = vptr;
+       for (n = 1; n < maxlen; n++) {
+               if ( (rc = my_read(fd, &c)) == 1) {
+                       *ptr++ = c;
+                       if (c == '\n')
+                               break;
+               } else if (rc == 0) {
+                       *ptr = 0;
+                       return(n - 1);  /* EOF, n - 1 bytes were read */
+               } else
+                       return(-1);     /* error */
+       }
+
+       *ptr = 0;
+       return(n);
+}
+/* end readline */
+
+ssize_t
+Readline(int fd, void *ptr, size_t maxlen)
+{
+       ssize_t         n;
+
+       if ( (n = readline(fd, ptr, maxlen)) == -1)
+               err_sys("readline error");
+       return(n);
+}
diff --git a/test/readline3.c b/test/readline3.c
new file mode 100644 (file)
index 0000000..4b8f8bb
--- /dev/null
@@ -0,0 +1,70 @@
+/* include readline */
+#include       "unp.h"
+#include       "readline.h"
+
+static ssize_t
+my_read(Rline *rptr, char *ptr)
+{
+       if (rptr->rl_cnt <= 0) {
+again:
+               rptr->rl_cnt = read(rptr->read_fd, rptr->rl_buf, sizeof(rptr->rl_buf));
+               if (rptr->rl_cnt < 0) {
+                       if (errno == EINTR)
+                               goto again;
+                       else
+                               return(-1);
+               }
+               else if (rptr->rl_cnt == 0)
+                       return(0);
+               rptr->rl_bufptr = rptr->rl_buf;
+       }
+
+       rptr->rl_cnt--;
+       *ptr = *rptr->rl_bufptr++ & 255;
+       return(1);
+}
+
+void
+readline_rinit(int fd, void *ptr, size_t maxlen, Rline *rptr)
+{
+       rptr->read_fd = fd;                             /* save caller's arguments */
+       rptr->read_ptr = ptr;
+       rptr->read_maxlen = maxlen;
+
+       rptr->rl_cnt = 0;                               /* and init our counter & pointer */
+       rptr->rl_bufptr = rptr->rl_buf;
+}
+
+ssize_t
+readline_r(Rline *rptr)
+{
+       int             n, rc;
+       char    c, *ptr;
+
+       ptr = rptr->read_ptr;
+       for (n = 1; n < rptr->read_maxlen; n++) {
+               if ( (rc = my_read(rptr, &c)) == 1) {
+                       *ptr++ = c;
+                       if (c == '\n')
+                               break;
+               } else if (rc == 0) {
+                       *ptr = 0;
+                       return(n - 1);  /* EOF, n - 1 bytes were read */
+               } else
+                       return(-1);     /* error */
+       }
+
+       *ptr = 0;
+       return(n);
+}
+/* end readline */
+
+ssize_t
+Readline(int fd, void *ptr, size_t maxlen)
+{
+       ssize_t         n;
+
+       if ( (n = readline(fd, ptr, maxlen)) == -1)
+               err_sys("readline error");
+       return(n);
+}
diff --git a/test/test.h b/test/test.h
new file mode 100644 (file)
index 0000000..911eff0
--- /dev/null
@@ -0,0 +1,10 @@
+#include       "unp.h"
+
+       /* globals */
+extern struct sockaddr_in      servaddr, cliaddr;
+extern char            buff[8192];
+extern int             verbose;
+
+int            TcpSockByAddr(char *, int);
+int            UdpSockByAddr(char *, int);
+int            UdpConnSockByAddr(char *, int);
diff --git a/test/test1.c b/test/test1.c
new file mode 100644 (file)
index 0000000..6b671f5
--- /dev/null
@@ -0,0 +1,206 @@
+#include       "test.h"
+
+/*
+ * Socket test program.
+ * Try and figure out everything that we can automatically.
+ * Lines preceded by a + are deviations from 4.4BSD.
+ * Lines preceded by a ! are fatal errors.
+ * Lines without a + or ! are just informational.
+ */
+
+       /* allocate globals */
+struct sockaddr_in     servaddr, cliaddr;
+char   buff[8192];
+int            verbose;
+
+/*
+ * Check whether various header flags are defined.
+ */
+
+void
+header_flags()
+{
+
+                       /* these are all "if not defined" */
+#ifndef        MSG_DONTROUTE
+       printf("+ MSG_DONTROUTE not defined\n");
+#endif
+
+#ifndef        MSG_OOB
+       printf("+ MSG_OOB not defined\n");
+#endif
+
+#ifndef        MSG_PEEK
+       printf("+ MSG_PEEK not defined\n");
+#endif
+
+#ifndef        MSG_WAITALL
+       printf("+ MSG_WAITALL not defined\n");
+#endif
+}
+
+/*
+ * Check whether we can use sendto() and recvfrom() with a TCP socket.
+ * Use a different length for each output function, so if it does work,
+ * we can see it with tcpdump and separate it from the other outputs.
+ */
+
+void
+sendto_01()
+{
+       int             sockfd, n;
+       socklen_t       len;
+
+       sockfd = TcpSockByAddr("140.252.13.34", 7);             /* echo server */
+
+       /*
+        * This also verifies that we can call sendto() on a TCP socket
+        * if we don't specify a destination address.
+        */
+
+       Sendto(sockfd, "hello", 5, 0, NULL, NULL);
+
+       if ( (n = Recvfrom(sockfd, buff, sizeof(buff), 0, NULL, NULL)) != 5)
+               err_quit("! Recvfrom expected 5");
+
+       /*
+        * Now see what happens when we ask for the server's address.
+        * Berkeley-derived implementations do not return this (p. 517, tcpipiv2)
+        * while Solaris does.
+        */
+
+       Sendto(sockfd, "world", 5, 0, NULL, NULL);
+
+       len = sizeof(servaddr) * 2;     /* that's a lie */
+       if ( (n = Recvfrom(sockfd, buff, sizeof(buff), 0,
+                                          (SA *) &servaddr, &len)) != 5)
+               err_quit("! Recvfrom expected 5");
+       if (len != 0) {
+               err_msg("+ recvfrom on TCP socket returns len = %d for sender's addr",
+                               len);
+               if (len == sizeof(servaddr))
+                       printf("  recvfrom from %s, port %d\n",
+                                  inet_ntoa(servaddr.sin_addr), ntohs(servaddr.sin_port));
+       }
+
+       Close(sockfd);
+
+       /*
+        * Now try and specify a destination address for sendto() on
+        * a TCP socket.
+        */
+
+       sockfd = TcpSockByAddr("140.252.13.34", 7);             /* echo server */
+
+               /* should not work with destination address specified */
+       n = sendto(sockfd, "hello1", 6, 0, (SA *) &servaddr, sizeof(servaddr));
+       if (n < 0)
+               err_ret("sendto on TCP socket specifying dest addr returns error");
+       else if (n == 6)
+#ifdef MSG_EOF         /* defined only if T/TCP supported */
+               err_msg("+ sendto on TCP socket specifying dest addr OK (T/TCP supported)");
+#else
+               err_msg("+ sendto on TCP socket specifying dest addr OK");
+#endif
+       else
+               err_quit("! sendto on TCP socket specifying dest addr, n = %d", n);
+
+       Close(sockfd);
+
+       /*
+        * Now an unconnected UDP socket.
+        */
+
+       sockfd = UdpSockByAddr("140.252.13.34", 7);             /* echo server */
+
+               /* should not work */
+       if ( (n = sendto(sockfd, "hello12", 7, 0, (SA *) 0, 0)) >= 0)
+               err_msg("+ sendto on unconnected UDP without dest addr OK, n = %d", n);
+       else if (errno != EDESTADDRREQ)
+               err_ret("+ sendto on unconnected UDP without dest addr, unexpected errno");
+
+               /* should not work */
+       if ( (n = write(sockfd, "hello", 7)) >= 0)
+               err_msg("+ write on unconnected UDP OK, n = %d", n);
+       else if (errno != EDESTADDRREQ)
+               err_ret("+ write on unconnected UDP, unexpected errno");
+
+       Close(sockfd);
+
+       /*
+        * Now a connected UDP socket.
+        */
+
+       sockfd = UdpConnSockByAddr("140.252.13.34", 7);         /* echo server */
+
+               /* should work */
+       if ( (n = write(sockfd, "hello123", 8)) < 0)
+               err_sys("! write on connected UDP, n = %d", n);
+       else if (n != 8)
+               err_quit("! write on connected UDP, n = %d", n);
+
+               /* should work */
+       if ( (n = sendto(sockfd, "hello1234", 9, 0, (SA *) 0, 0)) < 0)
+               err_sys("! sendto on connected UDP without dest addr, n = %d", n);
+       else if (n != 9)
+               err_quit("! sendto on connected UDP without dest addr, n = %d", n);
+
+               /* should not work */
+       n = sendto(sockfd, "hello12345", 10, 0, (SA *) &servaddr, sizeof(servaddr));
+       if (n < 0 && errno != EISCONN)
+               err_ret("+ sendto on connected UDP with dest addr, unexpected errno");
+       else if (n >= 0)
+               err_msg("+ sendto on connected UDP with dest addr OK, n = %d", n);
+
+       Close(sockfd);
+}
+
+/*
+ * Send a UDP datagram to a server at IP address 1, and look at
+ * the return address in the response.  If the server is multihomed,
+ * the return address can differ from our original destination address.
+ */
+
+void
+udp_01()
+{
+}
+
+static void
+usage(const char *msg)
+{
+       err_msg(
+"options: -v    verbose\n"
+);
+
+       if (msg[0] != 0)
+               err_quit("%s", msg);
+       exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+       int             c;
+
+       opterr = 0;             /* don't want getopt() writing to stderr */
+       while ( (c = getopt(argc, argv, "v")) != -1) {
+               switch (c) {
+               case 'v':
+                       verbose = 1;
+                       break;
+
+               case '?':
+                       usage("unrecognized option");
+               }
+       }
+
+       if (verbose) printf("header_flags\n");
+       header_flags();
+
+       if (verbose) printf("udp_01\n");
+       udp_01();
+
+       if (verbose) printf("sendto_01\n");
+       sendto_01();
+}
diff --git a/test/test2.c b/test/test2.c
new file mode 100644 (file)
index 0000000..9fbc122
--- /dev/null
@@ -0,0 +1,65 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                             sockfd;
+       socklen_t               salen;
+       struct addrinfo *res;
+       struct sockaddr *cli, *serv;
+
+       if (argc != 2)
+               err_quit("usage: test2 <IPaddress>");
+
+#ifdef notdef
+       res = Host_serv(argv[1], "daytime", AF_UNSPEC, SOCK_DGRAM);
+       printf("res->ai_addrlen = %d\n", res->ai_addrlen);
+       printf("res->ai_addr = %p\n", res->ai_addr);
+       printf("res->ai_next = %p\n", res->ai_next);
+       printf("res->ai_addr->sa_family = %p\n", res->ai_addr->sa_family);
+#endif
+       sockfd = Udp_client(argv[1], "13", (void **) &serv, &salen);
+       printf("sockfd = %d\n", sockfd);
+
+       exit(0);
+}
+#ifdef notdef
+int
+udp_client(const char *host, const char *serv, void **saptr, socklen_t *lenp)
+{
+       int                             sockfd, n;
+       struct addrinfo hints, *res, *ressave;
+
+       bzero(&hints, sizeof(struct addrinfo));
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_DGRAM;
+
+       if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0)
+               err_quit("udp_client error for %s, %s: %s",
+                                host, serv, gai_strerror(n));
+       ressave = res;
+
+       do {
+               sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+               if (sockfd >= 0)
+                       break;          /* success */
+       } while ( (res = res->ai_next) != NULL);
+
+       if (res == NULL)        /* errno set from final socket() */
+               err_sys("udp_client error for %s, %s", host, serv);
+
+       *saptr = Malloc(res->ai_addrlen);
+       memcpy(*saptr, res->ai_addr, res->ai_addrlen);
+       *lenp = res->ai_addrlen;
+
+       freeaddrinfo(ressave);
+
+       return(sockfd);
+}
+
+int
+Udp_client(const char *host, const char *serv, void **saptr, socklen_t *lenptr)
+{
+       return(udp_client(host, serv, saptr, lenptr));
+}
+#endif
diff --git a/test/tisfdtype.c b/test/tisfdtype.c
new file mode 100644 (file)
index 0000000..6cd9de2
--- /dev/null
@@ -0,0 +1,18 @@
+#include       "unp.h"
+
+main()
+{
+       int     tcpsock, udpsock;
+
+       printf("stdin: %d\n", Isfdtype(STDIN_FILENO, S_IFSOCK));
+       printf("stdout: %d\n", Isfdtype(STDOUT_FILENO, S_IFSOCK));
+       printf("stderr: %d\n", Isfdtype(STDERR_FILENO, S_IFSOCK));
+
+       tcpsock = Socket(AF_INET, SOCK_STREAM, 0);
+       printf("TCP socket: %d\n", Isfdtype(tcpsock, S_IFSOCK));
+
+       udpsock = Socket(AF_INET, SOCK_DGRAM, 0);
+       printf("UDP socket: %d\n", Isfdtype(udpsock, S_IFSOCK));
+
+       exit(0);
+}
diff --git a/test/treadline1.c b/test/treadline1.c
new file mode 100644 (file)
index 0000000..8551c10
--- /dev/null
@@ -0,0 +1,13 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             count = 0;
+       ssize_t n;
+       char    recvline[MAXLINE];
+
+       while ( ( n = readline(STDIN_FILENO, recvline, MAXLINE)) > 0)
+               count++;
+       printf("%d lines\n", count);
+}
diff --git a/test/treadline2.c b/test/treadline2.c
new file mode 100644 (file)
index 0000000..8551c10
--- /dev/null
@@ -0,0 +1,13 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             count = 0;
+       ssize_t n;
+       char    recvline[MAXLINE];
+
+       while ( ( n = readline(STDIN_FILENO, recvline, MAXLINE)) > 0)
+               count++;
+       printf("%d lines\n", count);
+}
diff --git a/test/treadline3.c b/test/treadline3.c
new file mode 100644 (file)
index 0000000..b580c0d
--- /dev/null
@@ -0,0 +1,16 @@
+#include       "unp.h"
+#include       "readline.h"
+
+int
+main(int argc, char **argv)
+{
+       int             count = 0;
+       ssize_t n;
+       char    recvline[MAXLINE];
+       Rline   rline;
+
+       readline_rinit(STDIN_FILENO, recvline, MAXLINE, &rline);
+       while ( (n = readline_r(&rline)) > 0)
+               count++;
+       printf("%d lines\n", count);
+}
diff --git a/test/tshutdown.c b/test/tshutdown.c
new file mode 100644 (file)
index 0000000..7d8bbaf
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unp.h"
+
+#define        BUFF    100000
+char   buff[BUFF];
+
+int
+main(int argc, char **argv)
+{
+       int             sockfd, nbytes;
+       ssize_t n;
+
+       if (argc != 3)
+               err_quit("usage: tshutdown <hostname> <service>");
+
+       sockfd = Tcp_connect(argv[1], argv[2]);
+       fprintf(stderr, "connected\n");
+
+       while ( (n = Read(STDIN_FILENO, buff, BUFF)) > 0) {
+               Writen(sockfd, buff, n);
+       }
+       Close(STDIN_FILENO);
+       /* Shutdown(sockfd, SHUT_WR); */
+       
+       nbytes = 0;
+       while ( (n = Read(sockfd, buff, BUFF)) > 0) {
+               /* fprintf(stderr, "read %d bytes from socket\n", n); */
+               Write(STDOUT_FILENO, buff, n);
+               nbytes += n;
+       }
+       fprintf(stderr, "total: %d bytes read from socket\n", nbytes);
+       Close(STDOUT_FILENO);
+
+       exit(0);
+}
diff --git a/test/tsnprintf.c b/test/tsnprintf.c
new file mode 100644 (file)
index 0000000..ae0ea45
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * If your system does not provide snprintf(), this program will compile
+ * but will have an undefined error from the linker.
+ *
+ * If you are using the lib/snprintf.c function that is supplied for
+ * systems without snprintf(), you should get an error output from our
+ * library function.
+ *
+ * If your system provides the function, and it works, there should be
+ * no output.
+ */
+
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             n;
+       char    buf[1024];
+
+       n = snprintf(buf, 4, "%d", 9999);
+       if (n > 3)
+               printf("error: snprintf overflowed buffer, n = %d\n", n);
+       exit(0);
+}
diff --git a/threads/Makefile b/threads/Makefile
new file mode 100644 (file)
index 0000000..7a12f79
--- /dev/null
@@ -0,0 +1,65 @@
+include ../Make.defines
+
+PROGS =        web01 web02 web03 \
+       tcpcli01 tcpcli02 tcpserv01 tcpserv02 \
+       test01 example01 example02 example03
+
+all:   ${PROGS}
+
+web01: web01.o
+               ${CC} ${CFLAGS} -o $@ web01.o ${LIBS}
+
+web02: web02.o
+               ${CC} ${CFLAGS} -o $@ web02.o ${LIBS}
+
+web03: web03.o
+               ${CC} ${CFLAGS} -o $@ web03.o ${LIBS}
+
+tcpcli01:      tcpcli01.o strclithread.o
+               ${CC} ${CFLAGS} -o $@ tcpcli01.o strclithread.o ${LIBS}
+
+tcpcli02:      tcpcli02.o strclithread2.o
+               ${CC} ${CFLAGS} -o $@ tcpcli02.o strclithread2.o ${LIBS}
+
+tcpserv01:     tcpserv01.o
+               ${CC} ${CFLAGS} -o $@ tcpserv01.o ${LIBS}
+
+# Broken one that uses readline() from library.
+tcpserv02:     tcpserv02.o
+               ${CC} ${CFLAGS} -o $@ tcpserv02.o ${LIBS}
+
+# Correct one that uses thread-safe readline().
+tcpserv02g:    tcpserv02.o readline.o
+               ${CC} ${CFLAGS} -o $@ tcpserv02.o readline.o ${LIBS}
+
+test01:        test01.o
+               ${CC} ${CFLAGS} -o $@ test01.o ${LIBS}
+
+test02:        test02.o
+               ${CC} ${CFLAGS} -o $@ test02.o ${LIBS}
+
+test03:        test03.o
+               ${CC} ${CFLAGS} -o $@ test03.o ${LIBS}
+
+# Bad version uses readline() from library.
+test04b:       test04.o
+               ${CC} ${CFLAGS} -o $@ test04.o ${LIBS}
+
+# Good version uses readline.c in this directory.
+test04g:       test04.o readline.o
+               ${CC} ${CFLAGS} -o $@ test04.o readline.o ${LIBS}
+
+test05:        test05.o
+               ${CC} ${CFLAGS} -o $@ test05.o ${LIBS}
+
+example01:     example01.o
+               ${CC} ${CFLAGS} -o $@ example01.o ${LIBS}
+
+example02:     example02.o
+               ${CC} ${CFLAGS} -o $@ example02.o ${LIBS}
+
+example03:     example03.o
+               ${CC} ${CFLAGS} -o $@ example03.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/threads/doit.1 b/threads/doit.1
new file mode 100755 (executable)
index 0000000..dea312e
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+case $# in
+1)     break ;;
+*)     echo "one argument (#simultaneous connections) required" 1>&2
+       exit 1 ;;
+esac
+
+time ./web03 $1 192.207.117.2 / \
+       /img/logo/awl_logo_blue_50x40.gif \
+       /img/a_world_of_learning.gif \
+       /img/toolbar_soptions.gif \
+       /img/toolbar_purchase.gif \
+       /img/toolbar_feedback.gif \
+       /img/toolbar_top_hilite.gif \
+       /img/toolbar_qsearch.gif \
+       /img/blue_dot.gif \
+       /img/logo/pearson_logo_50.gif
diff --git a/threads/doit.2 b/threads/doit.2
new file mode 100755 (executable)
index 0000000..75ea42b
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+ClientP=/nfs/kohala/home/rstevens/doc/unp/src/tcpcliserv/tcpcli01 # client prog
+ServerH="206.62.226.33"                        # server host
+Infile=/usr/share/misc/zipcodes                # big BSD/OS text file
+
+$ClientP $ServerH < $Infile > temp.1 &
+$ClientP $ServerH < $Infile > temp.2 &
+$ClientP $ServerH < $Infile > temp.3 &
+# $ClientP $ServerH < $Infile > temp.4 &
+# $ClientP $ServerH < $Infile > temp.5 &
+# $ClientP $ServerH < $Infile > temp.6 &
+# $ClientP $ServerH < $Infile > temp.7 &
+# $ClientP $ServerH < $Infile > temp.8 &
+# $ClientP $ServerH < $Infile > temp.9 &
+
+wait
diff --git a/threads/example01.c b/threads/example01.c
new file mode 100644 (file)
index 0000000..960bf53
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unpthread.h"
+
+#define        NLOOP 5000
+
+int                            counter;                /* incremented by threads */
+
+void   *doit(void *);
+
+int
+main(int argc, char **argv)
+{
+       pthread_t       tidA, tidB;
+
+       Pthread_create(&tidA, NULL, &doit, NULL);
+       Pthread_create(&tidB, NULL, &doit, NULL);
+
+               /* 4wait for both threads to terminate */
+       Pthread_join(tidA, NULL);
+       Pthread_join(tidB, NULL);
+
+       exit(0);
+}
+
+void *
+doit(void *vptr)
+{
+       int             i, val;
+
+       /*
+        * Each thread fetches, prints, and increments the counter NLOOP times.
+        * The value of the counter should increase monotonically.
+        */
+
+       for (i = 0; i < NLOOP; i++) {
+               val = counter;
+               printf("%d: %d\n", pthread_self(), val + 1);
+               counter = val + 1;
+       }
+
+       return(NULL);
+}
diff --git a/threads/example01.lc b/threads/example01.lc
new file mode 100644 (file)
index 0000000..b02a372
--- /dev/null
@@ -0,0 +1,41 @@
+#include    "unpthread.h"##  1 ##src/threads/example01.c##
+
+#define NLOOP 5000##  2 ##src/threads/example01.c##
+
+int     counter;                /* this is incremented by the threads */##  3 ##src/threads/example01.c##
+
+void   *doit(void *);##  4 ##src/threads/example01.c##
+
+int##  5 ##src/threads/example01.c##
+main(int argc, char **argv)##  6 ##src/threads/example01.c##
+{##  7 ##src/threads/example01.c##
+    pthread_t tidA, tidB;##  8 ##src/threads/example01.c##
+
+    Pthread_create(&tidA, NULL, &doit, NULL);##  9 ##src/threads/example01.c##
+    Pthread_create(&tidB, NULL, &doit, NULL);## 10 ##src/threads/example01.c##
+
+    /* 4wait for both threads to terminate */## 11 ##src/threads/example01.c##
+    Pthread_join(tidA, NULL);## 12 ##src/threads/example01.c##
+    Pthread_join(tidB, NULL);## 13 ##src/threads/example01.c##
+
+    exit(0);## 14 ##src/threads/example01.c##
+}## 15 ##src/threads/example01.c##
+
+void   *## 16 ##src/threads/example01.c##
+doit(void *vptr)## 17 ##src/threads/example01.c##
+{## 18 ##src/threads/example01.c##
+    int     i, val;## 19 ##src/threads/example01.c##
+
+    /* ## 20 ##src/threads/example01.c##
+     * Each thread fetches, prints, and increments the counter NLOOP times.## 21 ##src/threads/example01.c##
+     * The value of the counter should increase monotonically.## 22 ##src/threads/example01.c##
+     */## 23 ##src/threads/example01.c##
+
+    for (i = 0; i < NLOOP; i++) {## 24 ##src/threads/example01.c##
+        val = counter;## 25 ##src/threads/example01.c##
+        printf("%d: %d\n", pthread_self(), val + 1);## 26 ##src/threads/example01.c##
+        counter = val + 1;## 27 ##src/threads/example01.c##
+    }## 28 ##src/threads/example01.c##
+
+    return (NULL);## 29 ##src/threads/example01.c##
+}## 30 ##src/threads/example01.c##
diff --git a/threads/example02.c b/threads/example02.c
new file mode 100644 (file)
index 0000000..1b91a3d
--- /dev/null
@@ -0,0 +1,46 @@
+#include       "unpthread.h"
+
+#define        NLOOP 5000
+
+int                            counter;                /* incremented by threads */
+pthread_mutex_t        counter_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void   *doit(void *);
+
+int
+main(int argc, char **argv)
+{
+       pthread_t       tidA, tidB;
+
+       Pthread_create(&tidA, NULL, &doit, NULL);
+       Pthread_create(&tidB, NULL, &doit, NULL);
+
+               /* 4wait for both threads to terminate */
+       Pthread_join(tidA, NULL);
+       Pthread_join(tidB, NULL);
+
+       exit(0);
+}
+
+void *
+doit(void *vptr)
+{
+       int             i, val;
+
+       /*
+        * Each thread fetches, prints, and increments the counter NLOOP times.
+        * The value of the counter should increase monotonically.
+        */
+
+       for (i = 0; i < NLOOP; i++) {
+               Pthread_mutex_lock(&counter_mutex);
+
+               val = counter;
+               printf("%d: %d\n", pthread_self(), val + 1);
+               counter = val + 1;
+
+               Pthread_mutex_unlock(&counter_mutex);
+       }
+
+       return(NULL);
+}
diff --git a/threads/example02.lc b/threads/example02.lc
new file mode 100644 (file)
index 0000000..07b7ec6
--- /dev/null
@@ -0,0 +1,46 @@
+#include    "unpthread.h"##  1 ##src/threads/example02.c##
+
+#define NLOOP 5000##  2 ##src/threads/example02.c##
+
+int     counter;                /* this is incremented by the threads */##  3 ##src/threads/example02.c##
+pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;##  4 ##src/threads/example02.c##
+
+void   *doit(void *);##  5 ##src/threads/example02.c##
+
+int##  6 ##src/threads/example02.c##
+main(int argc, char **argv)##  7 ##src/threads/example02.c##
+{##  8 ##src/threads/example02.c##
+    pthread_t tidA, tidB;##  9 ##src/threads/example02.c##
+
+    Pthread_create(&tidA, NULL, &doit, NULL);## 10 ##src/threads/example02.c##
+    Pthread_create(&tidB, NULL, &doit, NULL);## 11 ##src/threads/example02.c##
+
+    /* 4wait for both threads to terminate */## 12 ##src/threads/example02.c##
+    Pthread_join(tidA, NULL);## 13 ##src/threads/example02.c##
+    Pthread_join(tidB, NULL);## 14 ##src/threads/example02.c##
+
+    exit(0);## 15 ##src/threads/example02.c##
+}## 16 ##src/threads/example02.c##
+
+void   *## 17 ##src/threads/example02.c##
+doit(void *vptr)## 18 ##src/threads/example02.c##
+{## 19 ##src/threads/example02.c##
+    int     i, val;## 20 ##src/threads/example02.c##
+
+    /* ## 21 ##src/threads/example02.c##
+     * Each thread fetches, prints, and increments the counter NLOOP times.## 22 ##src/threads/example02.c##
+     * The value of the counter should increase monotonically.## 23 ##src/threads/example02.c##
+     */## 24 ##src/threads/example02.c##
+
+    for (i = 0; i < NLOOP; i++) {## 25 ##src/threads/example02.c##
+        Pthread_mutex_lock(&counter_mutex);## 26 ##src/threads/example02.c##
+
+        val = counter;## 27 ##src/threads/example02.c##
+        printf("%d: %d\n", pthread_self(), val + 1);## 28 ##src/threads/example02.c##
+        counter = val + 1;## 29 ##src/threads/example02.c##
+
+        Pthread_mutex_unlock(&counter_mutex);## 30 ##src/threads/example02.c##
+    }## 31 ##src/threads/example02.c##
+
+    return (NULL);## 32 ##src/threads/example02.c##
+}## 33 ##src/threads/example02.c##
diff --git a/threads/example03.c b/threads/example03.c
new file mode 100644 (file)
index 0000000..65ec7e5
--- /dev/null
@@ -0,0 +1,130 @@
+#include       "unpthread.h"
+
+#define        Pthread_mutex_lock(mptr) \
+       {       int  n; \
+               if ( (n = pthread_mutex_lock(mptr)) != 0) \
+                       { errno = n; err_sys("pthread_mutex_lock error"); } \
+       }
+#define        Pthread_mutex_unlock(mptr) \
+       {       int  n; \
+               if ( (n = pthread_mutex_unlock(mptr)) != 0) \
+                       { errno = n; err_sys("pthread_mutex_unlock error"); } \
+       }
+#define        Pthread_cond_wait(cptr,mptr) \
+       {       int  n; \
+               if ( (n = pthread_cond_wait(cptr,mptr)) != 0) \
+                       { errno = n; err_sys("pthread_cond_wait error"); } \
+       }
+#define        Pthread_cond_signal(cptr) \
+       {       int  n; \
+               if ( (n = pthread_cond_signal(cptr)) != 0) \
+                       { errno = n; err_sys("pthread_cond_signal error"); } \
+       }
+
+#define        NLOOP            50
+#define        BUFFSIZE         10
+
+struct buf_t {
+  int          b_buf[BUFFSIZE];        /* the buffer which contains integer items */
+  int          b_nitems;                       /* #items currently in buffer */
+  int          b_nextget;
+  int          b_nextput;
+  pthread_mutex_t      b_mutex;
+  pthread_cond_t       b_cond_consumer;        /* consumer waiting to get */
+  pthread_cond_t       b_cond_producer;        /* producer waiting to put */
+} buf_t;
+
+void   *produce_loop(void *);
+void   *consume_loop(void *);
+
+int
+main(int argc, char **argv)
+{
+       int                     n;
+       pthread_t       tidA, tidB;
+
+       printf("main, addr(stack) = %x, addr(global) = %x, addr(func) = %x\n",
+                       &n, &buf_t, &produce_loop);
+       if ( (n = pthread_create(&tidA, NULL, &produce_loop, NULL)) != 0)
+               errno = n, err_sys("pthread_create error for A");
+       if ( (n = pthread_create(&tidB, NULL, &consume_loop, NULL)) != 0)
+               errno = n, err_sys("pthread_create error for B");
+
+               /* wait for both threads to terminate */
+       if ( (n = pthread_join(tidA, NULL)) != 0)
+               errno = n, err_sys("pthread_join error for A");
+       if ( (n = pthread_join(tidB, NULL)) != 0)
+               errno = n, err_sys("pthread_join error for B");
+
+       exit(0);
+}
+
+void
+produce(struct buf_t *bptr, int val)
+{
+       Pthread_mutex_lock(&bptr->b_mutex);
+               /* Wait if buffer is full */
+       while (bptr->b_nitems >= BUFFSIZE)
+               Pthread_cond_wait(&bptr->b_cond_producer, &bptr->b_mutex);
+
+               /* There is room, store the new value */
+       printf("produce %d\n", val);
+       bptr->b_buf[bptr->b_nextput] = val;
+       if (++bptr->b_nextput >= BUFFSIZE)
+               bptr->b_nextput = 0;
+       bptr->b_nitems++;
+
+               /* Signal consumer */
+       Pthread_cond_signal(&bptr->b_cond_consumer);
+       Pthread_mutex_unlock(&bptr->b_mutex);
+}
+
+int
+consume(struct buf_t *bptr)
+{
+       int             val;
+
+       Pthread_mutex_lock(&bptr->b_mutex);
+               /* Wait if buffer is empty */
+       while (bptr->b_nitems <= 0)
+               Pthread_cond_wait(&bptr->b_cond_consumer, &bptr->b_mutex);
+
+               /* There is data, fetch the value */
+       val = bptr->b_buf[bptr->b_nextget];
+       printf("consume %d\n", val);
+       if (++bptr->b_nextget >= BUFFSIZE)
+               bptr->b_nextget = 0;
+       bptr->b_nitems--;
+
+               /* Signal producer; it might be waiting for space to store */
+       Pthread_cond_signal(&bptr->b_cond_producer);
+       Pthread_mutex_unlock(&bptr->b_mutex);
+
+       return(val);
+}
+
+void *
+produce_loop(void *vptr)
+{
+       int             i;
+
+       printf("produce_loop thread, addr(stack) = %x\n", &i);
+       for (i = 0; i < NLOOP; i++) {
+               produce(&buf_t, i);
+       }
+
+       return(NULL);
+}
+
+void *
+consume_loop(void *vptr)
+{
+       int             i, val;
+
+       printf("consume_loop thread, addr(stack) = %x\n", &i);
+       for (i = 0; i < NLOOP; i++) {
+               val = consume(&buf_t);
+       }
+
+       return(NULL);
+}
diff --git a/threads/readline.c b/threads/readline.c
new file mode 100644 (file)
index 0000000..5d372ef
--- /dev/null
@@ -0,0 +1,85 @@
+/* include readline1 */
+#include       "unpthread.h"
+
+static pthread_key_t   rl_key;
+static pthread_once_t  rl_once = PTHREAD_ONCE_INIT;
+
+static void
+readline_destructor(void *ptr)
+{
+       free(ptr);
+}
+
+static void
+readline_once(void)
+{
+       Pthread_key_create(&rl_key, readline_destructor);
+}
+
+typedef struct {
+  int   rl_cnt;                        /* initialize to 0 */
+  char *rl_bufptr;                     /* initialize to rl_buf */
+  char  rl_buf[MAXLINE];
+} Rline;
+/* end readline1 */
+
+/* include readline2 */
+static ssize_t
+my_read(Rline *tsd, int fd, char *ptr)
+{
+       if (tsd->rl_cnt <= 0) {
+again:
+               if ( (tsd->rl_cnt = read(fd, tsd->rl_buf, MAXLINE)) < 0) {
+                       if (errno == EINTR)
+                               goto again;
+                       return(-1);
+               } else if (tsd->rl_cnt == 0)
+                       return(0);
+               tsd->rl_bufptr = tsd->rl_buf;
+       }
+
+       tsd->rl_cnt--;
+       *ptr = *tsd->rl_bufptr++;
+       return(1);
+}
+
+ssize_t
+readline(int fd, void *vptr, size_t maxlen)
+{
+       size_t          n, rc;
+       char    c, *ptr;
+       Rline   *tsd;
+
+       Pthread_once(&rl_once, readline_once);
+       if ( (tsd = pthread_getspecific(rl_key)) == NULL) {
+               tsd = Calloc(1, sizeof(Rline));         /* init to 0 */
+               Pthread_setspecific(rl_key, tsd);
+       }
+
+       ptr = vptr;
+       for (n = 1; n < maxlen; n++) {
+               if ( (rc = my_read(tsd, fd, &c)) == 1) {
+                       *ptr++ = c;
+                       if (c == '\n')
+                               break;
+               } else if (rc == 0) {
+                       *ptr = 0;
+                       return(n - 1);          /* EOF, n - 1 bytes read */
+               } else
+                       return(-1);             /* error, errno set by read() */
+       }
+
+       *ptr = 0;
+       return(n);
+}
+/* end readline2 */
+
+ssize_t
+Readline(int fd, void *ptr, size_t maxlen)
+{
+       ssize_t         n;
+
+       if ( (n = readline(fd, ptr, maxlen)) < 0)
+               err_sys("readline error");
+       return(n);
+}
diff --git a/threads/readline.lc b/threads/readline.lc
new file mode 100644 (file)
index 0000000..66e70c9
--- /dev/null
@@ -0,0 +1,87 @@
+/* include readline1 */
+#include    "unpthread.h"##  1 ##src/threads/readline.c##
+
+static pthread_key_t rl_key;##  2 ##src/threads/readline.c##
+static pthread_once_t rl_once = PTHREAD_ONCE_INIT;##  3 ##src/threads/readline.c##
+
+static void##  4 ##src/threads/readline.c##
+readline_destructor(void *ptr)##  5 ##src/threads/readline.c##
+{##  6 ##src/threads/readline.c##
+    free(ptr);##  7 ##src/threads/readline.c##
+}##  8 ##src/threads/readline.c##
+
+static void##  9 ##src/threads/readline.c##
+readline_once(void)## 10 ##src/threads/readline.c##
+{## 11 ##src/threads/readline.c##
+    Pthread_key_create(&rl_key, readline_destructor);## 12 ##src/threads/readline.c##
+}## 13 ##src/threads/readline.c##
+
+typedef struct {## 14 ##src/threads/readline.c##
+    int     rl_cnt;             /* initialize to 0 */## 15 ##src/threads/readline.c##
+    char   *rl_bufptr;          /* initialize to rl_buf */## 16 ##src/threads/readline.c##
+    char    rl_buf[MAXLINE];## 17 ##src/threads/readline.c##
+} Rline;## 18 ##src/threads/readline.c##
+/* end readline1 */
+
+/* include readline2 */
+static ssize_t## 19 ##src/threads/readline.c##
+my_read(Rline *tsd, int fd, char *ptr)## 20 ##src/threads/readline.c##
+{## 21 ##src/threads/readline.c##
+    if (tsd->rl_cnt <= 0) {## 22 ##src/threads/readline.c##
+      again:## 23 ##src/threads/readline.c##
+        if ((tsd->rl_cnt = read(fd, tsd->rl_buf, MAXLINE)) < 0) {## 24 ##src/threads/readline.c##
+            if (errno == EINTR)## 25 ##src/threads/readline.c##
+                goto again;## 26 ##src/threads/readline.c##
+            return (-1);## 27 ##src/threads/readline.c##
+        } else if (tsd->rl_cnt == 0)## 28 ##src/threads/readline.c##
+            return (0);## 29 ##src/threads/readline.c##
+        tsd->rl_bufptr = tsd->rl_buf;## 30 ##src/threads/readline.c##
+    }## 31 ##src/threads/readline.c##
+
+    tsd->rl_cnt--;## 32 ##src/threads/readline.c##
+    *ptr = *tsd->rl_bufptr++;## 33 ##src/threads/readline.c##
+    return (1);## 34 ##src/threads/readline.c##
+}## 35 ##src/threads/readline.c##
+
+ssize_t## 36 ##src/threads/readline.c##
+readline(int fd, void *vptr, size_t maxlen)## 37 ##src/threads/readline.c##
+{## 38 ##src/threads/readline.c##
+    int     n, rc;## 39 ##src/threads/readline.c##
+    char    c, *ptr;## 40 ##src/threads/readline.c##
+    Rline  *tsd;## 41 ##src/threads/readline.c##
+
+    Pthread_once(&rl_once, readline_once);## 42 ##src/threads/readline.c##
+    if ((tsd = pthread_getspecific(rl_key)) == NULL) {## 43 ##src/threads/readline.c##
+        tsd = Calloc(1, sizeof(Rline)); /* init to 0 */## 44 ##src/threads/readline.c##
+        Pthread_setspecific(rl_key, tsd);## 45 ##src/threads/readline.c##
+    }## 46 ##src/threads/readline.c##
+
+    ptr = vptr;## 47 ##src/threads/readline.c##
+    for (n = 1; n < maxlen; n++) {## 48 ##src/threads/readline.c##
+        if ((rc = my_read(tsd, fd, &c)) == 1) {## 49 ##src/threads/readline.c##
+            *ptr++ = c;## 50 ##src/threads/readline.c##
+            if (c == '\n')## 51 ##src/threads/readline.c##
+                break;## 52 ##src/threads/readline.c##
+        } else if (rc == 0) {## 53 ##src/threads/readline.c##
+            if (n == 1)## 54 ##src/threads/readline.c##
+                return (0);     /* EOF, no data read */## 55 ##src/threads/readline.c##
+            else## 56 ##src/threads/readline.c##
+                break;          /* EOF, some data was read */## 57 ##src/threads/readline.c##
+        } else## 58 ##src/threads/readline.c##
+            return (-1);        /* error, errno set by read() */## 59 ##src/threads/readline.c##
+    }## 60 ##src/threads/readline.c##
+
+    *ptr = 0;## 61 ##src/threads/readline.c##
+    return (n);## 62 ##src/threads/readline.c##
+}## 63 ##src/threads/readline.c##
+/* end readline2 */
+
+ssize_t## 64 ##src/threads/readline.c##
+Readline(int fd, void *ptr, size_t maxlen)## 65 ##src/threads/readline.c##
+{## 66 ##src/threads/readline.c##
+    ssize_t n;## 67 ##src/threads/readline.c##
+
+    if ((n = readline(fd, ptr, maxlen)) < 0)## 68 ##src/threads/readline.c##
+        err_sys("readline error");## 69 ##src/threads/readline.c##
+    return (n);## 70 ##src/threads/readline.c##
+}## 71 ##src/threads/readline.c##
diff --git a/threads/script.example01 b/threads/script.example01
new file mode 100644 (file)
index 0000000..b8836d8
--- /dev/null
@@ -0,0 +1,10000 @@
+4: 1
+4: 2
+4: 3
+4: 4
+4: 5
+4: 6
+4: 7
+4: 8
+4: 9
+4: 10
+4: 11
+4: 12
+4: 13
+4: 14
+4: 15
+4: 16
+4: 17
+4: 18
+4: 19
+4: 20
+4: 21
+4: 22
+4: 23
+4: 24
+4: 25
+4: 26
+4: 27
+4: 28
+4: 29
+4: 30
+4: 31
+4: 32
+4: 33
+4: 34
+4: 35
+4: 36
+4: 37
+4: 38
+4: 39
+4: 40
+4: 41
+4: 42
+4: 43
+4: 44
+4: 45
+4: 46
+4: 47
+4: 48
+4: 49
+4: 50
+4: 51
+4: 52
+4: 53
+4: 54
+4: 55
+4: 56
+4: 57
+4: 58
+4: 59
+4: 60
+4: 61
+4: 62
+4: 63
+4: 64
+4: 65
+4: 66
+4: 67
+4: 68
+4: 69
+4: 70
+4: 71
+4: 72
+4: 73
+4: 74
+4: 75
+4: 76
+4: 77
+4: 78
+4: 79
+4: 80
+4: 81
+4: 82
+4: 83
+4: 84
+4: 85
+4: 86
+4: 87
+4: 88
+4: 89
+4: 90
+4: 91
+4: 92
+4: 93
+4: 94
+4: 95
+4: 96
+4: 97
+4: 98
+4: 99
+4: 100
+4: 101
+4: 102
+4: 103
+4: 104
+4: 105
+4: 106
+4: 107
+4: 108
+4: 109
+4: 110
+4: 111
+4: 112
+4: 113
+4: 114
+4: 115
+4: 116
+4: 117
+4: 118
+4: 119
+4: 120
+4: 121
+4: 122
+4: 123
+4: 124
+4: 125
+4: 126
+4: 127
+4: 128
+4: 129
+4: 130
+4: 131
+4: 132
+4: 133
+4: 134
+4: 135
+4: 136
+4: 137
+4: 138
+4: 139
+4: 140
+4: 141
+4: 142
+4: 143
+4: 144
+4: 145
+4: 146
+4: 147
+4: 148
+4: 149
+4: 150
+4: 151
+4: 152
+4: 153
+4: 154
+4: 155
+4: 156
+4: 157
+4: 158
+4: 159
+4: 160
+4: 161
+4: 162
+4: 163
+4: 164
+4: 165
+4: 166
+4: 167
+4: 168
+4: 169
+4: 170
+4: 171
+4: 172
+4: 173
+4: 174
+4: 175
+4: 176
+4: 177
+4: 178
+4: 179
+4: 180
+4: 181
+4: 182
+4: 183
+4: 184
+4: 185
+4: 186
+4: 187
+4: 188
+4: 189
+4: 190
+4: 191
+4: 192
+4: 193
+4: 194
+4: 195
+4: 196
+4: 197
+4: 198
+4: 199
+4: 200
+4: 201
+4: 202
+4: 203
+4: 204
+4: 205
+4: 206
+4: 207
+4: 208
+4: 209
+4: 210
+4: 211
+4: 212
+4: 213
+4: 214
+4: 215
+4: 216
+4: 217
+4: 218
+4: 219
+4: 220
+4: 221
+4: 222
+4: 223
+4: 224
+4: 225
+4: 226
+4: 227
+4: 228
+4: 229
+4: 230
+4: 231
+4: 232
+4: 233
+4: 234
+4: 235
+4: 236
+4: 237
+4: 238
+4: 239
+4: 240
+4: 241
+4: 242
+4: 243
+4: 244
+4: 245
+4: 246
+4: 247
+4: 248
+4: 249
+4: 250
+4: 251
+4: 252
+4: 253
+4: 254
+4: 255
+4: 256
+4: 257
+4: 258
+4: 259
+4: 260
+4: 261
+4: 262
+4: 263
+4: 264
+4: 265
+4: 266
+4: 267
+4: 268
+4: 269
+4: 270
+4: 271
+4: 272
+4: 273
+4: 274
+4: 275
+4: 276
+4: 277
+4: 278
+4: 279
+4: 280
+4: 281
+4: 282
+4: 283
+4: 284
+4: 285
+4: 286
+4: 287
+4: 288
+4: 289
+4: 290
+4: 291
+4: 292
+4: 293
+4: 294
+4: 295
+4: 296
+4: 297
+4: 298
+4: 299
+4: 300
+4: 301
+4: 302
+4: 303
+4: 304
+4: 305
+4: 306
+4: 307
+4: 308
+4: 309
+4: 310
+4: 311
+4: 312
+4: 313
+4: 314
+4: 315
+4: 316
+4: 317
+4: 318
+4: 319
+4: 320
+4: 321
+4: 322
+4: 323
+4: 324
+4: 325
+4: 326
+4: 327
+4: 328
+4: 329
+4: 330
+4: 331
+4: 332
+4: 333
+4: 334
+4: 335
+4: 336
+4: 337
+4: 338
+4: 339
+4: 340
+4: 341
+4: 342
+4: 343
+4: 344
+4: 345
+4: 346
+4: 347
+4: 348
+4: 349
+4: 350
+4: 351
+4: 352
+4: 353
+4: 354
+4: 355
+4: 356
+4: 357
+4: 358
+4: 359
+4: 360
+4: 361
+4: 362
+4: 363
+4: 364
+4: 365
+4: 366
+4: 367
+4: 368
+4: 369
+4: 370
+4: 371
+4: 372
+4: 373
+4: 374
+4: 375
+4: 376
+4: 377
+4: 378
+4: 379
+4: 380
+4: 381
+4: 382
+4: 383
+4: 384
+4: 385
+4: 386
+4: 387
+4: 388
+4: 389
+4: 390
+4: 391
+4: 392
+4: 393
+4: 394
+4: 395
+4: 396
+4: 397
+4: 398
+4: 399
+4: 400
+4: 401
+4: 402
+4: 403
+4: 404
+4: 405
+4: 406
+4: 407
+4: 408
+4: 409
+4: 410
+4: 411
+4: 412
+4: 413
+4: 414
+4: 415
+4: 416
+4: 417
+4: 418
+4: 419
+4: 420
+4: 421
+4: 422
+4: 423
+4: 424
+4: 425
+4: 426
+4: 427
+4: 428
+4: 429
+4: 430
+4: 431
+4: 432
+4: 433
+4: 434
+4: 435
+4: 436
+4: 437
+4: 438
+4: 439
+4: 440
+4: 441
+4: 442
+4: 443
+4: 444
+4: 445
+4: 446
+4: 447
+4: 448
+4: 449
+4: 450
+4: 451
+4: 452
+4: 453
+4: 454
+4: 455
+4: 456
+4: 457
+4: 458
+4: 459
+4: 460
+4: 461
+4: 462
+4: 463
+4: 464
+4: 465
+4: 466
+4: 467
+4: 468
+4: 469
+4: 470
+4: 471
+4: 472
+4: 473
+4: 474
+4: 475
+4: 476
+4: 477
+4: 478
+4: 479
+4: 480
+4: 481
+4: 482
+4: 483
+4: 484
+4: 485
+4: 486
+4: 487
+4: 488
+4: 489
+4: 490
+4: 491
+4: 492
+4: 493
+4: 494
+4: 495
+4: 496
+4: 497
+4: 498
+4: 499
+4: 500
+4: 501
+4: 502
+4: 503
+4: 504
+4: 505
+4: 506
+4: 507
+4: 508
+4: 509
+4: 510
+4: 511
+4: 512
+4: 513
+4: 514
+4: 515
+4: 516
+4: 517
+4: 518
+5: 518
+5: 519
+5: 520
+5: 521
+5: 522
+5: 523
+5: 524
+5: 525
+5: 526
+5: 527
+5: 528
+5: 529
+5: 530
+5: 531
+5: 532
+5: 533
+5: 534
+5: 535
+5: 536
+5: 537
+5: 538
+5: 539
+5: 540
+5: 541
+5: 542
+5: 543
+5: 544
+5: 545
+5: 546
+5: 547
+5: 548
+5: 549
+5: 550
+5: 551
+5: 552
+5: 553
+5: 554
+5: 555
+5: 556
+5: 557
+5: 558
+5: 559
+5: 560
+5: 561
+5: 562
+5: 563
+5: 564
+5: 565
+5: 566
+5: 567
+5: 568
+5: 569
+5: 570
+5: 571
+5: 572
+5: 573
+5: 574
+5: 575
+5: 576
+5: 577
+5: 578
+5: 579
+5: 580
+5: 581
+5: 582
+5: 583
+5: 584
+5: 585
+5: 586
+5: 587
+5: 588
+5: 589
+5: 590
+5: 591
+5: 592
+5: 593
+5: 594
+5: 595
+5: 596
+5: 597
+5: 598
+5: 599
+5: 600
+5: 601
+5: 602
+5: 603
+5: 604
+5: 605
+5: 606
+5: 607
+5: 608
+5: 609
+5: 610
+5: 611
+5: 612
+5: 613
+5: 614
+5: 615
+5: 616
+5: 617
+5: 618
+5: 619
+5: 620
+5: 621
+5: 622
+5: 623
+5: 624
+5: 625
+5: 626
+5: 627
+5: 628
+5: 629
+5: 630
+5: 631
+5: 632
+5: 633
+5: 634
+5: 635
+5: 636
+5: 637
+5: 638
+5: 639
+5: 640
+5: 641
+5: 642
+5: 643
+5: 644
+5: 645
+5: 646
+5: 647
+5: 648
+5: 649
+5: 650
+5: 651
+5: 652
+5: 653
+5: 654
+5: 655
+5: 656
+5: 657
+5: 658
+5: 659
+5: 660
+5: 661
+5: 662
+5: 663
+5: 664
+5: 665
+5: 666
+5: 667
+5: 668
+5: 669
+5: 670
+5: 671
+5: 672
+5: 673
+5: 674
+5: 675
+5: 676
+5: 677
+5: 678
+5: 679
+5: 680
+5: 681
+5: 682
+5: 683
+5: 684
+5: 685
+5: 686
+5: 687
+5: 688
+5: 689
+5: 690
+5: 691
+5: 692
+5: 693
+5: 694
+5: 695
+5: 696
+5: 697
+5: 698
+5: 699
+5: 700
+5: 701
+5: 702
+5: 703
+5: 704
+5: 705
+5: 706
+5: 707
+5: 708
+5: 709
+5: 710
+5: 711
+5: 712
+5: 713
+5: 714
+5: 715
+5: 716
+5: 717
+5: 718
+5: 719
+5: 720
+5: 721
+5: 722
+5: 723
+5: 724
+5: 725
+5: 726
+5: 727
+5: 728
+5: 729
+5: 730
+5: 731
+5: 732
+5: 733
+5: 734
+5: 735
+5: 736
+5: 737
+5: 738
+5: 739
+5: 740
+5: 741
+5: 742
+5: 743
+5: 744
+5: 745
+5: 746
+5: 747
+5: 748
+5: 749
+5: 750
+5: 751
+5: 752
+5: 753
+5: 754
+5: 755
+5: 756
+5: 757
+5: 758
+5: 759
+5: 760
+5: 761
+5: 762
+5: 763
+5: 764
+5: 765
+5: 766
+5: 767
+5: 768
+5: 769
+5: 770
+5: 771
+5: 772
+5: 773
+5: 774
+5: 775
+5: 776
+5: 777
+5: 778
+5: 779
+5: 780
+5: 781
+5: 782
+5: 783
+5: 784
+5: 785
+5: 786
+5: 787
+5: 788
+5: 789
+5: 790
+5: 791
+5: 792
+5: 793
+5: 794
+5: 795
+5: 796
+5: 797
+5: 798
+5: 799
+5: 800
+5: 801
+5: 802
+5: 803
+5: 804
+5: 805
+5: 806
+5: 807
+5: 808
+5: 809
+5: 810
+5: 811
+5: 812
+5: 813
+5: 814
+5: 815
+5: 816
+5: 817
+5: 818
+5: 819
+5: 820
+5: 821
+5: 822
+5: 823
+5: 824
+5: 825
+5: 826
+5: 827
+5: 828
+5: 829
+5: 830
+5: 831
+5: 832
+5: 833
+5: 834
+5: 835
+5: 836
+5: 837
+5: 838
+5: 839
+5: 840
+5: 841
+5: 842
+5: 843
+5: 844
+5: 845
+5: 846
+5: 847
+5: 848
+5: 849
+5: 850
+5: 851
+5: 852
+5: 853
+5: 854
+5: 855
+5: 856
+5: 857
+5: 858
+5: 859
+5: 860
+5: 861
+5: 862
+5: 863
+5: 864
+5: 865
+5: 866
+5: 867
+5: 868
+5: 869
+5: 870
+5: 871
+5: 872
+5: 873
+5: 874
+5: 875
+5: 876
+5: 877
+5: 878
+5: 879
+5: 880
+5: 881
+5: 882
+5: 883
+5: 884
+5: 885
+5: 886
+5: 887
+5: 888
+5: 889
+5: 890
+5: 891
+5: 892
+5: 893
+5: 894
+5: 895
+5: 896
+5: 897
+5: 898
+5: 899
+5: 900
+5: 901
+5: 902
+5: 903
+5: 904
+5: 905
+5: 906
+5: 907
+5: 908
+5: 909
+5: 910
+5: 911
+5: 912
+5: 913
+5: 914
+5: 915
+5: 916
+5: 917
+5: 918
+5: 919
+5: 920
+5: 921
+5: 922
+5: 923
+5: 924
+5: 925
+5: 926
+5: 927
+4: 519
+4: 520
+4: 521
+4: 522
+4: 523
+4: 524
+4: 525
+4: 526
+4: 527
+4: 528
+4: 529
+4: 530
+4: 531
+4: 532
+4: 533
+4: 534
+4: 535
+4: 536
+4: 537
+4: 538
+4: 539
+4: 540
+4: 541
+4: 542
+4: 543
+4: 544
+4: 545
+4: 546
+4: 547
+4: 548
+4: 549
+4: 550
+4: 551
+4: 552
+4: 553
+4: 554
+4: 555
+4: 556
+4: 557
+4: 558
+4: 559
+4: 560
+4: 561
+4: 562
+4: 563
+4: 564
+4: 565
+4: 566
+4: 567
+4: 568
+4: 569
+4: 570
+4: 571
+4: 572
+4: 573
+4: 574
+4: 575
+4: 576
+4: 577
+4: 578
+4: 579
+4: 580
+4: 581
+4: 582
+4: 583
+4: 584
+4: 585
+4: 586
+4: 587
+4: 588
+4: 589
+4: 590
+4: 591
+4: 592
+4: 593
+4: 594
+4: 595
+4: 596
+4: 597
+4: 598
+4: 599
+4: 600
+4: 601
+4: 602
+4: 603
+4: 604
+4: 605
+4: 606
+4: 607
+4: 608
+4: 609
+4: 610
+4: 611
+4: 612
+4: 613
+4: 614
+4: 615
+4: 616
+4: 617
+4: 618
+4: 619
+4: 620
+4: 621
+4: 622
+4: 623
+4: 624
+4: 625
+4: 626
+4: 627
+4: 628
+4: 629
+4: 630
+4: 631
+4: 632
+4: 633
+4: 634
+4: 635
+4: 636
+4: 637
+4: 638
+4: 639
+4: 640
+4: 641
+4: 642
+4: 643
+4: 644
+4: 645
+4: 646
+4: 647
+4: 648
+4: 649
+4: 650
+4: 651
+4: 652
+4: 653
+4: 654
+4: 655
+4: 656
+4: 657
+4: 658
+4: 659
+4: 660
+4: 661
+4: 662
+4: 663
+4: 664
+4: 665
+4: 666
+4: 667
+4: 668
+4: 669
+4: 670
+4: 671
+4: 672
+4: 673
+4: 674
+5: 928
+5: 929
+5: 930
+5: 931
+5: 932
+5: 933
+5: 934
+5: 935
+5: 936
+5: 937
+5: 938
+5: 939
+5: 940
+5: 941
+5: 942
+5: 943
+5: 944
+5: 945
+5: 946
+5: 947
+5: 948
+5: 949
+5: 950
+5: 951
+5: 952
+5: 953
+5: 954
+5: 955
+5: 956
+5: 957
+5: 958
+5: 959
+5: 960
+5: 961
+5: 962
+5: 963
+5: 964
+5: 965
+5: 966
+5: 967
+5: 968
+5: 969
+5: 970
+5: 971
+5: 972
+5: 973
+5: 974
+5: 975
+5: 976
+5: 977
+5: 978
+5: 979
+5: 980
+5: 981
+5: 982
+5: 983
+5: 984
+5: 985
+5: 986
+5: 987
+5: 988
+5: 989
+5: 990
+5: 991
+5: 992
+5: 993
+5: 994
+5: 995
+5: 996
+5: 997
+5: 998
+5: 999
+5: 1000
+5: 1001
+5: 1002
+5: 1003
+5: 1004
+5: 1005
+5: 1006
+5: 1007
+5: 1008
+5: 1009
+5: 1010
+5: 1011
+5: 1012
+5: 1013
+5: 1014
+5: 1015
+5: 1016
+5: 1017
+5: 1018
+5: 1019
+5: 1020
+5: 1021
+5: 1022
+5: 1023
+5: 1024
+5: 1025
+5: 1026
+5: 1027
+5: 1028
+5: 1029
+5: 1030
+5: 1031
+5: 1032
+5: 1033
+5: 1034
+5: 1035
+5: 1036
+5: 1037
+5: 1038
+5: 1039
+5: 1040
+5: 1041
+5: 1042
+5: 1043
+5: 1044
+5: 1045
+5: 1046
+5: 1047
+5: 1048
+5: 1049
+5: 1050
+5: 1051
+5: 1052
+5: 1053
+5: 1054
+5: 1055
+5: 1056
+5: 1057
+5: 1058
+5: 1059
+5: 1060
+5: 1061
+5: 1062
+5: 1063
+5: 1064
+5: 1065
+5: 1066
+5: 1067
+5: 1068
+5: 1069
+5: 1070
+5: 1071
+5: 1072
+5: 1073
+5: 1074
+5: 1075
+5: 1076
+5: 1077
+5: 1078
+5: 1079
+5: 1080
+5: 1081
+5: 1082
+5: 1083
+5: 1084
+5: 1085
+5: 1086
+5: 1087
+5: 1088
+5: 1089
+5: 1090
+5: 1091
+5: 1092
+5: 1093
+5: 1094
+5: 1095
+4: 675
+4: 676
+4: 677
+4: 678
+4: 679
+4: 680
+4: 681
+4: 682
+4: 683
+4: 684
+4: 685
+4: 686
+4: 687
+4: 688
+4: 689
+4: 690
+4: 691
+4: 692
+4: 693
+4: 694
+4: 695
+4: 696
+4: 697
+4: 698
+4: 699
+4: 700
+4: 701
+4: 702
+4: 703
+4: 704
+4: 705
+4: 706
+4: 707
+4: 708
+4: 709
+4: 710
+4: 711
+4: 712
+4: 713
+4: 714
+4: 715
+4: 716
+4: 717
+4: 718
+4: 719
+4: 720
+4: 721
+4: 722
+4: 723
+4: 724
+4: 725
+4: 726
+4: 727
+4: 728
+4: 729
+4: 730
+4: 731
+4: 732
+4: 733
+4: 734
+4: 735
+4: 736
+4: 737
+4: 738
+4: 739
+4: 740
+4: 741
+4: 742
+4: 743
+4: 744
+4: 745
+4: 746
+4: 747
+4: 748
+4: 749
+4: 750
+4: 751
+4: 752
+4: 753
+4: 754
+4: 755
+4: 756
+4: 757
+4: 758
+4: 759
+4: 760
+4: 761
+4: 762
+4: 763
+4: 764
+4: 765
+4: 766
+4: 767
+4: 768
+4: 769
+4: 770
+4: 771
+4: 772
+4: 773
+4: 774
+4: 775
+4: 776
+4: 777
+5: 1096
+5: 1097
+5: 1098
+5: 1099
+5: 1100
+5: 1101
+5: 1102
+5: 1103
+5: 1104
+5: 1105
+5: 1106
+5: 1107
+5: 1108
+5: 1109
+5: 1110
+5: 1111
+5: 1112
+5: 1113
+5: 1114
+5: 1115
+5: 1116
+5: 1117
+5: 1118
+5: 1119
+5: 1120
+5: 1121
+5: 1122
+5: 1123
+5: 1124
+5: 1125
+5: 1126
+5: 1127
+5: 1128
+5: 1129
+5: 1130
+5: 1131
+5: 1132
+5: 1133
+5: 1134
+5: 1135
+5: 1136
+5: 1137
+5: 1138
+5: 1139
+5: 1140
+5: 1141
+5: 1142
+5: 1143
+5: 1144
+5: 1145
+5: 1146
+5: 1147
+5: 1148
+5: 1149
+5: 1150
+5: 1151
+5: 1152
+5: 1153
+5: 1154
+5: 1155
+5: 1156
+5: 1157
+5: 1158
+5: 1159
+5: 1160
+5: 1161
+5: 1162
+5: 1163
+5: 1164
+5: 1165
+5: 1166
+5: 1167
+5: 1168
+5: 1169
+5: 1170
+5: 1171
+5: 1172
+5: 1173
+5: 1174
+5: 1175
+5: 1176
+5: 1177
+5: 1178
+5: 1179
+5: 1180
+5: 1181
+5: 1182
+5: 1183
+5: 1184
+5: 1185
+5: 1186
+5: 1187
+5: 1188
+5: 1189
+5: 1190
+5: 1191
+5: 1192
+5: 1193
+5: 1194
+5: 1195
+5: 1196
+5: 1197
+5: 1198
+5: 1199
+5: 1200
+5: 1201
+5: 1202
+5: 1203
+5: 1204
+5: 1205
+5: 1206
+5: 1207
+5: 1208
+5: 1209
+5: 1210
+5: 1211
+5: 1212
+5: 1213
+5: 1214
+5: 1215
+5: 1216
+5: 1217
+5: 1218
+5: 1219
+5: 1220
+5: 1221
+5: 1222
+5: 1223
+5: 1224
+5: 1225
+5: 1226
+5: 1227
+5: 1228
+5: 1229
+5: 1230
+5: 1231
+5: 1232
+5: 1233
+5: 1234
+5: 1235
+5: 1236
+5: 1237
+5: 1238
+5: 1239
+5: 1240
+5: 1241
+5: 1242
+5: 1243
+5: 1244
+5: 1245
+5: 1246
+5: 1247
+5: 1248
+5: 1249
+5: 1250
+5: 1251
+5: 1252
+5: 1253
+5: 1254
+5: 1255
+5: 1256
+5: 1257
+5: 1258
+5: 1259
+5: 1260
+5: 1261
+5: 1262
+5: 1263
+5: 1264
+5: 1265
+5: 1266
+5: 1267
+5: 1268
+5: 1269
+5: 1270
+5: 1271
+5: 1272
+5: 1273
+5: 1274
+5: 1275
+5: 1276
+5: 1277
+5: 1278
+5: 1279
+5: 1280
+5: 1281
+5: 1282
+5: 1283
+5: 1284
+5: 1285
+5: 1286
+5: 1287
+5: 1288
+5: 1289
+5: 1290
+5: 1291
+5: 1292
+5: 1293
+5: 1294
+5: 1295
+5: 1296
+5: 1297
+5: 1298
+5: 1299
+5: 1300
+5: 1301
+5: 1302
+5: 1303
+5: 1304
+5: 1305
+5: 1306
+5: 1307
+5: 1308
+5: 1309
+5: 1310
+5: 1311
+5: 1312
+5: 1313
+5: 1314
+5: 1315
+5: 1316
+5: 1317
+5: 1318
+5: 1319
+5: 1320
+5: 1321
+5: 1322
+5: 1323
+5: 1324
+5: 1325
+5: 1326
+5: 1327
+5: 1328
+5: 1329
+5: 1330
+5: 1331
+5: 1332
+5: 1333
+5: 1334
+5: 1335
+5: 1336
+5: 1337
+5: 1338
+4: 778
+4: 779
+4: 780
+4: 781
+4: 782
+4: 783
+4: 784
+4: 785
+4: 786
+4: 787
+4: 788
+4: 789
+4: 790
+4: 791
+4: 792
+4: 793
+4: 794
+4: 795
+4: 796
+4: 797
+4: 798
+4: 799
+4: 800
+4: 801
+4: 802
+4: 803
+4: 804
+4: 805
+4: 806
+4: 807
+4: 808
+4: 809
+4: 810
+4: 811
+4: 812
+4: 813
+4: 814
+4: 815
+4: 816
+4: 817
+4: 818
+4: 819
+4: 820
+4: 821
+4: 822
+4: 823
+4: 824
+4: 825
+4: 826
+4: 827
+4: 828
+4: 829
+4: 830
+4: 831
+4: 832
+4: 833
+4: 834
+4: 835
+4: 836
+4: 837
+4: 838
+4: 839
+4: 840
+4: 841
+4: 842
+4: 843
+4: 844
+4: 845
+4: 846
+4: 847
+4: 848
+4: 849
+4: 850
+4: 851
+4: 852
+4: 853
+4: 854
+4: 855
+4: 856
+4: 857
+4: 858
+4: 859
+4: 860
+4: 861
+4: 862
+4: 863
+4: 864
+4: 865
+4: 866
+4: 867
+4: 868
+4: 869
+4: 870
+4: 871
+4: 872
+4: 873
+4: 874
+4: 875
+4: 876
+4: 877
+4: 878
+4: 879
+4: 880
+4: 881
+4: 882
+4: 883
+4: 884
+4: 885
+4: 886
+4: 887
+4: 888
+4: 889
+4: 890
+4: 891
+4: 892
+4: 893
+4: 894
+4: 895
+4: 896
+4: 897
+4: 898
+4: 899
+4: 900
+4: 901
+4: 902
+4: 903
+4: 904
+4: 905
+4: 906
+4: 907
+4: 908
+4: 909
+4: 910
+4: 911
+4: 912
+4: 913
+4: 914
+4: 915
+4: 916
+4: 917
+4: 918
+4: 919
+4: 920
+4: 921
+4: 922
+4: 923
+4: 924
+4: 925
+4: 926
+4: 927
+4: 928
+4: 929
+4: 930
+4: 931
+4: 932
+4: 933
+4: 934
+4: 935
+4: 936
+4: 937
+4: 938
+4: 939
+4: 940
+4: 941
+4: 942
+4: 943
+4: 944
+4: 945
+4: 946
+4: 947
+4: 948
+4: 949
+4: 950
+4: 951
+4: 952
+4: 953
+4: 954
+4: 955
+4: 956
+4: 957
+4: 958
+4: 959
+4: 960
+4: 961
+4: 962
+4: 963
+4: 964
+4: 965
+4: 966
+4: 967
+4: 968
+4: 969
+4: 970
+4: 971
+4: 972
+4: 973
+4: 974
+4: 975
+4: 976
+4: 977
+4: 978
+4: 979
+4: 980
+4: 981
+4: 982
+4: 983
+4: 984
+4: 985
+4: 986
+4: 987
+4: 988
+4: 989
+4: 990
+4: 991
+4: 992
+4: 993
+4: 994
+4: 995
+4: 996
+4: 997
+4: 998
+4: 999
+4: 1000
+4: 1001
+4: 1002
+4: 1003
+4: 1004
+4: 1005
+4: 1006
+4: 1007
+4: 1008
+4: 1009
+4: 1010
+4: 1011
+4: 1012
+4: 1013
+4: 1014
+4: 1015
+4: 1016
+4: 1017
+4: 1018
+4: 1019
+4: 1020
+4: 1021
+4: 1022
+4: 1023
+4: 1024
+4: 1025
+4: 1026
+4: 1027
+4: 1028
+4: 1029
+4: 1030
+4: 1031
+4: 1032
+4: 1033
+4: 1034
+4: 1035
+4: 1036
+4: 1037
+4: 1038
+4: 1039
+4: 1040
+4: 1041
+4: 1042
+4: 1043
+4: 1044
+4: 1045
+4: 1046
+4: 1047
+4: 1048
+4: 1049
+4: 1050
+4: 1051
+4: 1052
+4: 1053
+4: 1054
+4: 1055
+4: 1056
+4: 1057
+4: 1058
+4: 1059
+4: 1060
+4: 1061
+4: 1062
+4: 1063
+4: 1064
+4: 1065
+4: 1066
+4: 1067
+4: 1068
+4: 1069
+4: 1070
+4: 1071
+4: 1072
+4: 1073
+4: 1074
+4: 1075
+4: 1076
+4: 1077
+4: 1078
+4: 1079
+4: 1080
+4: 1081
+4: 1082
+4: 1083
+4: 1084
+4: 1085
+4: 1086
+4: 1087
+4: 1088
+4: 1089
+4: 1090
+4: 1091
+4: 1092
+4: 1093
+4: 1094
+4: 1095
+4: 1096
+4: 1097
+4: 1098
+4: 1099
+4: 1100
+4: 1101
+4: 1102
+4: 1103
+4: 1104
+4: 1105
+4: 1106
+4: 1107
+4: 1108
+4: 1109
+4: 1110
+4: 1111
+5: 1339
+5: 1340
+5: 1341
+5: 1342
+5: 1343
+5: 1344
+5: 1345
+5: 1346
+5: 1347
+5: 1348
+5: 1349
+5: 1350
+5: 1351
+5: 1352
+5: 1353
+5: 1354
+5: 1355
+5: 1356
+5: 1357
+5: 1358
+5: 1359
+5: 1360
+5: 1361
+5: 1362
+5: 1363
+5: 1364
+5: 1365
+5: 1366
+5: 1367
+5: 1368
+5: 1369
+5: 1370
+5: 1371
+5: 1372
+5: 1373
+5: 1374
+5: 1375
+5: 1376
+5: 1377
+5: 1378
+5: 1379
+5: 1380
+5: 1381
+5: 1382
+5: 1383
+5: 1384
+5: 1385
+5: 1386
+5: 1387
+5: 1388
+5: 1389
+5: 1390
+5: 1391
+5: 1392
+5: 1393
+5: 1394
+5: 1395
+5: 1396
+5: 1397
+5: 1398
+5: 1399
+5: 1400
+5: 1401
+5: 1402
+5: 1403
+5: 1404
+5: 1405
+5: 1406
+5: 1407
+5: 1408
+5: 1409
+5: 1410
+5: 1411
+5: 1412
+5: 1413
+5: 1414
+5: 1415
+5: 1416
+5: 1417
+5: 1418
+5: 1419
+5: 1420
+5: 1421
+5: 1422
+5: 1423
+5: 1424
+5: 1425
+5: 1426
+5: 1427
+5: 1428
+5: 1429
+5: 1430
+5: 1431
+5: 1432
+5: 1433
+5: 1434
+5: 1435
+5: 1436
+5: 1437
+5: 1438
+5: 1439
+5: 1440
+5: 1441
+5: 1442
+5: 1443
+5: 1444
+5: 1445
+5: 1446
+5: 1447
+5: 1448
+5: 1449
+5: 1450
+5: 1451
+5: 1452
+5: 1453
+5: 1454
+5: 1455
+5: 1456
+5: 1457
+5: 1458
+5: 1459
+5: 1460
+5: 1461
+5: 1462
+5: 1463
+5: 1464
+5: 1465
+5: 1466
+5: 1467
+5: 1468
+5: 1469
+5: 1470
+5: 1471
+5: 1472
+5: 1473
+5: 1474
+5: 1475
+5: 1476
+5: 1477
+5: 1478
+5: 1479
+5: 1480
+5: 1481
+5: 1482
+5: 1483
+5: 1484
+5: 1485
+5: 1486
+5: 1487
+5: 1488
+5: 1489
+5: 1490
+5: 1491
+5: 1492
+5: 1493
+5: 1494
+5: 1495
+5: 1496
+5: 1497
+5: 1498
+5: 1499
+5: 1500
+5: 1501
+5: 1502
+5: 1503
+5: 1504
+5: 1505
+5: 1506
+5: 1507
+5: 1508
+5: 1509
+5: 1510
+5: 1511
+5: 1512
+5: 1513
+5: 1514
+5: 1515
+5: 1516
+5: 1517
+5: 1518
+5: 1519
+5: 1520
+5: 1521
+5: 1522
+5: 1523
+5: 1524
+5: 1525
+5: 1526
+5: 1527
+5: 1528
+5: 1529
+5: 1530
+5: 1531
+5: 1532
+5: 1533
+5: 1534
+5: 1535
+5: 1536
+5: 1537
+5: 1538
+5: 1539
+5: 1540
+5: 1541
+5: 1542
+5: 1543
+5: 1544
+5: 1545
+5: 1546
+5: 1547
+5: 1548
+5: 1549
+5: 1550
+5: 1551
+5: 1552
+5: 1553
+5: 1554
+5: 1555
+5: 1556
+5: 1557
+5: 1558
+5: 1559
+5: 1560
+5: 1561
+5: 1562
+5: 1563
+5: 1564
+5: 1565
+5: 1566
+5: 1567
+5: 1568
+5: 1569
+5: 1570
+5: 1571
+5: 1572
+5: 1573
+5: 1574
+5: 1575
+5: 1576
+5: 1577
+5: 1578
+5: 1579
+5: 1580
+5: 1581
+5: 1582
+5: 1583
+5: 1584
+5: 1585
+5: 1586
+5: 1587
+5: 1588
+5: 1589
+5: 1590
+5: 1591
+5: 1592
+5: 1593
+5: 1594
+5: 1595
+5: 1596
+5: 1597
+5: 1598
+5: 1599
+5: 1600
+5: 1601
+5: 1602
+5: 1603
+5: 1604
+5: 1605
+5: 1606
+5: 1607
+5: 1608
+5: 1609
+5: 1610
+5: 1611
+5: 1612
+5: 1613
+5: 1614
+5: 1615
+5: 1616
+5: 1617
+5: 1618
+5: 1619
+5: 1620
+5: 1621
+5: 1622
+5: 1623
+5: 1624
+5: 1625
+5: 1626
+5: 1627
+5: 1628
+5: 1629
+5: 1630
+5: 1631
+5: 1632
+5: 1633
+5: 1634
+5: 1635
+5: 1636
+5: 1637
+5: 1638
+5: 1639
+5: 1640
+5: 1641
+5: 1642
+5: 1643
+5: 1644
+5: 1645
+5: 1646
+5: 1647
+5: 1648
+5: 1649
+5: 1650
+5: 1651
+5: 1652
+5: 1653
+5: 1654
+5: 1655
+5: 1656
+5: 1657
+5: 1658
+5: 1659
+5: 1660
+5: 1661
+5: 1662
+5: 1663
+5: 1664
+5: 1665
+5: 1666
+5: 1667
+5: 1668
+5: 1669
+5: 1670
+5: 1671
+5: 1672
+5: 1673
+5: 1674
+5: 1675
+5: 1676
+5: 1677
+5: 1678
+5: 1679
+5: 1680
+5: 1681
+5: 1682
+5: 1683
+5: 1684
+5: 1685
+5: 1686
+5: 1687
+5: 1688
+5: 1689
+5: 1690
+5: 1691
+5: 1692
+5: 1693
+5: 1694
+5: 1695
+5: 1696
+5: 1697
+5: 1698
+5: 1699
+5: 1700
+5: 1701
+5: 1702
+5: 1703
+4: 1112
+4: 1113
+4: 1114
+4: 1115
+4: 1116
+4: 1117
+4: 1118
+4: 1119
+4: 1120
+4: 1121
+4: 1122
+4: 1123
+4: 1124
+4: 1125
+4: 1126
+4: 1127
+4: 1128
+4: 1129
+4: 1130
+4: 1131
+4: 1132
+4: 1133
+4: 1134
+4: 1135
+4: 1136
+4: 1137
+4: 1138
+4: 1139
+4: 1140
+4: 1141
+4: 1142
+4: 1143
+4: 1144
+4: 1145
+4: 1146
+4: 1147
+4: 1148
+4: 1149
+4: 1150
+4: 1151
+4: 1152
+4: 1153
+4: 1154
+4: 1155
+4: 1156
+4: 1157
+4: 1158
+4: 1159
+4: 1160
+4: 1161
+4: 1162
+4: 1163
+4: 1164
+4: 1165
+4: 1166
+4: 1167
+4: 1168
+4: 1169
+4: 1170
+4: 1171
+4: 1172
+4: 1173
+4: 1174
+4: 1175
+4: 1176
+4: 1177
+4: 1178
+4: 1179
+4: 1180
+4: 1181
+4: 1182
+4: 1183
+4: 1184
+4: 1185
+4: 1186
+4: 1187
+4: 1188
+4: 1189
+4: 1190
+4: 1191
+4: 1192
+4: 1193
+4: 1194
+4: 1195
+4: 1196
+4: 1197
+4: 1198
+4: 1199
+4: 1200
+4: 1201
+4: 1202
+4: 1203
+4: 1204
+4: 1205
+4: 1206
+4: 1207
+4: 1208
+4: 1209
+4: 1210
+4: 1211
+4: 1212
+4: 1213
+4: 1214
+4: 1215
+4: 1216
+4: 1217
+4: 1218
+4: 1219
+4: 1220
+4: 1221
+4: 1222
+4: 1223
+4: 1224
+4: 1225
+4: 1226
+4: 1227
+4: 1228
+4: 1229
+4: 1230
+4: 1231
+4: 1232
+4: 1233
+4: 1234
+4: 1235
+4: 1236
+4: 1237
+4: 1238
+4: 1239
+4: 1240
+4: 1241
+4: 1242
+4: 1243
+4: 1244
+4: 1245
+4: 1246
+4: 1247
+4: 1248
+4: 1249
+4: 1250
+4: 1251
+4: 1252
+4: 1253
+4: 1254
+4: 1255
+4: 1256
+4: 1257
+4: 1258
+4: 1259
+4: 1260
+4: 1261
+4: 1262
+4: 1263
+4: 1264
+4: 1265
+4: 1266
+4: 1267
+4: 1268
+4: 1269
+4: 1270
+4: 1271
+4: 1272
+4: 1273
+4: 1274
+4: 1275
+4: 1276
+4: 1277
+4: 1278
+4: 1279
+4: 1280
+4: 1281
+4: 1282
+4: 1283
+4: 1284
+4: 1285
+4: 1286
+4: 1287
+4: 1288
+4: 1289
+4: 1290
+4: 1291
+4: 1292
+4: 1293
+4: 1294
+4: 1295
+4: 1296
+4: 1297
+4: 1298
+4: 1299
+4: 1300
+4: 1301
+4: 1302
+4: 1303
+4: 1304
+4: 1305
+4: 1306
+4: 1307
+4: 1308
+4: 1309
+4: 1310
+4: 1311
+4: 1312
+4: 1313
+4: 1314
+4: 1315
+4: 1316
+4: 1317
+4: 1318
+4: 1319
+4: 1320
+4: 1321
+4: 1322
+4: 1323
+4: 1324
+4: 1325
+4: 1326
+4: 1327
+4: 1328
+4: 1329
+4: 1330
+4: 1331
+4: 1332
+4: 1333
+4: 1334
+4: 1335
+4: 1336
+4: 1337
+4: 1338
+4: 1339
+4: 1340
+4: 1341
+4: 1342
+4: 1343
+4: 1344
+4: 1345
+4: 1346
+4: 1347
+4: 1348
+4: 1349
+4: 1350
+4: 1351
+4: 1352
+4: 1353
+4: 1354
+4: 1355
+4: 1356
+4: 1357
+4: 1358
+4: 1359
+4: 1360
+4: 1361
+4: 1362
+4: 1363
+4: 1364
+4: 1365
+4: 1366
+4: 1367
+4: 1368
+4: 1369
+4: 1370
+4: 1371
+4: 1372
+4: 1373
+4: 1374
+4: 1375
+4: 1376
+4: 1377
+4: 1378
+4: 1379
+4: 1380
+4: 1381
+4: 1382
+4: 1383
+4: 1384
+4: 1385
+4: 1386
+4: 1387
+4: 1388
+4: 1389
+4: 1390
+4: 1391
+4: 1392
+4: 1393
+4: 1394
+4: 1395
+4: 1396
+4: 1397
+4: 1398
+4: 1399
+5: 1704
+5: 1705
+5: 1706
+5: 1707
+5: 1708
+5: 1709
+5: 1710
+5: 1711
+5: 1712
+5: 1713
+5: 1714
+5: 1715
+5: 1716
+5: 1717
+5: 1718
+5: 1719
+5: 1720
+5: 1721
+5: 1722
+5: 1723
+5: 1724
+5: 1725
+5: 1726
+5: 1727
+5: 1728
+5: 1729
+5: 1730
+5: 1731
+5: 1732
+5: 1733
+5: 1734
+5: 1735
+5: 1736
+5: 1737
+5: 1738
+5: 1739
+5: 1740
+5: 1741
+5: 1742
+5: 1743
+5: 1744
+5: 1745
+5: 1746
+5: 1747
+5: 1748
+5: 1749
+5: 1750
+5: 1751
+5: 1752
+5: 1753
+5: 1754
+5: 1755
+5: 1756
+5: 1757
+5: 1758
+5: 1759
+5: 1760
+5: 1761
+5: 1762
+5: 1763
+5: 1764
+5: 1765
+5: 1766
+5: 1767
+5: 1768
+5: 1769
+5: 1770
+5: 1771
+5: 1772
+5: 1773
+5: 1774
+5: 1775
+5: 1776
+5: 1777
+5: 1778
+5: 1779
+5: 1780
+5: 1781
+5: 1782
+5: 1783
+5: 1784
+5: 1785
+5: 1786
+5: 1787
+5: 1788
+5: 1789
+5: 1790
+5: 1791
+5: 1792
+5: 1793
+5: 1794
+5: 1795
+5: 1796
+5: 1797
+5: 1798
+5: 1799
+5: 1800
+5: 1801
+5: 1802
+5: 1803
+5: 1804
+5: 1805
+5: 1806
+5: 1807
+5: 1808
+5: 1809
+5: 1810
+5: 1811
+5: 1812
+5: 1813
+5: 1814
+5: 1815
+5: 1816
+5: 1817
+5: 1818
+5: 1819
+5: 1820
+5: 1821
+5: 1822
+5: 1823
+5: 1824
+5: 1825
+5: 1826
+5: 1827
+5: 1828
+5: 1829
+5: 1830
+5: 1831
+5: 1832
+5: 1833
+5: 1834
+5: 1835
+5: 1836
+5: 1837
+5: 1838
+5: 1839
+5: 1840
+5: 1841
+5: 1842
+5: 1843
+5: 1844
+5: 1845
+5: 1846
+5: 1847
+5: 1848
+5: 1849
+5: 1850
+5: 1851
+5: 1852
+5: 1853
+5: 1854
+5: 1855
+5: 1856
+5: 1857
+5: 1858
+5: 1859
+5: 1860
+5: 1861
+5: 1862
+5: 1863
+5: 1864
+5: 1865
+5: 1866
+5: 1867
+5: 1868
+5: 1869
+5: 1870
+5: 1871
+5: 1872
+5: 1873
+5: 1874
+5: 1875
+5: 1876
+5: 1877
+5: 1878
+5: 1879
+5: 1880
+5: 1881
+5: 1882
+5: 1883
+5: 1884
+5: 1885
+5: 1886
+5: 1887
+5: 1888
+5: 1889
+5: 1890
+5: 1891
+5: 1892
+5: 1893
+5: 1894
+5: 1895
+5: 1896
+5: 1897
+5: 1898
+5: 1899
+5: 1900
+5: 1901
+5: 1902
+5: 1903
+5: 1904
+5: 1905
+5: 1906
+5: 1907
+5: 1908
+5: 1909
+5: 1910
+5: 1911
+5: 1912
+5: 1913
+5: 1914
+5: 1915
+5: 1916
+5: 1917
+5: 1918
+5: 1919
+5: 1920
+5: 1921
+5: 1922
+5: 1923
+5: 1924
+5: 1925
+5: 1926
+5: 1927
+5: 1928
+5: 1929
+5: 1930
+5: 1931
+5: 1932
+5: 1933
+5: 1934
+5: 1935
+5: 1936
+5: 1937
+5: 1938
+5: 1939
+5: 1940
+5: 1941
+5: 1942
+5: 1943
+5: 1944
+5: 1945
+5: 1946
+5: 1947
+5: 1948
+5: 1949
+5: 1950
+5: 1951
+5: 1952
+5: 1953
+5: 1954
+5: 1955
+5: 1956
+5: 1957
+5: 1958
+5: 1959
+5: 1960
+5: 1961
+5: 1962
+5: 1963
+5: 1964
+5: 1965
+5: 1966
+5: 1967
+5: 1968
+5: 1969
+5: 1970
+5: 1971
+5: 1972
+5: 1973
+5: 1974
+5: 1975
+5: 1976
+5: 1977
+5: 1978
+5: 1979
+5: 1980
+5: 1981
+5: 1982
+5: 1983
+5: 1984
+5: 1985
+5: 1986
+5: 1987
+5: 1988
+5: 1989
+5: 1990
+5: 1991
+5: 1992
+5: 1993
+5: 1994
+5: 1995
+5: 1996
+5: 1997
+5: 1998
+5: 1999
+5: 2000
+5: 2001
+5: 2002
+5: 2003
+5: 2004
+5: 2005
+5: 2006
+5: 2007
+5: 2008
+5: 2009
+5: 2010
+5: 2011
+5: 2012
+5: 2013
+5: 2014
+5: 2015
+5: 2016
+5: 2017
+5: 2018
+5: 2019
+5: 2020
+5: 2021
+5: 2022
+5: 2023
+5: 2024
+5: 2025
+5: 2026
+5: 2027
+5: 2028
+5: 2029
+5: 2030
+5: 2031
+5: 2032
+5: 2033
+5: 2034
+5: 2035
+5: 2036
+5: 2037
+5: 2038
+5: 2039
+5: 2040
+5: 2041
+5: 2042
+5: 2043
+5: 2044
+5: 2045
+5: 2046
+5: 2047
+5: 2048
+5: 2049
+5: 2050
+5: 2051
+5: 2052
+5: 2053
+5: 2054
+5: 2055
+5: 2056
+5: 2057
+5: 2058
+5: 2059
+5: 2060
+5: 2061
+5: 2062
+5: 2063
+5: 2064
+5: 2065
+5: 2066
+5: 2067
+5: 2068
+5: 2069
+5: 2070
+5: 2071
+5: 2072
+5: 2073
+5: 2074
+5: 2075
+5: 2076
+5: 2077
+5: 2078
+5: 2079
+5: 2080
+5: 2081
+5: 2082
+5: 2083
+5: 2084
+5: 2085
+5: 2086
+5: 2087
+5: 2088
+5: 2089
+5: 2090
+5: 2091
+5: 2092
+5: 2093
+5: 2094
+5: 2095
+5: 2096
+5: 2097
+5: 2098
+5: 2099
+5: 2100
+5: 2101
+5: 2102
+5: 2103
+5: 2104
+5: 2105
+5: 2106
+5: 2107
+5: 2108
+5: 2109
+5: 2110
+5: 2111
+5: 2112
+5: 2113
+5: 2114
+5: 2115
+5: 2116
+5: 2117
+5: 2118
+5: 2119
+5: 2120
+5: 2121
+5: 2122
+5: 2123
+5: 2124
+5: 2125
+5: 2126
+5: 2127
+5: 2128
+5: 2129
+5: 2130
+5: 2131
+5: 2132
+5: 2133
+5: 2134
+5: 2135
+5: 2136
+5: 2137
+5: 2138
+5: 2139
+5: 2140
+5: 2141
+5: 2142
+5: 2143
+5: 2144
+5: 2145
+5: 2146
+5: 2147
+5: 2148
+5: 2149
+4: 1400
+4: 1401
+4: 1402
+4: 1403
+4: 1404
+4: 1405
+4: 1406
+4: 1407
+4: 1408
+4: 1409
+4: 1410
+4: 1411
+4: 1412
+4: 1413
+4: 1414
+4: 1415
+4: 1416
+4: 1417
+4: 1418
+4: 1419
+4: 1420
+4: 1421
+4: 1422
+4: 1423
+4: 1424
+4: 1425
+4: 1426
+4: 1427
+4: 1428
+4: 1429
+4: 1430
+4: 1431
+4: 1432
+4: 1433
+4: 1434
+4: 1435
+4: 1436
+4: 1437
+4: 1438
+4: 1439
+4: 1440
+4: 1441
+4: 1442
+4: 1443
+4: 1444
+4: 1445
+4: 1446
+4: 1447
+4: 1448
+4: 1449
+4: 1450
+4: 1451
+4: 1452
+4: 1453
+4: 1454
+4: 1455
+4: 1456
+4: 1457
+4: 1458
+4: 1459
+4: 1460
+4: 1461
+4: 1462
+4: 1463
+4: 1464
+4: 1465
+4: 1466
+4: 1467
+4: 1468
+4: 1469
+4: 1470
+4: 1471
+4: 1472
+4: 1473
+4: 1474
+4: 1475
+4: 1476
+4: 1477
+4: 1478
+4: 1479
+4: 1480
+4: 1481
+4: 1482
+4: 1483
+4: 1484
+4: 1485
+4: 1486
+4: 1487
+4: 1488
+4: 1489
+4: 1490
+4: 1491
+4: 1492
+4: 1493
+4: 1494
+4: 1495
+4: 1496
+4: 1497
+4: 1498
+4: 1499
+4: 1500
+4: 1501
+4: 1502
+4: 1503
+4: 1504
+4: 1505
+4: 1506
+4: 1507
+4: 1508
+4: 1509
+4: 1510
+4: 1511
+4: 1512
+4: 1513
+4: 1514
+4: 1515
+4: 1516
+4: 1517
+4: 1518
+4: 1519
+4: 1520
+4: 1521
+4: 1522
+4: 1523
+4: 1524
+4: 1525
+4: 1526
+4: 1527
+4: 1528
+4: 1529
+4: 1530
+4: 1531
+4: 1532
+4: 1533
+4: 1534
+4: 1535
+4: 1536
+4: 1537
+4: 1538
+4: 1539
+4: 1540
+4: 1541
+4: 1542
+4: 1543
+4: 1544
+4: 1545
+4: 1546
+4: 1547
+4: 1548
+4: 1549
+4: 1550
+4: 1551
+4: 1552
+4: 1553
+4: 1554
+4: 1555
+4: 1556
+4: 1557
+4: 1558
+4: 1559
+4: 1560
+4: 1561
+4: 1562
+4: 1563
+4: 1564
+4: 1565
+4: 1566
+4: 1567
+4: 1568
+4: 1569
+4: 1570
+4: 1571
+4: 1572
+4: 1573
+4: 1574
+4: 1575
+4: 1576
+4: 1577
+4: 1578
+4: 1579
+4: 1580
+4: 1581
+4: 1582
+4: 1583
+4: 1584
+4: 1585
+4: 1586
+4: 1587
+4: 1588
+4: 1589
+4: 1590
+4: 1591
+4: 1592
+4: 1593
+4: 1594
+4: 1595
+4: 1596
+4: 1597
+4: 1598
+4: 1599
+4: 1600
+4: 1601
+4: 1602
+4: 1603
+4: 1604
+4: 1605
+4: 1606
+4: 1607
+4: 1608
+4: 1609
+4: 1610
+4: 1611
+4: 1612
+4: 1613
+4: 1614
+4: 1615
+4: 1616
+4: 1617
+4: 1618
+4: 1619
+4: 1620
+4: 1621
+4: 1622
+4: 1623
+4: 1624
+4: 1625
+4: 1626
+4: 1627
+4: 1628
+4: 1629
+4: 1630
+4: 1631
+4: 1632
+4: 1633
+4: 1634
+4: 1635
+4: 1636
+4: 1637
+4: 1638
+4: 1639
+4: 1640
+4: 1641
+4: 1642
+4: 1643
+4: 1644
+4: 1645
+4: 1646
+4: 1647
+4: 1648
+4: 1649
+4: 1650
+4: 1651
+4: 1652
+4: 1653
+4: 1654
+4: 1655
+4: 1656
+4: 1657
+4: 1658
+4: 1659
+4: 1660
+4: 1661
+4: 1662
+4: 1663
+4: 1664
+4: 1665
+4: 1666
+4: 1667
+4: 1668
+4: 1669
+4: 1670
+4: 1671
+4: 1672
+4: 1673
+4: 1674
+4: 1675
+4: 1676
+4: 1677
+4: 1678
+4: 1679
+4: 1680
+4: 1681
+4: 1682
+4: 1683
+4: 1684
+4: 1685
+4: 1686
+4: 1687
+4: 1688
+4: 1689
+4: 1690
+4: 1691
+4: 1692
+4: 1693
+4: 1694
+4: 1695
+4: 1696
+4: 1697
+4: 1698
+4: 1699
+4: 1700
+4: 1701
+4: 1702
+4: 1703
+4: 1704
+4: 1705
+4: 1706
+4: 1707
+4: 1708
+4: 1709
+4: 1710
+4: 1711
+4: 1712
+4: 1713
+4: 1714
+4: 1715
+4: 1716
+4: 1717
+4: 1718
+4: 1719
+4: 1720
+4: 1721
+4: 1722
+4: 1723
+4: 1724
+4: 1725
+4: 1726
+4: 1727
+4: 1728
+4: 1729
+4: 1730
+4: 1731
+4: 1732
+4: 1733
+4: 1734
+4: 1735
+4: 1736
+4: 1737
+4: 1738
+4: 1739
+4: 1740
+4: 1741
+4: 1742
+4: 1743
+4: 1744
+4: 1745
+4: 1746
+4: 1747
+4: 1748
+4: 1749
+4: 1750
+4: 1751
+4: 1752
+4: 1753
+4: 1754
+4: 1755
+4: 1756
+4: 1757
+4: 1758
+4: 1759
+4: 1760
+4: 1761
+4: 1762
+4: 1763
+4: 1764
+4: 1765
+4: 1766
+4: 1767
+4: 1768
+4: 1769
+4: 1770
+4: 1771
+4: 1772
+4: 1773
+4: 1774
+4: 1775
+4: 1776
+4: 1777
+4: 1778
+4: 1779
+4: 1780
+4: 1781
+4: 1782
+4: 1783
+4: 1784
+4: 1785
+4: 1786
+4: 1787
+4: 1788
+4: 1789
+4: 1790
+4: 1791
+4: 1792
+4: 1793
+4: 1794
+4: 1795
+4: 1796
+4: 1797
+4: 1798
+4: 1799
+4: 1800
+4: 1801
+4: 1802
+4: 1803
+4: 1804
+4: 1805
+4: 1806
+4: 1807
+4: 1808
+4: 1809
+4: 1810
+4: 1811
+4: 1812
+4: 1813
+4: 1814
+4: 1815
+4: 1816
+4: 1817
+4: 1818
+4: 1819
+4: 1820
+4: 1821
+4: 1822
+4: 1823
+4: 1824
+4: 1825
+4: 1826
+4: 1827
+4: 1828
+4: 1829
+4: 1830
+4: 1831
+4: 1832
+4: 1833
+4: 1834
+4: 1835
+4: 1836
+4: 1837
+4: 1838
+4: 1839
+4: 1840
+4: 1841
+4: 1842
+4: 1843
+4: 1844
+4: 1845
+4: 1846
+4: 1847
+4: 1848
+4: 1849
+4: 1850
+4: 1851
+4: 1852
+4: 1853
+4: 1854
+4: 1855
+4: 1856
+4: 1857
+4: 1858
+4: 1859
+4: 1860
+4: 1861
+4: 1862
+4: 1863
+4: 1864
+4: 1865
+4: 1866
+4: 1867
+4: 1868
+4: 1869
+4: 1870
+4: 1871
+4: 1872
+4: 1873
+4: 1874
+4: 1875
+4: 1876
+4: 1877
+4: 1878
+4: 1879
+4: 1880
+4: 1881
+4: 1882
+4: 1883
+4: 1884
+4: 1885
+4: 1886
+4: 1887
+4: 1888
+4: 1889
+4: 1890
+4: 1891
+4: 1892
+4: 1893
+4: 1894
+4: 1895
+4: 1896
+4: 1897
+4: 1898
+4: 1899
+4: 1900
+4: 1901
+4: 1902
+4: 1903
+4: 1904
+4: 1905
+4: 1906
+4: 1907
+4: 1908
+4: 1909
+4: 1910
+4: 1911
+4: 1912
+4: 1913
+4: 1914
+4: 1915
+4: 1916
+4: 1917
+4: 1918
+4: 1919
+4: 1920
+4: 1921
+4: 1922
+4: 1923
+4: 1924
+4: 1925
+4: 1926
+4: 1927
+4: 1928
+4: 1929
+4: 1930
+4: 1931
+4: 1932
+4: 1933
+4: 1934
+4: 1935
+4: 1936
+4: 1937
+4: 1938
+4: 1939
+4: 1940
+4: 1941
+4: 1942
+4: 1943
+4: 1944
+4: 1945
+4: 1946
+4: 1947
+4: 1948
+4: 1949
+4: 1950
+4: 1951
+4: 1952
+4: 1953
+4: 1954
+4: 1955
+4: 1956
+4: 1957
+4: 1958
+4: 1959
+4: 1960
+4: 1961
+4: 1962
+4: 1963
+4: 1964
+4: 1965
+4: 1966
+4: 1967
+4: 1968
+4: 1969
+4: 1970
+4: 1971
+4: 1972
+4: 1973
+4: 1974
+4: 1975
+4: 1976
+4: 1977
+4: 1978
+4: 1979
+4: 1980
+4: 1981
+4: 1982
+4: 1983
+4: 1984
+4: 1985
+4: 1986
+4: 1987
+4: 1988
+4: 1989
+4: 1990
+4: 1991
+4: 1992
+4: 1993
+4: 1994
+4: 1995
+4: 1996
+4: 1997
+4: 1998
+4: 1999
+4: 2000
+4: 2001
+4: 2002
+4: 2003
+4: 2004
+4: 2005
+4: 2006
+4: 2007
+4: 2008
+4: 2009
+4: 2010
+4: 2011
+4: 2012
+4: 2013
+4: 2014
+4: 2015
+4: 2016
+4: 2017
+4: 2018
+4: 2019
+4: 2020
+4: 2021
+4: 2022
+4: 2023
+4: 2024
+4: 2025
+4: 2026
+4: 2027
+4: 2028
+4: 2029
+4: 2030
+4: 2031
+4: 2032
+4: 2033
+4: 2034
+4: 2035
+4: 2036
+4: 2037
+4: 2038
+4: 2039
+4: 2040
+4: 2041
+4: 2042
+4: 2043
+4: 2044
+4: 2045
+4: 2046
+4: 2047
+4: 2048
+4: 2049
+4: 2050
+4: 2051
+4: 2052
+4: 2053
+4: 2054
+4: 2055
+4: 2056
+4: 2057
+4: 2058
+4: 2059
+4: 2060
+4: 2061
+4: 2062
+4: 2063
+4: 2064
+4: 2065
+4: 2066
+4: 2067
+4: 2068
+4: 2069
+4: 2070
+4: 2071
+4: 2072
+4: 2073
+4: 2074
+4: 2075
+4: 2076
+4: 2077
+4: 2078
+4: 2079
+4: 2080
+4: 2081
+4: 2082
+4: 2083
+4: 2084
+4: 2085
+4: 2086
+4: 2087
+4: 2088
+4: 2089
+4: 2090
+4: 2091
+4: 2092
+4: 2093
+4: 2094
+4: 2095
+4: 2096
+4: 2097
+4: 2098
+4: 2099
+4: 2100
+4: 2101
+4: 2102
+4: 2103
+4: 2104
+4: 2105
+4: 2106
+4: 2107
+4: 2108
+4: 2109
+4: 2110
+4: 2111
+4: 2112
+4: 2113
+4: 2114
+4: 2115
+4: 2116
+4: 2117
+4: 2118
+4: 2119
+4: 2120
+4: 2121
+4: 2122
+4: 2123
+4: 2124
+4: 2125
+4: 2126
+4: 2127
+4: 2128
+4: 2129
+4: 2130
+4: 2131
+4: 2132
+4: 2133
+4: 2134
+4: 2135
+4: 2136
+4: 2137
+4: 2138
+4: 2139
+4: 2140
+4: 2141
+4: 2142
+4: 2143
+4: 2144
+4: 2145
+4: 2146
+4: 2147
+4: 2148
+4: 2149
+4: 2150
+4: 2151
+4: 2152
+4: 2153
+4: 2154
+4: 2155
+4: 2156
+4: 2157
+4: 2158
+4: 2159
+4: 2160
+4: 2161
+4: 2162
+4: 2163
+4: 2164
+4: 2165
+4: 2166
+4: 2167
+4: 2168
+4: 2169
+4: 2170
+4: 2171
+4: 2172
+4: 2173
+4: 2174
+4: 2175
+4: 2176
+4: 2177
+4: 2178
+4: 2179
+4: 2180
+4: 2181
+4: 2182
+4: 2183
+4: 2184
+4: 2185
+4: 2186
+4: 2187
+4: 2188
+4: 2189
+4: 2190
+4: 2191
+4: 2192
+4: 2193
+4: 2194
+4: 2195
+4: 2196
+4: 2197
+4: 2198
+4: 2199
+4: 2200
+4: 2201
+4: 2202
+4: 2203
+4: 2204
+4: 2205
+4: 2206
+4: 2207
+4: 2208
+4: 2209
+4: 2210
+4: 2211
+4: 2212
+4: 2213
+4: 2214
+4: 2215
+4: 2216
+4: 2217
+4: 2218
+4: 2219
+4: 2220
+4: 2221
+4: 2222
+4: 2223
+4: 2224
+4: 2225
+4: 2226
+4: 2227
+4: 2228
+4: 2229
+4: 2230
+4: 2231
+4: 2232
+4: 2233
+4: 2234
+4: 2235
+4: 2236
+4: 2237
+4: 2238
+4: 2239
+4: 2240
+4: 2241
+4: 2242
+4: 2243
+4: 2244
+4: 2245
+4: 2246
+4: 2247
+4: 2248
+4: 2249
+4: 2250
+4: 2251
+4: 2252
+4: 2253
+4: 2254
+4: 2255
+4: 2256
+4: 2257
+4: 2258
+4: 2259
+4: 2260
+4: 2261
+4: 2262
+4: 2263
+4: 2264
+4: 2265
+4: 2266
+4: 2267
+4: 2268
+4: 2269
+4: 2270
+4: 2271
+4: 2272
+4: 2273
+4: 2274
+4: 2275
+4: 2276
+4: 2277
+4: 2278
+4: 2279
+4: 2280
+4: 2281
+4: 2282
+5: 2150
+5: 2151
+5: 2152
+5: 2153
+5: 2154
+5: 2155
+5: 2156
+5: 2157
+5: 2158
+5: 2159
+5: 2160
+5: 2161
+5: 2162
+5: 2163
+5: 2164
+5: 2165
+5: 2166
+5: 2167
+5: 2168
+5: 2169
+5: 2170
+5: 2171
+5: 2172
+5: 2173
+5: 2174
+5: 2175
+5: 2176
+5: 2177
+5: 2178
+5: 2179
+5: 2180
+5: 2181
+5: 2182
+5: 2183
+5: 2184
+5: 2185
+5: 2186
+5: 2187
+5: 2188
+5: 2189
+5: 2190
+5: 2191
+5: 2192
+5: 2193
+5: 2194
+5: 2195
+5: 2196
+5: 2197
+5: 2198
+5: 2199
+5: 2200
+5: 2201
+5: 2202
+5: 2203
+5: 2204
+5: 2205
+5: 2206
+5: 2207
+5: 2208
+5: 2209
+5: 2210
+5: 2211
+5: 2212
+5: 2213
+5: 2214
+5: 2215
+5: 2216
+5: 2217
+5: 2218
+5: 2219
+5: 2220
+5: 2221
+5: 2222
+5: 2223
+5: 2224
+5: 2225
+5: 2226
+5: 2227
+5: 2228
+5: 2229
+5: 2230
+5: 2231
+5: 2232
+5: 2233
+5: 2234
+5: 2235
+5: 2236
+5: 2237
+5: 2238
+5: 2239
+5: 2240
+5: 2241
+5: 2242
+5: 2243
+5: 2244
+5: 2245
+5: 2246
+5: 2247
+5: 2248
+5: 2249
+5: 2250
+5: 2251
+5: 2252
+5: 2253
+5: 2254
+5: 2255
+5: 2256
+5: 2257
+5: 2258
+5: 2259
+5: 2260
+5: 2261
+5: 2262
+5: 2263
+5: 2264
+5: 2265
+5: 2266
+5: 2267
+5: 2268
+5: 2269
+5: 2270
+5: 2271
+5: 2272
+5: 2273
+5: 2274
+5: 2275
+5: 2276
+5: 2277
+5: 2278
+5: 2279
+5: 2280
+5: 2281
+5: 2282
+5: 2283
+5: 2284
+5: 2285
+5: 2286
+5: 2287
+5: 2288
+5: 2289
+5: 2290
+5: 2291
+5: 2292
+5: 2293
+5: 2294
+5: 2295
+5: 2296
+5: 2297
+5: 2298
+5: 2299
+5: 2300
+5: 2301
+5: 2302
+5: 2303
+5: 2304
+5: 2305
+5: 2306
+5: 2307
+5: 2308
+5: 2309
+5: 2310
+5: 2311
+5: 2312
+5: 2313
+5: 2314
+5: 2315
+5: 2316
+5: 2317
+5: 2318
+5: 2319
+5: 2320
+5: 2321
+5: 2322
+5: 2323
+5: 2324
+5: 2325
+5: 2326
+5: 2327
+5: 2328
+5: 2329
+5: 2330
+5: 2331
+5: 2332
+5: 2333
+5: 2334
+5: 2335
+5: 2336
+5: 2337
+5: 2338
+5: 2339
+5: 2340
+5: 2341
+5: 2342
+5: 2343
+5: 2344
+5: 2345
+5: 2346
+5: 2347
+5: 2348
+5: 2349
+5: 2350
+5: 2351
+5: 2352
+5: 2353
+5: 2354
+5: 2355
+5: 2356
+5: 2357
+5: 2358
+5: 2359
+5: 2360
+5: 2361
+5: 2362
+5: 2363
+5: 2364
+5: 2365
+5: 2366
+5: 2367
+5: 2368
+5: 2369
+5: 2370
+5: 2371
+5: 2372
+5: 2373
+5: 2374
+5: 2375
+5: 2376
+5: 2377
+5: 2378
+5: 2379
+5: 2380
+5: 2381
+5: 2382
+5: 2383
+5: 2384
+5: 2385
+5: 2386
+5: 2387
+5: 2388
+5: 2389
+5: 2390
+5: 2391
+5: 2392
+5: 2393
+5: 2394
+5: 2395
+5: 2396
+5: 2397
+5: 2398
+5: 2399
+5: 2400
+5: 2401
+5: 2402
+5: 2403
+5: 2404
+5: 2405
+5: 2406
+5: 2407
+5: 2408
+5: 2409
+5: 2410
+5: 2411
+5: 2412
+5: 2413
+5: 2414
+5: 2415
+5: 2416
+5: 2417
+5: 2418
+5: 2419
+5: 2420
+5: 2421
+5: 2422
+5: 2423
+5: 2424
+5: 2425
+5: 2426
+5: 2427
+5: 2428
+5: 2429
+5: 2430
+5: 2431
+5: 2432
+5: 2433
+5: 2434
+5: 2435
+5: 2436
+5: 2437
+5: 2438
+5: 2439
+5: 2440
+5: 2441
+5: 2442
+5: 2443
+5: 2444
+5: 2445
+5: 2446
+5: 2447
+5: 2448
+5: 2449
+5: 2450
+5: 2451
+5: 2452
+5: 2453
+5: 2454
+5: 2455
+5: 2456
+5: 2457
+5: 2458
+5: 2459
+5: 2460
+5: 2461
+5: 2462
+5: 2463
+5: 2464
+5: 2465
+5: 2466
+5: 2467
+5: 2468
+5: 2469
+5: 2470
+5: 2471
+5: 2472
+5: 2473
+5: 2474
+5: 2475
+5: 2476
+5: 2477
+5: 2478
+5: 2479
+5: 2480
+5: 2481
+5: 2482
+5: 2483
+5: 2484
+4: 2283
+4: 2284
+4: 2285
+4: 2286
+4: 2287
+4: 2288
+4: 2289
+4: 2290
+4: 2291
+4: 2292
+4: 2293
+4: 2294
+4: 2295
+4: 2296
+4: 2297
+4: 2298
+4: 2299
+4: 2300
+4: 2301
+4: 2302
+4: 2303
+4: 2304
+4: 2305
+4: 2306
+4: 2307
+4: 2308
+4: 2309
+4: 2310
+4: 2311
+4: 2312
+4: 2313
+4: 2314
+4: 2315
+4: 2316
+4: 2317
+4: 2318
+4: 2319
+4: 2320
+4: 2321
+4: 2322
+4: 2323
+4: 2324
+4: 2325
+4: 2326
+4: 2327
+4: 2328
+4: 2329
+4: 2330
+4: 2331
+4: 2332
+4: 2333
+4: 2334
+4: 2335
+4: 2336
+4: 2337
+4: 2338
+4: 2339
+4: 2340
+4: 2341
+4: 2342
+4: 2343
+4: 2344
+4: 2345
+4: 2346
+4: 2347
+4: 2348
+4: 2349
+4: 2350
+4: 2351
+4: 2352
+4: 2353
+4: 2354
+4: 2355
+4: 2356
+4: 2357
+4: 2358
+4: 2359
+4: 2360
+4: 2361
+4: 2362
+4: 2363
+4: 2364
+4: 2365
+4: 2366
+4: 2367
+4: 2368
+4: 2369
+4: 2370
+4: 2371
+4: 2372
+4: 2373
+4: 2374
+4: 2375
+4: 2376
+4: 2377
+4: 2378
+4: 2379
+4: 2380
+4: 2381
+4: 2382
+4: 2383
+4: 2384
+4: 2385
+4: 2386
+4: 2387
+4: 2388
+4: 2389
+4: 2390
+4: 2391
+4: 2392
+4: 2393
+4: 2394
+4: 2395
+4: 2396
+4: 2397
+4: 2398
+4: 2399
+4: 2400
+4: 2401
+4: 2402
+4: 2403
+4: 2404
+4: 2405
+4: 2406
+4: 2407
+4: 2408
+4: 2409
+4: 2410
+4: 2411
+4: 2412
+4: 2413
+4: 2414
+4: 2415
+4: 2416
+4: 2417
+4: 2418
+4: 2419
+4: 2420
+4: 2421
+4: 2422
+4: 2423
+4: 2424
+4: 2425
+4: 2426
+4: 2427
+4: 2428
+4: 2429
+4: 2430
+4: 2431
+4: 2432
+4: 2433
+4: 2434
+4: 2435
+4: 2436
+4: 2437
+4: 2438
+4: 2439
+4: 2440
+4: 2441
+4: 2442
+4: 2443
+4: 2444
+4: 2445
+4: 2446
+4: 2447
+4: 2448
+4: 2449
+4: 2450
+4: 2451
+4: 2452
+4: 2453
+4: 2454
+4: 2455
+4: 2456
+4: 2457
+4: 2458
+4: 2459
+4: 2460
+4: 2461
+4: 2462
+4: 2463
+4: 2464
+4: 2465
+4: 2466
+4: 2467
+4: 2468
+4: 2469
+4: 2470
+4: 2471
+4: 2472
+4: 2473
+4: 2474
+4: 2475
+4: 2476
+4: 2477
+4: 2478
+4: 2479
+4: 2480
+4: 2481
+4: 2482
+4: 2483
+4: 2484
+4: 2485
+4: 2486
+4: 2487
+4: 2488
+4: 2489
+4: 2490
+4: 2491
+4: 2492
+4: 2493
+4: 2494
+4: 2495
+4: 2496
+4: 2497
+4: 2498
+4: 2499
+4: 2500
+4: 2501
+4: 2502
+4: 2503
+4: 2504
+4: 2505
+4: 2506
+4: 2507
+4: 2508
+4: 2509
+4: 2510
+4: 2511
+4: 2512
+4: 2513
+4: 2514
+4: 2515
+4: 2516
+4: 2517
+4: 2518
+4: 2519
+4: 2520
+4: 2521
+4: 2522
+4: 2523
+4: 2524
+4: 2525
+4: 2526
+4: 2527
+4: 2528
+4: 2529
+4: 2530
+4: 2531
+4: 2532
+4: 2533
+4: 2534
+4: 2535
+4: 2536
+4: 2537
+4: 2538
+4: 2539
+4: 2540
+4: 2541
+4: 2542
+4: 2543
+4: 2544
+4: 2545
+4: 2546
+4: 2547
+4: 2548
+4: 2549
+4: 2550
+4: 2551
+4: 2552
+4: 2553
+4: 2554
+4: 2555
+4: 2556
+4: 2557
+4: 2558
+4: 2559
+4: 2560
+4: 2561
+4: 2562
+4: 2563
+4: 2564
+4: 2565
+4: 2566
+4: 2567
+4: 2568
+4: 2569
+4: 2570
+4: 2571
+4: 2572
+4: 2573
+4: 2574
+4: 2575
+4: 2576
+4: 2577
+4: 2578
+4: 2579
+4: 2580
+4: 2581
+4: 2582
+4: 2583
+4: 2584
+4: 2585
+4: 2586
+4: 2587
+4: 2588
+4: 2589
+4: 2590
+4: 2591
+4: 2592
+4: 2593
+4: 2594
+4: 2595
+4: 2596
+4: 2597
+4: 2598
+4: 2599
+4: 2600
+4: 2601
+4: 2602
+4: 2603
+4: 2604
+4: 2605
+4: 2606
+4: 2607
+4: 2608
+4: 2609
+4: 2610
+4: 2611
+4: 2612
+4: 2613
+4: 2614
+4: 2615
+4: 2616
+4: 2617
+4: 2618
+4: 2619
+4: 2620
+4: 2621
+4: 2622
+4: 2623
+4: 2624
+4: 2625
+4: 2626
+4: 2627
+4: 2628
+4: 2629
+4: 2630
+4: 2631
+4: 2632
+4: 2633
+4: 2634
+4: 2635
+4: 2636
+4: 2637
+4: 2638
+4: 2639
+4: 2640
+4: 2641
+4: 2642
+4: 2643
+4: 2644
+4: 2645
+4: 2646
+4: 2647
+4: 2648
+4: 2649
+4: 2650
+4: 2651
+4: 2652
+4: 2653
+4: 2654
+4: 2655
+4: 2656
+4: 2657
+4: 2658
+4: 2659
+4: 2660
+4: 2661
+4: 2662
+4: 2663
+4: 2664
+4: 2665
+4: 2666
+4: 2667
+4: 2668
+4: 2669
+4: 2670
+4: 2671
+4: 2672
+4: 2673
+4: 2674
+4: 2675
+4: 2676
+4: 2677
+4: 2678
+4: 2679
+4: 2680
+4: 2681
+4: 2682
+4: 2683
+4: 2684
+4: 2685
+4: 2686
+4: 2687
+4: 2688
+4: 2689
+4: 2690
+4: 2691
+4: 2692
+4: 2693
+4: 2694
+4: 2695
+4: 2696
+4: 2697
+4: 2698
+4: 2699
+4: 2700
+4: 2701
+4: 2702
+4: 2703
+4: 2704
+4: 2705
+4: 2706
+4: 2707
+4: 2708
+4: 2709
+4: 2710
+4: 2711
+4: 2712
+4: 2713
+4: 2714
+4: 2715
+4: 2716
+4: 2717
+4: 2718
+4: 2719
+4: 2720
+4: 2721
+4: 2722
+4: 2723
+4: 2724
+4: 2725
+4: 2726
+4: 2727
+4: 2728
+4: 2729
+4: 2730
+4: 2731
+4: 2732
+4: 2733
+4: 2734
+4: 2735
+4: 2736
+4: 2737
+4: 2738
+4: 2739
+4: 2740
+4: 2741
+4: 2742
+4: 2743
+4: 2744
+4: 2745
+4: 2746
+4: 2747
+4: 2748
+4: 2749
+4: 2750
+4: 2751
+4: 2752
+5: 2485
+5: 2486
+5: 2487
+5: 2488
+5: 2489
+5: 2490
+5: 2491
+5: 2492
+5: 2493
+5: 2494
+5: 2495
+5: 2496
+5: 2497
+5: 2498
+5: 2499
+5: 2500
+5: 2501
+5: 2502
+5: 2503
+5: 2504
+5: 2505
+5: 2506
+5: 2507
+5: 2508
+5: 2509
+5: 2510
+5: 2511
+5: 2512
+5: 2513
+5: 2514
+5: 2515
+5: 2516
+5: 2517
+5: 2518
+5: 2519
+5: 2520
+5: 2521
+5: 2522
+5: 2523
+5: 2524
+5: 2525
+5: 2526
+5: 2527
+5: 2528
+5: 2529
+5: 2530
+5: 2531
+5: 2532
+5: 2533
+5: 2534
+5: 2535
+5: 2536
+5: 2537
+5: 2538
+5: 2539
+5: 2540
+5: 2541
+5: 2542
+5: 2543
+5: 2544
+5: 2545
+5: 2546
+5: 2547
+5: 2548
+5: 2549
+5: 2550
+5: 2551
+5: 2552
+5: 2553
+5: 2554
+5: 2555
+5: 2556
+5: 2557
+5: 2558
+5: 2559
+5: 2560
+5: 2561
+5: 2562
+5: 2563
+5: 2564
+5: 2565
+5: 2566
+5: 2567
+5: 2568
+5: 2569
+5: 2570
+5: 2571
+5: 2572
+5: 2573
+5: 2574
+5: 2575
+5: 2576
+5: 2577
+5: 2578
+5: 2579
+5: 2580
+5: 2581
+5: 2582
+5: 2583
+5: 2584
+5: 2585
+5: 2586
+5: 2587
+5: 2588
+5: 2589
+5: 2590
+5: 2591
+5: 2592
+5: 2593
+5: 2594
+5: 2595
+5: 2596
+5: 2597
+5: 2598
+5: 2599
+5: 2600
+5: 2601
+5: 2602
+5: 2603
+5: 2604
+5: 2605
+5: 2606
+5: 2607
+5: 2608
+5: 2609
+5: 2610
+5: 2611
+5: 2612
+5: 2613
+5: 2614
+5: 2615
+5: 2616
+5: 2617
+5: 2618
+5: 2619
+5: 2620
+5: 2621
+5: 2622
+5: 2623
+5: 2624
+5: 2625
+5: 2626
+5: 2627
+5: 2628
+5: 2629
+5: 2630
+5: 2631
+5: 2632
+5: 2633
+5: 2634
+5: 2635
+5: 2636
+5: 2637
+5: 2638
+5: 2639
+5: 2640
+5: 2641
+5: 2642
+5: 2643
+5: 2644
+5: 2645
+5: 2646
+5: 2647
+5: 2648
+5: 2649
+5: 2650
+5: 2651
+5: 2652
+5: 2653
+5: 2654
+5: 2655
+5: 2656
+5: 2657
+5: 2658
+5: 2659
+5: 2660
+5: 2661
+5: 2662
+5: 2663
+5: 2664
+5: 2665
+5: 2666
+5: 2667
+5: 2668
+5: 2669
+5: 2670
+5: 2671
+5: 2672
+5: 2673
+5: 2674
+5: 2675
+5: 2676
+5: 2677
+5: 2678
+5: 2679
+5: 2680
+5: 2681
+5: 2682
+5: 2683
+5: 2684
+5: 2685
+5: 2686
+5: 2687
+5: 2688
+5: 2689
+5: 2690
+5: 2691
+5: 2692
+5: 2693
+5: 2694
+5: 2695
+5: 2696
+5: 2697
+5: 2698
+5: 2699
+5: 2700
+5: 2701
+5: 2702
+5: 2703
+5: 2704
+5: 2705
+5: 2706
+5: 2707
+5: 2708
+5: 2709
+5: 2710
+5: 2711
+5: 2712
+5: 2713
+5: 2714
+5: 2715
+5: 2716
+5: 2717
+5: 2718
+5: 2719
+5: 2720
+5: 2721
+5: 2722
+5: 2723
+5: 2724
+5: 2725
+5: 2726
+5: 2727
+5: 2728
+5: 2729
+5: 2730
+5: 2731
+5: 2732
+5: 2733
+5: 2734
+5: 2735
+5: 2736
+5: 2737
+5: 2738
+5: 2739
+5: 2740
+5: 2741
+5: 2742
+5: 2743
+5: 2744
+5: 2745
+5: 2746
+5: 2747
+5: 2748
+5: 2749
+5: 2750
+5: 2751
+5: 2752
+5: 2753
+5: 2754
+5: 2755
+5: 2756
+5: 2757
+5: 2758
+5: 2759
+5: 2760
+5: 2761
+5: 2762
+5: 2763
+5: 2764
+5: 2765
+5: 2766
+5: 2767
+5: 2768
+5: 2769
+5: 2770
+5: 2771
+5: 2772
+5: 2773
+5: 2774
+5: 2775
+5: 2776
+5: 2777
+5: 2778
+5: 2779
+5: 2780
+5: 2781
+5: 2782
+5: 2783
+5: 2784
+5: 2785
+5: 2786
+5: 2787
+5: 2788
+5: 2789
+5: 2790
+5: 2791
+5: 2792
+5: 2793
+5: 2794
+5: 2795
+5: 2796
+5: 2797
+5: 2798
+5: 2799
+5: 2800
+5: 2801
+5: 2802
+5: 2803
+5: 2804
+5: 2805
+5: 2806
+5: 2807
+5: 2808
+5: 2809
+5: 2810
+5: 2811
+5: 2812
+5: 2813
+5: 2814
+5: 2815
+5: 2816
+5: 2817
+5: 2818
+5: 2819
+5: 2820
+5: 2821
+5: 2822
+5: 2823
+5: 2824
+5: 2825
+5: 2826
+5: 2827
+5: 2828
+5: 2829
+5: 2830
+5: 2831
+5: 2832
+5: 2833
+5: 2834
+5: 2835
+5: 2836
+5: 2837
+5: 2838
+5: 2839
+5: 2840
+5: 2841
+5: 2842
+5: 2843
+5: 2844
+5: 2845
+5: 2846
+5: 2847
+5: 2848
+5: 2849
+5: 2850
+5: 2851
+5: 2852
+5: 2853
+5: 2854
+5: 2855
+5: 2856
+5: 2857
+5: 2858
+5: 2859
+5: 2860
+5: 2861
+5: 2862
+5: 2863
+5: 2864
+5: 2865
+5: 2866
+5: 2867
+5: 2868
+5: 2869
+5: 2870
+5: 2871
+5: 2872
+5: 2873
+5: 2874
+5: 2875
+5: 2876
+5: 2877
+5: 2878
+5: 2879
+5: 2880
+5: 2881
+5: 2882
+5: 2883
+5: 2884
+5: 2885
+5: 2886
+5: 2887
+5: 2888
+5: 2889
+5: 2890
+5: 2891
+5: 2892
+5: 2893
+5: 2894
+5: 2895
+5: 2896
+5: 2897
+5: 2898
+5: 2899
+5: 2900
+5: 2901
+5: 2902
+5: 2903
+5: 2904
+5: 2905
+5: 2906
+5: 2907
+5: 2908
+5: 2909
+5: 2910
+5: 2911
+5: 2912
+5: 2913
+5: 2914
+5: 2915
+5: 2916
+5: 2917
+5: 2918
+5: 2919
+5: 2920
+5: 2921
+5: 2922
+5: 2923
+5: 2924
+5: 2925
+4: 2753
+4: 2754
+4: 2755
+4: 2756
+4: 2757
+4: 2758
+4: 2759
+4: 2760
+4: 2761
+4: 2762
+4: 2763
+4: 2764
+4: 2765
+4: 2766
+4: 2767
+4: 2768
+4: 2769
+4: 2770
+4: 2771
+4: 2772
+4: 2773
+4: 2774
+4: 2775
+4: 2776
+4: 2777
+4: 2778
+4: 2779
+4: 2780
+4: 2781
+4: 2782
+4: 2783
+4: 2784
+4: 2785
+4: 2786
+4: 2787
+4: 2788
+4: 2789
+4: 2790
+4: 2791
+4: 2792
+4: 2793
+4: 2794
+4: 2795
+4: 2796
+4: 2797
+4: 2798
+4: 2799
+4: 2800
+4: 2801
+4: 2802
+4: 2803
+4: 2804
+4: 2805
+4: 2806
+4: 2807
+4: 2808
+4: 2809
+4: 2810
+4: 2811
+4: 2812
+4: 2813
+4: 2814
+4: 2815
+4: 2816
+4: 2817
+4: 2818
+4: 2819
+4: 2820
+4: 2821
+4: 2822
+4: 2823
+4: 2824
+4: 2825
+4: 2826
+4: 2827
+4: 2828
+4: 2829
+4: 2830
+4: 2831
+4: 2832
+4: 2833
+4: 2834
+4: 2835
+4: 2836
+4: 2837
+4: 2838
+4: 2839
+4: 2840
+4: 2841
+4: 2842
+4: 2843
+4: 2844
+4: 2845
+4: 2846
+4: 2847
+4: 2848
+4: 2849
+4: 2850
+4: 2851
+4: 2852
+4: 2853
+4: 2854
+4: 2855
+4: 2856
+4: 2857
+4: 2858
+4: 2859
+4: 2860
+4: 2861
+4: 2862
+4: 2863
+4: 2864
+4: 2865
+4: 2866
+4: 2867
+4: 2868
+4: 2869
+4: 2870
+4: 2871
+4: 2872
+4: 2873
+4: 2874
+4: 2875
+4: 2876
+4: 2877
+4: 2878
+4: 2879
+4: 2880
+4: 2881
+4: 2882
+4: 2883
+4: 2884
+4: 2885
+4: 2886
+4: 2887
+4: 2888
+4: 2889
+4: 2890
+4: 2891
+4: 2892
+4: 2893
+4: 2894
+4: 2895
+4: 2896
+4: 2897
+4: 2898
+4: 2899
+4: 2900
+4: 2901
+4: 2902
+4: 2903
+4: 2904
+4: 2905
+4: 2906
+4: 2907
+4: 2908
+4: 2909
+4: 2910
+4: 2911
+4: 2912
+4: 2913
+4: 2914
+4: 2915
+4: 2916
+4: 2917
+4: 2918
+4: 2919
+4: 2920
+4: 2921
+4: 2922
+4: 2923
+4: 2924
+4: 2925
+4: 2926
+4: 2927
+4: 2928
+4: 2929
+4: 2930
+4: 2931
+4: 2932
+4: 2933
+4: 2934
+4: 2935
+4: 2936
+4: 2937
+4: 2938
+4: 2939
+4: 2940
+5: 2926
+5: 2927
+5: 2928
+5: 2929
+5: 2930
+5: 2931
+5: 2932
+5: 2933
+5: 2934
+5: 2935
+5: 2936
+5: 2937
+5: 2938
+5: 2939
+5: 2940
+5: 2941
+5: 2942
+5: 2943
+5: 2944
+5: 2945
+5: 2946
+5: 2947
+5: 2948
+5: 2949
+5: 2950
+5: 2951
+5: 2952
+5: 2953
+5: 2954
+5: 2955
+5: 2956
+5: 2957
+5: 2958
+5: 2959
+5: 2960
+5: 2961
+5: 2962
+5: 2963
+5: 2964
+5: 2965
+5: 2966
+5: 2967
+5: 2968
+5: 2969
+5: 2970
+5: 2971
+5: 2972
+5: 2973
+5: 2974
+5: 2975
+5: 2976
+5: 2977
+5: 2978
+5: 2979
+5: 2980
+5: 2981
+5: 2982
+5: 2983
+5: 2984
+5: 2985
+5: 2986
+5: 2987
+5: 2988
+5: 2989
+5: 2990
+5: 2991
+5: 2992
+5: 2993
+5: 2994
+5: 2995
+5: 2996
+5: 2997
+5: 2998
+5: 2999
+5: 3000
+5: 3001
+5: 3002
+5: 3003
+4: 2941
+4: 2942
+4: 2943
+4: 2944
+4: 2945
+4: 2946
+4: 2947
+4: 2948
+4: 2949
+4: 2950
+4: 2951
+4: 2952
+4: 2953
+4: 2954
+4: 2955
+4: 2956
+4: 2957
+4: 2958
+4: 2959
+4: 2960
+4: 2961
+4: 2962
+4: 2963
+4: 2964
+4: 2965
+4: 2966
+4: 2967
+4: 2968
+4: 2969
+4: 2970
+4: 2971
+4: 2972
+4: 2973
+4: 2974
+4: 2975
+4: 2976
+4: 2977
+4: 2978
+4: 2979
+4: 2980
+4: 2981
+4: 2982
+4: 2983
+4: 2984
+4: 2985
+4: 2986
+4: 2987
+4: 2988
+4: 2989
+4: 2990
+4: 2991
+4: 2992
+4: 2993
+4: 2994
+4: 2995
+4: 2996
+4: 2997
+4: 2998
+4: 2999
+4: 3000
+4: 3001
+4: 3002
+4: 3003
+4: 3004
+4: 3005
+4: 3006
+4: 3007
+4: 3008
+4: 3009
+4: 3010
+4: 3011
+4: 3012
+4: 3013
+4: 3014
+4: 3015
+4: 3016
+4: 3017
+4: 3018
+4: 3019
+4: 3020
+4: 3021
+4: 3022
+4: 3023
+4: 3024
+4: 3025
+5: 3004
+5: 3005
+5: 3006
+5: 3007
+5: 3008
+5: 3009
+5: 3010
+5: 3011
+5: 3012
+5: 3013
+5: 3014
+5: 3015
+5: 3016
+5: 3017
+5: 3018
+5: 3019
+5: 3020
+5: 3021
+5: 3022
+5: 3023
+5: 3024
+5: 3025
+5: 3026
+5: 3027
+5: 3028
+5: 3029
+5: 3030
+5: 3031
+5: 3032
+5: 3033
+5: 3034
+5: 3035
+5: 3036
+5: 3037
+5: 3038
+5: 3039
+5: 3040
+5: 3041
+5: 3042
+5: 3043
+5: 3044
+5: 3045
+5: 3046
+5: 3047
+5: 3048
+5: 3049
+5: 3050
+5: 3051
+5: 3052
+5: 3053
+5: 3054
+5: 3055
+5: 3056
+5: 3057
+5: 3058
+5: 3059
+5: 3060
+5: 3061
+5: 3062
+5: 3063
+5: 3064
+5: 3065
+5: 3066
+5: 3067
+5: 3068
+5: 3069
+5: 3070
+5: 3071
+5: 3072
+5: 3073
+5: 3074
+5: 3075
+5: 3076
+5: 3077
+5: 3078
+5: 3079
+5: 3080
+5: 3081
+5: 3082
+5: 3083
+5: 3084
+5: 3085
+5: 3086
+5: 3087
+5: 3088
+5: 3089
+5: 3090
+5: 3091
+5: 3092
+5: 3093
+5: 3094
+5: 3095
+5: 3096
+5: 3097
+5: 3098
+5: 3099
+5: 3100
+5: 3101
+5: 3102
+5: 3103
+5: 3104
+5: 3105
+5: 3106
+5: 3107
+5: 3108
+5: 3109
+5: 3110
+5: 3111
+5: 3112
+5: 3113
+5: 3114
+5: 3115
+5: 3116
+5: 3117
+5: 3118
+5: 3119
+5: 3120
+5: 3121
+5: 3122
+5: 3123
+5: 3124
+5: 3125
+5: 3126
+5: 3127
+5: 3128
+5: 3129
+5: 3130
+5: 3131
+5: 3132
+5: 3133
+5: 3134
+5: 3135
+5: 3136
+5: 3137
+5: 3138
+5: 3139
+5: 3140
+5: 3141
+5: 3142
+5: 3143
+5: 3144
+5: 3145
+5: 3146
+5: 3147
+5: 3148
+5: 3149
+5: 3150
+5: 3151
+5: 3152
+5: 3153
+5: 3154
+5: 3155
+5: 3156
+5: 3157
+5: 3158
+5: 3159
+5: 3160
+5: 3161
+5: 3162
+5: 3163
+5: 3164
+5: 3165
+5: 3166
+5: 3167
+5: 3168
+5: 3169
+5: 3170
+5: 3171
+5: 3172
+5: 3173
+5: 3174
+5: 3175
+5: 3176
+5: 3177
+5: 3178
+5: 3179
+5: 3180
+5: 3181
+5: 3182
+5: 3183
+5: 3184
+5: 3185
+5: 3186
+5: 3187
+5: 3188
+5: 3189
+5: 3190
+5: 3191
+5: 3192
+5: 3193
+5: 3194
+5: 3195
+5: 3196
+5: 3197
+5: 3198
+5: 3199
+5: 3200
+5: 3201
+5: 3202
+5: 3203
+5: 3204
+5: 3205
+5: 3206
+5: 3207
+5: 3208
+5: 3209
+5: 3210
+5: 3211
+5: 3212
+5: 3213
+5: 3214
+5: 3215
+5: 3216
+5: 3217
+5: 3218
+5: 3219
+5: 3220
+5: 3221
+5: 3222
+5: 3223
+5: 3224
+5: 3225
+5: 3226
+5: 3227
+5: 3228
+5: 3229
+5: 3230
+5: 3231
+5: 3232
+5: 3233
+5: 3234
+5: 3235
+5: 3236
+5: 3237
+5: 3238
+5: 3239
+5: 3240
+5: 3241
+5: 3242
+5: 3243
+5: 3244
+5: 3245
+5: 3246
+5: 3247
+5: 3248
+5: 3249
+5: 3250
+5: 3251
+5: 3252
+5: 3253
+5: 3254
+5: 3255
+5: 3256
+5: 3257
+5: 3258
+5: 3259
+5: 3260
+5: 3261
+5: 3262
+5: 3263
+5: 3264
+5: 3265
+5: 3266
+5: 3267
+5: 3268
+5: 3269
+5: 3270
+5: 3271
+5: 3272
+5: 3273
+5: 3274
+5: 3275
+5: 3276
+5: 3277
+5: 3278
+5: 3279
+5: 3280
+5: 3281
+5: 3282
+5: 3283
+5: 3284
+5: 3285
+5: 3286
+5: 3287
+5: 3288
+5: 3289
+5: 3290
+5: 3291
+5: 3292
+5: 3293
+5: 3294
+5: 3295
+5: 3296
+5: 3297
+5: 3298
+5: 3299
+5: 3300
+5: 3301
+5: 3302
+5: 3303
+5: 3304
+5: 3305
+5: 3306
+5: 3307
+5: 3308
+5: 3309
+5: 3310
+5: 3311
+5: 3312
+5: 3313
+5: 3314
+5: 3315
+5: 3316
+5: 3317
+5: 3318
+5: 3319
+5: 3320
+5: 3321
+5: 3322
+5: 3323
+5: 3324
+5: 3325
+5: 3326
+5: 3327
+5: 3328
+5: 3329
+5: 3330
+5: 3331
+5: 3332
+5: 3333
+5: 3334
+5: 3335
+5: 3336
+5: 3337
+5: 3338
+5: 3339
+5: 3340
+5: 3341
+5: 3342
+5: 3343
+5: 3344
+5: 3345
+5: 3346
+5: 3347
+5: 3348
+5: 3349
+5: 3350
+5: 3351
+5: 3352
+5: 3353
+5: 3354
+5: 3355
+5: 3356
+5: 3357
+5: 3358
+5: 3359
+5: 3360
+5: 3361
+5: 3362
+5: 3363
+5: 3364
+5: 3365
+5: 3366
+5: 3367
+5: 3368
+5: 3369
+5: 3370
+5: 3371
+5: 3372
+5: 3373
+5: 3374
+5: 3375
+5: 3376
+5: 3377
+5: 3378
+5: 3379
+5: 3380
+5: 3381
+4: 3026
+4: 3027
+4: 3028
+4: 3029
+4: 3030
+4: 3031
+4: 3032
+4: 3033
+4: 3034
+4: 3035
+4: 3036
+4: 3037
+4: 3038
+4: 3039
+4: 3040
+4: 3041
+4: 3042
+4: 3043
+4: 3044
+4: 3045
+4: 3046
+4: 3047
+4: 3048
+4: 3049
+4: 3050
+4: 3051
+4: 3052
+4: 3053
+4: 3054
+4: 3055
+4: 3056
+4: 3057
+4: 3058
+4: 3059
+4: 3060
+4: 3061
+4: 3062
+4: 3063
+4: 3064
+4: 3065
+4: 3066
+4: 3067
+4: 3068
+4: 3069
+4: 3070
+4: 3071
+4: 3072
+4: 3073
+4: 3074
+4: 3075
+4: 3076
+4: 3077
+4: 3078
+4: 3079
+4: 3080
+4: 3081
+4: 3082
+4: 3083
+4: 3084
+4: 3085
+4: 3086
+4: 3087
+4: 3088
+4: 3089
+4: 3090
+4: 3091
+4: 3092
+4: 3093
+4: 3094
+4: 3095
+4: 3096
+4: 3097
+4: 3098
+4: 3099
+4: 3100
+4: 3101
+4: 3102
+4: 3103
+4: 3104
+4: 3105
+4: 3106
+4: 3107
+4: 3108
+4: 3109
+4: 3110
+4: 3111
+4: 3112
+4: 3113
+4: 3114
+4: 3115
+4: 3116
+4: 3117
+4: 3118
+4: 3119
+4: 3120
+4: 3121
+4: 3122
+4: 3123
+4: 3124
+4: 3125
+4: 3126
+4: 3127
+4: 3128
+4: 3129
+4: 3130
+4: 3131
+4: 3132
+4: 3133
+4: 3134
+4: 3135
+4: 3136
+4: 3137
+4: 3138
+4: 3139
+4: 3140
+4: 3141
+4: 3142
+4: 3143
+4: 3144
+4: 3145
+4: 3146
+4: 3147
+4: 3148
+4: 3149
+4: 3150
+4: 3151
+4: 3152
+4: 3153
+4: 3154
+4: 3155
+4: 3156
+4: 3157
+4: 3158
+4: 3159
+4: 3160
+4: 3161
+4: 3162
+4: 3163
+4: 3164
+4: 3165
+4: 3166
+4: 3167
+4: 3168
+4: 3169
+4: 3170
+4: 3171
+4: 3172
+4: 3173
+4: 3174
+4: 3175
+4: 3176
+4: 3177
+4: 3178
+4: 3179
+4: 3180
+4: 3181
+4: 3182
+4: 3183
+4: 3184
+4: 3185
+4: 3186
+4: 3187
+4: 3188
+4: 3189
+4: 3190
+4: 3191
+4: 3192
+4: 3193
+4: 3194
+4: 3195
+4: 3196
+4: 3197
+4: 3198
+4: 3199
+4: 3200
+4: 3201
+4: 3202
+4: 3203
+4: 3204
+4: 3205
+4: 3206
+4: 3207
+4: 3208
+4: 3209
+4: 3210
+4: 3211
+4: 3212
+4: 3213
+4: 3214
+4: 3215
+4: 3216
+4: 3217
+4: 3218
+4: 3219
+4: 3220
+4: 3221
+4: 3222
+4: 3223
+4: 3224
+4: 3225
+4: 3226
+4: 3227
+4: 3228
+4: 3229
+4: 3230
+4: 3231
+4: 3232
+4: 3233
+4: 3234
+4: 3235
+4: 3236
+4: 3237
+4: 3238
+4: 3239
+4: 3240
+4: 3241
+4: 3242
+4: 3243
+4: 3244
+4: 3245
+4: 3246
+4: 3247
+4: 3248
+4: 3249
+4: 3250
+4: 3251
+4: 3252
+4: 3253
+4: 3254
+4: 3255
+4: 3256
+4: 3257
+4: 3258
+4: 3259
+4: 3260
+4: 3261
+4: 3262
+4: 3263
+4: 3264
+4: 3265
+4: 3266
+4: 3267
+4: 3268
+4: 3269
+4: 3270
+4: 3271
+4: 3272
+4: 3273
+4: 3274
+4: 3275
+4: 3276
+4: 3277
+4: 3278
+4: 3279
+4: 3280
+4: 3281
+4: 3282
+5: 3382
+5: 3383
+5: 3384
+5: 3385
+5: 3386
+5: 3387
+5: 3388
+5: 3389
+5: 3390
+5: 3391
+5: 3392
+5: 3393
+5: 3394
+5: 3395
+5: 3396
+5: 3397
+5: 3398
+5: 3399
+5: 3400
+5: 3401
+5: 3402
+5: 3403
+5: 3404
+5: 3405
+5: 3406
+5: 3407
+5: 3408
+5: 3409
+5: 3410
+5: 3411
+5: 3412
+5: 3413
+5: 3414
+5: 3415
+5: 3416
+5: 3417
+5: 3418
+5: 3419
+5: 3420
+5: 3421
+5: 3422
+5: 3423
+5: 3424
+5: 3425
+5: 3426
+5: 3427
+5: 3428
+5: 3429
+5: 3430
+5: 3431
+5: 3432
+5: 3433
+5: 3434
+5: 3435
+5: 3436
+5: 3437
+5: 3438
+5: 3439
+5: 3440
+5: 3441
+5: 3442
+5: 3443
+5: 3444
+5: 3445
+5: 3446
+5: 3447
+5: 3448
+5: 3449
+5: 3450
+5: 3451
+5: 3452
+5: 3453
+5: 3454
+5: 3455
+5: 3456
+5: 3457
+5: 3458
+5: 3459
+5: 3460
+5: 3461
+5: 3462
+5: 3463
+5: 3464
+5: 3465
+5: 3466
+5: 3467
+5: 3468
+5: 3469
+5: 3470
+5: 3471
+5: 3472
+5: 3473
+5: 3474
+5: 3475
+5: 3476
+5: 3477
+5: 3478
+5: 3479
+5: 3480
+5: 3481
+5: 3482
+5: 3483
+5: 3484
+5: 3485
+5: 3486
+5: 3487
+5: 3488
+5: 3489
+5: 3490
+5: 3491
+5: 3492
+5: 3493
+5: 3494
+5: 3495
+5: 3496
+5: 3497
+5: 3498
+5: 3499
+5: 3500
+5: 3501
+5: 3502
+5: 3503
+5: 3504
+5: 3505
+5: 3506
+5: 3507
+5: 3508
+5: 3509
+5: 3510
+5: 3511
+5: 3512
+5: 3513
+5: 3514
+5: 3515
+5: 3516
+5: 3517
+5: 3518
+5: 3519
+5: 3520
+5: 3521
+5: 3522
+5: 3523
+5: 3524
+5: 3525
+5: 3526
+5: 3527
+5: 3528
+5: 3529
+5: 3530
+5: 3531
+5: 3532
+5: 3533
+5: 3534
+5: 3535
+5: 3536
+5: 3537
+5: 3538
+5: 3539
+5: 3540
+5: 3541
+5: 3542
+5: 3543
+5: 3544
+5: 3545
+5: 3546
+5: 3547
+5: 3548
+5: 3549
+5: 3550
+5: 3551
+5: 3552
+5: 3553
+5: 3554
+5: 3555
+5: 3556
+5: 3557
+5: 3558
+5: 3559
+5: 3560
+5: 3561
+5: 3562
+5: 3563
+5: 3564
+5: 3565
+5: 3566
+5: 3567
+5: 3568
+5: 3569
+5: 3570
+5: 3571
+5: 3572
+5: 3573
+5: 3574
+5: 3575
+5: 3576
+5: 3577
+5: 3578
+5: 3579
+5: 3580
+5: 3581
+5: 3582
+5: 3583
+5: 3584
+5: 3585
+5: 3586
+5: 3587
+5: 3588
+5: 3589
+5: 3590
+5: 3591
+5: 3592
+5: 3593
+5: 3594
+5: 3595
+5: 3596
+5: 3597
+5: 3598
+5: 3599
+5: 3600
+5: 3601
+5: 3602
+5: 3603
+5: 3604
+5: 3605
+5: 3606
+5: 3607
+5: 3608
+5: 3609
+5: 3610
+5: 3611
+5: 3612
+5: 3613
+5: 3614
+5: 3615
+5: 3616
+5: 3617
+5: 3618
+5: 3619
+5: 3620
+5: 3621
+5: 3622
+5: 3623
+5: 3624
+5: 3625
+5: 3626
+5: 3627
+5: 3628
+5: 3629
+5: 3630
+5: 3631
+5: 3632
+5: 3633
+5: 3634
+5: 3635
+5: 3636
+5: 3637
+5: 3638
+5: 3639
+5: 3640
+5: 3641
+5: 3642
+5: 3643
+5: 3644
+5: 3645
+5: 3646
+5: 3647
+5: 3648
+5: 3649
+5: 3650
+5: 3651
+5: 3652
+5: 3653
+5: 3654
+5: 3655
+5: 3656
+5: 3657
+5: 3658
+5: 3659
+5: 3660
+5: 3661
+5: 3662
+5: 3663
+5: 3664
+5: 3665
+5: 3666
+5: 3667
+5: 3668
+5: 3669
+5: 3670
+5: 3671
+4: 3283
+4: 3284
+4: 3285
+4: 3286
+4: 3287
+4: 3288
+4: 3289
+4: 3290
+4: 3291
+4: 3292
+4: 3293
+4: 3294
+4: 3295
+4: 3296
+4: 3297
+4: 3298
+4: 3299
+4: 3300
+4: 3301
+4: 3302
+4: 3303
+4: 3304
+4: 3305
+4: 3306
+4: 3307
+4: 3308
+4: 3309
+4: 3310
+4: 3311
+4: 3312
+4: 3313
+4: 3314
+4: 3315
+4: 3316
+4: 3317
+4: 3318
+4: 3319
+4: 3320
+4: 3321
+4: 3322
+4: 3323
+4: 3324
+4: 3325
+4: 3326
+4: 3327
+4: 3328
+4: 3329
+4: 3330
+4: 3331
+4: 3332
+4: 3333
+4: 3334
+4: 3335
+4: 3336
+4: 3337
+4: 3338
+4: 3339
+4: 3340
+4: 3341
+4: 3342
+4: 3343
+4: 3344
+4: 3345
+4: 3346
+4: 3347
+4: 3348
+4: 3349
+4: 3350
+4: 3351
+4: 3352
+4: 3353
+4: 3354
+4: 3355
+4: 3356
+4: 3357
+4: 3358
+4: 3359
+4: 3360
+4: 3361
+4: 3362
+4: 3363
+4: 3364
+4: 3365
+4: 3366
+4: 3367
+4: 3368
+4: 3369
+4: 3370
+4: 3371
+4: 3372
+4: 3373
+4: 3374
+4: 3375
+4: 3376
+4: 3377
+4: 3378
+4: 3379
+4: 3380
+4: 3381
+4: 3382
+4: 3383
+4: 3384
+4: 3385
+4: 3386
+4: 3387
+4: 3388
+4: 3389
+4: 3390
+4: 3391
+4: 3392
+4: 3393
+4: 3394
+4: 3395
+4: 3396
+4: 3397
+4: 3398
+4: 3399
+4: 3400
+4: 3401
+4: 3402
+4: 3403
+4: 3404
+4: 3405
+4: 3406
+4: 3407
+4: 3408
+4: 3409
+4: 3410
+4: 3411
+4: 3412
+4: 3413
+4: 3414
+4: 3415
+4: 3416
+4: 3417
+4: 3418
+4: 3419
+4: 3420
+4: 3421
+4: 3422
+4: 3423
+4: 3424
+4: 3425
+4: 3426
+4: 3427
+4: 3428
+4: 3429
+4: 3430
+4: 3431
+4: 3432
+4: 3433
+4: 3434
+4: 3435
+4: 3436
+4: 3437
+4: 3438
+4: 3439
+4: 3440
+4: 3441
+4: 3442
+4: 3443
+4: 3444
+4: 3445
+4: 3446
+4: 3447
+4: 3448
+4: 3449
+4: 3450
+4: 3451
+4: 3452
+4: 3453
+4: 3454
+4: 3455
+4: 3456
+4: 3457
+4: 3458
+4: 3459
+4: 3460
+4: 3461
+4: 3462
+4: 3463
+4: 3464
+4: 3465
+4: 3466
+4: 3467
+4: 3468
+4: 3469
+4: 3470
+4: 3471
+4: 3472
+4: 3473
+4: 3474
+4: 3475
+4: 3476
+4: 3477
+4: 3478
+4: 3479
+4: 3480
+4: 3481
+4: 3482
+4: 3483
+4: 3484
+4: 3485
+4: 3486
+4: 3487
+4: 3488
+4: 3489
+4: 3490
+4: 3491
+4: 3492
+4: 3493
+4: 3494
+4: 3495
+4: 3496
+4: 3497
+4: 3498
+4: 3499
+4: 3500
+4: 3501
+4: 3502
+4: 3503
+4: 3504
+4: 3505
+4: 3506
+4: 3507
+4: 3508
+4: 3509
+4: 3510
+4: 3511
+4: 3512
+4: 3513
+4: 3514
+4: 3515
+4: 3516
+4: 3517
+4: 3518
+4: 3519
+4: 3520
+4: 3521
+4: 3522
+4: 3523
+4: 3524
+4: 3525
+4: 3526
+4: 3527
+4: 3528
+4: 3529
+4: 3530
+4: 3531
+4: 3532
+4: 3533
+4: 3534
+4: 3535
+4: 3536
+4: 3537
+4: 3538
+4: 3539
+4: 3540
+4: 3541
+4: 3542
+4: 3543
+4: 3544
+4: 3545
+4: 3546
+4: 3547
+4: 3548
+4: 3549
+4: 3550
+4: 3551
+4: 3552
+4: 3553
+4: 3554
+4: 3555
+4: 3556
+4: 3557
+4: 3558
+4: 3559
+4: 3560
+4: 3561
+4: 3562
+4: 3563
+4: 3564
+4: 3565
+4: 3566
+4: 3567
+4: 3568
+4: 3569
+4: 3570
+4: 3571
+4: 3572
+4: 3573
+4: 3574
+4: 3575
+4: 3576
+4: 3577
+4: 3578
+4: 3579
+4: 3580
+4: 3581
+4: 3582
+4: 3583
+4: 3584
+4: 3585
+4: 3586
+4: 3587
+4: 3588
+4: 3589
+4: 3590
+4: 3591
+4: 3592
+4: 3593
+4: 3594
+4: 3595
+4: 3596
+4: 3597
+4: 3598
+4: 3599
+4: 3600
+4: 3601
+4: 3602
+4: 3603
+4: 3604
+5: 3672
+5: 3673
+5: 3674
+5: 3675
+5: 3676
+5: 3677
+5: 3678
+5: 3679
+5: 3680
+5: 3681
+5: 3682
+5: 3683
+5: 3684
+5: 3685
+5: 3686
+5: 3687
+5: 3688
+5: 3689
+5: 3690
+5: 3691
+5: 3692
+5: 3693
+5: 3694
+5: 3695
+5: 3696
+5: 3697
+5: 3698
+5: 3699
+5: 3700
+5: 3701
+5: 3702
+5: 3703
+5: 3704
+5: 3705
+5: 3706
+5: 3707
+5: 3708
+5: 3709
+5: 3710
+5: 3711
+5: 3712
+5: 3713
+5: 3714
+5: 3715
+5: 3716
+5: 3717
+5: 3718
+5: 3719
+5: 3720
+5: 3721
+5: 3722
+5: 3723
+5: 3724
+5: 3725
+5: 3726
+5: 3727
+5: 3728
+5: 3729
+5: 3730
+5: 3731
+5: 3732
+5: 3733
+5: 3734
+5: 3735
+5: 3736
+5: 3737
+5: 3738
+5: 3739
+5: 3740
+5: 3741
+5: 3742
+5: 3743
+5: 3744
+5: 3745
+5: 3746
+5: 3747
+5: 3748
+5: 3749
+5: 3750
+5: 3751
+5: 3752
+5: 3753
+5: 3754
+5: 3755
+5: 3756
+5: 3757
+5: 3758
+5: 3759
+5: 3760
+5: 3761
+5: 3762
+5: 3763
+5: 3764
+5: 3765
+5: 3766
+5: 3767
+5: 3768
+5: 3769
+5: 3770
+5: 3771
+5: 3772
+5: 3773
+5: 3774
+5: 3775
+5: 3776
+5: 3777
+5: 3778
+5: 3779
+5: 3780
+5: 3781
+5: 3782
+5: 3783
+5: 3784
+5: 3785
+5: 3786
+5: 3787
+5: 3788
+5: 3789
+5: 3790
+5: 3791
+5: 3792
+5: 3793
+5: 3794
+5: 3795
+5: 3796
+5: 3797
+5: 3798
+5: 3799
+5: 3800
+5: 3801
+5: 3802
+5: 3803
+5: 3804
+5: 3805
+5: 3806
+5: 3807
+5: 3808
+5: 3809
+5: 3810
+5: 3811
+5: 3812
+5: 3813
+5: 3814
+5: 3815
+5: 3816
+5: 3817
+5: 3818
+5: 3819
+5: 3820
+5: 3821
+5: 3822
+5: 3823
+5: 3824
+5: 3825
+5: 3826
+5: 3827
+5: 3828
+5: 3829
+5: 3830
+5: 3831
+5: 3832
+5: 3833
+5: 3834
+5: 3835
+5: 3836
+5: 3837
+5: 3838
+5: 3839
+5: 3840
+5: 3841
+5: 3842
+5: 3843
+5: 3844
+5: 3845
+5: 3846
+5: 3847
+5: 3848
+5: 3849
+5: 3850
+5: 3851
+5: 3852
+5: 3853
+5: 3854
+5: 3855
+5: 3856
+5: 3857
+5: 3858
+5: 3859
+5: 3860
+5: 3861
+5: 3862
+5: 3863
+5: 3864
+5: 3865
+5: 3866
+5: 3867
+5: 3868
+5: 3869
+5: 3870
+5: 3871
+5: 3872
+5: 3873
+5: 3874
+5: 3875
+5: 3876
+5: 3877
+5: 3878
+5: 3879
+5: 3880
+5: 3881
+5: 3882
+5: 3883
+5: 3884
+5: 3885
+5: 3886
+5: 3887
+5: 3888
+5: 3889
+5: 3890
+5: 3891
+5: 3892
+5: 3893
+5: 3894
+5: 3895
+5: 3896
+5: 3897
+5: 3898
+5: 3899
+5: 3900
+5: 3901
+5: 3902
+5: 3903
+5: 3904
+5: 3905
+5: 3906
+5: 3907
+5: 3908
+5: 3909
+5: 3910
+5: 3911
+5: 3912
+5: 3913
+5: 3914
+5: 3915
+5: 3916
+5: 3917
+5: 3918
+5: 3919
+5: 3920
+5: 3921
+5: 3922
+5: 3923
+5: 3924
+5: 3925
+5: 3926
+5: 3927
+5: 3928
+5: 3929
+5: 3930
+5: 3931
+5: 3932
+5: 3933
+5: 3934
+5: 3935
+5: 3936
+5: 3937
+5: 3938
+5: 3939
+5: 3940
+5: 3941
+5: 3942
+5: 3943
+5: 3944
+5: 3945
+5: 3946
+5: 3947
+5: 3948
+5: 3949
+5: 3950
+5: 3951
+5: 3952
+5: 3953
+5: 3954
+5: 3955
+5: 3956
+5: 3957
+5: 3958
+5: 3959
+5: 3960
+5: 3961
+5: 3962
+5: 3963
+5: 3964
+5: 3965
+5: 3966
+5: 3967
+5: 3968
+5: 3969
+5: 3970
+5: 3971
+5: 3972
+5: 3973
+5: 3974
+5: 3975
+5: 3976
+5: 3977
+5: 3978
+5: 3979
+5: 3980
+5: 3981
+5: 3982
+5: 3983
+5: 3984
+5: 3985
+5: 3986
+5: 3987
+5: 3988
+5: 3989
+5: 3990
+5: 3991
+5: 3992
+5: 3993
+5: 3994
+5: 3995
+5: 3996
+5: 3997
+5: 3998
+5: 3999
+5: 4000
+5: 4001
+5: 4002
+5: 4003
+5: 4004
+5: 4005
+5: 4006
+5: 4007
+5: 4008
+5: 4009
+5: 4010
+5: 4011
+5: 4012
+5: 4013
+5: 4014
+5: 4015
+5: 4016
+5: 4017
+5: 4018
+5: 4019
+5: 4020
+5: 4021
+5: 4022
+5: 4023
+5: 4024
+5: 4025
+5: 4026
+5: 4027
+5: 4028
+5: 4029
+5: 4030
+5: 4031
+5: 4032
+5: 4033
+5: 4034
+5: 4035
+5: 4036
+5: 4037
+5: 4038
+5: 4039
+5: 4040
+5: 4041
+5: 4042
+5: 4043
+5: 4044
+5: 4045
+5: 4046
+5: 4047
+5: 4048
+5: 4049
+5: 4050
+5: 4051
+5: 4052
+5: 4053
+5: 4054
+5: 4055
+5: 4056
+5: 4057
+5: 4058
+5: 4059
+5: 4060
+5: 4061
+5: 4062
+5: 4063
+5: 4064
+5: 4065
+5: 4066
+5: 4067
+5: 4068
+5: 4069
+5: 4070
+5: 4071
+5: 4072
+5: 4073
+5: 4074
+5: 4075
+5: 4076
+5: 4077
+5: 4078
+5: 4079
+5: 4080
+5: 4081
+5: 4082
+5: 4083
+5: 4084
+5: 4085
+5: 4086
+5: 4087
+5: 4088
+5: 4089
+5: 4090
+5: 4091
+5: 4092
+5: 4093
+5: 4094
+5: 4095
+5: 4096
+5: 4097
+5: 4098
+5: 4099
+5: 4100
+5: 4101
+5: 4102
+5: 4103
+5: 4104
+5: 4105
+5: 4106
+5: 4107
+5: 4108
+5: 4109
+5: 4110
+5: 4111
+5: 4112
+5: 4113
+5: 4114
+4: 3605
+4: 3606
+4: 3607
+4: 3608
+4: 3609
+4: 3610
+4: 3611
+4: 3612
+4: 3613
+4: 3614
+4: 3615
+4: 3616
+4: 3617
+4: 3618
+4: 3619
+4: 3620
+4: 3621
+4: 3622
+4: 3623
+4: 3624
+4: 3625
+4: 3626
+4: 3627
+4: 3628
+4: 3629
+4: 3630
+4: 3631
+4: 3632
+4: 3633
+4: 3634
+4: 3635
+4: 3636
+4: 3637
+4: 3638
+4: 3639
+4: 3640
+4: 3641
+4: 3642
+4: 3643
+4: 3644
+4: 3645
+4: 3646
+4: 3647
+4: 3648
+4: 3649
+4: 3650
+4: 3651
+4: 3652
+4: 3653
+4: 3654
+4: 3655
+4: 3656
+4: 3657
+4: 3658
+4: 3659
+4: 3660
+4: 3661
+4: 3662
+4: 3663
+4: 3664
+4: 3665
+4: 3666
+4: 3667
+4: 3668
+4: 3669
+4: 3670
+4: 3671
+4: 3672
+4: 3673
+4: 3674
+4: 3675
+4: 3676
+4: 3677
+4: 3678
+4: 3679
+4: 3680
+4: 3681
+4: 3682
+4: 3683
+4: 3684
+4: 3685
+4: 3686
+4: 3687
+4: 3688
+4: 3689
+4: 3690
+4: 3691
+4: 3692
+4: 3693
+4: 3694
+4: 3695
+4: 3696
+4: 3697
+4: 3698
+4: 3699
+4: 3700
+4: 3701
+4: 3702
+4: 3703
+4: 3704
+4: 3705
+4: 3706
+4: 3707
+4: 3708
+4: 3709
+4: 3710
+4: 3711
+4: 3712
+4: 3713
+4: 3714
+4: 3715
+4: 3716
+4: 3717
+4: 3718
+4: 3719
+4: 3720
+4: 3721
+4: 3722
+4: 3723
+4: 3724
+4: 3725
+4: 3726
+4: 3727
+4: 3728
+4: 3729
+4: 3730
+4: 3731
+4: 3732
+4: 3733
+4: 3734
+4: 3735
+4: 3736
+4: 3737
+4: 3738
+4: 3739
+4: 3740
+4: 3741
+4: 3742
+4: 3743
+4: 3744
+4: 3745
+4: 3746
+4: 3747
+4: 3748
+4: 3749
+4: 3750
+4: 3751
+4: 3752
+4: 3753
+4: 3754
+4: 3755
+4: 3756
+4: 3757
+4: 3758
+4: 3759
+4: 3760
+4: 3761
+4: 3762
+4: 3763
+4: 3764
+4: 3765
+4: 3766
+4: 3767
+4: 3768
+4: 3769
+4: 3770
+4: 3771
+4: 3772
+4: 3773
+4: 3774
+4: 3775
+4: 3776
+4: 3777
+4: 3778
+4: 3779
+4: 3780
+4: 3781
+4: 3782
+4: 3783
+4: 3784
+4: 3785
+4: 3786
+4: 3787
+4: 3788
+4: 3789
+4: 3790
+4: 3791
+4: 3792
+4: 3793
+4: 3794
+4: 3795
+4: 3796
+4: 3797
+4: 3798
+4: 3799
+4: 3800
+4: 3801
+4: 3802
+4: 3803
+4: 3804
+4: 3805
+4: 3806
+4: 3807
+4: 3808
+4: 3809
+4: 3810
+4: 3811
+4: 3812
+4: 3813
+4: 3814
+4: 3815
+4: 3816
+4: 3817
+4: 3818
+4: 3819
+4: 3820
+4: 3821
+4: 3822
+4: 3823
+4: 3824
+4: 3825
+4: 3826
+4: 3827
+4: 3828
+4: 3829
+4: 3830
+4: 3831
+4: 3832
+4: 3833
+4: 3834
+4: 3835
+4: 3836
+4: 3837
+4: 3838
+4: 3839
+4: 3840
+4: 3841
+4: 3842
+4: 3843
+4: 3844
+4: 3845
+4: 3846
+4: 3847
+4: 3848
+4: 3849
+4: 3850
+4: 3851
+4: 3852
+4: 3853
+4: 3854
+4: 3855
+4: 3856
+4: 3857
+4: 3858
+4: 3859
+4: 3860
+4: 3861
+4: 3862
+4: 3863
+4: 3864
+4: 3865
+4: 3866
+4: 3867
+4: 3868
+4: 3869
+4: 3870
+4: 3871
+4: 3872
+4: 3873
+4: 3874
+4: 3875
+4: 3876
+4: 3877
+4: 3878
+4: 3879
+4: 3880
+4: 3881
+4: 3882
+4: 3883
+4: 3884
+4: 3885
+4: 3886
+4: 3887
+4: 3888
+4: 3889
+4: 3890
+4: 3891
+4: 3892
+4: 3893
+4: 3894
+4: 3895
+4: 3896
+4: 3897
+4: 3898
+4: 3899
+4: 3900
+4: 3901
+4: 3902
+4: 3903
+4: 3904
+4: 3905
+4: 3906
+4: 3907
+4: 3908
+4: 3909
+4: 3910
+4: 3911
+4: 3912
+4: 3913
+4: 3914
+4: 3915
+4: 3916
+4: 3917
+4: 3918
+4: 3919
+4: 3920
+4: 3921
+4: 3922
+4: 3923
+4: 3924
+4: 3925
+4: 3926
+4: 3927
+4: 3928
+4: 3929
+4: 3930
+4: 3931
+4: 3932
+4: 3933
+4: 3934
+4: 3935
+4: 3936
+4: 3937
+4: 3938
+4: 3939
+4: 3940
+4: 3941
+4: 3942
+4: 3943
+4: 3944
+4: 3945
+4: 3946
+4: 3947
+4: 3948
+4: 3949
+4: 3950
+4: 3951
+4: 3952
+4: 3953
+4: 3954
+4: 3955
+4: 3956
+4: 3957
+4: 3958
+4: 3959
+4: 3960
+4: 3961
+4: 3962
+4: 3963
+4: 3964
+4: 3965
+4: 3966
+4: 3967
+4: 3968
+4: 3969
+4: 3970
+4: 3971
+4: 3972
+4: 3973
+4: 3974
+4: 3975
+4: 3976
+4: 3977
+4: 3978
+4: 3979
+4: 3980
+4: 3981
+4: 3982
+4: 3983
+4: 3984
+4: 3985
+4: 3986
+4: 3987
+4: 3988
+4: 3989
+4: 3990
+4: 3991
+4: 3992
+4: 3993
+4: 3994
+4: 3995
+4: 3996
+4: 3997
+4: 3998
+4: 3999
+4: 4000
+4: 4001
+4: 4002
+4: 4003
+4: 4004
+4: 4005
+4: 4006
+4: 4007
+4: 4008
+4: 4009
+4: 4010
+4: 4011
+4: 4012
+4: 4013
+4: 4014
+4: 4015
+4: 4016
+4: 4017
+4: 4018
+4: 4019
+4: 4020
+5: 4115
+5: 4116
+5: 4117
+5: 4118
+5: 4119
+5: 4120
+5: 4121
+5: 4122
+5: 4123
+5: 4124
+5: 4125
+5: 4126
+5: 4127
+5: 4128
+5: 4129
+5: 4130
+5: 4131
+5: 4132
+5: 4133
+5: 4134
+5: 4135
+5: 4136
+5: 4137
+5: 4138
+5: 4139
+5: 4140
+5: 4141
+5: 4142
+5: 4143
+5: 4144
+5: 4145
+5: 4146
+5: 4147
+5: 4148
+5: 4149
+5: 4150
+5: 4151
+5: 4152
+5: 4153
+5: 4154
+5: 4155
+5: 4156
+5: 4157
+5: 4158
+5: 4159
+5: 4160
+5: 4161
+5: 4162
+5: 4163
+5: 4164
+5: 4165
+5: 4166
+5: 4167
+5: 4168
+5: 4169
+5: 4170
+5: 4171
+5: 4172
+5: 4173
+5: 4174
+5: 4175
+5: 4176
+5: 4177
+5: 4178
+5: 4179
+5: 4180
+5: 4181
+5: 4182
+5: 4183
+5: 4184
+5: 4185
+5: 4186
+5: 4187
+5: 4188
+5: 4189
+5: 4190
+5: 4191
+5: 4192
+5: 4193
+5: 4194
+5: 4195
+5: 4196
+5: 4197
+5: 4198
+5: 4199
+5: 4200
+5: 4201
+5: 4202
+5: 4203
+5: 4204
+5: 4205
+5: 4206
+5: 4207
+5: 4208
+5: 4209
+5: 4210
+5: 4211
+5: 4212
+5: 4213
+5: 4214
+5: 4215
+5: 4216
+5: 4217
+5: 4218
+5: 4219
+5: 4220
+5: 4221
+5: 4222
+5: 4223
+5: 4224
+5: 4225
+5: 4226
+5: 4227
+5: 4228
+5: 4229
+5: 4230
+5: 4231
+5: 4232
+5: 4233
+5: 4234
+5: 4235
+5: 4236
+5: 4237
+5: 4238
+5: 4239
+5: 4240
+5: 4241
+5: 4242
+5: 4243
+5: 4244
+5: 4245
+5: 4246
+5: 4247
+5: 4248
+5: 4249
+5: 4250
+5: 4251
+5: 4252
+5: 4253
+5: 4254
+5: 4255
+5: 4256
+5: 4257
+5: 4258
+5: 4259
+5: 4260
+5: 4261
+5: 4262
+5: 4263
+5: 4264
+5: 4265
+5: 4266
+5: 4267
+5: 4268
+5: 4269
+5: 4270
+5: 4271
+5: 4272
+5: 4273
+5: 4274
+5: 4275
+5: 4276
+5: 4277
+5: 4278
+5: 4279
+5: 4280
+5: 4281
+5: 4282
+5: 4283
+5: 4284
+5: 4285
+5: 4286
+5: 4287
+5: 4288
+5: 4289
+5: 4290
+5: 4291
+5: 4292
+5: 4293
+5: 4294
+5: 4295
+5: 4296
+5: 4297
+5: 4298
+5: 4299
+5: 4300
+5: 4301
+5: 4302
+5: 4303
+5: 4304
+5: 4305
+5: 4306
+5: 4307
+4: 4021
+4: 4022
+4: 4023
+4: 4024
+4: 4025
+4: 4026
+4: 4027
+4: 4028
+4: 4029
+4: 4030
+4: 4031
+4: 4032
+4: 4033
+4: 4034
+4: 4035
+4: 4036
+4: 4037
+4: 4038
+4: 4039
+4: 4040
+4: 4041
+4: 4042
+4: 4043
+4: 4044
+4: 4045
+4: 4046
+4: 4047
+4: 4048
+4: 4049
+4: 4050
+4: 4051
+4: 4052
+4: 4053
+4: 4054
+4: 4055
+4: 4056
+4: 4057
+4: 4058
+4: 4059
+4: 4060
+4: 4061
+4: 4062
+4: 4063
+4: 4064
+4: 4065
+4: 4066
+4: 4067
+4: 4068
+4: 4069
+4: 4070
+4: 4071
+4: 4072
+4: 4073
+4: 4074
+4: 4075
+4: 4076
+4: 4077
+4: 4078
+4: 4079
+4: 4080
+4: 4081
+4: 4082
+4: 4083
+4: 4084
+4: 4085
+4: 4086
+4: 4087
+4: 4088
+4: 4089
+4: 4090
+4: 4091
+4: 4092
+4: 4093
+4: 4094
+4: 4095
+4: 4096
+4: 4097
+4: 4098
+4: 4099
+4: 4100
+4: 4101
+4: 4102
+4: 4103
+4: 4104
+4: 4105
+4: 4106
+4: 4107
+4: 4108
+4: 4109
+4: 4110
+4: 4111
+4: 4112
+4: 4113
+4: 4114
+4: 4115
+4: 4116
+4: 4117
+4: 4118
+4: 4119
+4: 4120
+4: 4121
+4: 4122
+4: 4123
+4: 4124
+4: 4125
+4: 4126
+4: 4127
+4: 4128
+4: 4129
+4: 4130
+4: 4131
+4: 4132
+4: 4133
+4: 4134
+4: 4135
+4: 4136
+4: 4137
+4: 4138
+4: 4139
+4: 4140
+4: 4141
+4: 4142
+4: 4143
+4: 4144
+4: 4145
+4: 4146
+4: 4147
+4: 4148
+4: 4149
+4: 4150
+4: 4151
+4: 4152
+4: 4153
+4: 4154
+4: 4155
+4: 4156
+4: 4157
+4: 4158
+4: 4159
+4: 4160
+4: 4161
+4: 4162
+4: 4163
+4: 4164
+4: 4165
+4: 4166
+4: 4167
+4: 4168
+4: 4169
+4: 4170
+4: 4171
+4: 4172
+4: 4173
+4: 4174
+4: 4175
+4: 4176
+4: 4177
+4: 4178
+4: 4179
+4: 4180
+4: 4181
+4: 4182
+4: 4183
+4: 4184
+4: 4185
+4: 4186
+4: 4187
+4: 4188
+4: 4189
+4: 4190
+4: 4191
+4: 4192
+4: 4193
+4: 4194
+4: 4195
+4: 4196
+4: 4197
+4: 4198
+4: 4199
+4: 4200
+4: 4201
+4: 4202
+4: 4203
+4: 4204
+4: 4205
+4: 4206
+4: 4207
+4: 4208
+4: 4209
+4: 4210
+4: 4211
+4: 4212
+4: 4213
+4: 4214
+4: 4215
+4: 4216
+4: 4217
+4: 4218
+5: 4308
+5: 4309
+5: 4310
+5: 4311
+5: 4312
+5: 4313
+5: 4314
+5: 4315
+5: 4316
+5: 4317
+5: 4318
+5: 4319
+5: 4320
+5: 4321
+5: 4322
+5: 4323
+5: 4324
+5: 4325
+5: 4326
+5: 4327
+5: 4328
+5: 4329
+5: 4330
+5: 4331
+5: 4332
+5: 4333
+5: 4334
+5: 4335
+5: 4336
+5: 4337
+5: 4338
+5: 4339
+5: 4340
+5: 4341
+5: 4342
+5: 4343
+5: 4344
+5: 4345
+5: 4346
+5: 4347
+5: 4348
+5: 4349
+5: 4350
+5: 4351
+5: 4352
+5: 4353
+5: 4354
+5: 4355
+5: 4356
+5: 4357
+5: 4358
+5: 4359
+5: 4360
+5: 4361
+5: 4362
+5: 4363
+5: 4364
+5: 4365
+5: 4366
+5: 4367
+5: 4368
+5: 4369
+5: 4370
+5: 4371
+5: 4372
+5: 4373
+5: 4374
+5: 4375
+5: 4376
+5: 4377
+5: 4378
+5: 4379
+5: 4380
+5: 4381
+5: 4382
+5: 4383
+5: 4384
+5: 4385
+5: 4386
+5: 4387
+5: 4388
+5: 4389
+5: 4390
+5: 4391
+5: 4392
+5: 4393
+5: 4394
+5: 4395
+5: 4396
+5: 4397
+5: 4398
+5: 4399
+5: 4400
+5: 4401
+5: 4402
+5: 4403
+5: 4404
+5: 4405
+4: 4219
+4: 4220
+4: 4221
+4: 4222
+4: 4223
+4: 4224
+4: 4225
+4: 4226
+4: 4227
+4: 4228
+4: 4229
+4: 4230
+4: 4231
+4: 4232
+4: 4233
+4: 4234
+4: 4235
+4: 4236
+4: 4237
+4: 4238
+4: 4239
+4: 4240
+4: 4241
+4: 4242
+4: 4243
+4: 4244
+4: 4245
+4: 4246
+4: 4247
+4: 4248
+4: 4249
+4: 4250
+4: 4251
+4: 4252
+4: 4253
+4: 4254
+4: 4255
+4: 4256
+4: 4257
+4: 4258
+4: 4259
+4: 4260
+4: 4261
+4: 4262
+4: 4263
+4: 4264
+4: 4265
+4: 4266
+4: 4267
+4: 4268
+4: 4269
+4: 4270
+4: 4271
+4: 4272
+4: 4273
+4: 4274
+4: 4275
+4: 4276
+4: 4277
+4: 4278
+4: 4279
+4: 4280
+4: 4281
+4: 4282
+4: 4283
+4: 4284
+4: 4285
+4: 4286
+4: 4287
+4: 4288
+4: 4289
+4: 4290
+4: 4291
+4: 4292
+4: 4293
+4: 4294
+4: 4295
+4: 4296
+4: 4297
+4: 4298
+4: 4299
+4: 4300
+4: 4301
+4: 4302
+4: 4303
+4: 4304
+4: 4305
+4: 4306
+4: 4307
+4: 4308
+4: 4309
+4: 4310
+4: 4311
+4: 4312
+4: 4313
+4: 4314
+4: 4315
+4: 4316
+4: 4317
+4: 4318
+4: 4319
+4: 4320
+4: 4321
+4: 4322
+4: 4323
+4: 4324
+4: 4325
+4: 4326
+4: 4327
+4: 4328
+4: 4329
+4: 4330
+4: 4331
+4: 4332
+4: 4333
+4: 4334
+4: 4335
+4: 4336
+4: 4337
+4: 4338
+4: 4339
+4: 4340
+4: 4341
+4: 4342
+4: 4343
+4: 4344
+4: 4345
+4: 4346
+4: 4347
+4: 4348
+4: 4349
+4: 4350
+4: 4351
+4: 4352
+4: 4353
+4: 4354
+4: 4355
+4: 4356
+4: 4357
+4: 4358
+4: 4359
+4: 4360
+4: 4361
+4: 4362
+4: 4363
+4: 4364
+4: 4365
+4: 4366
+4: 4367
+4: 4368
+4: 4369
+4: 4370
+4: 4371
+4: 4372
+4: 4373
+4: 4374
+4: 4375
+4: 4376
+4: 4377
+4: 4378
+4: 4379
+4: 4380
+4: 4381
+4: 4382
+4: 4383
+4: 4384
+4: 4385
+4: 4386
+4: 4387
+4: 4388
+4: 4389
+4: 4390
+4: 4391
+4: 4392
+4: 4393
+4: 4394
+4: 4395
+4: 4396
+4: 4397
+4: 4398
+4: 4399
+4: 4400
+4: 4401
+4: 4402
+4: 4403
+4: 4404
+4: 4405
+4: 4406
+4: 4407
+4: 4408
+4: 4409
+4: 4410
+4: 4411
+4: 4412
+4: 4413
+4: 4414
+4: 4415
+4: 4416
+4: 4417
+4: 4418
+4: 4419
+4: 4420
+4: 4421
+4: 4422
+4: 4423
+4: 4424
+4: 4425
+4: 4426
+4: 4427
+4: 4428
+4: 4429
+4: 4430
+4: 4431
+4: 4432
+4: 4433
+4: 4434
+4: 4435
+4: 4436
+4: 4437
+4: 4438
+4: 4439
+4: 4440
+4: 4441
+4: 4442
+4: 4443
+4: 4444
+4: 4445
+4: 4446
+4: 4447
+4: 4448
+4: 4449
+4: 4450
+4: 4451
+4: 4452
+4: 4453
+4: 4454
+4: 4455
+4: 4456
+4: 4457
+4: 4458
+4: 4459
+4: 4460
+4: 4461
+4: 4462
+4: 4463
+4: 4464
+4: 4465
+4: 4466
+4: 4467
+4: 4468
+4: 4469
+4: 4470
+4: 4471
+4: 4472
+4: 4473
+4: 4474
+4: 4475
+4: 4476
+4: 4477
+4: 4478
+4: 4479
+4: 4480
+4: 4481
+4: 4482
+4: 4483
+4: 4484
+4: 4485
+4: 4486
+4: 4487
+4: 4488
+4: 4489
+4: 4490
+4: 4491
+4: 4492
+4: 4493
+4: 4494
+4: 4495
+4: 4496
+4: 4497
+4: 4498
+4: 4499
+4: 4500
+4: 4501
+4: 4502
+4: 4503
+4: 4504
+4: 4505
+4: 4506
+4: 4507
+4: 4508
+4: 4509
+4: 4510
+4: 4511
+4: 4512
+4: 4513
+4: 4514
+4: 4515
+4: 4516
+4: 4517
+4: 4518
+4: 4519
+4: 4520
+4: 4521
+4: 4522
+4: 4523
+4: 4524
+4: 4525
+4: 4526
+4: 4527
+4: 4528
+4: 4529
+4: 4530
+4: 4531
+4: 4532
+4: 4533
+4: 4534
+4: 4535
+4: 4536
+4: 4537
+4: 4538
+4: 4539
+4: 4540
+4: 4541
+4: 4542
+4: 4543
+4: 4544
+4: 4545
+4: 4546
+4: 4547
+4: 4548
+5: 4406
+5: 4407
+5: 4408
+5: 4409
+5: 4410
+5: 4411
+5: 4412
+5: 4413
+5: 4414
+5: 4415
+5: 4416
+5: 4417
+5: 4418
+5: 4419
+5: 4420
+5: 4421
+5: 4422
+5: 4423
+5: 4424
+5: 4425
+5: 4426
+5: 4427
+5: 4428
+5: 4429
+5: 4430
+5: 4431
+5: 4432
+5: 4433
+5: 4434
+5: 4435
+5: 4436
+5: 4437
+5: 4438
+5: 4439
+5: 4440
+5: 4441
+5: 4442
+5: 4443
+5: 4444
+5: 4445
+5: 4446
+5: 4447
+5: 4448
+5: 4449
+5: 4450
+5: 4451
+5: 4452
+5: 4453
+5: 4454
+5: 4455
+5: 4456
+5: 4457
+5: 4458
+5: 4459
+5: 4460
+5: 4461
+5: 4462
+5: 4463
+5: 4464
+5: 4465
+5: 4466
+5: 4467
+5: 4468
+5: 4469
+5: 4470
+5: 4471
+5: 4472
+5: 4473
+5: 4474
+5: 4475
+5: 4476
+5: 4477
+5: 4478
+5: 4479
+5: 4480
+5: 4481
+5: 4482
+5: 4483
+5: 4484
+5: 4485
+5: 4486
+5: 4487
+5: 4488
+5: 4489
+5: 4490
+5: 4491
+5: 4492
+5: 4493
+5: 4494
+5: 4495
+5: 4496
+5: 4497
+5: 4498
+5: 4499
+5: 4500
+5: 4501
+5: 4502
+5: 4503
+5: 4504
+5: 4505
+5: 4506
+5: 4507
+5: 4508
+5: 4509
+5: 4510
+5: 4511
+5: 4512
+5: 4513
+5: 4514
+5: 4515
+5: 4516
+5: 4517
+5: 4518
+5: 4519
+5: 4520
+5: 4521
+5: 4522
+5: 4523
+5: 4524
+5: 4525
+5: 4526
+5: 4527
+5: 4528
+5: 4529
+5: 4530
+5: 4531
+5: 4532
+5: 4533
+5: 4534
+5: 4535
+5: 4536
+5: 4537
+5: 4538
+5: 4539
+5: 4540
+5: 4541
+5: 4542
+5: 4543
+5: 4544
+5: 4545
+5: 4546
+5: 4547
+5: 4548
+5: 4549
+5: 4550
+5: 4551
+5: 4552
+5: 4553
+5: 4554
+5: 4555
+5: 4556
+5: 4557
+5: 4558
+5: 4559
+5: 4560
+5: 4561
+5: 4562
+5: 4563
+5: 4564
+5: 4565
+5: 4566
+5: 4567
+5: 4568
+5: 4569
+5: 4570
+5: 4571
+5: 4572
+5: 4573
+5: 4574
+5: 4575
+5: 4576
+5: 4577
+5: 4578
+5: 4579
+5: 4580
+5: 4581
+5: 4582
+5: 4583
+5: 4584
+5: 4585
+5: 4586
+5: 4587
+5: 4588
+5: 4589
+5: 4590
+5: 4591
+5: 4592
+5: 4593
+5: 4594
+5: 4595
+5: 4596
+5: 4597
+5: 4598
+5: 4599
+5: 4600
+5: 4601
+5: 4602
+5: 4603
+5: 4604
+5: 4605
+5: 4606
+5: 4607
+5: 4608
+5: 4609
+5: 4610
+5: 4611
+5: 4612
+5: 4613
+5: 4614
+5: 4615
+5: 4616
+5: 4617
+5: 4618
+5: 4619
+5: 4620
+5: 4621
+5: 4622
+5: 4623
+5: 4624
+5: 4625
+5: 4626
+5: 4627
+5: 4628
+5: 4629
+5: 4630
+5: 4631
+5: 4632
+5: 4633
+5: 4634
+5: 4635
+5: 4636
+5: 4637
+5: 4638
+5: 4639
+5: 4640
+5: 4641
+5: 4642
+5: 4643
+5: 4644
+5: 4645
+5: 4646
+5: 4647
+5: 4648
+5: 4649
+5: 4650
+5: 4651
+5: 4652
+5: 4653
+5: 4654
+5: 4655
+5: 4656
+5: 4657
+5: 4658
+5: 4659
+5: 4660
+5: 4661
+5: 4662
+5: 4663
+5: 4664
+5: 4665
+5: 4666
+5: 4667
+5: 4668
+5: 4669
+5: 4670
+5: 4671
+5: 4672
+5: 4673
+5: 4674
+5: 4675
+5: 4676
+5: 4677
+5: 4678
+5: 4679
+5: 4680
+5: 4681
+5: 4682
+5: 4683
+5: 4684
+5: 4685
+5: 4686
+5: 4687
+5: 4688
+5: 4689
+5: 4690
+5: 4691
+5: 4692
+5: 4693
+5: 4694
+5: 4695
+5: 4696
+5: 4697
+5: 4698
+5: 4699
+5: 4700
+5: 4701
+5: 4702
+5: 4703
+5: 4704
+5: 4705
+5: 4706
+5: 4707
+5: 4708
+5: 4709
+5: 4710
+5: 4711
+5: 4712
+5: 4713
+5: 4714
+5: 4715
+5: 4716
+5: 4717
+5: 4718
+4: 4549
+4: 4550
+4: 4551
+4: 4552
+4: 4553
+4: 4554
+4: 4555
+4: 4556
+4: 4557
+4: 4558
+4: 4559
+4: 4560
+4: 4561
+4: 4562
+4: 4563
+4: 4564
+4: 4565
+4: 4566
+4: 4567
+4: 4568
+4: 4569
+4: 4570
+4: 4571
+4: 4572
+4: 4573
+4: 4574
+4: 4575
+4: 4576
+4: 4577
+4: 4578
+4: 4579
+4: 4580
+4: 4581
+4: 4582
+4: 4583
+4: 4584
+4: 4585
+4: 4586
+4: 4587
+4: 4588
+4: 4589
+4: 4590
+4: 4591
+4: 4592
+4: 4593
+4: 4594
+4: 4595
+4: 4596
+4: 4597
+4: 4598
+4: 4599
+4: 4600
+4: 4601
+4: 4602
+4: 4603
+4: 4604
+4: 4605
+4: 4606
+4: 4607
+4: 4608
+4: 4609
+4: 4610
+4: 4611
+4: 4612
+4: 4613
+4: 4614
+4: 4615
+4: 4616
+4: 4617
+4: 4618
+4: 4619
+4: 4620
+4: 4621
+4: 4622
+4: 4623
+4: 4624
+4: 4625
+4: 4626
+4: 4627
+4: 4628
+4: 4629
+4: 4630
+4: 4631
+4: 4632
+4: 4633
+4: 4634
+4: 4635
+4: 4636
+4: 4637
+4: 4638
+4: 4639
+4: 4640
+4: 4641
+4: 4642
+4: 4643
+4: 4644
+4: 4645
+4: 4646
+4: 4647
+4: 4648
+4: 4649
+4: 4650
+4: 4651
+4: 4652
+4: 4653
+4: 4654
+4: 4655
+4: 4656
+4: 4657
+4: 4658
+4: 4659
+4: 4660
+4: 4661
+4: 4662
+4: 4663
+4: 4664
+4: 4665
+4: 4666
+4: 4667
+4: 4668
+4: 4669
+4: 4670
+4: 4671
+4: 4672
+4: 4673
+4: 4674
+4: 4675
+4: 4676
+4: 4677
+4: 4678
+4: 4679
+4: 4680
+4: 4681
+4: 4682
+4: 4683
+4: 4684
+4: 4685
+4: 4686
+4: 4687
+4: 4688
+4: 4689
+4: 4690
+4: 4691
+4: 4692
+4: 4693
+4: 4694
+4: 4695
+4: 4696
+4: 4697
+4: 4698
+4: 4699
+4: 4700
+4: 4701
+4: 4702
+4: 4703
+4: 4704
+4: 4705
+4: 4706
+4: 4707
+4: 4708
+4: 4709
+4: 4710
+4: 4711
+4: 4712
+4: 4713
+4: 4714
+4: 4715
+4: 4716
+4: 4717
+4: 4718
+4: 4719
+4: 4720
+4: 4721
+4: 4722
+4: 4723
+4: 4724
+4: 4725
+4: 4726
+4: 4727
+4: 4728
+4: 4729
+4: 4730
+4: 4731
+4: 4732
+4: 4733
+4: 4734
+4: 4735
+4: 4736
+4: 4737
+4: 4738
+4: 4739
+4: 4740
+4: 4741
+4: 4742
+4: 4743
+4: 4744
+4: 4745
+4: 4746
+4: 4747
+4: 4748
+4: 4749
+4: 4750
+5: 4719
+5: 4720
+5: 4721
+5: 4722
+5: 4723
+5: 4724
+5: 4725
+5: 4726
+5: 4727
+5: 4728
+5: 4729
+5: 4730
+5: 4731
+5: 4732
+5: 4733
+5: 4734
+5: 4735
+5: 4736
+5: 4737
+5: 4738
+5: 4739
+5: 4740
+5: 4741
+5: 4742
+5: 4743
+5: 4744
+5: 4745
+5: 4746
+5: 4747
+5: 4748
+5: 4749
+5: 4750
+5: 4751
+5: 4752
+5: 4753
+5: 4754
+5: 4755
+5: 4756
+5: 4757
+5: 4758
+5: 4759
+5: 4760
+5: 4761
+5: 4762
+5: 4763
+5: 4764
+5: 4765
+5: 4766
+5: 4767
+5: 4768
+5: 4769
+5: 4770
+5: 4771
+5: 4772
+5: 4773
+5: 4774
+5: 4775
+5: 4776
+5: 4777
+5: 4778
+5: 4779
+5: 4780
+5: 4781
+5: 4782
+5: 4783
+5: 4784
+5: 4785
+5: 4786
+5: 4787
+5: 4788
+5: 4789
+5: 4790
+5: 4791
+5: 4792
+5: 4793
+5: 4794
+5: 4795
+5: 4796
+5: 4797
+5: 4798
+5: 4799
+5: 4800
+5: 4801
+5: 4802
+5: 4803
+5: 4804
+5: 4805
+5: 4806
+5: 4807
+5: 4808
+5: 4809
+5: 4810
+5: 4811
+5: 4812
+5: 4813
+5: 4814
+5: 4815
+5: 4816
+5: 4817
+5: 4818
+5: 4819
+5: 4820
+5: 4821
+5: 4822
+5: 4823
+5: 4824
+5: 4825
+5: 4826
+5: 4827
+5: 4828
+5: 4829
+5: 4830
+5: 4831
+5: 4832
+5: 4833
+5: 4834
+5: 4835
+5: 4836
+5: 4837
+5: 4838
+5: 4839
+5: 4840
+5: 4841
+5: 4842
+5: 4843
+5: 4844
+5: 4845
+5: 4846
+5: 4847
+5: 4848
+5: 4849
+5: 4850
+5: 4851
+5: 4852
+5: 4853
+5: 4854
+5: 4855
+5: 4856
+5: 4857
+5: 4858
+5: 4859
+5: 4860
+5: 4861
+5: 4862
+5: 4863
+5: 4864
+5: 4865
+5: 4866
+5: 4867
+5: 4868
+5: 4869
+5: 4870
+5: 4871
+5: 4872
+5: 4873
+5: 4874
+5: 4875
+5: 4876
+5: 4877
+5: 4878
+5: 4879
+5: 4880
+5: 4881
+5: 4882
+5: 4883
+5: 4884
+5: 4885
+5: 4886
+5: 4887
+5: 4888
+5: 4889
+5: 4890
+5: 4891
+5: 4892
+5: 4893
+5: 4894
+5: 4895
+5: 4896
+5: 4897
+5: 4898
+5: 4899
+5: 4900
+5: 4901
+5: 4902
+5: 4903
+5: 4904
+5: 4905
+5: 4906
+5: 4907
+5: 4908
+5: 4909
+5: 4910
+5: 4911
+5: 4912
+5: 4913
+5: 4914
+5: 4915
+5: 4916
+5: 4917
+5: 4918
+5: 4919
+5: 4920
+5: 4921
+5: 4922
+5: 4923
+5: 4924
+5: 4925
+5: 4926
+5: 4927
+5: 4928
+5: 4929
+5: 4930
+5: 4931
+5: 4932
+5: 4933
+5: 4934
+5: 4935
+5: 4936
+5: 4937
+5: 4938
+5: 4939
+5: 4940
+5: 4941
+5: 4942
+5: 4943
+5: 4944
+5: 4945
+5: 4946
+5: 4947
+5: 4948
+5: 4949
+5: 4950
+5: 4951
+5: 4952
+5: 4953
+5: 4954
+5: 4955
+5: 4956
+5: 4957
+5: 4958
+5: 4959
+5: 4960
+5: 4961
+5: 4962
+5: 4963
+5: 4964
+5: 4965
+5: 4966
+5: 4967
+5: 4968
+5: 4969
+5: 4970
+5: 4971
+5: 4972
+5: 4973
+5: 4974
+5: 4975
+5: 4976
+5: 4977
+5: 4978
+5: 4979
+5: 4980
+5: 4981
+5: 4982
+5: 4983
+5: 4984
+5: 4985
+5: 4986
+5: 4987
+5: 4988
+5: 4989
+5: 4990
+5: 4991
+5: 4992
+5: 4993
+5: 4994
+5: 4995
+5: 4996
+5: 4997
+5: 4998
+5: 4999
+5: 5000
+5: 5001
+5: 5002
+5: 5003
+5: 5004
+4: 4751
+4: 4752
+4: 4753
+4: 4754
+4: 4755
+4: 4756
+4: 4757
+4: 4758
+4: 4759
+4: 4760
+4: 4761
+4: 4762
+4: 4763
+4: 4764
+4: 4765
+4: 4766
+4: 4767
+4: 4768
+4: 4769
+4: 4770
+4: 4771
+4: 4772
+4: 4773
+4: 4774
+4: 4775
+4: 4776
+4: 4777
+4: 4778
+4: 4779
+4: 4780
+4: 4781
+4: 4782
+4: 4783
+4: 4784
+4: 4785
+4: 4786
+4: 4787
+4: 4788
+4: 4789
+4: 4790
+4: 4791
+4: 4792
+4: 4793
+4: 4794
+4: 4795
+4: 4796
+4: 4797
+4: 4798
+4: 4799
+4: 4800
+4: 4801
+4: 4802
+4: 4803
+4: 4804
+4: 4805
+4: 4806
+4: 4807
+4: 4808
+4: 4809
+4: 4810
+4: 4811
+4: 4812
+4: 4813
+4: 4814
+4: 4815
+4: 4816
+4: 4817
+4: 4818
+4: 4819
+4: 4820
+4: 4821
+4: 4822
+4: 4823
+4: 4824
+4: 4825
+4: 4826
+4: 4827
+4: 4828
+4: 4829
+4: 4830
+4: 4831
+4: 4832
+4: 4833
+4: 4834
+4: 4835
+4: 4836
+4: 4837
+4: 4838
+4: 4839
+4: 4840
+4: 4841
+4: 4842
+4: 4843
+4: 4844
+4: 4845
+4: 4846
+4: 4847
+4: 4848
+4: 4849
+4: 4850
+4: 4851
+4: 4852
+4: 4853
+4: 4854
+4: 4855
+4: 4856
+4: 4857
+4: 4858
+4: 4859
+4: 4860
+4: 4861
+4: 4862
+4: 4863
+4: 4864
+4: 4865
+4: 4866
+4: 4867
+4: 4868
+4: 4869
+4: 4870
+4: 4871
+4: 4872
+4: 4873
+4: 4874
+4: 4875
+4: 4876
+4: 4877
+4: 4878
+4: 4879
+4: 4880
+4: 4881
+4: 4882
+4: 4883
+4: 4884
+4: 4885
+4: 4886
+4: 4887
+4: 4888
+4: 4889
+4: 4890
+4: 4891
+4: 4892
+4: 4893
+4: 4894
+4: 4895
+4: 4896
+4: 4897
+4: 4898
+4: 4899
+4: 4900
+4: 4901
+4: 4902
+4: 4903
+4: 4904
+4: 4905
+4: 4906
+4: 4907
+4: 4908
+4: 4909
+4: 4910
+4: 4911
+4: 4912
+4: 4913
+4: 4914
+4: 4915
+4: 4916
+4: 4917
+4: 4918
+4: 4919
+4: 4920
+4: 4921
+4: 4922
+4: 4923
+4: 4924
+4: 4925
+4: 4926
+4: 4927
+4: 4928
+4: 4929
+4: 4930
+4: 4931
+4: 4932
+4: 4933
+4: 4934
+4: 4935
+4: 4936
+4: 4937
+4: 4938
+4: 4939
+4: 4940
+4: 4941
+4: 4942
+4: 4943
+4: 4944
+4: 4945
+4: 4946
+4: 4947
+4: 4948
+4: 4949
+4: 4950
+4: 4951
+4: 4952
+4: 4953
+4: 4954
+4: 4955
+4: 4956
+4: 4957
+4: 4958
+4: 4959
+4: 4960
+4: 4961
+4: 4962
+4: 4963
+4: 4964
+4: 4965
+4: 4966
+4: 4967
+4: 4968
+4: 4969
+4: 4970
+4: 4971
+4: 4972
+4: 4973
+4: 4974
+4: 4975
+4: 4976
+4: 4977
+4: 4978
+4: 4979
+4: 4980
+4: 4981
+4: 4982
+4: 4983
+4: 4984
+4: 4985
+4: 4986
+4: 4987
+4: 4988
+4: 4989
+4: 4990
+4: 4991
+4: 4992
+4: 4993
+4: 4994
+4: 4995
+4: 4996
+4: 4997
+4: 4998
+4: 4999
+4: 5000
+5: 5005
+5: 5006
+5: 5007
+5: 5008
+5: 5009
+5: 5010
+5: 5011
+5: 5012
+5: 5013
+5: 5014
+5: 5015
+5: 5016
+5: 5017
+5: 5018
+5: 5019
+5: 5020
+5: 5021
+5: 5022
+5: 5023
+5: 5024
+5: 5025
+5: 5026
+5: 5027
+5: 5028
+5: 5029
+5: 5030
+5: 5031
+5: 5032
+5: 5033
+5: 5034
+5: 5035
+5: 5036
+5: 5037
+5: 5038
+5: 5039
+5: 5040
+5: 5041
+5: 5042
+5: 5043
+5: 5044
+5: 5045
+5: 5046
+5: 5047
+5: 5048
+5: 5049
+5: 5050
+5: 5051
+5: 5052
+5: 5053
+5: 5054
+5: 5055
+5: 5056
+5: 5057
+5: 5058
+5: 5059
+5: 5060
+5: 5061
+5: 5062
+5: 5063
+5: 5064
+5: 5065
+5: 5066
+5: 5067
+5: 5068
+5: 5069
+5: 5070
+5: 5071
+5: 5072
+5: 5073
+5: 5074
+5: 5075
+5: 5076
+5: 5077
+5: 5078
+5: 5079
+5: 5080
+5: 5081
+5: 5082
+5: 5083
+5: 5084
+5: 5085
+5: 5086
+5: 5087
+5: 5088
+5: 5089
+5: 5090
+5: 5091
+5: 5092
+5: 5093
+5: 5094
+5: 5095
+5: 5096
+5: 5097
+5: 5098
+5: 5099
+5: 5100
+5: 5101
+5: 5102
+5: 5103
+5: 5104
+5: 5105
+5: 5106
+5: 5107
+5: 5108
+5: 5109
+5: 5110
+5: 5111
+5: 5112
+5: 5113
+5: 5114
+5: 5115
+5: 5116
+5: 5117
+5: 5118
+5: 5119
+5: 5120
+5: 5121
+5: 5122
+5: 5123
+5: 5124
+5: 5125
+5: 5126
+5: 5127
+5: 5128
+5: 5129
+5: 5130
+5: 5131
+5: 5132
+5: 5133
+5: 5134
+5: 5135
+5: 5136
+5: 5137
+5: 5138
+5: 5139
+5: 5140
+5: 5141
+5: 5142
+5: 5143
+5: 5144
+5: 5145
+5: 5146
+5: 5147
+5: 5148
+5: 5149
+5: 5150
+5: 5151
+5: 5152
+5: 5153
+5: 5154
+5: 5155
+5: 5156
+5: 5157
+5: 5158
+5: 5159
+5: 5160
+5: 5161
+5: 5162
+5: 5163
+5: 5164
+5: 5165
+5: 5166
+5: 5167
+5: 5168
+5: 5169
+5: 5170
+5: 5171
+5: 5172
+5: 5173
+5: 5174
+5: 5175
+5: 5176
+5: 5177
+5: 5178
+5: 5179
+5: 5180
+5: 5181
+5: 5182
+5: 5183
+5: 5184
+5: 5185
+5: 5186
+5: 5187
+5: 5188
+5: 5189
+5: 5190
+5: 5191
+5: 5192
+5: 5193
+5: 5194
+5: 5195
+5: 5196
+5: 5197
+5: 5198
+5: 5199
+5: 5200
+5: 5201
+5: 5202
+5: 5203
+5: 5204
+5: 5205
+5: 5206
+5: 5207
+5: 5208
+5: 5209
+5: 5210
+5: 5211
+5: 5212
+5: 5213
+5: 5214
+5: 5215
+5: 5216
+5: 5217
+5: 5218
+5: 5219
+5: 5220
+5: 5221
+5: 5222
+5: 5223
+5: 5224
+5: 5225
+5: 5226
+5: 5227
+5: 5228
+5: 5229
+5: 5230
+5: 5231
+5: 5232
+5: 5233
+5: 5234
+5: 5235
+5: 5236
+5: 5237
+5: 5238
+5: 5239
+5: 5240
+5: 5241
+5: 5242
+5: 5243
+5: 5244
+5: 5245
+5: 5246
+5: 5247
+5: 5248
+5: 5249
+5: 5250
+5: 5251
+5: 5252
+5: 5253
+5: 5254
+5: 5255
+5: 5256
+5: 5257
+5: 5258
+5: 5259
+5: 5260
+5: 5261
+5: 5262
+5: 5263
+5: 5264
+5: 5265
+5: 5266
+5: 5267
+5: 5268
+5: 5269
+5: 5270
+5: 5271
+5: 5272
+5: 5273
+5: 5274
+5: 5275
+5: 5276
+5: 5277
+5: 5278
+5: 5279
+5: 5280
+5: 5281
+5: 5282
+5: 5283
+5: 5284
+5: 5285
+5: 5286
+5: 5287
+5: 5288
+5: 5289
+5: 5290
+5: 5291
+5: 5292
+5: 5293
+5: 5294
+5: 5295
+5: 5296
+5: 5297
+5: 5298
+5: 5299
+5: 5300
+5: 5301
+5: 5302
+5: 5303
+5: 5304
+5: 5305
+5: 5306
+5: 5307
+5: 5308
+5: 5309
+5: 5310
+5: 5311
+5: 5312
+5: 5313
+5: 5314
+5: 5315
+5: 5316
+5: 5317
+5: 5318
+5: 5319
+5: 5320
+5: 5321
+5: 5322
+5: 5323
+5: 5324
+5: 5325
+5: 5326
+5: 5327
+5: 5328
+5: 5329
+5: 5330
+5: 5331
+5: 5332
+5: 5333
+5: 5334
+5: 5335
+5: 5336
+5: 5337
+5: 5338
+5: 5339
+5: 5340
+5: 5341
+5: 5342
+5: 5343
+5: 5344
+5: 5345
+5: 5346
+5: 5347
+5: 5348
+5: 5349
+5: 5350
+5: 5351
+5: 5352
+5: 5353
+5: 5354
+5: 5355
+5: 5356
+5: 5357
+5: 5358
+5: 5359
+5: 5360
+5: 5361
+5: 5362
+5: 5363
+5: 5364
+5: 5365
+5: 5366
+5: 5367
+5: 5368
+5: 5369
+5: 5370
+5: 5371
+5: 5372
+5: 5373
+5: 5374
+5: 5375
+5: 5376
+5: 5377
+5: 5378
+5: 5379
+5: 5380
+5: 5381
+5: 5382
+5: 5383
+5: 5384
+5: 5385
+5: 5386
+5: 5387
+5: 5388
+5: 5389
+5: 5390
+5: 5391
+5: 5392
+5: 5393
+5: 5394
+5: 5395
+5: 5396
+5: 5397
+5: 5398
+5: 5399
+5: 5400
+5: 5401
+5: 5402
+5: 5403
+5: 5404
+5: 5405
+5: 5406
+5: 5407
+5: 5408
+5: 5409
+5: 5410
+5: 5411
+5: 5412
+5: 5413
+5: 5414
+5: 5415
+5: 5416
+5: 5417
+5: 5418
+5: 5419
+5: 5420
+5: 5421
+5: 5422
+5: 5423
+5: 5424
+5: 5425
+5: 5426
+5: 5427
+5: 5428
+5: 5429
+5: 5430
+5: 5431
+5: 5432
+5: 5433
+5: 5434
+5: 5435
+5: 5436
+5: 5437
+5: 5438
+5: 5439
+5: 5440
+5: 5441
+5: 5442
+5: 5443
+5: 5444
+5: 5445
+5: 5446
+5: 5447
+5: 5448
+5: 5449
+5: 5450
+5: 5451
+5: 5452
+5: 5453
+5: 5454
+5: 5455
+5: 5456
+5: 5457
+5: 5458
+5: 5459
+5: 5460
+5: 5461
+5: 5462
+5: 5463
+5: 5464
+5: 5465
+5: 5466
+5: 5467
+5: 5468
+5: 5469
+5: 5470
+5: 5471
+5: 5472
+5: 5473
+5: 5474
+5: 5475
+5: 5476
+5: 5477
+5: 5478
+5: 5479
+5: 5480
+5: 5481
+5: 5482
+5: 5483
+5: 5484
+5: 5485
+5: 5486
+5: 5487
+5: 5488
+5: 5489
+5: 5490
+5: 5491
+5: 5492
+5: 5493
+5: 5494
+5: 5495
+5: 5496
+5: 5497
+5: 5498
+5: 5499
+5: 5500
+5: 5501
+5: 5502
+5: 5503
+5: 5504
+5: 5505
+5: 5506
+5: 5507
+5: 5508
+5: 5509
+5: 5510
+5: 5511
+5: 5512
+5: 5513
+5: 5514
+5: 5515
+5: 5516
+5: 5517
diff --git a/threads/script.example02 b/threads/script.example02
new file mode 100644 (file)
index 0000000..5db87b5
--- /dev/null
@@ -0,0 +1,10000 @@
+4: 1
+4: 2
+4: 3
+4: 4
+4: 5
+4: 6
+4: 7
+4: 8
+4: 9
+4: 10
+4: 11
+4: 12
+4: 13
+4: 14
+4: 15
+4: 16
+4: 17
+4: 18
+4: 19
+4: 20
+4: 21
+4: 22
+4: 23
+4: 24
+4: 25
+4: 26
+4: 27
+4: 28
+4: 29
+4: 30
+4: 31
+4: 32
+4: 33
+4: 34
+4: 35
+4: 36
+4: 37
+4: 38
+4: 39
+4: 40
+4: 41
+4: 42
+4: 43
+4: 44
+4: 45
+4: 46
+4: 47
+4: 48
+4: 49
+4: 50
+4: 51
+4: 52
+4: 53
+4: 54
+4: 55
+4: 56
+4: 57
+4: 58
+4: 59
+4: 60
+4: 61
+4: 62
+4: 63
+4: 64
+4: 65
+4: 66
+4: 67
+4: 68
+4: 69
+4: 70
+4: 71
+4: 72
+4: 73
+4: 74
+4: 75
+4: 76
+4: 77
+4: 78
+4: 79
+4: 80
+4: 81
+4: 82
+4: 83
+4: 84
+4: 85
+4: 86
+4: 87
+4: 88
+4: 89
+4: 90
+4: 91
+4: 92
+4: 93
+4: 94
+4: 95
+4: 96
+4: 97
+4: 98
+4: 99
+4: 100
+4: 101
+4: 102
+4: 103
+4: 104
+4: 105
+4: 106
+4: 107
+4: 108
+4: 109
+4: 110
+4: 111
+4: 112
+4: 113
+4: 114
+4: 115
+4: 116
+4: 117
+4: 118
+4: 119
+4: 120
+4: 121
+4: 122
+4: 123
+4: 124
+4: 125
+4: 126
+4: 127
+4: 128
+4: 129
+4: 130
+4: 131
+4: 132
+4: 133
+4: 134
+4: 135
+4: 136
+4: 137
+4: 138
+4: 139
+4: 140
+4: 141
+4: 142
+4: 143
+4: 144
+4: 145
+4: 146
+4: 147
+4: 148
+4: 149
+4: 150
+4: 151
+4: 152
+4: 153
+4: 154
+4: 155
+4: 156
+4: 157
+4: 158
+4: 159
+4: 160
+4: 161
+4: 162
+4: 163
+4: 164
+4: 165
+4: 166
+4: 167
+4: 168
+4: 169
+4: 170
+4: 171
+4: 172
+4: 173
+4: 174
+4: 175
+4: 176
+4: 177
+4: 178
+4: 179
+4: 180
+4: 181
+4: 182
+4: 183
+4: 184
+4: 185
+4: 186
+4: 187
+4: 188
+4: 189
+4: 190
+4: 191
+4: 192
+4: 193
+4: 194
+4: 195
+4: 196
+4: 197
+4: 198
+4: 199
+4: 200
+4: 201
+4: 202
+4: 203
+4: 204
+4: 205
+4: 206
+4: 207
+4: 208
+4: 209
+4: 210
+4: 211
+4: 212
+4: 213
+4: 214
+4: 215
+4: 216
+4: 217
+4: 218
+4: 219
+4: 220
+4: 221
+4: 222
+4: 223
+4: 224
+4: 225
+4: 226
+4: 227
+4: 228
+4: 229
+4: 230
+4: 231
+4: 232
+4: 233
+4: 234
+4: 235
+4: 236
+4: 237
+4: 238
+4: 239
+4: 240
+4: 241
+4: 242
+4: 243
+4: 244
+4: 245
+4: 246
+4: 247
+4: 248
+4: 249
+4: 250
+4: 251
+4: 252
+4: 253
+4: 254
+4: 255
+4: 256
+4: 257
+4: 258
+4: 259
+4: 260
+4: 261
+4: 262
+4: 263
+4: 264
+4: 265
+4: 266
+4: 267
+4: 268
+4: 269
+4: 270
+4: 271
+4: 272
+4: 273
+4: 274
+4: 275
+4: 276
+4: 277
+4: 278
+4: 279
+4: 280
+4: 281
+4: 282
+4: 283
+4: 284
+4: 285
+4: 286
+4: 287
+4: 288
+4: 289
+4: 290
+4: 291
+4: 292
+4: 293
+4: 294
+4: 295
+4: 296
+4: 297
+4: 298
+4: 299
+4: 300
+4: 301
+4: 302
+4: 303
+4: 304
+4: 305
+4: 306
+4: 307
+4: 308
+4: 309
+4: 310
+4: 311
+4: 312
+4: 313
+4: 314
+4: 315
+4: 316
+4: 317
+4: 318
+4: 319
+4: 320
+4: 321
+4: 322
+4: 323
+4: 324
+4: 325
+4: 326
+4: 327
+4: 328
+4: 329
+4: 330
+4: 331
+4: 332
+4: 333
+4: 334
+4: 335
+4: 336
+4: 337
+4: 338
+4: 339
+4: 340
+4: 341
+4: 342
+4: 343
+4: 344
+4: 345
+4: 346
+4: 347
+4: 348
+4: 349
+4: 350
+4: 351
+4: 352
+4: 353
+4: 354
+4: 355
+4: 356
+4: 357
+4: 358
+4: 359
+4: 360
+4: 361
+4: 362
+4: 363
+4: 364
+4: 365
+4: 366
+4: 367
+4: 368
+4: 369
+4: 370
+4: 371
+4: 372
+4: 373
+4: 374
+4: 375
+4: 376
+4: 377
+4: 378
+4: 379
+4: 380
+4: 381
+4: 382
+4: 383
+4: 384
+4: 385
+4: 386
+4: 387
+4: 388
+4: 389
+4: 390
+4: 391
+4: 392
+4: 393
+4: 394
+4: 395
+4: 396
+4: 397
+4: 398
+4: 399
+4: 400
+4: 401
+4: 402
+4: 403
+4: 404
+4: 405
+4: 406
+4: 407
+4: 408
+4: 409
+4: 410
+4: 411
+4: 412
+4: 413
+4: 414
+4: 415
+4: 416
+4: 417
+4: 418
+4: 419
+4: 420
+4: 421
+4: 422
+4: 423
+4: 424
+4: 425
+4: 426
+4: 427
+4: 428
+4: 429
+4: 430
+4: 431
+4: 432
+4: 433
+4: 434
+4: 435
+4: 436
+4: 437
+4: 438
+4: 439
+4: 440
+4: 441
+4: 442
+4: 443
+4: 444
+4: 445
+4: 446
+4: 447
+4: 448
+4: 449
+4: 450
+4: 451
+4: 452
+4: 453
+4: 454
+4: 455
+4: 456
+4: 457
+4: 458
+4: 459
+4: 460
+4: 461
+4: 462
+4: 463
+4: 464
+4: 465
+4: 466
+4: 467
+4: 468
+4: 469
+4: 470
+4: 471
+4: 472
+4: 473
+4: 474
+4: 475
+4: 476
+4: 477
+4: 478
+4: 479
+4: 480
+4: 481
+4: 482
+4: 483
+4: 484
+4: 485
+4: 486
+4: 487
+4: 488
+4: 489
+4: 490
+4: 491
+4: 492
+4: 493
+4: 494
+4: 495
+4: 496
+4: 497
+4: 498
+4: 499
+4: 500
+4: 501
+4: 502
+4: 503
+4: 504
+4: 505
+4: 506
+4: 507
+4: 508
+4: 509
+4: 510
+4: 511
+4: 512
+4: 513
+4: 514
+4: 515
+4: 516
+4: 517
+4: 518
+4: 519
+4: 520
+4: 521
+4: 522
+4: 523
+4: 524
+4: 525
+4: 526
+4: 527
+4: 528
+4: 529
+4: 530
+4: 531
+4: 532
+4: 533
+4: 534
+4: 535
+4: 536
+4: 537
+4: 538
+4: 539
+4: 540
+4: 541
+4: 542
+4: 543
+4: 544
+4: 545
+4: 546
+4: 547
+4: 548
+4: 549
+4: 550
+4: 551
+4: 552
+4: 553
+4: 554
+4: 555
+4: 556
+4: 557
+4: 558
+4: 559
+4: 560
+4: 561
+4: 562
+4: 563
+4: 564
+4: 565
+4: 566
+4: 567
+4: 568
+4: 569
+4: 570
+4: 571
+4: 572
+4: 573
+4: 574
+4: 575
+4: 576
+4: 577
+4: 578
+4: 579
+4: 580
+4: 581
+4: 582
+4: 583
+4: 584
+4: 585
+4: 586
+4: 587
+4: 588
+4: 589
+4: 590
+4: 591
+4: 592
+4: 593
+4: 594
+4: 595
+4: 596
+4: 597
+4: 598
+4: 599
+4: 600
+4: 601
+4: 602
+4: 603
+4: 604
+4: 605
+4: 606
+4: 607
+4: 608
+4: 609
+4: 610
+4: 611
+4: 612
+4: 613
+4: 614
+4: 615
+4: 616
+4: 617
+4: 618
+4: 619
+4: 620
+4: 621
+4: 622
+4: 623
+4: 624
+4: 625
+4: 626
+4: 627
+4: 628
+4: 629
+4: 630
+4: 631
+4: 632
+4: 633
+4: 634
+4: 635
+4: 636
+4: 637
+4: 638
+4: 639
+4: 640
+4: 641
+4: 642
+4: 643
+4: 644
+4: 645
+4: 646
+4: 647
+4: 648
+4: 649
+4: 650
+4: 651
+4: 652
+4: 653
+4: 654
+4: 655
+4: 656
+4: 657
+4: 658
+4: 659
+4: 660
+4: 661
+4: 662
+4: 663
+4: 664
+4: 665
+4: 666
+4: 667
+4: 668
+4: 669
+4: 670
+4: 671
+4: 672
+4: 673
+4: 674
+4: 675
+4: 676
+4: 677
+4: 678
+4: 679
+4: 680
+4: 681
+4: 682
+4: 683
+4: 684
+4: 685
+4: 686
+4: 687
+4: 688
+4: 689
+4: 690
+4: 691
+4: 692
+4: 693
+4: 694
+4: 695
+4: 696
+4: 697
+4: 698
+4: 699
+4: 700
+4: 701
+4: 702
+4: 703
+4: 704
+4: 705
+4: 706
+4: 707
+4: 708
+4: 709
+4: 710
+4: 711
+4: 712
+4: 713
+4: 714
+4: 715
+4: 716
+4: 717
+4: 718
+4: 719
+4: 720
+4: 721
+4: 722
+4: 723
+4: 724
+4: 725
+4: 726
+4: 727
+4: 728
+4: 729
+4: 730
+4: 731
+4: 732
+4: 733
+4: 734
+4: 735
+4: 736
+4: 737
+4: 738
+4: 739
+4: 740
+4: 741
+4: 742
+4: 743
+4: 744
+4: 745
+4: 746
+4: 747
+4: 748
+4: 749
+4: 750
+4: 751
+4: 752
+4: 753
+4: 754
+4: 755
+4: 756
+4: 757
+4: 758
+4: 759
+4: 760
+4: 761
+4: 762
+4: 763
+4: 764
+4: 765
+4: 766
+4: 767
+4: 768
+4: 769
+4: 770
+4: 771
+4: 772
+4: 773
+4: 774
+4: 775
+4: 776
+4: 777
+4: 778
+4: 779
+4: 780
+4: 781
+4: 782
+5: 783
+5: 784
+5: 785
+5: 786
+5: 787
+5: 788
+5: 789
+5: 790
+5: 791
+5: 792
+5: 793
+5: 794
+5: 795
+5: 796
+5: 797
+5: 798
+5: 799
+5: 800
+5: 801
+5: 802
+5: 803
+5: 804
+5: 805
+5: 806
+5: 807
+5: 808
+5: 809
+5: 810
+5: 811
+5: 812
+5: 813
+5: 814
+5: 815
+5: 816
+5: 817
+5: 818
+5: 819
+5: 820
+5: 821
+5: 822
+5: 823
+5: 824
+5: 825
+5: 826
+5: 827
+5: 828
+5: 829
+5: 830
+5: 831
+5: 832
+5: 833
+5: 834
+5: 835
+5: 836
+5: 837
+5: 838
+5: 839
+5: 840
+5: 841
+5: 842
+5: 843
+5: 844
+5: 845
+5: 846
+5: 847
+5: 848
+5: 849
+5: 850
+5: 851
+5: 852
+5: 853
+5: 854
+5: 855
+5: 856
+5: 857
+5: 858
+5: 859
+5: 860
+5: 861
+5: 862
+5: 863
+5: 864
+5: 865
+5: 866
+5: 867
+5: 868
+5: 869
+5: 870
+5: 871
+5: 872
+5: 873
+5: 874
+5: 875
+5: 876
+5: 877
+5: 878
+5: 879
+5: 880
+5: 881
+5: 882
+5: 883
+5: 884
+5: 885
+5: 886
+5: 887
+5: 888
+5: 889
+5: 890
+5: 891
+5: 892
+5: 893
+5: 894
+5: 895
+5: 896
+5: 897
+5: 898
+5: 899
+5: 900
+5: 901
+5: 902
+5: 903
+5: 904
+5: 905
+5: 906
+5: 907
+5: 908
+5: 909
+5: 910
+5: 911
+5: 912
+5: 913
+5: 914
+5: 915
+5: 916
+5: 917
+5: 918
+5: 919
+5: 920
+5: 921
+5: 922
+5: 923
+5: 924
+5: 925
+5: 926
+5: 927
+5: 928
+5: 929
+5: 930
+5: 931
+5: 932
+5: 933
+5: 934
+5: 935
+5: 936
+5: 937
+5: 938
+5: 939
+5: 940
+5: 941
+5: 942
+5: 943
+5: 944
+5: 945
+5: 946
+5: 947
+5: 948
+5: 949
+5: 950
+5: 951
+5: 952
+5: 953
+5: 954
+5: 955
+5: 956
+5: 957
+5: 958
+5: 959
+5: 960
+5: 961
+5: 962
+5: 963
+5: 964
+5: 965
+5: 966
+5: 967
+5: 968
+5: 969
+5: 970
+5: 971
+5: 972
+5: 973
+5: 974
+5: 975
+5: 976
+5: 977
+5: 978
+5: 979
+5: 980
+5: 981
+5: 982
+5: 983
+5: 984
+5: 985
+5: 986
+5: 987
+5: 988
+5: 989
+5: 990
+5: 991
+5: 992
+5: 993
+5: 994
+5: 995
+5: 996
+5: 997
+5: 998
+5: 999
+5: 1000
+5: 1001
+5: 1002
+5: 1003
+5: 1004
+5: 1005
+5: 1006
+5: 1007
+5: 1008
+5: 1009
+5: 1010
+5: 1011
+5: 1012
+5: 1013
+5: 1014
+5: 1015
+5: 1016
+5: 1017
+5: 1018
+5: 1019
+5: 1020
+5: 1021
+5: 1022
+5: 1023
+5: 1024
+5: 1025
+5: 1026
+5: 1027
+5: 1028
+5: 1029
+5: 1030
+5: 1031
+5: 1032
+5: 1033
+5: 1034
+5: 1035
+5: 1036
+5: 1037
+5: 1038
+5: 1039
+5: 1040
+5: 1041
+5: 1042
+5: 1043
+5: 1044
+5: 1045
+5: 1046
+5: 1047
+5: 1048
+5: 1049
+5: 1050
+5: 1051
+5: 1052
+5: 1053
+5: 1054
+5: 1055
+5: 1056
+5: 1057
+5: 1058
+5: 1059
+5: 1060
+5: 1061
+5: 1062
+5: 1063
+5: 1064
+5: 1065
+5: 1066
+5: 1067
+5: 1068
+5: 1069
+5: 1070
+5: 1071
+5: 1072
+5: 1073
+5: 1074
+5: 1075
+5: 1076
+5: 1077
+5: 1078
+5: 1079
+5: 1080
+5: 1081
+5: 1082
+5: 1083
+5: 1084
+5: 1085
+5: 1086
+5: 1087
+5: 1088
+5: 1089
+5: 1090
+5: 1091
+5: 1092
+5: 1093
+5: 1094
+5: 1095
+5: 1096
+5: 1097
+5: 1098
+5: 1099
+5: 1100
+5: 1101
+5: 1102
+5: 1103
+5: 1104
+5: 1105
+5: 1106
+5: 1107
+5: 1108
+5: 1109
+5: 1110
+5: 1111
+5: 1112
+5: 1113
+5: 1114
+5: 1115
+5: 1116
+5: 1117
+5: 1118
+5: 1119
+5: 1120
+5: 1121
+5: 1122
+5: 1123
+5: 1124
+5: 1125
+5: 1126
+5: 1127
+5: 1128
+5: 1129
+5: 1130
+5: 1131
+5: 1132
+5: 1133
+5: 1134
+5: 1135
+5: 1136
+5: 1137
+5: 1138
+5: 1139
+5: 1140
+5: 1141
+5: 1142
+5: 1143
+5: 1144
+5: 1145
+5: 1146
+5: 1147
+5: 1148
+5: 1149
+5: 1150
+5: 1151
+5: 1152
+5: 1153
+5: 1154
+5: 1155
+5: 1156
+5: 1157
+5: 1158
+5: 1159
+5: 1160
+5: 1161
+5: 1162
+5: 1163
+5: 1164
+5: 1165
+5: 1166
+5: 1167
+5: 1168
+5: 1169
+5: 1170
+5: 1171
+5: 1172
+5: 1173
+5: 1174
+5: 1175
+5: 1176
+5: 1177
+5: 1178
+5: 1179
+5: 1180
+5: 1181
+4: 1182
+4: 1183
+4: 1184
+4: 1185
+4: 1186
+4: 1187
+4: 1188
+4: 1189
+4: 1190
+4: 1191
+4: 1192
+4: 1193
+4: 1194
+4: 1195
+4: 1196
+4: 1197
+4: 1198
+4: 1199
+4: 1200
+4: 1201
+4: 1202
+4: 1203
+4: 1204
+4: 1205
+4: 1206
+4: 1207
+4: 1208
+4: 1209
+4: 1210
+4: 1211
+4: 1212
+4: 1213
+4: 1214
+4: 1215
+4: 1216
+4: 1217
+4: 1218
+4: 1219
+4: 1220
+4: 1221
+4: 1222
+4: 1223
+4: 1224
+4: 1225
+4: 1226
+4: 1227
+4: 1228
+4: 1229
+4: 1230
+4: 1231
+4: 1232
+4: 1233
+4: 1234
+4: 1235
+4: 1236
+4: 1237
+4: 1238
+4: 1239
+4: 1240
+4: 1241
+4: 1242
+5: 1243
+5: 1244
+5: 1245
+5: 1246
+5: 1247
+5: 1248
+5: 1249
+5: 1250
+5: 1251
+5: 1252
+5: 1253
+5: 1254
+5: 1255
+5: 1256
+5: 1257
+5: 1258
+5: 1259
+5: 1260
+5: 1261
+5: 1262
+5: 1263
+5: 1264
+5: 1265
+5: 1266
+5: 1267
+5: 1268
+5: 1269
+5: 1270
+5: 1271
+5: 1272
+5: 1273
+5: 1274
+5: 1275
+5: 1276
+5: 1277
+5: 1278
+5: 1279
+5: 1280
+5: 1281
+5: 1282
+5: 1283
+5: 1284
+5: 1285
+5: 1286
+5: 1287
+5: 1288
+5: 1289
+5: 1290
+5: 1291
+5: 1292
+5: 1293
+5: 1294
+5: 1295
+5: 1296
+5: 1297
+5: 1298
+5: 1299
+5: 1300
+5: 1301
+5: 1302
+5: 1303
+5: 1304
+5: 1305
+5: 1306
+5: 1307
+5: 1308
+5: 1309
+5: 1310
+5: 1311
+5: 1312
+5: 1313
+5: 1314
+5: 1315
+5: 1316
+5: 1317
+5: 1318
+5: 1319
+5: 1320
+5: 1321
+5: 1322
+5: 1323
+5: 1324
+5: 1325
+5: 1326
+5: 1327
+5: 1328
+5: 1329
+5: 1330
+5: 1331
+5: 1332
+5: 1333
+5: 1334
+5: 1335
+5: 1336
+5: 1337
+5: 1338
+5: 1339
+5: 1340
+5: 1341
+5: 1342
+5: 1343
+5: 1344
+5: 1345
+5: 1346
+5: 1347
+5: 1348
+5: 1349
+5: 1350
+5: 1351
+5: 1352
+5: 1353
+5: 1354
+5: 1355
+5: 1356
+5: 1357
+5: 1358
+5: 1359
+5: 1360
+5: 1361
+5: 1362
+5: 1363
+5: 1364
+5: 1365
+5: 1366
+5: 1367
+5: 1368
+5: 1369
+5: 1370
+5: 1371
+5: 1372
+5: 1373
+5: 1374
+5: 1375
+5: 1376
+5: 1377
+5: 1378
+5: 1379
+5: 1380
+5: 1381
+5: 1382
+5: 1383
+5: 1384
+5: 1385
+5: 1386
+5: 1387
+5: 1388
+5: 1389
+5: 1390
+5: 1391
+5: 1392
+5: 1393
+5: 1394
+5: 1395
+5: 1396
+5: 1397
+5: 1398
+5: 1399
+5: 1400
+5: 1401
+5: 1402
+5: 1403
+5: 1404
+5: 1405
+5: 1406
+5: 1407
+5: 1408
+5: 1409
+5: 1410
+5: 1411
+5: 1412
+5: 1413
+5: 1414
+5: 1415
+5: 1416
+5: 1417
+5: 1418
+5: 1419
+5: 1420
+5: 1421
+5: 1422
+5: 1423
+5: 1424
+5: 1425
+5: 1426
+5: 1427
+5: 1428
+5: 1429
+5: 1430
+5: 1431
+5: 1432
+5: 1433
+5: 1434
+5: 1435
+5: 1436
+5: 1437
+5: 1438
+5: 1439
+5: 1440
+5: 1441
+5: 1442
+5: 1443
+5: 1444
+5: 1445
+5: 1446
+5: 1447
+5: 1448
+5: 1449
+5: 1450
+5: 1451
+5: 1452
+5: 1453
+5: 1454
+5: 1455
+5: 1456
+5: 1457
+5: 1458
+5: 1459
+5: 1460
+5: 1461
+5: 1462
+5: 1463
+5: 1464
+5: 1465
+5: 1466
+5: 1467
+5: 1468
+5: 1469
+5: 1470
+5: 1471
+5: 1472
+5: 1473
+5: 1474
+5: 1475
+5: 1476
+5: 1477
+5: 1478
+5: 1479
+5: 1480
+5: 1481
+5: 1482
+5: 1483
+5: 1484
+5: 1485
+5: 1486
+5: 1487
+5: 1488
+5: 1489
+5: 1490
+5: 1491
+5: 1492
+5: 1493
+5: 1494
+5: 1495
+5: 1496
+5: 1497
+5: 1498
+5: 1499
+5: 1500
+5: 1501
+5: 1502
+5: 1503
+5: 1504
+5: 1505
+5: 1506
+5: 1507
+5: 1508
+5: 1509
+5: 1510
+5: 1511
+5: 1512
+5: 1513
+5: 1514
+5: 1515
+5: 1516
+5: 1517
+5: 1518
+5: 1519
+5: 1520
+5: 1521
+5: 1522
+5: 1523
+5: 1524
+5: 1525
+5: 1526
+5: 1527
+5: 1528
+5: 1529
+5: 1530
+5: 1531
+5: 1532
+5: 1533
+5: 1534
+5: 1535
+5: 1536
+5: 1537
+5: 1538
+5: 1539
+5: 1540
+5: 1541
+4: 1542
+4: 1543
+4: 1544
+4: 1545
+4: 1546
+4: 1547
+4: 1548
+4: 1549
+4: 1550
+4: 1551
+4: 1552
+4: 1553
+4: 1554
+4: 1555
+4: 1556
+4: 1557
+4: 1558
+4: 1559
+4: 1560
+4: 1561
+4: 1562
+4: 1563
+4: 1564
+4: 1565
+4: 1566
+4: 1567
+4: 1568
+4: 1569
+4: 1570
+4: 1571
+4: 1572
+4: 1573
+4: 1574
+4: 1575
+4: 1576
+4: 1577
+4: 1578
+4: 1579
+4: 1580
+4: 1581
+4: 1582
+4: 1583
+4: 1584
+4: 1585
+4: 1586
+4: 1587
+4: 1588
+4: 1589
+4: 1590
+4: 1591
+4: 1592
+4: 1593
+4: 1594
+4: 1595
+4: 1596
+4: 1597
+4: 1598
+4: 1599
+4: 1600
+4: 1601
+4: 1602
+4: 1603
+4: 1604
+4: 1605
+4: 1606
+4: 1607
+4: 1608
+4: 1609
+4: 1610
+4: 1611
+4: 1612
+4: 1613
+4: 1614
+4: 1615
+4: 1616
+4: 1617
+4: 1618
+4: 1619
+4: 1620
+4: 1621
+4: 1622
+4: 1623
+4: 1624
+4: 1625
+4: 1626
+4: 1627
+4: 1628
+4: 1629
+4: 1630
+4: 1631
+4: 1632
+4: 1633
+4: 1634
+4: 1635
+4: 1636
+4: 1637
+4: 1638
+4: 1639
+4: 1640
+4: 1641
+4: 1642
+4: 1643
+4: 1644
+4: 1645
+4: 1646
+4: 1647
+4: 1648
+4: 1649
+4: 1650
+4: 1651
+4: 1652
+4: 1653
+4: 1654
+4: 1655
+4: 1656
+4: 1657
+4: 1658
+4: 1659
+4: 1660
+4: 1661
+4: 1662
+4: 1663
+4: 1664
+4: 1665
+4: 1666
+4: 1667
+4: 1668
+4: 1669
+4: 1670
+4: 1671
+4: 1672
+4: 1673
+4: 1674
+4: 1675
+4: 1676
+4: 1677
+4: 1678
+4: 1679
+4: 1680
+4: 1681
+4: 1682
+4: 1683
+4: 1684
+4: 1685
+4: 1686
+4: 1687
+4: 1688
+4: 1689
+4: 1690
+4: 1691
+4: 1692
+4: 1693
+4: 1694
+4: 1695
+4: 1696
+4: 1697
+4: 1698
+4: 1699
+4: 1700
+4: 1701
+4: 1702
+4: 1703
+4: 1704
+4: 1705
+4: 1706
+4: 1707
+4: 1708
+4: 1709
+4: 1710
+4: 1711
+4: 1712
+4: 1713
+4: 1714
+4: 1715
+4: 1716
+4: 1717
+4: 1718
+4: 1719
+4: 1720
+4: 1721
+4: 1722
+4: 1723
+4: 1724
+4: 1725
+4: 1726
+4: 1727
+4: 1728
+4: 1729
+4: 1730
+4: 1731
+4: 1732
+4: 1733
+4: 1734
+4: 1735
+4: 1736
+4: 1737
+4: 1738
+4: 1739
+4: 1740
+4: 1741
+4: 1742
+4: 1743
+4: 1744
+4: 1745
+4: 1746
+4: 1747
+4: 1748
+4: 1749
+4: 1750
+4: 1751
+4: 1752
+4: 1753
+4: 1754
+4: 1755
+4: 1756
+4: 1757
+4: 1758
+4: 1759
+4: 1760
+4: 1761
+4: 1762
+4: 1763
+4: 1764
+4: 1765
+4: 1766
+4: 1767
+4: 1768
+4: 1769
+4: 1770
+4: 1771
+4: 1772
+4: 1773
+4: 1774
+4: 1775
+4: 1776
+4: 1777
+4: 1778
+4: 1779
+4: 1780
+4: 1781
+4: 1782
+4: 1783
+4: 1784
+4: 1785
+4: 1786
+4: 1787
+4: 1788
+4: 1789
+4: 1790
+4: 1791
+4: 1792
+4: 1793
+4: 1794
+4: 1795
+4: 1796
+4: 1797
+4: 1798
+4: 1799
+4: 1800
+4: 1801
+4: 1802
+4: 1803
+4: 1804
+4: 1805
+4: 1806
+4: 1807
+4: 1808
+4: 1809
+4: 1810
+4: 1811
+4: 1812
+4: 1813
+4: 1814
+4: 1815
+4: 1816
+4: 1817
+4: 1818
+4: 1819
+4: 1820
+4: 1821
+4: 1822
+4: 1823
+4: 1824
+4: 1825
+4: 1826
+4: 1827
+4: 1828
+4: 1829
+4: 1830
+4: 1831
+5: 1832
+5: 1833
+5: 1834
+5: 1835
+5: 1836
+5: 1837
+5: 1838
+5: 1839
+5: 1840
+5: 1841
+5: 1842
+5: 1843
+5: 1844
+5: 1845
+5: 1846
+5: 1847
+5: 1848
+5: 1849
+5: 1850
+5: 1851
+5: 1852
+5: 1853
+5: 1854
+5: 1855
+5: 1856
+5: 1857
+5: 1858
+5: 1859
+5: 1860
+5: 1861
+5: 1862
+5: 1863
+5: 1864
+5: 1865
+5: 1866
+5: 1867
+5: 1868
+5: 1869
+5: 1870
+5: 1871
+5: 1872
+5: 1873
+5: 1874
+5: 1875
+5: 1876
+5: 1877
+5: 1878
+5: 1879
+5: 1880
+5: 1881
+5: 1882
+5: 1883
+5: 1884
+5: 1885
+5: 1886
+5: 1887
+5: 1888
+5: 1889
+5: 1890
+5: 1891
+5: 1892
+5: 1893
+5: 1894
+5: 1895
+5: 1896
+5: 1897
+5: 1898
+5: 1899
+5: 1900
+5: 1901
+5: 1902
+5: 1903
+5: 1904
+5: 1905
+5: 1906
+5: 1907
+5: 1908
+5: 1909
+5: 1910
+5: 1911
+5: 1912
+5: 1913
+5: 1914
+5: 1915
+5: 1916
+5: 1917
+5: 1918
+5: 1919
+5: 1920
+5: 1921
+5: 1922
+5: 1923
+5: 1924
+5: 1925
+5: 1926
+5: 1927
+5: 1928
+5: 1929
+5: 1930
+5: 1931
+5: 1932
+5: 1933
+5: 1934
+5: 1935
+5: 1936
+5: 1937
+5: 1938
+5: 1939
+5: 1940
+5: 1941
+5: 1942
+5: 1943
+5: 1944
+5: 1945
+5: 1946
+5: 1947
+5: 1948
+5: 1949
+5: 1950
+5: 1951
+5: 1952
+5: 1953
+5: 1954
+5: 1955
+5: 1956
+5: 1957
+5: 1958
+5: 1959
+5: 1960
+5: 1961
+5: 1962
+5: 1963
+5: 1964
+5: 1965
+5: 1966
+5: 1967
+5: 1968
+5: 1969
+5: 1970
+5: 1971
+5: 1972
+5: 1973
+5: 1974
+5: 1975
+5: 1976
+5: 1977
+5: 1978
+5: 1979
+5: 1980
+5: 1981
+5: 1982
+5: 1983
+5: 1984
+5: 1985
+5: 1986
+5: 1987
+5: 1988
+5: 1989
+5: 1990
+5: 1991
+5: 1992
+5: 1993
+5: 1994
+5: 1995
+5: 1996
+5: 1997
+5: 1998
+5: 1999
+5: 2000
+5: 2001
+5: 2002
+5: 2003
+5: 2004
+5: 2005
+5: 2006
+5: 2007
+5: 2008
+5: 2009
+5: 2010
+5: 2011
+5: 2012
+5: 2013
+5: 2014
+5: 2015
+5: 2016
+5: 2017
+5: 2018
+5: 2019
+5: 2020
+5: 2021
+5: 2022
+5: 2023
+5: 2024
+5: 2025
+5: 2026
+5: 2027
+5: 2028
+5: 2029
+5: 2030
+5: 2031
+5: 2032
+5: 2033
+5: 2034
+5: 2035
+5: 2036
+5: 2037
+5: 2038
+5: 2039
+5: 2040
+5: 2041
+5: 2042
+5: 2043
+5: 2044
+5: 2045
+5: 2046
+5: 2047
+5: 2048
+5: 2049
+5: 2050
+5: 2051
+5: 2052
+5: 2053
+5: 2054
+5: 2055
+5: 2056
+5: 2057
+5: 2058
+5: 2059
+5: 2060
+5: 2061
+5: 2062
+5: 2063
+5: 2064
+5: 2065
+5: 2066
+5: 2067
+5: 2068
+5: 2069
+5: 2070
+5: 2071
+5: 2072
+5: 2073
+5: 2074
+5: 2075
+5: 2076
+5: 2077
+5: 2078
+5: 2079
+5: 2080
+5: 2081
+5: 2082
+5: 2083
+5: 2084
+5: 2085
+5: 2086
+5: 2087
+5: 2088
+5: 2089
+5: 2090
+5: 2091
+5: 2092
+5: 2093
+5: 2094
+5: 2095
+5: 2096
+5: 2097
+5: 2098
+5: 2099
+5: 2100
+5: 2101
+5: 2102
+5: 2103
+5: 2104
+5: 2105
+5: 2106
+5: 2107
+5: 2108
+5: 2109
+5: 2110
+5: 2111
+5: 2112
+5: 2113
+5: 2114
+5: 2115
+5: 2116
+5: 2117
+5: 2118
+5: 2119
+5: 2120
+5: 2121
+5: 2122
+5: 2123
+5: 2124
+5: 2125
+5: 2126
+5: 2127
+5: 2128
+5: 2129
+5: 2130
+5: 2131
+5: 2132
+5: 2133
+5: 2134
+5: 2135
+5: 2136
+5: 2137
+5: 2138
+5: 2139
+5: 2140
+5: 2141
+5: 2142
+5: 2143
+5: 2144
+5: 2145
+5: 2146
+5: 2147
+5: 2148
+5: 2149
+5: 2150
+5: 2151
+5: 2152
+5: 2153
+5: 2154
+5: 2155
+5: 2156
+5: 2157
+5: 2158
+5: 2159
+5: 2160
+5: 2161
+5: 2162
+5: 2163
+5: 2164
+5: 2165
+5: 2166
+5: 2167
+5: 2168
+5: 2169
+5: 2170
+5: 2171
+5: 2172
+5: 2173
+5: 2174
+5: 2175
+5: 2176
+5: 2177
+5: 2178
+5: 2179
+5: 2180
+5: 2181
+5: 2182
+5: 2183
+5: 2184
+5: 2185
+5: 2186
+5: 2187
+5: 2188
+5: 2189
+5: 2190
+5: 2191
+5: 2192
+5: 2193
+5: 2194
+5: 2195
+5: 2196
+5: 2197
+5: 2198
+5: 2199
+5: 2200
+5: 2201
+5: 2202
+5: 2203
+5: 2204
+5: 2205
+5: 2206
+5: 2207
+5: 2208
+5: 2209
+5: 2210
+5: 2211
+5: 2212
+5: 2213
+5: 2214
+5: 2215
+5: 2216
+5: 2217
+5: 2218
+5: 2219
+5: 2220
+5: 2221
+5: 2222
+5: 2223
+5: 2224
+5: 2225
+5: 2226
+5: 2227
+5: 2228
+5: 2229
+5: 2230
+5: 2231
+5: 2232
+5: 2233
+5: 2234
+5: 2235
+5: 2236
+5: 2237
+5: 2238
+5: 2239
+5: 2240
+5: 2241
+5: 2242
+5: 2243
+5: 2244
+5: 2245
+5: 2246
+5: 2247
+5: 2248
+5: 2249
+5: 2250
+5: 2251
+5: 2252
+5: 2253
+5: 2254
+5: 2255
+5: 2256
+5: 2257
+5: 2258
+5: 2259
+5: 2260
+5: 2261
+5: 2262
+5: 2263
+5: 2264
+5: 2265
+5: 2266
+5: 2267
+5: 2268
+5: 2269
+5: 2270
+5: 2271
+5: 2272
+5: 2273
+5: 2274
+5: 2275
+5: 2276
+5: 2277
+5: 2278
+5: 2279
+5: 2280
+5: 2281
+5: 2282
+5: 2283
+5: 2284
+5: 2285
+5: 2286
+5: 2287
+5: 2288
+5: 2289
+5: 2290
+5: 2291
+5: 2292
+5: 2293
+5: 2294
+5: 2295
+5: 2296
+5: 2297
+5: 2298
+5: 2299
+5: 2300
+5: 2301
+5: 2302
+5: 2303
+5: 2304
+5: 2305
+5: 2306
+5: 2307
+5: 2308
+5: 2309
+5: 2310
+5: 2311
+5: 2312
+5: 2313
+5: 2314
+5: 2315
+5: 2316
+5: 2317
+5: 2318
+5: 2319
+5: 2320
+5: 2321
+5: 2322
+5: 2323
+5: 2324
+5: 2325
+5: 2326
+5: 2327
+5: 2328
+5: 2329
+5: 2330
+5: 2331
+5: 2332
+5: 2333
+5: 2334
+5: 2335
+5: 2336
+5: 2337
+5: 2338
+5: 2339
+5: 2340
+5: 2341
+5: 2342
+4: 2343
+4: 2344
+4: 2345
+4: 2346
+4: 2347
+4: 2348
+4: 2349
+4: 2350
+4: 2351
+4: 2352
+4: 2353
+4: 2354
+4: 2355
+4: 2356
+4: 2357
+4: 2358
+4: 2359
+4: 2360
+4: 2361
+4: 2362
+4: 2363
+4: 2364
+4: 2365
+4: 2366
+4: 2367
+4: 2368
+4: 2369
+4: 2370
+4: 2371
+4: 2372
+4: 2373
+4: 2374
+4: 2375
+4: 2376
+4: 2377
+4: 2378
+4: 2379
+4: 2380
+4: 2381
+4: 2382
+4: 2383
+4: 2384
+4: 2385
+4: 2386
+4: 2387
+4: 2388
+4: 2389
+4: 2390
+4: 2391
+4: 2392
+4: 2393
+4: 2394
+4: 2395
+4: 2396
+4: 2397
+4: 2398
+4: 2399
+4: 2400
+4: 2401
+4: 2402
+4: 2403
+4: 2404
+4: 2405
+4: 2406
+4: 2407
+4: 2408
+4: 2409
+4: 2410
+4: 2411
+4: 2412
+4: 2413
+4: 2414
+4: 2415
+4: 2416
+4: 2417
+4: 2418
+4: 2419
+4: 2420
+4: 2421
+4: 2422
+4: 2423
+4: 2424
+4: 2425
+4: 2426
+4: 2427
+4: 2428
+4: 2429
+4: 2430
+4: 2431
+4: 2432
+4: 2433
+4: 2434
+4: 2435
+4: 2436
+4: 2437
+4: 2438
+4: 2439
+4: 2440
+4: 2441
+4: 2442
+4: 2443
+4: 2444
+4: 2445
+4: 2446
+4: 2447
+4: 2448
+4: 2449
+4: 2450
+4: 2451
+4: 2452
+4: 2453
+4: 2454
+4: 2455
+4: 2456
+4: 2457
+4: 2458
+4: 2459
+4: 2460
+4: 2461
+4: 2462
+4: 2463
+4: 2464
+4: 2465
+4: 2466
+4: 2467
+4: 2468
+4: 2469
+4: 2470
+4: 2471
+4: 2472
+4: 2473
+4: 2474
+4: 2475
+4: 2476
+4: 2477
+4: 2478
+4: 2479
+4: 2480
+4: 2481
+4: 2482
+4: 2483
+4: 2484
+4: 2485
+4: 2486
+4: 2487
+4: 2488
+4: 2489
+4: 2490
+4: 2491
+4: 2492
+4: 2493
+4: 2494
+4: 2495
+4: 2496
+4: 2497
+4: 2498
+4: 2499
+4: 2500
+4: 2501
+4: 2502
+4: 2503
+4: 2504
+4: 2505
+4: 2506
+4: 2507
+4: 2508
+4: 2509
+4: 2510
+4: 2511
+4: 2512
+4: 2513
+4: 2514
+4: 2515
+4: 2516
+4: 2517
+4: 2518
+4: 2519
+4: 2520
+4: 2521
+4: 2522
+4: 2523
+4: 2524
+4: 2525
+4: 2526
+4: 2527
+4: 2528
+4: 2529
+4: 2530
+4: 2531
+4: 2532
+4: 2533
+4: 2534
+4: 2535
+4: 2536
+4: 2537
+4: 2538
+4: 2539
+4: 2540
+4: 2541
+4: 2542
+4: 2543
+4: 2544
+4: 2545
+4: 2546
+4: 2547
+4: 2548
+4: 2549
+4: 2550
+4: 2551
+4: 2552
+4: 2553
+4: 2554
+4: 2555
+4: 2556
+4: 2557
+4: 2558
+4: 2559
+4: 2560
+4: 2561
+4: 2562
+4: 2563
+4: 2564
+4: 2565
+4: 2566
+4: 2567
+4: 2568
+4: 2569
+4: 2570
+4: 2571
+4: 2572
+4: 2573
+4: 2574
+4: 2575
+4: 2576
+4: 2577
+4: 2578
+4: 2579
+4: 2580
+4: 2581
+4: 2582
+4: 2583
+4: 2584
+4: 2585
+4: 2586
+4: 2587
+4: 2588
+4: 2589
+4: 2590
+4: 2591
+4: 2592
+4: 2593
+4: 2594
+4: 2595
+4: 2596
+4: 2597
+4: 2598
+4: 2599
+4: 2600
+4: 2601
+4: 2602
+4: 2603
+4: 2604
+4: 2605
+4: 2606
+4: 2607
+4: 2608
+4: 2609
+4: 2610
+4: 2611
+4: 2612
+4: 2613
+4: 2614
+4: 2615
+4: 2616
+4: 2617
+4: 2618
+4: 2619
+4: 2620
+4: 2621
+4: 2622
+4: 2623
+4: 2624
+4: 2625
+4: 2626
+4: 2627
+4: 2628
+4: 2629
+4: 2630
+4: 2631
+4: 2632
+4: 2633
+4: 2634
+4: 2635
+4: 2636
+4: 2637
+4: 2638
+4: 2639
+4: 2640
+4: 2641
+4: 2642
+4: 2643
+4: 2644
+4: 2645
+4: 2646
+4: 2647
+4: 2648
+4: 2649
+4: 2650
+4: 2651
+4: 2652
+4: 2653
+4: 2654
+4: 2655
+4: 2656
+4: 2657
+4: 2658
+4: 2659
+4: 2660
+4: 2661
+4: 2662
+4: 2663
+4: 2664
+4: 2665
+4: 2666
+4: 2667
+4: 2668
+4: 2669
+4: 2670
+4: 2671
+4: 2672
+4: 2673
+4: 2674
+4: 2675
+4: 2676
+4: 2677
+4: 2678
+4: 2679
+4: 2680
+4: 2681
+4: 2682
+4: 2683
+4: 2684
+4: 2685
+4: 2686
+4: 2687
+4: 2688
+4: 2689
+4: 2690
+4: 2691
+4: 2692
+4: 2693
+4: 2694
+4: 2695
+4: 2696
+4: 2697
+4: 2698
+4: 2699
+4: 2700
+5: 2701
+5: 2702
+5: 2703
+5: 2704
+5: 2705
+5: 2706
+5: 2707
+5: 2708
+5: 2709
+5: 2710
+5: 2711
+5: 2712
+5: 2713
+5: 2714
+5: 2715
+5: 2716
+5: 2717
+5: 2718
+5: 2719
+5: 2720
+5: 2721
+5: 2722
+5: 2723
+5: 2724
+5: 2725
+5: 2726
+5: 2727
+5: 2728
+5: 2729
+5: 2730
+5: 2731
+5: 2732
+5: 2733
+5: 2734
+5: 2735
+5: 2736
+5: 2737
+5: 2738
+5: 2739
+5: 2740
+5: 2741
+5: 2742
+5: 2743
+5: 2744
+5: 2745
+5: 2746
+5: 2747
+5: 2748
+5: 2749
+5: 2750
+5: 2751
+5: 2752
+5: 2753
+5: 2754
+5: 2755
+5: 2756
+5: 2757
+5: 2758
+5: 2759
+5: 2760
+5: 2761
+5: 2762
+5: 2763
+5: 2764
+5: 2765
+5: 2766
+5: 2767
+5: 2768
+5: 2769
+5: 2770
+5: 2771
+5: 2772
+5: 2773
+5: 2774
+5: 2775
+5: 2776
+5: 2777
+5: 2778
+5: 2779
+5: 2780
+5: 2781
+5: 2782
+5: 2783
+5: 2784
+5: 2785
+5: 2786
+5: 2787
+5: 2788
+5: 2789
+5: 2790
+5: 2791
+5: 2792
+5: 2793
+5: 2794
+5: 2795
+5: 2796
+5: 2797
+5: 2798
+5: 2799
+5: 2800
+5: 2801
+5: 2802
+5: 2803
+5: 2804
+5: 2805
+5: 2806
+5: 2807
+5: 2808
+5: 2809
+5: 2810
+5: 2811
+5: 2812
+5: 2813
+5: 2814
+5: 2815
+5: 2816
+5: 2817
+5: 2818
+5: 2819
+5: 2820
+5: 2821
+5: 2822
+5: 2823
+5: 2824
+5: 2825
+5: 2826
+5: 2827
+5: 2828
+5: 2829
+5: 2830
+5: 2831
+5: 2832
+5: 2833
+5: 2834
+5: 2835
+5: 2836
+5: 2837
+5: 2838
+5: 2839
+5: 2840
+5: 2841
+5: 2842
+5: 2843
+5: 2844
+5: 2845
+5: 2846
+5: 2847
+5: 2848
+5: 2849
+5: 2850
+5: 2851
+5: 2852
+5: 2853
+5: 2854
+5: 2855
+5: 2856
+5: 2857
+5: 2858
+5: 2859
+5: 2860
+5: 2861
+5: 2862
+5: 2863
+5: 2864
+5: 2865
+5: 2866
+5: 2867
+5: 2868
+5: 2869
+5: 2870
+5: 2871
+5: 2872
+5: 2873
+5: 2874
+5: 2875
+5: 2876
+5: 2877
+5: 2878
+5: 2879
+5: 2880
+5: 2881
+5: 2882
+5: 2883
+5: 2884
+5: 2885
+5: 2886
+5: 2887
+5: 2888
+5: 2889
+5: 2890
+5: 2891
+5: 2892
+5: 2893
+5: 2894
+5: 2895
+5: 2896
+5: 2897
+5: 2898
+5: 2899
+5: 2900
+5: 2901
+5: 2902
+5: 2903
+5: 2904
+5: 2905
+5: 2906
+5: 2907
+5: 2908
+5: 2909
+5: 2910
+5: 2911
+5: 2912
+5: 2913
+5: 2914
+5: 2915
+5: 2916
+5: 2917
+5: 2918
+5: 2919
+5: 2920
+5: 2921
+5: 2922
+5: 2923
+5: 2924
+5: 2925
+5: 2926
+5: 2927
+5: 2928
+5: 2929
+5: 2930
+5: 2931
+5: 2932
+5: 2933
+5: 2934
+5: 2935
+5: 2936
+5: 2937
+5: 2938
+5: 2939
+5: 2940
+5: 2941
+5: 2942
+5: 2943
+5: 2944
+5: 2945
+5: 2946
+5: 2947
+5: 2948
+5: 2949
+5: 2950
+5: 2951
+5: 2952
+5: 2953
+5: 2954
+5: 2955
+5: 2956
+5: 2957
+5: 2958
+5: 2959
+5: 2960
+5: 2961
+5: 2962
+5: 2963
+5: 2964
+5: 2965
+5: 2966
+5: 2967
+5: 2968
+5: 2969
+5: 2970
+5: 2971
+5: 2972
+5: 2973
+5: 2974
+5: 2975
+5: 2976
+5: 2977
+5: 2978
+5: 2979
+5: 2980
+5: 2981
+5: 2982
+5: 2983
+5: 2984
+5: 2985
+5: 2986
+5: 2987
+5: 2988
+5: 2989
+5: 2990
+5: 2991
+5: 2992
+5: 2993
+5: 2994
+5: 2995
+5: 2996
+5: 2997
+5: 2998
+5: 2999
+5: 3000
+5: 3001
+5: 3002
+5: 3003
+5: 3004
+5: 3005
+5: 3006
+5: 3007
+5: 3008
+5: 3009
+5: 3010
+5: 3011
+5: 3012
+5: 3013
+5: 3014
+5: 3015
+5: 3016
+5: 3017
+5: 3018
+5: 3019
+5: 3020
+5: 3021
+5: 3022
+5: 3023
+5: 3024
+5: 3025
+5: 3026
+5: 3027
+5: 3028
+5: 3029
+5: 3030
+5: 3031
+5: 3032
+5: 3033
+5: 3034
+5: 3035
+5: 3036
+5: 3037
+5: 3038
+5: 3039
+5: 3040
+5: 3041
+5: 3042
+5: 3043
+5: 3044
+5: 3045
+5: 3046
+5: 3047
+5: 3048
+5: 3049
+5: 3050
+5: 3051
+5: 3052
+5: 3053
+5: 3054
+5: 3055
+5: 3056
+5: 3057
+5: 3058
+5: 3059
+5: 3060
+5: 3061
+5: 3062
+5: 3063
+5: 3064
+5: 3065
+5: 3066
+5: 3067
+5: 3068
+5: 3069
+5: 3070
+5: 3071
+5: 3072
+5: 3073
+5: 3074
+5: 3075
+5: 3076
+5: 3077
+5: 3078
+5: 3079
+5: 3080
+5: 3081
+5: 3082
+5: 3083
+5: 3084
+5: 3085
+5: 3086
+5: 3087
+5: 3088
+5: 3089
+5: 3090
+5: 3091
+5: 3092
+5: 3093
+5: 3094
+5: 3095
+5: 3096
+5: 3097
+5: 3098
+5: 3099
+5: 3100
+5: 3101
+5: 3102
+5: 3103
+5: 3104
+5: 3105
+5: 3106
+5: 3107
+5: 3108
+5: 3109
+5: 3110
+5: 3111
+5: 3112
+5: 3113
+5: 3114
+5: 3115
+5: 3116
+5: 3117
+5: 3118
+5: 3119
+5: 3120
+5: 3121
+5: 3122
+5: 3123
+5: 3124
+5: 3125
+5: 3126
+5: 3127
+5: 3128
+5: 3129
+5: 3130
+5: 3131
+5: 3132
+5: 3133
+5: 3134
+5: 3135
+5: 3136
+5: 3137
+5: 3138
+5: 3139
+5: 3140
+5: 3141
+5: 3142
+5: 3143
+5: 3144
+5: 3145
+5: 3146
+5: 3147
+5: 3148
+5: 3149
+5: 3150
+5: 3151
+5: 3152
+5: 3153
+5: 3154
+5: 3155
+5: 3156
+5: 3157
+5: 3158
+5: 3159
+5: 3160
+5: 3161
+5: 3162
+5: 3163
+5: 3164
+5: 3165
+5: 3166
+5: 3167
+5: 3168
+5: 3169
+5: 3170
+5: 3171
+5: 3172
+5: 3173
+5: 3174
+5: 3175
+5: 3176
+5: 3177
+5: 3178
+5: 3179
+5: 3180
+5: 3181
+5: 3182
+5: 3183
+5: 3184
+5: 3185
+5: 3186
+5: 3187
+5: 3188
+5: 3189
+5: 3190
+5: 3191
+5: 3192
+5: 3193
+5: 3194
+5: 3195
+5: 3196
+5: 3197
+5: 3198
+5: 3199
+5: 3200
+5: 3201
+5: 3202
+5: 3203
+5: 3204
+5: 3205
+5: 3206
+5: 3207
+5: 3208
+5: 3209
+5: 3210
+5: 3211
+5: 3212
+5: 3213
+5: 3214
+5: 3215
+5: 3216
+5: 3217
+5: 3218
+5: 3219
+5: 3220
+4: 3221
+4: 3222
+4: 3223
+4: 3224
+4: 3225
+4: 3226
+4: 3227
+4: 3228
+4: 3229
+4: 3230
+4: 3231
+4: 3232
+4: 3233
+4: 3234
+4: 3235
+4: 3236
+4: 3237
+4: 3238
+4: 3239
+4: 3240
+4: 3241
+4: 3242
+4: 3243
+4: 3244
+4: 3245
+4: 3246
+4: 3247
+4: 3248
+4: 3249
+4: 3250
+4: 3251
+4: 3252
+4: 3253
+4: 3254
+4: 3255
+4: 3256
+4: 3257
+4: 3258
+4: 3259
+4: 3260
+4: 3261
+4: 3262
+4: 3263
+4: 3264
+4: 3265
+4: 3266
+4: 3267
+4: 3268
+4: 3269
+4: 3270
+4: 3271
+4: 3272
+4: 3273
+4: 3274
+4: 3275
+4: 3276
+4: 3277
+4: 3278
+4: 3279
+4: 3280
+4: 3281
+4: 3282
+4: 3283
+4: 3284
+4: 3285
+4: 3286
+4: 3287
+4: 3288
+4: 3289
+4: 3290
+4: 3291
+4: 3292
+4: 3293
+4: 3294
+4: 3295
+4: 3296
+4: 3297
+4: 3298
+4: 3299
+4: 3300
+4: 3301
+4: 3302
+4: 3303
+4: 3304
+4: 3305
+4: 3306
+4: 3307
+4: 3308
+4: 3309
+4: 3310
+4: 3311
+4: 3312
+4: 3313
+4: 3314
+4: 3315
+4: 3316
+4: 3317
+4: 3318
+4: 3319
+4: 3320
+4: 3321
+4: 3322
+4: 3323
+4: 3324
+4: 3325
+4: 3326
+4: 3327
+4: 3328
+4: 3329
+4: 3330
+4: 3331
+4: 3332
+4: 3333
+4: 3334
+4: 3335
+4: 3336
+4: 3337
+4: 3338
+4: 3339
+4: 3340
+4: 3341
+4: 3342
+4: 3343
+4: 3344
+4: 3345
+4: 3346
+4: 3347
+4: 3348
+4: 3349
+4: 3350
+4: 3351
+4: 3352
+4: 3353
+4: 3354
+4: 3355
+4: 3356
+4: 3357
+4: 3358
+4: 3359
+4: 3360
+4: 3361
+4: 3362
+4: 3363
+4: 3364
+4: 3365
+4: 3366
+4: 3367
+4: 3368
+4: 3369
+4: 3370
+4: 3371
+4: 3372
+4: 3373
+4: 3374
+4: 3375
+4: 3376
+4: 3377
+4: 3378
+4: 3379
+4: 3380
+4: 3381
+4: 3382
+4: 3383
+4: 3384
+4: 3385
+4: 3386
+4: 3387
+4: 3388
+4: 3389
+4: 3390
+4: 3391
+4: 3392
+4: 3393
+4: 3394
+4: 3395
+4: 3396
+4: 3397
+4: 3398
+4: 3399
+4: 3400
+4: 3401
+4: 3402
+4: 3403
+4: 3404
+4: 3405
+4: 3406
+4: 3407
+4: 3408
+4: 3409
+4: 3410
+4: 3411
+4: 3412
+4: 3413
+4: 3414
+4: 3415
+4: 3416
+4: 3417
+4: 3418
+4: 3419
+4: 3420
+4: 3421
+4: 3422
+4: 3423
+4: 3424
+4: 3425
+4: 3426
+4: 3427
+4: 3428
+4: 3429
+4: 3430
+4: 3431
+4: 3432
+4: 3433
+4: 3434
+4: 3435
+4: 3436
+4: 3437
+4: 3438
+4: 3439
+4: 3440
+4: 3441
+4: 3442
+4: 3443
+4: 3444
+4: 3445
+4: 3446
+4: 3447
+4: 3448
+4: 3449
+4: 3450
+4: 3451
+4: 3452
+4: 3453
+4: 3454
+4: 3455
+4: 3456
+4: 3457
+4: 3458
+4: 3459
+4: 3460
+4: 3461
+4: 3462
+4: 3463
+4: 3464
+4: 3465
+4: 3466
+4: 3467
+4: 3468
+4: 3469
+4: 3470
+4: 3471
+4: 3472
+4: 3473
+4: 3474
+4: 3475
+4: 3476
+4: 3477
+4: 3478
+4: 3479
+4: 3480
+4: 3481
+4: 3482
+4: 3483
+4: 3484
+4: 3485
+4: 3486
+4: 3487
+4: 3488
+4: 3489
+4: 3490
+4: 3491
+4: 3492
+4: 3493
+4: 3494
+4: 3495
+4: 3496
+4: 3497
+4: 3498
+4: 3499
+4: 3500
+4: 3501
+4: 3502
+4: 3503
+4: 3504
+4: 3505
+4: 3506
+4: 3507
+4: 3508
+4: 3509
+4: 3510
+4: 3511
+4: 3512
+4: 3513
+4: 3514
+4: 3515
+4: 3516
+4: 3517
+4: 3518
+4: 3519
+4: 3520
+4: 3521
+4: 3522
+4: 3523
+4: 3524
+4: 3525
+4: 3526
+4: 3527
+4: 3528
+4: 3529
+4: 3530
+4: 3531
+4: 3532
+4: 3533
+4: 3534
+4: 3535
+4: 3536
+4: 3537
+4: 3538
+4: 3539
+4: 3540
+4: 3541
+4: 3542
+4: 3543
+4: 3544
+4: 3545
+4: 3546
+4: 3547
+4: 3548
+4: 3549
+4: 3550
+4: 3551
+4: 3552
+4: 3553
+4: 3554
+4: 3555
+4: 3556
+4: 3557
+4: 3558
+4: 3559
+4: 3560
+4: 3561
+4: 3562
+4: 3563
+4: 3564
+4: 3565
+4: 3566
+4: 3567
+4: 3568
+4: 3569
+4: 3570
+4: 3571
+4: 3572
+4: 3573
+4: 3574
+4: 3575
+4: 3576
+4: 3577
+4: 3578
+4: 3579
+4: 3580
+4: 3581
+4: 3582
+4: 3583
+4: 3584
+4: 3585
+4: 3586
+4: 3587
+4: 3588
+4: 3589
+4: 3590
+4: 3591
+4: 3592
+4: 3593
+4: 3594
+4: 3595
+4: 3596
+4: 3597
+4: 3598
+4: 3599
+4: 3600
+4: 3601
+4: 3602
+4: 3603
+4: 3604
+4: 3605
+4: 3606
+4: 3607
+4: 3608
+4: 3609
+4: 3610
+4: 3611
+4: 3612
+4: 3613
+4: 3614
+4: 3615
+4: 3616
+4: 3617
+4: 3618
+4: 3619
+4: 3620
+4: 3621
+4: 3622
+4: 3623
+4: 3624
+4: 3625
+4: 3626
+4: 3627
+4: 3628
+4: 3629
+4: 3630
+4: 3631
+4: 3632
+4: 3633
+4: 3634
+4: 3635
+4: 3636
+4: 3637
+4: 3638
+4: 3639
+4: 3640
+4: 3641
+4: 3642
+4: 3643
+4: 3644
+4: 3645
+4: 3646
+4: 3647
+4: 3648
+4: 3649
+4: 3650
+4: 3651
+4: 3652
+4: 3653
+4: 3654
+4: 3655
+4: 3656
+4: 3657
+4: 3658
+4: 3659
+4: 3660
+4: 3661
+4: 3662
+4: 3663
+4: 3664
+4: 3665
+4: 3666
+4: 3667
+4: 3668
+4: 3669
+4: 3670
+4: 3671
+4: 3672
+4: 3673
+4: 3674
+4: 3675
+4: 3676
+4: 3677
+4: 3678
+4: 3679
+4: 3680
+4: 3681
+4: 3682
+4: 3683
+4: 3684
+4: 3685
+4: 3686
+4: 3687
+4: 3688
+4: 3689
+4: 3690
+4: 3691
+4: 3692
+4: 3693
+4: 3694
+4: 3695
+4: 3696
+4: 3697
+4: 3698
+4: 3699
+4: 3700
+4: 3701
+4: 3702
+4: 3703
+4: 3704
+4: 3705
+4: 3706
+4: 3707
+4: 3708
+4: 3709
+4: 3710
+4: 3711
+4: 3712
+5: 3713
+5: 3714
+5: 3715
+5: 3716
+5: 3717
+5: 3718
+5: 3719
+5: 3720
+5: 3721
+5: 3722
+5: 3723
+5: 3724
+5: 3725
+5: 3726
+5: 3727
+5: 3728
+5: 3729
+5: 3730
+5: 3731
+5: 3732
+5: 3733
+5: 3734
+5: 3735
+5: 3736
+5: 3737
+5: 3738
+5: 3739
+5: 3740
+5: 3741
+5: 3742
+5: 3743
+5: 3744
+5: 3745
+5: 3746
+5: 3747
+5: 3748
+5: 3749
+5: 3750
+5: 3751
+5: 3752
+5: 3753
+5: 3754
+5: 3755
+5: 3756
+5: 3757
+5: 3758
+5: 3759
+5: 3760
+5: 3761
+5: 3762
+5: 3763
+5: 3764
+5: 3765
+5: 3766
+5: 3767
+5: 3768
+5: 3769
+5: 3770
+5: 3771
+5: 3772
+5: 3773
+5: 3774
+5: 3775
+5: 3776
+5: 3777
+5: 3778
+5: 3779
+5: 3780
+5: 3781
+5: 3782
+5: 3783
+5: 3784
+5: 3785
+5: 3786
+5: 3787
+5: 3788
+5: 3789
+5: 3790
+5: 3791
+5: 3792
+5: 3793
+5: 3794
+5: 3795
+5: 3796
+5: 3797
+5: 3798
+5: 3799
+5: 3800
+5: 3801
+5: 3802
+5: 3803
+5: 3804
+5: 3805
+5: 3806
+5: 3807
+5: 3808
+5: 3809
+5: 3810
+5: 3811
+5: 3812
+5: 3813
+5: 3814
+5: 3815
+5: 3816
+5: 3817
+5: 3818
+5: 3819
+5: 3820
+5: 3821
+5: 3822
+5: 3823
+5: 3824
+5: 3825
+5: 3826
+5: 3827
+5: 3828
+5: 3829
+5: 3830
+5: 3831
+5: 3832
+5: 3833
+5: 3834
+5: 3835
+5: 3836
+5: 3837
+5: 3838
+5: 3839
+5: 3840
+5: 3841
+5: 3842
+5: 3843
+5: 3844
+5: 3845
+5: 3846
+5: 3847
+5: 3848
+5: 3849
+5: 3850
+5: 3851
+5: 3852
+5: 3853
+5: 3854
+5: 3855
+5: 3856
+5: 3857
+5: 3858
+5: 3859
+5: 3860
+5: 3861
+5: 3862
+5: 3863
+5: 3864
+5: 3865
+5: 3866
+5: 3867
+5: 3868
+5: 3869
+5: 3870
+5: 3871
+5: 3872
+5: 3873
+5: 3874
+5: 3875
+5: 3876
+5: 3877
+5: 3878
+5: 3879
+5: 3880
+5: 3881
+5: 3882
+5: 3883
+5: 3884
+5: 3885
+5: 3886
+5: 3887
+5: 3888
+5: 3889
+5: 3890
+5: 3891
+5: 3892
+5: 3893
+5: 3894
+5: 3895
+5: 3896
+5: 3897
+5: 3898
+5: 3899
+5: 3900
+5: 3901
+5: 3902
+5: 3903
+5: 3904
+5: 3905
+5: 3906
+5: 3907
+5: 3908
+5: 3909
+5: 3910
+5: 3911
+5: 3912
+5: 3913
+5: 3914
+5: 3915
+5: 3916
+5: 3917
+5: 3918
+5: 3919
+5: 3920
+5: 3921
+5: 3922
+5: 3923
+5: 3924
+5: 3925
+5: 3926
+5: 3927
+5: 3928
+5: 3929
+5: 3930
+5: 3931
+5: 3932
+5: 3933
+5: 3934
+5: 3935
+5: 3936
+5: 3937
+5: 3938
+5: 3939
+5: 3940
+5: 3941
+5: 3942
+5: 3943
+5: 3944
+5: 3945
+5: 3946
+5: 3947
+5: 3948
+5: 3949
+5: 3950
+5: 3951
+5: 3952
+5: 3953
+5: 3954
+5: 3955
+5: 3956
+5: 3957
+5: 3958
+5: 3959
+5: 3960
+5: 3961
+5: 3962
+5: 3963
+5: 3964
+5: 3965
+5: 3966
+5: 3967
+5: 3968
+5: 3969
+5: 3970
+5: 3971
+5: 3972
+5: 3973
+5: 3974
+5: 3975
+5: 3976
+5: 3977
+5: 3978
+5: 3979
+5: 3980
+5: 3981
+5: 3982
+5: 3983
+5: 3984
+5: 3985
+5: 3986
+5: 3987
+5: 3988
+5: 3989
+5: 3990
+5: 3991
+5: 3992
+5: 3993
+5: 3994
+5: 3995
+5: 3996
+5: 3997
+5: 3998
+5: 3999
+5: 4000
+5: 4001
+5: 4002
+5: 4003
+5: 4004
+4: 4005
+4: 4006
+4: 4007
+4: 4008
+4: 4009
+4: 4010
+4: 4011
+4: 4012
+4: 4013
+4: 4014
+4: 4015
+4: 4016
+4: 4017
+4: 4018
+4: 4019
+4: 4020
+4: 4021
+4: 4022
+4: 4023
+4: 4024
+4: 4025
+4: 4026
+4: 4027
+4: 4028
+4: 4029
+4: 4030
+4: 4031
+4: 4032
+4: 4033
+4: 4034
+4: 4035
+4: 4036
+4: 4037
+4: 4038
+4: 4039
+4: 4040
+4: 4041
+4: 4042
+4: 4043
+4: 4044
+4: 4045
+4: 4046
+4: 4047
+4: 4048
+4: 4049
+4: 4050
+4: 4051
+4: 4052
+4: 4053
+4: 4054
+4: 4055
+4: 4056
+4: 4057
+4: 4058
+4: 4059
+4: 4060
+4: 4061
+4: 4062
+4: 4063
+4: 4064
+4: 4065
+4: 4066
+4: 4067
+4: 4068
+4: 4069
+4: 4070
+4: 4071
+4: 4072
+4: 4073
+4: 4074
+4: 4075
+4: 4076
+4: 4077
+4: 4078
+4: 4079
+4: 4080
+4: 4081
+4: 4082
+4: 4083
+4: 4084
+4: 4085
+4: 4086
+4: 4087
+4: 4088
+4: 4089
+4: 4090
+4: 4091
+4: 4092
+4: 4093
+4: 4094
+4: 4095
+4: 4096
+4: 4097
+4: 4098
+4: 4099
+4: 4100
+4: 4101
+4: 4102
+4: 4103
+4: 4104
+4: 4105
+4: 4106
+4: 4107
+4: 4108
+4: 4109
+4: 4110
+4: 4111
+4: 4112
+4: 4113
+4: 4114
+4: 4115
+4: 4116
+4: 4117
+4: 4118
+4: 4119
+4: 4120
+4: 4121
+4: 4122
+4: 4123
+4: 4124
+4: 4125
+4: 4126
+4: 4127
+4: 4128
+4: 4129
+4: 4130
+4: 4131
+4: 4132
+4: 4133
+4: 4134
+4: 4135
+4: 4136
+4: 4137
+4: 4138
+4: 4139
+4: 4140
+4: 4141
+4: 4142
+4: 4143
+4: 4144
+4: 4145
+4: 4146
+4: 4147
+4: 4148
+4: 4149
+4: 4150
+4: 4151
+4: 4152
+4: 4153
+4: 4154
+4: 4155
+4: 4156
+4: 4157
+4: 4158
+4: 4159
+4: 4160
+4: 4161
+4: 4162
+4: 4163
+4: 4164
+4: 4165
+4: 4166
+4: 4167
+4: 4168
+4: 4169
+4: 4170
+4: 4171
+4: 4172
+4: 4173
+4: 4174
+4: 4175
+4: 4176
+4: 4177
+4: 4178
+4: 4179
+4: 4180
+4: 4181
+4: 4182
+4: 4183
+4: 4184
+4: 4185
+4: 4186
+4: 4187
+4: 4188
+4: 4189
+4: 4190
+4: 4191
+4: 4192
+4: 4193
+4: 4194
+4: 4195
+4: 4196
+4: 4197
+4: 4198
+4: 4199
+4: 4200
+4: 4201
+4: 4202
+4: 4203
+4: 4204
+4: 4205
+4: 4206
+4: 4207
+4: 4208
+4: 4209
+4: 4210
+4: 4211
+4: 4212
+4: 4213
+4: 4214
+4: 4215
+4: 4216
+4: 4217
+4: 4218
+4: 4219
+4: 4220
+4: 4221
+4: 4222
+4: 4223
+4: 4224
+4: 4225
+4: 4226
+4: 4227
+4: 4228
+4: 4229
+4: 4230
+4: 4231
+4: 4232
+4: 4233
+4: 4234
+4: 4235
+4: 4236
+4: 4237
+4: 4238
+4: 4239
+4: 4240
+4: 4241
+4: 4242
+4: 4243
+4: 4244
+4: 4245
+4: 4246
+4: 4247
+4: 4248
+4: 4249
+4: 4250
+4: 4251
+4: 4252
+4: 4253
+4: 4254
+4: 4255
+4: 4256
+4: 4257
+4: 4258
+4: 4259
+4: 4260
+4: 4261
+4: 4262
+4: 4263
+4: 4264
+4: 4265
+4: 4266
+4: 4267
+4: 4268
+4: 4269
+4: 4270
+4: 4271
+4: 4272
+4: 4273
+4: 4274
+4: 4275
+4: 4276
+4: 4277
+4: 4278
+4: 4279
+4: 4280
+4: 4281
+4: 4282
+4: 4283
+4: 4284
+4: 4285
+4: 4286
+4: 4287
+4: 4288
+4: 4289
+4: 4290
+4: 4291
+4: 4292
+4: 4293
+4: 4294
+4: 4295
+4: 4296
+4: 4297
+4: 4298
+4: 4299
+4: 4300
+4: 4301
+4: 4302
+4: 4303
+4: 4304
+4: 4305
+4: 4306
+4: 4307
+4: 4308
+4: 4309
+4: 4310
+4: 4311
+4: 4312
+4: 4313
+4: 4314
+4: 4315
+4: 4316
+4: 4317
+4: 4318
+4: 4319
+4: 4320
+4: 4321
+5: 4322
+5: 4323
+5: 4324
+5: 4325
+5: 4326
+5: 4327
+5: 4328
+5: 4329
+5: 4330
+5: 4331
+5: 4332
+5: 4333
+5: 4334
+5: 4335
+5: 4336
+5: 4337
+5: 4338
+5: 4339
+5: 4340
+5: 4341
+5: 4342
+5: 4343
+5: 4344
+5: 4345
+5: 4346
+5: 4347
+5: 4348
+5: 4349
+5: 4350
+5: 4351
+5: 4352
+5: 4353
+5: 4354
+5: 4355
+5: 4356
+5: 4357
+5: 4358
+5: 4359
+5: 4360
+5: 4361
+5: 4362
+5: 4363
+5: 4364
+5: 4365
+5: 4366
+5: 4367
+5: 4368
+5: 4369
+5: 4370
+5: 4371
+5: 4372
+5: 4373
+5: 4374
+5: 4375
+5: 4376
+5: 4377
+5: 4378
+5: 4379
+5: 4380
+5: 4381
+5: 4382
+5: 4383
+5: 4384
+5: 4385
+5: 4386
+5: 4387
+5: 4388
+5: 4389
+5: 4390
+5: 4391
+5: 4392
+5: 4393
+5: 4394
+5: 4395
+5: 4396
+5: 4397
+5: 4398
+5: 4399
+5: 4400
+5: 4401
+5: 4402
+5: 4403
+5: 4404
+5: 4405
+5: 4406
+5: 4407
+5: 4408
+5: 4409
+5: 4410
+5: 4411
+5: 4412
+5: 4413
+5: 4414
+5: 4415
+5: 4416
+5: 4417
+5: 4418
+5: 4419
+5: 4420
+5: 4421
+5: 4422
+5: 4423
+5: 4424
+5: 4425
+5: 4426
+5: 4427
+5: 4428
+5: 4429
+5: 4430
+5: 4431
+5: 4432
+5: 4433
+5: 4434
+5: 4435
+5: 4436
+5: 4437
+5: 4438
+5: 4439
+5: 4440
+5: 4441
+5: 4442
+5: 4443
+5: 4444
+5: 4445
+5: 4446
+5: 4447
+5: 4448
+5: 4449
+5: 4450
+5: 4451
+5: 4452
+5: 4453
+5: 4454
+5: 4455
+5: 4456
+5: 4457
+5: 4458
+5: 4459
+5: 4460
+5: 4461
+5: 4462
+5: 4463
+5: 4464
+5: 4465
+5: 4466
+5: 4467
+5: 4468
+5: 4469
+5: 4470
+5: 4471
+5: 4472
+5: 4473
+5: 4474
+5: 4475
+5: 4476
+5: 4477
+5: 4478
+5: 4479
+5: 4480
+5: 4481
+5: 4482
+5: 4483
+5: 4484
+5: 4485
+5: 4486
+5: 4487
+5: 4488
+5: 4489
+5: 4490
+5: 4491
+5: 4492
+5: 4493
+5: 4494
+5: 4495
+5: 4496
+5: 4497
+5: 4498
+5: 4499
+5: 4500
+5: 4501
+5: 4502
+5: 4503
+5: 4504
+5: 4505
+5: 4506
+5: 4507
+5: 4508
+5: 4509
+5: 4510
+5: 4511
+5: 4512
+5: 4513
+5: 4514
+5: 4515
+5: 4516
+5: 4517
+5: 4518
+5: 4519
+5: 4520
+5: 4521
+5: 4522
+5: 4523
+5: 4524
+5: 4525
+5: 4526
+5: 4527
+5: 4528
+5: 4529
+5: 4530
+5: 4531
+5: 4532
+5: 4533
+5: 4534
+5: 4535
+5: 4536
+5: 4537
+5: 4538
+5: 4539
+5: 4540
+5: 4541
+5: 4542
+5: 4543
+5: 4544
+5: 4545
+5: 4546
+5: 4547
+5: 4548
+5: 4549
+5: 4550
+5: 4551
+5: 4552
+5: 4553
+5: 4554
+5: 4555
+5: 4556
+5: 4557
+5: 4558
+5: 4559
+5: 4560
+5: 4561
+5: 4562
+5: 4563
+5: 4564
+5: 4565
+5: 4566
+5: 4567
+5: 4568
+5: 4569
+5: 4570
+5: 4571
+5: 4572
+5: 4573
+5: 4574
+5: 4575
+5: 4576
+5: 4577
+5: 4578
+5: 4579
+5: 4580
+5: 4581
+5: 4582
+5: 4583
+5: 4584
+5: 4585
+5: 4586
+5: 4587
+5: 4588
+5: 4589
+5: 4590
+5: 4591
+5: 4592
+5: 4593
+5: 4594
+5: 4595
+5: 4596
+5: 4597
+5: 4598
+5: 4599
+5: 4600
+5: 4601
+5: 4602
+5: 4603
+5: 4604
+5: 4605
+5: 4606
+5: 4607
+5: 4608
+5: 4609
+5: 4610
+5: 4611
+5: 4612
+5: 4613
+5: 4614
+5: 4615
+5: 4616
+5: 4617
+5: 4618
+5: 4619
+5: 4620
+5: 4621
+5: 4622
+5: 4623
+5: 4624
+5: 4625
+5: 4626
+5: 4627
+5: 4628
+5: 4629
+5: 4630
+5: 4631
+5: 4632
+5: 4633
+5: 4634
+5: 4635
+5: 4636
+5: 4637
+5: 4638
+5: 4639
+5: 4640
+5: 4641
+5: 4642
+5: 4643
+5: 4644
+5: 4645
+5: 4646
+5: 4647
+5: 4648
+5: 4649
+5: 4650
+5: 4651
+5: 4652
+5: 4653
+5: 4654
+5: 4655
+5: 4656
+5: 4657
+5: 4658
+5: 4659
+5: 4660
+5: 4661
+5: 4662
+5: 4663
+5: 4664
+5: 4665
+5: 4666
+5: 4667
+5: 4668
+5: 4669
+5: 4670
+5: 4671
+5: 4672
+5: 4673
+5: 4674
+5: 4675
+5: 4676
+5: 4677
+5: 4678
+5: 4679
+5: 4680
+5: 4681
+5: 4682
+5: 4683
+5: 4684
+5: 4685
+5: 4686
+5: 4687
+5: 4688
+5: 4689
+5: 4690
+5: 4691
+5: 4692
+5: 4693
+5: 4694
+5: 4695
+5: 4696
+5: 4697
+5: 4698
+5: 4699
+5: 4700
+5: 4701
+5: 4702
+5: 4703
+5: 4704
+5: 4705
+5: 4706
+5: 4707
+5: 4708
+5: 4709
+5: 4710
+5: 4711
+5: 4712
+5: 4713
+5: 4714
+5: 4715
+5: 4716
+5: 4717
+5: 4718
+5: 4719
+5: 4720
+5: 4721
+5: 4722
+5: 4723
+5: 4724
+5: 4725
+5: 4726
+5: 4727
+5: 4728
+5: 4729
+5: 4730
+5: 4731
+5: 4732
+5: 4733
+5: 4734
+5: 4735
+5: 4736
+5: 4737
+5: 4738
+5: 4739
+5: 4740
+5: 4741
+5: 4742
+5: 4743
+5: 4744
+5: 4745
+5: 4746
+5: 4747
+5: 4748
+5: 4749
+5: 4750
+5: 4751
+5: 4752
+5: 4753
+5: 4754
+5: 4755
+5: 4756
+5: 4757
+5: 4758
+5: 4759
+5: 4760
+5: 4761
+5: 4762
+5: 4763
+5: 4764
+5: 4765
+5: 4766
+5: 4767
+5: 4768
+5: 4769
+5: 4770
+5: 4771
+5: 4772
+5: 4773
+5: 4774
+5: 4775
+5: 4776
+5: 4777
+5: 4778
+5: 4779
+5: 4780
+5: 4781
+5: 4782
+5: 4783
+5: 4784
+5: 4785
+5: 4786
+5: 4787
+5: 4788
+5: 4789
+5: 4790
+5: 4791
+5: 4792
+5: 4793
+5: 4794
+5: 4795
+5: 4796
+5: 4797
+5: 4798
+5: 4799
+5: 4800
+5: 4801
+5: 4802
+5: 4803
+5: 4804
+5: 4805
+5: 4806
+5: 4807
+5: 4808
+5: 4809
+5: 4810
+5: 4811
+5: 4812
+5: 4813
+5: 4814
+5: 4815
+5: 4816
+5: 4817
+5: 4818
+5: 4819
+5: 4820
+5: 4821
+5: 4822
+5: 4823
+5: 4824
+5: 4825
+5: 4826
+5: 4827
+5: 4828
+5: 4829
+5: 4830
+5: 4831
+5: 4832
+5: 4833
+5: 4834
+5: 4835
+5: 4836
+5: 4837
+5: 4838
+5: 4839
+5: 4840
+5: 4841
+5: 4842
+5: 4843
+5: 4844
+5: 4845
+5: 4846
+5: 4847
+5: 4848
+5: 4849
+5: 4850
+5: 4851
+5: 4852
+5: 4853
+5: 4854
+5: 4855
+5: 4856
+5: 4857
+5: 4858
+5: 4859
+5: 4860
+5: 4861
+5: 4862
+5: 4863
+5: 4864
+5: 4865
+5: 4866
+5: 4867
+5: 4868
+5: 4869
+5: 4870
+5: 4871
+5: 4872
+5: 4873
+5: 4874
+5: 4875
+5: 4876
+5: 4877
+5: 4878
+5: 4879
+5: 4880
+5: 4881
+5: 4882
+5: 4883
+5: 4884
+5: 4885
+5: 4886
+5: 4887
+5: 4888
+5: 4889
+5: 4890
+5: 4891
+5: 4892
+5: 4893
+5: 4894
+5: 4895
+5: 4896
+5: 4897
+5: 4898
+5: 4899
+5: 4900
+5: 4901
+5: 4902
+5: 4903
+5: 4904
+5: 4905
+5: 4906
+5: 4907
+5: 4908
+5: 4909
+5: 4910
+5: 4911
+5: 4912
+5: 4913
+5: 4914
+5: 4915
+5: 4916
+5: 4917
+5: 4918
+5: 4919
+5: 4920
+5: 4921
+5: 4922
+5: 4923
+5: 4924
+5: 4925
+5: 4926
+5: 4927
+5: 4928
+5: 4929
+5: 4930
+5: 4931
+5: 4932
+5: 4933
+5: 4934
+5: 4935
+5: 4936
+5: 4937
+5: 4938
+5: 4939
+5: 4940
+5: 4941
+5: 4942
+5: 4943
+5: 4944
+5: 4945
+5: 4946
+5: 4947
+5: 4948
+5: 4949
+5: 4950
+5: 4951
+5: 4952
+5: 4953
+5: 4954
+5: 4955
+5: 4956
+5: 4957
+5: 4958
+5: 4959
+5: 4960
+5: 4961
+5: 4962
+5: 4963
+5: 4964
+5: 4965
+5: 4966
+5: 4967
+5: 4968
+5: 4969
+5: 4970
+5: 4971
+5: 4972
+5: 4973
+5: 4974
+5: 4975
+5: 4976
+5: 4977
+5: 4978
+5: 4979
+5: 4980
+5: 4981
+5: 4982
+5: 4983
+5: 4984
+4: 4985
+4: 4986
+4: 4987
+4: 4988
+4: 4989
+4: 4990
+4: 4991
+4: 4992
+4: 4993
+4: 4994
+4: 4995
+4: 4996
+4: 4997
+4: 4998
+4: 4999
+4: 5000
+4: 5001
+4: 5002
+4: 5003
+4: 5004
+4: 5005
+4: 5006
+4: 5007
+4: 5008
+4: 5009
+4: 5010
+4: 5011
+4: 5012
+4: 5013
+4: 5014
+4: 5015
+4: 5016
+4: 5017
+4: 5018
+4: 5019
+4: 5020
+4: 5021
+4: 5022
+4: 5023
+4: 5024
+4: 5025
+4: 5026
+4: 5027
+4: 5028
+4: 5029
+4: 5030
+4: 5031
+4: 5032
+4: 5033
+4: 5034
+4: 5035
+4: 5036
+4: 5037
+4: 5038
+4: 5039
+4: 5040
+4: 5041
+4: 5042
+4: 5043
+4: 5044
+4: 5045
+4: 5046
+4: 5047
+4: 5048
+4: 5049
+4: 5050
+4: 5051
+4: 5052
+4: 5053
+4: 5054
+4: 5055
+4: 5056
+4: 5057
+4: 5058
+4: 5059
+4: 5060
+4: 5061
+4: 5062
+4: 5063
+4: 5064
+4: 5065
+4: 5066
+4: 5067
+4: 5068
+4: 5069
+4: 5070
+4: 5071
+4: 5072
+4: 5073
+4: 5074
+4: 5075
+4: 5076
+4: 5077
+4: 5078
+4: 5079
+4: 5080
+4: 5081
+4: 5082
+4: 5083
+4: 5084
+4: 5085
+4: 5086
+4: 5087
+4: 5088
+4: 5089
+4: 5090
+4: 5091
+4: 5092
+4: 5093
+4: 5094
+4: 5095
+4: 5096
+4: 5097
+4: 5098
+4: 5099
+4: 5100
+4: 5101
+4: 5102
+4: 5103
+4: 5104
+4: 5105
+4: 5106
+4: 5107
+4: 5108
+4: 5109
+4: 5110
+4: 5111
+4: 5112
+4: 5113
+4: 5114
+4: 5115
+4: 5116
+4: 5117
+4: 5118
+4: 5119
+4: 5120
+4: 5121
+4: 5122
+4: 5123
+4: 5124
+4: 5125
+4: 5126
+4: 5127
+4: 5128
+4: 5129
+4: 5130
+4: 5131
+4: 5132
+4: 5133
+4: 5134
+4: 5135
+4: 5136
+4: 5137
+4: 5138
+4: 5139
+4: 5140
+4: 5141
+4: 5142
+4: 5143
+4: 5144
+4: 5145
+4: 5146
+4: 5147
+4: 5148
+4: 5149
+4: 5150
+4: 5151
+4: 5152
+4: 5153
+4: 5154
+4: 5155
+4: 5156
+4: 5157
+4: 5158
+4: 5159
+4: 5160
+4: 5161
+4: 5162
+4: 5163
+4: 5164
+4: 5165
+4: 5166
+4: 5167
+4: 5168
+4: 5169
+4: 5170
+4: 5171
+4: 5172
+4: 5173
+4: 5174
+4: 5175
+4: 5176
+4: 5177
+4: 5178
+4: 5179
+4: 5180
+4: 5181
+4: 5182
+4: 5183
+4: 5184
+4: 5185
+4: 5186
+4: 5187
+4: 5188
+4: 5189
+4: 5190
+4: 5191
+4: 5192
+4: 5193
+4: 5194
+4: 5195
+4: 5196
+4: 5197
+4: 5198
+4: 5199
+4: 5200
+4: 5201
+4: 5202
+4: 5203
+4: 5204
+4: 5205
+4: 5206
+4: 5207
+4: 5208
+4: 5209
+4: 5210
+4: 5211
+4: 5212
+4: 5213
+4: 5214
+4: 5215
+4: 5216
+4: 5217
+4: 5218
+4: 5219
+4: 5220
+4: 5221
+4: 5222
+4: 5223
+4: 5224
+4: 5225
+4: 5226
+4: 5227
+4: 5228
+4: 5229
+4: 5230
+4: 5231
+4: 5232
+4: 5233
+4: 5234
+4: 5235
+4: 5236
+4: 5237
+4: 5238
+4: 5239
+4: 5240
+4: 5241
+4: 5242
+4: 5243
+4: 5244
+4: 5245
+4: 5246
+4: 5247
+4: 5248
+4: 5249
+4: 5250
+4: 5251
+4: 5252
+4: 5253
+4: 5254
+4: 5255
+4: 5256
+4: 5257
+4: 5258
+4: 5259
+4: 5260
+4: 5261
+5: 5262
+5: 5263
+5: 5264
+5: 5265
+5: 5266
+5: 5267
+5: 5268
+5: 5269
+5: 5270
+5: 5271
+5: 5272
+5: 5273
+5: 5274
+5: 5275
+5: 5276
+5: 5277
+5: 5278
+5: 5279
+5: 5280
+5: 5281
+5: 5282
+5: 5283
+5: 5284
+5: 5285
+5: 5286
+5: 5287
+5: 5288
+5: 5289
+5: 5290
+5: 5291
+5: 5292
+5: 5293
+5: 5294
+5: 5295
+5: 5296
+5: 5297
+5: 5298
+5: 5299
+5: 5300
+5: 5301
+5: 5302
+5: 5303
+5: 5304
+5: 5305
+5: 5306
+5: 5307
+5: 5308
+5: 5309
+5: 5310
+5: 5311
+5: 5312
+5: 5313
+5: 5314
+5: 5315
+5: 5316
+5: 5317
+5: 5318
+5: 5319
+5: 5320
+5: 5321
+5: 5322
+5: 5323
+5: 5324
+5: 5325
+5: 5326
+5: 5327
+5: 5328
+5: 5329
+5: 5330
+5: 5331
+5: 5332
+5: 5333
+5: 5334
+5: 5335
+5: 5336
+5: 5337
+5: 5338
+5: 5339
+5: 5340
+5: 5341
+5: 5342
+5: 5343
+5: 5344
+5: 5345
+5: 5346
+5: 5347
+5: 5348
+5: 5349
+5: 5350
+5: 5351
+5: 5352
+5: 5353
+5: 5354
+5: 5355
+5: 5356
+5: 5357
+5: 5358
+5: 5359
+5: 5360
+5: 5361
+5: 5362
+5: 5363
+5: 5364
+5: 5365
+5: 5366
+5: 5367
+5: 5368
+5: 5369
+5: 5370
+5: 5371
+5: 5372
+5: 5373
+5: 5374
+5: 5375
+5: 5376
+5: 5377
+5: 5378
+5: 5379
+5: 5380
+5: 5381
+5: 5382
+5: 5383
+5: 5384
+5: 5385
+5: 5386
+5: 5387
+5: 5388
+5: 5389
+5: 5390
+5: 5391
+5: 5392
+5: 5393
+5: 5394
+5: 5395
+5: 5396
+5: 5397
+5: 5398
+5: 5399
+5: 5400
+5: 5401
+5: 5402
+5: 5403
+5: 5404
+5: 5405
+5: 5406
+5: 5407
+5: 5408
+5: 5409
+5: 5410
+5: 5411
+5: 5412
+5: 5413
+5: 5414
+5: 5415
+5: 5416
+5: 5417
+5: 5418
+5: 5419
+5: 5420
+5: 5421
+5: 5422
+5: 5423
+5: 5424
+5: 5425
+5: 5426
+5: 5427
+5: 5428
+5: 5429
+5: 5430
+5: 5431
+5: 5432
+5: 5433
+5: 5434
+5: 5435
+5: 5436
+5: 5437
+5: 5438
+5: 5439
+5: 5440
+5: 5441
+5: 5442
+5: 5443
+5: 5444
+5: 5445
+5: 5446
+5: 5447
+5: 5448
+5: 5449
+5: 5450
+5: 5451
+5: 5452
+5: 5453
+5: 5454
+5: 5455
+5: 5456
+5: 5457
+5: 5458
+5: 5459
+5: 5460
+5: 5461
+5: 5462
+5: 5463
+5: 5464
+5: 5465
+5: 5466
+5: 5467
+5: 5468
+5: 5469
+5: 5470
+5: 5471
+5: 5472
+5: 5473
+5: 5474
+5: 5475
+5: 5476
+5: 5477
+5: 5478
+5: 5479
+5: 5480
+5: 5481
+5: 5482
+5: 5483
+5: 5484
+5: 5485
+5: 5486
+5: 5487
+5: 5488
+5: 5489
+5: 5490
+5: 5491
+5: 5492
+5: 5493
+5: 5494
+5: 5495
+5: 5496
+5: 5497
+5: 5498
+5: 5499
+5: 5500
+5: 5501
+5: 5502
+5: 5503
+5: 5504
+5: 5505
+5: 5506
+5: 5507
+5: 5508
+5: 5509
+5: 5510
+5: 5511
+5: 5512
+5: 5513
+5: 5514
+5: 5515
+5: 5516
+5: 5517
+5: 5518
+5: 5519
+5: 5520
+5: 5521
+5: 5522
+5: 5523
+5: 5524
+5: 5525
+5: 5526
+5: 5527
+5: 5528
+5: 5529
+5: 5530
+5: 5531
+5: 5532
+5: 5533
+5: 5534
+5: 5535
+5: 5536
+5: 5537
+5: 5538
+5: 5539
+5: 5540
+5: 5541
+5: 5542
+5: 5543
+5: 5544
+5: 5545
+5: 5546
+5: 5547
+5: 5548
+5: 5549
+5: 5550
+5: 5551
+5: 5552
+5: 5553
+5: 5554
+5: 5555
+5: 5556
+5: 5557
+5: 5558
+5: 5559
+5: 5560
+5: 5561
+5: 5562
+5: 5563
+5: 5564
+5: 5565
+5: 5566
+5: 5567
+5: 5568
+5: 5569
+5: 5570
+5: 5571
+5: 5572
+5: 5573
+5: 5574
+5: 5575
+5: 5576
+5: 5577
+5: 5578
+5: 5579
+5: 5580
+5: 5581
+5: 5582
+5: 5583
+5: 5584
+5: 5585
+5: 5586
+5: 5587
+5: 5588
+5: 5589
+5: 5590
+5: 5591
+5: 5592
+5: 5593
+5: 5594
+5: 5595
+5: 5596
+5: 5597
+5: 5598
+5: 5599
+5: 5600
+5: 5601
+5: 5602
+4: 5603
+4: 5604
+4: 5605
+4: 5606
+4: 5607
+4: 5608
+4: 5609
+4: 5610
+4: 5611
+4: 5612
+4: 5613
+4: 5614
+4: 5615
+4: 5616
+4: 5617
+4: 5618
+4: 5619
+4: 5620
+4: 5621
+4: 5622
+4: 5623
+4: 5624
+4: 5625
+4: 5626
+4: 5627
+4: 5628
+4: 5629
+4: 5630
+4: 5631
+4: 5632
+4: 5633
+4: 5634
+4: 5635
+4: 5636
+4: 5637
+4: 5638
+4: 5639
+4: 5640
+4: 5641
+4: 5642
+4: 5643
+4: 5644
+4: 5645
+4: 5646
+4: 5647
+4: 5648
+4: 5649
+4: 5650
+4: 5651
+4: 5652
+4: 5653
+4: 5654
+4: 5655
+4: 5656
+4: 5657
+4: 5658
+4: 5659
+4: 5660
+4: 5661
+4: 5662
+4: 5663
+4: 5664
+4: 5665
+4: 5666
+4: 5667
+4: 5668
+4: 5669
+4: 5670
+4: 5671
+4: 5672
+4: 5673
+4: 5674
+4: 5675
+4: 5676
+4: 5677
+4: 5678
+4: 5679
+4: 5680
+4: 5681
+4: 5682
+4: 5683
+4: 5684
+4: 5685
+4: 5686
+4: 5687
+4: 5688
+4: 5689
+4: 5690
+4: 5691
+4: 5692
+4: 5693
+4: 5694
+4: 5695
+4: 5696
+4: 5697
+4: 5698
+4: 5699
+4: 5700
+4: 5701
+4: 5702
+4: 5703
+4: 5704
+4: 5705
+4: 5706
+4: 5707
+4: 5708
+4: 5709
+4: 5710
+4: 5711
+4: 5712
+4: 5713
+4: 5714
+4: 5715
+4: 5716
+4: 5717
+4: 5718
+4: 5719
+4: 5720
+4: 5721
+4: 5722
+4: 5723
+4: 5724
+4: 5725
+4: 5726
+4: 5727
+4: 5728
+4: 5729
+4: 5730
+4: 5731
+4: 5732
+4: 5733
+4: 5734
+4: 5735
+4: 5736
+4: 5737
+4: 5738
+4: 5739
+4: 5740
+4: 5741
+4: 5742
+4: 5743
+4: 5744
+4: 5745
+4: 5746
+4: 5747
+4: 5748
+4: 5749
+4: 5750
+4: 5751
+4: 5752
+4: 5753
+4: 5754
+4: 5755
+4: 5756
+4: 5757
+4: 5758
+4: 5759
+4: 5760
+4: 5761
+4: 5762
+4: 5763
+4: 5764
+4: 5765
+4: 5766
+4: 5767
+4: 5768
+4: 5769
+4: 5770
+4: 5771
+4: 5772
+4: 5773
+4: 5774
+4: 5775
+4: 5776
+4: 5777
+4: 5778
+4: 5779
+4: 5780
+4: 5781
+4: 5782
+4: 5783
+4: 5784
+4: 5785
+4: 5786
+4: 5787
+4: 5788
+4: 5789
+4: 5790
+4: 5791
+4: 5792
+4: 5793
+4: 5794
+4: 5795
+4: 5796
+4: 5797
+4: 5798
+4: 5799
+4: 5800
+4: 5801
+4: 5802
+4: 5803
+4: 5804
+4: 5805
+4: 5806
+4: 5807
+4: 5808
+4: 5809
+4: 5810
+4: 5811
+4: 5812
+4: 5813
+4: 5814
+4: 5815
+4: 5816
+4: 5817
+4: 5818
+4: 5819
+4: 5820
+4: 5821
+4: 5822
+4: 5823
+4: 5824
+4: 5825
+4: 5826
+4: 5827
+4: 5828
+4: 5829
+4: 5830
+4: 5831
+4: 5832
+4: 5833
+4: 5834
+4: 5835
+4: 5836
+4: 5837
+4: 5838
+4: 5839
+4: 5840
+4: 5841
+4: 5842
+4: 5843
+4: 5844
+4: 5845
+4: 5846
+4: 5847
+4: 5848
+4: 5849
+4: 5850
+4: 5851
+4: 5852
+4: 5853
+4: 5854
+4: 5855
+4: 5856
+4: 5857
+4: 5858
+4: 5859
+4: 5860
+4: 5861
+4: 5862
+4: 5863
+4: 5864
+4: 5865
+4: 5866
+4: 5867
+4: 5868
+4: 5869
+4: 5870
+4: 5871
+4: 5872
+4: 5873
+4: 5874
+4: 5875
+4: 5876
+4: 5877
+4: 5878
+4: 5879
+4: 5880
+4: 5881
+4: 5882
+4: 5883
+4: 5884
+4: 5885
+4: 5886
+4: 5887
+4: 5888
+4: 5889
+4: 5890
+4: 5891
+4: 5892
+4: 5893
+4: 5894
+4: 5895
+4: 5896
+4: 5897
+4: 5898
+4: 5899
+4: 5900
+4: 5901
+4: 5902
+4: 5903
+4: 5904
+4: 5905
+4: 5906
+4: 5907
+4: 5908
+4: 5909
+4: 5910
+4: 5911
+4: 5912
+4: 5913
+4: 5914
+4: 5915
+4: 5916
+4: 5917
+4: 5918
+4: 5919
+4: 5920
+4: 5921
+4: 5922
+4: 5923
+4: 5924
+4: 5925
+4: 5926
+4: 5927
+4: 5928
+4: 5929
+4: 5930
+4: 5931
+4: 5932
+4: 5933
+4: 5934
+4: 5935
+4: 5936
+4: 5937
+4: 5938
+4: 5939
+4: 5940
+4: 5941
+4: 5942
+4: 5943
+4: 5944
+4: 5945
+4: 5946
+4: 5947
+4: 5948
+4: 5949
+4: 5950
+4: 5951
+4: 5952
+4: 5953
+4: 5954
+4: 5955
+4: 5956
+4: 5957
+4: 5958
+4: 5959
+4: 5960
+4: 5961
+4: 5962
+4: 5963
+4: 5964
+4: 5965
+4: 5966
+4: 5967
+4: 5968
+4: 5969
+4: 5970
+4: 5971
+4: 5972
+4: 5973
+4: 5974
+4: 5975
+4: 5976
+4: 5977
+4: 5978
+4: 5979
+4: 5980
+4: 5981
+4: 5982
+4: 5983
+4: 5984
+4: 5985
+4: 5986
+4: 5987
+4: 5988
+4: 5989
+4: 5990
+4: 5991
+4: 5992
+4: 5993
+4: 5994
+4: 5995
+4: 5996
+4: 5997
+4: 5998
+4: 5999
+4: 6000
+4: 6001
+4: 6002
+4: 6003
+4: 6004
+4: 6005
+4: 6006
+4: 6007
+4: 6008
+4: 6009
+4: 6010
+4: 6011
+4: 6012
+4: 6013
+4: 6014
+4: 6015
+4: 6016
+4: 6017
+4: 6018
+4: 6019
+4: 6020
+4: 6021
+4: 6022
+4: 6023
+4: 6024
+4: 6025
+4: 6026
+4: 6027
+4: 6028
+4: 6029
+4: 6030
+4: 6031
+4: 6032
+4: 6033
+4: 6034
+4: 6035
+4: 6036
+4: 6037
+4: 6038
+4: 6039
+4: 6040
+4: 6041
+4: 6042
+4: 6043
+4: 6044
+4: 6045
+4: 6046
+4: 6047
+4: 6048
+4: 6049
+4: 6050
+4: 6051
+4: 6052
+4: 6053
+4: 6054
+4: 6055
+4: 6056
+4: 6057
+4: 6058
+4: 6059
+4: 6060
+4: 6061
+4: 6062
+4: 6063
+4: 6064
+4: 6065
+4: 6066
+4: 6067
+4: 6068
+4: 6069
+4: 6070
+4: 6071
+4: 6072
+4: 6073
+4: 6074
+4: 6075
+4: 6076
+4: 6077
+4: 6078
+4: 6079
+4: 6080
+4: 6081
+4: 6082
+4: 6083
+4: 6084
+4: 6085
+4: 6086
+4: 6087
+4: 6088
+4: 6089
+4: 6090
+4: 6091
+4: 6092
+4: 6093
+4: 6094
+4: 6095
+4: 6096
+4: 6097
+4: 6098
+4: 6099
+4: 6100
+4: 6101
+4: 6102
+4: 6103
+4: 6104
+4: 6105
+4: 6106
+4: 6107
+4: 6108
+4: 6109
+4: 6110
+4: 6111
+4: 6112
+4: 6113
+4: 6114
+4: 6115
+4: 6116
+4: 6117
+4: 6118
+4: 6119
+4: 6120
+4: 6121
+4: 6122
+4: 6123
+4: 6124
+4: 6125
+4: 6126
+4: 6127
+4: 6128
+4: 6129
+4: 6130
+4: 6131
+4: 6132
+4: 6133
+4: 6134
+4: 6135
+4: 6136
+4: 6137
+4: 6138
+4: 6139
+4: 6140
+4: 6141
+4: 6142
+4: 6143
+4: 6144
+4: 6145
+4: 6146
+4: 6147
+4: 6148
+4: 6149
+4: 6150
+4: 6151
+4: 6152
+4: 6153
+4: 6154
+4: 6155
+4: 6156
+4: 6157
+4: 6158
+4: 6159
+4: 6160
+4: 6161
+4: 6162
+4: 6163
+4: 6164
+4: 6165
+4: 6166
+4: 6167
+4: 6168
+4: 6169
+4: 6170
+4: 6171
+4: 6172
+4: 6173
+4: 6174
+4: 6175
+4: 6176
+4: 6177
+4: 6178
+4: 6179
+4: 6180
+4: 6181
+4: 6182
+4: 6183
+4: 6184
+4: 6185
+4: 6186
+4: 6187
+4: 6188
+5: 6189
+5: 6190
+5: 6191
+5: 6192
+5: 6193
+5: 6194
+5: 6195
+5: 6196
+5: 6197
+5: 6198
+5: 6199
+5: 6200
+5: 6201
+5: 6202
+5: 6203
+5: 6204
+5: 6205
+5: 6206
+5: 6207
+5: 6208
+5: 6209
+5: 6210
+5: 6211
+5: 6212
+5: 6213
+5: 6214
+5: 6215
+5: 6216
+5: 6217
+5: 6218
+5: 6219
+5: 6220
+5: 6221
+5: 6222
+5: 6223
+5: 6224
+5: 6225
+5: 6226
+5: 6227
+5: 6228
+5: 6229
+5: 6230
+5: 6231
+5: 6232
+5: 6233
+5: 6234
+5: 6235
+5: 6236
+5: 6237
+5: 6238
+5: 6239
+5: 6240
+5: 6241
+5: 6242
+5: 6243
+5: 6244
+5: 6245
+5: 6246
+5: 6247
+5: 6248
+5: 6249
+5: 6250
+5: 6251
+5: 6252
+5: 6253
+5: 6254
+5: 6255
+5: 6256
+5: 6257
+5: 6258
+5: 6259
+5: 6260
+5: 6261
+5: 6262
+5: 6263
+5: 6264
+5: 6265
+5: 6266
+5: 6267
+5: 6268
+5: 6269
+5: 6270
+5: 6271
+5: 6272
+5: 6273
+5: 6274
+5: 6275
+5: 6276
+5: 6277
+5: 6278
+5: 6279
+5: 6280
+5: 6281
+5: 6282
+5: 6283
+5: 6284
+5: 6285
+5: 6286
+5: 6287
+5: 6288
+5: 6289
+5: 6290
+5: 6291
+5: 6292
+5: 6293
+5: 6294
+5: 6295
+5: 6296
+5: 6297
+5: 6298
+5: 6299
+5: 6300
+5: 6301
+5: 6302
+5: 6303
+5: 6304
+5: 6305
+5: 6306
+5: 6307
+5: 6308
+5: 6309
+5: 6310
+5: 6311
+5: 6312
+5: 6313
+5: 6314
+5: 6315
+5: 6316
+5: 6317
+5: 6318
+5: 6319
+5: 6320
+5: 6321
+5: 6322
+5: 6323
+5: 6324
+5: 6325
+5: 6326
+5: 6327
+5: 6328
+5: 6329
+5: 6330
+5: 6331
+5: 6332
+5: 6333
+5: 6334
+5: 6335
+5: 6336
+5: 6337
+5: 6338
+5: 6339
+5: 6340
+5: 6341
+5: 6342
+5: 6343
+5: 6344
+5: 6345
+5: 6346
+5: 6347
+5: 6348
+5: 6349
+5: 6350
+5: 6351
+5: 6352
+5: 6353
+5: 6354
+5: 6355
+5: 6356
+5: 6357
+5: 6358
+5: 6359
+5: 6360
+5: 6361
+5: 6362
+5: 6363
+5: 6364
+5: 6365
+5: 6366
+5: 6367
+5: 6368
+5: 6369
+5: 6370
+5: 6371
+5: 6372
+5: 6373
+5: 6374
+5: 6375
+5: 6376
+5: 6377
+5: 6378
+5: 6379
+5: 6380
+5: 6381
+5: 6382
+5: 6383
+5: 6384
+5: 6385
+5: 6386
+5: 6387
+5: 6388
+5: 6389
+5: 6390
+5: 6391
+5: 6392
+5: 6393
+5: 6394
+5: 6395
+5: 6396
+5: 6397
+5: 6398
+5: 6399
+5: 6400
+5: 6401
+5: 6402
+5: 6403
+5: 6404
+5: 6405
+5: 6406
+5: 6407
+5: 6408
+5: 6409
+5: 6410
+5: 6411
+5: 6412
+5: 6413
+5: 6414
+5: 6415
+5: 6416
+5: 6417
+5: 6418
+5: 6419
+5: 6420
+5: 6421
+5: 6422
+5: 6423
+5: 6424
+5: 6425
+5: 6426
+5: 6427
+5: 6428
+5: 6429
+5: 6430
+5: 6431
+5: 6432
+5: 6433
+5: 6434
+5: 6435
+5: 6436
+5: 6437
+5: 6438
+5: 6439
+5: 6440
+5: 6441
+5: 6442
+5: 6443
+5: 6444
+5: 6445
+5: 6446
+5: 6447
+5: 6448
+5: 6449
+5: 6450
+5: 6451
+5: 6452
+5: 6453
+5: 6454
+5: 6455
+5: 6456
+5: 6457
+5: 6458
+5: 6459
+5: 6460
+5: 6461
+5: 6462
+5: 6463
+5: 6464
+5: 6465
+5: 6466
+5: 6467
+5: 6468
+5: 6469
+5: 6470
+5: 6471
+5: 6472
+5: 6473
+5: 6474
+5: 6475
+5: 6476
+5: 6477
+5: 6478
+5: 6479
+5: 6480
+5: 6481
+5: 6482
+5: 6483
+5: 6484
+5: 6485
+5: 6486
+5: 6487
+5: 6488
+5: 6489
+5: 6490
+5: 6491
+5: 6492
+5: 6493
+5: 6494
+5: 6495
+5: 6496
+5: 6497
+5: 6498
+5: 6499
+5: 6500
+5: 6501
+5: 6502
+5: 6503
+5: 6504
+5: 6505
+5: 6506
+5: 6507
+5: 6508
+5: 6509
+5: 6510
+5: 6511
+5: 6512
+5: 6513
+5: 6514
+5: 6515
+5: 6516
+5: 6517
+5: 6518
+5: 6519
+5: 6520
+5: 6521
+5: 6522
+5: 6523
+5: 6524
+5: 6525
+5: 6526
+5: 6527
+5: 6528
+5: 6529
+5: 6530
+5: 6531
+5: 6532
+5: 6533
+5: 6534
+5: 6535
+5: 6536
+5: 6537
+5: 6538
+5: 6539
+5: 6540
+5: 6541
+5: 6542
+5: 6543
+5: 6544
+5: 6545
+5: 6546
+5: 6547
+5: 6548
+5: 6549
+5: 6550
+5: 6551
+5: 6552
+5: 6553
+5: 6554
+5: 6555
+5: 6556
+5: 6557
+5: 6558
+5: 6559
+5: 6560
+5: 6561
+5: 6562
+5: 6563
+5: 6564
+5: 6565
+5: 6566
+4: 6567
+4: 6568
+4: 6569
+4: 6570
+4: 6571
+4: 6572
+4: 6573
+4: 6574
+4: 6575
+4: 6576
+4: 6577
+4: 6578
+4: 6579
+4: 6580
+4: 6581
+4: 6582
+4: 6583
+4: 6584
+4: 6585
+4: 6586
+4: 6587
+4: 6588
+4: 6589
+4: 6590
+4: 6591
+4: 6592
+4: 6593
+4: 6594
+4: 6595
+4: 6596
+4: 6597
+4: 6598
+4: 6599
+4: 6600
+4: 6601
+4: 6602
+4: 6603
+4: 6604
+4: 6605
+4: 6606
+4: 6607
+4: 6608
+4: 6609
+4: 6610
+4: 6611
+4: 6612
+4: 6613
+4: 6614
+4: 6615
+4: 6616
+4: 6617
+4: 6618
+4: 6619
+4: 6620
+4: 6621
+4: 6622
+4: 6623
+4: 6624
+4: 6625
+4: 6626
+4: 6627
+4: 6628
+4: 6629
+4: 6630
+4: 6631
+4: 6632
+4: 6633
+4: 6634
+4: 6635
+4: 6636
+4: 6637
+4: 6638
+4: 6639
+4: 6640
+4: 6641
+4: 6642
+4: 6643
+4: 6644
+4: 6645
+4: 6646
+4: 6647
+4: 6648
+4: 6649
+4: 6650
+4: 6651
+4: 6652
+4: 6653
+4: 6654
+4: 6655
+4: 6656
+4: 6657
+4: 6658
+4: 6659
+4: 6660
+4: 6661
+4: 6662
+4: 6663
+4: 6664
+4: 6665
+4: 6666
+4: 6667
+4: 6668
+4: 6669
+4: 6670
+4: 6671
+4: 6672
+4: 6673
+4: 6674
+4: 6675
+4: 6676
+4: 6677
+4: 6678
+4: 6679
+4: 6680
+4: 6681
+4: 6682
+4: 6683
+4: 6684
+4: 6685
+4: 6686
+4: 6687
+4: 6688
+4: 6689
+4: 6690
+4: 6691
+4: 6692
+4: 6693
+4: 6694
+4: 6695
+4: 6696
+4: 6697
+4: 6698
+4: 6699
+4: 6700
+4: 6701
+4: 6702
+4: 6703
+4: 6704
+4: 6705
+4: 6706
+4: 6707
+4: 6708
+4: 6709
+4: 6710
+4: 6711
+4: 6712
+4: 6713
+4: 6714
+4: 6715
+4: 6716
+4: 6717
+4: 6718
+4: 6719
+4: 6720
+4: 6721
+4: 6722
+4: 6723
+4: 6724
+4: 6725
+4: 6726
+4: 6727
+4: 6728
+4: 6729
+4: 6730
+4: 6731
+4: 6732
+4: 6733
+4: 6734
+4: 6735
+4: 6736
+4: 6737
+4: 6738
+4: 6739
+4: 6740
+4: 6741
+4: 6742
+4: 6743
+4: 6744
+4: 6745
+4: 6746
+4: 6747
+4: 6748
+4: 6749
+4: 6750
+4: 6751
+4: 6752
+4: 6753
+4: 6754
+4: 6755
+4: 6756
+4: 6757
+4: 6758
+4: 6759
+4: 6760
+4: 6761
+4: 6762
+4: 6763
+4: 6764
+4: 6765
+4: 6766
+4: 6767
+4: 6768
+4: 6769
+4: 6770
+4: 6771
+4: 6772
+4: 6773
+4: 6774
+4: 6775
+4: 6776
+4: 6777
+4: 6778
+4: 6779
+4: 6780
+4: 6781
+4: 6782
+4: 6783
+4: 6784
+4: 6785
+4: 6786
+4: 6787
+4: 6788
+4: 6789
+4: 6790
+4: 6791
+4: 6792
+4: 6793
+4: 6794
+4: 6795
+4: 6796
+4: 6797
+4: 6798
+4: 6799
+4: 6800
+4: 6801
+4: 6802
+4: 6803
+4: 6804
+4: 6805
+4: 6806
+4: 6807
+4: 6808
+4: 6809
+4: 6810
+4: 6811
+4: 6812
+4: 6813
+4: 6814
+4: 6815
+4: 6816
+4: 6817
+4: 6818
+4: 6819
+4: 6820
+4: 6821
+4: 6822
+4: 6823
+4: 6824
+4: 6825
+4: 6826
+4: 6827
+4: 6828
+4: 6829
+4: 6830
+4: 6831
+4: 6832
+4: 6833
+4: 6834
+4: 6835
+4: 6836
+4: 6837
+4: 6838
+4: 6839
+4: 6840
+4: 6841
+4: 6842
+4: 6843
+4: 6844
+4: 6845
+4: 6846
+4: 6847
+4: 6848
+4: 6849
+4: 6850
+4: 6851
+4: 6852
+4: 6853
+4: 6854
+4: 6855
+4: 6856
+4: 6857
+4: 6858
+4: 6859
+4: 6860
+4: 6861
+4: 6862
+4: 6863
+4: 6864
+4: 6865
+4: 6866
+4: 6867
+4: 6868
+4: 6869
+4: 6870
+4: 6871
+4: 6872
+4: 6873
+4: 6874
+4: 6875
+4: 6876
+4: 6877
+4: 6878
+4: 6879
+4: 6880
+4: 6881
+4: 6882
+4: 6883
+4: 6884
+4: 6885
+4: 6886
+4: 6887
+4: 6888
+4: 6889
+4: 6890
+4: 6891
+4: 6892
+4: 6893
+4: 6894
+4: 6895
+4: 6896
+4: 6897
+4: 6898
+4: 6899
+4: 6900
+4: 6901
+4: 6902
+4: 6903
+4: 6904
+4: 6905
+4: 6906
+4: 6907
+4: 6908
+4: 6909
+4: 6910
+4: 6911
+4: 6912
+4: 6913
+4: 6914
+4: 6915
+4: 6916
+4: 6917
+4: 6918
+4: 6919
+4: 6920
+4: 6921
+4: 6922
+4: 6923
+4: 6924
+4: 6925
+4: 6926
+4: 6927
+4: 6928
+4: 6929
+4: 6930
+4: 6931
+4: 6932
+4: 6933
+4: 6934
+4: 6935
+4: 6936
+4: 6937
+4: 6938
+4: 6939
+4: 6940
+4: 6941
+4: 6942
+4: 6943
+4: 6944
+4: 6945
+4: 6946
+4: 6947
+4: 6948
+4: 6949
+4: 6950
+4: 6951
+4: 6952
+4: 6953
+4: 6954
+4: 6955
+4: 6956
+4: 6957
+4: 6958
+4: 6959
+4: 6960
+4: 6961
+4: 6962
+4: 6963
+4: 6964
+4: 6965
+4: 6966
+4: 6967
+4: 6968
+4: 6969
+4: 6970
+4: 6971
+4: 6972
+4: 6973
+4: 6974
+4: 6975
+4: 6976
+4: 6977
+4: 6978
+4: 6979
+4: 6980
+4: 6981
+4: 6982
+4: 6983
+4: 6984
+4: 6985
+4: 6986
+4: 6987
+4: 6988
+4: 6989
+4: 6990
+4: 6991
+4: 6992
+4: 6993
+4: 6994
+4: 6995
+4: 6996
+4: 6997
+4: 6998
+4: 6999
+4: 7000
+4: 7001
+4: 7002
+4: 7003
+4: 7004
+4: 7005
+4: 7006
+4: 7007
+4: 7008
+4: 7009
+4: 7010
+4: 7011
+4: 7012
+4: 7013
+4: 7014
+4: 7015
+4: 7016
+4: 7017
+4: 7018
+4: 7019
+4: 7020
+4: 7021
+4: 7022
+4: 7023
+4: 7024
+4: 7025
+4: 7026
+4: 7027
+4: 7028
+4: 7029
+4: 7030
+4: 7031
+4: 7032
+4: 7033
+4: 7034
+4: 7035
+4: 7036
+4: 7037
+4: 7038
+4: 7039
+4: 7040
+4: 7041
+4: 7042
+4: 7043
+4: 7044
+4: 7045
+4: 7046
+4: 7047
+4: 7048
+4: 7049
+4: 7050
+4: 7051
+4: 7052
+4: 7053
+4: 7054
+4: 7055
+4: 7056
+4: 7057
+4: 7058
+4: 7059
+4: 7060
+4: 7061
+4: 7062
+4: 7063
+4: 7064
+4: 7065
+4: 7066
+4: 7067
+4: 7068
+4: 7069
+4: 7070
+4: 7071
+4: 7072
+4: 7073
+4: 7074
+4: 7075
+4: 7076
+4: 7077
+4: 7078
+4: 7079
+4: 7080
+4: 7081
+4: 7082
+4: 7083
+4: 7084
+4: 7085
+4: 7086
+4: 7087
+5: 7088
+5: 7089
+5: 7090
+5: 7091
+5: 7092
+5: 7093
+5: 7094
+5: 7095
+5: 7096
+5: 7097
+5: 7098
+5: 7099
+5: 7100
+5: 7101
+5: 7102
+5: 7103
+5: 7104
+5: 7105
+5: 7106
+5: 7107
+5: 7108
+5: 7109
+5: 7110
+5: 7111
+5: 7112
+5: 7113
+5: 7114
+5: 7115
+5: 7116
+5: 7117
+5: 7118
+5: 7119
+5: 7120
+5: 7121
+5: 7122
+5: 7123
+5: 7124
+5: 7125
+5: 7126
+5: 7127
+5: 7128
+5: 7129
+5: 7130
+5: 7131
+5: 7132
+5: 7133
+5: 7134
+5: 7135
+5: 7136
+5: 7137
+5: 7138
+5: 7139
+5: 7140
+5: 7141
+5: 7142
+5: 7143
+5: 7144
+5: 7145
+5: 7146
+5: 7147
+5: 7148
+5: 7149
+5: 7150
+5: 7151
+5: 7152
+5: 7153
+5: 7154
+5: 7155
+5: 7156
+5: 7157
+5: 7158
+5: 7159
+5: 7160
+5: 7161
+5: 7162
+5: 7163
+5: 7164
+5: 7165
+5: 7166
+5: 7167
+5: 7168
+5: 7169
+5: 7170
+5: 7171
+5: 7172
+5: 7173
+5: 7174
+5: 7175
+5: 7176
+5: 7177
+5: 7178
+5: 7179
+5: 7180
+5: 7181
+5: 7182
+5: 7183
+5: 7184
+5: 7185
+5: 7186
+5: 7187
+5: 7188
+5: 7189
+5: 7190
+5: 7191
+5: 7192
+5: 7193
+5: 7194
+5: 7195
+5: 7196
+5: 7197
+5: 7198
+5: 7199
+5: 7200
+5: 7201
+5: 7202
+5: 7203
+5: 7204
+5: 7205
+5: 7206
+5: 7207
+5: 7208
+5: 7209
+5: 7210
+5: 7211
+5: 7212
+5: 7213
+5: 7214
+5: 7215
+5: 7216
+5: 7217
+5: 7218
+5: 7219
+5: 7220
+5: 7221
+5: 7222
+5: 7223
+5: 7224
+5: 7225
+5: 7226
+5: 7227
+5: 7228
+5: 7229
+5: 7230
+5: 7231
+5: 7232
+5: 7233
+5: 7234
+5: 7235
+5: 7236
+5: 7237
+5: 7238
+5: 7239
+5: 7240
+5: 7241
+5: 7242
+5: 7243
+5: 7244
+5: 7245
+5: 7246
+5: 7247
+5: 7248
+5: 7249
+5: 7250
+5: 7251
+5: 7252
+5: 7253
+5: 7254
+5: 7255
+5: 7256
+5: 7257
+5: 7258
+5: 7259
+5: 7260
+5: 7261
+5: 7262
+5: 7263
+5: 7264
+5: 7265
+5: 7266
+5: 7267
+5: 7268
+5: 7269
+5: 7270
+5: 7271
+5: 7272
+5: 7273
+5: 7274
+5: 7275
+5: 7276
+5: 7277
+5: 7278
+5: 7279
+5: 7280
+5: 7281
+5: 7282
+5: 7283
+5: 7284
+5: 7285
+5: 7286
+5: 7287
+5: 7288
+5: 7289
+5: 7290
+5: 7291
+5: 7292
+5: 7293
+5: 7294
+5: 7295
+5: 7296
+5: 7297
+5: 7298
+5: 7299
+5: 7300
+5: 7301
+5: 7302
+5: 7303
+5: 7304
+5: 7305
+5: 7306
+5: 7307
+5: 7308
+5: 7309
+5: 7310
+5: 7311
+5: 7312
+5: 7313
+5: 7314
+5: 7315
+5: 7316
+5: 7317
+5: 7318
+5: 7319
+5: 7320
+5: 7321
+5: 7322
+5: 7323
+5: 7324
+5: 7325
+5: 7326
+5: 7327
+5: 7328
+5: 7329
+5: 7330
+5: 7331
+5: 7332
+5: 7333
+5: 7334
+5: 7335
+5: 7336
+5: 7337
+5: 7338
+5: 7339
+5: 7340
+5: 7341
+5: 7342
+5: 7343
+5: 7344
+5: 7345
+5: 7346
+5: 7347
+5: 7348
+5: 7349
+5: 7350
+5: 7351
+5: 7352
+5: 7353
+5: 7354
+5: 7355
+5: 7356
+5: 7357
+5: 7358
+5: 7359
+5: 7360
+5: 7361
+5: 7362
+5: 7363
+5: 7364
+5: 7365
+5: 7366
+5: 7367
+5: 7368
+5: 7369
+5: 7370
+5: 7371
+5: 7372
+5: 7373
+5: 7374
+5: 7375
+5: 7376
+5: 7377
+5: 7378
+5: 7379
+5: 7380
+5: 7381
+5: 7382
+5: 7383
+5: 7384
+5: 7385
+5: 7386
+5: 7387
+5: 7388
+5: 7389
+5: 7390
+5: 7391
+5: 7392
+5: 7393
+5: 7394
+5: 7395
+5: 7396
+5: 7397
+5: 7398
+5: 7399
+5: 7400
+5: 7401
+5: 7402
+5: 7403
+5: 7404
+5: 7405
+5: 7406
+5: 7407
+5: 7408
+5: 7409
+5: 7410
+5: 7411
+5: 7412
+5: 7413
+5: 7414
+5: 7415
+5: 7416
+5: 7417
+5: 7418
+5: 7419
+5: 7420
+5: 7421
+5: 7422
+5: 7423
+5: 7424
+5: 7425
+5: 7426
+5: 7427
+5: 7428
+5: 7429
+5: 7430
+5: 7431
+5: 7432
+5: 7433
+5: 7434
+5: 7435
+5: 7436
+5: 7437
+5: 7438
+5: 7439
+5: 7440
+5: 7441
+5: 7442
+5: 7443
+5: 7444
+5: 7445
+5: 7446
+5: 7447
+5: 7448
+5: 7449
+5: 7450
+5: 7451
+5: 7452
+5: 7453
+5: 7454
+5: 7455
+5: 7456
+5: 7457
+5: 7458
+5: 7459
+5: 7460
+5: 7461
+5: 7462
+5: 7463
+5: 7464
+5: 7465
+5: 7466
+5: 7467
+5: 7468
+5: 7469
+5: 7470
+5: 7471
+5: 7472
+5: 7473
+5: 7474
+5: 7475
+5: 7476
+5: 7477
+5: 7478
+5: 7479
+5: 7480
+5: 7481
+5: 7482
+5: 7483
+5: 7484
+5: 7485
+5: 7486
+5: 7487
+5: 7488
+5: 7489
+5: 7490
+5: 7491
+5: 7492
+5: 7493
+5: 7494
+5: 7495
+5: 7496
+5: 7497
+5: 7498
+5: 7499
+5: 7500
+5: 7501
+5: 7502
+5: 7503
+5: 7504
+5: 7505
+5: 7506
+5: 7507
+5: 7508
+5: 7509
+5: 7510
+5: 7511
+5: 7512
+5: 7513
+5: 7514
+5: 7515
+5: 7516
+5: 7517
+5: 7518
+5: 7519
+5: 7520
+5: 7521
+5: 7522
+5: 7523
+5: 7524
+5: 7525
+5: 7526
+5: 7527
+5: 7528
+5: 7529
+5: 7530
+5: 7531
+5: 7532
+5: 7533
+5: 7534
+5: 7535
+5: 7536
+5: 7537
+5: 7538
+5: 7539
+5: 7540
+5: 7541
+5: 7542
+5: 7543
+5: 7544
+5: 7545
+5: 7546
+5: 7547
+5: 7548
+5: 7549
+5: 7550
+5: 7551
+5: 7552
+5: 7553
+5: 7554
+5: 7555
+5: 7556
+5: 7557
+5: 7558
+5: 7559
+5: 7560
+5: 7561
+5: 7562
+5: 7563
+5: 7564
+5: 7565
+5: 7566
+5: 7567
+5: 7568
+5: 7569
+5: 7570
+5: 7571
+5: 7572
+5: 7573
+5: 7574
+5: 7575
+5: 7576
+5: 7577
+5: 7578
+5: 7579
+5: 7580
+5: 7581
+5: 7582
+5: 7583
+5: 7584
+5: 7585
+5: 7586
+5: 7587
+5: 7588
+5: 7589
+5: 7590
+5: 7591
+5: 7592
+5: 7593
+5: 7594
+5: 7595
+5: 7596
+5: 7597
+5: 7598
+5: 7599
+5: 7600
+5: 7601
+5: 7602
+5: 7603
+5: 7604
+5: 7605
+5: 7606
+5: 7607
+5: 7608
+5: 7609
+5: 7610
+5: 7611
+5: 7612
+5: 7613
+5: 7614
+5: 7615
+5: 7616
+5: 7617
+5: 7618
+5: 7619
+5: 7620
+5: 7621
+5: 7622
+5: 7623
+5: 7624
+5: 7625
+5: 7626
+5: 7627
+5: 7628
+5: 7629
+5: 7630
+5: 7631
+5: 7632
+5: 7633
+5: 7634
+5: 7635
+5: 7636
+5: 7637
+5: 7638
+5: 7639
+5: 7640
+5: 7641
+5: 7642
+5: 7643
+5: 7644
+5: 7645
+5: 7646
+5: 7647
+5: 7648
+5: 7649
+5: 7650
+5: 7651
+5: 7652
+5: 7653
+5: 7654
+5: 7655
+5: 7656
+5: 7657
+5: 7658
+5: 7659
+5: 7660
+5: 7661
+5: 7662
+5: 7663
+5: 7664
+5: 7665
+5: 7666
+5: 7667
+5: 7668
+5: 7669
+5: 7670
+5: 7671
+5: 7672
+5: 7673
+5: 7674
+5: 7675
+5: 7676
+5: 7677
+5: 7678
+5: 7679
+5: 7680
+5: 7681
+5: 7682
+5: 7683
+5: 7684
+5: 7685
+5: 7686
+5: 7687
+5: 7688
+5: 7689
+5: 7690
+5: 7691
+5: 7692
+5: 7693
+5: 7694
+5: 7695
+5: 7696
+5: 7697
+5: 7698
+5: 7699
+5: 7700
+5: 7701
+5: 7702
+5: 7703
+5: 7704
+5: 7705
+5: 7706
+5: 7707
+5: 7708
+5: 7709
+5: 7710
+5: 7711
+5: 7712
+5: 7713
+5: 7714
+5: 7715
+5: 7716
+5: 7717
+5: 7718
+5: 7719
+5: 7720
+5: 7721
+5: 7722
+5: 7723
+5: 7724
+5: 7725
+5: 7726
+5: 7727
+5: 7728
+5: 7729
+5: 7730
+5: 7731
+5: 7732
+5: 7733
+5: 7734
+5: 7735
+5: 7736
+5: 7737
+5: 7738
+5: 7739
+5: 7740
+5: 7741
+5: 7742
+5: 7743
+5: 7744
+5: 7745
+5: 7746
+5: 7747
+5: 7748
+5: 7749
+5: 7750
+5: 7751
+5: 7752
+5: 7753
+5: 7754
+5: 7755
+5: 7756
+5: 7757
+5: 7758
+5: 7759
+5: 7760
+5: 7761
+5: 7762
+5: 7763
+5: 7764
+5: 7765
+5: 7766
+5: 7767
+5: 7768
+5: 7769
+5: 7770
+5: 7771
+5: 7772
+5: 7773
+5: 7774
+5: 7775
+5: 7776
+5: 7777
+5: 7778
+5: 7779
+5: 7780
+5: 7781
+5: 7782
+5: 7783
+5: 7784
+5: 7785
+5: 7786
+5: 7787
+5: 7788
+5: 7789
+5: 7790
+5: 7791
+5: 7792
+5: 7793
+5: 7794
+5: 7795
+5: 7796
+5: 7797
+5: 7798
+5: 7799
+5: 7800
+5: 7801
+5: 7802
+5: 7803
+5: 7804
+5: 7805
+5: 7806
+5: 7807
+5: 7808
+5: 7809
+5: 7810
+5: 7811
+5: 7812
+5: 7813
+5: 7814
+5: 7815
+5: 7816
+5: 7817
+5: 7818
+5: 7819
+4: 7820
+4: 7821
+4: 7822
+4: 7823
+4: 7824
+4: 7825
+4: 7826
+4: 7827
+4: 7828
+4: 7829
+4: 7830
+4: 7831
+4: 7832
+4: 7833
+4: 7834
+4: 7835
+4: 7836
+4: 7837
+4: 7838
+4: 7839
+4: 7840
+4: 7841
+4: 7842
+4: 7843
+4: 7844
+4: 7845
+4: 7846
+4: 7847
+4: 7848
+4: 7849
+4: 7850
+4: 7851
+4: 7852
+4: 7853
+4: 7854
+4: 7855
+4: 7856
+4: 7857
+4: 7858
+4: 7859
+4: 7860
+4: 7861
+4: 7862
+4: 7863
+4: 7864
+4: 7865
+4: 7866
+4: 7867
+4: 7868
+4: 7869
+4: 7870
+4: 7871
+4: 7872
+4: 7873
+4: 7874
+4: 7875
+4: 7876
+4: 7877
+4: 7878
+4: 7879
+4: 7880
+4: 7881
+4: 7882
+4: 7883
+4: 7884
+4: 7885
+4: 7886
+4: 7887
+4: 7888
+4: 7889
+4: 7890
+4: 7891
+4: 7892
+4: 7893
+4: 7894
+4: 7895
+4: 7896
+4: 7897
+4: 7898
+4: 7899
+4: 7900
+4: 7901
+4: 7902
+4: 7903
+4: 7904
+4: 7905
+4: 7906
+4: 7907
+4: 7908
+4: 7909
+4: 7910
+4: 7911
+4: 7912
+4: 7913
+4: 7914
+4: 7915
+4: 7916
+4: 7917
+4: 7918
+4: 7919
+4: 7920
+4: 7921
+4: 7922
+4: 7923
+4: 7924
+4: 7925
+4: 7926
+4: 7927
+4: 7928
+4: 7929
+4: 7930
+4: 7931
+4: 7932
+4: 7933
+4: 7934
+4: 7935
+4: 7936
+4: 7937
+4: 7938
+4: 7939
+4: 7940
+4: 7941
+4: 7942
+4: 7943
+4: 7944
+4: 7945
+4: 7946
+4: 7947
+4: 7948
+4: 7949
+4: 7950
+4: 7951
+4: 7952
+4: 7953
+4: 7954
+4: 7955
+4: 7956
+4: 7957
+4: 7958
+4: 7959
+4: 7960
+4: 7961
+4: 7962
+4: 7963
+4: 7964
+4: 7965
+4: 7966
+4: 7967
+4: 7968
+4: 7969
+4: 7970
+4: 7971
+4: 7972
+4: 7973
+4: 7974
+4: 7975
+4: 7976
+4: 7977
+4: 7978
+4: 7979
+4: 7980
+4: 7981
+4: 7982
+4: 7983
+4: 7984
+4: 7985
+4: 7986
+4: 7987
+4: 7988
+4: 7989
+4: 7990
+4: 7991
+4: 7992
+4: 7993
+4: 7994
+4: 7995
+4: 7996
+4: 7997
+4: 7998
+4: 7999
+4: 8000
+4: 8001
+4: 8002
+4: 8003
+4: 8004
+4: 8005
+4: 8006
+4: 8007
+4: 8008
+4: 8009
+4: 8010
+4: 8011
+4: 8012
+4: 8013
+4: 8014
+4: 8015
+4: 8016
+4: 8017
+4: 8018
+4: 8019
+4: 8020
+4: 8021
+4: 8022
+4: 8023
+4: 8024
+4: 8025
+4: 8026
+4: 8027
+4: 8028
+4: 8029
+4: 8030
+4: 8031
+4: 8032
+4: 8033
+4: 8034
+4: 8035
+4: 8036
+4: 8037
+4: 8038
+4: 8039
+4: 8040
+4: 8041
+4: 8042
+4: 8043
+4: 8044
+4: 8045
+4: 8046
+4: 8047
+4: 8048
+4: 8049
+4: 8050
+4: 8051
+4: 8052
+4: 8053
+4: 8054
+4: 8055
+4: 8056
+4: 8057
+4: 8058
+4: 8059
+4: 8060
+4: 8061
+4: 8062
+4: 8063
+4: 8064
+4: 8065
+4: 8066
+4: 8067
+4: 8068
+4: 8069
+5: 8070
+5: 8071
+5: 8072
+5: 8073
+5: 8074
+5: 8075
+5: 8076
+5: 8077
+5: 8078
+5: 8079
+5: 8080
+5: 8081
+5: 8082
+5: 8083
+5: 8084
+5: 8085
+5: 8086
+5: 8087
+5: 8088
+5: 8089
+5: 8090
+5: 8091
+5: 8092
+5: 8093
+5: 8094
+5: 8095
+5: 8096
+5: 8097
+5: 8098
+5: 8099
+5: 8100
+5: 8101
+5: 8102
+5: 8103
+5: 8104
+5: 8105
+5: 8106
+5: 8107
+5: 8108
+5: 8109
+5: 8110
+5: 8111
+5: 8112
+5: 8113
+5: 8114
+5: 8115
+5: 8116
+5: 8117
+5: 8118
+5: 8119
+5: 8120
+5: 8121
+5: 8122
+5: 8123
+5: 8124
+5: 8125
+5: 8126
+5: 8127
+5: 8128
+5: 8129
+5: 8130
+5: 8131
+5: 8132
+5: 8133
+5: 8134
+5: 8135
+5: 8136
+5: 8137
+5: 8138
+5: 8139
+5: 8140
+5: 8141
+5: 8142
+5: 8143
+5: 8144
+5: 8145
+5: 8146
+5: 8147
+5: 8148
+5: 8149
+5: 8150
+5: 8151
+5: 8152
+5: 8153
+5: 8154
+5: 8155
+5: 8156
+5: 8157
+5: 8158
+5: 8159
+5: 8160
+5: 8161
+5: 8162
+5: 8163
+5: 8164
+5: 8165
+5: 8166
+5: 8167
+5: 8168
+5: 8169
+5: 8170
+5: 8171
+5: 8172
+5: 8173
+5: 8174
+5: 8175
+5: 8176
+5: 8177
+5: 8178
+5: 8179
+5: 8180
+5: 8181
+5: 8182
+5: 8183
+5: 8184
+5: 8185
+5: 8186
+5: 8187
+5: 8188
+5: 8189
+5: 8190
+5: 8191
+5: 8192
+5: 8193
+5: 8194
+5: 8195
+5: 8196
+5: 8197
+5: 8198
+5: 8199
+5: 8200
+5: 8201
+5: 8202
+5: 8203
+5: 8204
+5: 8205
+5: 8206
+5: 8207
+5: 8208
+5: 8209
+5: 8210
+5: 8211
+5: 8212
+5: 8213
+5: 8214
+5: 8215
+5: 8216
+5: 8217
+5: 8218
+5: 8219
+5: 8220
+5: 8221
+5: 8222
+5: 8223
+5: 8224
+5: 8225
+5: 8226
+5: 8227
+5: 8228
+5: 8229
+5: 8230
+5: 8231
+5: 8232
+5: 8233
+5: 8234
+5: 8235
+5: 8236
+5: 8237
+5: 8238
+5: 8239
+5: 8240
+5: 8241
+5: 8242
+5: 8243
+5: 8244
+5: 8245
+5: 8246
+5: 8247
+5: 8248
+5: 8249
+5: 8250
+5: 8251
+5: 8252
+5: 8253
+5: 8254
+5: 8255
+5: 8256
+5: 8257
+5: 8258
+5: 8259
+5: 8260
+5: 8261
+5: 8262
+5: 8263
+5: 8264
+5: 8265
+5: 8266
+5: 8267
+5: 8268
+5: 8269
+5: 8270
+5: 8271
+5: 8272
+5: 8273
+5: 8274
+5: 8275
+5: 8276
+5: 8277
+5: 8278
+5: 8279
+5: 8280
+5: 8281
+5: 8282
+5: 8283
+5: 8284
+5: 8285
+5: 8286
+5: 8287
+5: 8288
+5: 8289
+5: 8290
+5: 8291
+5: 8292
+5: 8293
+5: 8294
+5: 8295
+5: 8296
+5: 8297
+5: 8298
+5: 8299
+5: 8300
+5: 8301
+5: 8302
+5: 8303
+5: 8304
+5: 8305
+5: 8306
+5: 8307
+5: 8308
+5: 8309
+5: 8310
+5: 8311
+5: 8312
+5: 8313
+5: 8314
+5: 8315
+5: 8316
+5: 8317
+5: 8318
+5: 8319
+5: 8320
+5: 8321
+5: 8322
+5: 8323
+5: 8324
+5: 8325
+5: 8326
+5: 8327
+5: 8328
+5: 8329
+5: 8330
+5: 8331
+5: 8332
+5: 8333
+5: 8334
+5: 8335
+5: 8336
+5: 8337
+5: 8338
+5: 8339
+5: 8340
+5: 8341
+5: 8342
+5: 8343
+5: 8344
+5: 8345
+5: 8346
+5: 8347
+5: 8348
+5: 8349
+5: 8350
+5: 8351
+5: 8352
+5: 8353
+5: 8354
+5: 8355
+5: 8356
+5: 8357
+5: 8358
+5: 8359
+5: 8360
+5: 8361
+5: 8362
+5: 8363
+5: 8364
+5: 8365
+5: 8366
+5: 8367
+5: 8368
+5: 8369
+5: 8370
+5: 8371
+5: 8372
+5: 8373
+5: 8374
+5: 8375
+5: 8376
+5: 8377
+5: 8378
+5: 8379
+5: 8380
+5: 8381
+5: 8382
+5: 8383
+5: 8384
+5: 8385
+5: 8386
+5: 8387
+5: 8388
+5: 8389
+5: 8390
+5: 8391
+5: 8392
+5: 8393
+5: 8394
+5: 8395
+5: 8396
+5: 8397
+5: 8398
+5: 8399
+5: 8400
+5: 8401
+5: 8402
+5: 8403
+5: 8404
+5: 8405
+5: 8406
+5: 8407
+5: 8408
+5: 8409
+5: 8410
+5: 8411
+5: 8412
+5: 8413
+5: 8414
+5: 8415
+5: 8416
+5: 8417
+5: 8418
+5: 8419
+5: 8420
+5: 8421
+5: 8422
+5: 8423
+5: 8424
+5: 8425
+5: 8426
+5: 8427
+5: 8428
+5: 8429
+5: 8430
+5: 8431
+5: 8432
+5: 8433
+5: 8434
+5: 8435
+5: 8436
+5: 8437
+5: 8438
+5: 8439
+5: 8440
+5: 8441
+5: 8442
+5: 8443
+5: 8444
+5: 8445
+5: 8446
+5: 8447
+5: 8448
+5: 8449
+5: 8450
+5: 8451
+5: 8452
+5: 8453
+5: 8454
+5: 8455
+5: 8456
+5: 8457
+5: 8458
+5: 8459
+5: 8460
+5: 8461
+5: 8462
+5: 8463
+5: 8464
+5: 8465
+5: 8466
+5: 8467
+5: 8468
+5: 8469
+5: 8470
+5: 8471
+5: 8472
+5: 8473
+5: 8474
+5: 8475
+5: 8476
+5: 8477
+5: 8478
+5: 8479
+5: 8480
+5: 8481
+5: 8482
+5: 8483
+5: 8484
+5: 8485
+5: 8486
+5: 8487
+5: 8488
+5: 8489
+5: 8490
+5: 8491
+5: 8492
+5: 8493
+5: 8494
+5: 8495
+5: 8496
+5: 8497
+5: 8498
+5: 8499
+5: 8500
+5: 8501
+5: 8502
+5: 8503
+5: 8504
+5: 8505
+5: 8506
+5: 8507
+5: 8508
+5: 8509
+5: 8510
+5: 8511
+5: 8512
+5: 8513
+5: 8514
+5: 8515
+5: 8516
+5: 8517
+5: 8518
+5: 8519
+5: 8520
+5: 8521
+5: 8522
+5: 8523
+5: 8524
+5: 8525
+5: 8526
+5: 8527
+5: 8528
+5: 8529
+5: 8530
+5: 8531
+5: 8532
+5: 8533
+5: 8534
+5: 8535
+5: 8536
+5: 8537
+5: 8538
+5: 8539
+5: 8540
+5: 8541
+5: 8542
+5: 8543
+5: 8544
+5: 8545
+5: 8546
+5: 8547
+5: 8548
+5: 8549
+5: 8550
+5: 8551
+5: 8552
+5: 8553
+5: 8554
+5: 8555
+5: 8556
+5: 8557
+5: 8558
+5: 8559
+5: 8560
+5: 8561
+5: 8562
+5: 8563
+5: 8564
+5: 8565
+5: 8566
+5: 8567
+5: 8568
+5: 8569
+5: 8570
+4: 8571
+4: 8572
+4: 8573
+4: 8574
+4: 8575
+4: 8576
+4: 8577
+4: 8578
+4: 8579
+4: 8580
+4: 8581
+4: 8582
+4: 8583
+4: 8584
+4: 8585
+4: 8586
+4: 8587
+4: 8588
+4: 8589
+4: 8590
+4: 8591
+4: 8592
+4: 8593
+4: 8594
+4: 8595
+4: 8596
+4: 8597
+4: 8598
+4: 8599
+4: 8600
+4: 8601
+4: 8602
+4: 8603
+4: 8604
+4: 8605
+4: 8606
+4: 8607
+4: 8608
+4: 8609
+4: 8610
+4: 8611
+4: 8612
+4: 8613
+4: 8614
+4: 8615
+4: 8616
+4: 8617
+4: 8618
+4: 8619
+4: 8620
+4: 8621
+4: 8622
+4: 8623
+4: 8624
+4: 8625
+4: 8626
+4: 8627
+4: 8628
+4: 8629
+4: 8630
+4: 8631
+4: 8632
+4: 8633
+4: 8634
+4: 8635
+4: 8636
+4: 8637
+4: 8638
+4: 8639
+4: 8640
+4: 8641
+4: 8642
+4: 8643
+4: 8644
+4: 8645
+4: 8646
+4: 8647
+4: 8648
+4: 8649
+4: 8650
+4: 8651
+4: 8652
+4: 8653
+4: 8654
+4: 8655
+4: 8656
+4: 8657
+4: 8658
+4: 8659
+4: 8660
+4: 8661
+4: 8662
+4: 8663
+4: 8664
+4: 8665
+4: 8666
+4: 8667
+4: 8668
+4: 8669
+4: 8670
+4: 8671
+4: 8672
+4: 8673
+4: 8674
+4: 8675
+4: 8676
+4: 8677
+4: 8678
+4: 8679
+4: 8680
+4: 8681
+4: 8682
+4: 8683
+4: 8684
+4: 8685
+4: 8686
+4: 8687
+4: 8688
+4: 8689
+4: 8690
+4: 8691
+4: 8692
+4: 8693
+4: 8694
+4: 8695
+4: 8696
+4: 8697
+4: 8698
+4: 8699
+4: 8700
+4: 8701
+4: 8702
+4: 8703
+4: 8704
+4: 8705
+4: 8706
+4: 8707
+4: 8708
+4: 8709
+4: 8710
+4: 8711
+4: 8712
+4: 8713
+4: 8714
+4: 8715
+4: 8716
+4: 8717
+4: 8718
+4: 8719
+4: 8720
+4: 8721
+4: 8722
+4: 8723
+4: 8724
+4: 8725
+4: 8726
+4: 8727
+4: 8728
+4: 8729
+4: 8730
+4: 8731
+4: 8732
+4: 8733
+4: 8734
+4: 8735
+4: 8736
+4: 8737
+4: 8738
+4: 8739
+4: 8740
+4: 8741
+4: 8742
+4: 8743
+4: 8744
+4: 8745
+4: 8746
+4: 8747
+4: 8748
+4: 8749
+4: 8750
+4: 8751
+4: 8752
+4: 8753
+4: 8754
+4: 8755
+4: 8756
+4: 8757
+4: 8758
+4: 8759
+4: 8760
+4: 8761
+4: 8762
+4: 8763
+4: 8764
+4: 8765
+4: 8766
+4: 8767
+4: 8768
+4: 8769
+4: 8770
+4: 8771
+4: 8772
+4: 8773
+4: 8774
+4: 8775
+4: 8776
+4: 8777
+4: 8778
+4: 8779
+4: 8780
+4: 8781
+4: 8782
+4: 8783
+4: 8784
+4: 8785
+4: 8786
+4: 8787
+4: 8788
+4: 8789
+4: 8790
+4: 8791
+4: 8792
+4: 8793
+4: 8794
+4: 8795
+4: 8796
+4: 8797
+4: 8798
+4: 8799
+4: 8800
+4: 8801
+4: 8802
+4: 8803
+4: 8804
+4: 8805
+4: 8806
+4: 8807
+4: 8808
+4: 8809
+4: 8810
+4: 8811
+4: 8812
+4: 8813
+4: 8814
+4: 8815
+4: 8816
+4: 8817
+4: 8818
+4: 8819
+4: 8820
+4: 8821
+4: 8822
+4: 8823
+4: 8824
+4: 8825
+4: 8826
+4: 8827
+4: 8828
+4: 8829
+4: 8830
+4: 8831
+4: 8832
+4: 8833
+4: 8834
+4: 8835
+4: 8836
+4: 8837
+4: 8838
+4: 8839
+4: 8840
+4: 8841
+4: 8842
+4: 8843
+4: 8844
+4: 8845
+4: 8846
+4: 8847
+4: 8848
+4: 8849
+4: 8850
+4: 8851
+4: 8852
+4: 8853
+4: 8854
+4: 8855
+4: 8856
+4: 8857
+4: 8858
+4: 8859
+4: 8860
+4: 8861
+4: 8862
+4: 8863
+4: 8864
+4: 8865
+4: 8866
+4: 8867
+4: 8868
+4: 8869
+4: 8870
+4: 8871
+4: 8872
+4: 8873
+4: 8874
+4: 8875
+4: 8876
+4: 8877
+4: 8878
+4: 8879
+4: 8880
+4: 8881
+4: 8882
+4: 8883
+4: 8884
+4: 8885
+4: 8886
+4: 8887
+4: 8888
+4: 8889
+4: 8890
+4: 8891
+4: 8892
+4: 8893
+4: 8894
+4: 8895
+4: 8896
+4: 8897
+4: 8898
+4: 8899
+4: 8900
+4: 8901
+4: 8902
+4: 8903
+4: 8904
+4: 8905
+4: 8906
+4: 8907
+4: 8908
+4: 8909
+4: 8910
+4: 8911
+4: 8912
+4: 8913
+4: 8914
+4: 8915
+4: 8916
+4: 8917
+4: 8918
+4: 8919
+4: 8920
+4: 8921
+4: 8922
+4: 8923
+4: 8924
+4: 8925
+4: 8926
+4: 8927
+4: 8928
+4: 8929
+4: 8930
+4: 8931
+4: 8932
+4: 8933
+4: 8934
+4: 8935
+4: 8936
+4: 8937
+4: 8938
+4: 8939
+4: 8940
+4: 8941
+4: 8942
+4: 8943
+4: 8944
+4: 8945
+4: 8946
+4: 8947
+4: 8948
+4: 8949
+4: 8950
+4: 8951
+4: 8952
+4: 8953
+4: 8954
+4: 8955
+4: 8956
+4: 8957
+4: 8958
+4: 8959
+4: 8960
+4: 8961
+4: 8962
+4: 8963
+4: 8964
+4: 8965
+4: 8966
+4: 8967
+4: 8968
+4: 8969
+4: 8970
+4: 8971
+4: 8972
+4: 8973
+4: 8974
+4: 8975
+4: 8976
+4: 8977
+4: 8978
+4: 8979
+4: 8980
+4: 8981
+4: 8982
+4: 8983
+4: 8984
+4: 8985
+4: 8986
+4: 8987
+4: 8988
+4: 8989
+4: 8990
+4: 8991
+4: 8992
+4: 8993
+4: 8994
+4: 8995
+4: 8996
+4: 8997
+4: 8998
+4: 8999
+4: 9000
+4: 9001
+4: 9002
+4: 9003
+4: 9004
+4: 9005
+4: 9006
+4: 9007
+4: 9008
+4: 9009
+4: 9010
+4: 9011
+4: 9012
+4: 9013
+4: 9014
+4: 9015
+4: 9016
+4: 9017
+4: 9018
+4: 9019
+4: 9020
+4: 9021
+4: 9022
+4: 9023
+4: 9024
+4: 9025
+4: 9026
+4: 9027
+4: 9028
+4: 9029
+4: 9030
+4: 9031
+4: 9032
+4: 9033
+4: 9034
+4: 9035
+4: 9036
+4: 9037
+4: 9038
+4: 9039
+4: 9040
+4: 9041
+4: 9042
+4: 9043
+4: 9044
+4: 9045
+4: 9046
+4: 9047
+4: 9048
+4: 9049
+4: 9050
+4: 9051
+4: 9052
+4: 9053
+4: 9054
+4: 9055
+4: 9056
+4: 9057
+4: 9058
+4: 9059
+4: 9060
+4: 9061
+4: 9062
+4: 9063
+4: 9064
+4: 9065
+4: 9066
+4: 9067
+4: 9068
+4: 9069
+4: 9070
+4: 9071
+4: 9072
+4: 9073
+4: 9074
+4: 9075
+4: 9076
+4: 9077
+4: 9078
+4: 9079
+4: 9080
+4: 9081
+4: 9082
+4: 9083
+4: 9084
+4: 9085
+4: 9086
+4: 9087
+4: 9088
+4: 9089
+4: 9090
+4: 9091
+4: 9092
+4: 9093
+4: 9094
+4: 9095
+4: 9096
+4: 9097
+4: 9098
+4: 9099
+4: 9100
+4: 9101
+4: 9102
+4: 9103
+4: 9104
+4: 9105
+4: 9106
+4: 9107
+4: 9108
+4: 9109
+4: 9110
+4: 9111
+4: 9112
+4: 9113
+4: 9114
+4: 9115
+4: 9116
+4: 9117
+4: 9118
+4: 9119
+4: 9120
+4: 9121
+4: 9122
+4: 9123
+4: 9124
+4: 9125
+4: 9126
+4: 9127
+4: 9128
+4: 9129
+4: 9130
+4: 9131
+4: 9132
+4: 9133
+4: 9134
+4: 9135
+4: 9136
+4: 9137
+4: 9138
+4: 9139
+4: 9140
+4: 9141
+4: 9142
+4: 9143
+4: 9144
+4: 9145
+4: 9146
+4: 9147
+4: 9148
+4: 9149
+4: 9150
+4: 9151
+4: 9152
+4: 9153
+4: 9154
+4: 9155
+4: 9156
+4: 9157
+4: 9158
+4: 9159
+4: 9160
+4: 9161
+4: 9162
+4: 9163
+4: 9164
+4: 9165
+4: 9166
+4: 9167
+4: 9168
+4: 9169
+4: 9170
+4: 9171
+4: 9172
+4: 9173
+4: 9174
+4: 9175
+4: 9176
+4: 9177
+4: 9178
+4: 9179
+4: 9180
+4: 9181
+4: 9182
+4: 9183
+4: 9184
+4: 9185
+4: 9186
+4: 9187
+4: 9188
+4: 9189
+4: 9190
+4: 9191
+4: 9192
+4: 9193
+4: 9194
+4: 9195
+4: 9196
+4: 9197
+4: 9198
+4: 9199
+4: 9200
+4: 9201
+4: 9202
+4: 9203
+4: 9204
+4: 9205
+4: 9206
+4: 9207
+4: 9208
+4: 9209
+4: 9210
+4: 9211
+4: 9212
+4: 9213
+4: 9214
+4: 9215
+4: 9216
+4: 9217
+4: 9218
+5: 9219
+5: 9220
+5: 9221
+5: 9222
+5: 9223
+5: 9224
+5: 9225
+5: 9226
+5: 9227
+5: 9228
+5: 9229
+5: 9230
+5: 9231
+5: 9232
+5: 9233
+5: 9234
+5: 9235
+5: 9236
+5: 9237
+5: 9238
+5: 9239
+5: 9240
+5: 9241
+5: 9242
+5: 9243
+5: 9244
+5: 9245
+5: 9246
+5: 9247
+5: 9248
+5: 9249
+5: 9250
+5: 9251
+5: 9252
+5: 9253
+5: 9254
+5: 9255
+5: 9256
+5: 9257
+5: 9258
+5: 9259
+5: 9260
+5: 9261
+5: 9262
+5: 9263
+5: 9264
+5: 9265
+5: 9266
+5: 9267
+5: 9268
+5: 9269
+5: 9270
+5: 9271
+5: 9272
+5: 9273
+5: 9274
+5: 9275
+5: 9276
+5: 9277
+5: 9278
+5: 9279
+5: 9280
+5: 9281
+5: 9282
+5: 9283
+5: 9284
+5: 9285
+5: 9286
+5: 9287
+5: 9288
+5: 9289
+5: 9290
+5: 9291
+5: 9292
+5: 9293
+5: 9294
+5: 9295
+5: 9296
+5: 9297
+5: 9298
+5: 9299
+5: 9300
+5: 9301
+5: 9302
+5: 9303
+5: 9304
+5: 9305
+5: 9306
+5: 9307
+5: 9308
+5: 9309
+5: 9310
+5: 9311
+5: 9312
+5: 9313
+5: 9314
+5: 9315
+5: 9316
+5: 9317
+5: 9318
+5: 9319
+5: 9320
+5: 9321
+5: 9322
+5: 9323
+5: 9324
+5: 9325
+5: 9326
+5: 9327
+5: 9328
+5: 9329
+5: 9330
+5: 9331
+5: 9332
+5: 9333
+5: 9334
+5: 9335
+5: 9336
+5: 9337
+5: 9338
+5: 9339
+5: 9340
+5: 9341
+5: 9342
+5: 9343
+5: 9344
+5: 9345
+5: 9346
+5: 9347
+5: 9348
+5: 9349
+5: 9350
+5: 9351
+5: 9352
+5: 9353
+5: 9354
+5: 9355
+5: 9356
+5: 9357
+5: 9358
+5: 9359
+5: 9360
+5: 9361
+5: 9362
+5: 9363
+5: 9364
+5: 9365
+5: 9366
+5: 9367
+5: 9368
+5: 9369
+5: 9370
+5: 9371
+5: 9372
+5: 9373
+5: 9374
+5: 9375
+5: 9376
+5: 9377
+5: 9378
+5: 9379
+5: 9380
+5: 9381
+5: 9382
+5: 9383
+5: 9384
+5: 9385
+5: 9386
+5: 9387
+5: 9388
+5: 9389
+5: 9390
+5: 9391
+5: 9392
+5: 9393
+5: 9394
+5: 9395
+5: 9396
+5: 9397
+5: 9398
+5: 9399
+5: 9400
+5: 9401
+5: 9402
+5: 9403
+5: 9404
+5: 9405
+5: 9406
+5: 9407
+5: 9408
+5: 9409
+5: 9410
+5: 9411
+5: 9412
+5: 9413
+5: 9414
+5: 9415
+5: 9416
+5: 9417
+5: 9418
+5: 9419
+5: 9420
+5: 9421
+5: 9422
+5: 9423
+5: 9424
+5: 9425
+5: 9426
+5: 9427
+5: 9428
+5: 9429
+5: 9430
+5: 9431
+5: 9432
+5: 9433
+5: 9434
+5: 9435
+5: 9436
+5: 9437
+5: 9438
+5: 9439
+5: 9440
+5: 9441
+5: 9442
+5: 9443
+5: 9444
+5: 9445
+5: 9446
+5: 9447
+5: 9448
+5: 9449
+5: 9450
+5: 9451
+5: 9452
+5: 9453
+5: 9454
+5: 9455
+5: 9456
+5: 9457
+5: 9458
+5: 9459
+5: 9460
+5: 9461
+5: 9462
+5: 9463
+5: 9464
+5: 9465
+5: 9466
+5: 9467
+5: 9468
+5: 9469
+5: 9470
+5: 9471
+5: 9472
+5: 9473
+5: 9474
+5: 9475
+5: 9476
+5: 9477
+5: 9478
+5: 9479
+5: 9480
+4: 9481
+4: 9482
+4: 9483
+4: 9484
+4: 9485
+4: 9486
+4: 9487
+4: 9488
+4: 9489
+4: 9490
+4: 9491
+4: 9492
+4: 9493
+4: 9494
+4: 9495
+4: 9496
+4: 9497
+4: 9498
+4: 9499
+4: 9500
+4: 9501
+4: 9502
+4: 9503
+4: 9504
+4: 9505
+4: 9506
+4: 9507
+4: 9508
+4: 9509
+4: 9510
+4: 9511
+4: 9512
+4: 9513
+4: 9514
+4: 9515
+4: 9516
+4: 9517
+4: 9518
+4: 9519
+4: 9520
+4: 9521
+4: 9522
+4: 9523
+4: 9524
+4: 9525
+4: 9526
+4: 9527
+4: 9528
+4: 9529
+4: 9530
+4: 9531
+4: 9532
+4: 9533
+4: 9534
+4: 9535
+4: 9536
+4: 9537
+4: 9538
+4: 9539
+4: 9540
+4: 9541
+4: 9542
+4: 9543
+4: 9544
+4: 9545
+4: 9546
+4: 9547
+4: 9548
+4: 9549
+4: 9550
+4: 9551
+4: 9552
+4: 9553
+4: 9554
+4: 9555
+4: 9556
+4: 9557
+4: 9558
+4: 9559
+4: 9560
+4: 9561
+4: 9562
+4: 9563
+4: 9564
+4: 9565
+4: 9566
+4: 9567
+4: 9568
+4: 9569
+4: 9570
+4: 9571
+4: 9572
+4: 9573
+4: 9574
+4: 9575
+4: 9576
+4: 9577
+4: 9578
+4: 9579
+4: 9580
+4: 9581
+4: 9582
+4: 9583
+4: 9584
+4: 9585
+4: 9586
+4: 9587
+4: 9588
+4: 9589
+4: 9590
+4: 9591
+4: 9592
+4: 9593
+4: 9594
+4: 9595
+4: 9596
+4: 9597
+4: 9598
+4: 9599
+4: 9600
+4: 9601
+4: 9602
+4: 9603
+4: 9604
+4: 9605
+4: 9606
+4: 9607
+4: 9608
+4: 9609
+4: 9610
+4: 9611
+4: 9612
+4: 9613
+4: 9614
+4: 9615
+4: 9616
+4: 9617
+4: 9618
+4: 9619
+4: 9620
+4: 9621
+4: 9622
+4: 9623
+4: 9624
+4: 9625
+4: 9626
+4: 9627
+4: 9628
+4: 9629
+4: 9630
+4: 9631
+4: 9632
+4: 9633
+4: 9634
+4: 9635
+4: 9636
+4: 9637
+4: 9638
+4: 9639
+4: 9640
+4: 9641
+4: 9642
+4: 9643
+4: 9644
+4: 9645
+4: 9646
+4: 9647
+4: 9648
+4: 9649
+4: 9650
+4: 9651
+4: 9652
+4: 9653
+4: 9654
+4: 9655
+4: 9656
+4: 9657
+4: 9658
+4: 9659
+4: 9660
+4: 9661
+4: 9662
+4: 9663
+4: 9664
+4: 9665
+4: 9666
+4: 9667
+4: 9668
+4: 9669
+4: 9670
+4: 9671
+4: 9672
+4: 9673
+4: 9674
+4: 9675
+4: 9676
+4: 9677
+4: 9678
+4: 9679
+4: 9680
+4: 9681
+4: 9682
+4: 9683
+4: 9684
+4: 9685
+4: 9686
+4: 9687
+4: 9688
+4: 9689
+4: 9690
+4: 9691
+4: 9692
+4: 9693
+4: 9694
+4: 9695
+4: 9696
+4: 9697
+4: 9698
+4: 9699
+4: 9700
+4: 9701
+4: 9702
+4: 9703
+4: 9704
+4: 9705
+4: 9706
+4: 9707
+4: 9708
+4: 9709
+4: 9710
+4: 9711
+4: 9712
+4: 9713
+4: 9714
+4: 9715
+4: 9716
+4: 9717
+4: 9718
+4: 9719
+4: 9720
+4: 9721
+4: 9722
+4: 9723
+4: 9724
+4: 9725
+4: 9726
+4: 9727
+4: 9728
+4: 9729
+4: 9730
+4: 9731
+4: 9732
+4: 9733
+4: 9734
+4: 9735
+4: 9736
+4: 9737
+4: 9738
+4: 9739
+4: 9740
+4: 9741
+4: 9742
+4: 9743
+4: 9744
+4: 9745
+4: 9746
+4: 9747
+4: 9748
+4: 9749
+4: 9750
+4: 9751
+4: 9752
+4: 9753
+4: 9754
+4: 9755
+4: 9756
+4: 9757
+4: 9758
+4: 9759
+4: 9760
+4: 9761
+4: 9762
+4: 9763
+4: 9764
+4: 9765
+4: 9766
+4: 9767
+4: 9768
+4: 9769
+4: 9770
+4: 9771
+4: 9772
+4: 9773
+4: 9774
+4: 9775
+4: 9776
+4: 9777
+4: 9778
+4: 9779
+4: 9780
+4: 9781
+4: 9782
+4: 9783
+4: 9784
+4: 9785
+4: 9786
+4: 9787
+4: 9788
+4: 9789
+4: 9790
+4: 9791
+4: 9792
+4: 9793
+4: 9794
+4: 9795
+4: 9796
+4: 9797
+4: 9798
+4: 9799
+4: 9800
+4: 9801
+4: 9802
+4: 9803
+4: 9804
+4: 9805
+4: 9806
+4: 9807
+4: 9808
+4: 9809
+4: 9810
+4: 9811
+4: 9812
+4: 9813
+4: 9814
+4: 9815
+4: 9816
+4: 9817
+4: 9818
+4: 9819
+4: 9820
+4: 9821
+4: 9822
+4: 9823
+4: 9824
+4: 9825
+4: 9826
+4: 9827
+4: 9828
+4: 9829
+4: 9830
+4: 9831
+4: 9832
+4: 9833
+4: 9834
+4: 9835
+4: 9836
+4: 9837
+4: 9838
+4: 9839
+4: 9840
+4: 9841
+4: 9842
+4: 9843
+4: 9844
+4: 9845
+4: 9846
+4: 9847
+4: 9848
+4: 9849
+4: 9850
+4: 9851
+4: 9852
+4: 9853
+4: 9854
+4: 9855
+4: 9856
+4: 9857
+4: 9858
+4: 9859
+4: 9860
+4: 9861
+4: 9862
+4: 9863
+4: 9864
+4: 9865
+4: 9866
+4: 9867
+4: 9868
+4: 9869
+4: 9870
+4: 9871
+4: 9872
+4: 9873
+4: 9874
+4: 9875
+4: 9876
+4: 9877
+4: 9878
+4: 9879
+4: 9880
+4: 9881
+4: 9882
+4: 9883
+4: 9884
+4: 9885
+4: 9886
+4: 9887
+4: 9888
+4: 9889
+4: 9890
+4: 9891
+4: 9892
+4: 9893
+4: 9894
+4: 9895
+4: 9896
+4: 9897
+4: 9898
+5: 9899
+5: 9900
+5: 9901
+5: 9902
+5: 9903
+5: 9904
+5: 9905
+5: 9906
+5: 9907
+5: 9908
+5: 9909
+5: 9910
+5: 9911
+5: 9912
+5: 9913
+5: 9914
+5: 9915
+5: 9916
+5: 9917
+5: 9918
+5: 9919
+5: 9920
+5: 9921
+5: 9922
+5: 9923
+5: 9924
+5: 9925
+5: 9926
+5: 9927
+5: 9928
+5: 9929
+5: 9930
+5: 9931
+5: 9932
+5: 9933
+5: 9934
+5: 9935
+5: 9936
+5: 9937
+5: 9938
+5: 9939
+5: 9940
+5: 9941
+5: 9942
+5: 9943
+5: 9944
+5: 9945
+5: 9946
+5: 9947
+5: 9948
+5: 9949
+5: 9950
+5: 9951
+5: 9952
+5: 9953
+5: 9954
+5: 9955
+5: 9956
+5: 9957
+5: 9958
+5: 9959
+5: 9960
+5: 9961
+5: 9962
+5: 9963
+5: 9964
+5: 9965
+5: 9966
+5: 9967
+5: 9968
+5: 9969
+5: 9970
+5: 9971
+5: 9972
+5: 9973
+5: 9974
+5: 9975
+5: 9976
+5: 9977
+5: 9978
+5: 9979
+5: 9980
+5: 9981
+5: 9982
+5: 9983
+5: 9984
+5: 9985
+5: 9986
+5: 9987
+5: 9988
+5: 9989
+5: 9990
+5: 9991
+5: 9992
+5: 9993
+5: 9994
+5: 9995
+5: 9996
+5: 9997
+5: 9998
+5: 9999
+5: 10000
diff --git a/threads/strclithread.c b/threads/strclithread.c
new file mode 100644 (file)
index 0000000..22dd4db
--- /dev/null
@@ -0,0 +1,35 @@
+#include       "unpthread.h"
+
+void   *copyto(void *);
+
+static int     sockfd;         /* global for both threads to access */
+static FILE    *fp;
+
+void
+str_cli(FILE *fp_arg, int sockfd_arg)
+{
+       char            recvline[MAXLINE];
+       pthread_t       tid;
+
+       sockfd = sockfd_arg;    /* copy arguments to externals */
+       fp = fp_arg;
+
+       Pthread_create(&tid, NULL, copyto, NULL);
+
+       while (Readline(sockfd, recvline, MAXLINE) > 0)
+               Fputs(recvline, stdout);
+}
+
+void *
+copyto(void *arg)
+{
+       char    sendline[MAXLINE];
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL)
+               Writen(sockfd, sendline, strlen(sendline));
+
+       Shutdown(sockfd, SHUT_WR);      /* EOF on stdin, send FIN */
+
+       return(NULL);
+               /* 4return (i.e., thread terminates) when EOF on stdin */
+}
diff --git a/threads/strclithread.lc b/threads/strclithread.lc
new file mode 100644 (file)
index 0000000..58bf087
--- /dev/null
@@ -0,0 +1,35 @@
+#include    "unpthread.h"##  1 ##src/threads/strclithread.c##
+
+void   *copyto(void *);##  2 ##src/threads/strclithread.c##
+
+static int sockfd;              /* global for both threads to access */##  3 ##src/threads/strclithread.c##
+static FILE *fp;##  4 ##src/threads/strclithread.c##
+
+void##  5 ##src/threads/strclithread.c##
+str_cli(FILE *fp_arg, int sockfd_arg)##  6 ##src/threads/strclithread.c##
+{##  7 ##src/threads/strclithread.c##
+    char    recvline[MAXLINE];##  8 ##src/threads/strclithread.c##
+    pthread_t tid;##  9 ##src/threads/strclithread.c##
+
+    sockfd = sockfd_arg;        /* copy arguments to externals */## 10 ##src/threads/strclithread.c##
+    fp = fp_arg;## 11 ##src/threads/strclithread.c##
+
+    Pthread_create(&tid, NULL, copyto, NULL);## 12 ##src/threads/strclithread.c##
+
+    while (Readline(sockfd, recvline, MAXLINE) > 0)## 13 ##src/threads/strclithread.c##
+        Fputs(recvline, stdout);## 14 ##src/threads/strclithread.c##
+}## 15 ##src/threads/strclithread.c##
+
+void   *## 16 ##src/threads/strclithread.c##
+copyto(void *arg)## 17 ##src/threads/strclithread.c##
+{## 18 ##src/threads/strclithread.c##
+    char    sendline[MAXLINE];## 19 ##src/threads/strclithread.c##
+
+    while (Fgets(sendline, MAXLINE, fp) != NULL)## 20 ##src/threads/strclithread.c##
+        Writen(sockfd, sendline, strlen(sendline));## 21 ##src/threads/strclithread.c##
+
+    Shutdown(sockfd, SHUT_WR);  /* EOF on stdin, send FIN */## 22 ##src/threads/strclithread.c##
+
+    return (NULL);## 23 ##src/threads/strclithread.c##
+    /* 4return (i.e., thread terminates) when end-of-file on stdin */## 24 ##src/threads/strclithread.c##
+}## 25 ##src/threads/strclithread.c##
diff --git a/threads/strclithread2.c b/threads/strclithread2.c
new file mode 100644 (file)
index 0000000..2fb624e
--- /dev/null
@@ -0,0 +1,40 @@
+#include       "unpthread.h"
+
+void   *copyto(void *);
+
+static int     sockfd;
+static FILE    *fp;
+static int     done;
+
+void
+str_cli(FILE *fp_arg, int sockfd_arg)
+{
+       char            recvline[MAXLINE];
+       pthread_t       tid;
+
+       sockfd = sockfd_arg;    /* copy arguments to externals */
+       fp = fp_arg;
+
+       Pthread_create(&tid, NULL, copyto, NULL);
+
+       while (Readline(sockfd, recvline, MAXLINE) > 0)
+               Fputs(recvline, stdout);
+
+       if (done == 0)
+               err_quit("server terminated prematurely");
+}
+
+void *
+copyto(void *arg)
+{
+       char    sendline[MAXLINE];
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL)
+               Writen(sockfd, sendline, strlen(sendline));
+
+       Shutdown(sockfd, SHUT_WR);      /* EOF on stdin, send FIN */
+
+       done = 1;
+       return(NULL);
+       /* return (i.e., thread terminates) when end-of-file on stdin */
+}
diff --git a/threads/tcpcli01.c b/threads/tcpcli01.c
new file mode 100644 (file)
index 0000000..aa1300e
--- /dev/null
@@ -0,0 +1,16 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             sockfd;
+
+       if (argc != 3)
+               err_quit("usage: tcpcli <hostname> <service>");
+
+       sockfd = Tcp_connect(argv[1], argv[2]);
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/threads/tcpcli02.c b/threads/tcpcli02.c
new file mode 100644 (file)
index 0000000..aa1300e
--- /dev/null
@@ -0,0 +1,16 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             sockfd;
+
+       if (argc != 3)
+               err_quit("usage: tcpcli <hostname> <service>");
+
+       sockfd = Tcp_connect(argv[1], argv[2]);
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/threads/tcpserv01.c b/threads/tcpserv01.c
new file mode 100644 (file)
index 0000000..5bd1346
--- /dev/null
@@ -0,0 +1,36 @@
+#include       "unpthread.h"
+
+static void    *doit(void *);          /* each thread executes this function */
+
+int
+main(int argc, char **argv)
+{
+       int                             listenfd, connfd;
+       pthread_t               tid;
+       socklen_t               addrlen, len;
+       struct sockaddr *cliaddr;
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: tcpserv01 [ <host> ] <service or port>");
+
+       cliaddr = Malloc(addrlen);
+
+       for ( ; ; ) {
+               len = addrlen;
+               connfd = Accept(listenfd, cliaddr, &len);
+               Pthread_create(&tid, NULL, &doit, (void *) connfd);
+       }
+}
+
+static void *
+doit(void *arg)
+{
+       Pthread_detach(pthread_self());
+       str_echo((int) arg);    /* same function as before */
+       Close((int) arg);               /* done with connected socket */
+       return(NULL);
+}
diff --git a/threads/tcpserv02.c b/threads/tcpserv02.c
new file mode 100644 (file)
index 0000000..b8da350
--- /dev/null
@@ -0,0 +1,42 @@
+#include       "unpthread.h"
+
+static void    *doit(void *);          /* each thread executes this function */
+
+int
+main(int argc, char **argv)
+{
+       int                             listenfd, *iptr;
+       thread_t                tid;
+       socklen_t               addrlen, len;
+       struct sockaddr *cliaddr;
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: tcpserv01 [ <host> ] <service or port>");
+
+       cliaddr = Malloc(addrlen);
+
+       for ( ; ; ) {
+               len = addrlen;
+               iptr = Malloc(sizeof(int));
+               *iptr = Accept(listenfd, cliaddr, &len);
+               Pthread_create(&tid, NULL, &doit, iptr);
+       }
+}
+
+static void *
+doit(void *arg)
+{
+       int             connfd;
+
+       connfd = *((int *) arg);
+       free(arg);
+
+       Pthread_detach(pthread_self());
+       str_echo(connfd);               /* same function as before */
+       Close(connfd);                  /* done with connected socket */
+       return(NULL);
+}
diff --git a/threads/test01.c b/threads/test01.c
new file mode 100644 (file)
index 0000000..bbb3e2c
--- /dev/null
@@ -0,0 +1,29 @@
+#include       "unpthread.h"
+
+void *
+myfunc(void *ptr)
+{
+       pause();
+}
+
+int
+main(int argc, char **argv)
+{
+       pthread_t       tid;
+       int                     n;
+
+       /* Let's see what the return value is and what errno is after a error. */
+       for ( ; ; ) {
+               errno = 0;
+               if ( (n = pthread_create(&tid, NULL, myfunc, NULL)) != 0) {
+                       printf("pthread_create returned %d, errno = %d\n", n, errno);
+
+                       errno = 0;
+                       n = pthread_join(777777, NULL);
+                       printf("pthread_join returned %d, errno = %d\n", n, errno);
+
+                       exit(0);
+               }
+               printf("created tid %d\n", tid);
+       }
+}
diff --git a/threads/test02.c b/threads/test02.c
new file mode 100644 (file)
index 0000000..a4e4ba5
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unpthread.h"
+
+void *
+myfunc(void *ptr)
+{
+       int             val;
+
+       printf("thread ID of myfunc: %d\n", pthread_self());
+
+       val = *((int *) ptr);
+       printf("val = %d\n", val);
+       sleep(10);
+       val = *((int *) ptr);
+       printf("val = %d\n", val);
+}
+
+int
+main(int argc, char **argv)
+{
+       pthread_t       tid;
+       int                     n, val;
+
+       printf("thread ID of main: %d\n", pthread_self());
+
+       /* Let's verify that the value pointed to the thread's argument is
+          modifiable */
+       val = 123;
+       if ( (n = pthread_create(&tid, NULL, myfunc, &val)) != 0)
+               errno = n, err_sys("pthread_create error");
+       sleep(5);
+       val = 789;
+       sleep(20);
+       exit(0);
+}
diff --git a/threads/test03.c b/threads/test03.c
new file mode 100644 (file)
index 0000000..a266e90
--- /dev/null
@@ -0,0 +1,47 @@
+/* test pthread_cond_timedwait() */
+
+#include       "unpthread.h"
+
+int                            ndone;
+pthread_mutex_t        ndone_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t ndone_cond = PTHREAD_COND_INITIALIZER;
+
+void *
+myfunc(void *ptr)
+{
+       int             val;
+
+       sleep(100);             /* do not set ndone, do not cond_signal() */
+       return(NULL);
+}
+
+int
+main(int argc, char **argv)
+{
+       pthread_t               tid;
+       int                             n, val;
+       struct timeval  tv;
+       struct timespec ts;
+
+       if ( (n = pthread_create(&tid, NULL, myfunc, &val)) != 0)
+               errno = n, err_sys("pthread_create error");
+
+       if (gettimeofday(&tv, NULL) < 0)
+               err_sys("gettimeofday error");
+       ts.tv_sec  = tv.tv_sec + 5;             /* 5 seconds in future */
+       ts.tv_nsec = tv.tv_usec * 1000;
+
+       if ( (n = pthread_mutex_lock(&ndone_mutex)) != 0)
+               errno = n, err_sys("pthread_mutex_lock error");
+       while (ndone == 0)
+               if ( (n = pthread_cond_timedwait(&ndone_cond, &ndone_mutex, &ts)) != 0){
+                       if (n == ETIME)
+                               err_quit("timewait timed out");
+                       errno = n, err_sys("pthread_cond_timedwait error");
+               }
+
+       if ( (n = pthread_mutex_unlock(&ndone_mutex)) != 0)
+               errno = n, err_sys("pthread_mutex_unlock error");
+
+       exit(0);
+}
diff --git a/threads/test04.c b/threads/test04.c
new file mode 100644 (file)
index 0000000..993198d
--- /dev/null
@@ -0,0 +1,50 @@
+/* test readline() */
+
+#include       "unpthread.h"
+
+static char    *infile;        /* from argv[1]; read-only by threads */
+
+void *
+myfunc(void *ptr)
+{
+       int             i, fdin;
+       char    buf[MAXLINE];
+       FILE    *fpout;
+
+       snprintf(buf, sizeof(buf), "temp.%d", pthread_self());
+       fpout = Fopen(buf, "w+");
+       /* printf("created %s\n", buf); */
+
+       for (i = 0; i < 5; i++) {
+               fdin = Open(infile, O_RDONLY, 0);
+
+               while (Readline(fdin, buf, sizeof(buf)) > 0) {
+                       fputs(buf, fpout);
+               }
+               Close(fdin);
+       }
+       Fclose(fpout);
+
+       printf("thread %d done\n", pthread_self());
+       return(NULL);
+}
+
+int
+main(int argc, char **argv)
+{
+       int                             i, nthreads;
+       pthread_t               tid;
+
+       if (argc != 3)
+               err_quit("usage: test04 <input-file> <#threads>");
+       infile = argv[1];
+       nthreads = atoi(argv[2]);
+
+       for (i = 0; i < nthreads; i++) {
+               Pthread_create(&tid, NULL, myfunc, NULL);
+       }
+
+       pause();
+
+       exit(0);
+}
diff --git a/threads/test05.c b/threads/test05.c
new file mode 100644 (file)
index 0000000..7d5aa02
--- /dev/null
@@ -0,0 +1,33 @@
+/* See what the implementation returns for TSD keys */
+
+#include       "unpthread.h"
+
+pthread_key_t  my_key;
+
+int
+main(int argc, char **argv)
+{
+       int             *iptr;
+
+       Pthread_key_create(&my_key, NULL);
+       printf("first key = %d\n", my_key);
+
+       Pthread_key_create(&my_key, NULL);
+       printf("second key = %d\n", my_key);
+
+       Pthread_key_create(&my_key, NULL);
+       printf("third key = %d\n", my_key);
+
+       if ( (iptr = pthread_getspecific((pthread_key_t) 0)) == NULL)
+               printf("key 0 pointer is NULL\n");
+       else
+               printf("value in key 0 = %d\n", *iptr);
+
+       errno = 67;
+       if ( (iptr = pthread_getspecific((pthread_key_t) 0)) == NULL)
+               printf("key 0 pointer is NULL\n");
+       else
+               printf("value in key 0 = %d\n", *iptr);
+
+       exit(0);
+}
diff --git a/threads/unpthread.h b/threads/unpthread.h
new file mode 100644 (file)
index 0000000..e79b779
--- /dev/null
@@ -0,0 +1,31 @@
+/* Our own header for the programs that use threads.
+   Include this file, instead of "unp.h". */
+
+#ifndef        __unp_pthread_h
+#define        __unp_pthread_h
+
+#include       "unp.h"
+
+void   Pthread_create(pthread_t *, const pthread_attr_t *,
+                                          void * (*)(void *), void *);
+void   Pthread_join(pthread_t, void **);
+void   Pthread_detach(pthread_t);
+void   Pthread_kill(pthread_t, int);
+
+void   Pthread_mutexattr_init(pthread_mutexattr_t *);
+void   Pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
+void   Pthread_mutex_init(pthread_mutex_t *, pthread_mutexattr_t *);
+void   Pthread_mutex_lock(pthread_mutex_t *);
+void   Pthread_mutex_unlock(pthread_mutex_t *);
+
+void   Pthread_cond_broadcast(pthread_cond_t *);
+void   Pthread_cond_signal(pthread_cond_t *);
+void   Pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
+void   Pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *,
+                                                          const struct timespec *);
+
+void   Pthread_key_create(pthread_key_t *, void (*)(void *));
+void   Pthread_setspecific(pthread_key_t, const void *);
+void   Pthread_once(pthread_once_t *, void (*)(void));
+
+#endif /* __unp_pthread_h */
diff --git a/threads/web01.c b/threads/web01.c
new file mode 100644 (file)
index 0000000..adc9bba
--- /dev/null
@@ -0,0 +1,149 @@
+/* include web1 */
+#include       "unpthread.h"
+#include       <thread.h>              /* Solaris threads */
+
+#define        MAXFILES        20
+#define        SERV            "80"    /* port number or service name */
+
+struct file {
+  char *f_name;                        /* filename */
+  char *f_host;                        /* hostname or IP address */
+  int    f_fd;                         /* descriptor */
+  int   f_flags;                       /* F_xxx below */
+  pthread_t     f_tid;                 /* thread ID */
+} file[MAXFILES];
+#define        F_CONNECTING    1       /* connect() in progress */
+#define        F_READING               2       /* connect() complete; now reading */
+#define        F_DONE                  4       /* all done */
+
+#define        GET_CMD         "GET %s HTTP/1.0\r\n\r\n"
+
+int            nconn, nfiles, nlefttoconn, nlefttoread;
+
+void   *do_get_read(void *);
+void   home_page(const char *, const char *);
+void   write_get_cmd(struct file *);
+
+int
+main(int argc, char **argv)
+{
+       int                     i, n, maxnconn;
+       pthread_t       tid;
+       struct file     *fptr;
+
+       if (argc < 5)
+               err_quit("usage: web <#conns> <IPaddr> <homepage> file1 ...");
+       maxnconn = atoi(argv[1]);
+
+       nfiles = min(argc - 4, MAXFILES);
+       for (i = 0; i < nfiles; i++) {
+               file[i].f_name = argv[i + 4];
+               file[i].f_host = argv[2];
+               file[i].f_flags = 0;
+       }
+       printf("nfiles = %d\n", nfiles);
+
+       home_page(argv[2], argv[3]);
+
+       nlefttoread = nlefttoconn = nfiles;
+       nconn = 0;
+/* end web1 */
+/* include web2 */
+       while (nlefttoread > 0) {
+               while (nconn < maxnconn && nlefttoconn > 0) {
+                               /* 4find a file to read */
+                       for (i = 0 ; i < nfiles; i++)
+                               if (file[i].f_flags == 0)
+                                       break;
+                       if (i == nfiles)
+                               err_quit("nlefttoconn = %d but nothing found", nlefttoconn);
+
+                       file[i].f_flags = F_CONNECTING;
+                       Pthread_create(&tid, NULL, &do_get_read, &file[i]);
+                       file[i].f_tid = tid;
+                       nconn++;
+                       nlefttoconn--;
+               }
+
+               if ( (n = thr_join(0, &tid, (void **) &fptr)) != 0)
+                       errno = n, err_sys("thr_join error");
+
+               nconn--;
+               nlefttoread--;
+               printf("thread id %d for %s done\n", tid, fptr->f_name);
+       }
+
+       exit(0);
+}
+/* end web2 */
+
+/* include do_get_read */
+void *
+do_get_read(void *vptr)
+{
+       int                                     fd, n;
+       char                            line[MAXLINE];
+       struct file                     *fptr;
+
+       fptr = (struct file *) vptr;
+
+       fd = Tcp_connect(fptr->f_host, SERV);
+       fptr->f_fd = fd;
+       printf("do_get_read for %s, fd %d, thread %d\n",
+                       fptr->f_name, fd, fptr->f_tid);
+
+       write_get_cmd(fptr);    /* write() the GET command */
+
+               /* 4Read server's reply */
+       for ( ; ; ) {
+               if ( (n = Read(fd, line, MAXLINE)) == 0)
+                       break;          /* server closed connection */
+
+               printf("read %d bytes from %s\n", n, fptr->f_name);
+       }
+       printf("end-of-file on %s\n", fptr->f_name);
+       Close(fd);
+       fptr->f_flags = F_DONE;         /* clears F_READING */
+
+       return(fptr);           /* terminate thread */
+}
+/* end do_get_read */
+
+/* include write_get_cmd */
+void
+write_get_cmd(struct file *fptr)
+{
+       int             n;
+       char    line[MAXLINE];
+
+       n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name);
+       Writen(fptr->f_fd, line, n);
+       printf("wrote %d bytes for %s\n", n, fptr->f_name);
+
+       fptr->f_flags = F_READING;                      /* clears F_CONNECTING */
+}
+/* end write_get_cmd */
+
+/* include home_page */
+void
+home_page(const char *host, const char *fname)
+{
+       int             fd, n;
+       char    line[MAXLINE];
+
+       fd = Tcp_connect(host, SERV);   /* blocking connect() */
+
+       n = snprintf(line, sizeof(line), GET_CMD, fname);
+       Writen(fd, line, n);
+
+       for ( ; ; ) {
+               if ( (n = Read(fd, line, MAXLINE)) == 0)
+                       break;          /* server closed connection */
+
+               printf("read %d bytes of home page\n", n);
+               /* do whatever with data */
+       }
+       printf("end-of-file on home page\n");
+       Close(fd);
+}
+/* end home_page */
diff --git a/threads/web01.lc b/threads/web01.lc
new file mode 100644 (file)
index 0000000..162fedd
--- /dev/null
@@ -0,0 +1,149 @@
+/* include web1 */
+#include    "unpthread.h"##  1 ##src/threads/web01.c##
+#include    <thread.h>          /* Solaris threads */##  2 ##src/threads/web01.c##
+
+#define MAXFILES    20##  3 ##src/threads/web01.c##
+#define SERV        "80"        /* port number or service name */##  4 ##src/threads/web01.c##
+
+struct file {##  5 ##src/threads/web01.c##
+    char   *f_name;             /* filename */##  6 ##src/threads/web01.c##
+    char   *f_host;             /* hostname or IP address */##  7 ##src/threads/web01.c##
+    int     f_fd;               /* descriptor */##  8 ##src/threads/web01.c##
+    int     f_flags;            /* F_xxx below */##  9 ##src/threads/web01.c##
+    pthread_t f_tid;            /* thread ID */## 10 ##src/threads/web01.c##
+} file[MAXFILES];## 11 ##src/threads/web01.c##
+#define F_CONNECTING    1       /* connect() in progress */## 12 ##src/threads/web01.c##
+#define F_READING       2       /* connect() complete; now reading */## 13 ##src/threads/web01.c##
+#define F_DONE          4       /* all done */## 14 ##src/threads/web01.c##
+
+#define GET_CMD     "GET %s HTTP/1.0\r\n\r\n"## 15 ##src/threads/web01.c##
+
+int     nconn, nfiles, nlefttoconn, nlefttoread;## 16 ##src/threads/web01.c##
+
+void   *do_get_read(void *);## 17 ##src/threads/web01.c##
+void    home_page(const char *, const char *);## 18 ##src/threads/web01.c##
+void    write_get_cmd(struct file *);## 19 ##src/threads/web01.c##
+
+int## 20 ##src/threads/web01.c##
+main(int argc, char **argv)## 21 ##src/threads/web01.c##
+{## 22 ##src/threads/web01.c##
+    int     i, n, maxnconn;## 23 ##src/threads/web01.c##
+    pthread_t tid;## 24 ##src/threads/web01.c##
+    struct file *fptr;## 25 ##src/threads/web01.c##
+
+    if (argc < 5)## 26 ##src/threads/web01.c##
+        err_quit("usage: web <#conns> <IPaddr> <homepage> file1 ...");## 27 ##src/threads/web01.c##
+    maxnconn = atoi(argv[1]);## 28 ##src/threads/web01.c##
+
+    nfiles = min(argc - 4, MAXFILES);## 29 ##src/threads/web01.c##
+    for (i = 0; i < nfiles; i++) {## 30 ##src/threads/web01.c##
+        file[i].f_name = argv[i + 4];## 31 ##src/threads/web01.c##
+        file[i].f_host = argv[2];## 32 ##src/threads/web01.c##
+        file[i].f_flags = 0;## 33 ##src/threads/web01.c##
+    }## 34 ##src/threads/web01.c##
+    printf("nfiles = %d\n", nfiles);## 35 ##src/threads/web01.c##
+
+    home_page(argv[2], argv[3]);## 36 ##src/threads/web01.c##
+
+    nlefttoread = nlefttoconn = nfiles;## 37 ##src/threads/web01.c##
+    nconn = 0;## 38 ##src/threads/web01.c##
+/* end web1 */
+/* include web2 */
+    while (nlefttoread > 0) {## 39 ##src/threads/web01.c##
+        while (nconn < maxnconn && nlefttoconn > 0) {## 40 ##src/threads/web01.c##
+            /* 4find a file to read */## 41 ##src/threads/web01.c##
+            for (i = 0; i < nfiles; i++)## 42 ##src/threads/web01.c##
+                if (file[i].f_flags == 0)## 43 ##src/threads/web01.c##
+                    break;## 44 ##src/threads/web01.c##
+            if (i == nfiles)## 45 ##src/threads/web01.c##
+                err_quit("nlefttoconn = %d but nothing found", nlefttoconn);## 46 ##src/threads/web01.c##
+
+            file[i].f_flags = F_CONNECTING;## 47 ##src/threads/web01.c##
+            Pthread_create(&tid, NULL, &do_get_read, &file[i]);## 48 ##src/threads/web01.c##
+            file[i].f_tid = tid;## 49 ##src/threads/web01.c##
+            nconn++;## 50 ##src/threads/web01.c##
+            nlefttoconn--;## 51 ##src/threads/web01.c##
+        }## 52 ##src/threads/web01.c##
+
+        if ((n = thr_join(0, &tid, (void **) &fptr)) != 0)## 53 ##src/threads/web01.c##
+            errno = n, err_sys("thr_join error");## 54 ##src/threads/web01.c##
+
+        nconn--;## 55 ##src/threads/web01.c##
+        nlefttoread--;## 56 ##src/threads/web01.c##
+        printf("thread id %d for %s done\n", tid, fptr->f_name);## 57 ##src/threads/web01.c##
+    }## 58 ##src/threads/web01.c##
+
+    exit(0);## 59 ##src/threads/web01.c##
+}## 60 ##src/threads/web01.c##
+/* end web2 */
+
+/* include do_get_read */
+void   *## 61 ##src/threads/web01.c##
+do_get_read(void *vptr)## 62 ##src/threads/web01.c##
+{## 63 ##src/threads/web01.c##
+    int     fd, n;## 64 ##src/threads/web01.c##
+    char    line[MAXLINE];## 65 ##src/threads/web01.c##
+    struct file *fptr;## 66 ##src/threads/web01.c##
+
+    fptr = (struct file *) vptr;## 67 ##src/threads/web01.c##
+
+    fd = Tcp_connect(fptr->f_host, SERV);## 68 ##src/threads/web01.c##
+    fptr->f_fd = fd;## 69 ##src/threads/web01.c##
+    printf("do_get_read for %s, fd %d, thread %d\n",## 70 ##src/threads/web01.c##
+           fptr->f_name, fd, fptr->f_tid);## 71 ##src/threads/web01.c##
+
+    write_get_cmd(fptr);        /* write() the GET command */## 72 ##src/threads/web01.c##
+
+    /* 4Read server's reply */## 73 ##src/threads/web01.c##
+    for (;;) {## 74 ##src/threads/web01.c##
+        if ((n = Read(fd, line, MAXLINE)) == 0)## 75 ##src/threads/web01.c##
+            break;              /* server closed connection */## 76 ##src/threads/web01.c##
+
+        printf("read %d bytes from %s\n", n, fptr->f_name);## 77 ##src/threads/web01.c##
+    }## 78 ##src/threads/web01.c##
+    printf("end-of-file on %s\n", fptr->f_name);## 79 ##src/threads/web01.c##
+    Close(fd);## 80 ##src/threads/web01.c##
+    fptr->f_flags = F_DONE;     /* clears F_READING */## 81 ##src/threads/web01.c##
+
+    return (fptr);              /* terminate thread */## 82 ##src/threads/web01.c##
+}## 83 ##src/threads/web01.c##
+/* end do_get_read */
+
+/* include write_get_cmd */
+void## 84 ##src/threads/web01.c##
+write_get_cmd(struct file *fptr)## 85 ##src/threads/web01.c##
+{## 86 ##src/threads/web01.c##
+    int     n;## 87 ##src/threads/web01.c##
+    char    line[MAXLINE];## 88 ##src/threads/web01.c##
+
+    n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name);## 89 ##src/threads/web01.c##
+    Writen(fptr->f_fd, line, n);## 90 ##src/threads/web01.c##
+    printf("wrote %d bytes for %s\n", n, fptr->f_name);## 91 ##src/threads/web01.c##
+
+    fptr->f_flags = F_READING;  /* clears F_CONNECTING */## 92 ##src/threads/web01.c##
+}## 93 ##src/threads/web01.c##
+/* end write_get_cmd */
+
+/* include home_page */
+void## 94 ##src/threads/web01.c##
+home_page(const char *host, const char *fname)## 95 ##src/threads/web01.c##
+{## 96 ##src/threads/web01.c##
+    int     fd, n;## 97 ##src/threads/web01.c##
+    char    line[MAXLINE];## 98 ##src/threads/web01.c##
+
+    fd = Tcp_connect(host, SERV);   /* blocking connect() */## 99 ##src/threads/web01.c##
+
+    n = snprintf(line, sizeof(line), GET_CMD, fname);##100 ##src/threads/web01.c##
+    Writen(fd, line, n);##101 ##src/threads/web01.c##
+
+    for (;;) {##102 ##src/threads/web01.c##
+        if ((n = Read(fd, line, MAXLINE)) == 0)##103 ##src/threads/web01.c##
+            break;              /* server closed connection */##104 ##src/threads/web01.c##
+
+        printf("read %d bytes of home page\n", n);##105 ##src/threads/web01.c##
+        /* do whatever with data */##106 ##src/threads/web01.c##
+    }##107 ##src/threads/web01.c##
+    printf("end-of-file on home page\n");##108 ##src/threads/web01.c##
+    Close(fd);##109 ##src/threads/web01.c##
+}##110 ##src/threads/web01.c##
+/* end home_page */
diff --git a/threads/web02.c b/threads/web02.c
new file mode 100644 (file)
index 0000000..cb7d7ba
--- /dev/null
@@ -0,0 +1,184 @@
+/* Doesn't work right.  Main thread sucks up all the CPU time polling unless
+   we call thr_yield(). */
+#include       "unpthread.h"
+#include       <thread.h>              /* Solaris threads */
+
+#define        MAXFILES        20
+#define        SERV            "80"    /* port number or service name */
+
+struct file {
+  char *f_name;                        /* filename */
+  char *f_host;                        /* hostname or IP address */
+  int    f_fd;                         /* descriptor */
+  int   f_flags;                       /* F_xxx below */
+  pthread_t     f_tid;                 /* thread ID */
+} file[MAXFILES];
+#define        F_CONNECTING    1       /* connect() in progress */
+#define        F_READING               2       /* connect() complete; now reading */
+#define        F_DONE                  4       /* all done */
+#define        F_JOINED                8       /* main has pthread_join'ed */
+
+int            nconn, nfiles, nlefttoconn, nlefttoread;
+char   get[] = "GET / HTTP/1.0\r\n\r\n";       /* for home page */
+
+int                            ndone;          /* number of terminated threads & mutex */
+pthread_mutex_t        ndone_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void   *do_get_read(void *);
+void   home_page(const char *, const char *);
+void   write_get_cmd(struct file *);
+
+int
+main(int argc, char **argv)
+{
+       int                     i, n, maxnconn;
+       pthread_t       tid;
+       struct file     *fptr;
+
+       if (argc < 5)
+               err_quit("usage: web <#conns> <IPaddr> <homepage> file1 ...");
+       maxnconn = atoi(argv[1]);
+
+       nfiles = min(argc - 4, MAXFILES);
+       for (i = 0; i < nfiles; i++) {
+               file[i].f_name = argv[i + 4];
+               file[i].f_host = argv[2];
+               file[i].f_flags = 0;
+       }
+       printf("nfiles = %d\n", nfiles);
+
+       home_page(argv[2], argv[3]);
+
+       nlefttoread = nlefttoconn = nfiles;
+       nconn = 0;
+       while (nlefttoread > 0) {
+/* printf("nconn = %d, nlefttoconn = %d\n", nconn, nlefttoconn); */
+               while (nconn < maxnconn && nlefttoconn > 0) {
+                               /* find a file to read */
+                       for (i = 0 ; i < nfiles; i++)
+                               if (file[i].f_flags == 0)
+                                       break;
+                       if (i == nfiles)
+                               err_quit("nlefttoconn = %d but nothing found", nlefttoconn);
+
+                       if ( (n = pthread_create(&tid, NULL, &do_get_read, &file[i])) != 0)
+                               errno = n, err_sys("pthread_create error");
+printf("created thread %d\n", tid);
+                       file[i].f_tid = tid;
+                       file[i].f_flags = F_CONNECTING;
+                       nconn++;
+                       nlefttoconn--;
+               }
+thr_yield();
+
+                       /* See if one of the threads is done */
+               if ( (n = pthread_mutex_lock(&ndone_mutex)) != 0)
+                       errno = n, err_sys("pthread_mutex_lock error");
+               if (ndone > 0) {
+                       for (i = 0; i < nfiles; i++) {
+                               if (file[i].f_flags & F_DONE) {
+                                       if ( (n = pthread_join(file[i].f_tid, (void **) &fptr)) != 0)
+                                               errno = n, err_sys("pthread_join error");
+               
+                                       if (&file[i] != fptr)
+                                               err_quit("file[i] != fptr");
+                                       fptr->f_flags = F_JOINED;       /* clears F_DONE */
+                                       ndone--;
+                                       nconn--;
+                                       nlefttoread--;
+                                       printf("thread id %d for %s done\n",
+                                                       file[i].f_tid, fptr->f_name);
+                               }
+                       }
+               }
+               if ( (n = pthread_mutex_unlock(&ndone_mutex)) != 0)
+                       errno = n, err_sys("pthread_mutex_unlock error");
+       }
+
+       exit(0);
+}
+
+void *
+do_get_read(void *vptr)
+{
+       int                                     fd, n;
+       char                            line[MAXLINE];
+       struct file                     *fptr;
+
+       fptr = (struct file *) vptr;
+
+       fd = Tcp_connect(fptr->f_host, SERV);
+       fptr->f_fd = fd;
+       printf("do_get_read for %s, fd %d, thread %d\n",
+                       fptr->f_name, fd, fptr->f_tid);
+
+       write_get_cmd(fptr);    /* write() the GET command */
+
+               /* Read server's reply */
+       for ( ; ; ) {
+               if ( (n = read(fd, line, MAXLINE)) <= 0) {
+                       if (n == 0)
+                               break;          /* server closed connection */
+                       else
+                               err_sys("read error");
+               }
+               printf("read %d bytes from %s\n", n, fptr->f_name);
+       }
+       printf("end-of-file on %s\n", fptr->f_name);
+       close(fd);
+       fptr->f_flags = F_DONE;         /* clears F_READING */
+
+       if ( (n = pthread_mutex_lock(&ndone_mutex)) != 0)
+               errno = n, err_sys("pthread_mutex_lock error");
+       ndone++;
+       if ( (n = pthread_mutex_unlock(&ndone_mutex)) != 0)
+               errno = n, err_sys("pthread_mutex_unlock error");
+
+       return(fptr);           /* terminate thread */
+}
+
+void
+write_get_cmd(struct file *fptr)
+{
+       int             n;
+       char    line[MAXLINE];
+
+       strcpy(line, "GET ");
+       strcat(line, fptr->f_name);
+       strcat(line, " HTTP/1.0\r\n\r\n");
+       n = strlen(line);
+       if (writen(fptr->f_fd, line, n) != n)
+               err_sys("writen error");
+       printf("wrote %d bytes for %s\n", n, fptr->f_name);
+
+       fptr->f_flags = F_READING;                      /* clears F_CONNECTING */
+}
+
+void
+home_page(const char *host, const char *fname)
+{
+       int                                     fd, n;
+       char                            line[MAXLINE];
+
+       fd = Tcp_connect(host, SERV);
+
+       strcpy(line, "GET ");
+       strcat(line, fname);
+       strcat(line, " HTTP/1.0\r\n\r\n");
+       n = strlen(line);
+       if (writen(fd, line, n) != n)
+               err_sys("writen error");
+
+       for ( ; ; ) {
+               if ( (n = read(fd, line, MAXLINE)) <= 0) {
+                       if (n == 0)
+                               break;          /* server closed connection */
+                       else
+                               err_sys("read error");
+               }
+               printf("read %d bytes of home page\n", n);
+               /* do whatever with data */
+       }
+       printf("end-of-file on home page\n");
+       close(fd);
+}
diff --git a/threads/web03.c b/threads/web03.c
new file mode 100644 (file)
index 0000000..ee87391
--- /dev/null
@@ -0,0 +1,164 @@
+#include       "unpthread.h"
+#include       <thread.h>              /* Solaris threads */
+
+#define        MAXFILES        20
+#define        SERV            "80"    /* port number or service name */
+
+struct file {
+  char *f_name;                        /* filename */
+  char *f_host;                        /* hostname or IP address */
+  int    f_fd;                         /* descriptor */
+  int   f_flags;                       /* F_xxx below */
+  pthread_t     f_tid;                 /* thread ID */
+} file[MAXFILES];
+#define        F_CONNECTING    1       /* connect() in progress */
+#define        F_READING               2       /* connect() complete; now reading */
+#define        F_DONE                  4       /* all done */
+#define        F_JOINED                8       /* main has pthread_join'ed */
+
+#define        GET_CMD         "GET %s HTTP/1.0\r\n\r\n"
+
+int            nconn, nfiles, nlefttoconn, nlefttoread;
+
+int                            ndone;          /* number of terminated threads */
+pthread_mutex_t        ndone_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t ndone_cond = PTHREAD_COND_INITIALIZER;
+
+void   *do_get_read(void *);
+void   home_page(const char *, const char *);
+void   write_get_cmd(struct file *);
+
+int
+main(int argc, char **argv)
+{
+       int                     i, maxnconn;
+       pthread_t       tid;
+       struct file     *fptr;
+
+       if (argc < 5)
+               err_quit("usage: web <#conns> <IPaddr> <homepage> file1 ...");
+       maxnconn = atoi(argv[1]);
+
+       nfiles = min(argc - 4, MAXFILES);
+       for (i = 0; i < nfiles; i++) {
+               file[i].f_name = argv[i + 4];
+               file[i].f_host = argv[2];
+               file[i].f_flags = 0;
+       }
+       printf("nfiles = %d\n", nfiles);
+
+       home_page(argv[2], argv[3]);
+
+       nlefttoread = nlefttoconn = nfiles;
+       nconn = 0;
+/* include web2 */
+       while (nlefttoread > 0) {
+               while (nconn < maxnconn && nlefttoconn > 0) {
+                               /* 4find a file to read */
+                       for (i = 0 ; i < nfiles; i++)
+                               if (file[i].f_flags == 0)
+                                       break;
+                       if (i == nfiles)
+                               err_quit("nlefttoconn = %d but nothing found", nlefttoconn);
+
+                       file[i].f_flags = F_CONNECTING;
+                       Pthread_create(&tid, NULL, &do_get_read, &file[i]);
+                       file[i].f_tid = tid;
+                       nconn++;
+                       nlefttoconn--;
+               }
+
+                       /* 4Wait for thread to terminate */
+               Pthread_mutex_lock(&ndone_mutex);
+               while (ndone == 0)
+                       Pthread_cond_wait(&ndone_cond, &ndone_mutex);
+
+               for (i = 0; i < nfiles; i++) {
+                       if (file[i].f_flags & F_DONE) {
+                               Pthread_join(file[i].f_tid, (void **) &fptr);
+
+                               if (&file[i] != fptr)
+                                       err_quit("file[i] != fptr");
+                               fptr->f_flags = F_JOINED;       /* clears F_DONE */
+                               ndone--;
+                               nconn--;
+                               nlefttoread--;
+                               printf("thread %d for %s done\n", fptr->f_tid, fptr->f_name);
+                       }
+               }
+               Pthread_mutex_unlock(&ndone_mutex);
+       }
+
+       exit(0);
+}
+/* end web2 */
+
+void *
+do_get_read(void *vptr)
+{
+       int                                     fd, n;
+       char                            line[MAXLINE];
+       struct file                     *fptr;
+
+       fptr = (struct file *) vptr;
+
+       fd = Tcp_connect(fptr->f_host, SERV);
+       fptr->f_fd = fd;
+       printf("do_get_read for %s, fd %d, thread %d\n",
+                       fptr->f_name, fd, fptr->f_tid);
+
+       write_get_cmd(fptr);    /* write() the GET command */
+
+               /* 4Read server's reply */
+       for ( ; ; ) {
+               if ( (n = Read(fd, line, MAXLINE)) == 0)
+                       break;          /* server closed connection */
+
+               printf("read %d bytes from %s\n", n, fptr->f_name);
+       }
+       printf("end-of-file on %s\n", fptr->f_name);
+       Close(fd);
+       fptr->f_flags = F_DONE;         /* clears F_READING */
+
+       Pthread_mutex_lock(&ndone_mutex);
+       ndone++;
+       Pthread_cond_signal(&ndone_cond);
+       Pthread_mutex_unlock(&ndone_mutex);
+
+       return(fptr);           /* terminate thread */
+}
+
+void
+write_get_cmd(struct file *fptr)
+{
+       int             n;
+       char    line[MAXLINE];
+
+       n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name);
+       Writen(fptr->f_fd, line, n);
+       printf("wrote %d bytes for %s\n", n, fptr->f_name);
+
+       fptr->f_flags = F_READING;                      /* clears F_CONNECTING */
+}
+
+void
+home_page(const char *host, const char *fname)
+{
+       int             fd, n;
+       char    line[MAXLINE];
+
+       fd = Tcp_connect(host, SERV);   /* blocking connect() */
+
+       n = snprintf(line, sizeof(line), GET_CMD, fname);
+       Writen(fd, line, n);
+
+       for ( ; ; ) {
+               if ( (n = Read(fd, line, MAXLINE)) == 0)
+                       break;          /* server closed connection */
+
+               printf("read %d bytes of home page\n", n);
+               /* do whatever with data */
+       }
+       printf("end-of-file on home page\n");
+       Close(fd);
+}
diff --git a/threads/web03.lc b/threads/web03.lc
new file mode 100644 (file)
index 0000000..6b260b2
--- /dev/null
@@ -0,0 +1,164 @@
+#include    "unpthread.h"##  1 ##src/threads/web03.c##
+#include    <thread.h>          /* Solaris threads */##  2 ##src/threads/web03.c##
+
+#define MAXFILES    20##  3 ##src/threads/web03.c##
+#define SERV        "80"        /* port number or service name */##  4 ##src/threads/web03.c##
+
+struct file {##  5 ##src/threads/web03.c##
+    char   *f_name;             /* filename */##  6 ##src/threads/web03.c##
+    char   *f_host;             /* hostname or IP address */##  7 ##src/threads/web03.c##
+    int     f_fd;               /* descriptor */##  8 ##src/threads/web03.c##
+    int     f_flags;            /* F_xxx below */##  9 ##src/threads/web03.c##
+    pthread_t f_tid;            /* thread ID */## 10 ##src/threads/web03.c##
+} file[MAXFILES];## 11 ##src/threads/web03.c##
+#define F_CONNECTING    1       /* connect() in progress */## 12 ##src/threads/web03.c##
+#define F_READING       2       /* connect() complete; now reading */## 13 ##src/threads/web03.c##
+#define F_DONE          4       /* all done */## 14 ##src/threads/web03.c##
+#define F_JOINED        8       /* main has pthread_join'ed */## 15 ##src/threads/web03.c##
+
+#define GET_CMD     "GET %s HTTP/1.0\r\n\r\n"## 16 ##src/threads/web03.c##
+
+int     nconn, nfiles, nlefttoconn, nlefttoread;## 17 ##src/threads/web03.c##
+
+int     ndone;                  /* number of terminated threads */## 18 ##src/threads/web03.c##
+pthread_mutex_t ndone_mutex = PTHREAD_MUTEX_INITIALIZER;## 19 ##src/threads/web03.c##
+pthread_cond_t ndone_cond = PTHREAD_COND_INITIALIZER;## 20 ##src/threads/web03.c##
+
+void   *do_get_read(void *);## 21 ##src/threads/web03.c##
+void    home_page(const char *, const char *);## 22 ##src/threads/web03.c##
+void    write_get_cmd(struct file *);## 23 ##src/threads/web03.c##
+
+int## 24 ##src/threads/web03.c##
+main(int argc, char **argv)## 25 ##src/threads/web03.c##
+{## 26 ##src/threads/web03.c##
+    int     i, maxnconn;## 27 ##src/threads/web03.c##
+    pthread_t tid;## 28 ##src/threads/web03.c##
+    struct file *fptr;## 29 ##src/threads/web03.c##
+
+    if (argc < 5)## 30 ##src/threads/web03.c##
+        err_quit("usage: web <#conns> <IPaddr> <homepage> file1 ...");## 31 ##src/threads/web03.c##
+    maxnconn = atoi(argv[1]);## 32 ##src/threads/web03.c##
+
+    nfiles = min(argc - 4, MAXFILES);## 33 ##src/threads/web03.c##
+    for (i = 0; i < nfiles; i++) {## 34 ##src/threads/web03.c##
+        file[i].f_name = argv[i + 4];## 35 ##src/threads/web03.c##
+        file[i].f_host = argv[2];## 36 ##src/threads/web03.c##
+        file[i].f_flags = 0;## 37 ##src/threads/web03.c##
+    }## 38 ##src/threads/web03.c##
+    printf("nfiles = %d\n", nfiles);## 39 ##src/threads/web03.c##
+
+    home_page(argv[2], argv[3]);## 40 ##src/threads/web03.c##
+
+    nlefttoread = nlefttoconn = nfiles;## 41 ##src/threads/web03.c##
+    nconn = 0;## 42 ##src/threads/web03.c##
+/* include web2 */
+    while (nlefttoread > 0) {## 43 ##src/threads/web03.c##
+        while (nconn < maxnconn && nlefttoconn > 0) {## 44 ##src/threads/web03.c##
+            /* 4find a file to read */## 45 ##src/threads/web03.c##
+            for (i = 0; i < nfiles; i++)## 46 ##src/threads/web03.c##
+                if (file[i].f_flags == 0)## 47 ##src/threads/web03.c##
+                    break;## 48 ##src/threads/web03.c##
+            if (i == nfiles)## 49 ##src/threads/web03.c##
+                err_quit("nlefttoconn = %d but nothing found", nlefttoconn);## 50 ##src/threads/web03.c##
+
+            file[i].f_flags = F_CONNECTING;## 51 ##src/threads/web03.c##
+            Pthread_create(&tid, NULL, &do_get_read, &file[i]);## 52 ##src/threads/web03.c##
+            file[i].f_tid = tid;## 53 ##src/threads/web03.c##
+            nconn++;## 54 ##src/threads/web03.c##
+            nlefttoconn--;## 55 ##src/threads/web03.c##
+        }## 56 ##src/threads/web03.c##
+
+        /* 4Wait for one of the threads to terminate */## 57 ##src/threads/web03.c##
+        Pthread_mutex_lock(&ndone_mutex);## 58 ##src/threads/web03.c##
+        while (ndone == 0)## 59 ##src/threads/web03.c##
+            Pthread_cond_wait(&ndone_cond, &ndone_mutex);## 60 ##src/threads/web03.c##
+
+        for (i = 0; i < nfiles; i++) {## 61 ##src/threads/web03.c##
+            if (file[i].f_flags & F_DONE) {## 62 ##src/threads/web03.c##
+                Pthread_join(file[i].f_tid, (void **) &fptr);## 63 ##src/threads/web03.c##
+
+                if (&file[i] != fptr)## 64 ##src/threads/web03.c##
+                    err_quit("file[i] != fptr");## 65 ##src/threads/web03.c##
+                fptr->f_flags = F_JOINED;   /* clears F_DONE */## 66 ##src/threads/web03.c##
+                ndone--;## 67 ##src/threads/web03.c##
+                nconn--;## 68 ##src/threads/web03.c##
+                nlefttoread--;## 69 ##src/threads/web03.c##
+                printf("thread %d for %s done\n", fptr->f_tid, fptr->f_name);## 70 ##src/threads/web03.c##
+            }## 71 ##src/threads/web03.c##
+        }## 72 ##src/threads/web03.c##
+        Pthread_mutex_unlock(&ndone_mutex);## 73 ##src/threads/web03.c##
+    }## 74 ##src/threads/web03.c##
+
+    exit(0);## 75 ##src/threads/web03.c##
+}## 76 ##src/threads/web03.c##
+/* end web2 */
+
+void   *## 77 ##src/threads/web03.c##
+do_get_read(void *vptr)## 78 ##src/threads/web03.c##
+{## 79 ##src/threads/web03.c##
+    int     fd, n;## 80 ##src/threads/web03.c##
+    char    line[MAXLINE];## 81 ##src/threads/web03.c##
+    struct file *fptr;## 82 ##src/threads/web03.c##
+
+    fptr = (struct file *) vptr;## 83 ##src/threads/web03.c##
+
+    fd = Tcp_connect(fptr->f_host, SERV);## 84 ##src/threads/web03.c##
+    fptr->f_fd = fd;## 85 ##src/threads/web03.c##
+    printf("do_get_read for %s, fd %d, thread %d\n",## 86 ##src/threads/web03.c##
+           fptr->f_name, fd, fptr->f_tid);## 87 ##src/threads/web03.c##
+
+    write_get_cmd(fptr);        /* write() the GET command */## 88 ##src/threads/web03.c##
+
+    /* 4Read server's reply */## 89 ##src/threads/web03.c##
+    for (;;) {## 90 ##src/threads/web03.c##
+        if ((n = Read(fd, line, MAXLINE)) == 0)## 91 ##src/threads/web03.c##
+            break;              /* server closed connection */## 92 ##src/threads/web03.c##
+
+        printf("read %d bytes from %s\n", n, fptr->f_name);## 93 ##src/threads/web03.c##
+    }## 94 ##src/threads/web03.c##
+    printf("end-of-file on %s\n", fptr->f_name);## 95 ##src/threads/web03.c##
+    Close(fd);## 96 ##src/threads/web03.c##
+    fptr->f_flags = F_DONE;     /* clears F_READING */## 97 ##src/threads/web03.c##
+
+    Pthread_mutex_lock(&ndone_mutex);## 98 ##src/threads/web03.c##
+    ndone++;## 99 ##src/threads/web03.c##
+    Pthread_cond_signal(&ndone_cond);##100 ##src/threads/web03.c##
+    Pthread_mutex_unlock(&ndone_mutex);##101 ##src/threads/web03.c##
+
+    return (fptr);              /* terminate thread */##102 ##src/threads/web03.c##
+}##103 ##src/threads/web03.c##
+
+void##104 ##src/threads/web03.c##
+write_get_cmd(struct file *fptr)##105 ##src/threads/web03.c##
+{##106 ##src/threads/web03.c##
+    int     n;##107 ##src/threads/web03.c##
+    char    line[MAXLINE];##108 ##src/threads/web03.c##
+
+    n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name);##109 ##src/threads/web03.c##
+    Writen(fptr->f_fd, line, n);##110 ##src/threads/web03.c##
+    printf("wrote %d bytes for %s\n", n, fptr->f_name);##111 ##src/threads/web03.c##
+
+    fptr->f_flags = F_READING;  /* clears F_CONNECTING */##112 ##src/threads/web03.c##
+}##113 ##src/threads/web03.c##
+
+void##114 ##src/threads/web03.c##
+home_page(const char *host, const char *fname)##115 ##src/threads/web03.c##
+{##116 ##src/threads/web03.c##
+    int     fd, n;##117 ##src/threads/web03.c##
+    char    line[MAXLINE];##118 ##src/threads/web03.c##
+
+    fd = Tcp_connect(host, SERV);   /* blocking connect() */##119 ##src/threads/web03.c##
+
+    n = snprintf(line, sizeof(line), GET_CMD, fname);##120 ##src/threads/web03.c##
+    Writen(fd, line, n);##121 ##src/threads/web03.c##
+
+    for (;;) {##122 ##src/threads/web03.c##
+        if ((n = Read(fd, line, MAXLINE)) == 0)##123 ##src/threads/web03.c##
+            break;              /* server closed connection */##124 ##src/threads/web03.c##
+
+        printf("read %d bytes of home page\n", n);##125 ##src/threads/web03.c##
+        /* do whatever with data */##126 ##src/threads/web03.c##
+    }##127 ##src/threads/web03.c##
+    printf("end-of-file on home page\n");##128 ##src/threads/web03.c##
+    Close(fd);##129 ##src/threads/web03.c##
+}##130 ##src/threads/web03.c##
diff --git a/traceroute/Makefile b/traceroute/Makefile
new file mode 100644 (file)
index 0000000..348c627
--- /dev/null
@@ -0,0 +1,13 @@
+include ../Make.defines
+
+OBJS = main.o icmpcode_v4.o icmpcode_v6.o recv_v4.o recv_v6.o \
+               sig_alrm.o traceloop.o tv_sub.o
+PROGS =        traceroute
+
+all:   ${PROGS}
+
+traceroute:    ${OBJS}
+               ${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/traceroute/icmpcode_v4.c b/traceroute/icmpcode_v4.c
new file mode 100644 (file)
index 0000000..27dde74
--- /dev/null
@@ -0,0 +1,27 @@
+#include       "trace.h"
+
+const char *
+icmpcode_v4(int code)
+{
+       static char errbuf[100];
+       switch (code) {
+       case  0:        return("network unreachable");
+       case  1:        return("host unreachable");
+       case  2:        return("protocol unreachable");
+       case  3:        return("port unreachable");
+       case  4:        return("fragmentation required but DF bit set");
+       case  5:        return("source route failed");
+       case  6:        return("destination network unknown");
+       case  7:        return("destination host unknown");
+       case  8:        return("source host isolated (obsolete)");
+       case  9:        return("destination network administratively prohibited");
+       case 10:        return("destination host administratively prohibited");
+       case 11:        return("network unreachable for TOS");
+       case 12:        return("host unreachable for TOS");
+       case 13:        return("communication administratively prohibited by filtering");
+       case 14:        return("host recedence violation");
+       case 15:        return("precedence cutoff in effect");
+       default:        sprintf(errbuf, "[unknown code %d]", code);
+                               return errbuf;
+       }
+}
diff --git a/traceroute/icmpcode_v6.c b/traceroute/icmpcode_v6.c
new file mode 100644 (file)
index 0000000..a42cdbc
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "trace.h"
+
+const char *
+icmpcode_v6(int code)
+{
+#ifdef IPV6
+       static char errbuf[100];
+       switch (code) {
+       case  ICMP6_DST_UNREACH_NOROUTE:
+               return("no route to host");
+       case  ICMP6_DST_UNREACH_ADMIN:
+               return("administratively prohibited");
+       case  ICMP6_DST_UNREACH_NOTNEIGHBOR:
+               return("not a neighbor");
+       case  ICMP6_DST_UNREACH_ADDR:
+               return("address unreachable");
+       case  ICMP6_DST_UNREACH_NOPORT:
+               return("port unreachable");
+       default:
+               sprintf(errbuf, "[unknown code %d]", code);
+               return errbuf;
+       }
+#endif
+}
diff --git a/traceroute/main.c b/traceroute/main.c
new file mode 100644 (file)
index 0000000..2ddecde
--- /dev/null
@@ -0,0 +1,75 @@
+#include       "trace.h"
+
+struct proto   proto_v4 = { icmpcode_v4, recv_v4, NULL, NULL, NULL, NULL, 0,
+                                                        IPPROTO_ICMP, IPPROTO_IP, IP_TTL };
+
+#ifdef IPV6
+struct proto   proto_v6 = { icmpcode_v6, recv_v6, NULL, NULL, NULL, NULL, 0,
+                                                        IPPROTO_ICMPV6, IPPROTO_IPV6, IPV6_UNICAST_HOPS };
+#endif
+
+int            datalen = sizeof(struct rec);   /* defaults */
+int            max_ttl = 30;
+int            nprobes = 3;
+u_short        dport = 32768 + 666;
+
+int
+main(int argc, char **argv)
+{
+       int                             c;
+       struct addrinfo *ai;
+       char *h;
+
+       opterr = 0;             /* don't want getopt() writing to stderr */
+       while ( (c = getopt(argc, argv, "m:v")) != -1) {
+               switch (c) {
+               case 'm':
+                       if ( (max_ttl = atoi(optarg)) <= 1)
+                               err_quit("invalid -m value");
+                       break;
+
+               case 'v':
+                       verbose++;
+                       break;
+
+               case '?':
+                       err_quit("unrecognized option: %c", c);
+               }
+       }
+
+       if (optind != argc-1)
+               err_quit("usage: traceroute [ -m <maxttl> -v ] <hostname>");
+       host = argv[optind];
+
+       pid = getpid();
+       Signal(SIGALRM, sig_alrm);
+
+       ai = Host_serv(host, NULL, 0, 0);
+
+       h = Sock_ntop_host(ai->ai_addr, ai->ai_addrlen);
+       printf("traceroute to %s (%s): %d hops max, %d data bytes\n",
+                  ai->ai_canonname ? ai->ai_canonname : h,
+                  h, max_ttl, datalen);
+
+               /* initialize according to protocol */
+       if (ai->ai_family == AF_INET) {
+               pr = &proto_v4;
+#ifdef IPV6
+       } else if (ai->ai_family == AF_INET6) {
+               pr = &proto_v6;
+               if (IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr)))
+                       err_quit("cannot traceroute IPv4-mapped IPv6 address");
+#endif
+       } else
+               err_quit("unknown address family %d", ai->ai_family);
+
+       pr->sasend = ai->ai_addr;               /* contains destination address */
+       pr->sarecv = Calloc(1, ai->ai_addrlen);
+       pr->salast = Calloc(1, ai->ai_addrlen);
+       pr->sabind = Calloc(1, ai->ai_addrlen);
+       pr->salen = ai->ai_addrlen;
+
+       traceloop();
+
+       exit(0);
+}
diff --git a/traceroute/main.lc b/traceroute/main.lc
new file mode 100644 (file)
index 0000000..518f14f
--- /dev/null
@@ -0,0 +1,76 @@
+#include    "trace.h"##  1 ##src/traceroute/main.c##
+
+struct proto proto_v4 = { icmpcode_v4, recv_v4, NULL, NULL, NULL, NULL, 0,##  2 ##src/traceroute/main.c##
+    IPPROTO_ICMP, IPPROTO_IP, IP_TTL##  3 ##src/traceroute/main.c##
+};##  4 ##src/traceroute/main.c##
+
+#ifdef  IPV6##  5 ##src/traceroute/main.c##
+struct proto proto_v6 = { icmpcode_v6, recv_v6, NULL, NULL, NULL, NULL, 0,##  6 ##src/traceroute/main.c##
+    IPPROTO_ICMPV6, IPPROTO_IPV6, IPV6_UNICAST_HOPS##  7 ##src/traceroute/main.c##
+};##  8 ##src/traceroute/main.c##
+#endif##  9 ##src/traceroute/main.c##
+
+int     datalen = sizeof(struct rec);   /* defaults */## 10 ##src/traceroute/main.c##
+int     max_ttl = 30;## 11 ##src/traceroute/main.c##
+int     nprobes = 3;## 12 ##src/traceroute/main.c##
+u_short dport = 32768 + 666;## 13 ##src/traceroute/main.c##
+
+int## 14 ##src/traceroute/main.c##
+main(int argc, char **argv)## 15 ##src/traceroute/main.c##
+{## 16 ##src/traceroute/main.c##
+    int     c;## 17 ##src/traceroute/main.c##
+    struct addrinfo *ai;## 18 ##src/traceroute/main.c##
+
+    opterr = 0;                 /* don't want getopt() writing to stderr */## 19 ##src/traceroute/main.c##
+    while ((c = getopt(argc, argv, "m:v")) != -1) {## 20 ##src/traceroute/main.c##
+        switch (c) {## 21 ##src/traceroute/main.c##
+        case 'm':## 22 ##src/traceroute/main.c##
+            if ((max_ttl = atoi(optarg)) <= 1)## 23 ##src/traceroute/main.c##
+                err_quit("invalid -m value");## 24 ##src/traceroute/main.c##
+            break;## 25 ##src/traceroute/main.c##
+
+        case 'v':## 26 ##src/traceroute/main.c##
+            verbose++;## 27 ##src/traceroute/main.c##
+            break;## 28 ##src/traceroute/main.c##
+
+        case '?':## 29 ##src/traceroute/main.c##
+            err_quit("unrecognized option: %c", c);## 30 ##src/traceroute/main.c##
+        }## 31 ##src/traceroute/main.c##
+    }## 32 ##src/traceroute/main.c##
+
+    if (optind != argc - 1)## 33 ##src/traceroute/main.c##
+        err_quit("usage: traceroute [ -m <maxttl> -v ] <hostname>");## 34 ##src/traceroute/main.c##
+    host = argv[optind];## 35 ##src/traceroute/main.c##
+
+    pid = getpid();## 36 ##src/traceroute/main.c##
+    Signal(SIGALRM, sig_alrm);## 37 ##src/traceroute/main.c##
+
+    ai = Host_serv(host, NULL, 0, 0);## 38 ##src/traceroute/main.c##
+
+    printf("traceroute to %s (%s): %d hops max, %d data bytes\n",## 39 ##src/traceroute/main.c##
+           ai->ai_canonname,## 40 ##src/traceroute/main.c##
+           Sock_ntop_host(ai->ai_addr, ai->ai_addrlen), max_ttl, datalen);## 41 ##src/traceroute/main.c##
+
+    /* initialize according to protocol */## 42 ##src/traceroute/main.c##
+    if (ai->ai_family == AF_INET) {## 43 ##src/traceroute/main.c##
+        pr = &proto_v4;## 44 ##src/traceroute/main.c##
+#ifdef  IPV6## 45 ##src/traceroute/main.c##
+    } else if (ai->ai_family == AF_INET6) {## 46 ##src/traceroute/main.c##
+        pr = &proto_v6;## 47 ##src/traceroute/main.c##
+        if (IN6_IS_ADDR_V4MAPPED## 48 ##src/traceroute/main.c##
+            (&(((struct sockaddr_in6 *) ai->ai_addr)->sin6_addr)))## 49 ##src/traceroute/main.c##
+            err_quit("cannot traceroute IPv4-mapped IPv6 address");## 50 ##src/traceroute/main.c##
+#endif## 51 ##src/traceroute/main.c##
+    } else## 52 ##src/traceroute/main.c##
+        err_quit("unknown address family %d", ai->ai_family);## 53 ##src/traceroute/main.c##
+
+    pr->sasend = ai->ai_addr;   /* contains destination address */## 54 ##src/traceroute/main.c##
+    pr->sarecv = Calloc(1, ai->ai_addrlen);## 55 ##src/traceroute/main.c##
+    pr->salast = Calloc(1, ai->ai_addrlen);## 56 ##src/traceroute/main.c##
+    pr->sabind = Calloc(1, ai->ai_addrlen);## 57 ##src/traceroute/main.c##
+    pr->salen = ai->ai_addrlen;## 58 ##src/traceroute/main.c##
+
+    traceloop();## 59 ##src/traceroute/main.c##
+
+    exit(0);## 60 ##src/traceroute/main.c##
+}## 61 ##src/traceroute/main.c##
diff --git a/traceroute/recv_v4.c b/traceroute/recv_v4.c
new file mode 100644 (file)
index 0000000..e7ec19c
--- /dev/null
@@ -0,0 +1,91 @@
+#include       "trace.h"
+
+extern int gotalarm;
+
+/*
+ * Return: -3 on timeout
+ *                -2 on ICMP time exceeded in transit (caller keeps going)
+ *                -1 on ICMP port unreachable (caller is done)
+ *              >= 0 return value is some other ICMP unreachable code
+ */
+
+int
+recv_v4(int seq, struct timeval *tv)
+{
+       int                             hlen1, hlen2, icmplen, ret;
+       socklen_t               len;
+       ssize_t                 n;
+       struct ip               *ip, *hip;
+       struct icmp             *icmp;
+       struct udphdr   *udp;
+
+       gotalarm = 0;
+       alarm(3);
+       for ( ; ; ) {
+               if (gotalarm)
+                       return(-3);             /* alarm expired */
+               len = pr->salen;
+               n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len);
+               if (n < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       else
+                               err_sys("recvfrom error");
+               }
+
+               ip = (struct ip *) recvbuf;     /* start of IP header */
+               hlen1 = ip->ip_hl << 2;         /* length of IP header */
+       
+               icmp = (struct icmp *) (recvbuf + hlen1); /* start of ICMP header */
+               if ( (icmplen = n - hlen1) < 8)
+                       continue;                               /* not enough to look at ICMP header */
+       
+               if (icmp->icmp_type == ICMP_TIMXCEED &&
+                       icmp->icmp_code == ICMP_TIMXCEED_INTRANS) {
+                       if (icmplen < 8 + sizeof(struct ip))
+                               continue;                       /* not enough data to look at inner IP */
+
+                       hip = (struct ip *) (recvbuf + hlen1 + 8);
+                       hlen2 = hip->ip_hl << 2;
+                       if (icmplen < 8 + hlen2 + 4)
+                               continue;                       /* not enough data to look at UDP ports */
+
+                       udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2);
+                       if (hip->ip_p == IPPROTO_UDP &&
+                               udp->uh_sport == htons(sport) &&
+                               udp->uh_dport == htons(dport + seq)) {
+                               ret = -2;               /* we hit an intermediate router */
+                               break;
+                       }
+
+               } else if (icmp->icmp_type == ICMP_UNREACH) {
+                       if (icmplen < 8 + sizeof(struct ip))
+                               continue;                       /* not enough data to look at inner IP */
+
+                       hip = (struct ip *) (recvbuf + hlen1 + 8);
+                       hlen2 = hip->ip_hl << 2;
+                       if (icmplen < 8 + hlen2 + 4)
+                               continue;                       /* not enough data to look at UDP ports */
+
+                       udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2);
+                       if (hip->ip_p == IPPROTO_UDP &&
+                               udp->uh_sport == htons(sport) &&
+                               udp->uh_dport == htons(dport + seq)) {
+                               if (icmp->icmp_code == ICMP_UNREACH_PORT)
+                                       ret = -1;       /* have reached destination */
+                               else
+                                       ret = icmp->icmp_code;  /* 0, 1, 2, ... */
+                               break;
+                       }
+               }
+               if (verbose) {
+                       printf(" (from %s: type = %d, code = %d)\n",
+                                       Sock_ntop_host(pr->sarecv, pr->salen),
+                                       icmp->icmp_type, icmp->icmp_code);
+               }
+               /* Some other ICMP error, recvfrom() again */
+       }
+       alarm(0);                                       /* don't leave alarm running */
+       Gettimeofday(tv, NULL);         /* get time of packet arrival */
+       return(ret);
+}
diff --git a/traceroute/recv_v4.lc b/traceroute/recv_v4.lc
new file mode 100644 (file)
index 0000000..461ecb5
--- /dev/null
@@ -0,0 +1,74 @@
+#include    "trace.h"##  1 ##src/traceroute/recv_v4.c##
+
+/*##  2 ##src/traceroute/recv_v4.c##
+ * Return: -3 on timeout##  3 ##src/traceroute/recv_v4.c##
+ *         -2 on ICMP time exceeded in transit (caller keeps going)##  4 ##src/traceroute/recv_v4.c##
+ *         -1 on ICMP port unreachable (caller is done)##  5 ##src/traceroute/recv_v4.c##
+ *       >= 0 return value is some other ICMP unreachable code##  6 ##src/traceroute/recv_v4.c##
+ */##  7 ##src/traceroute/recv_v4.c##
+
+int##  8 ##src/traceroute/recv_v4.c##
+recv_v4(int seq, struct timeval *tv)##  9 ##src/traceroute/recv_v4.c##
+{## 10 ##src/traceroute/recv_v4.c##
+    int     hlen1, hlen2, icmplen;## 11 ##src/traceroute/recv_v4.c##
+    socklen_t len;## 12 ##src/traceroute/recv_v4.c##
+    ssize_t n;## 13 ##src/traceroute/recv_v4.c##
+    struct ip *ip, *hip;## 14 ##src/traceroute/recv_v4.c##
+    struct icmp *icmp;## 15 ##src/traceroute/recv_v4.c##
+    struct udphdr *udp;## 16 ##src/traceroute/recv_v4.c##
+
+    alarm(3);## 17 ##src/traceroute/recv_v4.c##
+    for (;;) {## 18 ##src/traceroute/recv_v4.c##
+        len = pr->salen;## 19 ##src/traceroute/recv_v4.c##
+        n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len);## 20 ##src/traceroute/recv_v4.c##
+        if (n < 0) {## 21 ##src/traceroute/recv_v4.c##
+            if (errno == EINTR)## 22 ##src/traceroute/recv_v4.c##
+                return (-3);    /* alarm expired */## 23 ##src/traceroute/recv_v4.c##
+            else## 24 ##src/traceroute/recv_v4.c##
+                err_sys("recvfrom error");## 25 ##src/traceroute/recv_v4.c##
+        }## 26 ##src/traceroute/recv_v4.c##
+        Gettimeofday(tv, NULL); /* get time of packet arrival */## 27 ##src/traceroute/recv_v4.c##
+
+        ip = (struct ip *) recvbuf; /* start of IP header */## 28 ##src/traceroute/recv_v4.c##
+        hlen1 = ip->ip_hl << 2; /* length of IP header */## 29 ##src/traceroute/recv_v4.c##
+
+        icmp = (struct icmp *) (recvbuf + hlen1);   /* start of ICMP header */## 30 ##src/traceroute/recv_v4.c##
+        if ((icmplen = n - hlen1) < 8)## 31 ##src/traceroute/recv_v4.c##
+            err_quit("icmplen (%d) < 8", icmplen);## 32 ##src/traceroute/recv_v4.c##
+
+        if (icmp->icmp_type == ICMP_TIMXCEED &&## 33 ##src/traceroute/recv_v4.c##
+            icmp->icmp_code == ICMP_TIMXCEED_INTRANS) {## 34 ##src/traceroute/recv_v4.c##
+            if (icmplen < 8 + 20 + 8)## 35 ##src/traceroute/recv_v4.c##
+                err_quit("icmplen (%d) < 8 + 20 + 8", icmplen);## 36 ##src/traceroute/recv_v4.c##
+
+            hip = (struct ip *) (recvbuf + hlen1 + 8);## 37 ##src/traceroute/recv_v4.c##
+            hlen2 = hip->ip_hl << 2;## 38 ##src/traceroute/recv_v4.c##
+            udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2);## 39 ##src/traceroute/recv_v4.c##
+            if (hip->ip_p == IPPROTO_UDP &&## 40 ##src/traceroute/recv_v4.c##
+                udp->uh_sport == htons(sport) &&## 41 ##src/traceroute/recv_v4.c##
+                udp->uh_dport == htons(dport + seq))## 42 ##src/traceroute/recv_v4.c##
+                return (-2);    /* we hit an intermediate router */## 43 ##src/traceroute/recv_v4.c##
+
+        } else if (icmp->icmp_type == ICMP_UNREACH) {## 44 ##src/traceroute/recv_v4.c##
+            if (icmplen < 8 + 20 + 8)## 45 ##src/traceroute/recv_v4.c##
+                err_quit("icmplen (%d) < 8 + 20 + 8", icmplen);## 46 ##src/traceroute/recv_v4.c##
+
+            hip = (struct ip *) (recvbuf + hlen1 + 8);## 47 ##src/traceroute/recv_v4.c##
+            hlen2 = hip->ip_hl << 2;## 48 ##src/traceroute/recv_v4.c##
+            udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2);## 49 ##src/traceroute/recv_v4.c##
+            if (hip->ip_p == IPPROTO_UDP &&## 50 ##src/traceroute/recv_v4.c##
+                udp->uh_sport == htons(sport) &&## 51 ##src/traceroute/recv_v4.c##
+                udp->uh_dport == htons(dport + seq)) {## 52 ##src/traceroute/recv_v4.c##
+                if (icmp->icmp_code == ICMP_UNREACH_PORT)## 53 ##src/traceroute/recv_v4.c##
+                    return (-1);    /* have reached destination */## 54 ##src/traceroute/recv_v4.c##
+                else## 55 ##src/traceroute/recv_v4.c##
+                    return (icmp->icmp_code);   /* 0, 1, 2, ... */## 56 ##src/traceroute/recv_v4.c##
+            }## 57 ##src/traceroute/recv_v4.c##
+        } else if (verbose) {## 58 ##src/traceroute/recv_v4.c##
+            printf(" (from %s: type = %d, code = %d)\n",## 59 ##src/traceroute/recv_v4.c##
+                   Sock_ntop_host(pr->sarecv, pr->salen),## 60 ##src/traceroute/recv_v4.c##
+                   icmp->icmp_type, icmp->icmp_code);## 61 ##src/traceroute/recv_v4.c##
+        }## 62 ##src/traceroute/recv_v4.c##
+        /* Some other ICMP error, recvfrom() again */## 63 ##src/traceroute/recv_v4.c##
+    }## 64 ##src/traceroute/recv_v4.c##
+}## 65 ##src/traceroute/recv_v4.c##
diff --git a/traceroute/recv_v6.c b/traceroute/recv_v6.c
new file mode 100644 (file)
index 0000000..f84011a
--- /dev/null
@@ -0,0 +1,82 @@
+#include       "trace.h"
+
+extern int gotalarm;
+
+/*
+ * Return: -3 on timeout
+ *                -2 on ICMP time exceeded in transit (caller keeps going)
+ *                -1 on ICMP port unreachable (caller is done)
+ *              >= 0 return value is some other ICMP unreachable code
+ */
+
+int
+recv_v6(int seq, struct timeval *tv)
+{
+#ifdef IPV6
+       int                                     hlen2, icmp6len, ret;
+       ssize_t                         n;
+       socklen_t                       len;
+       struct ip6_hdr          *hip6;
+       struct icmp6_hdr        *icmp6;
+       struct udphdr           *udp;
+
+       gotalarm = 0;
+       alarm(3);
+       for ( ; ; ) {
+               if (gotalarm)
+                       return(-3);             /* alarm expired */
+               len = pr->salen;
+               n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len);
+               if (n < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       else
+                               err_sys("recvfrom error");
+               }
+
+               icmp6 = (struct icmp6_hdr *) recvbuf; /* ICMP header */
+               if ( ( icmp6len = n ) < 8)
+                       continue;                               /* not enough to look at ICMP header */
+       
+               if (icmp6->icmp6_type == ICMP6_TIME_EXCEEDED &&
+                       icmp6->icmp6_code == ICMP6_TIME_EXCEED_TRANSIT) {
+                       if (icmp6len < 8 + sizeof(struct ip6_hdr) + 4)
+                               continue;                       /* not enough data to look at inner header */
+
+                       hip6 = (struct ip6_hdr *) (recvbuf + 8);
+                       hlen2 = sizeof(struct ip6_hdr);
+                       udp = (struct udphdr *) (recvbuf + 8 + hlen2);
+                       if (hip6->ip6_nxt == IPPROTO_UDP &&
+                               udp->uh_sport == htons(sport) &&
+                               udp->uh_dport == htons(dport + seq))
+                               ret = -2;               /* we hit an intermediate router */
+                               break;
+
+               } else if (icmp6->icmp6_type == ICMP6_DST_UNREACH) {
+                       if (icmp6len < 8 + sizeof(struct ip6_hdr) + 4)
+                               continue;                       /* not enough data to look at inner header */
+
+                       hip6 = (struct ip6_hdr *) (recvbuf + 8);
+                       hlen2 = sizeof(struct ip6_hdr);
+                       udp = (struct udphdr *) (recvbuf + 8 + hlen2);
+                       if (hip6->ip6_nxt == IPPROTO_UDP &&
+                               udp->uh_sport == htons(sport) &&
+                               udp->uh_dport == htons(dport + seq)) {
+                               if (icmp6->icmp6_code == ICMP6_DST_UNREACH_NOPORT)
+                                       ret = -1;       /* have reached destination */
+                               else
+                                       ret = icmp6->icmp6_code;        /* 0, 1, 2, ... */
+                               break;
+                       }
+               } else if (verbose) {
+                       printf(" (from %s: type = %d, code = %d)\n",
+                                       Sock_ntop_host(pr->sarecv, pr->salen),
+                                       icmp6->icmp6_type, icmp6->icmp6_code);
+               }
+               /* Some other ICMP error, recvfrom() again */
+       }
+       alarm(0);                                       /* don't leave alarm running */
+       Gettimeofday(tv, NULL);         /* get time of packet arrival */
+       return(ret);
+#endif
+}
diff --git a/traceroute/recv_v6.lc b/traceroute/recv_v6.lc
new file mode 100644 (file)
index 0000000..4154066
--- /dev/null
@@ -0,0 +1,76 @@
+#include    "trace.h"##  1 ##src/traceroute/recv_v6.c##
+
+/*##  2 ##src/traceroute/recv_v6.c##
+ * Return: -3 on timeout##  3 ##src/traceroute/recv_v6.c##
+ *         -2 on ICMP time exceeded in transit (caller keeps going)##  4 ##src/traceroute/recv_v6.c##
+ *         -1 on ICMP port unreachable (caller is done)##  5 ##src/traceroute/recv_v6.c##
+ *       >= 0 return value is some other ICMP unreachable code##  6 ##src/traceroute/recv_v6.c##
+ */##  7 ##src/traceroute/recv_v6.c##
+
+int##  8 ##src/traceroute/recv_v6.c##
+recv_v6(int seq, struct timeval *tv)##  9 ##src/traceroute/recv_v6.c##
+{## 10 ##src/traceroute/recv_v6.c##
+#ifdef  IPV6## 11 ##src/traceroute/recv_v6.c##
+    int     hlen1, hlen2, icmp6len;## 12 ##src/traceroute/recv_v6.c##
+    ssize_t n;## 13 ##src/traceroute/recv_v6.c##
+    socklen_t len;## 14 ##src/traceroute/recv_v6.c##
+    struct ip6_hdr *ip6, *hip6;## 15 ##src/traceroute/recv_v6.c##
+    struct icmp6_hdr *icmp6;## 16 ##src/traceroute/recv_v6.c##
+    struct udphdr *udp;## 17 ##src/traceroute/recv_v6.c##
+
+    alarm(3);## 18 ##src/traceroute/recv_v6.c##
+    for (;;) {## 19 ##src/traceroute/recv_v6.c##
+        len = pr->salen;## 20 ##src/traceroute/recv_v6.c##
+        n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len);## 21 ##src/traceroute/recv_v6.c##
+        if (n < 0) {## 22 ##src/traceroute/recv_v6.c##
+            if (errno == EINTR)## 23 ##src/traceroute/recv_v6.c##
+                return (-3);    /* alarm expired */## 24 ##src/traceroute/recv_v6.c##
+            else## 25 ##src/traceroute/recv_v6.c##
+                err_sys("recvfrom error");## 26 ##src/traceroute/recv_v6.c##
+        }## 27 ##src/traceroute/recv_v6.c##
+        Gettimeofday(tv, NULL); /* get time of packet arrival */## 28 ##src/traceroute/recv_v6.c##
+
+        ip6 = (struct ip6_hdr *) recvbuf;   /* start of IPv6 header */## 29 ##src/traceroute/recv_v6.c##
+        hlen1 = sizeof(struct ip6_hdr);## 30 ##src/traceroute/recv_v6.c##
+
+        icmp6 = (struct icmp6_hdr *) (recvbuf + hlen1); /* ICMP hdr */## 31 ##src/traceroute/recv_v6.c##
+        if ((icmp6len = n - hlen1) < 8)## 32 ##src/traceroute/recv_v6.c##
+            err_quit("icmp6len (%d) < 8", icmp6len);## 33 ##src/traceroute/recv_v6.c##
+
+        if (icmp6->icmp6_type == ICMP6_TIME_EXCEEDED &&## 34 ##src/traceroute/recv_v6.c##
+            icmp6->icmp6_code == ICMP6_TIME_EXCEED_TRANSIT) {## 35 ##src/traceroute/recv_v6.c##
+            if (icmp6len < 8 + 40 + 8)## 36 ##src/traceroute/recv_v6.c##
+                err_quit("icmp6len (%d) < 8 + 40 + 8", icmp6len);## 37 ##src/traceroute/recv_v6.c##
+
+            hip6 = (struct ip6_hdr *) (recvbuf + hlen1 + 8);## 38 ##src/traceroute/recv_v6.c##
+            hlen2 = sizeof(struct ip6_hdr);## 39 ##src/traceroute/recv_v6.c##
+            udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2);## 40 ##src/traceroute/recv_v6.c##
+            if (hip6->ip6_nxt == IPPROTO_UDP &&## 41 ##src/traceroute/recv_v6.c##
+                udp->uh_sport == htons(sport) &&## 42 ##src/traceroute/recv_v6.c##
+                udp->uh_dport == htons(dport + seq))## 43 ##src/traceroute/recv_v6.c##
+                return (-2);    /* we hit an intermediate router */## 44 ##src/traceroute/recv_v6.c##
+
+        } else if (icmp6->icmp6_type == ICMP6_DST_UNREACH) {## 45 ##src/traceroute/recv_v6.c##
+            if (icmp6len < 8 + 40 + 8)## 46 ##src/traceroute/recv_v6.c##
+                err_quit("icmp6len (%d) < 8 + 40 + 8", icmp6len);## 47 ##src/traceroute/recv_v6.c##
+
+            hip6 = (struct ip6_hdr *) (recvbuf + hlen1 + 8);## 48 ##src/traceroute/recv_v6.c##
+            hlen2 = 40;## 49 ##src/traceroute/recv_v6.c##
+            udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2);## 50 ##src/traceroute/recv_v6.c##
+            if (hip6->ip6_nxt == IPPROTO_UDP &&## 51 ##src/traceroute/recv_v6.c##
+                udp->uh_sport == htons(sport) &&## 52 ##src/traceroute/recv_v6.c##
+                udp->uh_dport == htons(dport + seq)) {## 53 ##src/traceroute/recv_v6.c##
+                if (icmp6->icmp6_code == ICMP6_DST_UNREACH_NOPORT)## 54 ##src/traceroute/recv_v6.c##
+                    return (-1);    /* have reached destination */## 55 ##src/traceroute/recv_v6.c##
+                else## 56 ##src/traceroute/recv_v6.c##
+                    return (icmp6->icmp6_code); /* 0, 1, 2, ... */## 57 ##src/traceroute/recv_v6.c##
+            }## 58 ##src/traceroute/recv_v6.c##
+        } else if (verbose) {## 59 ##src/traceroute/recv_v6.c##
+            printf(" (from %s: type = %d, code = %d)\n",## 60 ##src/traceroute/recv_v6.c##
+                   Sock_ntop_host(pr->sarecv, pr->salen),## 61 ##src/traceroute/recv_v6.c##
+                   icmp6->icmp6_type, icmp6->icmp6_code);## 62 ##src/traceroute/recv_v6.c##
+        }## 63 ##src/traceroute/recv_v6.c##
+        /* Some other ICMP error, recvfrom() again */## 64 ##src/traceroute/recv_v6.c##
+    }## 65 ##src/traceroute/recv_v6.c##
+#endif## 66 ##src/traceroute/recv_v6.c##
+}## 67 ##src/traceroute/recv_v6.c##
diff --git a/traceroute/sig_alrm.c b/traceroute/sig_alrm.c
new file mode 100644 (file)
index 0000000..db4eee5
--- /dev/null
@@ -0,0 +1,10 @@
+#include       "trace.h"
+
+int gotalarm;
+
+void
+sig_alrm(int signo)
+{
+       gotalarm = 1;   /* set flag to note that alarm occurred */
+       return;                 /* and interrupt the recvfrom() */
+}
diff --git a/traceroute/trace.h b/traceroute/trace.h
new file mode 100644 (file)
index 0000000..f339e97
--- /dev/null
@@ -0,0 +1,56 @@
+#include       "unp.h"
+#include       <netinet/in_systm.h>
+#include       <netinet/ip.h>
+#include       <netinet/ip_icmp.h>
+#include       <netinet/udp.h>
+
+#define        BUFSIZE         1500
+
+struct rec {                                   /* format of outgoing UDP data */
+  u_short      rec_seq;                        /* sequence number */
+  u_short      rec_ttl;                        /* TTL packet left with */
+  struct timeval       rec_tv;         /* time packet left */
+};
+
+                       /* globals */
+char    recvbuf[BUFSIZE];
+char    sendbuf[BUFSIZE];
+
+int             datalen;                       /* # bytes of data following ICMP header */
+char   *host;
+u_short         sport, dport;
+int             nsent;                         /* add 1 for each sendto() */
+pid_t   pid;                           /* our PID */
+int             probe, nprobes;
+int             sendfd, recvfd;        /* send on UDP sock, read on raw ICMP sock */
+int             ttl, max_ttl;
+int             verbose;
+
+                       /* function prototypes */
+const char     *icmpcode_v4(int);
+const char     *icmpcode_v6(int);
+int             recv_v4(int, struct timeval *);
+int             recv_v6(int, struct timeval *);
+void    sig_alrm(int);
+void    traceloop(void);
+void    tv_sub(struct timeval *, struct timeval *);
+
+struct proto {
+  const char   *(*icmpcode)(int);
+  int   (*recv)(int, struct timeval *);
+  struct sockaddr  *sasend;    /* sockaddr{} for send, from getaddrinfo */
+  struct sockaddr  *sarecv;    /* sockaddr{} for receiving */
+  struct sockaddr  *salast;    /* last sockaddr{} for receiving */
+  struct sockaddr  *sabind;    /* sockaddr{} for binding source port */
+  socklen_t            salen;  /* length of sockaddr{}s */
+  int                  icmpproto;      /* IPPROTO_xxx value for ICMP */
+  int     ttllevel;            /* setsockopt() level to set TTL */
+  int     ttloptname;          /* setsockopt() name to set TTL */
+} *pr;
+
+#ifdef IPV6
+
+#include       <netinet/ip6.h>
+#include       <netinet/icmp6.h>
+
+#endif
diff --git a/traceroute/trace.lh b/traceroute/trace.lh
new file mode 100644 (file)
index 0000000..fdb837f
--- /dev/null
@@ -0,0 +1,56 @@
+#include    "unp.h"##  1 ##src/traceroute/trace.h##
+#include    <netinet/in_systm.h>##  2 ##src/traceroute/trace.h##
+#include    <netinet/ip.h>##  3 ##src/traceroute/trace.h##
+#include    <netinet/ip_icmp.h>##  4 ##src/traceroute/trace.h##
+#include    <netinet/udp.h>##  5 ##src/traceroute/trace.h##
+
+#define BUFSIZE     1500##  6 ##src/traceroute/trace.h##
+
+struct rec {                    /* of outgoing UDP data */##  7 ##src/traceroute/trace.h##
+    u_short rec_seq;            /* sequence number */##  8 ##src/traceroute/trace.h##
+    u_short rec_ttl;            /* TTL packet left with */##  9 ##src/traceroute/trace.h##
+    struct timeval rec_tv;      /* time packet left */## 10 ##src/traceroute/trace.h##
+};## 11 ##src/traceroute/trace.h##
+
+            /* globals */## 12 ##src/traceroute/trace.h##
+char    recvbuf[BUFSIZE];## 13 ##src/traceroute/trace.h##
+char    sendbuf[BUFSIZE];## 14 ##src/traceroute/trace.h##
+
+int     datalen;                /* #bytes of data, following ICMP header */## 15 ##src/traceroute/trace.h##
+char   *host;## 16 ##src/traceroute/trace.h##
+u_short sport, dport;## 17 ##src/traceroute/trace.h##
+int     nsent;                  /* add 1 for each sendto() */## 18 ##src/traceroute/trace.h##
+pid_t   pid;                    /* our PID */## 19 ##src/traceroute/trace.h##
+int     probe, nprobes;## 20 ##src/traceroute/trace.h##
+int     sendfd, recvfd;         /* send on UDP sock, read on raw ICMP sock */## 21 ##src/traceroute/trace.h##
+int     ttl, max_ttl;## 22 ##src/traceroute/trace.h##
+int     verbose;## 23 ##src/traceroute/trace.h##
+
+            /* function prototypes */## 24 ##src/traceroute/trace.h##
+const char *icmpcode_v4(int);## 25 ##src/traceroute/trace.h##
+const char *icmpcode_v6(int);## 26 ##src/traceroute/trace.h##
+int     recv_v4(int, struct timeval *);## 27 ##src/traceroute/trace.h##
+int     recv_v6(int, struct timeval *);## 28 ##src/traceroute/trace.h##
+void    sig_alrm(int);## 29 ##src/traceroute/trace.h##
+void    traceloop(void);## 30 ##src/traceroute/trace.h##
+void    tv_sub(struct timeval *, struct timeval *);## 31 ##src/traceroute/trace.h##
+
+struct proto {## 32 ##src/traceroute/trace.h##
+    const char *(*icmpcode) (int);## 33 ##src/traceroute/trace.h##
+    int     (*recv) (int, struct timeval *);## 34 ##src/traceroute/trace.h##
+    struct sockaddr *sasend;    /* sockaddr{} for send, from getaddrinfo */## 35 ##src/traceroute/trace.h##
+    struct sockaddr *sarecv;    /* sockaddr{} for receiving */## 36 ##src/traceroute/trace.h##
+    struct sockaddr *salast;    /* last sockaddr{} for receiving */## 37 ##src/traceroute/trace.h##
+    struct sockaddr *sabind;    /* sockaddr{} for binding source port */## 38 ##src/traceroute/trace.h##
+    socklen_t salen;            /* length of sockaddr{}s */## 39 ##src/traceroute/trace.h##
+    int     icmpproto;          /* IPPROTO_xxx value for ICMP */## 40 ##src/traceroute/trace.h##
+    int     ttllevel;           /* setsockopt() level to set TTL */## 41 ##src/traceroute/trace.h##
+    int     ttloptname;         /* setsockopt() name to set TTL */## 42 ##src/traceroute/trace.h##
+}      *pr;## 43 ##src/traceroute/trace.h##
+
+#ifdef  IPV6## 44 ##src/traceroute/trace.h##
+
+#include    <netinet/ip6.h>## 45 ##src/traceroute/trace.h##
+#include    <netinet/icmp6.h>## 46 ##src/traceroute/trace.h##
+
+#endif## 47 ##src/traceroute/trace.h##
diff --git a/traceroute/traceloop.c b/traceroute/traceloop.c
new file mode 100644 (file)
index 0000000..a78b509
--- /dev/null
@@ -0,0 +1,80 @@
+#include       "trace.h"
+
+void
+traceloop(void)
+{
+       int                                     seq, code, done;
+       double                          rtt;
+       struct rec                      *rec;
+       struct timeval          tvrecv;
+
+       recvfd = Socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto);
+       setuid(getuid());               /* don't need special permissions anymore */
+
+#ifdef IPV6
+       if (pr->sasend->sa_family == AF_INET6 && verbose == 0) {
+               struct icmp6_filter myfilt;
+               ICMP6_FILTER_SETBLOCKALL(&myfilt);
+               ICMP6_FILTER_SETPASS(ICMP6_TIME_EXCEEDED, &myfilt);
+               ICMP6_FILTER_SETPASS(ICMP6_DST_UNREACH, &myfilt);
+               setsockopt(recvfd, IPPROTO_IPV6, ICMP6_FILTER,
+                                       &myfilt, sizeof(myfilt));
+       }
+#endif
+
+       sendfd = Socket(pr->sasend->sa_family, SOCK_DGRAM, 0);
+
+       pr->sabind->sa_family = pr->sasend->sa_family;
+       sport = (getpid() & 0xffff) | 0x8000;   /* our source UDP port # */
+       sock_set_port(pr->sabind, pr->salen, htons(sport));
+       Bind(sendfd, pr->sabind, pr->salen);
+
+       sig_alrm(SIGALRM);
+
+       seq = 0;
+       done = 0;
+       for (ttl = 1; ttl <= max_ttl && done == 0; ttl++) {
+               Setsockopt(sendfd, pr->ttllevel, pr->ttloptname, &ttl, sizeof(int));
+               bzero(pr->salast, pr->salen);
+
+               printf("%2d ", ttl);
+               fflush(stdout);
+
+               for (probe = 0; probe < nprobes; probe++) {
+                       rec = (struct rec *) sendbuf;
+                       rec->rec_seq = ++seq;
+                       rec->rec_ttl = ttl;
+                       Gettimeofday(&rec->rec_tv, NULL);
+
+                       sock_set_port(pr->sasend, pr->salen, htons(dport + seq));
+                       Sendto(sendfd, sendbuf, datalen, 0, pr->sasend, pr->salen);
+
+                       if ( (code = (*pr->recv)(seq, &tvrecv)) == -3)
+                               printf(" *");           /* timeout, no reply */
+                       else {
+                               char    str[NI_MAXHOST];
+
+                               if (sock_cmp_addr(pr->sarecv, pr->salast, pr->salen) != 0) {
+                                       if (getnameinfo(pr->sarecv, pr->salen, str, sizeof(str),
+                                                                       NULL, 0, 0) == 0)
+                                               printf(" %s (%s)", str,
+                                                               Sock_ntop_host(pr->sarecv, pr->salen));
+                                       else
+                                               printf(" %s",
+                                                               Sock_ntop_host(pr->sarecv, pr->salen));
+                                       memcpy(pr->salast, pr->sarecv, pr->salen);
+                               }
+                               tv_sub(&tvrecv, &rec->rec_tv);
+                               rtt = tvrecv.tv_sec * 1000.0 + tvrecv.tv_usec / 1000.0;
+                               printf("  %.3f ms", rtt);
+
+                               if (code == -1)         /* port unreachable; at destination */
+                                       done++;
+                               else if (code >= 0)
+                                       printf(" (ICMP %s)", (*pr->icmpcode)(code));
+                       }
+                       fflush(stdout);
+               }
+               printf("\n");
+       }
+}
diff --git a/traceroute/traceloop.lc b/traceroute/traceloop.lc
new file mode 100644 (file)
index 0000000..dbd20ab
--- /dev/null
@@ -0,0 +1,79 @@
+#include    "trace.h"##  1 ##src/traceroute/traceloop.c##
+
+void##  2 ##src/traceroute/traceloop.c##
+traceloop(void)##  3 ##src/traceroute/traceloop.c##
+{##  4 ##src/traceroute/traceloop.c##
+    int     seq, code, done;##  5 ##src/traceroute/traceloop.c##
+    double  rtt;##  6 ##src/traceroute/traceloop.c##
+    struct rec *rec;##  7 ##src/traceroute/traceloop.c##
+    struct timeval tvrecv;##  8 ##src/traceroute/traceloop.c##
+
+    recvfd = Socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto);##  9 ##src/traceroute/traceloop.c##
+    setuid(getuid());           /* don't need special permissions any more */## 10 ##src/traceroute/traceloop.c##
+
+#ifdef  IPV6## 11 ##src/traceroute/traceloop.c##
+    if (pr->sasend->sa_family == AF_INET && verbose == 0) {## 12 ##src/traceroute/traceloop.c##
+        struct icmp6_filter myfilt;## 13 ##src/traceroute/traceloop.c##
+        ICMP6_FILTER_SETBLOCKALL(&myfilt);## 14 ##src/traceroute/traceloop.c##
+        ICMP6_FILTER_SETPASS(ICMP6_TIME_EXCEEDED, &myfilt);## 15 ##src/traceroute/traceloop.c##
+        ICMP6_FILTER_SETPASS(ICMP6_DST_UNREACH, &myfilt);## 16 ##src/traceroute/traceloop.c##
+        setsockopt(recvfd, IPPROTO_IPV6, ICMP6_FILTER,## 17 ##src/traceroute/traceloop.c##
+                   &myfilt, sizeof(myfilt));## 18 ##src/traceroute/traceloop.c##
+    }## 19 ##src/traceroute/traceloop.c##
+#endif## 20 ##src/traceroute/traceloop.c##
+
+    sendfd = Socket(pr->sasend->sa_family, SOCK_DGRAM, 0);## 21 ##src/traceroute/traceloop.c##
+
+    pr->sabind->sa_family = pr->sasend->sa_family;## 22 ##src/traceroute/traceloop.c##
+    sport = (getpid() & 0xffff) | 0x8000;   /* our source UDP port# */## 23 ##src/traceroute/traceloop.c##
+    sock_set_port(pr->sabind, pr->salen, htons(sport));## 24 ##src/traceroute/traceloop.c##
+    Bind(sendfd, pr->sabind, pr->salen);## 25 ##src/traceroute/traceloop.c##
+
+    sig_alrm(SIGALRM);## 26 ##src/traceroute/traceloop.c##
+
+    seq = 0;## 27 ##src/traceroute/traceloop.c##
+    done = 0;## 28 ##src/traceroute/traceloop.c##
+    for (ttl = 1; ttl <= max_ttl && done == 0; ttl++) {## 29 ##src/traceroute/traceloop.c##
+        Setsockopt(sendfd, pr->ttllevel, pr->ttloptname, &ttl, sizeof(int));## 30 ##src/traceroute/traceloop.c##
+        bzero(pr->salast, pr->salen);## 31 ##src/traceroute/traceloop.c##
+
+        printf("%2d  ", ttl);## 32 ##src/traceroute/traceloop.c##
+        fflush(stdout);## 33 ##src/traceroute/traceloop.c##
+
+        for (probe = 0; probe < nprobes; probe++) {## 34 ##src/traceroute/traceloop.c##
+            rec = (struct rec *) sendbuf;## 35 ##src/traceroute/traceloop.c##
+            rec->rec_seq = ++seq;## 36 ##src/traceroute/traceloop.c##
+            rec->rec_ttl = ttl;## 37 ##src/traceroute/traceloop.c##
+            Gettimeofday(&rec->rec_tv, NULL);## 38 ##src/traceroute/traceloop.c##
+
+            sock_set_port(pr->sasend, pr->salen, htons(dport + seq));## 39 ##src/traceroute/traceloop.c##
+            Sendto(sendfd, sendbuf, datalen, 0, pr->sasend, pr->salen);## 40 ##src/traceroute/traceloop.c##
+
+            if ((code = (*pr->recv) (seq, &tvrecv)) == -3)## 41 ##src/traceroute/traceloop.c##
+                printf(" *");   /* timeout, no reply */## 42 ##src/traceroute/traceloop.c##
+            else {## 43 ##src/traceroute/traceloop.c##
+                char    str[NI_MAXHOST];## 44 ##src/traceroute/traceloop.c##
+
+                if (sock_cmp_addr(pr->sarecv, pr->salast, pr->salen) != 0) {## 45 ##src/traceroute/traceloop.c##
+                    if (getnameinfo(pr->sarecv, pr->salen, str, sizeof(str),## 46 ##src/traceroute/traceloop.c##
+                                    NULL, 0, 0) == 0)## 47 ##src/traceroute/traceloop.c##
+                        printf(" %s (%s)", str,## 48 ##src/traceroute/traceloop.c##
+                               Sock_ntop_host(pr->sarecv, pr->salen));## 49 ##src/traceroute/traceloop.c##
+                    else## 50 ##src/traceroute/traceloop.c##
+                        printf(" %s", Sock_ntop_host(pr->sarecv, pr->salen));## 51 ##src/traceroute/traceloop.c##
+                    memcpy(pr->salast, pr->sarecv, pr->salen);## 52 ##src/traceroute/traceloop.c##
+                }## 53 ##src/traceroute/traceloop.c##
+                tv_sub(&tvrecv, &rec->rec_tv);## 54 ##src/traceroute/traceloop.c##
+                rtt = tvrecv.tv_sec * 1000.0 + tvrecv.tv_usec / 1000.0;## 55 ##src/traceroute/traceloop.c##
+                printf("  %.3f ms", rtt);## 56 ##src/traceroute/traceloop.c##
+
+                if (code == -1) /* port unreachable; at destination */## 57 ##src/traceroute/traceloop.c##
+                    done++;## 58 ##src/traceroute/traceloop.c##
+                else if (code >= 0)## 59 ##src/traceroute/traceloop.c##
+                    printf(" (ICMP %s)", (*pr->icmpcode) (code));## 60 ##src/traceroute/traceloop.c##
+            }## 61 ##src/traceroute/traceloop.c##
+            fflush(stdout);## 62 ##src/traceroute/traceloop.c##
+        }## 63 ##src/traceroute/traceloop.c##
+        printf("\n");## 64 ##src/traceroute/traceloop.c##
+    }## 65 ##src/traceroute/traceloop.c##
+}## 66 ##src/traceroute/traceloop.c##
diff --git a/traceroute/tv_sub.c b/traceroute/tv_sub.c
new file mode 100644 (file)
index 0000000..7ad7830
--- /dev/null
@@ -0,0 +1,11 @@
+#include       "unp.h"
+
+void
+tv_sub(struct timeval *out, struct timeval *in)
+{
+       if ( (out->tv_usec -= in->tv_usec) < 0) {       /* out -= in */
+               --out->tv_sec;
+               out->tv_usec += 1000000;
+       }
+       out->tv_sec -= in->tv_sec;
+}
diff --git a/udpcksum/Makefile b/udpcksum/Makefile
new file mode 100644 (file)
index 0000000..3d7de4c
--- /dev/null
@@ -0,0 +1,21 @@
+include ../Make.defines
+
+OBJS = main.o cleanup.o pcap.o udpcksum.o senddnsquery-raw.o udpread.o udpwrite.o
+OBJSNET = main.o cleanup.o pcap.o udpcksum.o senddnsquery-libnet.o udpread.o
+PROGS =        udpcksum udpcksum-libnet
+
+all:   ${PROGS}
+
+udpcksum:      ${OBJS}
+               ${CC} ${CFLAGS} -o $@ ${OBJS} -L/usr/local/lib -lpcap ${LIBS}
+
+# Include special linking flags from libnet-config program
+udpcksum-libnet:       ${OBJSNET}
+               ${CC} ${CFLAGS} -o $@ ${OBJSNET} -L/usr/local/lib -lpcap ${LIBS} `libnet-config --libs`
+
+# Include special compilation flags from libnet-config program
+senddnsquery-libnet.o: senddnsquery-libnet.c
+               ${CC} ${CFLAGS} `libnet-config --defines --cflags` -c -o $@ $<
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/udpcksum/cleanup.c b/udpcksum/cleanup.c
new file mode 100644 (file)
index 0000000..97743ec
--- /dev/null
@@ -0,0 +1,20 @@
+#include       "udpcksum.h"
+
+/* include cleanup */
+void
+cleanup(int signo)
+{
+       struct pcap_stat        stat;
+
+       putc('\n', stdout);
+
+       if (verbose) {
+               if (pcap_stats(pd, &stat) < 0)
+                       err_quit("pcap_stats: %s\n", pcap_geterr(pd));
+               printf("%d packets received by filter\n", stat.ps_recv);
+               printf("%d packets dropped by kernel\n", stat.ps_drop);
+       }
+
+       exit(0);
+}
+/* end cleanup */
diff --git a/udpcksum/cleanup.lc b/udpcksum/cleanup.lc
new file mode 100644 (file)
index 0000000..9cffc80
--- /dev/null
@@ -0,0 +1,21 @@
+#include    "udpcksum.h"##  1 ##src/udpcksum/cleanup.c##
+
+/* include cleanup */
+void##  2 ##src/udpcksum/cleanup.c##
+cleanup(int signo)##  3 ##src/udpcksum/cleanup.c##
+{##  4 ##src/udpcksum/cleanup.c##
+    struct pcap_stat stat;##  5 ##src/udpcksum/cleanup.c##
+
+    fflush(stdout);##  6 ##src/udpcksum/cleanup.c##
+    putc('\n', stdout);##  7 ##src/udpcksum/cleanup.c##
+
+    if (verbose) {##  8 ##src/udpcksum/cleanup.c##
+        if (pcap_stats(pd, &stat) < 0)##  9 ##src/udpcksum/cleanup.c##
+            err_quit("pcap_stats: %s\n", pcap_geterr(pd));## 10 ##src/udpcksum/cleanup.c##
+        printf("%d packets received by filter\n", stat.ps_recv);## 11 ##src/udpcksum/cleanup.c##
+        printf("%d packets dropped by kernel\n", stat.ps_drop);## 12 ##src/udpcksum/cleanup.c##
+    }## 13 ##src/udpcksum/cleanup.c##
+
+    exit(0);## 14 ##src/udpcksum/cleanup.c##
+}## 15 ##src/udpcksum/cleanup.c##
+/* end cleanup */
diff --git a/udpcksum/main.c b/udpcksum/main.c
new file mode 100644 (file)
index 0000000..45b33d3
--- /dev/null
@@ -0,0 +1,124 @@
+/* include main1 */
+#include       "udpcksum.h"
+
+                       /* DefinE global variables */
+struct sockaddr        *dest, *local;
+struct sockaddr_in locallookup;
+socklen_t              destlen, locallen;
+
+int            datalink;               /* from pcap_datalink(), in <net/bpf.h> */
+char   *device;                        /* pcap device */
+pcap_t *pd;                            /* packet capture struct pointer */
+int            rawfd;                  /* raw socket to write on */
+int            snaplen = 200;  /* amount of data to capture */
+int            verbose;
+int            zerosum;                /* send UDP query with no checksum */
+
+static void    usage(const char *);
+
+int
+main(int argc, char *argv[])
+{
+       int                             c, lopt=0;
+       char                    *ptr, localname[1024], *localport;
+       struct addrinfo *aip;
+/* end main1 */
+
+/* include main2 */
+       opterr = 0;             /* don't want getopt() writing to stderr */
+       while ( (c = getopt(argc, argv, "0i:l:v")) != -1) {
+               switch (c) {
+
+               case '0':
+                       zerosum = 1;
+                       break;
+
+               case 'i':
+                       device = optarg;                        /* pcap device */
+                       break;
+
+               case 'l':                       /* local IP address and port #: a.b.c.d.p */
+                       if ( (ptr = strrchr(optarg, '.')) == NULL)
+                               usage("invalid -l option");
+
+                       *ptr++ = 0;                                     /* null replaces final period */
+                       localport = ptr;                        /* service name or port number */
+                       strncpy(localname, optarg, sizeof(localname));
+                       lopt = 1;
+                       break;
+
+               case 'v':
+                       verbose = 1;
+                       break;
+
+               case '?':
+                       usage("unrecognized option");
+               }
+       }
+/* end main2 */
+/* include main3 */
+       if (optind != argc-2)
+               usage("missing <host> and/or <serv>");
+
+               /* 4convert destination name and service */
+       aip = Host_serv(argv[optind], argv[optind+1], AF_INET, SOCK_DGRAM);
+       dest = aip->ai_addr;            /* don't freeaddrinfo() */
+       destlen = aip->ai_addrlen;
+
+       /*
+        * Need local IP address for source IP address for UDP datagrams.
+        * Can't specify 0 and let IP choose, as we need to know it for
+        * the pseudoheader to calculate the UDP checksum.
+        * If -l option supplied, then use those values; otherwise,
+        * connect a UDP socket to the destination to determine the right
+        * source address.
+        */
+       if (lopt) {
+                   /* 4convert local name and service */
+           aip = Host_serv(localname, localport, AF_INET, SOCK_DGRAM);
+           local = aip->ai_addr;               /* don't freeaddrinfo() */
+           locallen = aip->ai_addrlen;
+       } else {
+               int s;
+               s = Socket(AF_INET, SOCK_DGRAM, 0);
+               Connect(s, dest, destlen);
+               /* kernel chooses correct local address for dest */
+               locallen = sizeof(locallookup);
+           local = (struct sockaddr *)&locallookup;
+               Getsockname(s, local, &locallen);
+               if (locallookup.sin_addr.s_addr == htonl(INADDR_ANY))
+                       err_quit("Can't determine local address - use -l\n");
+               close(s);
+       }
+
+       open_output();          /* open output, either raw socket or libnet */
+
+       open_pcap();            /* open packet capture device */
+
+       setuid(getuid());       /* don't need superuser privileges anymore */
+
+       Signal(SIGTERM, cleanup);
+       Signal(SIGINT, cleanup);
+       Signal(SIGHUP, cleanup);
+
+       test_udp();
+
+       cleanup(0);
+}
+/* end main3 */
+
+static void
+usage(const char *msg)
+{
+       err_msg(
+"usage: udpcksum [ options ] <host> <serv>\n"
+"options: -0    send UDP datagram with checksum set to 0\n"
+"         -i s  packet capture device\n"
+"         -l a.b.c.d.p  local IP=a.b.c.d, local port=p\n"
+"         -v    verbose output"
+);
+
+       if (msg[0] != 0)
+               err_quit("%s", msg);
+       exit(1);
+}
diff --git a/udpcksum/main.lc b/udpcksum/main.lc
new file mode 100644 (file)
index 0000000..3ebe718
--- /dev/null
@@ -0,0 +1,125 @@
+/* include main1 */
+#include    "udpcksum.h"##  1 ##src/udpcksum/main.c##
+
+            /* define global variables */##  2 ##src/udpcksum/main.c##
+struct sockaddr *dest, *local;##  3 ##src/udpcksum/main.c##
+struct sockaddr_in locallookup;##  4 ##src/udpcksum/main.c##
+socklen_t destlen, locallen;##  5 ##src/udpcksum/main.c##
+
+int     datalink;               /* from pcap_datalink(), in <net/bpf.h> */##  6 ##src/udpcksum/main.c##
+char   *device;                 /* pcap device */##  7 ##src/udpcksum/main.c##
+pcap_t *pd;                     /* packet capture struct pointer */##  8 ##src/udpcksum/main.c##
+int     rawfd;                  /* raw socket to write on */##  9 ##src/udpcksum/main.c##
+int     snaplen = 200;          /* amount of data to capture */## 10 ##src/udpcksum/main.c##
+int     verbose;## 11 ##src/udpcksum/main.c##
+int     zerosum;                /* send UDP query with no checksum */## 12 ##src/udpcksum/main.c##
+
+static void usage(const char *);## 13 ##src/udpcksum/main.c##
+
+int## 14 ##src/udpcksum/main.c##
+main(int argc, char *argv[])## 15 ##src/udpcksum/main.c##
+{## 16 ##src/udpcksum/main.c##
+    int     c, lopt = 0;## 17 ##src/udpcksum/main.c##
+    char   *ptr, localname[1024], *localport;## 18 ##src/udpcksum/main.c##
+    struct addrinfo *aip;## 19 ##src/udpcksum/main.c##
+
+    if (argc < 2)## 20 ##src/udpcksum/main.c##
+        usage("");## 21 ##src/udpcksum/main.c##
+/* end main1 */
+
+/* include main2 */
+    opterr = 0;                 /* don't want getopt() writing to stderr */## 22 ##src/udpcksum/main.c##
+    while ((c = getopt(argc, argv, "0i:l:v")) != -1) {## 23 ##src/udpcksum/main.c##
+        switch (c) {## 24 ##src/udpcksum/main.c##
+
+        case '0':## 25 ##src/udpcksum/main.c##
+            zerosum = 1;## 26 ##src/udpcksum/main.c##
+            break;## 27 ##src/udpcksum/main.c##
+
+        case 'i':## 28 ##src/udpcksum/main.c##
+            device = optarg;    /* pcap device */## 29 ##src/udpcksum/main.c##
+            break;## 30 ##src/udpcksum/main.c##
+
+        case 'l':               /* local IP address and port#: a.b.c.d.p */## 31 ##src/udpcksum/main.c##
+            if ((ptr = strrchr(optarg, '.')) == NULL)## 32 ##src/udpcksum/main.c##
+                usage("invalid -l option");## 33 ##src/udpcksum/main.c##
+
+            *ptr++ = 0;         /* null replaces final period */## 34 ##src/udpcksum/main.c##
+            localport = ptr;    /* service name or port number */## 35 ##src/udpcksum/main.c##
+            strncpy(localname, optarg, sizeof(localname));## 36 ##src/udpcksum/main.c##
+            lopt = 1;## 37 ##src/udpcksum/main.c##
+            break;## 38 ##src/udpcksum/main.c##
+
+        case 'v':## 39 ##src/udpcksum/main.c##
+            verbose = 1;## 40 ##src/udpcksum/main.c##
+            break;## 41 ##src/udpcksum/main.c##
+
+        case '?':## 42 ##src/udpcksum/main.c##
+            usage("unrecognized option");## 43 ##src/udpcksum/main.c##
+        }## 44 ##src/udpcksum/main.c##
+    }## 45 ##src/udpcksum/main.c##
+/* end main2 */
+/* include main3 */
+    if (optind != argc - 2)## 46 ##src/udpcksum/main.c##
+        usage("missing <host> and/or <serv>");## 47 ##src/udpcksum/main.c##
+
+    /* 4convert destination name and service */## 48 ##src/udpcksum/main.c##
+    aip = Host_serv(argv[optind], argv[optind + 1], AF_INET, SOCK_DGRAM);## 49 ##src/udpcksum/main.c##
+    dest = aip->ai_addr;        /* don't freeaddrinfo() */## 50 ##src/udpcksum/main.c##
+    destlen = aip->ai_addrlen;## 51 ##src/udpcksum/main.c##
+
+    /* ## 52 ##src/udpcksum/main.c##
+     * Need local IP address for source IP address for UDP datagrams.## 53 ##src/udpcksum/main.c##
+     * Can't specify 0 and let IP choose, as we need to know it for## 54 ##src/udpcksum/main.c##
+     * the pseudo-header to calculate the UDP checksum.## 55 ##src/udpcksum/main.c##
+     * If -l option supplied, then use those values; otherwise,## 56 ##src/udpcksum/main.c##
+     * connect a UDP socket to the destination to determine the right## 57 ##src/udpcksum/main.c##
+     * source address.## 58 ##src/udpcksum/main.c##
+     */## 59 ##src/udpcksum/main.c##
+    if (lopt) {## 60 ##src/udpcksum/main.c##
+        /* 4convert local name and service */## 61 ##src/udpcksum/main.c##
+        aip = Host_serv(localname, localport, AF_INET, SOCK_DGRAM);## 62 ##src/udpcksum/main.c##
+        local = aip->ai_addr;   /* don't freeaddrinfo() */## 63 ##src/udpcksum/main.c##
+        locallen = aip->ai_addrlen;## 64 ##src/udpcksum/main.c##
+    } else {## 65 ##src/udpcksum/main.c##
+        int     s;## 66 ##src/udpcksum/main.c##
+        s = Socket(AF_INET, SOCK_DGRAM, 0);## 67 ##src/udpcksum/main.c##
+        Connect(s, dest, destlen);## 68 ##src/udpcksum/main.c##
+        /* the kernel chooses the correct local address for dest */## 69 ##src/udpcksum/main.c##
+        locallen = sizeof(locallookup);## 70 ##src/udpcksum/main.c##
+        local = (struct sockaddr *) &locallookup;## 71 ##src/udpcksum/main.c##
+        Getsockname(s, local, &locallen);## 72 ##src/udpcksum/main.c##
+        if (locallookup.sin_addr.s_addr == htonl(INADDR_ANY))## 73 ##src/udpcksum/main.c##
+            err_quit("Can't determine local address - use -l\n");## 74 ##src/udpcksum/main.c##
+        close(s);## 75 ##src/udpcksum/main.c##
+    }## 76 ##src/udpcksum/main.c##
+
+    open_output();              /* open output, either raw socket or libnet */## 77 ##src/udpcksum/main.c##
+
+    open_pcap();                /* open packet capture device */## 78 ##src/udpcksum/main.c##
+
+    setuid(getuid());           /* don't need superuser privileges any more */## 79 ##src/udpcksum/main.c##
+
+    Signal(SIGTERM, cleanup);## 80 ##src/udpcksum/main.c##
+    Signal(SIGINT, cleanup);## 81 ##src/udpcksum/main.c##
+    Signal(SIGHUP, cleanup);## 82 ##src/udpcksum/main.c##
+
+    test_udp();## 83 ##src/udpcksum/main.c##
+
+    cleanup(0);## 84 ##src/udpcksum/main.c##
+}## 85 ##src/udpcksum/main.c##
+/* end main3 */
+
+static void## 86 ##src/udpcksum/main.c##
+usage(const char *msg)## 87 ##src/udpcksum/main.c##
+{## 88 ##src/udpcksum/main.c##
+    err_msg("usage: udpcksum [ options ] <host> <serv>\n"## 89 ##src/udpcksum/main.c##
+            "options: -0    send UDP datagram with checksum set to 0\n"## 90 ##src/udpcksum/main.c##
+            "         -i s  packet capture device\n"## 91 ##src/udpcksum/main.c##
+            "         -l a.b.c.d.p  local IP=a.b.c.d, local port=p\n"## 92 ##src/udpcksum/main.c##
+            "         -v    verbose output");## 93 ##src/udpcksum/main.c##
+
+    if (msg[0] != 0)## 94 ##src/udpcksum/main.c##
+        err_quit("%s", msg);## 95 ##src/udpcksum/main.c##
+    exit(1);## 96 ##src/udpcksum/main.c##
+}## 97 ##src/udpcksum/main.c##
diff --git a/udpcksum/pcap.c b/udpcksum/pcap.c
new file mode 100644 (file)
index 0000000..a88cc43
--- /dev/null
@@ -0,0 +1,63 @@
+/* include open_pcap */
+#include       "udpcksum.h"
+
+#define        CMD             "udp and src host %s and src port %d"
+
+void
+open_pcap(void)
+{
+       uint32_t                        localnet, netmask;
+       char                            cmd[MAXLINE], errbuf[PCAP_ERRBUF_SIZE],
+                                               str1[INET_ADDRSTRLEN], str2[INET_ADDRSTRLEN];
+       struct bpf_program      fcode;
+
+       if (device == NULL) {
+               if ( (device = pcap_lookupdev(errbuf)) == NULL)
+                       err_quit("pcap_lookup: %s", errbuf);
+       }
+       printf("device = %s\n", device);
+
+               /* 4hardcode: promisc=0, to_ms=500 */
+       if ( (pd = pcap_open_live(device, snaplen, 0, 500, errbuf)) == NULL)
+               err_quit("pcap_open_live: %s", errbuf);
+
+       if (pcap_lookupnet(device, &localnet, &netmask, errbuf) < 0)
+               err_quit("pcap_lookupnet: %s", errbuf);
+       if (verbose)
+               printf("localnet = %s, netmask = %s\n",
+                          Inet_ntop(AF_INET, &localnet, str1, sizeof(str1)),
+                          Inet_ntop(AF_INET, &netmask, str2, sizeof(str2)));
+
+       snprintf(cmd, sizeof(cmd), CMD,
+                        Sock_ntop_host(dest, destlen),
+                        ntohs(sock_get_port(dest, destlen)));
+       if (verbose)
+               printf("cmd = %s\n", cmd);
+       if (pcap_compile(pd, &fcode, cmd, 0, netmask) < 0)
+               err_quit("pcap_compile: %s", pcap_geterr(pd));
+
+       if (pcap_setfilter(pd, &fcode) < 0)
+               err_quit("pcap_setfilter: %s", pcap_geterr(pd));
+
+       if ( (datalink = pcap_datalink(pd)) < 0)
+               err_quit("pcap_datalink: %s", pcap_geterr(pd));
+       if (verbose)
+               printf("datalink = %d\n", datalink);
+}
+/* end open_pcap */
+
+/* include next_pcap */
+char *
+next_pcap(int *len)
+{
+       char                            *ptr;
+       struct pcap_pkthdr      hdr;
+
+               /* 4keep looping until packet ready */
+       while ( (ptr = (char *) pcap_next(pd, &hdr)) == NULL)
+               ;
+
+       *len = hdr.caplen;      /* captured length */
+       return(ptr);
+}
+/* end next_pcap */
diff --git a/udpcksum/pcap.lc b/udpcksum/pcap.lc
new file mode 100644 (file)
index 0000000..cd77a78
--- /dev/null
@@ -0,0 +1,62 @@
+/* include open_pcap */
+#include    "udpcksum.h"##  1 ##src/udpcksum/pcap.c##
+
+#define CMD     "udp and src host %s and src port %d"##  2 ##src/udpcksum/pcap.c##
+
+void##  3 ##src/udpcksum/pcap.c##
+open_pcap(void)##  4 ##src/udpcksum/pcap.c##
+{##  5 ##src/udpcksum/pcap.c##
+    uint32_t localnet, netmask;##  6 ##src/udpcksum/pcap.c##
+    char    cmd[MAXLINE], errbuf[PCAP_ERRBUF_SIZE],##  7 ##src/udpcksum/pcap.c##
+        str1[INET_ADDRSTRLEN], str2[INET_ADDRSTRLEN];##  8 ##src/udpcksum/pcap.c##
+    struct bpf_program fcode;##  9 ##src/udpcksum/pcap.c##
+
+    if (device == NULL) {## 10 ##src/udpcksum/pcap.c##
+        if ((device = pcap_lookupdev(errbuf)) == NULL)## 11 ##src/udpcksum/pcap.c##
+            err_quit("pcap_lookup: %s", errbuf);## 12 ##src/udpcksum/pcap.c##
+    }## 13 ##src/udpcksum/pcap.c##
+    printf("device = %s\n", device);## 14 ##src/udpcksum/pcap.c##
+
+    /* 4hardcode: promisc=0, to_ms=500 */## 15 ##src/udpcksum/pcap.c##
+    if ((pd = pcap_open_live(device, snaplen, 0, 500, errbuf)) == NULL)## 16 ##src/udpcksum/pcap.c##
+        err_quit("pcap_open_live: %s", errbuf);## 17 ##src/udpcksum/pcap.c##
+
+    if (pcap_lookupnet(device, &localnet, &netmask, errbuf) < 0)## 18 ##src/udpcksum/pcap.c##
+        err_quit("pcap_lookupnet: %s", errbuf);## 19 ##src/udpcksum/pcap.c##
+    if (verbose)## 20 ##src/udpcksum/pcap.c##
+        printf("localnet = %s, netmask = %s\n",## 21 ##src/udpcksum/pcap.c##
+               Inet_ntop(AF_INET, &localnet, str1, sizeof(str1)),## 22 ##src/udpcksum/pcap.c##
+               Inet_ntop(AF_INET, &netmask, str2, sizeof(str2)));## 23 ##src/udpcksum/pcap.c##
+
+    snprintf(cmd, sizeof(cmd), CMD,## 24 ##src/udpcksum/pcap.c##
+             Sock_ntop_host(dest, destlen),## 25 ##src/udpcksum/pcap.c##
+             ntohs(sock_get_port(dest, destlen)));## 26 ##src/udpcksum/pcap.c##
+    if (verbose)## 27 ##src/udpcksum/pcap.c##
+        printf("cmd = %s\n", cmd);## 28 ##src/udpcksum/pcap.c##
+    if (pcap_compile(pd, &fcode, cmd, 0, netmask) < 0)## 29 ##src/udpcksum/pcap.c##
+        err_quit("pcap_compile: %s", pcap_geterr(pd));## 30 ##src/udpcksum/pcap.c##
+
+    if (pcap_setfilter(pd, &fcode) < 0)## 31 ##src/udpcksum/pcap.c##
+        err_quit("pcap_setfilter: %s", pcap_geterr(pd));## 32 ##src/udpcksum/pcap.c##
+
+    if ((datalink = pcap_datalink(pd)) < 0)## 33 ##src/udpcksum/pcap.c##
+        err_quit("pcap_datalink: %s", pcap_geterr(pd));## 34 ##src/udpcksum/pcap.c##
+    if (verbose)## 35 ##src/udpcksum/pcap.c##
+        printf("datalink = %d\n", datalink);## 36 ##src/udpcksum/pcap.c##
+}## 37 ##src/udpcksum/pcap.c##
+/* end open_pcap */
+
+/* include next_pcap */
+char   *## 38 ##src/udpcksum/pcap.c##
+next_pcap(int *len)## 39 ##src/udpcksum/pcap.c##
+{## 40 ##src/udpcksum/pcap.c##
+    char   *ptr;## 41 ##src/udpcksum/pcap.c##
+    struct pcap_pkthdr hdr;## 42 ##src/udpcksum/pcap.c##
+
+    /* 4keep looping until packet ready */## 43 ##src/udpcksum/pcap.c##
+    while ((ptr = (char *) pcap_next(pd, &hdr)) == NULL) ;## 44 ##src/udpcksum/pcap.c##
+
+    *len = hdr.caplen;          /* captured length */## 45 ##src/udpcksum/pcap.c##
+    return (ptr);## 46 ##src/udpcksum/pcap.c##
+}## 47 ##src/udpcksum/pcap.c##
+/* end next_pcap */
diff --git a/udpcksum/senddnsquery-libnet.c b/udpcksum/senddnsquery-libnet.c
new file mode 100644 (file)
index 0000000..614e2ae
--- /dev/null
@@ -0,0 +1,78 @@
+#include       "udpcksum.h"
+#include       <libnet.h>
+
+/*
+ * Build a DNS A query for "a.root-servers.net" and write it to
+ * the raw socket.
+ */
+
+/* include open_output_libnet */
+static libnet_t *l;            /* libnet descriptor */
+
+void
+open_output(void)
+{
+       char errbuf[LIBNET_ERRBUF_SIZE];
+
+       /* Initialize libnet with an IPv4 raw socket */
+       l = libnet_init(LIBNET_RAW4, NULL, errbuf);
+       if (l == NULL) {
+               err_quit("Can't initialize libnet: %s", errbuf);
+       }
+}
+/* end open_output_libnet */
+
+/* include send_dns_query_libnet */
+void
+send_dns_query(void)
+{
+       char                             qbuf[24], *ptr;
+       u_int16_t                        one;
+       int                                      packet_size = LIBNET_UDP_H + LIBNET_DNSV4_H + 24;
+       static libnet_ptag_t ip_tag, udp_tag, dns_tag;
+
+       /* build query portion of DNS packet */
+       ptr = qbuf;
+       memcpy(ptr, "\001a\014root-servers\003net\000", 20);
+       ptr += 20;
+       one = htons(1);
+       memcpy(ptr, &one, 2);                           /* query type = A */
+       ptr += 2;
+       memcpy(ptr, &one, 2);                           /* query class = 1 (IP addr) */
+
+       /* build DNS packet */
+       dns_tag = libnet_build_dnsv4(
+                       1234 /* identification */,
+                       0x0100 /* flags: recursion desired */,
+                       1 /* # questions */,    0 /* # answer RRs */,
+                       0 /* # authority RRs */, 0 /* # additional RRs */,
+                       qbuf /* query */, 24 /* length of query */, l, dns_tag);
+       /* build UDP header */
+       udp_tag = libnet_build_udp(
+                       ((struct sockaddr_in *) local)->sin_port /* source port */,
+                       ((struct sockaddr_in *) dest)->sin_port /* dest port */,
+                       packet_size /* length */, 0 /* checksum */,
+                       NULL /* payload */, 0 /* payload length */, l, udp_tag);
+       /* Since we specified the checksum as 0, libnet will automatically */
+       /* calculate the UDP checksum.  Turn it off if the user doesn't want it. */
+       if (zerosum)
+               if (libnet_toggle_checksum(l, udp_tag, LIBNET_OFF) < 0)
+                       err_quit("turning off checksums: %s\n", libnet_geterror(l));
+       /* build IP header */
+/* *INDENT-OFF* */
+       ip_tag = libnet_build_ipv4(packet_size + LIBNET_IPV4_H /* len */,
+                       0 /* tos */, 0 /* IP ID */, 0 /* fragment */,
+                       TTL_OUT /* ttl */, IPPROTO_UDP /* protocol */,
+                       0 /* checksum */,
+                       ((struct sockaddr_in *) local)->sin_addr.s_addr /* source */,
+                       ((struct sockaddr_in *) dest)->sin_addr.s_addr /* dest */,
+                       NULL /* payload */, 0 /* payload length */, l, ip_tag);
+/* *INDENT-ON* */
+
+       if (libnet_write(l) < 0) {
+               err_quit("libnet_write: %s\n", libnet_geterror(l));
+       }
+       if (verbose)
+               printf("sent: %d bytes of data\n", packet_size);
+}
+/* end send_dns_query_libnet */
diff --git a/udpcksum/senddnsquery-libnet.lc b/udpcksum/senddnsquery-libnet.lc
new file mode 100644 (file)
index 0000000..3708a65
--- /dev/null
@@ -0,0 +1,79 @@
+#include    "udpcksum.h"##  1 ##src/udpcksum/senddnsquery-libnet.c##
+#include    <libnet.h>##  2 ##src/udpcksum/senddnsquery-libnet.c##
+
+/*##  3 ##src/udpcksum/senddnsquery-libnet.c##
+ * Build a DNS A query for "a.root-servers.net" and write it to##  4 ##src/udpcksum/senddnsquery-libnet.c##
+ * the raw socket.##  5 ##src/udpcksum/senddnsquery-libnet.c##
+ */##  6 ##src/udpcksum/senddnsquery-libnet.c##
+
+/* include open_output_libnet */
+static libnet_t *l;             /* libnet descriptor */##  7 ##src/udpcksum/senddnsquery-libnet.c##
+
+void##  8 ##src/udpcksum/senddnsquery-libnet.c##
+open_output(void)##  9 ##src/udpcksum/senddnsquery-libnet.c##
+{## 10 ##src/udpcksum/senddnsquery-libnet.c##
+    char    errbuf[LIBNET_ERRBUF_SIZE];## 11 ##src/udpcksum/senddnsquery-libnet.c##
+
+    /* Initialize libnet, with an IPv4 raw socket. */## 12 ##src/udpcksum/senddnsquery-libnet.c##
+    l = libnet_init(LIBNET_RAW4, NULL, errbuf);## 13 ##src/udpcksum/senddnsquery-libnet.c##
+    if (l == NULL) {## 14 ##src/udpcksum/senddnsquery-libnet.c##
+        err_quit("Can't initialize libnet: %s", errbuf);## 15 ##src/udpcksum/senddnsquery-libnet.c##
+    }## 16 ##src/udpcksum/senddnsquery-libnet.c##
+}## 17 ##src/udpcksum/senddnsquery-libnet.c##
+/* end open_output_libnet */
+
+/* include send_dns_query_libnet */
+void## 18 ##src/udpcksum/senddnsquery-libnet.c##
+send_dns_query(void)## 19 ##src/udpcksum/senddnsquery-libnet.c##
+{## 20 ##src/udpcksum/senddnsquery-libnet.c##
+    char    qbuf[24], *ptr;## 21 ##src/udpcksum/senddnsquery-libnet.c##
+    u_int16_t one;## 22 ##src/udpcksum/senddnsquery-libnet.c##
+    int     packet_size = LIBNET_UDP_H + LIBNET_DNSV4_H + 24;## 23 ##src/udpcksum/senddnsquery-libnet.c##
+    static libnet_ptag_t ip_tag, udp_tag, dns_tag;## 24 ##src/udpcksum/senddnsquery-libnet.c##
+
+    /* Build the query portion of the DNS packet. */## 25 ##src/udpcksum/senddnsquery-libnet.c##
+    ptr = qbuf;## 26 ##src/udpcksum/senddnsquery-libnet.c##
+    memcpy(ptr, "\001a\014root-servers\003net\000", 20);## 27 ##src/udpcksum/senddnsquery-libnet.c##
+    ptr += 20;## 28 ##src/udpcksum/senddnsquery-libnet.c##
+    one = htons(1);## 29 ##src/udpcksum/senddnsquery-libnet.c##
+    memcpy(ptr, &one, 2);       /* query type = A */## 30 ##src/udpcksum/senddnsquery-libnet.c##
+    ptr += 2;## 31 ##src/udpcksum/senddnsquery-libnet.c##
+    memcpy(ptr, &one, 2);       /* query class = 1 (IP addr) */## 32 ##src/udpcksum/senddnsquery-libnet.c##
+
+    /* Build the DNS packet. */## 33 ##src/udpcksum/senddnsquery-libnet.c##
+    dns_tag = libnet_build_dnsv4(1234 /* identification */ ,## 34 ##src/udpcksum/senddnsquery-libnet.c##
+                                 0x0100 /* flags: recursion desired */ ,## 35 ##src/udpcksum/senddnsquery-libnet.c##
+                                 1 /* #questions */ , 0 /* #answer RRs */ ,## 36 ##src/udpcksum/senddnsquery-libnet.c##
+                                 0 /* #authority RRs */ ,## 37 ##src/udpcksum/senddnsquery-libnet.c##
+                                 0 /* #additional RRs */ ,## 38 ##src/udpcksum/senddnsquery-libnet.c##
+                                 qbuf /* query */ ,## 39 ##src/udpcksum/senddnsquery-libnet.c##
+                                 24 /* length of query */ , l, dns_tag);## 40 ##src/udpcksum/senddnsquery-libnet.c##
+    /* Build the UDP header. */## 41 ##src/udpcksum/senddnsquery-libnet.c##
+    udp_tag = libnet_build_udp(((struct sockaddr_in *) local)->## 42 ##src/udpcksum/senddnsquery-libnet.c##
+                               sin_port /* source port */ ,## 43 ##src/udpcksum/senddnsquery-libnet.c##
+                               ((struct sockaddr_in *) dest)->## 44 ##src/udpcksum/senddnsquery-libnet.c##
+                               sin_port /* dest port */ ,## 45 ##src/udpcksum/senddnsquery-libnet.c##
+                               packet_size /* length */ , 0 /* checksum */ ,## 46 ##src/udpcksum/senddnsquery-libnet.c##
+                               NULL /* payload */ , 0 /* payload length */ ,## 47 ##src/udpcksum/senddnsquery-libnet.c##
+                               l, udp_tag);## 48 ##src/udpcksum/senddnsquery-libnet.c##
+    /* Since we specified the checksum as 0, libnet will automatically */## 49 ##src/udpcksum/senddnsquery-libnet.c##
+    /* calculate the udp checksum.  Turn it off if the user doesn't want it */## 50 ##src/udpcksum/senddnsquery-libnet.c##
+    if (zerosum)## 51 ##src/udpcksum/senddnsquery-libnet.c##
+        if (libnet_toggle_checksum(l, udp_tag, LIBNET_OFF) < 0)## 52 ##src/udpcksum/senddnsquery-libnet.c##
+            err_quit("turning off checksums: %s\n", libnet_geterror(l));## 53 ##src/udpcksum/senddnsquery-libnet.c##
+    /* Build the IP header. */## 54 ##src/udpcksum/senddnsquery-libnet.c##
+    ip_tag = libnet_build_ipv4(packet_size + LIBNET_IPV4_H /* len */,## 55 ##src/udpcksum/senddnsquery-libnet.c##
+            0 /* tos */, 0 /* IP ID */, 0 /* fragment */,## 56 ##src/udpcksum/senddnsquery-libnet.c##
+            TTL_OUT /* ttl */, IPPROTO_UDP /* protocol */,## 57 ##src/udpcksum/senddnsquery-libnet.c##
+            0 /* checksum */,## 58 ##src/udpcksum/senddnsquery-libnet.c##
+            ((struct sockaddr_in *) local)->sin_addr.s_addr /* source */,## 59 ##src/udpcksum/senddnsquery-libnet.c##
+            ((struct sockaddr_in *) dest)->sin_addr.s_addr /* dest */,## 60 ##src/udpcksum/senddnsquery-libnet.c##
+            NULL /* payload */, 0 /* payload length */, l, ip_tag);## 61 ##src/udpcksum/senddnsquery-libnet.c##
+
+    if (libnet_write(l) < 0) {## 62 ##src/udpcksum/senddnsquery-libnet.c##
+        err_quit("libnet_write: %s\n", libnet_geterror(l));## 63 ##src/udpcksum/senddnsquery-libnet.c##
+    }## 64 ##src/udpcksum/senddnsquery-libnet.c##
+    if (verbose)## 65 ##src/udpcksum/senddnsquery-libnet.c##
+        printf("sent: %d bytes of data\n", packet_size);## 66 ##src/udpcksum/senddnsquery-libnet.c##
+}## 67 ##src/udpcksum/senddnsquery-libnet.c##
+/* end send_dns_query_libnet */
diff --git a/udpcksum/senddnsquery-raw.c b/udpcksum/senddnsquery-raw.c
new file mode 100644 (file)
index 0000000..1f16875
--- /dev/null
@@ -0,0 +1,43 @@
+#include       "udpcksum.h"
+
+/*
+ * Build a DNS A query for "a.root-servers.net" and write it to
+ * the raw socket.
+ */
+
+/* include send_dns_query */
+void
+send_dns_query(void)
+{
+       size_t          nbytes;
+       char            *buf, *ptr;
+
+       buf = Malloc(sizeof(struct udpiphdr) + 100);
+       ptr = buf + sizeof(struct udpiphdr);/* leave room for IP/UDP headers */
+
+       *((uint16_t *) ptr) = htons(1234);      /* identification */
+       ptr += 2;
+       *((uint16_t *) ptr) = htons(0x0100);    /* flags: recursion desired */
+       ptr += 2;
+       *((uint16_t *) ptr) = htons(1);         /* # questions */
+       ptr += 2;
+       *((uint16_t *) ptr) = 0;                        /* # answer RRs */
+       ptr += 2;
+       *((uint16_t *) ptr) = 0;                        /* # authority RRs */
+       ptr += 2;
+       *((uint16_t *) ptr) = 0;                        /* # additional RRs */
+       ptr += 2;
+
+       memcpy(ptr, "\001a\014root-servers\003net\000", 20);
+       ptr += 20;
+       *((uint16_t *) ptr) = htons(1);         /* query type = A */
+       ptr += 2;
+       *((uint16_t *) ptr) = htons(1);         /* query class = 1 (IP addr) */
+       ptr += 2;
+
+       nbytes = (ptr - buf) - sizeof(struct udpiphdr);
+       udp_write(buf, nbytes);
+       if (verbose)
+               printf("sent: %d bytes of data\n", nbytes);
+}
+/* end send_dns_query */
diff --git a/udpcksum/senddnsquery-raw.lc b/udpcksum/senddnsquery-raw.lc
new file mode 100644 (file)
index 0000000..1ad6f8d
--- /dev/null
@@ -0,0 +1,44 @@
+#include    "udpcksum.h"##  1 ##src/udpcksum/senddnsquery-raw.c##
+
+/*##  2 ##src/udpcksum/senddnsquery-raw.c##
+ * Build a DNS A query for "a.root-servers.net" and write it to##  3 ##src/udpcksum/senddnsquery-raw.c##
+ * the raw socket.##  4 ##src/udpcksum/senddnsquery-raw.c##
+ */##  5 ##src/udpcksum/senddnsquery-raw.c##
+
+/* include send_dns_query */
+void##  6 ##src/udpcksum/senddnsquery-raw.c##
+send_dns_query(void)##  7 ##src/udpcksum/senddnsquery-raw.c##
+{##  8 ##src/udpcksum/senddnsquery-raw.c##
+    size_t  nbytes;##  9 ##src/udpcksum/senddnsquery-raw.c##
+    char    buf[sizeof(struct udpiphdr) + 100], *ptr;## 10 ##src/udpcksum/senddnsquery-raw.c##
+    uint16_t one;## 11 ##src/udpcksum/senddnsquery-raw.c##
+
+    ptr = buf + sizeof(struct udpiphdr);    /* leave room for IP/UDP headers */## 12 ##src/udpcksum/senddnsquery-raw.c##
+
+    *((uint16_t *) ptr) = htons(1234);  /* identification */## 13 ##src/udpcksum/senddnsquery-raw.c##
+    ptr += 2;## 14 ##src/udpcksum/senddnsquery-raw.c##
+    *((uint16_t *) ptr) = htons(0x0100);    /* flags: recursion desired */## 15 ##src/udpcksum/senddnsquery-raw.c##
+    ptr += 2;## 16 ##src/udpcksum/senddnsquery-raw.c##
+    *((uint16_t *) ptr) = htons(1); /* #questions */## 17 ##src/udpcksum/senddnsquery-raw.c##
+    ptr += 2;## 18 ##src/udpcksum/senddnsquery-raw.c##
+    *((uint16_t *) ptr) = 0;    /* #answer RRs */## 19 ##src/udpcksum/senddnsquery-raw.c##
+    ptr += 2;## 20 ##src/udpcksum/senddnsquery-raw.c##
+    *((uint16_t *) ptr) = 0;    /* #authority RRs */## 21 ##src/udpcksum/senddnsquery-raw.c##
+    ptr += 2;## 22 ##src/udpcksum/senddnsquery-raw.c##
+    *((uint16_t *) ptr) = 0;    /* #additional RRs */## 23 ##src/udpcksum/senddnsquery-raw.c##
+    ptr += 2;## 24 ##src/udpcksum/senddnsquery-raw.c##
+
+    memcpy(ptr, "\001a\014root-servers\003net\000", 20);## 25 ##src/udpcksum/senddnsquery-raw.c##
+    ptr += 20;## 26 ##src/udpcksum/senddnsquery-raw.c##
+    one = htons(1);## 27 ##src/udpcksum/senddnsquery-raw.c##
+    memcpy(ptr, &one, 2);       /* query type = A */## 28 ##src/udpcksum/senddnsquery-raw.c##
+    ptr += 2;## 29 ##src/udpcksum/senddnsquery-raw.c##
+    memcpy(ptr, &one, 2);       /* query class = 1 (IP addr) */## 30 ##src/udpcksum/senddnsquery-raw.c##
+    ptr += 2;## 31 ##src/udpcksum/senddnsquery-raw.c##
+
+    nbytes = 36;## 32 ##src/udpcksum/senddnsquery-raw.c##
+    udp_write(buf, nbytes);## 33 ##src/udpcksum/senddnsquery-raw.c##
+    if (verbose)## 34 ##src/udpcksum/senddnsquery-raw.c##
+        printf("sent: %d bytes of data\n", nbytes);## 35 ##src/udpcksum/senddnsquery-raw.c##
+}## 36 ##src/udpcksum/senddnsquery-raw.c##
+/* end send_dns_query */
diff --git a/udpcksum/udpcksum.c b/udpcksum/udpcksum.c
new file mode 100644 (file)
index 0000000..d6e7929
--- /dev/null
@@ -0,0 +1,49 @@
+/* include sig_alrm */
+#include       "udpcksum.h"
+#include       <setjmp.h>
+
+static sigjmp_buf      jmpbuf;
+static int                     canjump;
+
+void
+sig_alrm(int signo)
+{
+       if (canjump == 0)
+               return;
+       siglongjmp(jmpbuf, 1);
+}
+/* end sig_alrm */
+
+/* include test_udp */
+void
+test_udp(void)
+{
+       volatile int    nsent = 0, timeout = 3;
+       struct udpiphdr *ui;
+
+       Signal(SIGALRM, sig_alrm);
+
+       if (sigsetjmp(jmpbuf, 1)) {
+               if (nsent >= 3)
+                       err_quit("no response");
+               printf("timeout\n");
+               timeout *= 2;           /* exponential backoff: 3, 6, 12 */
+       }
+       canjump = 1;    /* siglongjmp is now OK */
+
+       send_dns_query();
+       nsent++;
+
+       alarm(timeout);
+       ui = udp_read();
+       canjump = 0;
+       alarm(0);
+
+       if (ui->ui_sum == 0)
+               printf("UDP checksums off\n");
+       else
+               printf("UDP checksums on\n");
+       if (verbose)
+               printf("received UDP checksum = %x\n", ntohs(ui->ui_sum));
+}
+/* end test_udp */
diff --git a/udpcksum/udpcksum.h b/udpcksum/udpcksum.h
new file mode 100644 (file)
index 0000000..f48842b
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unp.h"
+#include       <pcap.h>
+
+#include       <netinet/in_systm.h>    /* required for ip.h */
+#include       <netinet/in.h>
+#include       <netinet/ip.h>
+#include       <netinet/ip_var.h>
+#include       <netinet/udp.h>
+#include       <netinet/udp_var.h>
+#include       <net/if.h>
+#include       <netinet/if_ether.h>
+
+#define        TTL_OUT         64                              /* outgoing TTL */
+
+                                       /* declare global variables */
+extern struct sockaddr *dest, *local;
+extern socklen_t               destlen, locallen;
+extern int             datalink;
+extern char    *device;
+extern pcap_t  *pd;
+extern int             rawfd;
+extern int             snaplen;
+extern int             verbose;
+extern int             zerosum;
+
+                                       /* function prototypes */
+void                    cleanup(int);
+char                   *next_pcap(int *);
+void                    open_output(void);
+void                    open_pcap(void);
+void                    send_dns_query(void);
+void                    test_udp(void);
+void                    udp_write(char *, int);
+struct udpiphdr *udp_read(void);
diff --git a/udpcksum/udpcksum.lc b/udpcksum/udpcksum.lc
new file mode 100644 (file)
index 0000000..fc765db
--- /dev/null
@@ -0,0 +1,49 @@
+/* include sig_alrm */
+#include    "udpcksum.h"##  1 ##src/udpcksum/udpcksum.c##
+#include    <setjmp.h>##  2 ##src/udpcksum/udpcksum.c##
+
+static sigjmp_buf jmpbuf;##  3 ##src/udpcksum/udpcksum.c##
+static int canjump;##  4 ##src/udpcksum/udpcksum.c##
+
+void##  5 ##src/udpcksum/udpcksum.c##
+sig_alrm(int signo)##  6 ##src/udpcksum/udpcksum.c##
+{##  7 ##src/udpcksum/udpcksum.c##
+    if (canjump == 0)##  8 ##src/udpcksum/udpcksum.c##
+        return;##  9 ##src/udpcksum/udpcksum.c##
+    siglongjmp(jmpbuf, 1);## 10 ##src/udpcksum/udpcksum.c##
+}## 11 ##src/udpcksum/udpcksum.c##
+/* end sig_alrm */
+
+/* include test_udp */
+void## 12 ##src/udpcksum/udpcksum.c##
+test_udp(void)## 13 ##src/udpcksum/udpcksum.c##
+{## 14 ##src/udpcksum/udpcksum.c##
+    volatile int nsent = 0, timeout = 3;## 15 ##src/udpcksum/udpcksum.c##
+    struct udpiphdr *ui;## 16 ##src/udpcksum/udpcksum.c##
+
+    Signal(SIGALRM, sig_alrm);## 17 ##src/udpcksum/udpcksum.c##
+
+    if (sigsetjmp(jmpbuf, 1)) {## 18 ##src/udpcksum/udpcksum.c##
+        if (nsent >= 3)## 19 ##src/udpcksum/udpcksum.c##
+            err_quit("no response");## 20 ##src/udpcksum/udpcksum.c##
+        printf("timeout\n");## 21 ##src/udpcksum/udpcksum.c##
+        timeout *= 2;           /* exponential backoff: 3, 6, 12 */## 22 ##src/udpcksum/udpcksum.c##
+    }## 23 ##src/udpcksum/udpcksum.c##
+    canjump = 1;                /* siglongjmp is now OK */## 24 ##src/udpcksum/udpcksum.c##
+
+    send_dns_query();## 25 ##src/udpcksum/udpcksum.c##
+    nsent++;## 26 ##src/udpcksum/udpcksum.c##
+
+    alarm(timeout);## 27 ##src/udpcksum/udpcksum.c##
+    ui = udp_read();## 28 ##src/udpcksum/udpcksum.c##
+    canjump = 0;## 29 ##src/udpcksum/udpcksum.c##
+    alarm(0);## 30 ##src/udpcksum/udpcksum.c##
+
+    if (ui->ui_sum == 0)## 31 ##src/udpcksum/udpcksum.c##
+        printf("UDP checksums off\n");## 32 ##src/udpcksum/udpcksum.c##
+    else## 33 ##src/udpcksum/udpcksum.c##
+        printf("UDP checksums on\n");## 34 ##src/udpcksum/udpcksum.c##
+    if (verbose)## 35 ##src/udpcksum/udpcksum.c##
+        printf("received UDP checksum = %x\n", ntohs(ui->ui_sum));## 36 ##src/udpcksum/udpcksum.c##
+}## 37 ##src/udpcksum/udpcksum.c##
+/* end test_udp */
diff --git a/udpcksum/udpread.c b/udpcksum/udpread.c
new file mode 100644 (file)
index 0000000..5499963
--- /dev/null
@@ -0,0 +1,85 @@
+#include       "udpcksum.h"
+
+struct udpiphdr        *udp_check(char *, int);
+
+/*
+ * Read from the network until a UDP datagram is read that matches
+ * the arguments.
+ */
+
+/* include udp_read */
+struct udpiphdr *
+udp_read(void)
+{
+       int                                     len;
+       char                            *ptr;
+       struct ether_header     *eptr;
+
+       for ( ; ; ) {
+               ptr = next_pcap(&len);
+
+               switch (datalink) {
+               case DLT_NULL:  /* loopback header = 4 bytes */
+                       return(udp_check(ptr+4, len-4));
+
+               case DLT_EN10MB:
+                       eptr = (struct ether_header *) ptr;
+                       if (ntohs(eptr->ether_type) != ETHERTYPE_IP)
+                               err_quit("Ethernet type %x not IP", ntohs(eptr->ether_type));
+                       return(udp_check(ptr+14, len-14));
+
+               case DLT_SLIP:  /* SLIP header = 24 bytes */
+                       return(udp_check(ptr+24, len-24));
+
+               case DLT_PPP:   /* PPP header = 24 bytes */
+                       return(udp_check(ptr+24, len-24));
+
+               default:
+                       err_quit("unsupported datalink (%d)", datalink);
+               }
+       }
+}
+/* end udp_read */
+
+/*
+ * Check the received packet.
+ * If UDP and OK, return pointer to packet.
+ * If ICMP error, return NULL.
+ * We assume the filter picks out desired UDP datagrams.
+ */
+
+/* include udp_check */
+struct udpiphdr *
+udp_check(char *ptr, int len)
+{
+       int                                     hlen;
+       struct ip                       *ip;
+       struct udpiphdr         *ui;
+/* *INDENT-OFF* */
+
+       if (len < sizeof(struct ip) + sizeof(struct udphdr))
+               err_quit("len = %d", len);
+/* *INDENT-ON* */
+
+               /* 4minimal verification of IP header */
+       ip = (struct ip *) ptr;
+       if (ip->ip_v != IPVERSION)
+               err_quit("ip_v = %d", ip->ip_v);
+       hlen = ip->ip_hl << 2;
+/* *INDENT-OFF* */
+       if (hlen < sizeof(struct ip))
+               err_quit("ip_hl = %d", ip->ip_hl);
+       if (len < hlen + sizeof(struct udphdr))
+               err_quit("len = %d, hlen = %d", len, hlen);
+/* *INDENT-ON* */
+
+       if ( (ip->ip_sum = in_cksum((uint16_t *) ip, hlen)) != 0)
+               err_quit("ip checksum error");
+
+       if (ip->ip_p == IPPROTO_UDP) {
+               ui = (struct udpiphdr *) ip;
+               return(ui);
+       } else
+               err_quit("not a UDP packet");
+}
+/* end udp_check */
diff --git a/udpcksum/udpread.c.bad b/udpcksum/udpread.c.bad
new file mode 100644 (file)
index 0000000..36dff4b
--- /dev/null
@@ -0,0 +1,85 @@
+#include       "udpcksum.h"
+
+struct udpiphdr *udp_check (char *, int);
+
+/*
+ * Read from the network until a UDP datagram is read that matches
+ * the arguments.
+ */
+
+/* include udp_read */
+struct udpiphdr *
+udp_read (void)
+{
+  int len;
+  char *ptr;
+  struct ether_header *eptr;
+
+  for (;;)
+    {
+      ptr = next_pcap (&len);
+
+      switch (datalink)
+       {
+       case DLT_NULL:          /* loopback header = 4 bytes */
+         return (udp_check (ptr + 4, len - 4));
+
+       case DLT_EN10MB:
+         eptr = (struct ether_header *) ptr;
+         if (ntohs (eptr->ether_type) != ETHERTYPE_IP)
+           err_quit ("Ethernet type %x not IP", ntohs (eptr->ether_type));
+         return (udp_check (ptr + 14, len - 14));
+
+       case DLT_SLIP:          /* SLIP header = 24 bytes */
+         return (udp_check (ptr + 24, len - 24));
+
+       case DLT_PPP:           /* PPP header = 24 bytes */
+         return (udp_check (ptr + 24, len - 24));
+
+       default:
+         err_quit ("unsupported data link (%d)", datalink);
+       }
+    }
+}
+/* end udp_read */
+
+/*
+ * Check the received packet.
+ * If UDP and OK, return pointer to packet.
+ * If ICMP error, return NULL.
+ * We assume the filter picks out desired UDP datagrams.
+ */
+
+/* include udp_check */
+struct udpiphdr *
+udp_check (char *ptr, int len)
+{
+  int hlen;
+  struct ip *ip;
+  struct udpiphdr *ui;
+
+  if (len < sizeof (struct ip) + sizeof (struct udphdr))
+      err_quit ("len = %d", len);
+
+  /* minimal verification of IP header */
+  ip = (struct ip *) ptr;
+  if (ip->ip_v != IPVERSION)
+    err_quit ("ip_v = %d", ip->ip_v);
+  hlen = ip->ip_hl << 2;
+  if (hlen < sizeof (struct ip))
+      err_quit ("ip_hl = %d", ip->ip_hl);
+  if (len < hlen + sizeof (struct udphdr))
+      err_quit ("len = %d, hlen = %d", len, hlen);
+
+  if ((ip->ip_sum = in_cksum ((u_short *) ip, hlen)) != 0)
+    err_quit ("ip checksum error");
+
+  if (ip->ip_p == IPPROTO_UDP)
+    {
+      ui = (struct udpiphdr *) ip;
+      return (ui);
+    }
+  else
+    err_quit ("not a UDP packet");
+}
+/* end udp_check */
diff --git a/udpcksum/udpread.lc b/udpcksum/udpread.lc
new file mode 100644 (file)
index 0000000..c5eb376
--- /dev/null
@@ -0,0 +1,81 @@
+#include    "udpcksum.h"##  1 ##src/udpcksum/udpread.c##
+
+struct udpiphdr *udp_check(char *, int);##  2 ##src/udpcksum/udpread.c##
+
+/*##  3 ##src/udpcksum/udpread.c##
+ * Read from the network until a UDP datagram is read that matches##  4 ##src/udpcksum/udpread.c##
+ * the arguments.##  5 ##src/udpcksum/udpread.c##
+ */##  6 ##src/udpcksum/udpread.c##
+
+/* include udp_read */
+struct udpiphdr *##  7 ##src/udpcksum/udpread.c##
+udp_read(void)##  8 ##src/udpcksum/udpread.c##
+{##  9 ##src/udpcksum/udpread.c##
+    int     len;## 10 ##src/udpcksum/udpread.c##
+    char   *ptr;## 11 ##src/udpcksum/udpread.c##
+    struct ether_header *eptr;## 12 ##src/udpcksum/udpread.c##
+
+    for (;;) {## 13 ##src/udpcksum/udpread.c##
+        ptr = next_pcap(&len);## 14 ##src/udpcksum/udpread.c##
+
+        switch (datalink) {## 15 ##src/udpcksum/udpread.c##
+        case DLT_NULL:          /* loopback header = 4 bytes */## 16 ##src/udpcksum/udpread.c##
+            return (udp_check(ptr + 4, len - 4));## 17 ##src/udpcksum/udpread.c##
+
+        case DLT_EN10MB:## 18 ##src/udpcksum/udpread.c##
+            eptr = (struct ether_header *) ptr;## 19 ##src/udpcksum/udpread.c##
+            if (ntohs(eptr->ether_type) != ETHERTYPE_IP)## 20 ##src/udpcksum/udpread.c##
+                err_quit("Ethernet type %x not IP", ntohs(eptr->ether_type));## 21 ##src/udpcksum/udpread.c##
+            return (udp_check(ptr + 14, len - 14));## 22 ##src/udpcksum/udpread.c##
+
+        case DLT_SLIP:          /* SLIP header = 24 bytes */## 23 ##src/udpcksum/udpread.c##
+            return (udp_check(ptr + 24, len - 24));## 24 ##src/udpcksum/udpread.c##
+
+        case DLT_PPP:           /* PPP header = 24 bytes */## 25 ##src/udpcksum/udpread.c##
+            return (udp_check(ptr + 24, len - 24));## 26 ##src/udpcksum/udpread.c##
+
+        default:## 27 ##src/udpcksum/udpread.c##
+            err_quit("unsupported datalink (%d)", datalink);## 28 ##src/udpcksum/udpread.c##
+        }## 29 ##src/udpcksum/udpread.c##
+    }## 30 ##src/udpcksum/udpread.c##
+}## 31 ##src/udpcksum/udpread.c##
+/* end udp_read */
+
+/*## 32 ##src/udpcksum/udpread.c##
+ * Check the received packet.## 33 ##src/udpcksum/udpread.c##
+ * If UDP and OK, return pointer to packet.## 34 ##src/udpcksum/udpread.c##
+ * If ICMP error, return NULL.## 35 ##src/udpcksum/udpread.c##
+ * We assume the filter picks out desired UDP datagrams.## 36 ##src/udpcksum/udpread.c##
+ */## 37 ##src/udpcksum/udpread.c##
+
+/* include udp_check */
+struct udpiphdr *## 38 ##src/udpcksum/udpread.c##
+udp_check(char *ptr, int len)## 39 ##src/udpcksum/udpread.c##
+{## 40 ##src/udpcksum/udpread.c##
+    int     hlen;## 41 ##src/udpcksum/udpread.c##
+    struct ip *ip;## 42 ##src/udpcksum/udpread.c##
+    struct udpiphdr *ui;## 43 ##src/udpcksum/udpread.c##
+
+    if (len < sizeof(struct ip) + sizeof(struct udphdr))## 44 ##src/udpcksum/udpread.c##
+        err_quit("len = %d", len);## 45 ##src/udpcksum/udpread.c##
+
+    /* 4minimal verification of IP header */## 46 ##src/udpcksum/udpread.c##
+    ip = (struct ip *) ptr;## 47 ##src/udpcksum/udpread.c##
+    if (ip->ip_v != IPVERSION)## 48 ##src/udpcksum/udpread.c##
+        err_quit("ip_v = %d", ip->ip_v);## 49 ##src/udpcksum/udpread.c##
+    hlen = ip->ip_hl << 2;## 50 ##src/udpcksum/udpread.c##
+    if (hlen < sizeof(struct ip))## 51 ##src/udpcksum/udpread.c##
+        err_quit("ip_hl = %d", ip->ip_hl);## 52 ##src/udpcksum/udpread.c##
+    if (len < hlen + sizeof(struct udphdr))## 53 ##src/udpcksum/udpread.c##
+        err_quit("len = %d, hlen = %d", len, hlen);## 54 ##src/udpcksum/udpread.c##
+
+    if ((ip->ip_sum = in_cksum((uint16_t *) ip, hlen)) != 0)## 55 ##src/udpcksum/udpread.c##
+        err_quit("ip checksum error");## 56 ##src/udpcksum/udpread.c##
+
+    if (ip->ip_p == IPPROTO_UDP) {## 57 ##src/udpcksum/udpread.c##
+        ui = (struct udpiphdr *) ip;## 58 ##src/udpcksum/udpread.c##
+        return (ui);## 59 ##src/udpcksum/udpread.c##
+    } else## 60 ##src/udpcksum/udpread.c##
+        err_quit("not a UDP packet");## 61 ##src/udpcksum/udpread.c##
+}## 62 ##src/udpcksum/udpread.c##
+/* end udp_check */
diff --git a/udpcksum/udpwrite.c b/udpcksum/udpwrite.c
new file mode 100644 (file)
index 0000000..0329aec
--- /dev/null
@@ -0,0 +1,74 @@
+#include       "udpcksum.h"
+
+/* include open_output_raw */
+int            rawfd;                  /* raw socket to write on */
+
+void
+open_output(void)
+{
+       int     on=1;
+       /*
+        * Need a raw socket to write our own IP datagrams to.
+        * Process must have superuser privileges to create this socket.
+        * Also must set IP_HDRINCL so we can write our own IP headers.
+        */
+
+       rawfd = Socket(dest->sa_family, SOCK_RAW, 0);
+
+       Setsockopt(rawfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));
+}
+/* end open_output_raw */
+
+/*
+ * "buf" points to an empty IP/UDP header,
+ * followed by "ulen" bytes of user data.
+ */
+
+/* include udp_write */
+void
+udp_write(char *buf, int userlen)
+{
+       struct udpiphdr         *ui;
+       struct ip                       *ip;
+
+               /* 4fill in and checksum UDP header */
+       ip = (struct ip *) buf;
+       ui = (struct udpiphdr *) buf;
+       bzero(ui, sizeof(*ui));
+                       /* 8add 8 to userlen for pseudoheader length */
+       ui->ui_len = htons((uint16_t) (sizeof(struct udphdr) + userlen));
+                       /* 8then add 28 for IP datagram length */
+       userlen += sizeof(struct udpiphdr);
+
+       ui->ui_pr = IPPROTO_UDP;
+       ui->ui_src.s_addr = ((struct sockaddr_in *) local)->sin_addr.s_addr;
+       ui->ui_dst.s_addr = ((struct sockaddr_in *) dest)->sin_addr.s_addr;
+       ui->ui_sport = ((struct sockaddr_in *) local)->sin_port;
+       ui->ui_dport = ((struct sockaddr_in *) dest)->sin_port;
+       ui->ui_ulen = ui->ui_len;
+       if (zerosum == 0) {
+#if 1  /* change to if 0 for Solaris 2.x, x < 6 */
+               if ( (ui->ui_sum = in_cksum((u_int16_t *) ui, userlen)) == 0)
+                       ui->ui_sum = 0xffff;
+#else
+               ui->ui_sum = ui->ui_len;
+#endif
+       }
+
+               /* 4fill in rest of IP header; */
+               /* 4ip_output() calcuates & stores IP header checksum */
+       ip->ip_v = IPVERSION;
+       ip->ip_hl = sizeof(struct ip) >> 2;
+       ip->ip_tos = 0;
+#if defined(linux) || defined(__OpenBSD__)
+       ip->ip_len = htons(userlen);    /* network byte order */
+#else
+       ip->ip_len = userlen;                   /* host byte order */
+#endif
+       ip->ip_id = 0;                  /* let IP set this */
+       ip->ip_off = 0;                 /* frag offset, MF and DF flags */
+       ip->ip_ttl = TTL_OUT;
+
+       Sendto(rawfd, buf, userlen, 0, dest, destlen);
+}
+/* end udp_write */
diff --git a/udpcksum/udpwrite.lc b/udpcksum/udpwrite.lc
new file mode 100644 (file)
index 0000000..7da7a30
--- /dev/null
@@ -0,0 +1,74 @@
+#include    "udpcksum.h"##  1 ##src/udpcksum/udpwrite.c##
+
+/* include open_output_raw */
+int     rawfd;                  /* raw socket to write on */##  2 ##src/udpcksum/udpwrite.c##
+
+void##  3 ##src/udpcksum/udpwrite.c##
+open_output(void)##  4 ##src/udpcksum/udpwrite.c##
+{##  5 ##src/udpcksum/udpwrite.c##
+    int     on = 1;##  6 ##src/udpcksum/udpwrite.c##
+    /* ##  7 ##src/udpcksum/udpwrite.c##
+     * Need a raw socket to write our own IP datagrams to.##  8 ##src/udpcksum/udpwrite.c##
+     * Process must have superuser privileges to create this socket.##  9 ##src/udpcksum/udpwrite.c##
+     * Also must set IP_HDRINCL so we can write our own IP headers.## 10 ##src/udpcksum/udpwrite.c##
+     */## 11 ##src/udpcksum/udpwrite.c##
+
+    rawfd = Socket(dest->sa_family, SOCK_RAW, 0);## 12 ##src/udpcksum/udpwrite.c##
+
+    Setsockopt(rawfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));## 13 ##src/udpcksum/udpwrite.c##
+}## 14 ##src/udpcksum/udpwrite.c##
+/* end open_output_raw */
+
+/*## 15 ##src/udpcksum/udpwrite.c##
+ * "buf" points to an empty IP/UDP header,## 16 ##src/udpcksum/udpwrite.c##
+ * followed by "ulen" bytes of user data.## 17 ##src/udpcksum/udpwrite.c##
+ */## 18 ##src/udpcksum/udpwrite.c##
+
+/* include udp_write */
+void## 19 ##src/udpcksum/udpwrite.c##
+udp_write(char *buf, int userlen)## 20 ##src/udpcksum/udpwrite.c##
+{## 21 ##src/udpcksum/udpwrite.c##
+    struct udpiphdr *ui;## 22 ##src/udpcksum/udpwrite.c##
+    struct ip *ip;## 23 ##src/udpcksum/udpwrite.c##
+
+    /* 4Fill in and checksum UDP header */## 24 ##src/udpcksum/udpwrite.c##
+    ip = (struct ip *) buf;## 25 ##src/udpcksum/udpwrite.c##
+    ui = (struct udpiphdr *) buf;## 26 ##src/udpcksum/udpwrite.c##
+    bzero(ui, sizeof(*ui));## 27 ##src/udpcksum/udpwrite.c##
+    /* 8add 8 to userlen for pseudo-header length */## 28 ##src/udpcksum/udpwrite.c##
+    ui->ui_len = htons((uint16_t) (sizeof(struct udphdr) + userlen));## 29 ##src/udpcksum/udpwrite.c##
+    /* 8then add 28 for IP datagram length */## 30 ##src/udpcksum/udpwrite.c##
+    userlen += sizeof(struct udpiphdr);## 31 ##src/udpcksum/udpwrite.c##
+
+    ui->ui_pr = IPPROTO_UDP;## 32 ##src/udpcksum/udpwrite.c##
+    ui->ui_src.s_addr = ((struct sockaddr_in *) local)->sin_addr.s_addr;## 33 ##src/udpcksum/udpwrite.c##
+    ui->ui_dst.s_addr = ((struct sockaddr_in *) dest)->sin_addr.s_addr;## 34 ##src/udpcksum/udpwrite.c##
+    ui->ui_sport = ((struct sockaddr_in *) local)->sin_port;## 35 ##src/udpcksum/udpwrite.c##
+    ui->ui_dport = ((struct sockaddr_in *) dest)->sin_port;## 36 ##src/udpcksum/udpwrite.c##
+    ui->ui_ulen = ui->ui_len;## 37 ##src/udpcksum/udpwrite.c##
+    if (zerosum == 0) {## 38 ##src/udpcksum/udpwrite.c##
+#if 1                           /* change to if 0 for Solaris 2.x, x < 6 */## 39 ##src/udpcksum/udpwrite.c##
+        if ((ui->ui_sum = in_cksum((u_int16_t *) ui, userlen)) == 0)## 40 ##src/udpcksum/udpwrite.c##
+            ui->ui_sum = 0xffff;## 41 ##src/udpcksum/udpwrite.c##
+#else## 42 ##src/udpcksum/udpwrite.c##
+        ui->ui_sum = ui->ui_len;## 43 ##src/udpcksum/udpwrite.c##
+#endif## 44 ##src/udpcksum/udpwrite.c##
+    }## 45 ##src/udpcksum/udpwrite.c##
+
+    /* 4Fill in rest of IP header; */## 46 ##src/udpcksum/udpwrite.c##
+    /* 4ip_output() calcuates & stores IP header checksum */## 47 ##src/udpcksum/udpwrite.c##
+    ip->ip_v = IPVERSION;## 48 ##src/udpcksum/udpwrite.c##
+    ip->ip_hl = sizeof(struct ip) >> 2;## 49 ##src/udpcksum/udpwrite.c##
+    ip->ip_tos = 0;## 50 ##src/udpcksum/udpwrite.c##
+#if defined(linux) || defined(__OpenBSD__)## 51 ##src/udpcksum/udpwrite.c##
+    ip->ip_len = htons(userlen);    /* network byte order */## 52 ##src/udpcksum/udpwrite.c##
+#else## 53 ##src/udpcksum/udpwrite.c##
+    ip->ip_len = userlen;       /* host byte order */## 54 ##src/udpcksum/udpwrite.c##
+#endif## 55 ##src/udpcksum/udpwrite.c##
+    ip->ip_id = 0;              /* let IP set this */## 56 ##src/udpcksum/udpwrite.c##
+    ip->ip_off = 0;             /* frag offset, MF and DF flags */## 57 ##src/udpcksum/udpwrite.c##
+    ip->ip_ttl = TTL_OUT;## 58 ##src/udpcksum/udpwrite.c##
+
+    Sendto(rawfd, buf, userlen, 0, dest, destlen);## 59 ##src/udpcksum/udpwrite.c##
+}## 60 ##src/udpcksum/udpwrite.c##
+/* end udp_write */
diff --git a/udpcliserv/Makefile b/udpcliserv/Makefile
new file mode 100644 (file)
index 0000000..bdded3b
--- /dev/null
@@ -0,0 +1,49 @@
+include ../Make.defines
+
+PROGS =        udpcli01 udpserv01 udpcli02 udpcli03 udpcli04 \
+               udpcli06 udpserv06 udpserv07 udpcli08 udpcli09 udpcli10 \
+               udpservselect01
+
+all:   ${PROGS}
+
+udpcli01:      udpcli01.o
+               ${CC} ${CFLAGS} -o $@ udpcli01.o ${LIBS}
+
+udpserv01:     udpserv01.o
+               ${CC} ${CFLAGS} -o $@ udpserv01.o ${LIBS}
+
+udpcli02:      udpcli02.o dgcliaddr.o
+               ${CC} ${CFLAGS} -o $@ udpcli02.o dgcliaddr.o ${LIBS}
+
+udpcli03:      udpcli03.o dgcliinetaddr.o
+               ${CC} ${CFLAGS} -o $@ udpcli03.o dgcliinetaddr.o ${LIBS}
+
+udpcli04:      udpcli04.o dgcliconnect.o
+               ${CC} ${CFLAGS} -o $@ udpcli04.o dgcliconnect.o ${LIBS}
+
+udpcli06:      udpcli06.o dgcliloop1.o
+               ${CC} ${CFLAGS} -o $@ udpcli06.o dgcliloop1.o ${LIBS}
+
+udpserv06:     udpserv06.o dgecholoop1.o
+               ${CC} ${CFLAGS} -o $@ udpserv06.o dgecholoop1.o ${LIBS}
+
+udpcli07:      udpcli07.o dgcliloop2.o
+               ${CC} ${CFLAGS} -o $@ udpcli07.o dgcliloop2.o ${LIBS}
+
+udpserv07:     udpserv07.o dgecholoop2.o
+               ${CC} ${CFLAGS} -o $@ udpserv07.o dgecholoop2.o ${LIBS}
+
+udpcli08:      udpcli08.o dgcliloop3.o
+               ${CC} ${CFLAGS} -o $@ udpcli08.o dgcliloop3.o ${LIBS}
+
+udpcli09:      udpcli09.o
+               ${CC} ${CFLAGS} -o $@ udpcli09.o ${LIBS}
+
+udpcli10:      udpcli10.o dgclibig.o
+               ${CC} ${CFLAGS} -o $@ udpcli10.o dgclibig.o ${LIBS}
+
+udpservselect01:       udpservselect01.o sigchldwaitpid.o
+               ${CC} ${CFLAGS} -o $@ udpservselect01.o sigchldwaitpid.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/udpcliserv/dgcliaddr.c b/udpcliserv/dgcliaddr.c
new file mode 100644 (file)
index 0000000..b037ac9
--- /dev/null
@@ -0,0 +1,28 @@
+#include       "unp.h"
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                             n;
+       char                    sendline[MAXLINE], recvline[MAXLINE + 1];
+       socklen_t               len;
+       struct sockaddr *preply_addr;
+
+       preply_addr = Malloc(servlen);
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               len = servlen;
+               n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);
+               if (len != servlen || memcmp(pservaddr, preply_addr, len) != 0) {
+                       printf("reply from %s (ignored)\n",
+                                       Sock_ntop(preply_addr, len));
+                       continue;
+               }
+
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+}
diff --git a/udpcliserv/dgclibig.c b/udpcliserv/dgclibig.c
new file mode 100644 (file)
index 0000000..a425151
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+#undef MAXLINE
+#define        MAXLINE 65507
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                     size;
+       char            sendline[MAXLINE], recvline[MAXLINE + 1];
+       ssize_t         n;
+
+       size = 70000;
+       Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
+       Setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
+
+       Sendto(sockfd, sendline, MAXLINE, 0, pservaddr, servlen);
+
+       n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
+
+       printf("received %d bytes\n", n);
+}
diff --git a/udpcliserv/dgclibig.lc b/udpcliserv/dgclibig.lc
new file mode 100644 (file)
index 0000000..931401f
--- /dev/null
@@ -0,0 +1,22 @@
+#include    "unp.h"##  1 ##src/udpcliserv/dgclibig.c##
+
+#undef  MAXLINE##  2 ##src/udpcliserv/dgclibig.c##
+#define MAXLINE 65507##  3 ##src/udpcliserv/dgclibig.c##
+
+void##  4 ##src/udpcliserv/dgclibig.c##
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)##  5 ##src/udpcliserv/dgclibig.c##
+{##  6 ##src/udpcliserv/dgclibig.c##
+    int     size;##  7 ##src/udpcliserv/dgclibig.c##
+    char    sendline[MAXLINE], recvline[MAXLINE + 1];##  8 ##src/udpcliserv/dgclibig.c##
+    ssize_t n;##  9 ##src/udpcliserv/dgclibig.c##
+
+    size = 70000;## 10 ##src/udpcliserv/dgclibig.c##
+    Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));## 11 ##src/udpcliserv/dgclibig.c##
+    Setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));## 12 ##src/udpcliserv/dgclibig.c##
+
+    Sendto(sockfd, sendline, MAXLINE, 0, pservaddr, servlen);## 13 ##src/udpcliserv/dgclibig.c##
+
+    n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);## 14 ##src/udpcliserv/dgclibig.c##
+
+    printf("received %d bytes\n", n);## 15 ##src/udpcliserv/dgclibig.c##
+}## 16 ##src/udpcliserv/dgclibig.c##
diff --git a/udpcliserv/dgcliconnect.c b/udpcliserv/dgcliconnect.c
new file mode 100644 (file)
index 0000000..a65b24a
--- /dev/null
@@ -0,0 +1,20 @@
+#include       "unp.h"
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int             n;
+       char    sendline[MAXLINE], recvline[MAXLINE + 1];
+
+       Connect(sockfd, (SA *) pservaddr, servlen);
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Write(sockfd, sendline, strlen(sendline));
+
+               n = Read(sockfd, recvline, MAXLINE);
+
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+}
diff --git a/udpcliserv/dgcliconnect.lc b/udpcliserv/dgcliconnect.lc
new file mode 100644 (file)
index 0000000..6dc4026
--- /dev/null
@@ -0,0 +1,20 @@
+#include    "unp.h"##  1 ##src/udpcliserv/dgcliconnect.c##
+
+void##  2 ##src/udpcliserv/dgcliconnect.c##
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)##  3 ##src/udpcliserv/dgcliconnect.c##
+{##  4 ##src/udpcliserv/dgcliconnect.c##
+    int     n;##  5 ##src/udpcliserv/dgcliconnect.c##
+    char    sendline[MAXLINE], recvline[MAXLINE + 1];##  6 ##src/udpcliserv/dgcliconnect.c##
+
+    Connect(sockfd, (SA *) pservaddr, servlen);##  7 ##src/udpcliserv/dgcliconnect.c##
+
+    while (Fgets(sendline, MAXLINE, fp) != NULL) {##  8 ##src/udpcliserv/dgcliconnect.c##
+
+        Write(sockfd, sendline, strlen(sendline));##  9 ##src/udpcliserv/dgcliconnect.c##
+
+        n = Read(sockfd, recvline, MAXLINE);## 10 ##src/udpcliserv/dgcliconnect.c##
+
+        recvline[n] = 0;        /* null terminate */## 11 ##src/udpcliserv/dgcliconnect.c##
+        Fputs(recvline, stdout);## 12 ##src/udpcliserv/dgcliconnect.c##
+    }## 13 ##src/udpcliserv/dgcliconnect.c##
+}## 14 ##src/udpcliserv/dgcliconnect.c##
diff --git a/udpcliserv/dgcliinetaddr.c b/udpcliserv/dgcliinetaddr.c
new file mode 100644 (file)
index 0000000..b79b3a9
--- /dev/null
@@ -0,0 +1,25 @@
+#include       "unp.h"
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int                             n;
+       char                    sendline[MAXLINE], recvline[MAXLINE + 1];
+       socklen_t               len;
+       struct sockaddr_in      *replyaddr;
+
+       replyaddr = Malloc(servlen);
+
+       while (Fgets(sendline, MAXLINE, fp) != NULL) {
+
+               Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
+
+               len = servlen;
+               n = Recvfrom(sockfd, recvline, MAXLINE, 0, (SA *) replyaddr, &len);
+               printf("received reply from %s, port %d\n",
+                          inet_ntoa(replyaddr->sin_addr), htons(replyaddr->sin_port));
+
+               recvline[n] = 0;        /* null terminate */
+               Fputs(recvline, stdout);
+       }
+}
diff --git a/udpcliserv/dgcliloop1.c b/udpcliserv/dgcliloop1.c
new file mode 100644 (file)
index 0000000..cb5ce4b
--- /dev/null
@@ -0,0 +1,15 @@
+#include       "unp.h"
+
+#define        NDG             2000    /* datagrams to send */
+#define        DGLEN   1400    /* length of each datagram */
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int             i;
+       char    sendline[DGLEN];
+
+       for (i = 0; i < NDG; i++) {
+               Sendto(sockfd, sendline, DGLEN, 0, pservaddr, servlen);
+       }
+}
diff --git a/udpcliserv/dgcliloop3.c b/udpcliserv/dgcliloop3.c
new file mode 100644 (file)
index 0000000..85567f1
--- /dev/null
@@ -0,0 +1,21 @@
+#include       "unp.h"
+
+/* Try and get ENOBUFS from sendto() by sending huge datagrams.
+   But I still cannot get the error. */
+
+#define        NDG              2000   /* datagrams to send */
+#define        DGLEN   65507   /* length of each datagram */
+
+void
+dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
+{
+       int             i, n;
+       char    sendline[DGLEN];
+
+       n = 100 * 1024;
+       Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n));
+
+       for (i = 0; i < NDG; i++) {
+               Sendto(sockfd, sendline, DGLEN, 0, pservaddr, servlen);
+       }
+}
diff --git a/udpcliserv/dgecholoop1.c b/udpcliserv/dgecholoop1.c
new file mode 100644 (file)
index 0000000..c9b900b
--- /dev/null
@@ -0,0 +1,27 @@
+#include       "unp.h"
+
+static void    recvfrom_int(int);
+static int     count;
+
+void
+dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
+{
+       socklen_t       len;
+       char            mesg[MAXLINE];
+
+       Signal(SIGINT, recvfrom_int);
+
+       for ( ; ; ) {
+               len = clilen;
+               Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
+
+               count++;
+       }
+}
+
+static void
+recvfrom_int(int signo)
+{
+       printf("\nreceived %d datagrams\n", count);
+       exit(0);
+}
diff --git a/udpcliserv/dgecholoop2.c b/udpcliserv/dgecholoop2.c
new file mode 100644 (file)
index 0000000..c94b49e
--- /dev/null
@@ -0,0 +1,31 @@
+#include       "unp.h"
+
+static void    recvfrom_int(int);
+static int     count;
+
+void
+dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
+{
+       int                     n;
+       socklen_t       len;
+       char            mesg[MAXLINE];
+
+       Signal(SIGINT, recvfrom_int);
+
+       n = 220 * 1024;
+       Setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n));
+
+       for ( ; ; ) {
+               len = clilen;
+               Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
+
+               count++;
+       }
+}
+
+static void
+recvfrom_int(int signo)
+{
+       printf("\nreceived %d datagrams\n", count);
+       exit(0);
+}
diff --git a/udpcliserv/dgecholoop2.lc b/udpcliserv/dgecholoop2.lc
new file mode 100644 (file)
index 0000000..f0b39de
--- /dev/null
@@ -0,0 +1,31 @@
+#include    "unp.h"##  1 ##src/udpcliserv/dgecholoop2.c##
+
+static void recvfrom_int(int);##  2 ##src/udpcliserv/dgecholoop2.c##
+static int count;##  3 ##src/udpcliserv/dgecholoop2.c##
+
+void##  4 ##src/udpcliserv/dgecholoop2.c##
+dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)##  5 ##src/udpcliserv/dgecholoop2.c##
+{##  6 ##src/udpcliserv/dgecholoop2.c##
+    int     n;##  7 ##src/udpcliserv/dgecholoop2.c##
+    socklen_t len;##  8 ##src/udpcliserv/dgecholoop2.c##
+    char    mesg[MAXLINE];##  9 ##src/udpcliserv/dgecholoop2.c##
+
+    Signal(SIGINT, recvfrom_int);## 10 ##src/udpcliserv/dgecholoop2.c##
+
+    n = 240 * 1024;## 11 ##src/udpcliserv/dgecholoop2.c##
+    Setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n));## 12 ##src/udpcliserv/dgecholoop2.c##
+
+    for (;;) {## 13 ##src/udpcliserv/dgecholoop2.c##
+        len = clilen;## 14 ##src/udpcliserv/dgecholoop2.c##
+        Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);## 15 ##src/udpcliserv/dgecholoop2.c##
+
+        count++;## 16 ##src/udpcliserv/dgecholoop2.c##
+    }## 17 ##src/udpcliserv/dgecholoop2.c##
+}## 18 ##src/udpcliserv/dgecholoop2.c##
+
+static void## 19 ##src/udpcliserv/dgecholoop2.c##
+recvfrom_int(int signo)## 20 ##src/udpcliserv/dgecholoop2.c##
+{## 21 ##src/udpcliserv/dgecholoop2.c##
+    printf("\nreceived %d datagrams\n", count);## 22 ##src/udpcliserv/dgecholoop2.c##
+    exit(0);## 23 ##src/udpcliserv/dgecholoop2.c##
+}## 24 ##src/udpcliserv/dgecholoop2.c##
diff --git a/udpcliserv/sigchldwaitpid.c b/udpcliserv/sigchldwaitpid.c
new file mode 100644 (file)
index 0000000..12b5ff3
--- /dev/null
@@ -0,0 +1,12 @@
+#include       "unp.h"
+
+void
+sig_chld(int signo)
+{
+       pid_t   pid;
+       int             stat;
+
+       while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
+               printf("child %d terminated\n", pid);
+       return;
+}
diff --git a/udpcliserv/udpcli01.c b/udpcliserv/udpcli01.c
new file mode 100644 (file)
index 0000000..1d5a5d9
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/udpcliserv/udpcli02.c b/udpcliserv/udpcli02.c
new file mode 100644 (file)
index 0000000..71b4175
--- /dev/null
@@ -0,0 +1,25 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+#ifdef HAVE_SOCKADDR_SA_LEN
+       servaddr.sin_len = sizeof(servaddr);
+#endif
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(7);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/udpcliserv/udpcli03.c b/udpcliserv/udpcli03.c
new file mode 100644 (file)
index 0000000..01beb88
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(7);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/udpcliserv/udpcli04.c b/udpcliserv/udpcli04.c
new file mode 100644 (file)
index 0000000..1d5a5d9
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/udpcliserv/udpcli05.c b/udpcliserv/udpcli05.c
new file mode 100644 (file)
index 0000000..44c1113
--- /dev/null
@@ -0,0 +1,28 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       bzero(&cliaddr, sizeof(cliaddr));
+       cliaddr.sin_family = AF_INET;
+       cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       cliaddr.sin_port = htons(0); /* force assignment of ephemeral port */
+       Bind(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/udpcliserv/udpcli06.c b/udpcliserv/udpcli06.c
new file mode 100644 (file)
index 0000000..1d5a5d9
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/udpcliserv/udpcli08.c b/udpcliserv/udpcli08.c
new file mode 100644 (file)
index 0000000..a37ff30
--- /dev/null
@@ -0,0 +1,22 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli <IPaddress>");
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(9);           /* discard server */
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/udpcliserv/udpcli09.c b/udpcliserv/udpcli09.c
new file mode 100644 (file)
index 0000000..b5d3deb
--- /dev/null
@@ -0,0 +1,27 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       socklen_t                       len;
+       struct sockaddr_in      cliaddr, servaddr;
+
+       if (argc != 2)
+               err_quit("usage: udpcli <IPaddress>");
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family = AF_INET;
+       servaddr.sin_port = htons(SERV_PORT);
+       Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       len = sizeof(cliaddr);
+       Getsockname(sockfd, (SA *) &cliaddr, &len);
+       printf("local address %s\n", Sock_ntop((SA *) &cliaddr, len));
+
+       exit(0);
+}
diff --git a/udpcliserv/udpcli10.c b/udpcliserv/udpcli10.c
new file mode 100644 (file)
index 0000000..634b894
--- /dev/null
@@ -0,0 +1,18 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       socklen_t                       salen;
+       struct sockaddr         *sa;
+
+       if (argc != 3)
+               err_quit("usage: udpcli02 <hostname> <service>");
+
+       sockfd = Udp_client(argv[1], argv[2], (void **) &sa, &salen);
+
+       dg_cli(stdin, sockfd, sa, salen);
+
+       exit(0);
+}
diff --git a/udpcliserv/udpserv01.c b/udpcliserv/udpserv01.c
new file mode 100644 (file)
index 0000000..a21a857
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr, cliaddr;
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
+}
diff --git a/udpcliserv/udpserv06.c b/udpcliserv/udpserv06.c
new file mode 100644 (file)
index 0000000..a21a857
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr, cliaddr;
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
+}
diff --git a/udpcliserv/udpserv07.c b/udpcliserv/udpserv07.c
new file mode 100644 (file)
index 0000000..a21a857
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_in      servaddr, cliaddr;
+
+       sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
+}
diff --git a/udpcliserv/udpservselect01.c b/udpcliserv/udpservselect01.c
new file mode 100644 (file)
index 0000000..4aedf8a
--- /dev/null
@@ -0,0 +1,76 @@
+/* include udpservselect01 */
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd, udpfd, nready, maxfdp1;
+       char                            mesg[MAXLINE];
+       pid_t                           childpid;
+       fd_set                          rset;
+       ssize_t                         n;
+       socklen_t                       len;
+       const int                       on = 1;
+       struct sockaddr_in      cliaddr, servaddr;
+       void                            sig_chld(int);
+
+               /* 4create listening TCP socket */
+       listenfd = Socket(AF_INET, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+               /* 4create UDP socket */
+       udpfd = Socket(AF_INET, SOCK_DGRAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sin_family      = AF_INET;
+       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+       servaddr.sin_port        = htons(SERV_PORT);
+
+       Bind(udpfd, (SA *) &servaddr, sizeof(servaddr));
+/* end udpservselect01 */
+
+/* include udpservselect02 */
+       Signal(SIGCHLD, sig_chld);      /* must call waitpid() */
+
+       FD_ZERO(&rset);
+       maxfdp1 = max(listenfd, udpfd) + 1;
+       for ( ; ; ) {
+               FD_SET(listenfd, &rset);
+               FD_SET(udpfd, &rset);
+               if ( (nready = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {
+                       if (errno == EINTR)
+                               continue;               /* back to for() */
+                       else
+                               err_sys("select error");
+               }
+
+               if (FD_ISSET(listenfd, &rset)) {
+                       len = sizeof(cliaddr);
+                       connfd = Accept(listenfd, (SA *) &cliaddr, &len);
+       
+                       if ( (childpid = Fork()) == 0) {        /* child process */
+                               Close(listenfd);        /* close listening socket */
+                               str_echo(connfd);       /* process the request */
+                               exit(0);
+                       }
+                       Close(connfd);                  /* parent closes connected socket */
+               }
+
+               if (FD_ISSET(udpfd, &rset)) {
+                       len = sizeof(cliaddr);
+                       n = Recvfrom(udpfd, mesg, MAXLINE, 0, (SA *) &cliaddr, &len);
+
+                       Sendto(udpfd, mesg, n, 0, (SA *) &cliaddr, len);
+               }
+       }
+}
+/* end udpservselect02 */
diff --git a/udpcliserv/udpservselect01.lc b/udpcliserv/udpservselect01.lc
new file mode 100644 (file)
index 0000000..3d58628
--- /dev/null
@@ -0,0 +1,76 @@
+/* include udpservselect01 */
+#include    "unp.h"##  1 ##src/udpcliserv/udpservselect01.c##
+
+int##  2 ##src/udpcliserv/udpservselect01.c##
+main(int argc, char **argv)##  3 ##src/udpcliserv/udpservselect01.c##
+{##  4 ##src/udpcliserv/udpservselect01.c##
+    int     listenfd, connfd, udpfd, nready, maxfdp1;##  5 ##src/udpcliserv/udpservselect01.c##
+    char    mesg[MAXLINE];##  6 ##src/udpcliserv/udpservselect01.c##
+    pid_t   childpid;##  7 ##src/udpcliserv/udpservselect01.c##
+    fd_set  rset;##  8 ##src/udpcliserv/udpservselect01.c##
+    ssize_t n;##  9 ##src/udpcliserv/udpservselect01.c##
+    socklen_t len;## 10 ##src/udpcliserv/udpservselect01.c##
+    const int on = 1;## 11 ##src/udpcliserv/udpservselect01.c##
+    struct sockaddr_in cliaddr, servaddr;## 12 ##src/udpcliserv/udpservselect01.c##
+    void    sig_chld(int);## 13 ##src/udpcliserv/udpservselect01.c##
+
+    /* 4create listening TCP socket */## 14 ##src/udpcliserv/udpservselect01.c##
+    listenfd = Socket(AF_INET, SOCK_STREAM, 0);## 15 ##src/udpcliserv/udpservselect01.c##
+
+    bzero(&servaddr, sizeof(servaddr));## 16 ##src/udpcliserv/udpservselect01.c##
+    servaddr.sin_family = AF_INET;## 17 ##src/udpcliserv/udpservselect01.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 18 ##src/udpcliserv/udpservselect01.c##
+    servaddr.sin_port = htons(SERV_PORT);## 19 ##src/udpcliserv/udpservselect01.c##
+
+    Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));## 20 ##src/udpcliserv/udpservselect01.c##
+    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 21 ##src/udpcliserv/udpservselect01.c##
+
+    Listen(listenfd, LISTENQ);## 22 ##src/udpcliserv/udpservselect01.c##
+
+    /* 4create UDP socket */## 23 ##src/udpcliserv/udpservselect01.c##
+    udpfd = Socket(AF_INET, SOCK_DGRAM, 0);## 24 ##src/udpcliserv/udpservselect01.c##
+
+    bzero(&servaddr, sizeof(servaddr));## 25 ##src/udpcliserv/udpservselect01.c##
+    servaddr.sin_family = AF_INET;## 26 ##src/udpcliserv/udpservselect01.c##
+    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);## 27 ##src/udpcliserv/udpservselect01.c##
+    servaddr.sin_port = htons(SERV_PORT);## 28 ##src/udpcliserv/udpservselect01.c##
+
+    Bind(udpfd, (SA *) &servaddr, sizeof(servaddr));## 29 ##src/udpcliserv/udpservselect01.c##
+/* end udpservselect01 */
+
+/* include udpservselect02 */
+    Signal(SIGCHLD, sig_chld);  /* must call waitpid() */## 30 ##src/udpcliserv/udpservselect01.c##
+
+    FD_ZERO(&rset);## 31 ##src/udpcliserv/udpservselect01.c##
+    maxfdp1 = max(listenfd, udpfd) + 1;## 32 ##src/udpcliserv/udpservselect01.c##
+    for (;;) {## 33 ##src/udpcliserv/udpservselect01.c##
+        FD_SET(listenfd, &rset);## 34 ##src/udpcliserv/udpservselect01.c##
+        FD_SET(udpfd, &rset);## 35 ##src/udpcliserv/udpservselect01.c##
+        if ((nready = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {## 36 ##src/udpcliserv/udpservselect01.c##
+            if (errno == EINTR)## 37 ##src/udpcliserv/udpservselect01.c##
+                continue;       /* back to for() */## 38 ##src/udpcliserv/udpservselect01.c##
+            else## 39 ##src/udpcliserv/udpservselect01.c##
+                err_sys("select error");## 40 ##src/udpcliserv/udpservselect01.c##
+        }## 41 ##src/udpcliserv/udpservselect01.c##
+
+        if (FD_ISSET(listenfd, &rset)) {## 42 ##src/udpcliserv/udpservselect01.c##
+            len = sizeof(cliaddr);## 43 ##src/udpcliserv/udpservselect01.c##
+            connfd = Accept(listenfd, (SA *) &cliaddr, &len);## 44 ##src/udpcliserv/udpservselect01.c##
+
+            if ((childpid = Fork()) == 0) { /* child process */## 45 ##src/udpcliserv/udpservselect01.c##
+                Close(listenfd);    /* close listening socket */## 46 ##src/udpcliserv/udpservselect01.c##
+                str_echo(connfd);   /* process the request */## 47 ##src/udpcliserv/udpservselect01.c##
+                exit(0);## 48 ##src/udpcliserv/udpservselect01.c##
+            }## 49 ##src/udpcliserv/udpservselect01.c##
+            Close(connfd);      /* parent closes connected socket */## 50 ##src/udpcliserv/udpservselect01.c##
+        }## 51 ##src/udpcliserv/udpservselect01.c##
+
+        if (FD_ISSET(udpfd, &rset)) {## 52 ##src/udpcliserv/udpservselect01.c##
+            len = sizeof(cliaddr);## 53 ##src/udpcliserv/udpservselect01.c##
+            n = Recvfrom(udpfd, mesg, MAXLINE, 0, (SA *) &cliaddr, &len);## 54 ##src/udpcliserv/udpservselect01.c##
+
+            Sendto(udpfd, mesg, n, 0, (SA *) &cliaddr, len);## 55 ##src/udpcliserv/udpservselect01.c##
+        }## 56 ##src/udpcliserv/udpservselect01.c##
+    }## 57 ##src/udpcliserv/udpservselect01.c##
+}## 58 ##src/udpcliserv/udpservselect01.c##
+/* end udpservselect02 */
diff --git a/unixdomain/Makefile b/unixdomain/Makefile
new file mode 100644 (file)
index 0000000..0202967
--- /dev/null
@@ -0,0 +1,43 @@
+include ../Make.defines
+
+PROGS =        daytimetcpcli daytimetcpsrv2 mycat openfile \
+       tfcred01 unixbind unixstrcli01 unixstrserv01 unixstrserv02
+
+all:   ${PROGS}
+
+daytimetcpcli: daytimetcpcli.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpcli.o ${LIBS}
+
+daytimetcpsrv2:        daytimetcpsrv2.o
+               ${CC} ${CFLAGS} -o $@ daytimetcpsrv2.o ${LIBS}
+
+mycat:         mycat.o myopen.o
+               ${CC} ${CFLAGS} -o $@ mycat.o myopen.o ${LIBS}
+
+openfile:      openfile.o
+               ${CC} ${CFLAGS} -o $@ openfile.o ${LIBS}
+
+tfcred01:      tfcred01.o
+               ${CC} ${CFLAGS} -o $@ tfcred01.o ${LIBS}
+
+unixbind:      unixbind.o
+               ${CC} ${CFLAGS} -o $@ unixbind.o ${LIBS}
+
+unixdgcli01:   unixdgcli01.o
+               ${CC} ${CFLAGS} -o $@ unixdgcli01.o ${LIBS}
+
+unixdgserv01:  unixdgserv01.o
+               ${CC} ${CFLAGS} -o $@ unixdgserv01.o ${LIBS}
+
+unixstrcli01:  unixstrcli01.o
+               ${CC} ${CFLAGS} -o $@ unixstrcli01.o ${LIBS}
+
+unixstrserv01: unixstrserv01.o sigchldwaitpid.o
+               ${CC} ${CFLAGS} -o $@ unixstrserv01.o sigchldwaitpid.o ${LIBS}
+
+unixstrserv02: unixstrserv02.o strecho.o sigchldwaitpid.o readcred.o
+               ${CC} ${CFLAGS} -o $@ unixstrserv02.o strecho.o sigchldwaitpid.o \
+                               readcred.o ${LIBS}
+
+clean:
+               rm -f ${PROGS} ${CLEANFILES}
diff --git a/unixdomain/daytimetcpcli.c b/unixdomain/daytimetcpcli.c
new file mode 100644 (file)
index 0000000..975a9e7
--- /dev/null
@@ -0,0 +1,27 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                             sockfd, n;
+       char                    recvline[MAXLINE + 1];
+       socklen_t               len;
+       struct sockaddr *sa;
+
+       if (argc != 3)
+               err_quit("usage: daytimetcpcli <hostname/IPaddress> <service/port#>");
+
+       sockfd = Tcp_connect(argv[1], argv[2]);
+
+       sa = Malloc(sizeof(struct sockaddr_storage));
+       len = sizeof(struct sockaddr_storage);
+       Getpeername(sockfd, sa, &len);
+       printf("connected to %s\n", Sock_ntop_host(sa, len));
+       sleep(5);
+
+       while ( (n = Read(sockfd, recvline, MAXLINE)) > 0) {
+               recvline[n] = 0;        /* null terminate */
+               printf("%d bytes: %s", n, recvline);
+       }
+       exit(0);
+}
diff --git a/unixdomain/daytimetcpsrv2.c b/unixdomain/daytimetcpsrv2.c
new file mode 100644 (file)
index 0000000..10c8b82
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unp.h"
+#include       <time.h>
+
+int
+main(int argc, char **argv)
+{
+       int                             i, listenfd, connfd;
+       socklen_t               addrlen, len;
+       struct sockaddr *cliaddr;
+       char                    buff[MAXLINE];
+       time_t                  ticks;
+
+       if (argc == 2)
+               listenfd = Tcp_listen(NULL, argv[1], &addrlen);
+       else if (argc == 3)
+               listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
+       else
+               err_quit("usage: daytimetcpsrv2 [ <host> ] <service or port>");
+
+       cliaddr = Malloc(addrlen);
+
+       for ( ; ; ) {
+               len = addrlen;
+               connfd = Accept(listenfd, cliaddr, &len);
+               printf("connection from %s\n", Sock_ntop(cliaddr, len));
+
+        ticks = time(NULL);
+        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
+               for (i = 0; i < strlen(buff); i++)
+               Send(connfd, &buff[i], 1, MSG_EOR);
+
+               Close(connfd);
+       }
+}
diff --git a/unixdomain/mycat.c b/unixdomain/mycat.c
new file mode 100644 (file)
index 0000000..b9a5720
--- /dev/null
@@ -0,0 +1,21 @@
+#include       "unp.h"
+
+int            my_open(const char *, int);
+
+int
+main(int argc, char **argv)
+{
+       int             fd, n;
+       char    buff[BUFFSIZE];
+
+       if (argc != 2)
+               err_quit("usage: mycat <pathname>");
+
+       if ( (fd = my_open(argv[1], O_RDONLY)) < 0)
+               err_sys("cannot open %s", argv[1]);
+
+       while ( (n = Read(fd, buff, BUFFSIZE)) > 0)
+               Write(STDOUT_FILENO, buff, n);
+
+       exit(0);
+}
diff --git a/unixdomain/mycat.lc b/unixdomain/mycat.lc
new file mode 100644 (file)
index 0000000..4836627
--- /dev/null
@@ -0,0 +1,21 @@
+#include    "unp.h"##  1 ##src/unixdomain/mycat.c##
+
+int     my_open(const char *, int);##  2 ##src/unixdomain/mycat.c##
+
+int##  3 ##src/unixdomain/mycat.c##
+main(int argc, char **argv)##  4 ##src/unixdomain/mycat.c##
+{##  5 ##src/unixdomain/mycat.c##
+    int     fd, n;##  6 ##src/unixdomain/mycat.c##
+    char    buff[BUFFSIZE];##  7 ##src/unixdomain/mycat.c##
+
+    if (argc != 2)##  8 ##src/unixdomain/mycat.c##
+        err_quit("usage: mycat <pathname>");##  9 ##src/unixdomain/mycat.c##
+
+    if ((fd = my_open(argv[1], O_RDONLY)) < 0)## 10 ##src/unixdomain/mycat.c##
+        err_sys("cannot open %s", argv[1]);## 11 ##src/unixdomain/mycat.c##
+
+    while ((n = Read(fd, buff, BUFFSIZE)) > 0)## 12 ##src/unixdomain/mycat.c##
+        Write(STDOUT_FILENO, buff, n);## 13 ##src/unixdomain/mycat.c##
+
+    exit(0);## 14 ##src/unixdomain/mycat.c##
+}## 15 ##src/unixdomain/mycat.c##
diff --git a/unixdomain/myopen.c b/unixdomain/myopen.c
new file mode 100644 (file)
index 0000000..86c5c44
--- /dev/null
@@ -0,0 +1,36 @@
+#include       "unp.h"
+
+int
+my_open(const char *pathname, int mode)
+{
+       int                     fd, sockfd[2], status;
+       pid_t           childpid;
+       char            c, argsockfd[10], argmode[10];
+
+       Socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);
+
+       if ( (childpid = Fork()) == 0) {                /* child process */
+               Close(sockfd[0]);
+               snprintf(argsockfd, sizeof(argsockfd), "%d", sockfd[1]);
+               snprintf(argmode, sizeof(argmode), "%d", mode);
+               execl("./openfile", "openfile", argsockfd, pathname, argmode,
+                         (char *) NULL);
+               err_sys("execl error");
+       }
+
+       /* parent process - wait for the child to terminate */
+       Close(sockfd[1]);                       /* close the end we don't use */
+
+       Waitpid(childpid, &status, 0);
+       if (WIFEXITED(status) == 0)
+               err_quit("child did not terminate");
+       if ( (status = WEXITSTATUS(status)) == 0)
+               Read_fd(sockfd[0], &c, 1, &fd);
+       else {
+               errno = status;         /* set errno value from child's status */
+               fd = -1;
+       }
+
+       Close(sockfd[0]);
+       return(fd);
+}
diff --git a/unixdomain/openfile.c b/unixdomain/openfile.c
new file mode 100644 (file)
index 0000000..c98a1f7
--- /dev/null
@@ -0,0 +1,18 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int             fd;
+
+       if (argc != 4)
+               err_quit("openfile <sockfd#> <filename> <mode>");
+
+       if ( (fd = open(argv[2], atoi(argv[3]))) < 0)
+               exit( (errno > 0) ? errno : 255 );
+
+       if (write_fd(atoi(argv[1]), "", 1, fd) < 0)
+               exit( (errno > 0) ? errno : 255 );
+
+       exit(0);
+}
diff --git a/unixdomain/readcred.c b/unixdomain/readcred.c
new file mode 100644 (file)
index 0000000..1200ed9
--- /dev/null
@@ -0,0 +1,40 @@
+#include       "unp.h"
+
+#define        CONTROL_LEN     (sizeof(struct cmsghdr) + sizeof(struct cmsgcred))
+
+ssize_t
+read_cred(int fd, void *ptr, size_t nbytes, struct cmsgcred *cmsgcredptr)
+{
+       struct msghdr   msg;
+       struct iovec    iov[1];
+       char                    control[CONTROL_LEN];
+       int                             n;
+
+       msg.msg_name = NULL;
+       msg.msg_namelen = 0;
+       iov[0].iov_base = ptr;
+       iov[0].iov_len = nbytes;
+       msg.msg_iov = iov;
+       msg.msg_iovlen = 1;
+       msg.msg_control = control;
+       msg.msg_controllen = sizeof(control);
+       msg.msg_flags = 0;
+
+       if ( (n = recvmsg(fd, &msg, 0)) < 0)
+               return(n);
+
+       cmsgcredptr->cmcred_ngroups = 0;        /* indicates no credentials returned */
+       if (cmsgcredptr && msg.msg_controllen > 0) {
+               struct cmsghdr  *cmptr = (struct cmsghdr *) control;
+
+               if (cmptr->cmsg_len < CONTROL_LEN)
+                       err_quit("control length = %d", cmptr->cmsg_len);
+               if (cmptr->cmsg_level != SOL_SOCKET)
+                       err_quit("control level != SOL_SOCKET");
+               if (cmptr->cmsg_type != SCM_CREDS)
+                       err_quit("control type != SCM_CREDS");
+               memcpy(cmsgcredptr, CMSG_DATA(cmptr), sizeof(struct cmsgcred));
+       }
+
+       return(n);
+}
diff --git a/unixdomain/sigchldwaitpid.c b/unixdomain/sigchldwaitpid.c
new file mode 100644 (file)
index 0000000..5fa9cbf
--- /dev/null
@@ -0,0 +1,13 @@
+#include       "unp.h"
+
+void
+sig_chld(int signo)
+{
+       pid_t   pid;
+       int             stat;
+
+       while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) {
+               printf("child %d terminated\n", pid);
+       }
+       return;
+}
diff --git a/unixdomain/strecho.c b/unixdomain/strecho.c
new file mode 100644 (file)
index 0000000..0fff58d
--- /dev/null
@@ -0,0 +1,34 @@
+#include       "unp.h"
+
+ssize_t        read_cred(int, void *, size_t, struct cmsgcred *);
+
+void
+str_echo(int sockfd)
+{
+       ssize_t                 n;
+       int                     i;
+       char                    buf[MAXLINE];
+       struct cmsgcred cred;
+
+again:
+       while ( (n = read_cred(sockfd, buf, MAXLINE, &cred)) > 0) {
+               if (cred.cmcred_ngroups == 0) {
+                       printf("(no credentials returned)\n");
+               } else {
+                       printf("PID of sender = %d\n", cred.cmcred_pid);
+                       printf("real user ID = %d\n", cred.cmcred_uid);
+                       printf("real group ID = %d\n", cred.cmcred_gid);
+                       printf("effective user ID = %d\n", cred.cmcred_euid);
+                       printf("%d groups:", cred.cmcred_ngroups - 1);
+                       for (i = 1; i < cred.cmcred_ngroups; i++)
+                               printf(" %d", cred.cmcred_groups[i]);
+                       printf("\n");
+               }
+               Writen(sockfd, buf, n);
+       }
+
+       if (n < 0 && errno == EINTR)
+               goto again;
+       else if (n < 0)
+               err_sys("str_echo: read error");
+}
diff --git a/unixdomain/testfcred.c b/unixdomain/testfcred.c
new file mode 100644 (file)
index 0000000..48568e9
--- /dev/null
@@ -0,0 +1,10 @@
+#include       "unp.h"
+#include       <sys/param.h>
+#include       <sys/ucred.h>
+
+main()
+{
+       printf("sizeof(struct fcred) = %d\n", sizeof(struct fcred));
+       printf("sizeof(struct cmsghdr) = %d\n", sizeof(struct cmsghdr));
+       exit(0);
+}
diff --git a/unixdomain/tfcred01.c b/unixdomain/tfcred01.c
new file mode 100644 (file)
index 0000000..9204e4e
--- /dev/null
@@ -0,0 +1,84 @@
+#include       "unp.h"
+#include       <sys/param.h>
+#include       <sys/ucred.h>
+
+ssize_t        recv_cred(int, void *, size_t, struct fcred *);
+
+main()
+{
+       int                             fd[2], on, n;
+       char                    buf[100];
+       struct fcred    cred;
+
+       if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fd) < 0)
+               err_sys("socketpair error");
+
+               /* must set the socket option on the *receiving* socket */
+       on = 1;
+       Setsockopt(fd[1], 0, LOCAL_CREDS, &on, sizeof(on));
+
+       Write(fd[0], "hello, world\n", 13);
+
+       if ( (n = recv_cred(fd[1], buf, sizeof(buf), &cred)) < 0)
+               err_sys("recv_cred error");
+       else if (n == 0)
+               err_quit("recv_cred, unexpected EOF");
+
+       buf[n] = 0;                     /* null terminate */
+       printf("data: %s", buf);
+
+       if (cred.fc_ngroups == 0)
+               printf("(no credentials returned)\n");
+       else {
+               printf("real user ID = %d\n", cred.fc_ruid);
+               printf("real group ID = %d\n", cred.fc_rgid);
+               printf("login name = %-*s\n", MAXLOGNAME, cred.fc_login);
+               printf("effective user ID = %d\n", cred.fc_uid);
+               printf("effective group ID = %d\n", cred.fc_gid);
+               printf("%d supplementary groups:", cred.fc_ngroups - 1);
+               for (n = 1; n < cred.fc_ngroups; n++)   /* [0] is the egid */
+                       printf(" %d", cred.fc_groups[n]);
+               printf("\n");
+       }
+
+       exit(0);
+}
+
+#define        CONTROL_LEN     (sizeof(struct cmsghdr) + sizeof(struct fcred))
+
+ssize_t
+recv_cred(int fd, void *ptr, size_t nbytes, struct fcred *fcredptr)
+{
+       struct msghdr   msg;
+       struct iovec    iov[1];
+       char                    control[CONTROL_LEN + 20];
+       int                             n;
+
+       msg.msg_name = NULL;
+       msg.msg_namelen = 0;
+       iov[0].iov_base = ptr;
+       iov[0].iov_len = nbytes;
+       msg.msg_iov = iov;
+       msg.msg_iovlen = 1;
+       msg.msg_control = control;
+       msg.msg_controllen = sizeof(control);
+       msg.msg_flags = 0;
+
+       if ( (n = recvmsg(fd, &msg, 0)) < 0)
+               return(n);
+
+       fcredptr->fc_ngroups = 0;       /* indicates no credentials returned */
+       if (fcredptr && msg.msg_controllen > 0) {
+               struct cmsghdr  *cmptr = (struct cmsghdr *) control;
+
+               if (cmptr->cmsg_len != sizeof(struct cmsghdr) + sizeof(struct fcred))
+                       err_quit("control length = %d", cmptr->cmsg_len);
+               if (cmptr->cmsg_level != SOL_SOCKET)
+                       err_quit("control level != SOL_SOCKET");
+               if (cmptr->cmsg_type != SCM_CREDS)
+                       err_quit("control type != SCM_CREDS");
+               memcpy(fcredptr, CMSG_DATA(cmptr), sizeof(struct fcred));
+       }
+
+       return(n);
+}
diff --git a/unixdomain/unixbind.c b/unixdomain/unixbind.c
new file mode 100644 (file)
index 0000000..8bc8242
--- /dev/null
@@ -0,0 +1,27 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       socklen_t                       len;
+       struct sockaddr_un      addr1, addr2;
+
+       if (argc != 2)
+               err_quit("usage: unixbind <pathname>");
+
+       sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
+
+       unlink(argv[1]);                /* OK if this fails */
+
+       bzero(&addr1, sizeof(addr1));
+       addr1.sun_family = AF_LOCAL;
+       strncpy(addr1.sun_path, argv[1], sizeof(addr1.sun_path)-1);
+       Bind(sockfd, (SA *) &addr1, SUN_LEN(&addr1));
+
+       len = sizeof(addr2);
+       Getsockname(sockfd, (SA *) &addr2, &len);
+       printf("bound name = %s, returned len = %d\n", addr2.sun_path, len);
+       
+       exit(0);
+}
diff --git a/unixdomain/unixbind.lc b/unixdomain/unixbind.lc
new file mode 100644 (file)
index 0000000..56165f9
--- /dev/null
@@ -0,0 +1,27 @@
+#include    "unp.h"##  1 ##src/unixdomain/unixbind.c##
+
+int##  2 ##src/unixdomain/unixbind.c##
+main(int argc, char **argv)##  3 ##src/unixdomain/unixbind.c##
+{##  4 ##src/unixdomain/unixbind.c##
+    int     sockfd;##  5 ##src/unixdomain/unixbind.c##
+    socklen_t len;##  6 ##src/unixdomain/unixbind.c##
+    struct sockaddr_un addr1, addr2;##  7 ##src/unixdomain/unixbind.c##
+
+    if (argc != 2)##  8 ##src/unixdomain/unixbind.c##
+        err_quit("usage: unixbind <pathname>");##  9 ##src/unixdomain/unixbind.c##
+
+    sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0);## 10 ##src/unixdomain/unixbind.c##
+
+    unlink(argv[1]);            /* OK if this fails */## 11 ##src/unixdomain/unixbind.c##
+
+    bzero(&addr1, sizeof(addr1));## 12 ##src/unixdomain/unixbind.c##
+    addr1.sun_family = AF_LOCAL;## 13 ##src/unixdomain/unixbind.c##
+    strncpy(addr1.sun_path, argv[1], sizeof(addr1.sun_path) - 1);## 14 ##src/unixdomain/unixbind.c##
+    Bind(sockfd, (SA *) &addr1, SUN_LEN(&addr1));## 15 ##src/unixdomain/unixbind.c##
+
+    len = sizeof(addr2);## 16 ##src/unixdomain/unixbind.c##
+    Getsockname(sockfd, (SA *) &addr2, &len);## 17 ##src/unixdomain/unixbind.c##
+    printf("bound name = %s, returned len = %d\n", addr2.sun_path, len);## 18 ##src/unixdomain/unixbind.c##
+
+    exit(0);## 19 ##src/unixdomain/unixbind.c##
+}## 20 ##src/unixdomain/unixbind.c##
diff --git a/unixdomain/unixdgcli01.c b/unixdomain/unixdgcli01.c
new file mode 100644 (file)
index 0000000..008b8cc
--- /dev/null
@@ -0,0 +1,24 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_un      cliaddr, servaddr;
+
+       sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);
+
+       bzero(&cliaddr, sizeof(cliaddr));               /* bind an address for us */
+       cliaddr.sun_family = AF_LOCAL;
+       strcpy(cliaddr.sun_path, tmpnam(NULL));
+
+       Bind(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
+
+       bzero(&servaddr, sizeof(servaddr));     /* fill in server's address */
+       servaddr.sun_family = AF_LOCAL;
+       strcpy(servaddr.sun_path, UNIXDG_PATH);
+
+       dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       exit(0);
+}
diff --git a/unixdomain/unixdgcli01.lc b/unixdomain/unixdgcli01.lc
new file mode 100644 (file)
index 0000000..1f173d6
--- /dev/null
@@ -0,0 +1,24 @@
+#include    "unp.h"##  1 ##src/unixdomain/unixdgcli01.c##
+
+int##  2 ##src/unixdomain/unixdgcli01.c##
+main(int argc, char **argv)##  3 ##src/unixdomain/unixdgcli01.c##
+{##  4 ##src/unixdomain/unixdgcli01.c##
+    int     sockfd;##  5 ##src/unixdomain/unixdgcli01.c##
+    struct sockaddr_un cliaddr, servaddr;##  6 ##src/unixdomain/unixdgcli01.c##
+
+    sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);##  7 ##src/unixdomain/unixdgcli01.c##
+
+    bzero(&cliaddr, sizeof(cliaddr));   /* bind an address for us */##  8 ##src/unixdomain/unixdgcli01.c##
+    cliaddr.sun_family = AF_LOCAL;##  9 ##src/unixdomain/unixdgcli01.c##
+    strcpy(cliaddr.sun_path, tmpnam(NULL));## 10 ##src/unixdomain/unixdgcli01.c##
+
+    Bind(sockfd, (SA *) &cliaddr, sizeof(cliaddr));## 11 ##src/unixdomain/unixdgcli01.c##
+
+    bzero(&servaddr, sizeof(servaddr)); /* fill in server's address */## 12 ##src/unixdomain/unixdgcli01.c##
+    servaddr.sun_family = AF_LOCAL;## 13 ##src/unixdomain/unixdgcli01.c##
+    strcpy(servaddr.sun_path, UNIXDG_PATH);## 14 ##src/unixdomain/unixdgcli01.c##
+
+    dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));## 15 ##src/unixdomain/unixdgcli01.c##
+
+    exit(0);## 16 ##src/unixdomain/unixdgcli01.c##
+}## 17 ##src/unixdomain/unixdgcli01.c##
diff --git a/unixdomain/unixdgserv01.c b/unixdomain/unixdgserv01.c
new file mode 100644 (file)
index 0000000..fd9abe8
--- /dev/null
@@ -0,0 +1,19 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_un      servaddr, cliaddr;
+
+       sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);
+
+       unlink(UNIXDG_PATH);
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sun_family = AF_LOCAL;
+       strcpy(servaddr.sun_path, UNIXDG_PATH);
+
+       Bind(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
+}
diff --git a/unixdomain/unixstrcli01.c b/unixdomain/unixstrcli01.c
new file mode 100644 (file)
index 0000000..c346a62
--- /dev/null
@@ -0,0 +1,20 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     sockfd;
+       struct sockaddr_un      servaddr;
+
+       sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
+
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sun_family = AF_LOCAL;
+       strcpy(servaddr.sun_path, UNIXSTR_PATH);
+
+       Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
+
+       str_cli(stdin, sockfd);         /* do it all */
+
+       exit(0);
+}
diff --git a/unixdomain/unixstrserv01.c b/unixdomain/unixstrserv01.c
new file mode 100644 (file)
index 0000000..053dbde
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       pid_t                           childpid;
+       socklen_t                       clilen;
+       struct sockaddr_un      cliaddr, servaddr;
+       void                            sig_chld(int);
+
+       listenfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
+
+       unlink(UNIXSTR_PATH);
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sun_family = AF_LOCAL;
+       strcpy(servaddr.sun_path, UNIXSTR_PATH);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       Signal(SIGCHLD, sig_chld);
+
+       for ( ; ; ) {
+               clilen = sizeof(cliaddr);
+               if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
+                       if (errno == EINTR)
+                               continue;               /* back to for() */
+                       else
+                               err_sys("accept error");
+               }
+
+               if ( (childpid = Fork()) == 0) {        /* child process */
+                       Close(listenfd);        /* close listening socket */
+                       str_echo(connfd);       /* process request */
+                       exit(0);
+               }
+               Close(connfd);                  /* parent closes connected socket */
+       }
+}
diff --git a/unixdomain/unixstrserv01.lc b/unixdomain/unixstrserv01.lc
new file mode 100644 (file)
index 0000000..f26dd54
--- /dev/null
@@ -0,0 +1,41 @@
+#include    "unp.h"##  1 ##src/unixdomain/unixstrserv01.c##
+
+int##  2 ##src/unixdomain/unixstrserv01.c##
+main(int argc, char **argv)##  3 ##src/unixdomain/unixstrserv01.c##
+{##  4 ##src/unixdomain/unixstrserv01.c##
+    int     listenfd, connfd;##  5 ##src/unixdomain/unixstrserv01.c##
+    pid_t   childpid;##  6 ##src/unixdomain/unixstrserv01.c##
+    socklen_t clilen;##  7 ##src/unixdomain/unixstrserv01.c##
+    struct sockaddr_un cliaddr, servaddr;##  8 ##src/unixdomain/unixstrserv01.c##
+    void    sig_chld(int);##  9 ##src/unixdomain/unixstrserv01.c##
+
+    listenfd = Socket(AF_LOCAL, SOCK_STREAM, 0);## 10 ##src/unixdomain/unixstrserv01.c##
+
+    unlink(UNIXSTR_PATH);## 11 ##src/unixdomain/unixstrserv01.c##
+    bzero(&servaddr, sizeof(servaddr));## 12 ##src/unixdomain/unixstrserv01.c##
+    servaddr.sun_family = AF_LOCAL;## 13 ##src/unixdomain/unixstrserv01.c##
+    strcpy(servaddr.sun_path, UNIXSTR_PATH);## 14 ##src/unixdomain/unixstrserv01.c##
+
+    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));## 15 ##src/unixdomain/unixstrserv01.c##
+
+    Listen(listenfd, LISTENQ);## 16 ##src/unixdomain/unixstrserv01.c##
+
+    Signal(SIGCHLD, sig_chld);## 17 ##src/unixdomain/unixstrserv01.c##
+
+    for (;;) {## 18 ##src/unixdomain/unixstrserv01.c##
+        clilen = sizeof(cliaddr);## 19 ##src/unixdomain/unixstrserv01.c##
+        if ((connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {## 20 ##src/unixdomain/unixstrserv01.c##
+            if (errno == EINTR)## 21 ##src/unixdomain/unixstrserv01.c##
+                continue;       /* back to for() */## 22 ##src/unixdomain/unixstrserv01.c##
+            else## 23 ##src/unixdomain/unixstrserv01.c##
+                err_sys("accept error");## 24 ##src/unixdomain/unixstrserv01.c##
+        }## 25 ##src/unixdomain/unixstrserv01.c##
+
+        if ((childpid = Fork()) == 0) { /* child process */## 26 ##src/unixdomain/unixstrserv01.c##
+            Close(listenfd);    /* close listening socket */## 27 ##src/unixdomain/unixstrserv01.c##
+            str_echo(connfd);   /* process the request */## 28 ##src/unixdomain/unixstrserv01.c##
+            exit(0);## 29 ##src/unixdomain/unixstrserv01.c##
+        }## 30 ##src/unixdomain/unixstrserv01.c##
+        Close(connfd);          /* parent closes connected socket */## 31 ##src/unixdomain/unixstrserv01.c##
+    }## 32 ##src/unixdomain/unixstrserv01.c##
+}## 33 ##src/unixdomain/unixstrserv01.c##
diff --git a/unixdomain/unixstrserv02.c b/unixdomain/unixstrserv02.c
new file mode 100644 (file)
index 0000000..78a7dec
--- /dev/null
@@ -0,0 +1,41 @@
+#include       "unp.h"
+
+int
+main(int argc, char **argv)
+{
+       int                                     listenfd, connfd;
+       pid_t                           childpid;
+       socklen_t                       clilen;
+       struct sockaddr_un      cliaddr, servaddr;
+       void                            sig_chld(int);
+
+       listenfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
+
+       unlink(UNIXSTR_PATH);
+       bzero(&servaddr, sizeof(servaddr));
+       servaddr.sun_family = AF_LOCAL;
+       strcpy(servaddr.sun_path, UNIXSTR_PATH);
+
+       Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
+
+       Listen(listenfd, LISTENQ);
+
+       Signal(SIGCHLD, sig_chld);
+
+       for ( ; ; ) {
+               clilen = sizeof(cliaddr);
+               if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
+                       if (errno == EINTR)
+                               continue;               /* back to for() */
+                       else
+                               err_sys("accept error");
+               }
+
+               if ( (childpid = Fork()) == 0) {        /* child process */
+                       Close(listenfd);        /* close listening socket */
+                       str_echo(connfd);       /* process the request */
+                       exit(0);
+               }
+               Close(connfd);                  /* parent closes connected socket */
+       }
+}