diff options
author | Jon Marler <jmarler@debian.org> | 2001-06-27 17:50:48 -0500 |
---|---|---|
committer | Dmitry Bogatov <KAction@debian.org> | 2018-11-29 05:18:29 +0000 |
commit | a2409046e935d6971367976483a3d92b6d00b23a (patch) | |
tree | da67333d390a1de30f5a7bb5ebfc2da8661d9dbf | |
parent | 69ad798f290402999778ca0d4e147f98fe7e45e8 (diff) | |
parent | b19ff825af9758fa905bf0ba29bbff66fa66cd50 (diff) |
Import Debian changes 0.88-5
ucspi-tcp (0.88-5) testing unstable; urgency=low
* Fixed symlink from /usr/share/doc to /usr/doc (closes #102454)
ucspi-tcp (0.88-4) unstable; urgency=low
* Applied rss patch to allow rblsmtpd to use A records
* Removed "-R" advertisement from rblsmtpd
ucspi-tcp (0.88-3) unstable; urgency=low
* Moved docs to /usr/share/doc
ucspi-tcp (0.88-2) unstable; urgency=low
* Fixed dependancy (closes #71949)
ucspi-tcp (0.88-1) unstable; urgency=low
* New upstream release.
* Many changes. See http://cr.yp.to/ucspi-tcp/upgrade.html
* Now conflicts with rblsmtpd. rblsmtpd is included with ucspi-tcp
-rw-r--r-- | BLURB | 31 | ||||
-rw-r--r-- | CHANGES | 200 | ||||
-rw-r--r-- | FILES | 292 | ||||
-rw-r--r-- | INSTALL | 22 | ||||
-rw-r--r-- | Makefile | 901 | ||||
-rw-r--r-- | README | 164 | ||||
-rw-r--r-- | SYSDEPS | 5 | ||||
-rw-r--r-- | TARGETS | 245 | ||||
-rw-r--r-- | TCP | 45 | ||||
-rw-r--r-- | THANKS | 122 | ||||
-rw-r--r-- | TODO | 9 | ||||
-rw-r--r-- | UCSPI | 131 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | addcr.1 | 22 | ||||
-rw-r--r-- | addcr.c | 15 | ||||
-rw-r--r-- | alloc.3 | 62 | ||||
-rw-r--r-- | alloc.c | 2 | ||||
-rw-r--r-- | argv0.1 | 47 | ||||
-rw-r--r-- | argv0.c | 7 | ||||
-rw-r--r-- | auto-str.c | 17 | ||||
-rw-r--r-- | buffer.c | 10 | ||||
-rw-r--r-- | buffer.h | 56 | ||||
-rw-r--r-- | buffer_0.c | 12 | ||||
-rw-r--r-- | buffer_1.c | 6 | ||||
-rw-r--r-- | buffer_2.c | 6 | ||||
-rw-r--r-- | buffer_copy.c | 16 | ||||
-rw-r--r-- | buffer_get.c | 67 | ||||
-rw-r--r-- | buffer_put.c | 88 | ||||
-rw-r--r-- | case.3 | 100 | ||||
-rw-r--r-- | case.h | 12 | ||||
-rw-r--r-- | case_diffb.c | 18 | ||||
-rw-r--r-- | case_diffs.c | 17 | ||||
-rw-r--r-- | case_lowers.c | 12 | ||||
-rw-r--r-- | cdb.3 | 62 | ||||
-rw-r--r-- | cdb.c | 136 | ||||
-rw-r--r-- | cdb.h | 33 | ||||
-rw-r--r-- | cdb_hash.c | 17 | ||||
-rw-r--r-- | cdb_make.c | 153 | ||||
-rw-r--r-- | cdb_make.h | 39 | ||||
-rw-r--r-- | cdb_seek.c | 95 | ||||
-rw-r--r-- | cdb_unpack.c | 12 | ||||
-rw-r--r-- | cdbmake.h | 35 | ||||
-rw-r--r-- | cdbmake_add.c | 117 | ||||
-rw-r--r-- | cdbmake_hash.c | 10 | ||||
-rw-r--r-- | cdbmake_pack.c | 11 | ||||
-rw-r--r-- | cdbmss.c | 65 | ||||
-rw-r--r-- | cdbmss.h | 16 | ||||
-rw-r--r-- | chkshsgr.c | 10 | ||||
-rw-r--r-- | choose.sh | 18 | ||||
-rw-r--r-- | commands.c | 39 | ||||
-rw-r--r-- | commands.h | 12 | ||||
-rw-r--r-- | conf-cc | 2 | ||||
-rw-r--r-- | conf-home | 4 | ||||
-rw-r--r-- | conf-ld | 2 | ||||
-rw-r--r-- | date@.1 | 32 | ||||
-rw-r--r-- | debian/changelog | 35 | ||||
-rw-r--r-- | debian/control | 2 | ||||
-rw-r--r-- | debian/control.real | 6 | ||||
-rw-r--r-- | debian/copyright | 2 | ||||
-rw-r--r-- | debian/postinst | 7 | ||||
-rw-r--r-- | debian/prerm | 5 | ||||
-rwxr-xr-x | debian/rules | 47 | ||||
-rw-r--r-- | debian/src.postinst | 6 | ||||
-rw-r--r-- | debian/src.prerm | 5 | ||||
-rw-r--r-- | delcr.1 | 30 | ||||
-rw-r--r-- | delcr.c | 20 | ||||
-rw-r--r-- | dns.c | 400 | ||||
-rw-r--r-- | dns.h | 88 | ||||
-rw-r--r-- | dns_dfd.c | 69 | ||||
-rw-r--r-- | dns_domain.c | 61 | ||||
-rw-r--r-- | dns_dtda.c | 35 | ||||
-rw-r--r-- | dns_ip.c | 75 | ||||
-rw-r--r-- | dns_ipq.c | 71 | ||||
-rw-r--r-- | dns_name.c | 48 | ||||
-rw-r--r-- | dns_nd.c | 24 | ||||
-rw-r--r-- | dns_packet.c | 77 | ||||
-rw-r--r-- | dns_random.c | 62 | ||||
-rw-r--r-- | dns_rcip.c | 82 | ||||
-rw-r--r-- | dns_rcrw.c | 130 | ||||
-rw-r--r-- | dns_resolve.c | 29 | ||||
-rw-r--r-- | dns_sortip.c | 20 | ||||
-rw-r--r-- | dns_transmit.c | 364 | ||||
-rw-r--r-- | dns_txt.c | 59 | ||||
-rw-r--r-- | env.3 | 31 | ||||
-rw-r--r-- | env.c | 116 | ||||
-rw-r--r-- | env.h | 13 | ||||
-rw-r--r-- | envread.c | 30 | ||||
-rw-r--r-- | error.3 | 45 | ||||
-rw-r--r-- | error.c | 21 | ||||
-rw-r--r-- | error.h | 7 | ||||
-rw-r--r-- | error_str.3 | 19 | ||||
-rw-r--r-- | error_str.c | 15 | ||||
-rw-r--r-- | fd.h | 4 | ||||
-rw-r--r-- | fd_copy.3 | 44 | ||||
-rw-r--r-- | fd_copy.c | 4 | ||||
-rw-r--r-- | fd_move.3 | 41 | ||||
-rw-r--r-- | fd_move.c | 4 | ||||
-rw-r--r-- | find-systype.sh | 15 | ||||
-rw-r--r-- | finger@.1 | 45 | ||||
-rw-r--r-- | fixcr.1 | 11 | ||||
-rw-r--r-- | fixcr.c | 25 | ||||
-rw-r--r-- | fixcrio.c | 161 | ||||
-rw-r--r-- | fmt.h | 30 | ||||
-rw-r--r-- | fmt_str.c | 12 | ||||
-rw-r--r-- | fmt_ulong.c | 2 | ||||
-rw-r--r-- | fork.h1 | 9 | ||||
-rw-r--r-- | fork.h2 | 9 | ||||
-rw-r--r-- | gen_allocdefs.h | 6 | ||||
-rw-r--r-- | getln.3 | 51 | ||||
-rw-r--r-- | getln.c | 8 | ||||
-rw-r--r-- | getln.h | 7 | ||||
-rw-r--r-- | getln2.3 | 64 | ||||
-rw-r--r-- | getln2.c | 17 | ||||
-rw-r--r-- | hassgact.h1 | 1 | ||||
-rw-r--r-- | hassgact.h2 | 2 | ||||
-rw-r--r-- | hassgprm.h1 | 1 | ||||
-rw-r--r-- | hassgprm.h2 | 2 | ||||
-rw-r--r-- | hasshsgr.h1 | 1 | ||||
-rw-r--r-- | hasshsgr.h2 | 2 | ||||
-rw-r--r-- | haswaitp.h1 | 1 | ||||
-rw-r--r-- | haswaitp.h2 | 2 | ||||
-rw-r--r-- | hier.c | 60 | ||||
-rw-r--r-- | http@.1 | 52 | ||||
-rw-r--r-- | http@.sh | 6 | ||||
-rw-r--r-- | install.c | 26 | ||||
-rw-r--r-- | instcheck.c | 2 | ||||
-rw-r--r-- | iopause.c | 76 | ||||
-rw-r--r-- | iopause.h1 | 19 | ||||
-rw-r--r-- | iopause.h2 | 18 | ||||
-rw-r--r-- | ip.c | 53 | ||||
-rw-r--r-- | ip.h | 11 | ||||
-rw-r--r-- | ip4.h | 9 | ||||
-rw-r--r-- | ip4_fmt.c | 18 | ||||
-rw-r--r-- | ip4_scan.c | 19 | ||||
-rw-r--r-- | ipalloc.c | 7 | ||||
-rw-r--r-- | ipalloc.h | 14 | ||||
-rw-r--r-- | mconnect-io.c | 37 | ||||
-rw-r--r-- | mconnect.1 | 36 | ||||
-rw-r--r-- | ndelay.h | 4 | ||||
-rw-r--r-- | ndelay_off.c | 3 | ||||
-rw-r--r-- | ndelay_on.c (renamed from ndelay.c) | 3 | ||||
-rw-r--r-- | open.h | 10 | ||||
-rw-r--r-- | open_read.c | 2 | ||||
-rw-r--r-- | open_trunc.c | 2 | ||||
-rw-r--r-- | open_write.c | 6 | ||||
-rw-r--r-- | openreadclose.c | 16 | ||||
-rw-r--r-- | openreadclose.h | 8 | ||||
-rw-r--r-- | pathexec.h | 8 | ||||
-rw-r--r-- | pathexec_env.c | 68 | ||||
-rw-r--r-- | pathexec_run.c | 46 | ||||
-rw-r--r-- | prot.c | 19 | ||||
-rw-r--r-- | prot.h | 7 | ||||
-rw-r--r-- | rblsmtpd.c | 236 | ||||
-rw-r--r-- | readclose.c | 21 | ||||
-rw-r--r-- | readclose.h | 9 | ||||
-rw-r--r-- | recordio.1 | 75 | ||||
-rw-r--r-- | recordio.c | 121 | ||||
-rw-r--r-- | remoteinfo.c | 135 | ||||
-rw-r--r-- | remoteinfo.h | 5 | ||||
-rw-r--r-- | rts.exp | 280 | ||||
-rw-r--r-- | rts.sh | 2 | ||||
-rw-r--r-- | rts.tests | 318 | ||||
-rw-r--r-- | rules.c | 100 | ||||
-rw-r--r-- | rules.h | 9 | ||||
-rw-r--r-- | scan.h | 38 | ||||
-rw-r--r-- | scan_ulong.c | 15 | ||||
-rw-r--r-- | seek.h | 8 | ||||
-rw-r--r-- | seek_set.c | 2 | ||||
-rw-r--r-- | select.h1 | 2 | ||||
-rw-r--r-- | select.h2 | 2 | ||||
-rw-r--r-- | sgetopt.3 | 28 | ||||
-rw-r--r-- | sgetopt.c | 21 | ||||
-rw-r--r-- | sgetopt.h | 2 | ||||
-rw-r--r-- | sig.c | 12 | ||||
-rw-r--r-- | sig.h | 58 | ||||
-rw-r--r-- | sig_block.c | 8 | ||||
-rw-r--r-- | sig_catch.c | 4 | ||||
-rw-r--r-- | sig_child.c | 7 | ||||
-rw-r--r-- | sig_pause.c | 2 | ||||
-rw-r--r-- | sig_pipe.c | 5 | ||||
-rw-r--r-- | sig_term.c | 7 | ||||
-rw-r--r-- | socket.h | 22 | ||||
-rw-r--r-- | socket_accept.c | 21 | ||||
-rw-r--r-- | socket_bind.c | 33 | ||||
-rw-r--r-- | socket_conn.c | 33 | ||||
-rw-r--r-- | socket_delay.c | 11 | ||||
-rw-r--r-- | socket_listen.c | 10 | ||||
-rw-r--r-- | socket_local.c | 17 | ||||
-rw-r--r-- | socket_opts.c | 10 | ||||
-rw-r--r-- | socket_remote.c | 17 | ||||
-rw-r--r-- | socket_tcp.c | 16 | ||||
-rw-r--r-- | socket_udp.c | 16 | ||||
-rw-r--r-- | str.h | 14 | ||||
-rw-r--r-- | str_chr.c | 4 | ||||
-rw-r--r-- | str_cpy.c | 16 | ||||
-rw-r--r-- | str_diff.c | 4 | ||||
-rw-r--r-- | str_diffn.c | 18 | ||||
-rw-r--r-- | str_len.c | 3 | ||||
-rw-r--r-- | str_start.c | 13 | ||||
-rw-r--r-- | stralloc.3 | 160 | ||||
-rw-r--r-- | stralloc.h | 30 | ||||
-rw-r--r-- | stralloc_cat.c | 4 | ||||
-rw-r--r-- | stralloc_catb.c | 5 | ||||
-rw-r--r-- | stralloc_cats.c | 4 | ||||
-rw-r--r-- | stralloc_copy.c | 4 | ||||
-rw-r--r-- | stralloc_opyb.c | 5 | ||||
-rw-r--r-- | stralloc_opys.c | 4 | ||||
-rw-r--r-- | strerr.h | 60 | ||||
-rw-r--r-- | strerr_die.c | 34 | ||||
-rw-r--r-- | strerr_sys.c | 2 | ||||
-rw-r--r-- | subfd.h | 15 | ||||
-rw-r--r-- | subfderr.c | 7 | ||||
-rw-r--r-- | subfdin.c | 13 | ||||
-rw-r--r-- | subfdout.c | 7 | ||||
-rw-r--r-- | subgetopt.3 | 357 | ||||
-rw-r--r-- | subgetopt.c | 16 | ||||
-rw-r--r-- | subgetopt.h | 2 | ||||
-rw-r--r-- | substdi.c | 91 | ||||
-rw-r--r-- | substdio.c | 15 | ||||
-rw-r--r-- | substdio.h | 47 | ||||
-rw-r--r-- | substdio_copy.c | 18 | ||||
-rw-r--r-- | substdo.c | 108 | ||||
-rw-r--r-- | tai.h | 26 | ||||
-rw-r--r-- | tai_pack.c | 16 | ||||
-rw-r--r-- | taia.h | 33 | ||||
-rw-r--r-- | taia_add.c | 18 | ||||
-rw-r--r-- | taia_approx.c | 6 | ||||
-rw-r--r-- | taia_frac.c | 6 | ||||
-rw-r--r-- | taia_less.c | 12 | ||||
-rw-r--r-- | taia_now.c | 12 | ||||
-rw-r--r-- | taia_pack.c | 20 | ||||
-rw-r--r-- | taia_sub.c | 21 | ||||
-rw-r--r-- | taia_uint.c | 10 | ||||
-rw-r--r-- | tcp-environ.5 | 62 | ||||
-rw-r--r-- | tcpcat.1 | 20 | ||||
-rw-r--r-- | tcpclient.1 | 151 | ||||
-rw-r--r-- | tcpclient.c | 349 | ||||
-rw-r--r-- | tcprules.1 | 208 | ||||
-rw-r--r-- | tcprules.c | 104 | ||||
-rw-r--r-- | tcprulescheck.1 | 25 | ||||
-rw-r--r-- | tcprulescheck.c | 115 | ||||
-rw-r--r-- | tcpserver.1 | 244 | ||||
-rw-r--r-- | tcpserver.c | 694 | ||||
-rw-r--r-- | timeoutconn.c | 77 | ||||
-rw-r--r-- | timeoutconn.h | 4 | ||||
-rw-r--r-- | timeoutread.c | 22 | ||||
-rw-r--r-- | timeoutread.h | 6 | ||||
-rw-r--r-- | timeoutwrite.c | 22 | ||||
-rw-r--r-- | timeoutwrite.h | 6 | ||||
-rw-r--r-- | trycpp.c | 2 | ||||
-rw-r--r-- | trypoll.c | 18 | ||||
-rw-r--r-- | tryrsolv.c | 7 | ||||
-rw-r--r-- | trysgact.c | 2 | ||||
-rw-r--r-- | trysgprm.c | 2 | ||||
-rw-r--r-- | tryshsgr.c | 14 | ||||
-rw-r--r-- | tryulong32.c | 2 | ||||
-rw-r--r-- | tryulong64.c | 11 | ||||
-rw-r--r-- | tryvfork.c | 4 | ||||
-rw-r--r-- | trywaitp.c | 2 | ||||
-rw-r--r-- | ucspi-rss.diff | 64 | ||||
-rw-r--r-- | uint16.h | 11 | ||||
-rw-r--r-- | uint16_pack.c | 13 | ||||
-rw-r--r-- | uint16_unpack.c | 23 | ||||
-rw-r--r-- | uint32.h1 | 5 | ||||
-rw-r--r-- | uint32.h2 | 5 | ||||
-rw-r--r-- | uint32_pack.c | 21 | ||||
-rw-r--r-- | uint32_unpack.c | 31 | ||||
-rw-r--r-- | uint64.h1 | 8 | ||||
-rw-r--r-- | uint64.h2 | 8 | ||||
-rw-r--r-- | wait.3 | 93 | ||||
-rw-r--r-- | warn-shsgr | 3 | ||||
-rw-r--r-- | who@.1 | 32 | ||||
-rw-r--r-- | x86cpuid.c | 38 | ||||
-rw-r--r-- | ööööööööööö | 1 |
274 files changed, 6125 insertions, 6485 deletions
@@ -1,31 +0,0 @@ -tcpserver and tcpclient are easy-to-use command-line tools for building -TCP client-server applications. - - -tcpserver waits for incoming connections and, for each connection, runs -a program of your choice. Your program receives environment variables -showing the local and remote host names, IP addresses, and port numbers. - -tcpserver offers a concurrency limit to protect you from running out of -processes and memory. When you are handling 40 (by default) simultaneous -connections, tcpserver smoothly defers acceptance of new connections. - -tcpserver also provides TCP access control features, similar to -tcp-wrappers/tcpd's hosts.allow but much faster. Its access control -rules are compiled into a hashed format with cdb, so it can easily deal -with thousands of different hosts. - -This package includes a recordio tool that monitors all the input and -output of a server. - - -tcpclient makes a TCP connection and runs a program of your choice. It -sets up the same environment variables as tcpserver. - -This package includes several sample clients built on top of tcpclient: -who@, date@, finger@, http@, tcpcat, and mconnect. - - -tcpserver and tcpclient conform to UCSPI, the UNIX Client-Server Program -Interface, using the TCP protocol. UCSPI tools are available for several -different networks. @@ -1,52 +1,148 @@ -19981111 version: ucspi-tcp 0.84, beta. -19981111 code: avoided ndelay in recordio. -19981110 code: added some tcprules regression tests. -19981110 code: added tcprulescheck. -19981110 code: added tcpclient -i option. -19981110 doc: added references in tcpserver.0 and tcpclient.0. -19981110 code: rewrote recordio for instant output and other features. -19981110 code: added a few more regression tests. -19981110 code: revamped tcpclient messages. -19981110 code: revamped tcpserver messages. -19981110 doc: reorganized tcpserver.0. -19981110 doc: reorganized tcpclient.0. -19981110 code: added strport to tcpclient. -19981110 code: tcpclient now ignores port results from getpeername() - in favor of the port it tried connecting to. -19981110 code: added exec to mconnect. -19981109 doc: added http@ to BLURB. -19981108 version: ucspi-tcp 0.83, beta. -19981108 code: added a few regression tests. -19981108 code: added tcpserver -B. -19981107 code: stopped after 100 bytes in safeappend() in tcpserver. -19981107 code: added http@. -19981107 doc: cleaned up tcpclient.0. -19981107 code: added recordio. -19981107 doc: revamped BLURB. -19981107 code: added fixcr. -19981107 code: added argv0. -19981107 code: added mconnect-io. -19981107 code: moved printstatus() before fork in tcpserver. -19981107 code: unblocked SIGCHLD after setting SIGCHLD to SIG_DFL in - tcpserver, instead of before, to avoid confusion if someone - sends SIGCHLD manually. -19981107 code: eliminated numchildren in printpid() in tcpserver. -19981107 code: added printstatus() in tcpserver. -19981107 doc: added tcpcat.0, mconnect.0. -19981107 doc: added who@.0, date@.0, finger@.0. -19981107 doc: added addcr.0, delcr.0. -19981107 code: tcpclient now interprets empty host name as 0. -19981107 portability problem: OpenBSD connect() prohibits 0.0.0.0. - impact: tcpclient 0 fails. fix: interpret 0 as 127.0.0.1. - hopefully nobody needs 0 to mean primary interface. -19981107 code: switched to str_equal in tcpclient. -19981107 code: switched to strerr in tcpclient. -19981107 code: eliminated tcpclient -U; moved usage() to default. -19981107 code: switched to new install system. -19980118 ucspi-tcp 0.80, beta. -19970410 ucspi-tcp 0.73, beta. -19960922 ucspi-tcp 0.72, beta. -19960914 ucspi-tcp 0.71, beta. -19960903 ucspi-tcp 0.70, beta. -19960803 ucspi-tcp 0.60, alpha. -19960311 ucspi-tcp 0.50, alpha. +19960311 + version: ucspi-tcp 0.50, alpha. +19960803 + version: ucspi-tcp 0.60, alpha. +19960903 + version: ucspi-tcp 0.70, beta. +19960914 + version: ucspi-tcp 0.71, beta. +19960922 + version: ucspi-tcp 0.72, beta. +19970410 + version: ucspi-tcp 0.73, beta. +19980118 + version: ucspi-tcp 0.80, beta. +19981107 + code: switched to new install system. + code: eliminated tcpclient -U; moved usage() to default. + code: switched to strerr in tcpclient. + code: switched to str_equal in tcpclient. + portability problem: OpenBSD connect() prohibits 0.0.0.0. + impact: tcpclient 0 fails. fix: interpret 0 as + 127.0.0.1. hopefully nobody needs 0 to mean primary + interface. + code: tcpclient now interprets empty host name as 0. + doc: added addcr.0, delcr.0. + doc: added who@.0, date@.0, finger@.0. + doc: added tcpcat.0, mconnect.0. + code: added printstatus() in tcpserver. + code: eliminated numchildren in printpid() in tcpserver. + code: unblocked SIGCHLD after setting SIGCHLD to SIG_DFL in + tcpserver, instead of before, to avoid confusion if + someone sends SIGCHLD manually. + code: moved printstatus() before fork in tcpserver. + code: added mconnect-io. + code: added argv0. + code: added fixcr. + doc: revamped BLURB. + code: added recordio. + doc: cleaned up tcpclient.0. + code: added http@. + code: stopped after 100 bytes in safeappend() in tcpserver. +19981108 + code: added tcpserver -B. + code: added a few regression tests. + version: ucspi-tcp 0.83, beta. +19981109 + doc: added http@ to BLURB. +19981110 + code: added exec to mconnect. + code: tcpclient now ignores port results from getpeername() in + favor of the port it tried connecting to. + code: added strport to tcpclient. + doc: reorganized tcpclient.0. + doc: reorganized tcpserver.0. + code: revamped tcpserver messages. + code: revamped tcpclient messages. + code: added a few more regression tests. + code: rewrote recordio for instant output and other features. + doc: added references in tcpserver.0 and tcpclient.0. + code: added tcpclient -i option. + code: added tcprulescheck. + code: added some tcprules regression tests. +19981111 + code: avoided ndelay in recordio. + version: ucspi-tcp 0.84, beta. +19981212 + doc: improved description of host 0 in tcpserver.0. tnx to + several people. +19981218 + doc: reordered sample rules in tcprules.0. + tnx Harald Hanche-Olsen. +20000120 + internal: revamped packaging. + internal: massive rewrite. tnx to everyone for bug reports and + other comments on various versions of tcpclient, + tcpserver, tcpcontrol, and rblsmtpd: Akihiro Iijima, + Akihiro Terasaki, Albert J. deVera, Alex Vostrikov, + Amos Shapira, Anand R. Buddhdev, Andrea Paolini, + Andrew Pam, Araki Yasuhiro, Arne Wichmann, + Ayamura Kikuchi, Bart B. B. Hanssens, Bert Gijsbers, + Bradford M. Shelton, Brendan Kehoe, Brian J. Reichert, + Brian M. Fisk, Brian O'Reilly, Bruno Wolff, + Chris Garrigues, Chris Johnson, Christian Wettergren, + Dale N. Woolridge, Dan M. Vogel, Daniel C. Mahoney, + Darren Hall, Darren W. Rees, Dave Sill, David J. Walton, + David P. Smith, David Pool, Dax Kelson, Dirk Jaeckel, + Dirk Vluegels, Donald E. Blais, Ed Weinberg, + Edward S. Marshall, Eric A. Perlman, Erik Wallin, + Faried Nawaz, Fred B. Ringel, Frederik P. Lindberg, + Gerry Boudreaux, Giles Lean, Grant Holliday, + Greg D. Patterson, Harald Barth, Harald Fritzsche, + Harald Hanche-Olsen, Hirofumi Ukawa, Hiroshi Yamashita, + Hitesh Patel, Ingmar Hupp, J. B. Keith Humphreys, + Jakub K. Boguslaw, Janos Farkas, Jason R. Mastaler, + Jeff Hayward, Jeremy Wohl, Jim Littlefield, + Johan Holmberg, John Bolhuis, John D. Mitchell, + Jos Backus, Jose Monteiro, Joshua J. Ellis, + Julie L. Baumler, Karl Lehenbauer, Karsten Thygesen, + Keith Burdis, Kenny Elliott, Kikuchi Kousuke, + Kris Kennaway, Lars Balker Rasmussen, Louis S. Theran, + Lyndon F. Bartels, Mads E. Eilertsen, Mark Delany, + Martin Mersberger, Matt P. Simerson, Matthew A. Zahorik, + Michael B. Scher, Michael Handler, Michael Hirohama, + Michael R. Gile, Michael Salmon, Mikael Suokas, + Nobuhiro Murata, Patrick M. Kane, Paul R. Rotering, + Peter Rye, Peter Wilkinson, Petr Novotny, + Petri Kaukasoina, Raul D. Miller, Richard A. Soderberg, + Robert W. Luce, Roberto A. Lumbreras, Russ Allbery, + Russell Nelson, Sean Reifschneider, Shawn A. Clifford, + Shin Ohira, Shinya O'Hira, Stan Norton, + Stathy G. Touloumis, Stefan M. Linnemann, Sudish Joseph, + Thomas E. Erskine, Thomas Kuerten, Tim Goodwin, + Timothy L. Mayo, Todd Underwood, Tomoaki Terazawa, + Tomoki Yoshioka, Toshinori Maeno, Uwe Ohse, Vern Hart, + Vince Vielhaber, Waskita Adijarto, William E. Baxter, + Wolfgang Rufeger, Wu Ching-hong, Yoshitatsu Takeshita. +20000307 + internal: switched to various new libraries. + ui: tcpserver prints status on startup, before first connection. +20000309 + ui: incorporated rblsmtpd. + ui: tcpserver -X allows nonexistent rules file. + ui: http@ uses HTTP/1.0, sends Host, removes header. + ui: added fixcrio. + ui: delcr leaves CR alone at the end of a partial final line. +20000311 + ui: switched to prot; so setgid() is preceded by setgroups(). + ui: tcpserver supports -U. + ui: tcpserver supports hostname rules. + ui: tcprulescheck now uses environment variables. +20000312 + version: ucspi-tcp 0.86, beta. +20000314 + portability problem: the poll() emulation in RedHat 5.1 doesn't + clear revents when select() returns 0. tnx Petr Novotny. + impact: dns lookups busy-loop when they should time out. + fix: new iopause from DNScache. +20000315 + version: ucspi-tcp 0.87, beta. +20000318 + internal: split rules() out of tcpserver and tcprulescheck. + bug: didn't always clear rule length when $TCPREMOTEHOST was + set. impact: empty rule could be ignored. fix: obvious. + tnx Toshinori Maeno, Takashi Takizawa, Yuichi Katoh. + ui: check for lone = rule if $TCPREMOTEHOST is set. + ui: tcpclient supports fast+slow timeouts, 2+58 by default. + ui: tcpclient randomizes order of addresses. + version: ucspi-tcp 0.88, beta. @@ -1,84 +1,53 @@ -BLURB README TODO -THANKS CHANGES -UCSPI -TCP -FILES VERSION +FILES SYSDEPS TARGETS Makefile -tcpclient.1 +conf-cc +conf-ld +conf-home +tcpserver.c +tcprules.c +tcprulescheck.c +recordio.c +argv0.c tcpclient.c -who@.1 -who@.sh -date@.1 date@.sh -finger@.1 finger@.sh -http@.1 http@.sh -tcpcat.1 +who@.sh tcpcat.sh -mconnect.1 mconnect.sh mconnect-io.c -delcr.1 -delcr.c -addcr.1 addcr.c -fixcr.1 -fixcr.c -tcpserver.1 -tcpserver.c -tcprules.1 -tcprules.c -tcprulescheck.1 -tcprulescheck.c -tcp-environ.5 -recordio.1 -recordio.c -argv0.1 -argv0.c +delcr.c +fixcrio.c +rblsmtpd.c +remoteinfo.h +remoteinfo.c +timeoutconn.h +timeoutconn.c +rules.h +rules.c rts.sh rts.tests rts.exp -conf-cc -conf-ld -find-systype.sh -trycpp.c -warn-auto.sh -INSTALL -hier.c -conf-home +alloc.c +alloc.h +alloc_re.c auto-str.c auto_home.h -install.c -instcheck.c -substdio.h -substdio.c -substdi.c -substdo.c -substdio_copy.c -subfd.h -subfderr.c -subfdout.c -subfdin.c -readwrite.h -exit.h -strerr.h -strerr_sys.c -strerr_die.c -error.3 -error_str.3 -error.h -error.c -error_str.c -open.h -open_read.c -open_trunc.c +buffer.c +buffer.h +buffer_0.c +buffer_1.c +buffer_2.c +buffer_copy.c +buffer_get.c +buffer_put.c byte.h byte_chr.c byte_copy.c @@ -86,105 +55,164 @@ byte_cr.c byte_diff.c byte_rchr.c byte_zero.c -str.h -str_chr.c -str_cpy.c -str_diff.c -str_diffn.c -str_len.c -alloc.3 -alloc.h -alloc.c -alloc_re.c -case.3 case.h -case_lowers.c -cdb.3 +case_diffb.c +case_diffs.c +cdb.c cdb.h cdb_hash.c -cdb_seek.c -cdb_unpack.c -cdbmake.h -cdbmake_add.c -cdbmake_hash.c -cdbmake_pack.c -cdbmss.h -cdbmss.c +cdb_make.c +cdb_make.h +chkshsgr.c +choose.sh +commands.c +commands.h dns.h -dns.c -trylsock.c -tryrsolv.c -env.3 -env.h +dns_dfd.c +dns_domain.c +dns_dtda.c +dns_ip.c +dns_ipq.c +dns_name.c +dns_nd.c +dns_packet.c +dns_random.c +dns_rcip.c +dns_rcrw.c +dns_resolve.c +dns_sortip.c +dns_transmit.c +dns_txt.c env.c -envread.c +env.h +error.c +error.h +error_str.c +exit.h fd.h -fd_copy.3 fd_copy.c -fd_move.3 fd_move.c +find-systype.sh fmt.h -fmt_str.c fmt_ulong.c -scan.h -scan_ulong.c -getln.3 -getln.h +fork.h1 +fork.h2 +gen_alloc.h +gen_allocdefs.h getln.c -getln2.3 +getln.h getln2.c -sgetopt.3 -sgetopt.h -sgetopt.c -subgetopt.3 -subgetopt.h -subgetopt.c -ip.h -ip.c -ipalloc.h -ipalloc.c +hassgact.h1 +hassgact.h2 +hassgprm.h1 +hassgprm.h2 +hasshsgr.h1 +hasshsgr.h2 +haswaitp.h1 +haswaitp.h2 +hier.c +install.c +instcheck.c +iopause.c +iopause.h1 +iopause.h2 +ip4.h +ip4_fmt.c +ip4_scan.c ndelay.h -ndelay.c ndelay_off.c -remoteinfo.h -remoteinfo.c +ndelay_on.c +open.h +open_read.c +open_trunc.c +open_write.c +openreadclose.c +openreadclose.h +pathexec.h +pathexec_env.c +pathexec_run.c +prot.c +prot.h +readclose.c +readclose.h +readwrite.h +scan.h +scan_ulong.c seek.h seek_set.c select.h1 select.h2 -trysysel.c +sgetopt.c +sgetopt.h +sig.c sig.h sig_block.c sig_catch.c sig_pause.c -sig_pipe.c -sig_child.c -sig_term.c -trysgact.c -trysgprm.c -gen_alloc.h -gen_allocdefs.h -stralloc.3 +socket.h +socket_accept.c +socket_bind.c +socket_conn.c +socket_delay.c +socket_listen.c +socket_local.c +socket_opts.c +socket_remote.c +socket_tcp.c +socket_udp.c +str.h +str_chr.c +str_diff.c +str_len.c +str_start.c stralloc.h -stralloc_eady.c -stralloc_pend.c -stralloc_copy.c -stralloc_opyb.c -stralloc_opys.c stralloc_cat.c stralloc_catb.c stralloc_cats.c -timeoutconn.h -timeoutconn.c -timeoutread.h -timeoutread.c -timeoutwrite.h -timeoutwrite.c +stralloc_copy.c +stralloc_eady.c +stralloc_opyb.c +stralloc_opys.c +stralloc_pend.c +strerr.h +strerr_die.c +strerr_sys.c +subgetopt.c +subgetopt.h +tai.h +tai_pack.c +taia.h +taia_add.c +taia_approx.c +taia_frac.c +taia_less.c +taia_now.c +taia_pack.c +taia_sub.c +taia_uint.c +trycpp.c +trylsock.c +trypoll.c +trysgact.c +trysgprm.c +tryshsgr.c +trysysel.c +tryulong32.c +tryulong64.c +tryvfork.c +trywaitp.c +uint16.h +uint16_pack.c +uint16_unpack.c uint32.h1 uint32.h2 -tryulong32.c -wait.3 +uint32_pack.c +uint32_unpack.c +uint64.h1 +uint64.h2 wait.h wait_nohang.c wait_pid.c -trywaitp.c +warn-auto.sh +warn-shsgr +x86cpuid.c diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 43959e9..0000000 --- a/INSTALL +++ /dev/null @@ -1,22 +0,0 @@ -Like any other piece of software (and information generally), ucspi-tcp -comes with NO WARRANTY. - - -Things you have to decide before starting: - -* The ucspi-tcp home directory, normally /usr/local. To change this -directory, edit conf-home now. - - -How to install: - - 1. Compile the programs and create the formatted man pages: - % make - - 2. Install the programs and man pages: - # make setup check - - -That's it! To report success: - % ( echo 'First M. Last'; cat `cat SYSDEPS` ) | mail djb-qst@cr.yp.to -Replace First M. Last with your name. @@ -5,25 +5,13 @@ SHELL=/bin/sh default: it addcr: \ -load addcr.o substdio.a error.a str.a - ./load addcr substdio.a error.a str.a - -addcr.0: \ -addcr.1 - nroff -man addcr.1 > addcr.0 +load addcr.o unix.a byte.a + ./load addcr unix.a byte.a addcr.o: \ -compile addcr.c substdio.h subfd.h substdio.h exit.h +compile addcr.c buffer.h exit.h ./compile addcr.c -alloc.0: \ -alloc.3 - nroff -man alloc.3 > alloc.0 - -alloc.a: \ -makelib alloc.o alloc_re.o - ./makelib alloc.a alloc.o alloc_re.o - alloc.o: \ compile alloc.c alloc.h error.h ./compile alloc.c @@ -33,23 +21,19 @@ compile alloc_re.c alloc.h byte.h ./compile alloc_re.c argv0: \ -load argv0.o strerr.a substdio.a error.a str.a - ./load argv0 strerr.a substdio.a error.a str.a - -argv0.0: \ -argv0.1 - nroff -man argv0.1 > argv0.0 +load argv0.o unix.a byte.a + ./load argv0 unix.a byte.a argv0.o: \ -compile argv0.c strerr.h +compile argv0.c pathexec.h strerr.h ./compile argv0.c auto-str: \ -load auto-str.o substdio.a error.a str.a - ./load auto-str substdio.a error.a str.a +load auto-str.o unix.a byte.a + ./load auto-str unix.a byte.a auto-str.o: \ -compile auto-str.c substdio.h readwrite.h exit.h +compile auto-str.c buffer.h readwrite.h exit.h ./compile auto-str.c auto_home.c: \ @@ -60,6 +44,45 @@ auto_home.o: \ compile auto_home.c ./compile auto_home.c +buffer.o: \ +compile buffer.c buffer.h + ./compile buffer.c + +buffer_0.o: \ +compile buffer_0.c readwrite.h buffer.h + ./compile buffer_0.c + +buffer_1.o: \ +compile buffer_1.c readwrite.h buffer.h + ./compile buffer_1.c + +buffer_2.o: \ +compile buffer_2.c readwrite.h buffer.h + ./compile buffer_2.c + +buffer_copy.o: \ +compile buffer_copy.c buffer.h + ./compile buffer_copy.c + +buffer_get.o: \ +compile buffer_get.c buffer.h byte.h error.h + ./compile buffer_get.c + +buffer_put.o: \ +compile buffer_put.c buffer.h str.h byte.h error.h + ./compile buffer_put.c + +byte.a: \ +makelib byte_chr.o byte_copy.o byte_cr.o byte_diff.o byte_rchr.o \ +byte_zero.o case_diffb.o case_diffs.o fmt_ulong.o ip4_fmt.o \ +ip4_scan.o scan_ulong.o str_chr.o str_diff.o str_len.o str_start.o \ +uint16_pack.o uint16_unpack.o uint32_pack.o uint32_unpack.o + ./makelib byte.a byte_chr.o byte_copy.o byte_cr.o \ + byte_diff.o byte_rchr.o byte_zero.o case_diffb.o \ + case_diffs.o fmt_ulong.o ip4_fmt.o ip4_scan.o scan_ulong.o \ + str_chr.o str_diff.o str_len.o str_start.o uint16_pack.o \ + uint16_unpack.o uint32_pack.o uint32_unpack.o + byte_chr.o: \ compile byte_chr.c byte.h ./compile byte_chr.c @@ -84,63 +107,54 @@ byte_zero.o: \ compile byte_zero.c byte.h ./compile byte_zero.c -case.0: \ -case.3 - nroff -man case.3 > case.0 - -case.a: \ -makelib case_lowers.o - ./makelib case.a case_lowers.o +case_diffb.o: \ +compile case_diffb.c case.h + ./compile case_diffb.c -case_lowers.o: \ -compile case_lowers.c case.h - ./compile case_lowers.c - -cdb.0: \ -cdb.3 - nroff -man cdb.3 > cdb.0 +case_diffs.o: \ +compile case_diffs.c case.h + ./compile case_diffs.c cdb.a: \ -makelib cdb_hash.o cdb_unpack.o cdb_seek.o - ./makelib cdb.a cdb_hash.o cdb_unpack.o cdb_seek.o +makelib cdb.o cdb_hash.o cdb_make.o + ./makelib cdb.a cdb.o cdb_hash.o cdb_make.o + +cdb.o: \ +compile cdb.c readwrite.h error.h seek.h byte.h cdb.h uint32.h + ./compile cdb.c cdb_hash.o: \ compile cdb_hash.c cdb.h uint32.h ./compile cdb_hash.c -cdb_seek.o: \ -compile cdb_seek.c cdb.h uint32.h - ./compile cdb_seek.c - -cdb_unpack.o: \ -compile cdb_unpack.c cdb.h uint32.h - ./compile cdb_unpack.c +cdb_make.o: \ +compile cdb_make.c readwrite.h seek.h error.h alloc.h cdb.h uint32.h \ +cdb_make.h buffer.h uint32.h + ./compile cdb_make.c -cdbmake.a: \ -makelib cdbmake_pack.o cdbmake_hash.o cdbmake_add.o - ./makelib cdbmake.a cdbmake_pack.o cdbmake_hash.o \ - cdbmake_add.o - -cdbmake_add.o: \ -compile cdbmake_add.c cdbmake.h uint32.h - ./compile cdbmake_add.c +check: \ +it instcheck + ./instcheck -cdbmake_hash.o: \ -compile cdbmake_hash.c cdbmake.h uint32.h - ./compile cdbmake_hash.c +chkshsgr: \ +load chkshsgr.o + ./load chkshsgr -cdbmake_pack.o: \ -compile cdbmake_pack.c cdbmake.h uint32.h - ./compile cdbmake_pack.c +chkshsgr.o: \ +compile chkshsgr.c exit.h + ./compile chkshsgr.c -cdbmss.o: \ -compile cdbmss.c readwrite.h seek.h alloc.h cdbmss.h cdbmake.h \ -uint32.h substdio.h - ./compile cdbmss.c +choose: \ +warn-auto.sh choose.sh conf-home + cat warn-auto.sh choose.sh \ + | sed s}HOME}"`head -1 conf-home`"}g \ + > choose + chmod 755 choose -check: \ -it instcheck - ./instcheck +commands.o: \ +compile commands.c buffer.h stralloc.h gen_alloc.h str.h case.h \ +commands.h + ./compile commands.c compile: \ warn-auto.sh conf-cc @@ -156,86 +170,117 @@ warn-auto.sh date@.sh conf-home > date@ chmod 755 date@ -date@.0: \ -date@.1 - nroff -man date@.1 > date@.0 - delcr: \ -load delcr.o substdio.a error.a str.a - ./load delcr substdio.a error.a str.a - -delcr.0: \ -delcr.1 - nroff -man delcr.1 > delcr.0 +load delcr.o unix.a byte.a + ./load delcr unix.a byte.a delcr.o: \ -compile delcr.c substdio.h subfd.h substdio.h exit.h +compile delcr.c buffer.h exit.h ./compile delcr.c -dns.lib: \ -tryrsolv.c compile load socket.lib - ( ( ./compile tryrsolv.c && ./load tryrsolv \ - -lresolv `cat socket.lib` ) >/dev/null 2>&1 \ - && echo -lresolv || exit 0 ) > dns.lib - rm -f tryrsolv.o tryrsolv - -dns.o: \ -compile dns.c ip.h ipalloc.h ip.h gen_alloc.h fmt.h alloc.h str.h \ -stralloc.h gen_alloc.h dns.h case.h - ./compile dns.c - -env.0: \ -env.3 - nroff -man env.3 > env.0 - -env.a: \ -makelib env.o envread.o - ./makelib env.a env.o envread.o +dns.a: \ +makelib dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o dns_ipq.o \ +dns_name.o dns_nd.o dns_packet.o dns_random.o dns_rcip.o dns_rcrw.o \ +dns_resolve.o dns_sortip.o dns_transmit.o dns_txt.o + ./makelib dns.a dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o \ + dns_ipq.o dns_name.o dns_nd.o dns_packet.o dns_random.o \ + dns_rcip.o dns_rcrw.o dns_resolve.o dns_sortip.o \ + dns_transmit.o dns_txt.o + +dns_dfd.o: \ +compile dns_dfd.c error.h alloc.h byte.h dns.h stralloc.h gen_alloc.h \ +iopause.h taia.h tai.h uint64.h taia.h + ./compile dns_dfd.c + +dns_domain.o: \ +compile dns_domain.c error.h alloc.h case.h byte.h dns.h stralloc.h \ +gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h + ./compile dns_domain.c + +dns_dtda.o: \ +compile dns_dtda.c stralloc.h gen_alloc.h dns.h stralloc.h iopause.h \ +taia.h tai.h uint64.h taia.h + ./compile dns_dtda.c + +dns_ip.o: \ +compile dns_ip.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \ +stralloc.h iopause.h taia.h tai.h uint64.h taia.h + ./compile dns_ip.c + +dns_ipq.o: \ +compile dns_ipq.c stralloc.h gen_alloc.h case.h byte.h str.h dns.h \ +stralloc.h iopause.h taia.h tai.h uint64.h taia.h + ./compile dns_ipq.c + +dns_name.o: \ +compile dns_name.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \ +stralloc.h iopause.h taia.h tai.h uint64.h taia.h + ./compile dns_name.c + +dns_nd.o: \ +compile dns_nd.c byte.h fmt.h dns.h stralloc.h gen_alloc.h iopause.h \ +taia.h tai.h uint64.h taia.h + ./compile dns_nd.c + +dns_packet.o: \ +compile dns_packet.c error.h dns.h stralloc.h gen_alloc.h iopause.h \ +taia.h tai.h uint64.h taia.h + ./compile dns_packet.c + +dns_random.o: \ +compile dns_random.c dns.h stralloc.h gen_alloc.h iopause.h taia.h \ +tai.h uint64.h taia.h taia.h uint32.h + ./compile dns_random.c + +dns_rcip.o: \ +compile dns_rcip.c taia.h tai.h uint64.h openreadclose.h stralloc.h \ +gen_alloc.h byte.h ip4.h env.h dns.h stralloc.h iopause.h taia.h \ +taia.h + ./compile dns_rcip.c + +dns_rcrw.o: \ +compile dns_rcrw.c taia.h tai.h uint64.h env.h byte.h str.h \ +openreadclose.h stralloc.h gen_alloc.h dns.h stralloc.h iopause.h \ +taia.h taia.h + ./compile dns_rcrw.c + +dns_resolve.o: \ +compile dns_resolve.c iopause.h taia.h tai.h uint64.h taia.h byte.h \ +dns.h stralloc.h gen_alloc.h iopause.h taia.h + ./compile dns_resolve.c + +dns_sortip.o: \ +compile dns_sortip.c byte.h dns.h stralloc.h gen_alloc.h iopause.h \ +taia.h tai.h uint64.h taia.h + ./compile dns_sortip.c + +dns_transmit.o: \ +compile dns_transmit.c socket.h uint16.h alloc.h error.h byte.h \ +readwrite.h uint16.h dns.h stralloc.h gen_alloc.h iopause.h taia.h \ +tai.h uint64.h taia.h + ./compile dns_transmit.c + +dns_txt.o: \ +compile dns_txt.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \ +stralloc.h iopause.h taia.h tai.h uint64.h taia.h + ./compile dns_txt.c env.o: \ -compile env.c str.h alloc.h env.h +compile env.c str.h env.h ./compile env.c -envread.o: \ -compile envread.c env.h str.h - ./compile envread.c - -error.0: \ -error.3 - nroff -man error.3 > error.0 - -error.a: \ -makelib error.o error_str.o - ./makelib error.a error.o error_str.o - error.o: \ compile error.c error.h ./compile error.c -error_str.0: \ -error_str.3 - nroff -man error_str.3 > error_str.0 - error_str.o: \ compile error_str.c error.h ./compile error_str.c -fd.a: \ -makelib fd_copy.o fd_move.o - ./makelib fd.a fd_copy.o fd_move.o - -fd_copy.0: \ -fd_copy.3 - nroff -man fd_copy.3 > fd_copy.0 - fd_copy.o: \ compile fd_copy.c fd.h ./compile fd_copy.c -fd_move.0: \ -fd_move.3 - nroff -man fd_move.3 > fd_move.0 - fd_move.o: \ compile fd_move.c fd.h ./compile fd_move.c @@ -247,78 +292,48 @@ warn-auto.sh finger@.sh conf-home > finger@ chmod 755 finger@ -finger@.0: \ -finger@.1 - nroff -man finger@.1 > finger@.0 - -fixcr: \ -load fixcr.o substdio.a error.a str.a - ./load fixcr substdio.a error.a str.a +fixcrio: \ +load fixcrio.o time.a unix.a byte.a + ./load fixcrio time.a unix.a byte.a -fixcr.0: \ -fixcr.1 - nroff -man fixcr.1 > fixcr.0 - -fixcr.o: \ -compile fixcr.c substdio.h subfd.h substdio.h exit.h - ./compile fixcr.c - -fmt_str.o: \ -compile fmt_str.c fmt.h - ./compile fmt_str.c +fixcrio.o: \ +compile fixcrio.c sig.h buffer.h strerr.h byte.h readwrite.h exit.h \ +iopause.h taia.h tai.h uint64.h pathexec.h + ./compile fixcrio.c fmt_ulong.o: \ compile fmt_ulong.c fmt.h ./compile fmt_ulong.c -fs.a: \ -makelib fmt_str.o fmt_ulong.o scan_ulong.o - ./makelib fs.a fmt_str.o fmt_ulong.o scan_ulong.o - -getln.0: \ -getln.3 - nroff -man getln.3 > getln.0 - -getln.a: \ -makelib getln.o getln2.o - ./makelib getln.a getln.o getln2.o +fork.h: \ +choose compile load tryvfork.c fork.h1 fork.h2 + ./choose cl tryvfork fork.h1 fork.h2 > fork.h getln.o: \ -compile getln.c substdio.h byte.h stralloc.h gen_alloc.h getln.h +compile getln.c byte.h getln.h buffer.h stralloc.h gen_alloc.h ./compile getln.c -getln2.0: \ -getln2.3 - nroff -man getln2.3 > getln2.0 - getln2.o: \ -compile getln2.c substdio.h stralloc.h gen_alloc.h byte.h getln.h +compile getln2.c byte.h getln.h buffer.h stralloc.h gen_alloc.h ./compile getln2.c -getopt.a: \ -makelib subgetopt.o sgetopt.o - ./makelib getopt.a subgetopt.o sgetopt.o - hassgact.h: \ -trysgact.c compile load - ( ( ./compile trysgact.c && ./load trysgact ) >/dev/null \ - 2>&1 \ - && echo \#define HASSIGACTION 1 || exit 0 ) > hassgact.h - rm -f trysgact.o trysgact +choose compile load trysgact.c hassgact.h1 hassgact.h2 + ./choose cl trysgact hassgact.h1 hassgact.h2 > hassgact.h hassgprm.h: \ -trysgprm.c compile load - ( ( ./compile trysgprm.c && ./load trysgprm ) >/dev/null \ - 2>&1 \ - && echo \#define HASSIGPROCMASK 1 || exit 0 ) > hassgprm.h - rm -f trysgprm.o trysgprm +choose compile load trysgprm.c hassgprm.h1 hassgprm.h2 + ./choose cl trysgprm hassgprm.h1 hassgprm.h2 > hassgprm.h + +hasshsgr.h: \ +choose compile load tryshsgr.c hasshsgr.h1 hasshsgr.h2 chkshsgr \ +warn-shsgr + ./chkshsgr || ( cat warn-shsgr; exit 1 ) + ./choose clr tryshsgr hasshsgr.h1 hasshsgr.h2 > hasshsgr.h haswaitp.h: \ -trywaitp.c compile load - ( ( ./compile trywaitp.c && ./load trywaitp ) >/dev/null \ - 2>&1 \ - && echo \#define HASWAITPID 1 || exit 0 ) > haswaitp.h - rm -f trywaitp.o trywaitp +choose compile load trywaitp.c haswaitp.h1 haswaitp.h2 + ./choose cl trywaitp haswaitp.h1 haswaitp.h2 > haswaitp.h hier.o: \ compile hier.c auto_home.h @@ -331,41 +346,40 @@ warn-auto.sh http@.sh conf-home > http@ chmod 755 http@ -http@.0: \ -http@.1 - nroff -man http@.1 > http@.0 - install: \ -load install.o hier.o auto_home.o strerr.a substdio.a open.a error.a \ -str.a - ./load install hier.o auto_home.o strerr.a substdio.a \ - open.a error.a str.a +load install.o hier.o auto_home.o unix.a byte.a + ./load install hier.o auto_home.o unix.a byte.a install.o: \ -compile install.c substdio.h strerr.h error.h open.h readwrite.h \ -exit.h +compile install.c buffer.h strerr.h error.h open.h readwrite.h exit.h ./compile install.c instcheck: \ -load instcheck.o hier.o auto_home.o strerr.a substdio.a error.a str.a - ./load instcheck hier.o auto_home.o strerr.a substdio.a \ - error.a str.a +load instcheck.o hier.o auto_home.o unix.a byte.a + ./load instcheck hier.o auto_home.o unix.a byte.a instcheck.o: \ compile instcheck.c strerr.h error.h readwrite.h exit.h ./compile instcheck.c -ip.o: \ -compile ip.c fmt.h scan.h ip.h - ./compile ip.c +iopause.h: \ +choose compile trypoll.c iopause.h1 iopause.h2 + ./choose clr trypoll iopause.h1 iopause.h2 > iopause.h -ipalloc.o: \ -compile ipalloc.c alloc.h gen_allocdefs.h ip.h ipalloc.h ip.h \ -gen_alloc.h - ./compile ipalloc.c +iopause.o: \ +compile iopause.c taia.h tai.h uint64.h select.h iopause.h taia.h + ./compile iopause.c + +ip4_fmt.o: \ +compile ip4_fmt.c fmt.h ip4.h + ./compile ip4_fmt.c + +ip4_scan.o: \ +compile ip4_scan.c scan.h ip4.h + ./compile ip4_scan.c it: \ -man prog install instcheck +prog install instcheck load: \ warn-auto.sh conf-ld @@ -395,13 +409,6 @@ warn-auto.sh systype ) > makelib chmod 755 makelib -man: \ -tcpclient.0 tcpserver.0 tcprules.0 tcprulescheck.0 tcp-environ.0 \ -who@.0 date@.0 finger@.0 http@.0 tcpcat.0 mconnect.0 fixcr.0 addcr.0 \ -delcr.0 argv0.0 recordio.0 error.0 error_str.0 alloc.0 case.0 cdb.0 \ -env.0 fd_copy.0 fd_move.0 getln.0 getln2.0 sgetopt.0 subgetopt.0 \ -stralloc.0 wait.0 - mconnect: \ warn-auto.sh mconnect.sh conf-home cat warn-auto.sh mconnect.sh \ @@ -410,33 +417,21 @@ warn-auto.sh mconnect.sh conf-home chmod 755 mconnect mconnect-io: \ -load mconnect-io.o strerr.a substdio.a error.a str.a wait.a sig.a - ./load mconnect-io strerr.a substdio.a error.a str.a \ - wait.a sig.a +load mconnect-io.o unix.a byte.a + ./load mconnect-io unix.a byte.a mconnect-io.o: \ -compile mconnect-io.c sig.h substdio.h strerr.h readwrite.h exit.h +compile mconnect-io.c sig.h wait.h fork.h buffer.h strerr.h \ +readwrite.h exit.h ./compile mconnect-io.c -mconnect.0: \ -mconnect.1 - nroff -man mconnect.1 > mconnect.0 - -ndelay.a: \ -makelib ndelay.o ndelay_off.o - ./makelib ndelay.a ndelay.o ndelay_off.o - -ndelay.o: \ -compile ndelay.c ndelay.h - ./compile ndelay.c - ndelay_off.o: \ compile ndelay_off.c ndelay.h ./compile ndelay_off.c -open.a: \ -makelib open_read.o open_trunc.o - ./makelib open.a open_read.o open_trunc.o +ndelay_on.o: \ +compile ndelay_on.c ndelay.h + ./compile ndelay_on.c open_read.o: \ compile open_read.c open.h @@ -446,27 +441,64 @@ open_trunc.o: \ compile open_trunc.c open.h ./compile open_trunc.c +open_write.o: \ +compile open_write.c open.h + ./compile open_write.c + +openreadclose.o: \ +compile openreadclose.c error.h open.h readclose.h stralloc.h \ +gen_alloc.h openreadclose.h stralloc.h + ./compile openreadclose.c + +pathexec_env.o: \ +compile pathexec_env.c stralloc.h gen_alloc.h alloc.h str.h byte.h \ +env.h pathexec.h + ./compile pathexec_env.c + +pathexec_run.o: \ +compile pathexec_run.c error.h stralloc.h gen_alloc.h str.h env.h \ +pathexec.h + ./compile pathexec_run.c + prog: \ -tcpclient tcpserver tcprules tcprulescheck who@ date@ finger@ http@ \ -tcpcat mconnect mconnect-io fixcr addcr delcr argv0 recordio rts +tcpserver tcprules tcprulescheck argv0 recordio tcpclient who@ date@ \ +finger@ http@ tcpcat mconnect mconnect-io addcr delcr fixcrio \ +rblsmtpd rts + +prot.o: \ +compile prot.c hasshsgr.h prot.h + ./compile prot.c + +rblsmtpd: \ +load rblsmtpd.o commands.o dns.a time.a unix.a byte.a socket.lib + ./load rblsmtpd commands.o dns.a time.a unix.a byte.a \ + `cat socket.lib` + +rblsmtpd.o: \ +compile rblsmtpd.c byte.h str.h scan.h fmt.h env.h exit.h sig.h \ +buffer.h readwrite.h sgetopt.h subgetopt.h strerr.h stralloc.h \ +gen_alloc.h commands.h pathexec.h dns.h stralloc.h iopause.h taia.h \ +tai.h uint64.h taia.h + ./compile rblsmtpd.c + +readclose.o: \ +compile readclose.c readwrite.h error.h readclose.h stralloc.h \ +gen_alloc.h + ./compile readclose.c recordio: \ -load recordio.o strerr.a substdio.a error.a str.a fs.a fd.a sig.a - ./load recordio strerr.a substdio.a error.a str.a fs.a \ - fd.a sig.a - -recordio.0: \ -recordio.1 - nroff -man recordio.1 > recordio.0 +load recordio.o time.a unix.a byte.a + ./load recordio time.a unix.a byte.a recordio.o: \ -compile recordio.c sig.h substdio.h strerr.h str.h byte.h readwrite.h \ -exit.h fmt.h select.h +compile recordio.c sig.h buffer.h strerr.h str.h byte.h readwrite.h \ +exit.h fmt.h iopause.h taia.h tai.h uint64.h pathexec.h ./compile recordio.c remoteinfo.o: \ -compile remoteinfo.c byte.h substdio.h ip.h fmt.h timeoutconn.h \ -timeoutread.h timeoutwrite.h remoteinfo.h +compile remoteinfo.c fmt.h buffer.h socket.h uint16.h error.h \ +iopause.h taia.h tai.h uint64.h timeoutconn.h uint16.h remoteinfo.h \ +stralloc.h gen_alloc.h uint16.h ./compile remoteinfo.c rts: \ @@ -476,77 +508,34 @@ warn-auto.sh rts.sh conf-home > rts chmod 755 rts +rules.o: \ +compile rules.c alloc.h stralloc.h gen_alloc.h open.h cdb.h uint32.h \ +rules.h stralloc.h + ./compile rules.c + scan_ulong.o: \ compile scan_ulong.c scan.h ./compile scan_ulong.c -seek.a: \ -makelib seek_set.o - ./makelib seek.a seek_set.o - seek_set.o: \ compile seek_set.c seek.h ./compile seek_set.c select.h: \ -compile trysysel.c select.h1 select.h2 - ( ./compile trysysel.c >/dev/null 2>&1 \ - && cat select.h2 || cat select.h1 ) > select.h - rm -f trysysel.o trysysel +choose compile trysysel.c select.h1 select.h2 + ./choose c trysysel select.h1 select.h2 > select.h setup: \ it install ./install -sgetopt.0: \ -sgetopt.3 - nroff -man sgetopt.3 > sgetopt.0 - sgetopt.o: \ -compile sgetopt.c substdio.h subfd.h substdio.h sgetopt.h subgetopt.h \ -subgetopt.h +compile sgetopt.c buffer.h sgetopt.h subgetopt.h subgetopt.h ./compile sgetopt.c -shar: \ -FILES BLURB README TODO THANKS CHANGES UCSPI TCP FILES VERSION \ -SYSDEPS TARGETS Makefile tcpclient.1 tcpclient.c who@.1 who@.sh \ -date@.1 date@.sh finger@.1 finger@.sh http@.1 http@.sh tcpcat.1 \ -tcpcat.sh mconnect.1 mconnect.sh mconnect-io.c delcr.1 delcr.c \ -addcr.1 addcr.c fixcr.1 fixcr.c tcpserver.1 tcpserver.c tcprules.1 \ -tcprules.c tcprulescheck.1 tcprulescheck.c tcp-environ.5 recordio.1 \ -recordio.c argv0.1 argv0.c rts.sh rts.tests rts.exp conf-cc conf-ld \ -find-systype.sh trycpp.c warn-auto.sh INSTALL hier.c conf-home \ -auto-str.c auto_home.h install.c instcheck.c substdio.h substdio.c \ -substdi.c substdo.c substdio_copy.c subfd.h subfderr.c subfdout.c \ -subfdin.c readwrite.h exit.h strerr.h strerr_sys.c strerr_die.c \ -error.3 error_str.3 error.h error.c error_str.c open.h open_read.c \ -open_trunc.c byte.h byte_chr.c byte_copy.c byte_cr.c byte_diff.c \ -byte_rchr.c byte_zero.c str.h str_chr.c str_cpy.c str_diff.c \ -str_diffn.c str_len.c alloc.3 alloc.h alloc.c alloc_re.c case.3 \ -case.h case_lowers.c cdb.3 cdb.h cdb_hash.c cdb_seek.c cdb_unpack.c \ -cdbmake.h cdbmake_add.c cdbmake_hash.c cdbmake_pack.c cdbmss.h \ -cdbmss.c dns.h dns.c trylsock.c tryrsolv.c env.3 env.h env.c \ -envread.c fd.h fd_copy.3 fd_copy.c fd_move.3 fd_move.c fmt.h \ -fmt_str.c fmt_ulong.c scan.h scan_ulong.c getln.3 getln.h getln.c \ -getln2.3 getln2.c sgetopt.3 sgetopt.h sgetopt.c subgetopt.3 \ -subgetopt.h subgetopt.c ip.h ip.c ipalloc.h ipalloc.c ndelay.h \ -ndelay.c ndelay_off.c remoteinfo.h remoteinfo.c seek.h seek_set.c \ -select.h1 select.h2 trysysel.c sig.h sig_block.c sig_catch.c \ -sig_pause.c sig_pipe.c sig_child.c sig_term.c trysgact.c trysgprm.c \ -gen_alloc.h gen_allocdefs.h stralloc.3 stralloc.h stralloc_eady.c \ -stralloc_pend.c stralloc_copy.c stralloc_opyb.c stralloc_opys.c \ -stralloc_cat.c stralloc_catb.c stralloc_cats.c timeoutconn.h \ -timeoutconn.c timeoutread.h timeoutread.c timeoutwrite.h \ -timeoutwrite.c uint32.h1 uint32.h2 tryulong32.c wait.3 wait.h \ -wait_nohang.c wait_pid.c trywaitp.c - shar -m `cat FILES` > shar - chmod 400 shar - -sig.a: \ -makelib sig_block.o sig_catch.o sig_pause.o sig_pipe.o sig_child.o \ -sig_term.o - ./makelib sig.a sig_block.o sig_catch.o sig_pause.o \ - sig_pipe.o sig_child.o sig_term.o +sig.o: \ +compile sig.c sig.h + ./compile sig.c sig_block.o: \ compile sig_block.c sig.h hassgprm.h @@ -556,22 +545,10 @@ sig_catch.o: \ compile sig_catch.c sig.h hassgact.h ./compile sig_catch.c -sig_child.o: \ -compile sig_child.c sig.h - ./compile sig_child.c - sig_pause.o: \ compile sig_pause.c sig.h hassgprm.h ./compile sig_pause.c -sig_pipe.o: \ -compile sig_pipe.c sig.h - ./compile sig_pipe.c - -sig_term.o: \ -compile sig_term.c sig.h - ./compile sig_term.c - socket.lib: \ trylsock.c compile load ( ( ./compile trylsock.c && \ @@ -579,44 +556,61 @@ trylsock.c compile load && echo -lsocket -lnsl || exit 0 ) > socket.lib rm -f trylsock.o trylsock -str.a: \ -makelib str_chr.o str_len.o str_diff.o str_diffn.o str_cpy.o \ -byte_chr.o byte_rchr.o byte_diff.o byte_copy.o byte_cr.o byte_zero.o - ./makelib str.a str_chr.o str_len.o str_diff.o str_diffn.o \ - str_cpy.o byte_chr.o byte_rchr.o byte_diff.o byte_copy.o \ - byte_cr.o byte_zero.o +socket_accept.o: \ +compile socket_accept.c byte.h socket.h uint16.h + ./compile socket_accept.c + +socket_bind.o: \ +compile socket_bind.c byte.h socket.h uint16.h + ./compile socket_bind.c + +socket_conn.o: \ +compile socket_conn.c readwrite.h byte.h socket.h uint16.h + ./compile socket_conn.c + +socket_delay.o: \ +compile socket_delay.c socket.h uint16.h + ./compile socket_delay.c + +socket_listen.o: \ +compile socket_listen.c socket.h uint16.h + ./compile socket_listen.c + +socket_local.o: \ +compile socket_local.c byte.h socket.h uint16.h + ./compile socket_local.c + +socket_opts.o: \ +compile socket_opts.c socket.h uint16.h + ./compile socket_opts.c + +socket_remote.o: \ +compile socket_remote.c byte.h socket.h uint16.h + ./compile socket_remote.c + +socket_tcp.o: \ +compile socket_tcp.c ndelay.h socket.h uint16.h + ./compile socket_tcp.c + +socket_udp.o: \ +compile socket_udp.c ndelay.h socket.h uint16.h + ./compile socket_udp.c str_chr.o: \ compile str_chr.c str.h ./compile str_chr.c -str_cpy.o: \ -compile str_cpy.c str.h - ./compile str_cpy.c - str_diff.o: \ compile str_diff.c str.h ./compile str_diff.c -str_diffn.o: \ -compile str_diffn.c str.h - ./compile str_diffn.c - str_len.o: \ compile str_len.c str.h ./compile str_len.c -stralloc.0: \ -stralloc.3 - nroff -man stralloc.3 > stralloc.0 - -stralloc.a: \ -makelib stralloc_eady.o stralloc_pend.o stralloc_copy.o \ -stralloc_opys.o stralloc_opyb.o stralloc_cat.o stralloc_cats.o \ -stralloc_catb.o - ./makelib stralloc.a stralloc_eady.o stralloc_pend.o \ - stralloc_copy.o stralloc_opys.o stralloc_opyb.o \ - stralloc_cat.o stralloc_cats.o stralloc_catb.o +str_start.o: \ +compile str_start.c str.h + ./compile str_start.c stralloc_cat.o: \ compile stralloc_cat.c byte.h stralloc.h gen_alloc.h @@ -652,71 +646,61 @@ compile stralloc_pend.c alloc.h stralloc.h gen_alloc.h \ gen_allocdefs.h ./compile stralloc_pend.c -strerr.a: \ -makelib strerr_sys.o strerr_die.o - ./makelib strerr.a strerr_sys.o strerr_die.o - strerr_die.o: \ -compile strerr_die.c substdio.h subfd.h substdio.h exit.h strerr.h +compile strerr_die.c buffer.h exit.h strerr.h ./compile strerr_die.c strerr_sys.o: \ compile strerr_sys.c error.h strerr.h ./compile strerr_sys.c -subfderr.o: \ -compile subfderr.c readwrite.h substdio.h subfd.h substdio.h - ./compile subfderr.c - -subfdin.o: \ -compile subfdin.c readwrite.h substdio.h subfd.h substdio.h - ./compile subfdin.c - -subfdout.o: \ -compile subfdout.c readwrite.h substdio.h subfd.h substdio.h - ./compile subfdout.c - -subgetopt.0: \ -subgetopt.3 - nroff -man subgetopt.3 > subgetopt.0 - subgetopt.o: \ compile subgetopt.c subgetopt.h ./compile subgetopt.c -substdi.o: \ -compile substdi.c substdio.h byte.h error.h - ./compile substdi.c - -substdio.a: \ -makelib substdio.o substdi.o substdo.o subfderr.o subfdout.o \ -subfdin.o substdio_copy.o - ./makelib substdio.a substdio.o substdi.o substdo.o \ - subfderr.o subfdout.o subfdin.o substdio_copy.o - -substdio.o: \ -compile substdio.c substdio.h - ./compile substdio.c - -substdio_copy.o: \ -compile substdio_copy.c substdio.h - ./compile substdio_copy.c - -substdo.o: \ -compile substdo.c substdio.h str.h byte.h error.h - ./compile substdo.c - systype: \ -find-systype.sh conf-cc conf-ld trycpp.c +find-systype.sh conf-cc conf-ld trycpp.c x86cpuid.c ( cat warn-auto.sh; \ echo CC=\'`head -1 conf-cc`\'; \ echo LD=\'`head -1 conf-ld`\'; \ cat find-systype.sh; \ ) | sh > systype -tcp-environ.0: \ -tcp-environ.5 - nroff -man tcp-environ.5 > tcp-environ.0 +tai_pack.o: \ +compile tai_pack.c tai.h uint64.h + ./compile tai_pack.c + +taia_add.o: \ +compile taia_add.c taia.h tai.h uint64.h + ./compile taia_add.c + +taia_approx.o: \ +compile taia_approx.c taia.h tai.h uint64.h + ./compile taia_approx.c + +taia_frac.o: \ +compile taia_frac.c taia.h tai.h uint64.h + ./compile taia_frac.c + +taia_less.o: \ +compile taia_less.c taia.h tai.h uint64.h + ./compile taia_less.c + +taia_now.o: \ +compile taia_now.c taia.h tai.h uint64.h + ./compile taia_now.c + +taia_pack.o: \ +compile taia_pack.c taia.h tai.h uint64.h + ./compile taia_pack.c + +taia_sub.o: \ +compile taia_sub.c taia.h tai.h uint64.h + ./compile taia_sub.c + +taia_uint.o: \ +compile taia_uint.c taia.h tai.h uint64.h + ./compile taia_uint.c tcpcat: \ warn-auto.sh tcpcat.sh conf-home @@ -725,97 +709,72 @@ warn-auto.sh tcpcat.sh conf-home > tcpcat chmod 755 tcpcat -tcpcat.0: \ -tcpcat.1 - nroff -man tcpcat.1 > tcpcat.0 - tcpclient: \ -load tcpclient.o ip.o ipalloc.o dns.o remoteinfo.o timeoutconn.o \ -timeoutread.o timeoutwrite.o getopt.a strerr.a stralloc.a env.a \ -alloc.a ndelay.a substdio.a error.a str.a sig.a fd.a case.a fs.a \ -dns.lib socket.lib - ./load tcpclient ip.o ipalloc.o dns.o remoteinfo.o \ - timeoutconn.o timeoutread.o timeoutwrite.o getopt.a \ - strerr.a stralloc.a env.a alloc.a ndelay.a substdio.a \ - error.a str.a sig.a fd.a case.a fs.a `cat dns.lib` `cat \ - socket.lib` - -tcpclient.0: \ -tcpclient.1 - nroff -man tcpclient.1 > tcpclient.0 +load tcpclient.o remoteinfo.o timeoutconn.o dns.a time.a unix.a \ +byte.a socket.lib + ./load tcpclient remoteinfo.o timeoutconn.o dns.a time.a \ + unix.a byte.a `cat socket.lib` tcpclient.o: \ -compile tcpclient.c strerr.h stralloc.h gen_alloc.h str.h byte.h \ -sig.h fd.h ip.h ipalloc.h ip.h gen_alloc.h case.h sgetopt.h \ -subgetopt.h exit.h scan.h fmt.h env.h dns.h remoteinfo.h +compile tcpclient.c sig.h exit.h sgetopt.h subgetopt.h uint16.h fmt.h \ +scan.h str.h ip4.h uint16.h socket.h uint16.h fd.h stralloc.h \ +gen_alloc.h buffer.h error.h strerr.h pathexec.h timeoutconn.h \ +uint16.h remoteinfo.h stralloc.h uint16.h dns.h stralloc.h iopause.h \ +taia.h tai.h uint64.h taia.h ./compile tcpclient.c tcprules: \ -load tcprules.o cdbmss.o cdbmake.a getln.a strerr.a stralloc.a \ -substdio.a alloc.a error.a open.a seek.a str.a fs.a - ./load tcprules cdbmss.o cdbmake.a getln.a strerr.a \ - stralloc.a substdio.a alloc.a error.a open.a seek.a str.a \ - fs.a - -tcprules.0: \ -tcprules.1 - nroff -man tcprules.1 > tcprules.0 +load tcprules.o cdb.a unix.a byte.a + ./load tcprules cdb.a unix.a byte.a tcprules.o: \ -compile tcprules.c strerr.h stralloc.h gen_alloc.h getln.h substdio.h \ -subfd.h substdio.h exit.h fmt.h byte.h cdbmss.h cdbmake.h uint32.h \ -substdio.h +compile tcprules.c strerr.h stralloc.h gen_alloc.h getln.h buffer.h \ +stralloc.h buffer.h exit.h fmt.h byte.h cdb_make.h buffer.h uint32.h ./compile tcprules.c tcprulescheck: \ -load tcprulescheck.o cdb.a stralloc.a alloc.a strerr.a substdio.a \ -error.a str.a open.a - ./load tcprulescheck cdb.a stralloc.a alloc.a strerr.a \ - substdio.a error.a str.a open.a - -tcprulescheck.0: \ -tcprulescheck.1 - nroff -man tcprulescheck.1 > tcprulescheck.0 +load tcprulescheck.o rules.o cdb.a unix.a byte.a + ./load tcprulescheck rules.o cdb.a unix.a byte.a tcprulescheck.o: \ -compile tcprulescheck.c substdio.h subfd.h substdio.h strerr.h \ -stralloc.h gen_alloc.h alloc.h cdb.h uint32.h +compile tcprulescheck.c byte.h buffer.h strerr.h env.h rules.h \ +stralloc.h gen_alloc.h ./compile tcprulescheck.c tcpserver: \ -load tcpserver.o ip.o ipalloc.o dns.o remoteinfo.o timeoutconn.o \ -timeoutread.o timeoutwrite.o cdb.a open.a wait.a strerr.a stralloc.a \ -env.a ndelay.a alloc.a getopt.a substdio.a error.a str.a sig.a fd.a \ -case.a fs.a dns.lib socket.lib - ./load tcpserver ip.o ipalloc.o dns.o remoteinfo.o \ - timeoutconn.o timeoutread.o timeoutwrite.o cdb.a open.a \ - wait.a strerr.a stralloc.a env.a ndelay.a alloc.a getopt.a \ - substdio.a error.a str.a sig.a fd.a case.a fs.a `cat \ - dns.lib` `cat socket.lib` - -tcpserver.0: \ -tcpserver.1 - nroff -man tcpserver.1 > tcpserver.0 +load tcpserver.o rules.o remoteinfo.o timeoutconn.o cdb.a dns.a \ +time.a unix.a byte.a socket.lib + ./load tcpserver rules.o remoteinfo.o timeoutconn.o cdb.a \ + dns.a time.a unix.a byte.a `cat socket.lib` tcpserver.o: \ -compile tcpserver.c strerr.h substdio.h stralloc.h gen_alloc.h \ -alloc.h readwrite.h fd.h sig.h wait.h ip.h ipalloc.h ip.h gen_alloc.h \ -dns.h str.h case.h byte.h sgetopt.h subgetopt.h remoteinfo.h exit.h \ -open.h scan.h fmt.h env.h cdb.h uint32.h +compile tcpserver.c uint16.h str.h byte.h fmt.h scan.h ip4.h fd.h \ +exit.h env.h prot.h open.h wait.h readwrite.h stralloc.h gen_alloc.h \ +alloc.h buffer.h error.h strerr.h sgetopt.h subgetopt.h pathexec.h \ +socket.h uint16.h ndelay.h remoteinfo.h stralloc.h uint16.h rules.h \ +stralloc.h sig.h dns.h stralloc.h iopause.h taia.h tai.h uint64.h \ +taia.h ./compile tcpserver.c +time.a: \ +makelib iopause.o tai_pack.o taia_add.o taia_approx.o taia_frac.o \ +taia_less.o taia_now.o taia_pack.o taia_sub.o taia_uint.o + ./makelib time.a iopause.o tai_pack.o taia_add.o \ + taia_approx.o taia_frac.o taia_less.o taia_now.o \ + taia_pack.o taia_sub.o taia_uint.o + timeoutconn.o: \ -compile timeoutconn.c ndelay.h select.h error.h readwrite.h ip.h \ -byte.h timeoutconn.h +compile timeoutconn.c ndelay.h socket.h uint16.h iopause.h taia.h \ +tai.h uint64.h error.h timeoutconn.h uint16.h ./compile timeoutconn.c -timeoutread.o: \ -compile timeoutread.c timeoutread.h select.h error.h readwrite.h - ./compile timeoutread.c +uint16_pack.o: \ +compile uint16_pack.c uint16.h + ./compile uint16_pack.c -timeoutwrite.o: \ -compile timeoutwrite.c timeoutwrite.h select.h error.h readwrite.h - ./compile timeoutwrite.c +uint16_unpack.o: \ +compile uint16_unpack.c uint16.h + ./compile uint16_unpack.c uint32.h: \ tryulong32.c compile load uint32.h1 uint32.h2 @@ -824,13 +783,43 @@ tryulong32.c compile load uint32.h1 uint32.h2 && cat uint32.h2 || cat uint32.h1 ) > uint32.h rm -f tryulong32.o tryulong32 -wait.0: \ -wait.3 - nroff -man wait.3 > wait.0 - -wait.a: \ -makelib wait_nohang.o wait_pid.o - ./makelib wait.a wait_nohang.o wait_pid.o +uint32_pack.o: \ +compile uint32_pack.c uint32.h + ./compile uint32_pack.c + +uint32_unpack.o: \ +compile uint32_unpack.c uint32.h + ./compile uint32_unpack.c + +uint64.h: \ +choose compile load tryulong64.c uint64.h1 uint64.h2 + ./choose clr tryulong64 uint64.h1 uint64.h2 > uint64.h + +unix.a: \ +makelib alloc.o alloc_re.o buffer.o buffer_0.o buffer_1.o buffer_2.o \ +buffer_copy.o buffer_get.o buffer_put.o env.o error.o error_str.o \ +fd_copy.o fd_move.o getln.o getln2.o ndelay_off.o ndelay_on.o \ +open_read.o open_trunc.o open_write.o openreadclose.o pathexec_env.o \ +pathexec_run.o prot.o readclose.o seek_set.o sgetopt.o sig.o \ +sig_block.o sig_catch.o sig_pause.o socket_accept.o socket_bind.o \ +socket_conn.o socket_delay.o socket_listen.o socket_local.o \ +socket_opts.o socket_remote.o socket_tcp.o socket_udp.o \ +stralloc_cat.o stralloc_catb.o stralloc_cats.o stralloc_copy.o \ +stralloc_eady.o stralloc_opyb.o stralloc_opys.o stralloc_pend.o \ +strerr_die.o strerr_sys.o subgetopt.o wait_nohang.o wait_pid.o + ./makelib unix.a alloc.o alloc_re.o buffer.o buffer_0.o \ + buffer_1.o buffer_2.o buffer_copy.o buffer_get.o \ + buffer_put.o env.o error.o error_str.o fd_copy.o fd_move.o \ + getln.o getln2.o ndelay_off.o ndelay_on.o open_read.o \ + open_trunc.o open_write.o openreadclose.o pathexec_env.o \ + pathexec_run.o prot.o readclose.o seek_set.o sgetopt.o \ + sig.o sig_block.o sig_catch.o sig_pause.o socket_accept.o \ + socket_bind.o socket_conn.o socket_delay.o socket_listen.o \ + socket_local.o socket_opts.o socket_remote.o socket_tcp.o \ + socket_udp.o stralloc_cat.o stralloc_catb.o stralloc_cats.o \ + stralloc_copy.o stralloc_eady.o stralloc_opyb.o \ + stralloc_opys.o stralloc_pend.o strerr_die.o strerr_sys.o \ + subgetopt.o wait_nohang.o wait_pid.o wait_nohang.o: \ compile wait_nohang.c haswaitp.h @@ -846,7 +835,3 @@ warn-auto.sh who@.sh conf-home | sed s}HOME}"`head -1 conf-home`"}g \ > who@ chmod 755 who@ - -who@.0: \ -who@.1 - nroff -man who@.1 > who@.0 @@ -1,159 +1,7 @@ -ucspi-tcp 0.84, beta. -19981111 -Copyright 1998 -D. J. Bernstein, djb@pobox.com -http://pobox.com/~djb/ucspi-tcp.html +ucspi-tcp 0.88, beta. +20000318 +Copyright 2000 +D. J. Bernstein -tcpserver and tcpclient are easy-to-use command-line tools for building -TCP client-server applications. See BLURB for a more detailed -advertisement. - -INSTALL says how to set up tcpserver and tcpclient. - -You may distribute unmodified copies of the ucspi-tcp package. - -The rest of this file is a list of systypes where various versions of -ucspi-tcp have been reported to work. 0.70 was the first beta version. - -0.80: aix-4-1-:-:-:0024dd0a4c00-:- (tnx MH) -0.73: aix-4-2-:-:-:000055247900-:- (tnx JLB) -0.80: aix-4-2-:-:-:000136094c00-:- (tnx TU) -0.80: bsd.os-2.1-:i386-:-:pentium-:- (tnx ARB) -0.73: bsd.os-3.0-:i386-:-:pentium-:- (tnx SN) -0.80: bsd.os-4.0-:i386-:-:pentium-:- (tnx SGT) -0.73: freebsd-2.1.0-release-:i386-:-:i486.dx2-:- (tnx NM) -0.80: freebsd-2.1.0-release-:i386-:-:pentium.735\90.or.815\100-:- (tnx MBS) -0.73: freebsd-2.2-970422-releng-:i386-:-:pentium-:- (tnx TM) -0.73: freebsd-2.2-970618-releng-:i386-:-:pentium-:- (tnx LST) -0.72: freebsd-2.2-release-:i386-:-:pentium-:- (tnx frank@news=???) -0.73: freebsd-2.2-stable-:i386-:-:pentium-:- (tnx JJE) -0.73: freebsd-2.2.1-release-:i386-:-:-:- (tnx TM) -0.80: freebsd-2.2.1-release-:i386-:-:pentium-:- (tnx GB) -0.73: freebsd-2.2.2-release-:i386-:-:amd.unknown-:- (tnx FN) -0.80: freebsd-2.2.2-release-:i386-:-:i486-dx-:- (tnx MM) -0.73: freebsd-2.2.2-release-:i386-:-:pentium-:- (tnx BMF) -0.80: freebsd-2.2.5-release-:i386-:-:amd.am486dx2/4.write-through-:- (tnx AT) -0.80: freebsd-2.2.5-release-:i386-:-:i486-dx-:- (tnx root@lightyear=???) -0.80: freebsd-2.2.5-release-:i386-:-:pentium-:- (tnx BJR) -0.80: freebsd-2.2.5-release-:i386-:-:pentium.pro-:- (tnx AY) -0.80: freebsd-2.2.5-stable-:i386-:-:amd.k6-:- (tnx WCH) -0.80: freebsd-2.2.5-stable-:i386-:-:pentium-:- (tnx WCH) -0.80: freebsd-2.2.6-release-:i386-:-:amd.enhanced.am486dx4.write-back-:- (tnx YT) -0.80: freebsd-2.2.6-release-:i386-:-:pentium-:- (tnx DJW) -0.80: freebsd-2.2.6-stable-:i386-:-:pentium.ii-:- (tnx JM) -0.80: freebsd-2.2.7-release-:i386-:-:i486.dx2-:- (tnx AI) -0.80: freebsd-2.2.7-release-:i386-:-:pentium.pro-:- (tnx CJ) -0.80: freebsd-2.2.7-release-:i386-:-:pentium/p54c-:- (tnx WA) -0.73: freebsd-3.0-971012-snap-:i386-:-:i486.dx2-:- (tnx AY) -0.80: freebsd-3.0-971208-snap-:i386-:-:pentium.pro-:- (tnx AY) -0.80: freebsd-3.0-980524-snap-:i386-:-:pentium/p54c-:- (tnx DCM) -0.80: freebsd-3.0-current-:i386-:-:pentium-:- (tnx J2B) -0.72: hp-ux-b.09.00-a-:-:-:9000.360-:- (tnx VV) -0.72: hp-ux-b.10.01-a-:-:-:9000.715-:- (tnx BG) -0.80: hp-ux-b.10.20-a-:-:-:9000.712-:- (tnx VH) -0.80: irix-5.3-02091401-:-:-:ip22-:- (tnx K2K) -0.80: irix-5.3-11091812-:-:-:ip22-:- (tnx AP) -0.80: irix-6.2-03131015-:-:-:ip22-:- (tnx AK) -0.80: irix-6.3-12161207-:-:-:ip32-:- (tnx DH) -0.80: irix-6.5-05190004-:-:-:ip32-:- (tnx DS) -0.80: jcc_bsd+-1.0-jcc_bsd+.1.0.#101..wed.jun..5.14.16.28.jst.1996.-:-:-:powerpc-:- (tnx TY) -0.72: linux-1.2.13-:i386-:-:i486-:- (tnx JDM) -0.71: linux-1.2.13-:i386-:-:ppc-:- (tnx EAP) -0.73: linux-2.0.18-:i386-:-:pentium-:- (tnx JDM) -0.72: linux-2.0.21-:i386-:-:pentium-:- (tnx SJ) -0.80: linux-2.0.22-:i386-:-:pentium-:- (tnx BMS) -0.72: linux-2.0.23-:i386-:-:i486-:- (tnx J2W) -0.72: linux-2.0.24-:i386-:-:pentium-:- (tnx VV) -0.72: linux-2.0.25-:i386-:-:i486-:- (tnx FPL) -0.73: linux-2.0.25-:i386-:-:pentium-:- (tnx AW) -0.72: linux-2.0.26-:i386-:-:pentium-:- (tnx root@pointer=???) -0.80: linux-2.0.27-:i386-:-:pentium-:- (tnx MEE) -0.73: linux-2.0.27-:i386-:-:ppro-:- (tnx PMK) -0.73: linux-2.0.28-:alpha-:-:alpha-:- (tnx T2K) -0.73: linux-2.0.29-:i386-:-:i486-:- (tnx JBKH) -0.72: linux-2.0.29-:i386-:-:i686-:- (tnx SR) -0.73: linux-2.0.29-:i386-:-:pentium-:- (tnx RAL) -0.73: linux-2.0.29-:i386-:-:ppro-:- (tnx GDP) -0.73: linux-2.0.30-:-:-:sparc-:- (tnx DJ) -0.73: linux-2.0.30-:i386-:-:i386-:- (tnx DMV) -0.80: linux-2.0.30-:i386-:-:i486-:- (tnx FPL) -0.80: linux-2.0.30-:i386-:-:pentium-:- -0.73: linux-2.0.30-:i386-:-:ppro-:- (tnx TG) -0.80: linux-2.0.31-:i386-:-:pentium-:- (tnx DWR) -0.80: linux-2.0.32-:i386-:-:pentium-:- (tnx AY) -0.73: linux-2.0.32-:i386-:-:ppro-:- (tnx JB) -0.80: linux-2.0.32-osfmach3-:-:-:ppc-:- (tnx CG) -0.80: linux-2.0.33-:-:-:mips-:- (tnx MBS) -0.80: linux-2.0.33-:i386-:-:i486-:- (tnx IH) -0.80: linux-2.0.33-:i386-:-:pentium-:- (tnx AJDV) -0.80: linux-2.0.33-:i386-:-:ppro-:- (tnx PRR) -0.80: linux-2.0.34-:i386-:-:i486-:- (tnx PN) -0.80: linux-2.0.34-:i386-:-:pentium-:- (tnx E2W) -0.80: linux-2.0.34-:i386-:-:ppro-:- (tnx DP) -0.80: linux-2.0.35-:i386-:-:i386-:- (tnx GH) -0.80: linux-2.0.35-:i386-:-:i486-:- (tnx HF) -0.80: linux-2.0.35-:i386-:-:pentium-:- (tnx UO) -0.80: linux-2.0.35-:i386-:-:ppro-:- (tnx SR) -0.80: linux-2.0.36-:i386-:-:pentium-:- (tnx WR) -0.73: linux-2.0.7-:i386-:-:i486-:- (tnx TLM) -0.80: linux-2.1.102-:i386-:-:pentium-:- (tnx BBBH) -0.80: linux-2.1.105-:i386-:-:pentium-:- (tnx JF) -0.80: linux-2.1.108-:alpha-:-:alpha-:- (tnx PR) -0.73: linux-2.1.30-:i386-:-:pentium-:- (tnx RAS) -0.73: linux-2.1.36-:i386-:-:pentium-:- (tnx JF) -0.80: linux-2.1.82-:i386-:-:pentium-:- (tnx AY) -0.73: netbsd-1.1-:i386-:-:pentium.(genuineintel.586-class.cpu)-:- (tnx GL) -0.80: netbsd-1.3-:i386-:-:intel.486dx2.(486-class)-:- (tnx GL) -0.80: netbsd-1.3.1-:sun3-:-:sun.3/60-:- (tnx MBS) -0.73: netbsd-1.3_alpha-:i386-:-:intel.pentium.(p54c).(586-class)-:- (tnx GL) -0.80: netbsd-1.3h-:sparc-:-:mb86904.@.85.mhz,.on-chip.fpu-:- (tnx FN) -0.73: nextstep-3.3-:mc680x0-:-:68040-:- (tnx root@superscript=???) -0.80: nextstep-4.1-:mc680x0-:-:68040-:- (tnx FN) -0.80: openbsd-2.3-generic#6-:openbsd.i386-:-:i386-:- (tnx JM) -0.80: openbsd-2.3-work.kernel#0-:openbsd.i386-:-:i386-:- (tnx JKB) -0.80: osf1-v2.0-240-:-:-:alpha-:- (tnx JF) -0.73: osf1-v3.2-214-:-:-:alpha-:- (tnx A2P) -0.80: osf1-v4.0-564-:-:-:alpha-:- (tnx ayamura@gw=???) -0.80: osf1-v4.0-564.32-:-:-:alpha-:- (tnx TT) -0.80: sunos-4.1.3_u1-1-:sparc-:sun4-:sun4c-:sun4c- (tnx MBS) -0.80: sunos-4.1.3_u1-1-:sparc-:sun4-:sun4m-:sun4m- (tnx ayamura@honey=???) -0.73: sunos-4.1.3_u1-4-:unknown-:sun4-:sun4m-:sun4m- (tnx J2B) -0.73: sunos-4.1.4-2-:sparc-:sun4-:sun4m-:sun4m- -0.72: sunos-5.4-generic-:sparc-:-:sun4m-:- (tnx MS) -0.80: sunos-5.4-generic-:sparc-:sun4-:sun4m-:sun4m- -0.72: sunos-5.4-generic_101945-32-:sparc-:sun4-:sun4m-:sun4m- (tnx RDM) -0.80: sunos-5.4-generic_101945-34-:sparc-:sun4-:sun4m-:sun4m- (tnx HU) -0.73: sunos-5.5-generic-:i386-:i86pc-:i86pc-:i86pc- (tnx PW) -0.72: sunos-5.5-generic-:sparc-:sun4-:sun4c-:sun4c- (tnx CG) -0.80: sunos-5.5-generic-:sparc-:sun4-:sun4m-:sun4m- (tnx KB) -0.72: sunos-5.5-generic-:sparc-:sun4-:sun4u-:sun4u- (tnx SAC) -0.80: sunos-5.5-generic_103093-06-:sparc-:sun4-:sun4m-:sun4m- (tnx TEE) -0.72: sunos-5.5-generic_103094-03-:i386-:i86pc-:i86pc-:i86pc- (tnx D2K) -0.80: sunos-5.5-generic_103094-07-:i386-:i86pc-:i86pc-:i86pc- (tnx MRG) -0.73: sunos-5.5.1-generic-:sparc-:sun4-:sun4c-:sun4c- (tnx CG) -0.73: sunos-5.5.1-generic-:sparc-:sun4-:sun4m-:sun4m- (tnx MBS) -0.80: sunos-5.5.1-generic-:sparc-:sun4-:sun4u-:sun4u- (tnx DNW) -0.73: sunos-5.5.1-generic_103640-03-:sparc-:sun4-:sun4m-:sun4m- (tnx DPS) -0.72: sunos-5.5.1-generic_103640-03-:sparc-:sun4-:sun4u-:sun4u- (tnx root@adrastea=???) -0.80: sunos-5.5.1-generic_103640-05-:sparc-:sun4-:sun4c-:sun4c- (tnx JRM) -0.80: sunos-5.5.1-generic_103640-05-:sparc-:sun4-:sun4u-:sun4u- (tnx AY) -0.73: sunos-5.5.1-generic_103640-08-:sparc-:sun4-:sun4m-:sun4m- (tnx RA) -0.73: sunos-5.5.1-generic_103640-12-:sparc-:sun4-:sun4u-:sun4u- (tnx SO) -0.80: sunos-5.5.1-generic_103640-21-:sparc-:sun4-:sun4c-:sun4c- (tnx BK) -0.80: sunos-5.5.1-generic_105428-01-:sparc-:sun4-:sun4u-:sun4u- (tnx KK) -0.72: sunos-5.5.1-generic_patch-:i386-:i86pc-:i86pc-:i86pc- (tnx D2K) -0.73: sunos-5.5.1-iss_1.0-:sparc-:sun4-:sun4u-:sun4u- (tnx LST) -0.80: sunos-5.6-generic-:i386-:i86pc-:i86pc-:i86pc- (tnx MD) -0.73: sunos-5.6-generic-:sparc-:sun4-:sun4c-:sun4c- (tnx DS) -0.80: sunos-5.6-generic-:sparc-:sun4-:sun4u-:sun4u- (tnx SOH) -0.80: sunos-5.6-generic_105181-03-:sparc-:sun4-:sun4u-:sun4u- (tnx SJ) -0.80: sunos-5.6-generic_105181-06-:sparc-:sun4-:sun4u-:sun4u- (tnx BOR) -0.80: sunos-5.6-generic_105181-07-:sparc-:sun4-:sun4m-:sun4m- (tnx ESM) -0.80: sunos-5.6-generic_105181-07-:sparc-:sun4-:sun4u-:sun4u- (tnx root@test5=???) -0.80: sunos-5.6-generic_105181-08-:sparc-:sun4-:sun4u-:sun4u- (tnx KE) -0.80: sunos-5.6-generic_105182-08-:i386-:i86pc-:i86pc-:i86pc- (tnx LBR) -0.73: ultrix-4.3-0-:-:-:risc-:- (tnx BW) -0.80: ultrix-4.5-0-:-:-:risc-:- (tnx LFB) -0.80: unix_sv-4.2mp-1.release.1114.02.15-:r4000-:-:r4000-:- (tnx HY) -0.80: unix_sv-4.2mp-2.03-:i386-:-:i386-:- (tnx HP) -0.73: unix_sv-4.2mp-2.1.2-:i386-:-:i386-:- (tnx RN) +ucspi-tcp home page: http://cr.yp.to/ucspi-tcp.html +Installation instructions: http://cr.yp.to/ucspi-tcp/install.html @@ -1,9 +1,12 @@ VERSION systype +fork.h hassgact.h hassgprm.h +hasshsgr.h haswaitp.h +iopause.h select.h -dns.lib socket.lib uint32.h +uint64.h @@ -1,161 +1,160 @@ -tcpclient.0 -tcpserver.0 -tcprules.0 -tcprulescheck.0 -tcp-environ.0 -who@.0 -date@.0 -finger@.0 -http@.0 -tcpcat.0 -mconnect.0 -fixcr.0 -addcr.0 -delcr.0 -argv0.0 -recordio.0 -error.0 -error_str.0 -alloc.0 -case.0 -cdb.0 -env.0 -fd_copy.0 -fd_move.0 -getln.0 -getln2.0 -sgetopt.0 -subgetopt.0 -stralloc.0 -wait.0 -man load compile -tcpclient.o -ip.o -ipalloc.o -dns.o +choose +iopause.h +uint64.h +tcpserver.o +uint32.h +rules.o remoteinfo.o -select.h timeoutconn.o -timeoutread.o -timeoutwrite.o systype makelib -subgetopt.o -sgetopt.o -getopt.a -strerr_sys.o -strerr_die.o -strerr.a -stralloc_eady.o -stralloc_pend.o -stralloc_copy.o -stralloc_opys.o -stralloc_opyb.o -stralloc_cat.o -stralloc_cats.o -stralloc_catb.o -stralloc.a -env.o -envread.o -env.a +cdb.o +cdb_hash.o +cdb_make.o +cdb.a +dns_dfd.o +dns_domain.o +dns_dtda.o +dns_ip.o +dns_ipq.o +dns_name.o +dns_nd.o +dns_packet.o +dns_random.o +dns_rcip.o +dns_rcrw.o +dns_resolve.o +dns_sortip.o +dns_transmit.o +dns_txt.o +dns.a +select.h +iopause.o +tai_pack.o +taia_add.o +taia_approx.o +taia_frac.o +taia_less.o +taia_now.o +taia_pack.o +taia_sub.o +taia_uint.o +time.a alloc.o alloc_re.o -alloc.a -ndelay.o -ndelay_off.o -ndelay.a -substdio.o -substdi.o -substdo.o -subfderr.o -subfdout.o -subfdin.o -substdio_copy.o -substdio.a +buffer.o +buffer_0.o +buffer_1.o +buffer_2.o +buffer_copy.o +buffer_get.o +buffer_put.o +env.o error.o error_str.o -error.a -str_chr.o -str_len.o -str_diff.o -str_diffn.o -str_cpy.o -byte_chr.o -byte_rchr.o -byte_diff.o -byte_copy.o -byte_cr.o -byte_zero.o -str.a +fd_copy.o +fd_move.o +getln.o +getln2.o +ndelay_off.o +ndelay_on.o +open_read.o +open_trunc.o +open_write.o +openreadclose.o +pathexec_env.o +pathexec_run.o +chkshsgr.o +chkshsgr +hasshsgr.h +prot.o +readclose.o +seek_set.o +sgetopt.o +sig.o hassgprm.h sig_block.o hassgact.h sig_catch.o sig_pause.o -sig_pipe.o -sig_child.o -sig_term.o -sig.a -fd_copy.o -fd_move.o -fd.a -case_lowers.o -case.a -fmt_str.o -fmt_ulong.o -scan_ulong.o -fs.a -socket.lib -dns.lib -tcpclient -uint32.h -tcpserver.o -cdb_hash.o -cdb_unpack.o -cdb_seek.o -cdb.a -open_read.o -open_trunc.o -open.a +socket_accept.o +socket_bind.o +socket_conn.o +socket_delay.o +socket_listen.o +socket_local.o +socket_opts.o +socket_remote.o +socket_tcp.o +socket_udp.o +stralloc_cat.o +stralloc_catb.o +stralloc_cats.o +stralloc_copy.o +stralloc_eady.o +stralloc_opyb.o +stralloc_opys.o +stralloc_pend.o +strerr_die.o +strerr_sys.o +subgetopt.o haswaitp.h wait_nohang.o wait_pid.o -wait.a +unix.a +byte_chr.o +byte_copy.o +byte_cr.o +byte_diff.o +byte_rchr.o +byte_zero.o +case_diffb.o +case_diffs.o +fmt_ulong.o +ip4_fmt.o +ip4_scan.o +scan_ulong.o +str_chr.o +str_diff.o +str_len.o +str_start.o +uint16_pack.o +uint16_unpack.o +uint32_pack.o +uint32_unpack.o +byte.a +socket.lib tcpserver tcprules.o -cdbmss.o -cdbmake_pack.o -cdbmake_hash.o -cdbmake_add.o -cdbmake.a -getln.o -getln2.o -getln.a -seek_set.o -seek.a tcprules tcprulescheck.o tcprulescheck +argv0.o +argv0 +recordio.o +recordio +tcpclient.o +tcpclient who@ date@ finger@ http@ tcpcat mconnect +fork.h mconnect-io.o mconnect-io -fixcr.o -fixcr addcr.o addcr delcr.o delcr -argv0.o -argv0 -recordio.o -recordio +fixcrio.o +fixcrio +rblsmtpd.o +commands.o +rblsmtpd rts prog install.o @@ -1,45 +0,0 @@ -TCP UCSPI protocol definition -Copyright 1996 -D. J. Bernstein, djb@pobox.com - - -This document defines the TCP protocol for UCSPI-1996 tools. A TCP -client communicates with a TCP server, on the same machine or on a -different machine, via the TCP/IP protocol through an Internet-domain -socket. The descriptors passed to a TCP UCSPI application are copies of -that socket, dup()ed from a single connect() or accept(). - -[address] consists of two arguments: [hostname] [port]. - -There are three possibilities for [hostname]: the number 0, referring to -the local host; a dotted-decimal IP address, such as 192.48.96.5; or a -name understood by the system's resolver, such as mail.uu.net. TCP UCSPI -servers use only the first IP address from the resolver; TCP UCSPI -clients try each address in turn. - -There are three possibilities for [port]: a positive numeric TCP port -number, such as 25; the number 0, which permits selection of any port -number; or a name understood by the system's getservbyname(), such as -smtp. - -The client and server set up the following environment variables: - - PROTO: the string TCP - TCPLOCALIP: the dotted-decimal IP address of the local host - TCPLOCALPORT: the local TCP port number, in decimal - TCPREMOTEIP: the dotted-decimal IP address of the remote host - TCPREMOTEPORT: the remote TCP port number, in decimal - TCPLOCALHOST, if possible: the resolver's name for TCPLOCALIP - TCPREMOTEHOST, if possible: the resolver's name for TCPREMOTEIP - TCPREMOTEINFO, if possible: the result of a 931/1413/IDENT/TAP query - -Uppercase letters in TCPLOCALHOST and TCPREMOTEHOST are converted to -lowercase. TCPREMOTEINFO is a connection-specific string supplied by the -remote host via 931/1413/IDENT/TAP. - -TCP UCSPI tools take a -R option to turn off 931/1413/IDENT/TAP -querying, and a -r option to turn it back on. TCP UCSPI clients take a --p [locport] option to require a particular TCP port on the local side -of the connection. TCP UCSPI servers take a -1 option to print the local -port number (in decimal, followed by a newline) to descriptor 1 before -closing descriptor 1 and after preparing to receive connections. @@ -1,122 +0,0 @@ -Thanks to various people for bug reports and other comments on various -versions of tcpclient, tcpserver, and tcpcontrol: - -A2P = Andrea Paolini -AI = Akihiro Iijima -AJDV = Albert J. deVera -AK = Ayamura Kikuchi -AP = Andrew Pam -ARB = Anand R. Buddhdev -AS = Amos Shapira -AT = Akihiro Terasaki -AV = Alex Vostrikov -AW = Arne Wichmann -AY = Araki Yasuhiro -BBBH = Bart B. B. Hanssens -BG = Bert Gijsbers -BJR = Brian J. Reichert -BK = Brendan Kehoe -BMF = Brian M. Fisk -BMS = Bradford M. Shelton -BOR = Brian O'Reilly -BW = Bruno Wolff -CG = Chris Garrigues -CJ = Chris Johnson -CW = Christian Wettergren -D2K = Dax Kelson -DCM = Daniel C. Mahoney -DEB = Donald E. Blais -DH = Darren Hall -DJ = Dirk Jaeckel -DJW = David J. Walton -DMV = Dan M. Vogel -DNW = Dale N. Woolridge -DP = David Pool -DPS = David P. Smith -DS = Dave Sill -DV = Dirk Vluegels -DWR = Darren W. Rees -E2W = Ed Weinberg -EAP = Eric A. Perlman -ESM = Edward S. Marshall -EW = Erik Wallin -FN = Faried Nawaz -FPL = Frederik P. Lindberg -GB = Gerry Boudreaux -GDP = Greg D. Patterson -GH = Grant Holliday -GL = Giles Lean -HB = Harald Barth -HF = Harald Fritzsche -HP = Hitesh Patel -HU = Hirofumi Ukawa -HY = Hiroshi Yamashita -IH = Ingmar Hupp -J1H = Johan Holmberg -J2B = Jos Backus -J2H = Jeff Hayward -J2W = Jeremy Wohl -JB = John Bolhuis -JBKH = J. B. Keith Humphreys -JDM = John D. Mitchell -JF = Janos Farkas -JJE = Joshua J. Ellis -JKB = Jakub K. Boguslaw -JL = Jim Littlefield -JLB = Julie L. Baumler -JM = Jose Monteiro -JRM = Jason R. Mastaler -K2K = Kris Kennaway -KB = Keith Burdis -KE = Kenny Elliott -KK = Kikuchi Kousuke -KL = Karl Lehenbauer -LBR = Lars Balker Rasmussen -LFB = Lyndon F. Bartels -LST = Louis S. Theran -M1S = Michael Salmon -MAZ = Matthew A. Zahorik -MBS = Michael B. Scher -MD = Mark Delany -MEE = Mads E. Eilertsen -MH = Michael Hirohama -MM = Martin Mersberger -MPS = Matt P. Simerson -MRG = Michael R. Gile -MS = Mikael Suokas -NM = Nobuhiro Murata -PMK = Patrick M. Kane -PN = Petr Novotny -PR = Peter Rye -PRR = Paul R. Rotering -PW = Peter Wilkinson -RA = Russ Allbery -RAL = Roberto A. Lumbreras -RAS = Richard A. Soderberg -RDM = Raul D. Miller -RN = Russell Nelson -RWL = Robert W. Luce -SAC = Shawn A. Clifford -SGT = Stathy G. Touloumis -SJ = Sudish Joseph -SML = Stefan M. Linnemann -SN = Stan Norton -SO = Shin Ohira -SOH = Shinya O'Hira -SR = Sean Reifschneider -T2K = Thomas Kuerten -TEE = Thomas E. Erskine -TG = Tim Goodwin -TLM = Timothy L. Mayo -TM = Toshinori Maeno -TT = Tomoaki Terazawa -TU = Todd Underwood -TY = Tomoki Yoshioka -UO = Uwe Ohse -VH = Vern Hart -VV = Vince Vielhaber -WA = Waskita Adijarto -WCH = Wu Ching-hong -WEB = William E. Baxter -WR = Wolfgang Rufeger -YT = Yoshitatsu Takeshita @@ -1,6 +1,3 @@ -switch to new env, exec libraries -switch to better resolver -expand rts - -make pre-forking version of tcpserver -make DNS-free versions of tcpserver and tcpclient +inetd.conf conversion tools +pre-forking version of tcpserver? +rule directory in tcpserver? @@ -1,131 +0,0 @@ -UNIX Client-Server Program Interface, UCSPI-1996 -Copyright 1996 -D. J. Bernstein, djb@pobox.com - - -1. Introduction - -This document describes the UNIX Client-Server Program Interface, UCSPI -(ooks-pie), a command-line interface to client-server communications -tools. - -UCSPI provides several benefits. First, the UCSPI interface is -independent of the underlying communications medium; UCSPI applications -don't even have to be recompiled as the Internet upgrades from IPv4 to -IPv6. Second, UCSPI lets shell scripts take advantage of networking. -Third, UCSPI clients and servers conventionally set up environment -variables that display the local and remote addresses, so the -information is readily available to applications and users. - -Here is the general UCSPI framework. An UCSPI tool is a program that -understands how to talk to some communications medium. It sets up two -descriptors and then invokes an UCSPI application, which can read from -one descriptor and write to the other. Every communications medium -provides reliable two-way full-duplex strictly ordered not necessarily -timed stream communication. Some media may provide other types of -communication, such as expedited (``out-of-band'') transmission, in -which the stream is no longer ordered, but most UCSPI applications are -medium-independent and do not rely on such features. - - -2. Tools - -UCSPI tools are executable programs. They accept command lines in the -following general format: - - [tool] [options] [address] [application] - -Here [tool] is the name of the tool, [options] are zero or more option -arguments, [address] is a protocol-specific address, and [application] -is a user-specified program to run for each connection. - -[options] are processed by the getopt standard; thus an argument of -- -terminates [options]. [tool] supports three options to control how -much information it prints to stderr: - - -v all available messages - -Q all available error messages; no messages in case of success - -q no messages in any case - -The default is -Q; later arguments override earlier arguments. [tool] -may support many further options. - -[application] consists of one or more arguments, handled by the -conventions of execvp(). [tool] passes on all [application] arguments -without change, no matter what characters appear in those arguments. - -[tool] always changes certain file descriptors, as described in section -3, and environment variables, as described in section 4, before -executing [application]. - -[tool] might fork before executing [application], and it might reset -some signals that were previously ignored. Other than this, [tool] does -not change its process state before executing [application]. - -[tool] does not assume that any particular descriptors are open or -closed upon entry. [tool] does not force itself into the background; nor -does it attempt to detach from a controlling terminal. - -If [tool] cannot perform its functions, it exits with a nonzero code. - - -3. Clients and servers - -There are two types of UCSPI tools: clients and servers. - -An UCSPI client closes descriptors 6 and 7 and connects to a server at -[address]. Upon connecting, it spawns [application] with descriptor 6 -reading from the connection and descriptor 7 writing to the connection. -The client does not make any further connections. When [application] -dies, the client dies; the client exits with a zero code if and only if -[application] exited with a zero code. - -An UCSPI server closes descriptors 0 and 1 and waits for a client to -connect to [address]. Upon accepting a connection, it spawns -[application] with descriptor 0 reading from the connection and -descriptor 1 writing to the connection. Meanwhile, and subsequently, it -continues accepting connections to [address]. If the server receives -signal SIGTERM, it exits with code 0; this does not affect any current -connections. - - -4. Protocols - -Each UCSPI tool supports a protocol. A protocol definition provides -three pieces of information: the name of the protocol; the format and -meaning of [address]; and the environment variables set up by the tool. - -A protocol name is a sequence of one or more alphanumeric characters. -See section 5 for information about the allocation of protocol names. - -A protocol definition always states the number of arguments taken by -[address] and the allowed form for each argument. It also states an -underlying communications medium to be used by the tool, and gives the -interpretation of [address] in terms of that medium. - -Each tool passes the following environment variables to [application]: -PROTO=[PROTO], the name of the supported protocol; zero or more -variables beginning with [PROTO]LOCAL, as stated in the protocol -definition; and zero or more variables beginning with [PROTO]REMOTE, as -stated in the protocol definition. For clients, [PROTO]LOCAL variables -give information about the client, and [PROTO]REMOTE variables give -information about the server; vice versa for servers. - -Protocol definitions may specify environment variables that, in some -situations, are not set. Those variables might be set upon entry to an -UCSPI tool; if so, they must be unset, not passed along. - -A protocol definition may impose further requirements on clients and -servers, such as supported options, forking behavior, and the nature of -the descriptors passed to [application]. - - -5. Protocol management - -Public protocol definitions may be registered with me. I may refuse a -registration request on the grounds of a namespace problem, but in that -case I will suggest an acceptable replacement name. - -Protocol names beginning with x will be parcelled out to organizations -that would like to define their own protocols. Protocol names beginning -with X are reserved for experimental use. @@ -1 +1 @@ -ucspi-tcp 0.84 +ucspi-tcp 0.88 diff --git a/addcr.1 b/addcr.1 deleted file mode 100644 index 3bae1f7..0000000 --- a/addcr.1 +++ /dev/null @@ -1,22 +0,0 @@ -.TH addcr 1 -.SH NAME -addcr \- add a CR before each LF -.SH SYNOPSIS -.B addcr -.SH DESCRIPTION -.B addcr -inserts CR at the end of each line of input. -It does not insert CR at the end of a partial final line. -.SH COMPATIBILITY -Some vendors ship -.B unix2dos -or -.B bsd2dos -tools similar to -.BR addcr . -Those tools often blow up on long lines and nulls. -.B addcr -has no trouble with long lines and nulls. -.SH "SEE ALSO" -delcr(1), -fixcr(1) @@ -1,23 +1,22 @@ -#include "substdio.h" -#include "subfd.h" +#include "buffer.h" #include "exit.h" -void main() +main() { register int n; register char *x; char ch; for (;;) { - n = substdio_feed(subfdin); + n = buffer_feed(buffer_0); if (n < 0) _exit(111); if (!n) _exit(0); - x = substdio_PEEK(subfdin); - substdio_SEEK(subfdin,n); + x = buffer_PEEK(buffer_0); + buffer_SEEK(buffer_0,n); while (n > 0) { ch = *x++; --n; - if (ch == '\n') substdio_BPUTC(subfdout,"\r"[0]); - substdio_BPUTC(subfdout,ch); + if (ch == '\n') buffer_PUTC(buffer_1,"\r"[0]); + buffer_PUTC(buffer_1,ch); } } } diff --git a/alloc.3 b/alloc.3 deleted file mode 100644 index 58b4432..0000000 --- a/alloc.3 +++ /dev/null @@ -1,62 +0,0 @@ -.TH alloc 3 -.SH NAME -alloc \- allocate memory -.SH SYNTAX -.B #include <alloc.h> - -char *\fBalloc\fP(\fInew\fR); - -void \fBalloc_free\fP(\fIx\fR); - -void \fBalloc_re\fP(&\fIx\fR,\fIold\fR,\fInew\fR); - -char *\fIx\fR; -.br -unsigned int \fIold\fR; -.br -unsigned int \fInew\fR; -.SH DESCRIPTION -.B alloc -allocates enough space from the heap for -.I new -bytes of data, -adequately aligned for any data type. -.I new -may be 0. -.B alloc -returns a pointer to the space. -If space is not available, -.B alloc -returns 0, -setting -.B errno -appropriately. - -.B alloc_free -returns space to the heap. - -.B alloc_re -expands the space allocated to -.I x -from -.I old -bytes to -.I new -bytes. -It allocates new space, -copies -.I old -bytes from the old space to the new space, -returns the old space to the heap, -and changes -.I x -to point to the new space. -It then returns 1. -If space is not available, -.B alloc_re -returns 0, -leaving the old space alone. -.SH "SEE ALSO" -sbrk(2), -malloc(3), -error(3) @@ -4,7 +4,7 @@ extern char *malloc(); extern void free(); #define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */ -#define SPACE 4096 /* must be multiple of ALIGNMENT */ +#define SPACE 2048 /* must be multiple of ALIGNMENT */ typedef union { char irrelevant[ALIGNMENT]; double d; } aligned; static aligned realspace[SPACE / ALIGNMENT]; diff --git a/argv0.1 b/argv0.1 deleted file mode 100644 index ad9634d..0000000 --- a/argv0.1 +++ /dev/null @@ -1,47 +0,0 @@ -.TH argv0 1 -.SH NAME -argv0 \- run a program with a specified 0th argument -.SH SYNOPSIS -.B argv0 -.I realname -.I zero -[ -.I arg ... -] -.SH DESCRIPTION -.B argv0 -runs -the program stored as -.I realname -on disk, -with the given -arguments. -It sets the 0th argument of -the program to -.IR zero . - -For example, - -.EX - argv0 /bin/csh -bin/csh -.EE - -runs -.B /bin/csh -with a 0th argument of -.BR -bin/csh . -.B csh -will think it is a login shell -and behave accordingly. - -.B argv0 -can be used to run some -.B inetd -wrappers under -.BR tcpserver . -.SH "SEE ALSO" -csh(1), -tcpserver(1), -execve(2), -execvp(3), -inetd(8) @@ -1,11 +1,10 @@ +#include "pathexec.h" #include "strerr.h" -void main(argc,argv) -int argc; -char **argv; +main(int argc,char **argv,char **envp) { if (argc < 3) strerr_die1x(100,"argv0: usage: argv0 realname program [ arg ... ]"); - execvp(argv[1],argv + 2); + pathexec_run(argv[1],argv + 2,envp); strerr_die4sys(111,"argv0: fatal: ","unable to run ",argv[1],": "); } @@ -1,19 +1,16 @@ -#include "substdio.h" +#include "buffer.h" #include "readwrite.h" #include "exit.h" -char buf1[256]; -substdio ss1 = SUBSTDIO_FDBUF(write,1,buf1,sizeof(buf1)); +char bspace[256]; +buffer b = BUFFER_INIT(write,1,bspace,sizeof bspace); -void puts(s) -char *s; +void puts(char *s) { - if (substdio_puts(&ss1,s) == -1) _exit(111); + if (buffer_puts(&b,s) == -1) _exit(111); } -void main(argc,argv) -int argc; -char **argv; +main(int argc,char **argv) { char *name; char *value; @@ -39,6 +36,6 @@ char **argv; } puts("\\\n\";\n"); - if (substdio_flush(&ss1) == -1) _exit(111); + if (buffer_flush(&b) == -1) _exit(111); _exit(0); } diff --git a/buffer.c b/buffer.c new file mode 100644 index 0000000..f44a697 --- /dev/null +++ b/buffer.c @@ -0,0 +1,10 @@ +#include "buffer.h" + +void buffer_init(buffer *s,int (*op)(),int fd,char *buf,unsigned int len) +{ + s->x = buf; + s->fd = fd; + s->op = op; + s->p = 0; + s->n = len; +} diff --git a/buffer.h b/buffer.h new file mode 100644 index 0000000..12539b3 --- /dev/null +++ b/buffer.h @@ -0,0 +1,56 @@ +#ifndef BUFFER_H +#define BUFFER_H + +typedef struct buffer { + char *x; + unsigned int p; + unsigned int n; + int fd; + int (*op)(); +} buffer; + +#define BUFFER_INIT(op,fd,buf,len) { (buf), 0, (len), (fd), (op) } +#define BUFFER_INSIZE 8192 +#define BUFFER_OUTSIZE 8192 + +extern void buffer_init(buffer *,int (*)(),int,char *,unsigned int); + +extern int buffer_flush(buffer *); +extern int buffer_put(buffer *,char *,unsigned int); +extern int buffer_putalign(buffer *,char *,unsigned int); +extern int buffer_putflush(buffer *,char *,unsigned int); +extern int buffer_puts(buffer *,char *); +extern int buffer_putsalign(buffer *,char *); +extern int buffer_putsflush(buffer *,char *); + +#define buffer_PUTC(s,c) \ + ( ((s)->n != (s)->p) \ + ? ( (s)->x[(s)->p++] = (c), 0 ) \ + : buffer_put((s),&(c),1) \ + ) + +extern int buffer_get(buffer *,char *,unsigned int); +extern int buffer_bget(buffer *,char *,unsigned int); +extern int buffer_feed(buffer *); + +extern char *buffer_peek(buffer *); +extern void buffer_seek(buffer *,unsigned int); + +#define buffer_PEEK(s) ( (s)->x + (s)->n ) +#define buffer_SEEK(s,len) ( ( (s)->p -= (len) ) , ( (s)->n += (len) ) ) + +#define buffer_GETC(s,c) \ + ( ((s)->p > 0) \ + ? ( *(c) = (s)->x[(s)->n], buffer_SEEK((s),1), 1 ) \ + : buffer_get((s),(c),1) \ + ) + +extern int buffer_copy(buffer *,buffer *); + +extern buffer *buffer_0; +extern buffer *buffer_0small; +extern buffer *buffer_1; +extern buffer *buffer_1small; +extern buffer *buffer_2; + +#endif diff --git a/buffer_0.c b/buffer_0.c new file mode 100644 index 0000000..6c5365a --- /dev/null +++ b/buffer_0.c @@ -0,0 +1,12 @@ +#include "readwrite.h" +#include "buffer.h" + +int buffer_0_read(fd,buf,len) int fd; char *buf; int len; +{ + if (buffer_flush(buffer_1) == -1) return -1; + return read(fd,buf,len); +} + +char buffer_0_space[BUFFER_INSIZE]; +static buffer it = BUFFER_INIT(buffer_0_read,0,buffer_0_space,sizeof buffer_0_space); +buffer *buffer_0 = ⁢ diff --git a/buffer_1.c b/buffer_1.c new file mode 100644 index 0000000..3104e22 --- /dev/null +++ b/buffer_1.c @@ -0,0 +1,6 @@ +#include "readwrite.h" +#include "buffer.h" + +char buffer_1_space[BUFFER_OUTSIZE]; +static buffer it = BUFFER_INIT(write,1,buffer_1_space,sizeof buffer_1_space); +buffer *buffer_1 = ⁢ diff --git a/buffer_2.c b/buffer_2.c new file mode 100644 index 0000000..297825c --- /dev/null +++ b/buffer_2.c @@ -0,0 +1,6 @@ +#include "readwrite.h" +#include "buffer.h" + +char buffer_2_space[256]; +static buffer it = BUFFER_INIT(write,2,buffer_2_space,sizeof buffer_2_space); +buffer *buffer_2 = ⁢ diff --git a/buffer_copy.c b/buffer_copy.c new file mode 100644 index 0000000..dc4d4b1 --- /dev/null +++ b/buffer_copy.c @@ -0,0 +1,16 @@ +#include "buffer.h" + +int buffer_copy(buffer *bout,buffer *bin) +{ + int n; + char *x; + + for (;;) { + n = buffer_feed(bin); + if (n < 0) return -2; + if (!n) return 0; + x = buffer_PEEK(bin); + if (buffer_put(bout,x,n) == -1) return -3; + buffer_SEEK(bin,n); + } +} diff --git a/buffer_get.c b/buffer_get.c new file mode 100644 index 0000000..937b75e --- /dev/null +++ b/buffer_get.c @@ -0,0 +1,67 @@ +#include "buffer.h" +#include "byte.h" +#include "error.h" + +static int oneread(int (*op)(),int fd,char *buf,unsigned int len) +{ + int r; + + for (;;) { + r = op(fd,buf,len); + if (r == -1) if (errno == error_intr) continue; + return r; + } +} + +static int getthis(buffer *s,char *buf,unsigned int len) +{ + if (len > s->p) len = s->p; + s->p -= len; + byte_copy(buf,len,s->x + s->n); + s->n += len; + return len; +} + +int buffer_feed(buffer *s) +{ + int r; + + if (s->p) return s->p; + r = oneread(s->op,s->fd,s->x,s->n); + if (r <= 0) return r; + s->p = r; + s->n -= r; + if (s->n > 0) byte_copyr(s->x + s->n,r,s->x); + return r; +} + +int buffer_bget(buffer *s,char *buf,unsigned int len) +{ + int r; + + if (s->p > 0) return getthis(s,buf,len); + if (s->n <= len) return oneread(s->op,s->fd,buf,s->n); + r = buffer_feed(s); if (r <= 0) return r; + return getthis(s,buf,len); +} + +int buffer_get(buffer *s,char *buf,unsigned int len) +{ + int r; + + if (s->p > 0) return getthis(s,buf,len); + if (s->n <= len) return oneread(s->op,s->fd,buf,len); + r = buffer_feed(s); if (r <= 0) return r; + return getthis(s,buf,len); +} + +char *buffer_peek(buffer *s) +{ + return s->x + s->n; +} + +void buffer_seek(buffer *s,unsigned int len) +{ + s->n += len; + s->p -= len; +} diff --git a/buffer_put.c b/buffer_put.c new file mode 100644 index 0000000..a05e1f5 --- /dev/null +++ b/buffer_put.c @@ -0,0 +1,88 @@ +#include "buffer.h" +#include "str.h" +#include "byte.h" +#include "error.h" + +static int allwrite(int (*op)(),int fd,char *buf,unsigned int len) +{ + int w; + + while (len) { + w = op(fd,buf,len); + if (w == -1) { + if (errno == error_intr) continue; + return -1; /* note that some data may have been written */ + } + if (w == 0) ; /* luser's fault */ + buf += w; + len -= w; + } + return 0; +} + +int buffer_flush(buffer *s) +{ + int p; + + p = s->p; + if (!p) return 0; + s->p = 0; + return allwrite(s->op,s->fd,s->x,p); +} + +int buffer_putalign(buffer *s,char *buf,unsigned int len) +{ + unsigned int n; + + while (len > (n = s->n - s->p)) { + byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n; + if (buffer_flush(s) == -1) return -1; + } + /* now len <= s->n - s->p */ + byte_copy(s->x + s->p,len,buf); + s->p += len; + return 0; +} + +int buffer_put(buffer *s,char *buf,unsigned int len) +{ + unsigned int n; + + n = s->n; + if (len > n - s->p) { + if (buffer_flush(s) == -1) return -1; + /* now s->p == 0 */ + if (n < BUFFER_OUTSIZE) n = BUFFER_OUTSIZE; + while (len > s->n) { + if (n > len) n = len; + if (allwrite(s->op,s->fd,buf,n) == -1) return -1; + buf += n; + len -= n; + } + } + /* now len <= s->n - s->p */ + byte_copy(s->x + s->p,len,buf); + s->p += len; + return 0; +} + +int buffer_putflush(buffer *s,char *buf,unsigned int len) +{ + if (buffer_flush(s) == -1) return -1; + return allwrite(s->op,s->fd,buf,len); +} + +int buffer_putsalign(buffer *s,char *buf) +{ + return buffer_putalign(s,buf,str_len(buf)); +} + +int buffer_puts(buffer *s,char *buf) +{ + return buffer_put(s,buf,str_len(buf)); +} + +int buffer_putsflush(buffer *s,char *buf) +{ + return buffer_putflush(s,buf,str_len(buf)); +} @@ -1,100 +0,0 @@ -.TH case 3 -.SH NAME -case \- convert ASCII uppercase bytes to lowercase -.SH SYNTAX -.B #include <case.h> - -void \fBcase_lowers\fP(\fIs\fR); -.br -void \fBcase_lowerb\fP(\fIs\fR,\fIlen\fR); - -int \fBcase_diffs\fP(\fIs\fR,\fIt\fR); -.br -int \fBcase_equals\fP(\fIs\fR,\fIt\fR); -.br -int \fBcase_starts\fP(\fIs\fR,\fIt\fR); - -int \fBcase_diffb\fP(\fIs\fR,\fIlen\fR,\fIt\fR); -.br -int \fBcase_startb\fP(\fIs\fR,\fIlen\fR,\fIt\fR); - -char *\fIs\fR; -.br -char *\fIt\fR; -.br -unsigned int \fIlen\fR; -.SH DESCRIPTION -.B case_lowers -converts each uppercase byte in the string -.I s -to lowercase. -.I s -must be 0-terminated. - -.B case_lowerb -converts each uppercase byte in the buffer -.IR s , -of length -.IR len , -to lowercase. - -.B case_diffs -lexicographically compares lowercase versions of the strings -.I s -and -.IR t . -It returns something positive, negative, or zero -when the first is larger than, smaller than, or equal to the second. -.I s -and -.I t -must be 0-terminated. - -.B case_equals -means -.BR !case_diffs . - -.B case_starts -returns 1 if a lowercase version of -.I s -starts with a lowercase version of -.IR t . -.I s -and -.I t -must be 0-terminated. - -.B case_diffb -lexicographically compares lowercase versions of the buffers -.I s -and -.IR t , -each of length -.IR len . -It returns something positive, negative, or zero -when the first is larger than, smaller than, or equal to the second. - -.B case_startb -returns 1 if a lowercase version of the buffer -.IR s , -of length -.IR len , -starts with a lowercase version of the string -.IR t . -.I t -must be 0-terminated. - -The -.B case -routines -are ASCII-specific. -They are suitable for programs that handle -case-independent networking protocols. - -All comparisons are performed on unsigned bytes. -.SH "SEE ALSO" -byte_diff(3), -byte_equal(3), -str_diff(3), -str_equal(3), -str_start(3) @@ -1,12 +1,12 @@ #ifndef CASE_H #define CASE_H -extern void case_lowers(); -extern void case_lowerb(); -extern int case_diffs(); -extern int case_diffb(); -extern int case_starts(); -extern int case_startb(); +extern void case_lowers(char *); +extern void case_lowerb(char *,unsigned int); +extern int case_diffs(char *,char *); +extern int case_diffb(char *,unsigned int,char *); +extern int case_starts(char *,char *); +extern int case_startb(char *,unsigned int,char *); #define case_equals(s,t) (!case_diffs((s),(t))) diff --git a/case_diffb.c b/case_diffb.c new file mode 100644 index 0000000..967af56 --- /dev/null +++ b/case_diffb.c @@ -0,0 +1,18 @@ +#include "case.h" + +int case_diffb(register char *s,register unsigned int len,register char *t) +{ + register unsigned char x; + register unsigned char y; + + while (len > 0) { + --len; + x = *s++ - 'A'; + if (x <= 'Z' - 'A') x += 'a'; else x += 'A'; + y = *t++ - 'A'; + if (y <= 'Z' - 'A') y += 'a'; else y += 'A'; + if (x != y) + return ((int)(unsigned int) x) - ((int)(unsigned int) y); + } + return 0; +} diff --git a/case_diffs.c b/case_diffs.c new file mode 100644 index 0000000..2575184 --- /dev/null +++ b/case_diffs.c @@ -0,0 +1,17 @@ +#include "case.h" + +int case_diffs(register char *s,register char *t) +{ + register unsigned char x; + register unsigned char y; + + for (;;) { + x = *s++ - 'A'; + if (x <= 'Z' - 'A') x += 'a'; else x += 'A'; + y = *t++ - 'A'; + if (y <= 'Z' - 'A') y += 'a'; else y += 'A'; + if (x != y) break; + if (!x) break; + } + return ((int)(unsigned int) x) - ((int)(unsigned int) y); +} diff --git a/case_lowers.c b/case_lowers.c deleted file mode 100644 index 208b3f5..0000000 --- a/case_lowers.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "case.h" - -void case_lowers(s) -char *s; -{ - unsigned char x; - while (x = *s) { - x -= 'A'; - if (x <= 'Z' - 'A') *s = x + 'a'; - ++s; - } -} @@ -1,62 +0,0 @@ -.TH cdb 3 -.SH NAME -cdb \- read from a constant database -.SH SYNTAX -.B #include <cdb.h> - -int \fBcdb_seek(\fP\fIfd,key,len,dlen\fR\fB)\fP; - -int \fIfd\fR; -.br -char *\fIkey\fR; -.br -unsigned int \fIlen\fR; -.br -uint32 *\fIdlen\fR; -.SH DESCRIPTION -.B cdb_seek -looks up -.I key -in a constant database. -It returns 1 if -.I key -is present, -0 if -.I key -is not present, -or \-1 if there was a read error. -.I key -is an array of -.I len -characters. - -.B cdb_seek -needs an open file descriptor, -.IR fd , -pointing to the database. -If -.B cdb_seek -returns 1, -it points -.I fd -at the beginning of the data portion of the first record -indexed by -.IR key , -and it stores the data length in -.IR dlen. -.B cdb_seek -does not provide a way to read subsequent records with the same key. - -It's fine to do several -.B cdb_seek -lookups with the same open file descriptor. -Beware, however, that two simultaneous -.B cdb_seek -lookups can fail horribly; -separate processes should not share the same database descriptor. -Furthermore, any updates after the database was opened -will be invisible. -It's rarely a good idea for a long-running program -to hold a database open. -.SH "SEE ALSO" -cdbget(1) @@ -0,0 +1,136 @@ +/* Public domain. */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include "readwrite.h" +#include "error.h" +#include "seek.h" +#include "byte.h" +#include "cdb.h" + +void cdb_free(struct cdb *c) +{ + if (c->map) { + munmap(c->map,c->size); + c->map = 0; + } +} + +void cdb_findstart(struct cdb *c) +{ + c->loop = 0; +} + +void cdb_init(struct cdb *c,int fd) +{ + struct stat st; + char *x; + + cdb_free(c); + cdb_findstart(c); + c->fd = fd; + + if (fstat(fd,&st) == 0) + if (st.st_size <= 0xffffffff) { + x = mmap(0,st.st_size,PROT_READ,MAP_SHARED,fd,0); + if (x + 1) { + c->size = st.st_size; + c->map = x; + } + } +} + +int cdb_read(struct cdb *c,char *buf,unsigned int len,uint32 pos) +{ + if (c->map) { + if ((pos > c->size) || (c->size - pos < len)) goto FORMAT; + byte_copy(buf,len,c->map + pos); + } + else { + if (seek_set(c->fd,pos) == -1) return -1; + while (len > 0) { + int r; + do + r = read(c->fd,buf,len); + while ((r == -1) && (errno == error_intr)); + if (r == -1) return -1; + if (r == 0) goto FORMAT; + buf += r; + len -= r; + } + } + return 0; + + FORMAT: + errno = error_proto; + return -1; +} + +static int match(struct cdb *c,char *key,unsigned int len,uint32 pos) +{ + char buf[32]; + int n; + + while (len > 0) { + n = sizeof buf; + if (n > len) n = len; + if (cdb_read(c,buf,n,pos) == -1) return -1; + if (byte_diff(buf,n,key)) return 0; + pos += n; + key += n; + len -= n; + } + return 1; +} + +int cdb_findnext(struct cdb *c,char *key,unsigned int len) +{ + char buf[8]; + uint32 pos; + uint32 u; + + if (!c->loop) { + u = cdb_hash(key,len); + if (cdb_read(c,buf,8,(u << 3) & 2047) == -1) return -1; + uint32_unpack(buf + 4,&c->hslots); + if (!c->hslots) return 0; + uint32_unpack(buf,&c->hpos); + c->khash = u; + u >>= 8; + u %= c->hslots; + u <<= 3; + c->kpos = c->hpos + u; + } + + while (c->loop < c->hslots) { + if (cdb_read(c,buf,8,c->kpos) == -1) return -1; + uint32_unpack(buf + 4,&pos); + if (!pos) return 0; + c->loop += 1; + c->kpos += 8; + if (c->kpos == c->hpos + (c->hslots << 3)) c->kpos = c->hpos; + uint32_unpack(buf,&u); + if (u == c->khash) { + if (cdb_read(c,buf,8,pos) == -1) return -1; + uint32_unpack(buf,&u); + if (u == len) + switch(match(c,key,len,pos + 8)) { + case -1: + return -1; + case 1: + uint32_unpack(buf + 4,&c->dlen); + c->dpos = pos + 8 + len; + return 1; + } + } + } + + return 0; +} + +int cdb_find(struct cdb *c,char *key,unsigned int len) +{ + cdb_findstart(c); + return cdb_findnext(c,key,len); +} @@ -1,12 +1,37 @@ +/* Public domain. */ + #ifndef CDB_H #define CDB_H #include "uint32.h" -extern uint32 cdb_hash(); -extern uint32 cdb_unpack(); +#define CDB_HASHSTART 5381 +extern uint32 cdb_hashadd(uint32,unsigned char); +extern uint32 cdb_hash(char *,unsigned int); + +struct cdb { + char *map; /* 0 if no map is available */ + int fd; + uint32 size; /* initialized if map is nonzero */ + uint32 loop; /* number of hash slots searched under this key */ + uint32 khash; /* initialized if loop is nonzero */ + uint32 kpos; /* initialized if loop is nonzero */ + uint32 hpos; /* initialized if loop is nonzero */ + uint32 hslots; /* initialized if loop is nonzero */ + uint32 dpos; /* initialized if cdb_findnext() returns 1 */ + uint32 dlen; /* initialized if cdb_findnext() returns 1 */ +} ; + +extern void cdb_free(struct cdb *); +extern void cdb_init(struct cdb *,int fd); + +extern int cdb_read(struct cdb *,char *,unsigned int,uint32); + +extern void cdb_findstart(struct cdb *); +extern int cdb_findnext(struct cdb *,char *,unsigned int); +extern int cdb_find(struct cdb *,char *,unsigned int); -extern int cdb_bread(); -extern int cdb_seek(); +#define cdb_datapos(c) ((c)->dpos) +#define cdb_datalen(c) ((c)->dlen) #endif @@ -1,16 +1,21 @@ +/* Public domain. */ + #include "cdb.h" -uint32 cdb_hash(buf,len) -unsigned char *buf; -unsigned int len; +uint32 cdb_hashadd(uint32 h,unsigned char c) +{ + h += (h << 5); + return h ^ c; +} + +uint32 cdb_hash(char *buf,unsigned int len) { uint32 h; - h = 5381; + h = CDB_HASHSTART; while (len) { + h = cdb_hashadd(h,*buf++); --len; - h += (h << 5); - h ^= (uint32) *buf++; } return h; } diff --git a/cdb_make.c b/cdb_make.c new file mode 100644 index 0000000..6d1bd03 --- /dev/null +++ b/cdb_make.c @@ -0,0 +1,153 @@ +/* Public domain. */ + +#include "readwrite.h" +#include "seek.h" +#include "error.h" +#include "alloc.h" +#include "cdb.h" +#include "cdb_make.h" + +int cdb_make_start(struct cdb_make *c,int fd) +{ + c->head = 0; + c->split = 0; + c->hash = 0; + c->numentries = 0; + c->fd = fd; + c->pos = sizeof c->final; + buffer_init(&c->b,write,fd,c->bspace,sizeof c->bspace); + return seek_set(fd,c->pos); +} + +static int posplus(struct cdb_make *c,uint32 len) +{ + uint32 newpos = c->pos + len; + if (newpos < len) { errno = error_nomem; return -1; } + c->pos = newpos; + return 0; +} + +int cdb_make_addend(struct cdb_make *c,unsigned int keylen,unsigned int datalen,uint32 h) +{ + struct cdb_hplist *head; + + head = c->head; + if (!head || (head->num >= CDB_HPLIST)) { + head = (struct cdb_hplist *) alloc(sizeof(struct cdb_hplist)); + if (!head) return -1; + head->num = 0; + head->next = c->head; + c->head = head; + } + head->hp[head->num].h = h; + head->hp[head->num].p = c->pos; + ++head->num; + ++c->numentries; + if (posplus(c,8) == -1) return -1; + if (posplus(c,keylen) == -1) return -1; + if (posplus(c,datalen) == -1) return -1; + return 0; +} + +int cdb_make_addbegin(struct cdb_make *c,unsigned int keylen,unsigned int datalen) +{ + char buf[8]; + + if (keylen > 0xffffffff) { errno = error_nomem; return -1; } + if (datalen > 0xffffffff) { errno = error_nomem; return -1; } + + uint32_pack(buf,keylen); + uint32_pack(buf + 4,datalen); + if (buffer_putalign(&c->b,buf,8) == -1) return -1; + return 0; +} + +int cdb_make_add(struct cdb_make *c,char *key,unsigned int keylen,char *data,unsigned int datalen) +{ + if (cdb_make_addbegin(c,keylen,datalen) == -1) return -1; + if (buffer_putalign(&c->b,key,keylen) == -1) return -1; + if (buffer_putalign(&c->b,data,datalen) == -1) return -1; + return cdb_make_addend(c,keylen,datalen,cdb_hash(key,keylen)); +} + +int cdb_make_finish(struct cdb_make *c) +{ + char buf[8]; + int i; + uint32 len; + uint32 u; + uint32 memsize; + uint32 count; + uint32 where; + struct cdb_hplist *x; + struct cdb_hp *hp; + + for (i = 0;i < 256;++i) + c->count[i] = 0; + + for (x = c->head;x;x = x->next) { + i = x->num; + while (i--) + ++c->count[255 & x->hp[i].h]; + } + + memsize = 1; + for (i = 0;i < 256;++i) { + u = c->count[i] * 2; + if (u > memsize) + memsize = u; + } + + memsize += c->numentries; /* no overflow possible up to now */ + u = (uint32) 0 - (uint32) 1; + u /= sizeof(struct cdb_hp); + if (memsize > u) { errno = error_nomem; return -1; } + + c->split = (struct cdb_hp *) alloc(memsize * sizeof(struct cdb_hp)); + if (!c->split) return -1; + + c->hash = c->split + c->numentries; + + u = 0; + for (i = 0;i < 256;++i) { + u += c->count[i]; /* bounded by numentries, so no overflow */ + c->start[i] = u; + } + + for (x = c->head;x;x = x->next) { + i = x->num; + while (i--) + c->split[--c->start[255 & x->hp[i].h]] = x->hp[i]; + } + + for (i = 0;i < 256;++i) { + count = c->count[i]; + + len = count + count; /* no overflow possible */ + uint32_pack(c->final + 8 * i,c->pos); + uint32_pack(c->final + 8 * i + 4,len); + + for (u = 0;u < len;++u) + c->hash[u].h = c->hash[u].p = 0; + + hp = c->split + c->start[i]; + for (u = 0;u < count;++u) { + where = (hp->h >> 8) % len; + while (c->hash[where].p) + if (++where == len) + where = 0; + c->hash[where] = *hp++; + } + + for (u = 0;u < len;++u) { + uint32_pack(buf,c->hash[u].h); + uint32_pack(buf + 4,c->hash[u].p); + if (buffer_putalign(&c->b,buf,8) == -1) return -1; + if (posplus(c,8) == -1) return -1; + } + } + + if (buffer_flush(&c->b) == -1) return -1; + if (seek_begin(c->fd) == -1) return -1; + return buffer_putflush(&c->b,c->final,sizeof c->final); +} diff --git a/cdb_make.h b/cdb_make.h new file mode 100644 index 0000000..b8bbe4d --- /dev/null +++ b/cdb_make.h @@ -0,0 +1,39 @@ +/* Public domain. */ + +#ifndef CDB_MAKE_H +#define CDB_MAKE_H + +#include "buffer.h" +#include "uint32.h" + +#define CDB_HPLIST 1000 + +struct cdb_hp { uint32 h; uint32 p; } ; + +struct cdb_hplist { + struct cdb_hp hp[CDB_HPLIST]; + struct cdb_hplist *next; + int num; +} ; + +struct cdb_make { + char bspace[8192]; + char final[2048]; + uint32 count[256]; + uint32 start[256]; + struct cdb_hplist *head; + struct cdb_hp *split; /* includes space for hash */ + struct cdb_hp *hash; + uint32 numentries; + buffer b; + uint32 pos; + int fd; +} ; + +extern int cdb_make_start(struct cdb_make *,int); +extern int cdb_make_addbegin(struct cdb_make *,unsigned int,unsigned int); +extern int cdb_make_addend(struct cdb_make *,unsigned int,unsigned int,uint32); +extern int cdb_make_add(struct cdb_make *,char *,unsigned int,char *,unsigned int); +extern int cdb_make_finish(struct cdb_make *); + +#endif diff --git a/cdb_seek.c b/cdb_seek.c deleted file mode 100644 index 87ab614..0000000 --- a/cdb_seek.c +++ /dev/null @@ -1,95 +0,0 @@ -#include <sys/types.h> -#include <errno.h> -extern int errno; -#include "cdb.h" - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - -int cdb_bread(fd,buf,len) -int fd; -char *buf; -int len; -{ - int r; - while (len > 0) { - do - r = read(fd,buf,len); - while ((r == -1) && (errno == EINTR)); - if (r == -1) return -1; - if (r == 0) { errno = EIO; return -1; } - buf += r; - len -= r; - } - return 0; -} - -static int match(fd,key,len) -int fd; -char *key; -unsigned int len; -{ - char buf[32]; - int n; - int i; - - while (len > 0) { - n = sizeof(buf); - if (n > len) n = len; - if (cdb_bread(fd,buf,n) == -1) return -1; - for (i = 0;i < n;++i) if (buf[i] != key[i]) return 0; - key += n; - len -= n; - } - return 1; -} - -int cdb_seek(fd,key,len,dlen) -int fd; -char *key; -unsigned int len; -uint32 *dlen; -{ - char packbuf[8]; - uint32 pos; - uint32 h; - uint32 lenhash; - uint32 h2; - uint32 loop; - uint32 poskd; - - h = cdb_hash(key,len); - - pos = 8 * (h & 255); - if (lseek(fd,(off_t) pos,SEEK_SET) == -1) return -1; - - if (cdb_bread(fd,packbuf,8) == -1) return -1; - - pos = cdb_unpack(packbuf); - lenhash = cdb_unpack(packbuf + 4); - - if (!lenhash) return 0; - h2 = (h >> 8) % lenhash; - - for (loop = 0;loop < lenhash;++loop) { - if (lseek(fd,(off_t) (pos + 8 * h2),SEEK_SET) == -1) return -1; - if (cdb_bread(fd,packbuf,8) == -1) return -1; - poskd = cdb_unpack(packbuf + 4); - if (!poskd) return 0; - if (cdb_unpack(packbuf) == h) { - if (lseek(fd,(off_t) poskd,SEEK_SET) == -1) return -1; - if (cdb_bread(fd,packbuf,8) == -1) return -1; - if (cdb_unpack(packbuf) == len) - switch(match(fd,key,len)) { - case -1: - return -1; - case 1: - *dlen = cdb_unpack(packbuf + 4); - return 1; - } - } - if (++h2 == lenhash) h2 = 0; - } - return 0; -} diff --git a/cdb_unpack.c b/cdb_unpack.c deleted file mode 100644 index c882202..0000000 --- a/cdb_unpack.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "cdb.h" - -uint32 cdb_unpack(buf) -unsigned char *buf; -{ - uint32 num; - num = buf[3]; num <<= 8; - num += buf[2]; num <<= 8; - num += buf[1]; num <<= 8; - num += buf[0]; - return num; -} diff --git a/cdbmake.h b/cdbmake.h deleted file mode 100644 index 883a231..0000000 --- a/cdbmake.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef CDBMAKE_H -#define CDBMAKE_H - -#include "uint32.h" - -#define CDBMAKE_HPLIST 1000 - -struct cdbmake_hp { uint32 h; uint32 p; } ; - -struct cdbmake_hplist { - struct cdbmake_hp hp[CDBMAKE_HPLIST]; - struct cdbmake_hplist *next; - int num; -} ; - -struct cdbmake { - char final[2048]; - uint32 count[256]; - uint32 start[256]; - struct cdbmake_hplist *head; - struct cdbmake_hp *split; /* includes space for hash */ - struct cdbmake_hp *hash; - uint32 numentries; -} ; - -extern void cdbmake_pack(); -#define CDBMAKE_HASHSTART ((uint32) 5381) -extern uint32 cdbmake_hashadd(); - -extern void cdbmake_init(); -extern int cdbmake_add(); -extern int cdbmake_split(); -extern uint32 cdbmake_throw(); - -#endif diff --git a/cdbmake_add.c b/cdbmake_add.c deleted file mode 100644 index 115f828..0000000 --- a/cdbmake_add.c +++ /dev/null @@ -1,117 +0,0 @@ -#include "cdbmake.h" - -void cdbmake_init(cdbm) -struct cdbmake *cdbm; -{ - cdbm->head = 0; - cdbm->split = 0; - cdbm->hash = 0; - cdbm->numentries = 0; -} - -int cdbmake_add(cdbm,h,p,alloc) -struct cdbmake *cdbm; -uint32 h; -uint32 p; -char *(*alloc)(); -{ - struct cdbmake_hplist *head; - - head = cdbm->head; - if (!head || (head->num >= CDBMAKE_HPLIST)) { - head = (struct cdbmake_hplist *) alloc(sizeof(struct cdbmake_hplist)); - if (!head) return 0; - head->num = 0; - head->next = cdbm->head; - cdbm->head = head; - } - head->hp[head->num].h = h; - head->hp[head->num].p = p; - ++head->num; - ++cdbm->numentries; - return 1; -} - -int cdbmake_split(cdbm,alloc) -struct cdbmake *cdbm; -char *(*alloc)(); -{ - int i; - uint32 u; - uint32 memsize; - struct cdbmake_hplist *x; - - for (i = 0;i < 256;++i) - cdbm->count[i] = 0; - - for (x = cdbm->head;x;x = x->next) { - i = x->num; - while (i--) - ++cdbm->count[255 & x->hp[i].h]; - } - - memsize = 1; - for (i = 0;i < 256;++i) { - u = cdbm->count[i] * 2; - if (u > memsize) - memsize = u; - } - - memsize += cdbm->numentries; /* no overflow possible up to now */ - u = (uint32) 0 - (uint32) 1; - u /= sizeof(struct cdbmake_hp); - if (memsize > u) return 0; - - cdbm->split = (struct cdbmake_hp *) alloc(memsize * sizeof(struct cdbmake_hp)); - if (!cdbm->split) return 0; - - cdbm->hash = cdbm->split + cdbm->numentries; - - u = 0; - for (i = 0;i < 256;++i) { - u += cdbm->count[i]; /* bounded by numentries, so no overflow */ - cdbm->start[i] = u; - } - - for (x = cdbm->head;x;x = x->next) { - i = x->num; - while (i--) - cdbm->split[--cdbm->start[255 & x->hp[i].h]] = x->hp[i]; - } - - return 1; -} - -uint32 cdbmake_throw(cdbm,pos,b) -struct cdbmake *cdbm; -uint32 pos; -int b; -{ - uint32 len; - uint32 j; - uint32 count; - struct cdbmake_hp *hp; - uint32 where; - - count = cdbm->count[b]; - - len = count + count; /* no overflow possible */ - cdbmake_pack(cdbm->final + 8 * b,pos); - cdbmake_pack(cdbm->final + 8 * b + 4,len); - - if (len) { - for (j = 0;j < len;++j) - cdbm->hash[j].h = cdbm->hash[j].p = 0; - - hp = cdbm->split + cdbm->start[b]; - for (j = 0;j < count;++j) { - where = (hp->h >> 8) % len; - while (cdbm->hash[where].p) - if (++where == len) - where = 0; - cdbm->hash[where] = *hp++; - } - } - - return len; -} diff --git a/cdbmake_hash.c b/cdbmake_hash.c deleted file mode 100644 index f9dc3e5..0000000 --- a/cdbmake_hash.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "cdbmake.h" - -uint32 cdbmake_hashadd(h,c) -uint32 h; -unsigned int c; -{ - h += (h << 5); - h ^= (uint32) (unsigned char) c; - return h; -} diff --git a/cdbmake_pack.c b/cdbmake_pack.c deleted file mode 100644 index 04b5f5b..0000000 --- a/cdbmake_pack.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "cdbmake.h" - -void cdbmake_pack(buf,num) -unsigned char *buf; -uint32 num; -{ - *buf++ = num; num >>= 8; - *buf++ = num; num >>= 8; - *buf++ = num; num >>= 8; - *buf = num; -} diff --git a/cdbmss.c b/cdbmss.c deleted file mode 100644 index 2d8f367..0000000 --- a/cdbmss.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "readwrite.h" -#include "seek.h" -#include "alloc.h" -#include "cdbmss.h" - -int cdbmss_start(c,fd) -struct cdbmss *c; -int fd; -{ - cdbmake_init(&c->cdbm); - c->fd = fd; - c->pos = sizeof(c->cdbm.final); - substdio_fdbuf(&c->ss,write,fd,c->ssbuf,sizeof(c->ssbuf)); - return seek_set(fd,(seek_pos) c->pos); -} - -int cdbmss_add(c,key,keylen,data,datalen) -struct cdbmss *c; -unsigned char *key; -unsigned int keylen; -unsigned char *data; -unsigned int datalen; -{ - uint32 h; - int i; - - cdbmake_pack(c->packbuf,(uint32) keylen); - cdbmake_pack(c->packbuf + 4,(uint32) datalen); - if (substdio_put(&c->ss,c->packbuf,8) == -1) return -1; - if (substdio_put(&c->ss,key,keylen) == -1) return -1; - if (substdio_put(&c->ss,data,datalen) == -1) return -1; - - h = CDBMAKE_HASHSTART; - for (i = 0;i < keylen;++i) - h = cdbmake_hashadd(h,(unsigned int) key[i]); - - if (!cdbmake_add(&c->cdbm,h,c->pos,alloc)) return -1; - - c->pos += 8 + keylen + datalen; /* XXX: overflow? */ - return 0; -} - -int cdbmss_finish(c) -struct cdbmss *c; -{ - int i; - uint32 len; - uint32 u; - - if (!cdbmake_split(&c->cdbm,alloc)) return -1; - - for (i = 0;i < 256;++i) { - len = cdbmake_throw(&c->cdbm,c->pos,i); - for (u = 0;u < len;++u) { - cdbmake_pack(c->packbuf,c->cdbm.hash[u].h); - cdbmake_pack(c->packbuf + 4,c->cdbm.hash[u].p); - if (substdio_put(&c->ss,c->packbuf,8) == -1) return -1; - c->pos += 8; /* XXX: overflow? */ - } - } - - if (substdio_flush(&c->ss) == -1) return -1; - if (seek_begin(c->fd) == -1) return -1; - return substdio_putflush(&c->ss,c->cdbm.final,sizeof(c->cdbm.final)); -} diff --git a/cdbmss.h b/cdbmss.h deleted file mode 100644 index 5e6bdf4..0000000 --- a/cdbmss.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef CDBMSS_H -#define CDBMSS_H - -#include "cdbmake.h" -#include "substdio.h" - -struct cdbmss { - char ssbuf[1024]; - struct cdbmake cdbm; - substdio ss; - char packbuf[8]; - uint32 pos; - int fd; -} ; - -#endif diff --git a/chkshsgr.c b/chkshsgr.c new file mode 100644 index 0000000..4c7fc83 --- /dev/null +++ b/chkshsgr.c @@ -0,0 +1,10 @@ +#include "exit.h" + +main() +{ + short x[4]; + + x[0] = x[1] = 0; + if (getgroups(1,x) == 0) if (setgroups(1,x) == -1) _exit(1); + _exit(0); +} diff --git a/choose.sh b/choose.sh new file mode 100644 index 0000000..feff2da --- /dev/null +++ b/choose.sh @@ -0,0 +1,18 @@ + +result="$4" + +case "$1" in + *c*) ./compile $2.c >/dev/null 2>&1 || result="$3" ;; +esac + +case "$1" in + *l*) ./load $2 >/dev/null 2>&1 || result="$3" ;; +esac + +case "$1" in + *r*) ./$2 >/dev/null 2>&1 || result="$3" ;; +esac + +rm -f $2.o $2 + +exec cat "$result" diff --git a/commands.c b/commands.c new file mode 100644 index 0000000..b2dc77d --- /dev/null +++ b/commands.c @@ -0,0 +1,39 @@ +#include "buffer.h" +#include "stralloc.h" +#include "str.h" +#include "case.h" +#include "commands.h" + +static stralloc cmd = {0}; + +int commands(buffer *ss,struct commands *c) +{ + int i; + char *arg; + char ch; + + for (;;) { + if (!stralloc_copys(&cmd,"")) return -1; + + for (;;) { + i = buffer_get(ss,&ch,1); + if (i != 1) return i; + if (ch == '\n') break; + if (!ch) ch = '\n'; + if (!stralloc_append(&cmd,&ch)) return -1; + } + + if (cmd.len > 0) if (cmd.s[cmd.len - 1] == '\r') --cmd.len; + + if (!stralloc_0(&cmd)) return -1; + + i = str_chr(cmd.s,' '); + arg = cmd.s + i; + while (*arg == ' ') ++arg; + cmd.s[i] = 0; + + for (i = 0;c[i].verb;++i) if (case_equals(c[i].verb,cmd.s)) break; + c[i].action(arg); + if (c[i].flush) c[i].flush(); + } +} diff --git a/commands.h b/commands.h new file mode 100644 index 0000000..f5fb8fb --- /dev/null +++ b/commands.h @@ -0,0 +1,12 @@ +#ifndef COMMANDS_H +#define COMMANDS_H + +struct commands { + char *verb; + void (*action)(char *); + void (*flush)(void); +} ; + +extern int commands(buffer *,struct commands *); + +#endif @@ -1,3 +1,3 @@ -cc -O2 -g +gcc -O2 This will be used to compile .c files. @@ -1,4 +1,4 @@ /usr -This is the home directory. Programs will be installed in .../bin; man -pages will be installed in subdirectories of .../man. +This is the ucspi-tcp home directory. Programs will be installed in +.../bin. @@ -1,3 +1,3 @@ -cc +gcc -s This will be used to link .o files into an executable. diff --git a/date@.1 b/date@.1 deleted file mode 100644 index fa0ba98..0000000 --- a/date@.1 +++ /dev/null @@ -1,32 +0,0 @@ -.TH date@ 1 -.SH NAME -date@ \- print the date on a host -.SH SYNTAX -.B date@ -[ -.I host -] -.SH DESCRIPTION -.B date@ -connects to TCP port 13 (Daytime) on -.I host -and prints any data it receives. -It removes CR and converts unprintable characters to a visible format. - -If -.I host -is not supplied, -.B date@ -connects to the local host. - -Some computers respond to port 13 with a human-readable date. -For example, they may be running - -.EX - tcpserver 0 13 date & -.EE -.SH "SEE ALSO" -cat(1), -delcr(1), -tcpclient(1), -tcpserver(1) diff --git a/debian/changelog b/debian/changelog index c50aa49..e9597e5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,36 @@ +ucspi-tcp (0.88-5) testing unstable; urgency=low + + * Fixed symlink from /usr/share/doc to /usr/doc (closes #102454) + + -- Jon Marler <jmarler@debian.org> Wed, 27 Jun 2001 17:50:48 -0500 + +ucspi-tcp (0.88-4) unstable; urgency=low + + * Applied rss patch to allow rblsmtpd to use A records + * Removed "-R" advertisement from rblsmtpd + + -- Jon Marler <jmarler@debian.org> Tue, 26 Jun 2001 13:32:42 -0500 + +ucspi-tcp (0.88-3) unstable; urgency=low + + * Moved docs to /usr/share/doc + + -- Jon Marler <jmarler@debian.org> Mon, 26 Mar 2001 11:32:41 -0600 + +ucspi-tcp (0.88-2) unstable; urgency=low + + * Fixed dependancy (closes #71949) + + -- Jon Marler <jmarler@debian.org> Mon, 18 Dec 2000 15:03:16 -0600 + +ucspi-tcp (0.88-1) unstable; urgency=low + + * New upstream release. + * Many changes. See http://cr.yp.to/ucspi-tcp/upgrade.html + * Now conflicts with rblsmtpd. rblsmtpd is included with ucspi-tcp + + -- Jon Marler <jmarler@debian.org> Mon, 18 Dec 2000 12:34:10 -0600 + ucspi-tcp (0.84-1) unstable; urgency=low * New upstream release (closes: #34076) @@ -34,5 +67,5 @@ ucspi-tcp (0.80-1) non-free; urgency=low Local variables: mode: debian-changelog -add-log-mailing-address: "phil@hands.com" +add-log-mailing-address: "jmarler@debian.org" End: diff --git a/debian/control b/debian/control index 330cd7a..8c0c169 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: ucspi-tcp Section: non-free/net Priority: optional Maintainer: Jon Marler <jmarler@debian.org> -Standards-Version: 2.4.0.0 +Standards-Version: 3.0.0.0 Package: ucspi-tcp-src Architecture: all diff --git a/debian/control.real b/debian/control.real index bdce481..4a91800 100644 --- a/debian/control.real +++ b/debian/control.real @@ -2,11 +2,15 @@ Source: ucspi-tcp Section: non-free/net Priority: optional Maintainer: Jon Marler <jmarler@debian.org> -Standards-Version: 2.4.0.0 +Standards-Version: 3.0.0.0 Package: ucspi-tcp +Section: non-free/net +Priority: optional Architecture: any Depends: ${shlibs:Depends} +Provides: rblsmtpd +Conflicts: rblsmtpd Description: tools for building TCP client-server applications. Written by Dan J. Bernstein, tcpclient and tcpserver are powerful easy-to-use command-line tools for building TCP diff --git a/debian/copyright b/debian/copyright index 090e0ca..80bbc26 100644 --- a/debian/copyright +++ b/debian/copyright @@ -41,7 +41,7 @@ without his approval. See http://pobox.com/~djb/softwarelaw.html GPL. A copy of the GNU General Public License is available as -`/usr/doc/copyright/GPL' in the Debian GNU/Linux distribution or on +`/usr/share/doc/copyright/GPL' in the Debian GNU/Linux distribution or on the World Wide Web at `http://www.gnu.org/copyleft/gpl.html'. You can also obtain it by writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA diff --git a/debian/postinst b/debian/postinst new file mode 100644 index 0000000..53a09ad --- /dev/null +++ b/debian/postinst @@ -0,0 +1,7 @@ +#!/bin/sh -e +if [ "$1" = "configure" ]; then + if [ -d /usr/doc -a ! -e /usr/doc/ucspi-tcp -a -d /usr/share/doc/ucspi-tcp ]; then + ln -sf ../share/doc/ucspi-tcp /usr/doc/ucspi-tcp + fi +fi + diff --git a/debian/prerm b/debian/prerm new file mode 100644 index 0000000..e1dba46 --- /dev/null +++ b/debian/prerm @@ -0,0 +1,5 @@ +#!/bin/sh -e +if [ \( "$1" = "upgrade" -o "$1" = "remove" \) -a -L /usr/doc/ucspi-tcp ]; then + rm -f /usr/doc/ucspi-tcp +fi + diff --git a/debian/rules b/debian/rules index b08dad0..448cfbf 100755 --- a/debian/rules +++ b/debian/rules @@ -4,7 +4,7 @@ SHELL = /bin/bash -BINS = tcpserver tcpclient tcprules tcprulescheck mconnect-io addcr delcr fixcr argv0 recordio +BINS = tcpserver tcpclient tcprules tcprulescheck rblsmtpd mconnect-io addcr delcr fixcrio argv0 recordio SHBINS = who@ date@ finger@ tcpcat mconnect http@ @@ -12,7 +12,7 @@ MAN1 = tcpclient.1 tcpserver.1 tcprules.1 debian/addcr.1 debian/delcr.1 MAN5 = tcp-environ.5 -DOCS = BLURB README TCP THANKS TODO UCSPI +DOCS = README TODO VERSION SYSDEPS CHANGES FILES TARGETS PACKAGE = $(shell perl -e 'print <> =~ /(\S*)\s/' debian/changelog) PKG_VER = $(shell perl -e 'print <> =~ /\((.*)\)/' debian/changelog) @@ -33,7 +33,9 @@ clean: checkdir debian/control rm -f auto-ccld.sh make-load find-systype systype load \ make-compile compile select.h make-makelib makelib \ hassgprm.h hassgact.h dns.lib uint32.h haswaitp.h \ - install instcheck test.cdb auto-str rts auto_home.c + install instcheck test.cdb auto-str rts auto_home.c \ + chkshsgr choose conf-home-debian fork.h hasshsgr.h \ + iopause.h socket.lib uint64.h find . \( -name '#*#' -o -name '*~' -o -name DEADJOE -o \ -name '*.orig' -o -name '*.rej' -o -name '*.bak' -o \ -name '.*.orig' -o -name '.*.rej' -o -name .SUMS -o \ @@ -41,9 +43,9 @@ clean: checkdir debian/control binary-indep: checkroot build rm -rf debian/misc - install -d -m 0755 debian/misc/{DEBIAN,usr/{bin,doc}} + install -d -m 0755 debian/misc/{DEBIAN,usr/share/doc,usr/bin} install -m 0755 $(SHBINS) debian/misc/usr/bin/ - ln -s ucspi-tcp debian/misc/usr/doc/ucspi-tcp-misc + ln -s ucspi-tcp debian/misc/usr/share/doc/ucspi-tcp-misc dpkg-gencontrol -pucspi-tcp-misc -Pdebian/misc -cdebian/control.real chown -R root.root debian/misc @@ -51,17 +53,18 @@ binary-indep: checkroot build binary-arch: checkroot build rm -rf debian/tmp - install -d -m 0755 debian/tmp/{DEBIAN,usr/{bin,man/man{1,5},doc/ucspi-tcp}} + install -d -m 0755 debian/tmp/{DEBIAN,usr/{bin,man/man{1,5},share/doc/ucspi-tcp}} install -s -m 0755 $(BINS) debian/tmp/usr/bin/ - install -m 0644 $(MAN1) debian/tmp/usr/man/man1/ - install -m 0644 $(MAN5) debian/tmp/usr/man/man5/ + # Man pages are no longer provided + #install -m 0644 $(MAN1) debian/tmp/usr/man/man1/ + #install -m 0644 $(MAN5) debian/tmp/usr/man/man5/ - install -m 0644 CHANGES debian/tmp/usr/doc/ucspi-tcp/changelog - install -m 0644 debian/changelog debian/tmp/usr/doc/ucspi-tcp/changelog.Debian - install -m 0644 $(DOCS) debian/tmp/usr/doc/ucspi-tcp/ - gzip -9fr debian/tmp/usr/doc/ debian/tmp/usr/man/ - install -m 0644 debian/copyright debian/tmp/usr/doc/ucspi-tcp/copyright - install -p -m 0755 debian/postrm debian/preinst debian/tmp/DEBIAN + install -m 0644 CHANGES debian/tmp/usr/share/doc/ucspi-tcp/changelog + install -m 0644 debian/changelog debian/tmp/usr/share/doc/ucspi-tcp/changelog.Debian + install -m 0644 $(DOCS) debian/tmp/usr/share/doc/ucspi-tcp/ + gzip -fr debian/tmp/usr/share/doc/ debian/tmp/usr/man/ + install -m 0644 debian/copyright debian/tmp/usr/share/doc/ucspi-tcp/copyright + install -p -m 0755 debian/prerm debian/postrm debian/preinst debian/tmp/DEBIAN dpkg-shlibdeps $(BINS) dpkg-gencontrol -pucspi-tcp -cdebian/control.real @@ -75,7 +78,7 @@ binary-src: checkroot checkdir debian/control ../$(PACKAGE)_$(PKG_UPVER).orig.ta install -d $(TMPSRC)/DEBIAN \ $(TMPSRC)/usr/bin \ $(TMPSRC)/usr/src/$(PACKAGE)-src \ - $(TMPSRC)/usr/doc/$(PACKAGE)-src + $(TMPSRC)/usr/share/doc/$(PACKAGE)-src install -m 755 debian/build-PACKAGE $(TMPSRC)/usr/bin/build-$(PACKAGE) install -m 0644 ../$(PACKAGE)_$(PKG_UPVER).orig.tar.gz \ ../$(PACKAGE)_$(PKG_VER).dsc \ @@ -83,11 +86,15 @@ binary-src: checkroot checkdir debian/control ../$(PACKAGE)_$(PKG_UPVER).orig.ta $(TMPSRC)/usr/src/$(PACKAGE)-src/ sed -e "s/#PACKAGE#/$(PACKAGE)/" debian/src.postinst > $(TMPSRC)/DEBIAN/postinst chmod 755 $(TMPSRC)/DEBIAN/postinst - sed -e "s/#PACKAGE#/$(PACKAGE)/" debian/README-src > $(TMPSRC)/usr/doc/$(PACKAGE)-src/README.Debian - install -m 0644 debian/changelog $(TMPSRC)/usr/doc/$(PACKAGE)-src/changelog.Debian - chmod 644 $(TMPSRC)/usr/doc/$(PACKAGE)-src/changelog.Debian - gzip -9fr $(TMPSRC)/usr/doc/ - install -m 0644 debian/copyright $(TMPSRC)/usr/doc/$(PACKAGE)-src/ + + sed -e "s/#PACKAGE#/$(PACKAGE)/" debian/src.prerm > $(TMPSRC)/DEBIAN/prerm + chmod 755 $(TMPSRC)/DEBIAN/prerm + + sed -e "s/#PACKAGE#/$(PACKAGE)/" debian/README-src > $(TMPSRC)/usr/share/doc/$(PACKAGE)-src/README.Debian + install -m 0644 debian/changelog $(TMPSRC)/usr/share/doc/$(PACKAGE)-src/changelog.Debian + chmod 644 $(TMPSRC)/usr/share/doc/$(PACKAGE)-src/changelog.Debian + gzip -fr $(TMPSRC)/usr/share/doc/ + install -m 0644 debian/copyright $(TMPSRC)/usr/share/doc/$(PACKAGE)-src/ dpkg-gencontrol -p$(PACKAGE)-src -P$(TMPSRC) chown -R root.root $(TMPSRC) diff --git a/debian/src.postinst b/debian/src.postinst index e7cbd04..b5b0600 100644 --- a/debian/src.postinst +++ b/debian/src.postinst @@ -1,5 +1,11 @@ #!/bin/sh -e +if [ "$1" = "configure" ]; then + if [ -d /usr/doc -a ! -e /usr/doc/ucspi-tcp-src -a -d /usr/share/doc/ucspi-tcp-src ]; then + ln -sf ../share/doc/ucspi-tcp-src /usr/doc/ucspi-tcp-src + fi +fi + echo "" echo "To build #PACKAGE# binary package, you have to run" echo "" diff --git a/debian/src.prerm b/debian/src.prerm new file mode 100644 index 0000000..e1dba46 --- /dev/null +++ b/debian/src.prerm @@ -0,0 +1,5 @@ +#!/bin/sh -e +if [ \( "$1" = "upgrade" -o "$1" = "remove" \) -a -L /usr/doc/ucspi-tcp ]; then + rm -f /usr/doc/ucspi-tcp +fi + diff --git a/delcr.1 b/delcr.1 deleted file mode 100644 index 18ea736..0000000 --- a/delcr.1 +++ /dev/null @@ -1,30 +0,0 @@ -.TH delcr 1 -.SH NAME -delcr \- remove a CR before each LF -.SH SYNOPSIS -.B delcr -.SH DESCRIPTION -.B delcr -removes a CR at the end of each line of input, -if a CR is present. -It also removes a CR at the end of a partial final line. - -The pipeline - -.EX - addcr | delcr -.EE - -prints an exact copy of its input. -.SH COMPATIBILITY -Some vendors ship -.B dos2unix -or -.B dos2bsd -tools similar to -.BR delcr . -Those tools often blow up on long lines and nulls. -.B delcr -has no trouble with long lines and nulls. -.SH "SEE ALSO" -addcr(1) @@ -1,8 +1,7 @@ -#include "substdio.h" -#include "subfd.h" +#include "buffer.h" #include "exit.h" -void main() +main() { register int n; register char *x; @@ -10,28 +9,29 @@ void main() register int flagcr = 0; for (;;) { - n = substdio_feed(subfdin); + n = buffer_feed(buffer_0); if (n < 0) _exit(111); if (!n) { - if (flagcr) substdio_BPUTC(subfdout,"\r"[0]); + if (flagcr) buffer_PUTC(buffer_1,"\r"[0]); + buffer_flush(buffer_1); _exit(0); } - x = substdio_PEEK(subfdin); - substdio_SEEK(subfdin,n); + x = buffer_PEEK(buffer_0); + buffer_SEEK(buffer_0,n); while (n > 0) { ch = *x++; --n; if (!flagcr) { if (ch == '\r') { flagcr = 1; continue; } - substdio_BPUTC(subfdout,ch); + buffer_PUTC(buffer_1,ch); continue; } if (ch != '\n') { - substdio_BPUTC(subfdout,"\r"[0]); + buffer_PUTC(buffer_1,"\r"[0]); if (ch == '\r') continue; } flagcr = 0; - substdio_BPUTC(subfdout,ch); + buffer_PUTC(buffer_1,ch); } } } @@ -1,400 +0,0 @@ -#include <stdio.h> -#include <netdb.h> -#include <sys/types.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <resolv.h> -#include <errno.h> -extern int res_query(); -extern int res_search(); -extern int errno; -extern int h_errno; -#include "ip.h" -#include "ipalloc.h" -#include "fmt.h" -#include "alloc.h" -#include "str.h" -#include "stralloc.h" -#include "dns.h" -#include "case.h" - -static unsigned short getshort(c) unsigned char *c; -{ unsigned short u; u = c[0]; return (u << 8) + c[1]; } - -static union { HEADER hdr; unsigned char buf[PACKETSZ]; } response; -static int responselen; -static unsigned char *responseend; -static unsigned char *responsepos; - -static int numanswers; -static char name[MAXDNAME]; -static struct ip_address ip; -unsigned short pref; - -static stralloc glue = {0}; - -static int (*lookup)() = res_query; - -static int resolve(domain,type) -stralloc *domain; -int type; -{ - int n; - int i; - - errno = 0; - if (!stralloc_copy(&glue,domain)) return DNS_MEM; - if (!stralloc_0(&glue)) return DNS_MEM; - responselen = lookup(glue.s,C_IN,type,response.buf,sizeof(response)); - if (responselen <= 0) - { - if (errno == ECONNREFUSED) return DNS_SOFT; - if (h_errno == TRY_AGAIN) return DNS_SOFT; - return DNS_HARD; - } - if (responselen >= sizeof(response)) - responselen = sizeof(response); - responseend = response.buf + responselen; - responsepos = response.buf + sizeof(HEADER); - n = ntohs(response.hdr.qdcount); - while (n-- > 0) - { - i = dn_expand(response.buf,responseend,responsepos,name,MAXDNAME); - if (i < 0) return DNS_SOFT; - responsepos += i; - i = responseend - responsepos; - if (i < QFIXEDSZ) return DNS_SOFT; - responsepos += QFIXEDSZ; - } - numanswers = ntohs(response.hdr.ancount); - return 0; -} - -static int findname(wanttype) -int wanttype; -{ - unsigned short rrtype; - unsigned short rrdlen; - int i; - - if (numanswers <= 0) return 2; - --numanswers; - if (responsepos == responseend) return DNS_SOFT; - - i = dn_expand(response.buf,responseend,responsepos,name,MAXDNAME); - if (i < 0) return DNS_SOFT; - responsepos += i; - - i = responseend - responsepos; - if (i < 4 + 3 * 2) return DNS_SOFT; - - rrtype = getshort(responsepos); - rrdlen = getshort(responsepos + 8); - responsepos += 10; - - if (rrtype == wanttype) - { - if (dn_expand(response.buf,responseend,responsepos,name,MAXDNAME) < 0) - return DNS_SOFT; - responsepos += rrdlen; - return 1; - } - - responsepos += rrdlen; - return 0; -} - -static int findip(wanttype) -int wanttype; -{ - unsigned short rrtype; - unsigned short rrdlen; - int i; - - if (numanswers <= 0) return 2; - --numanswers; - if (responsepos == responseend) return DNS_SOFT; - - i = dn_expand(response.buf,responseend,responsepos,name,MAXDNAME); - if (i < 0) return DNS_SOFT; - responsepos += i; - - i = responseend - responsepos; - if (i < 4 + 3 * 2) return DNS_SOFT; - - rrtype = getshort(responsepos); - rrdlen = getshort(responsepos + 8); - responsepos += 10; - - if (rrtype == wanttype) - { - if (rrdlen < 4) - return DNS_SOFT; - ip.d[0] = responsepos[0]; - ip.d[1] = responsepos[1]; - ip.d[2] = responsepos[2]; - ip.d[3] = responsepos[3]; - responsepos += rrdlen; - return 1; - } - - responsepos += rrdlen; - return 0; -} - -static int findmx(wanttype) -int wanttype; -{ - unsigned short rrtype; - unsigned short rrdlen; - int i; - - if (numanswers <= 0) return 2; - --numanswers; - if (responsepos == responseend) return DNS_SOFT; - - i = dn_expand(response.buf,responseend,responsepos,name,MAXDNAME); - if (i < 0) return DNS_SOFT; - responsepos += i; - - i = responseend - responsepos; - if (i < 4 + 3 * 2) return DNS_SOFT; - - rrtype = getshort(responsepos); - rrdlen = getshort(responsepos + 8); - responsepos += 10; - - if (rrtype == wanttype) - { - if (rrdlen < 3) - return DNS_SOFT; - pref = (responsepos[0] << 8) + responsepos[1]; - if (dn_expand(response.buf,responseend,responsepos + 2,name,MAXDNAME) < 0) - return DNS_SOFT; - responsepos += rrdlen; - return 1; - } - - responsepos += rrdlen; - return 0; -} - -void dns_init(flagsearch) -int flagsearch; -{ - res_init(); - if (flagsearch) lookup = res_search; -} - -int dns_cname(sa) -stralloc *sa; -{ - int r; - int loop; - for (loop = 0;loop < 10;++loop) - { - if (!sa->len) return loop; - if (sa->s[sa->len - 1] == ']') return loop; - if (sa->s[sa->len - 1] == '.') { --sa->len; continue; } - switch(resolve(sa,T_ANY)) - { - case DNS_MEM: return DNS_MEM; - case DNS_SOFT: return DNS_SOFT; - case DNS_HARD: return loop; - default: - while ((r = findname(T_CNAME)) != 2) - { - if (r == DNS_SOFT) return DNS_SOFT; - if (r == 1) - { - if (!stralloc_copys(sa,name)) return DNS_MEM; - break; - } - } - if (r == 2) return loop; - } - } - return DNS_HARD; /* alias loop */ -} - -#define FMT_IAA 40 - -static int iaafmt(s,ip) -char *s; -struct ip_address *ip; -{ - unsigned int i; - unsigned int len; - len = 0; - i = fmt_ulong(s,(unsigned long) ip->d[3]); len += i; if (s) s += i; - i = fmt_str(s,"."); len += i; if (s) s += i; - i = fmt_ulong(s,(unsigned long) ip->d[2]); len += i; if (s) s += i; - i = fmt_str(s,"."); len += i; if (s) s += i; - i = fmt_ulong(s,(unsigned long) ip->d[1]); len += i; if (s) s += i; - i = fmt_str(s,"."); len += i; if (s) s += i; - i = fmt_ulong(s,(unsigned long) ip->d[0]); len += i; if (s) s += i; - i = fmt_str(s,".in-addr.arpa."); len += i; if (s) s += i; - return len; -} - -int dns_ptr(sa,ip) -stralloc *sa; -struct ip_address *ip; -{ - int r; - - if (!stralloc_ready(sa,iaafmt((char *) 0,ip))) return DNS_MEM; - sa->len = iaafmt(sa->s,ip); - switch(resolve(sa,T_PTR)) - { - case DNS_MEM: return DNS_MEM; - case DNS_SOFT: return DNS_SOFT; - case DNS_HARD: return DNS_HARD; - } - while ((r = findname(T_PTR)) != 2) - { - if (r == DNS_SOFT) return DNS_SOFT; - if (r == 1) - { - if (!stralloc_copys(sa,name)) return DNS_MEM; - return 0; - } - } - return DNS_HARD; -} - -static int dns_ipplus(ia,sa,pref) -ipalloc *ia; -stralloc *sa; -int pref; -{ - int r; - struct ip_mx ix; - - if (!stralloc_copy(&glue,sa)) return DNS_MEM; - if (!stralloc_0(&glue)) return DNS_MEM; - if (glue.s[0]) { - ix.pref = 0; - if (!glue.s[ip_scan(glue.s,&ix.ip)] || !glue.s[ip_scanbracket(glue.s,&ix.ip)]) - { - if (!ipalloc_append(ia,&ix)) return DNS_MEM; - return 0; - } - } - - switch(resolve(sa,T_A)) - { - case DNS_MEM: return DNS_MEM; - case DNS_SOFT: return DNS_SOFT; - case DNS_HARD: return DNS_HARD; - } - while ((r = findip(T_A)) != 2) - { - ix.ip = ip; - ix.pref = pref; - if (r == DNS_SOFT) return DNS_SOFT; - if (r == 1) - if (!ipalloc_append(ia,&ix)) return DNS_MEM; - } - return 0; -} - -int dns_ip(ia,sa) -ipalloc *ia; -stralloc *sa; -{ - if (!ipalloc_readyplus(ia,0)) return DNS_MEM; - ia->len = 0; - return dns_ipplus(ia,sa,0); -} - -int dns_mxip(ia,sa,random) -ipalloc *ia; -stralloc *sa; -unsigned long random; -{ - int r; - struct mx { stralloc sa; unsigned short p; } *mx; - struct ip_mx ix; - int nummx; - int i; - int j; - int flagsoft; - - if (!ipalloc_readyplus(ia,0)) return DNS_MEM; - ia->len = 0; - - if (!stralloc_copy(&glue,sa)) return DNS_MEM; - if (!stralloc_0(&glue)) return DNS_MEM; - if (glue.s[0]) { - ix.pref = 0; - if (!glue.s[ip_scan(glue.s,&ix.ip)] || !glue.s[ip_scanbracket(glue.s,&ix.ip)]) - { - if (!ipalloc_append(ia,&ix)) return DNS_MEM; - return 0; - } - } - - switch(resolve(sa,T_MX)) - { - case DNS_MEM: return DNS_MEM; - case DNS_SOFT: return DNS_SOFT; - case DNS_HARD: return dns_ip(ia,sa); - } - - mx = (struct mx *) alloc(numanswers * sizeof(struct mx)); - if (!mx) return DNS_MEM; - nummx = 0; - - while ((r = findmx(T_MX)) != 2) - { - if (r == DNS_SOFT) { alloc_free(mx); return DNS_SOFT; } - if (r == 1) - { - mx[nummx].p = pref; - mx[nummx].sa.s = 0; - if (!stralloc_copys(&mx[nummx].sa,name)) - { - while (nummx > 0) alloc_free(mx[--nummx].sa.s); - alloc_free(mx); return DNS_MEM; - } - ++nummx; - } - } - - if (!nummx) return dns_ip(ia,sa); /* e.g., CNAME -> A */ - - flagsoft = 0; - while (nummx > 0) - { - unsigned long numsame; - - i = 0; - numsame = 1; - for (j = 1;j < nummx;++j) - if (mx[j].p < mx[i].p) - { - i = j; - numsame = 1; - } - else if (mx[j].p == mx[i].p) - { - ++numsame; - random = random * 69069 + 1; - if ((random / 2) < (2147483647 / numsame)) - i = j; - } - - switch(dns_ipplus(ia,&mx[i].sa,mx[i].p)) - { - case DNS_MEM: case DNS_SOFT: - flagsoft = 1; break; - } - - alloc_free(mx[i].sa.s); - mx[i] = mx[--nummx]; - } - - alloc_free(mx); - return flagsoft; -} @@ -1,14 +1,84 @@ #ifndef DNS_H #define DNS_H -#define DNS_SOFT -1 -#define DNS_HARD -2 -#define DNS_MEM -3 - -void dns_init(); -int dns_cname(); -int dns_mxip(); -int dns_ip(); -int dns_ptr(); +#include "stralloc.h" +#include "iopause.h" +#include "taia.h" + +#define DNS_C_IN "\0\1" +#define DNS_C_ANY "\0\377" + +#define DNS_T_A "\0\1" +#define DNS_T_NS "\0\2" +#define DNS_T_CNAME "\0\5" +#define DNS_T_SOA "\0\6" +#define DNS_T_PTR "\0\14" +#define DNS_T_HINFO "\0\15" +#define DNS_T_MX "\0\17" +#define DNS_T_TXT "\0\20" +#define DNS_T_RP "\0\21" +#define DNS_T_SIG "\0\30" +#define DNS_T_KEY "\0\31" +#define DNS_T_AAAA "\0\34" +#define DNS_T_AXFR "\0\374" +#define DNS_T_ANY "\0\377" + +struct dns_transmit { + char *query; /* 0, or dynamically allocated */ + unsigned int querylen; + char *packet; /* 0, or dynamically allocated */ + unsigned int packetlen; + int s1; /* 0, or 1 + an open file descriptor */ + int tcpstate; + unsigned int udploop; + unsigned int curserver; + struct taia deadline; + unsigned int pos; + char *servers; + char localip[4]; + char qtype[2]; +} ; + +extern void dns_random_init(char *); +extern unsigned int dns_random(unsigned int); + +extern void dns_sortip(char *,unsigned int); + +extern void dns_domain_free(char **); +extern int dns_domain_copy(char **,char *); +extern unsigned int dns_domain_length(char *); +extern int dns_domain_equal(char *,char *); +extern char *dns_domain_suffix(char *,char *); +extern int dns_domain_fromdot(char **,char *,unsigned int); +extern int dns_domain_todot_cat(stralloc *,char *); + +extern unsigned int dns_packet_copy(char *,unsigned int,unsigned int,char *,unsigned int); +extern unsigned int dns_packet_getname(char *,unsigned int,unsigned int,char **); +extern unsigned int dns_packet_skipname(char *,unsigned int,unsigned int); +extern int dns_packet_nameequal(char *,unsigned int,unsigned int,char *,unsigned int,unsigned int); + +extern int dns_transmit_start(struct dns_transmit *,char *,int,char *,char *,char *); +extern void dns_transmit_free(struct dns_transmit *); +extern void dns_transmit_io(struct dns_transmit *,iopause_fd *,struct taia *); +extern int dns_transmit_get(struct dns_transmit *,iopause_fd *,struct taia *); + +extern int dns_resolvconfip(char *); +extern int dns_resolve(char *,char *); +extern struct dns_transmit dns_resolve_tx; + +extern int dns_ip4_packet(stralloc *,char *,unsigned int); +extern int dns_ip4(stralloc *,stralloc *); +extern int dns_name_packet(stralloc *,char *,unsigned int); +extern void dns_name4_domain(char *,char *); +#define DNS_NAME4_DOMAIN 31 +extern int dns_name4(stralloc *,char *); +extern int dns_txt_packet(stralloc *,char *,unsigned int); +extern int dns_txt(stralloc *,stralloc *); +extern int dns_mx_packet(stralloc *,char *,unsigned int); +extern int dns_mx(stralloc *,stralloc *); + +extern int dns_resolvconfrewrite(stralloc *); +extern int dns_ip4_qualify_rules(stralloc *,stralloc *,stralloc *,stralloc *); +extern int dns_ip4_qualify(stralloc *,stralloc *,stralloc *); #endif diff --git a/dns_dfd.c b/dns_dfd.c new file mode 100644 index 0000000..14a29d8 --- /dev/null +++ b/dns_dfd.c @@ -0,0 +1,69 @@ +#include "error.h" +#include "alloc.h" +#include "byte.h" +#include "dns.h" + +int dns_domain_fromdot(char **out,char *buf,unsigned int n) +{ + char label[63]; + unsigned int labellen = 0; /* <= sizeof label */ + char name[255]; + unsigned int namelen = 0; /* <= sizeof name */ + char ch; + char *x; + + errno = error_proto; + + for (;;) { + if (!n) break; + ch = *buf++; --n; + if (ch == '.') { + if (labellen) { + if (namelen + labellen + 1 > sizeof name) return 0; + name[namelen++] = labellen; + byte_copy(name + namelen,labellen,label); + namelen += labellen; + labellen = 0; + } + continue; + } + if (ch == '\\') { + if (!n) break; + ch = *buf++; --n; + if ((ch >= '0') && (ch <= '7')) { + ch -= '0'; + if (n && (*buf >= '0') && (*buf <= '7')) { + ch <<= 3; + ch += *buf - '0'; + ++buf; --n; + if (n && (*buf >= '0') && (*buf <= '7')) { + ch <<= 3; + ch += *buf - '0'; + ++buf; --n; + } + } + } + } + if (labellen >= sizeof label) return 0; + label[labellen++] = ch; + } + + if (labellen) { + if (namelen + labellen + 1 > sizeof name) return 0; + name[namelen++] = labellen; + byte_copy(name + namelen,labellen,label); + namelen += labellen; + labellen = 0; + } + + if (namelen + 1 > sizeof name) return 0; + name[namelen++] = 0; + + x = alloc(namelen); + if (!x) return 0; + byte_copy(x,namelen,name); + + if (*out) alloc_free(*out); + *out = x; + return 1; +} diff --git a/dns_domain.c b/dns_domain.c new file mode 100644 index 0000000..f898485 --- /dev/null +++ b/dns_domain.c @@ -0,0 +1,61 @@ +#include "error.h" +#include "alloc.h" +#include "case.h" +#include "byte.h" +#include "dns.h" + +unsigned int dns_domain_length(char *dn) +{ + char *x; + unsigned char c; + + x = dn; + while (c = *x++) + x += (unsigned int) c; + return x - dn; +} + +void dns_domain_free(char **out) +{ + if (*out) { + alloc_free(*out); + *out = 0; + } +} + +int dns_domain_copy(char **out,char *in) +{ + unsigned int len; + char *x; + + len = dns_domain_length(in); + x = alloc(len); + if (!x) return 0; + byte_copy(x,len,in); + if (*out) alloc_free(*out); + *out = x; + return 1; +} + +int dns_domain_equal(char *dn1,char *dn2) +{ + unsigned int len; + + len = dns_domain_length(dn1); + if (len != dns_domain_length(dn2)) return 0; + + if (case_diffb(dn1,len,dn2)) return 0; /* safe since 63 < 'A' */ + return 1; +} + +char *dns_domain_suffix(char *big,char *little) +{ + unsigned char c; + + for (;;) { + if (dns_domain_equal(big,little)) return big; + c = *big++; + if (!c) return 0; + big += c; + } +} diff --git a/dns_dtda.c b/dns_dtda.c new file mode 100644 index 0000000..00b41a1 --- /dev/null +++ b/dns_dtda.c @@ -0,0 +1,35 @@ +#include "stralloc.h" +#include "dns.h" + +int dns_domain_todot_cat(stralloc *out,char *d) +{ + char ch; + char ch2; + unsigned char ch3; + char buf[4]; + + if (!*d) + return stralloc_append(out,"."); + + for (;;) { + ch = *d++; + while (ch--) { + ch2 = *d++; + if ((ch2 >= 'A') && (ch2 <= 'Z')) + ch2 += 32; + if (((ch2 >= 'a') && (ch2 <= 'z')) || ((ch2 >= '0') && (ch2 <= '9')) || (ch2 == '-') || (ch2 == '_')) { + if (!stralloc_append(out,&ch2)) return 0; + } + else { + ch3 = ch2; + buf[3] = '0' + (ch3 & 7); ch3 >>= 3; + buf[2] = '0' + (ch3 & 7); ch3 >>= 3; + buf[1] = '0' + (ch3 & 7); + buf[0] = '\\'; + if (!stralloc_catb(out,buf,4)) return 0; + } + } + if (!*d) return 1; + if (!stralloc_append(out,".")) return 0; + } +} diff --git a/dns_ip.c b/dns_ip.c new file mode 100644 index 0000000..fb0526c --- /dev/null +++ b/dns_ip.c @@ -0,0 +1,75 @@ +#include "stralloc.h" +#include "uint16.h" +#include "byte.h" +#include "dns.h" + +int dns_ip4_packet(stralloc *out,char *buf,unsigned int len) +{ + unsigned int pos; + char header[12]; + uint16 numanswers; + uint16 datalen; + + if (!stralloc_copys(out,"")) return -1; + + pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; + uint16_unpack_big(header + 6,&numanswers); + pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; + pos += 4; + + while (numanswers--) { + pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; + pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; + uint16_unpack_big(header + 8,&datalen); + if (byte_equal(header,2,DNS_T_A)) + if (byte_equal(header + 2,2,DNS_C_IN)) + if (datalen == 4) { + if (!dns_packet_copy(buf,len,pos,header,4)) return -1; + if (!stralloc_catb(out,header,4)) return -1; + } + pos += datalen; + } + + dns_sortip(out->s,out->len); + return 0; +} + +static char *q = 0; + +int dns_ip4(stralloc *out,stralloc *fqdn) +{ + unsigned int i; + char code; + char ch; + + if (!stralloc_copys(out,"")) return -1; + code = 0; + for (i = 0;i <= fqdn->len;++i) { + if (i < fqdn->len) + ch = fqdn->s[i]; + else + ch = '.'; + + if ((ch == '[') || (ch == ']')) continue; + if (ch == '.') { + if (!stralloc_append(out,&code)) return -1; + code = 0; + continue; + } + if ((ch >= '0') && (ch <= '9')) { + code *= 10; + code += ch - '0'; + continue; + } + + if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; + if (dns_resolve(q,DNS_T_A) == -1) return -1; + if (dns_ip4_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; + dns_transmit_free(&dns_resolve_tx); + dns_domain_free(&q); + return 0; + } + + out->len &= ~3; + return 0; +} diff --git a/dns_ipq.c b/dns_ipq.c new file mode 100644 index 0000000..8181ab7 --- /dev/null +++ b/dns_ipq.c @@ -0,0 +1,71 @@ +#include "stralloc.h" +#include "case.h" +#include "byte.h" +#include "str.h" +#include "dns.h" + +static int doit(stralloc *work,char *rule) +{ + char ch; + unsigned int colon; + unsigned int prefixlen; + + ch = *rule++; + if ((ch != '?') && (ch != '=') && (ch != '*') && (ch != '-')) return 1; + colon = str_chr(rule,':'); + if (!rule[colon]) return 1; + + if (work->len < colon) return 1; + prefixlen = work->len - colon; + if ((ch == '=') && prefixlen) return 1; + if (case_diffb(rule,colon,work->s + prefixlen)) return 1; + if (ch == '?') { + if (byte_chr(work->s,prefixlen,'.') < prefixlen) return 1; + if (byte_chr(work->s,prefixlen,'[') < prefixlen) return 1; + if (byte_chr(work->s,prefixlen,']') < prefixlen) return 1; + } + + work->len = prefixlen; + if (ch == '-') work->len = 0; + return stralloc_cats(work,rule + colon + 1); +} + +int dns_ip4_qualify_rules(stralloc *out,stralloc *fqdn,stralloc *in,stralloc *rules) +{ + unsigned int i; + unsigned int j; + unsigned int plus; + unsigned int fqdnlen; + + if (!stralloc_copy(fqdn,in)) return -1; + + for (j = i = 0;j < rules->len;++j) + if (!rules->s[j]) { + if (!doit(fqdn,rules->s + i)) return -1; + i = j + 1; + } + + fqdnlen = fqdn->len; + plus = byte_chr(fqdn->s,fqdnlen,'+'); + if (plus >= fqdnlen) + return dns_ip4(out,fqdn); + + i = plus + 1; + for (;;) { + j = byte_chr(fqdn->s + i,fqdnlen - i,'+'); + byte_copy(fqdn->s + plus,j,fqdn->s + i); + fqdn->len = plus + j; + if (dns_ip4(out,fqdn) == -1) return -1; + if (out->len) return 0; + i += j; + if (i >= fqdnlen) return 0; + ++i; + } +} + +int dns_ip4_qualify(stralloc *out,stralloc *fqdn,stralloc *in) +{ + static stralloc rules; + if (dns_resolvconfrewrite(&rules) == -1) return -1; + return dns_ip4_qualify_rules(out,fqdn,in,&rules); +} diff --git a/dns_name.c b/dns_name.c new file mode 100644 index 0000000..dcb10c7 --- /dev/null +++ b/dns_name.c @@ -0,0 +1,48 @@ +#include "stralloc.h" +#include "uint16.h" +#include "byte.h" +#include "dns.h" + +static char *q = 0; + +int dns_name_packet(stralloc *out,char *buf,unsigned int len) +{ + unsigned int pos; + char header[12]; + uint16 numanswers; + uint16 datalen; + + if (!stralloc_copys(out,"")) return -1; + + pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; + uint16_unpack_big(header + 6,&numanswers); + pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; + pos += 4; + + while (numanswers--) { + pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; + pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; + uint16_unpack_big(header + 8,&datalen); + if (byte_equal(header,2,DNS_T_PTR)) + if (byte_equal(header + 2,2,DNS_C_IN)) { + if (!dns_packet_getname(buf,len,pos,&q)) return -1; + if (!dns_domain_todot_cat(out,q)) return -1; + return 0; + } + pos += datalen; + } + + return 0; +} + +int dns_name4(stralloc *out,char ip[4]) +{ + char name[DNS_NAME4_DOMAIN]; + + dns_name4_domain(name,ip); + if (dns_resolve(name,DNS_T_PTR) == -1) return -1; + if (dns_name_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; + dns_transmit_free(&dns_resolve_tx); + dns_domain_free(&q); + return 0; +} diff --git a/dns_nd.c b/dns_nd.c new file mode 100644 index 0000000..279d74d --- /dev/null +++ b/dns_nd.c @@ -0,0 +1,24 @@ +#include "byte.h" +#include "fmt.h" +#include "dns.h" + +void dns_name4_domain(char name[DNS_NAME4_DOMAIN],char ip[4]) +{ + unsigned int namelen; + unsigned int i; + + namelen = 0; + i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[3]); + name[namelen++] = i; + namelen += i; + i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[2]); + name[namelen++] = i; + namelen += i; + i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[1]); + name[namelen++] = i; + namelen += i; + i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[0]); + name[namelen++] = i; + namelen += i; + byte_copy(name + namelen,14,"\7in-addr\4arpa\0"); +} diff --git a/dns_packet.c b/dns_packet.c new file mode 100644 index 0000000..04a2cc8 --- /dev/null +++ b/dns_packet.c @@ -0,0 +1,77 @@ +/* +DNS should have used LZ77 instead of its own sophomoric compression algorithm. +*/ + +#include "error.h" +#include "dns.h" + +unsigned int dns_packet_copy(char *buf,unsigned int len,unsigned int pos,char *out,unsigned int outlen) +{ + while (outlen) { + if (pos >= len) { errno = error_proto; return 0; } + *out = buf[pos++]; + ++out; --outlen; + } + return pos; +} + +unsigned int dns_packet_skipname(char *buf,unsigned int len,unsigned int pos) +{ + unsigned char ch; + + for (;;) { + if (pos >= len) break; + ch = buf[pos++]; + if (ch >= 192) return pos + 1; + if (ch >= 64) break; + if (!ch) return pos; + pos += ch; + } + + errno = error_proto; + return 0; +} + +unsigned int dns_packet_getname(char *buf,unsigned int len,unsigned int pos,char **d) +{ + unsigned int loop = 0; + unsigned int state = 0; + unsigned int firstcompress = 0; + unsigned int where; + unsigned char ch; + char name[255]; + unsigned int namelen = 0; + + for (;;) { + if (pos >= len) goto PROTO; ch = buf[pos++]; + if (++loop >= 1000) goto PROTO; + + if (state) { + if (namelen + 1 > sizeof name) goto PROTO; name[namelen++] = ch; + --state; + } + else { + while (ch >= 192) { + where = ch; where -= 192; where <<= 8; + if (pos >= len) goto PROTO; ch = buf[pos++]; + if (!firstcompress) firstcompress = pos; + pos = where + ch; + if (pos >= len) goto PROTO; ch = buf[pos++]; + if (++loop >= 1000) goto PROTO; + } + if (ch >= 64) goto PROTO; + if (namelen + 1 > sizeof name) goto PROTO; name[namelen++] = ch; + if (!ch) break; + state = ch; + } + } + + if (!dns_domain_copy(d,name)) return 0; + + if (firstcompress) return firstcompress; + return pos; + + PROTO: + errno = error_proto; + return 0; +} diff --git a/dns_random.c b/dns_random.c new file mode 100644 index 0000000..b9892b4 --- /dev/null +++ b/dns_random.c @@ -0,0 +1,62 @@ +#include "dns.h" +#include "taia.h" +#include "uint32.h" + +static uint32 seed[32]; +static uint32 in[12]; +static uint32 out[8]; +static int outleft = 0; + +#define ROTATE(x,b) (((x) << (b)) | ((x) >> (32 - (b)))) +#define MUSH(i,b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x,b)); + +static void surf(void) +{ + uint32 t[12]; uint32 x; uint32 sum = 0; + int r; int i; int loop; + + for (i = 0;i < 12;++i) t[i] = in[i] ^ seed[12 + i]; + for (i = 0;i < 8;++i) out[i] = seed[24 + i]; + x = t[11]; + for (loop = 0;loop < 2;++loop) { + for (r = 0;r < 16;++r) { + sum += 0x9e3779b9; + MUSH(0,5) MUSH(1,7) MUSH(2,9) MUSH(3,13) + MUSH(4,5) MUSH(5,7) MUSH(6,9) MUSH(7,13) + MUSH(8,5) MUSH(9,7) MUSH(10,9) MUSH(11,13) + } + for (i = 0;i < 8;++i) out[i] ^= t[i + 4]; + } +} + +void dns_random_init(char data[128]) +{ + int i; + struct taia t; + char tpack[16]; + + for (i = 0;i < 32;++i) + uint32_unpack(data + 4 * i,seed + i); + + taia_now(&t); + taia_pack(tpack,&t); + for (i = 0;i < 4;++i) + uint32_unpack(tpack + 4 * i,in + 4 + i); + + in[8] = getpid(); + in[9] = getppid(); + /* more space in 10 and 11, but this is probably enough */ +} + +unsigned int dns_random(unsigned int n) +{ + if (!n) return 0; + + if (!outleft) { + if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3]; + surf(); + outleft = 8; + } + + return out[--outleft] % n; +} diff --git a/dns_rcip.c b/dns_rcip.c new file mode 100644 index 0000000..2356c8b --- /dev/null +++ b/dns_rcip.c @@ -0,0 +1,82 @@ +#include "taia.h" +#include "openreadclose.h" +#include "byte.h" +#include "ip4.h" +#include "env.h" +#include "dns.h" + +static stralloc data = {0}; + +static int init(char ip[64]) +{ + int i; + int j; + int iplen = 0; + char *x; + + x = env_get("DNSCACHEIP"); + if (x) + while (iplen <= 60) + if (*x == '.') + ++x; + else { + i = ip4_scan(x,ip + iplen); + if (!i) break; + x += i; + iplen += 4; + } + + if (!iplen) { + i = openreadclose("/etc/resolv.conf",&data,64); + if (i == -1) return -1; + if (i) { + if (!stralloc_append(&data,"\n")) return -1; + i = 0; + for (j = 0;j < data.len;++j) + if (data.s[j] == '\n') { + if (byte_equal("nameserver ",11,data.s + i) || byte_equal("nameserver\t",11,data.s + i)) { + i += 10; + while ((data.s[i] == ' ') || (data.s[i] == '\t')) + ++i; + if (iplen <= 60) + if (ip4_scan(data.s + i,ip + iplen)) + iplen += 4; + } + i = j + 1; + } + } + } + + if (!iplen) { + byte_copy(ip,4,"\177\0\0\1"); + iplen = 4; + } + byte_zero(ip + iplen,64 - iplen); + return 0; +} + +static int ok = 0; +static unsigned int uses; +static struct taia deadline; +static char ip[64]; /* defined if ok */ + +int dns_resolvconfip(char s[64]) +{ + struct taia now; + + taia_now(&now); + if (taia_less(&deadline,&now)) ok = 0; + if (!uses) ok = 0; + + if (!ok) { + if (init(ip) == -1) return -1; + taia_uint(&deadline,600); + taia_add(&deadline,&now,&deadline); + uses = 10000; + ok = 1; + } + + --uses; + byte_copy(s,64,ip); + return 0; +} diff --git a/dns_rcrw.c b/dns_rcrw.c new file mode 100644 index 0000000..6f215ac --- /dev/null +++ b/dns_rcrw.c @@ -0,0 +1,130 @@ +#include "taia.h" +#include "env.h" +#include "byte.h" +#include "str.h" +#include "openreadclose.h" +#include "dns.h" + +static stralloc data = {0}; + +static int init(stralloc *rules) +{ + char host[256]; + char *x; + int i; + int j; + int k; + + if (!stralloc_copys(rules,"")) return -1; + + x = env_get("DNSREWRITEFILE"); + if (!x) x = "/etc/dnsrewrite"; + + i = openreadclose(x,&data,64); + if (i == -1) return -1; + + if (i) { + if (!stralloc_append(&data,"\n")) return -1; + i = 0; + for (j = 0;j < data.len;++j) + if (data.s[j] == '\n') { + if (!stralloc_catb(rules,data.s + i,j - i)) return -1; + while (rules->len) { + if (rules->s[rules->len - 1] != ' ') + if (rules->s[rules->len - 1] != '\t') + if (rules->s[rules->len - 1] != '\r') + break; + --rules->len; + } + if (!stralloc_0(rules)) return -1; + i = j + 1; + } + return 0; + } + + x = env_get("LOCALDOMAIN"); + if (x) { + if (!stralloc_copys(&data,x)) return -1; + if (!stralloc_append(&data," ")) return -1; + if (!stralloc_copys(rules,"?:")) return -1; + i = 0; + for (j = 0;j < data.len;++j) + if (data.s[j] == ' ') { + if (!stralloc_cats(rules,"+.")) return -1; + if (!stralloc_catb(rules,data.s + i,j - i)) return -1; + i = j + 1; + } + if (!stralloc_0(rules)) return -1; + if (!stralloc_cats(rules,"*.:")) return -1; + if (!stralloc_0(rules)) return -1; + return 0; + } + + i = openreadclose("/etc/resolv.conf",&data,64); + if (i == -1) return -1; + + if (i) { + if (!stralloc_append(&data,"\n")) return -1; + i = 0; + for (j = 0;j < data.len;++j) + if (data.s[j] == '\n') { + if (byte_equal("search ",7,data.s + i) || byte_equal("search\t",7,data.s + i) || byte_equal("domain ",7,data.s + i) || byte_equal("domain\t",7,data.s + i)) { + if (!stralloc_copys(rules,"?:")) return -1; + i += 7; + while (i < j) { + k = byte_chr(data.s + i,j - i,' '); + k = byte_chr(data.s + i,k,'\t'); + if (!k) { ++i; continue; } + if (!stralloc_cats(rules,"+.")) return -1; + if (!stralloc_catb(rules,data.s + i,k)) return -1; + i += k; + } + if (!stralloc_0(rules)) return -1; + if (!stralloc_cats(rules,"*.:")) return -1; + if (!stralloc_0(rules)) return -1; + return 0; + } + i = j + 1; + } + } + + host[0] = 0; + if (gethostname(host,sizeof host) == -1) return -1; + host[(sizeof host) - 1] = 0; + i = str_chr(host,'.'); + if (host[i]) { + if (!stralloc_copys(rules,"?:")) return -1; + if (!stralloc_cats(rules,host + i)) return -1; + if (!stralloc_0(rules)) return -1; + } + if (!stralloc_cats(rules,"*.:")) return -1; + if (!stralloc_0(rules)) return -1; + + return 0; +} + +static int ok = 0; +static unsigned int uses; +static struct taia deadline; +static stralloc rules = {0}; /* defined if ok */ + +int dns_resolvconfrewrite(stralloc *out) +{ + struct taia now; + + taia_now(&now); + if (taia_less(&deadline,&now)) ok = 0; + if (!uses) ok = 0; + + if (!ok) { + if (init(&rules) == -1) return -1; + taia_uint(&deadline,600); + taia_add(&deadline,&now,&deadline); + uses = 10000; + ok = 1; + } + + --uses; + if (!stralloc_copy(out,&rules)) return -1; + return 0; +} diff --git a/dns_resolve.c b/dns_resolve.c new file mode 100644 index 0000000..3365c00 --- /dev/null +++ b/dns_resolve.c @@ -0,0 +1,29 @@ +#include "iopause.h" +#include "taia.h" +#include "byte.h" +#include "dns.h" + +struct dns_transmit dns_resolve_tx = {0}; + +int dns_resolve(char *q,char qtype[2]) +{ + struct taia stamp; + struct taia deadline; + char servers[64]; + iopause_fd x[1]; + int r; + + if (dns_resolvconfip(servers) == -1) return -1; + if (dns_transmit_start(&dns_resolve_tx,servers,1,q,qtype,"\0\0\0\0") == -1) return -1; + + for (;;) { + taia_now(&stamp); + taia_uint(&deadline,120); + taia_add(&deadline,&deadline,&stamp); + dns_transmit_io(&dns_resolve_tx,x,&deadline); + iopause(x,1,&deadline,&stamp); + r = dns_transmit_get(&dns_resolve_tx,x,&stamp); + if (r == -1) return -1; + if (r == 1) return 0; + } +} diff --git a/dns_sortip.c b/dns_sortip.c new file mode 100644 index 0000000..af9b235 --- /dev/null +++ b/dns_sortip.c @@ -0,0 +1,20 @@ +#include "byte.h" +#include "dns.h" + +/* XXX: sort servers by configurable notion of closeness? */ +/* XXX: pay attention to competence of each server? */ + +void dns_sortip(char *s,unsigned int n) +{ + unsigned int i; + char tmp[4]; + + n >>= 2; + while (n > 1) { + i = dns_random(n); + --n; + byte_copy(tmp,4,s + (i << 2)); + byte_copy(s + (i << 2),4,s + (n << 2)); + byte_copy(s + (n << 2),4,tmp); + } +} diff --git a/dns_transmit.c b/dns_transmit.c new file mode 100644 index 0000000..df12826 --- /dev/null +++ b/dns_transmit.c @@ -0,0 +1,364 @@ +#include "socket.h" +#include "alloc.h" +#include "error.h" +#include "byte.h" +#include "readwrite.h" +#include "uint16.h" +#include "dns.h" + +static int serverwantstcp(char *buf,unsigned int len) +{ + char out[12]; + + if (!dns_packet_copy(buf,len,0,out,12)) return 1; + if (out[2] & 2) return 1; + return 0; +} + +static int serverfailed(char *buf,unsigned int len) +{ + char out[12]; + unsigned int rcode; + + if (!dns_packet_copy(buf,len,0,out,12)) return 1; + rcode = out[3]; + rcode &= 15; + if (rcode && (rcode != 3)) { errno = error_again; return 1; } + return 0; +} + +static int irrelevant(struct dns_transmit *d,char *buf,unsigned int len) +{ + char out[12]; + char *dn; + unsigned int pos; + + pos = dns_packet_copy(buf,len,0,out,12); if (!pos) return 1; + if (byte_diff(out,2,d->query + 2)) return 1; + if (out[4] != 0) return 1; + if (out[5] != 1) return 1; + + dn = 0; + pos = dns_packet_getname(buf,len,pos,&dn); if (!pos) return 1; + if (!dns_domain_equal(dn,d->query + 14)) { alloc_free(dn); return 1; } + alloc_free(dn); + + pos = dns_packet_copy(buf,len,pos,out,4); if (!pos) return 1; + if (byte_diff(out,2,d->qtype)) return 1; + if (byte_diff(out + 2,2,DNS_C_IN)) return 1; + + return 0; +} + +static void packetfree(struct dns_transmit *d) +{ + if (!d->packet) return; + alloc_free(d->packet); + d->packet = 0; +} + +static void queryfree(struct dns_transmit *d) +{ + if (!d->query) return; + alloc_free(d->query); + d->query = 0; +} + +static void socketfree(struct dns_transmit *d) +{ + if (!d->s1) return; + close(d->s1 - 1); + d->s1 = 0; +} + +void dns_transmit_free(struct dns_transmit *d) +{ + queryfree(d); + socketfree(d); + packetfree(d); +} + +static int randombind(struct dns_transmit *d) +{ + int j; + + for (j = 0;j < 10;++j) + if (socket_bind4(d->s1 - 1,d->localip,1025 + dns_random(64510)) == 0) + return 0; + if (socket_bind4(d->s1 - 1,d->localip,0) == 0) + return 0; + return -1; +} + +static const int timeouts[4] = { 1, 3, 11, 45 }; + +static int thisudp(struct dns_transmit *d) +{ + char *ip; + + socketfree(d); + + while (d->udploop < 4) { + for (;d->curserver < 16;++d->curserver) { + ip = d->servers + 4 * d->curserver; + if (byte_diff(ip,4,"\0\0\0\0")) { + d->query[2] = dns_random(256); + d->query[3] = dns_random(256); + + d->s1 = 1 + socket_udp(); + if (!d->s1) { dns_transmit_free(d); return -1; } + if (randombind(d) == -1) { dns_transmit_free(d); return -1; } + + if (socket_connect4(d->s1 - 1,ip,53) == 0) + if (send(d->s1 - 1,d->query + 2,d->querylen - 2,0) == d->querylen - 2) { + struct taia now; + taia_now(&now); + taia_uint(&d->deadline,timeouts[d->udploop]); + taia_add(&d->deadline,&d->deadline,&now); + d->tcpstate = 0; + return 0; + } + + socketfree(d); + } + } + + ++d->udploop; + d->curserver = 0; + } + + dns_transmit_free(d); return -1; +} + +static int firstudp(struct dns_transmit *d) +{ + d->curserver = 0; + return thisudp(d); +} + +static int nextudp(struct dns_transmit *d) +{ + ++d->curserver; + return thisudp(d); +} + +static int thistcp(struct dns_transmit *d) +{ + struct taia now; + char *ip; + + socketfree(d); + packetfree(d); + + for (;d->curserver < 16;++d->curserver) { + ip = d->servers + 4 * d->curserver; + if (byte_diff(ip,4,"\0\0\0\0")) { + d->query[2] = dns_random(256); + d->query[3] = dns_random(256); + + d->s1 = 1 + socket_tcp(); + if (!d->s1) { dns_transmit_free(d); return -1; } + if (randombind(d) == -1) { dns_transmit_free(d); return -1; } + + taia_now(&now); + taia_uint(&d->deadline,10); + taia_add(&d->deadline,&d->deadline,&now); + if (socket_connect4(d->s1 - 1,ip,53) == 0) { + d->tcpstate = 2; + return 0; + } + if ((errno == error_inprogress) || (errno == error_wouldblock)) { + d->tcpstate = 1; + return 0; + } + + socketfree(d); + } + } + + dns_transmit_free(d); return -1; +} + +static int firsttcp(struct dns_transmit *d) +{ + d->curserver = 0; + return thistcp(d); +} + +static int nexttcp(struct dns_transmit *d) +{ + ++d->curserver; + return thistcp(d); +} + +int dns_transmit_start(struct dns_transmit *d,char servers[64],int flagrecursive,char *q,char qtype[2],char localip[4]) +{ + unsigned int len; + + dns_transmit_free(d); + errno = error_io; + + len = dns_domain_length(q); + d->querylen = len + 18; + d->query = alloc(d->querylen); + if (!d->query) return -1; + + uint16_pack_big(d->query,len + 16); + byte_copy(d->query + 2,12,flagrecursive ? "\0\0\1\0\0\1\0\0\0\0\0\0" : "\0\0\0\0\0\1\0\0\0\0\0\0gcc-bug-workaround"); + byte_copy(d->query + 14,len,q); + byte_copy(d->query + 14 + len,2,qtype); + byte_copy(d->query + 16 + len,2,DNS_C_IN); + + byte_copy(d->qtype,2,qtype); + d->servers = servers; + byte_copy(d->localip,4,localip); + + d->udploop = flagrecursive ? 1 : 0; + + if (len + 16 > 512) return firsttcp(d); + return firstudp(d); +} + +void dns_transmit_io(struct dns_transmit *d,iopause_fd *x,struct taia *deadline) +{ + x->fd = d->s1 - 1; + + switch(d->tcpstate) { + case 0: case 3: case 4: case 5: + x->events = IOPAUSE_READ; + break; + case 1: case 2: + x->events = IOPAUSE_WRITE; + break; + } + + if (taia_less(&d->deadline,deadline)) + *deadline = d->deadline; +} + +int dns_transmit_get(struct dns_transmit *d,iopause_fd *x,struct taia *when) +{ + char udpbuf[513]; + unsigned char ch; + int r; + int fd; + + errno = error_io; + fd = d->s1 - 1; + + if (!x->revents) { + if (taia_less(when,&d->deadline)) return 0; + errno = error_timeout; + if (d->tcpstate == 0) return nextudp(d); + return nexttcp(d); + } + + if (d->tcpstate == 0) { +/* +have attempted to send UDP query to each server udploop times +have sent query to curserver on UDP socket s +*/ + r = recv(fd,udpbuf,sizeof udpbuf,0); + if (r <= 0) { + if (d->udploop == 2) return 0; + return nextudp(d); + } + if (r + 1 > sizeof udpbuf) return 0; + + if (irrelevant(d,udpbuf,r)) return 0; + if (serverwantstcp(udpbuf,r)) return firsttcp(d); + if (serverfailed(udpbuf,r)) { + if (d->udploop == 2) return 0; + return nextudp(d); + } + socketfree(d); + + d->packetlen = r; + d->packet = alloc(d->packetlen); + if (!d->packet) { dns_transmit_free(d); return -1; } + byte_copy(d->packet,d->packetlen,udpbuf); + queryfree(d); + return 1; + } + + if (d->tcpstate == 1) { +/* +have sent connection attempt to curserver on TCP socket s +pos not defined +*/ + if (!socket_connected(fd)) return nexttcp(d); + d->pos = 0; + d->tcpstate = 2; + return 0; + } + + if (d->tcpstate == 2) { +/* +have connection to curserver on TCP socket s +have sent pos bytes of query +*/ + r = write(fd,d->query + d->pos,d->querylen - d->pos); + if (r <= 0) return nexttcp(d); + d->pos += r; + if (d->pos == d->querylen) { + struct taia now; + taia_now(&now); + taia_uint(&d->deadline,10); + taia_add(&d->deadline,&d->deadline,&now); + d->tcpstate = 3; + } + return 0; + } + + if (d->tcpstate == 3) { +/* +have sent entire query to curserver on TCP socket s +pos not defined +*/ + r = read(fd,&ch,1); + if (r <= 0) return nexttcp(d); + d->packetlen = ch; + d->tcpstate = 4; + return 0; + } + + if (d->tcpstate == 4) { +/* +have sent entire query to curserver on TCP socket s +pos not defined +have received one byte of packet length into packetlen +*/ + r = read(fd,&ch,1); + if (r <= 0) return nexttcp(d); + d->packetlen <<= 8; + d->packetlen += ch; + d->tcpstate = 5; + d->pos = 0; + d->packet = alloc(d->packetlen); + if (!d->packet) { dns_transmit_free(d); return -1; } + return 0; + } + + if (d->tcpstate == 5) { +/* +have sent entire query to curserver on TCP socket s +have received entire packet length into packetlen +packet is allocated +have received pos bytes of packet +*/ + r = read(fd,d->packet + d->pos,d->packetlen - d->pos); + if (r <= 0) return nexttcp(d); + d->pos += r; + if (d->pos < d->packetlen) return 0; + + socketfree(d); + if (irrelevant(d,d->packet,d->packetlen)) return nexttcp(d); + if (serverwantstcp(d->packet,d->packetlen)) return nexttcp(d); + if (serverfailed(d->packet,d->packetlen)) return nexttcp(d); + + queryfree(d); + return 1; + } + + return 0; +} diff --git a/dns_txt.c b/dns_txt.c new file mode 100644 index 0000000..263b641 --- /dev/null +++ b/dns_txt.c @@ -0,0 +1,59 @@ +#include "stralloc.h" +#include "uint16.h" +#include "byte.h" +#include "dns.h" + +int dns_txt_packet(stralloc *out,char *buf,unsigned int len) +{ + unsigned int pos; + char header[12]; + uint16 numanswers; + uint16 datalen; + char ch; + unsigned int txtlen; + int i; + + if (!stralloc_copys(out,"")) return -1; + + pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; + uint16_unpack_big(header + 6,&numanswers); + pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; + pos += 4; + + while (numanswers--) { + pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; + pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; + uint16_unpack_big(header + 8,&datalen); + if (byte_equal(header,2,DNS_T_TXT)) + if (byte_equal(header + 2,2,DNS_C_IN)) { + if (pos + datalen > len) return -1; + txtlen = 0; + for (i = 0;i < datalen;++i) { + ch = buf[pos + i]; + if (!txtlen) + txtlen = (unsigned char) ch; + else { + --txtlen; + if (ch < 32) ch = '?'; + if (ch > 126) ch = '?'; + if (!stralloc_append(out,&ch)) return -1; + } + } + } + pos += datalen; + } + + return 0; +} + +static char *q = 0; + +int dns_txt(stralloc *out,stralloc *fqdn) +{ + if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; + if (dns_resolve(q,DNS_T_TXT) == -1) return -1; + if (dns_txt_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; + dns_transmit_free(&dns_resolve_tx); + dns_domain_free(&q); + return 0; +} @@ -1,31 +0,0 @@ -.TH env 3 -.SH NAME -env \- manage the environment -.SH SYNTAX -.B #include <env.h> - -char **\fBenviron\fP; - -char *\fBenv_get\fP(\fIname\fR); -.br -char *\fBenv_pick\fP(); - -char *\fIname\fR; -.SH DESCRIPTION -The environment, -.BR environ , -is a 0-terminated array of 0-terminated strings, -called environment variables. -Each environment variable is of the form -.IR name\fB=\fIvalue . - -.B env_get -returns the value of the first variable whose name is -.IR name , -or 0 if there is no such variable. - -.B env_pick -returns any variable in the environment, -or 0 if the environment is empty. -.SH "SEE ALSO" -environ(7) @@ -1,113 +1,15 @@ -/* env.c, envread.c, env.h: environ library -Daniel J. Bernstein, djb@silverton.berkeley.edu. -Depends on str.h, alloc.h. -Requires environ. -19960113: rewrite. warning: interface is different. -No known patent problems. -*/ - #include "str.h" -#include "alloc.h" #include "env.h" -int env_isinit = 0; /* if env_isinit: */ -static int ea; /* environ is a pointer to ea+1 char*'s. */ -static int en; /* the first en of those are ALLOCATED. environ[en] is 0. */ - -static void env_goodbye(i) int i; -{ - alloc_free(environ[i]); - environ[i] = environ[--en]; - environ[en] = 0; -} - -static char *null = 0; - -void env_clear() +extern /*@null@*/char *env_get(char *s) { - if (env_isinit) while (en) env_goodbye(0); - else environ = &null; -} - -static void env_unsetlen(s,len) char *s; int len; -{ - int i; - for (i = en - 1;i >= 0;--i) - if (!str_diffn(s,environ[i],len)) - if (environ[i][len] == '=') - env_goodbye(i); -} + int i; + unsigned int len; -int env_unset(s) char *s; -{ - if (!env_isinit) if (!env_init()) return 0; - env_unsetlen(s,str_len(s)); - return 1; -} - -static int env_add(s) char *s; -{ - char *t; - t = env_findeq(s); - if (t) env_unsetlen(s,t - s); - if (en == ea) - { - ea += 30; - if (!alloc_re(&environ,(en + 1) * sizeof(char *),(ea + 1) * sizeof(char *))) - { ea = en; return 0; } - } - environ[en++] = s; - environ[en] = 0; - return 1; -} - -int env_put(s) char *s; -{ - char *u; - if (!env_isinit) if (!env_init()) return 0; - u = alloc(str_len(s) + 1); - if (!u) return 0; - str_copy(u,s); - if (!env_add(u)) { alloc_free(u); return 0; } - return 1; -} - -int env_put2(s,t) char *s; char *t; -{ - char *u; - int slen; - if (!env_isinit) if (!env_init()) return 0; - slen = str_len(s); - u = alloc(slen + str_len(t) + 2); - if (!u) return 0; - str_copy(u,s); - u[slen] = '='; - str_copy(u + slen + 1,t); - if (!env_add(u)) { alloc_free(u); return 0; } - return 1; -} - -int env_init() -{ - char **newenviron; - int i; - for (en = 0;environ[en];++en) ; - ea = en + 10; - newenviron = (char **) alloc((ea + 1) * sizeof(char *)); - if (!newenviron) return 0; - for (en = 0;environ[en];++en) - { - newenviron[en] = alloc(str_len(environ[en]) + 1); - if (!newenviron[en]) - { - for (i = 0;i < en;++i) alloc_free(newenviron[i]); - alloc_free(newenviron); - return 0; - } - str_copy(newenviron[en],environ[en]); - } - newenviron[en] = 0; - environ = newenviron; - env_isinit = 1; - return 1; + if (!s) return 0; + len = str_len(s); + for (i = 0;environ[i];++i) + if (str_start(environ[i],s) && (environ[i][len] == '=')) + return environ[i] + len + 1; + return 0; } @@ -1,17 +1,8 @@ #ifndef ENV_H #define ENV_H -extern int env_isinit; - -extern int env_init(); -extern int env_put(); -extern int env_put2(); -extern int env_unset(); -extern /*@null@*/char *env_get(); -extern char *env_pick(); -extern void env_clear(); -extern char *env_findeq(); - extern char **environ; +extern /*@null@*/char *env_get(char *); + #endif diff --git a/envread.c b/envread.c deleted file mode 100644 index 80185de..0000000 --- a/envread.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "env.h" -#include "str.h" - -extern /*@null@*/char *env_get(s) -char *s; -{ - int i; - unsigned int slen; - char *envi; - - slen = str_len(s); - for (i = 0;envi = environ[i];++i) - if ((!str_diffn(s,envi,slen)) && (envi[slen] == '=')) - return envi + slen + 1; - return 0; -} - -extern char *env_pick() -{ - return environ[0]; -} - -extern char *env_findeq(s) -char *s; -{ - for (;*s;++s) - if (*s == '=') - return s; - return 0; -} diff --git a/error.3 b/error.3 deleted file mode 100644 index e955b35..0000000 --- a/error.3 +++ /dev/null @@ -1,45 +0,0 @@ -.TH error 3 -.SH NAME -error \- syscall error codes -.SH SYNTAX -.B #include <error.h> - -extern int \fBerrno\fP; - -extern int \fBerror_intr\fP; -.br -extern int \fBerror_nomem\fP; -.br -extern int \fBerror_noent\fP; -.br -extern int \fBerror_txtbsy\fP; -.br -extern int \fBerror_io\fP; -.br -extern int \fBerror_exist\fP; -.br -extern int \fBerror_timeout\fP; -.br -extern int \fBerror_inprogress\fP; -.br -extern int \fBerror_wouldblock\fP; -.br -extern int \fBerror_again\fP; -.br -extern int \fBerror_pipe\fP; -.br -extern int \fBerror_perm\fP; -.br -extern int \fBerror_acces\fP; -.SH DESCRIPTION -UNIX syscalls provide detailed error codes in the -.B errno -variable. -The -.B error -library provides portable names for a variety of possible -.B errno -values. -.SH "SEE ALSO" -error_str(3), -error_temp(3) @@ -93,3 +93,24 @@ EACCES; #else -13; #endif + +int error_nodevice = +#ifdef ENXIO +ENXIO; +#else +-14; +#endif + +int error_proto = +#ifdef EPROTO +EPROTO; +#else +-15; +#endif + +int error_isdir = +#ifdef EISDIR +EISDIR; +#else +-16; +#endif @@ -16,8 +16,11 @@ extern int error_again; extern int error_pipe; extern int error_perm; extern int error_acces; +extern int error_nodevice; +extern int error_proto; +extern int error_isdir; -extern char *error_str(); -extern int error_temp(); +extern char *error_str(int); +extern int error_temp(int); #endif diff --git a/error_str.3 b/error_str.3 deleted file mode 100644 index 62043c4..0000000 --- a/error_str.3 +++ /dev/null @@ -1,19 +0,0 @@ -.TH error_str 3 -.SH NAME -error_str \- names for syscall error codes -.SH SYNTAX -.B #include <error.h> - -char *\fBerror_str\fP(\fIe\fR); - -int \fIe\fR; -.SH DESCRIPTION -.B error_str -returns a printable string describing syscall error code -.IR e . -Normally -.I e -is -.BR errno . -.SH "SEE ALSO" -error(3) diff --git a/error_str.c b/error_str.c index 804d1fa..c999ab0 100644 --- a/error_str.c +++ b/error_str.c @@ -3,8 +3,7 @@ #define X(e,s) if (i == e) return s; -char *error_str(i) -int i; +char *error_str(int i) { X(0,"no error") X(error_intr,"interrupted system call") @@ -20,12 +19,12 @@ int i; X(error_pipe,"broken pipe") X(error_perm,"permission denied") X(error_acces,"access denied") + X(error_nodevice,"device not configured") + X(error_proto,"protocol error") + X(error_isdir,"is a directory") #ifdef ESRCH X(ESRCH,"no such process") #endif -#ifdef ENXIO - X(ENXIO,"device not configured") -#endif #ifdef E2BIG X(E2BIG,"argument list too long") #endif @@ -59,9 +58,6 @@ int i; #ifdef ENOTDIR X(ENOTDIR,"not a directory") #endif -#ifdef EISDIR - X(EISDIR,"is a directory") -#endif #ifdef EINVAL X(EINVAL,"invalid argument") #endif @@ -263,9 +259,6 @@ int i; #ifdef ECOMM X(ECOMM,"communication error") #endif -#ifdef EPROTO - X(EPROTO,"protocol error") -#endif #ifdef EMULTIHOP X(EMULTIHOP,"multihop attempted") #endif @@ -1,7 +1,7 @@ #ifndef FD_H #define FD_H -extern int fd_copy(); -extern int fd_move(); +extern int fd_copy(int,int); +extern int fd_move(int,int); #endif diff --git a/fd_copy.3 b/fd_copy.3 deleted file mode 100644 index 758a7e7..0000000 --- a/fd_copy.3 +++ /dev/null @@ -1,44 +0,0 @@ -.TH fd_copy 3 -.SH NAME -fd_copy \- duplicate a descriptor -.SH SYNTAX -.B #include <fd.h> - -int \fBfd_copy\fP(\fIto\fR,\fIfrom\fR); - -int \fIto\fR; -.br -int \fIfrom\fR; -.SH DESCRIPTION -.B fd_copy -copies -descriptor -.I from -to descriptor -.IR to . -If -.I to -was already open, -.B fd_copy -closes it. -.B fd_copy -always leaves -.I from -intact; -if -.I to -and -.I from -are the same number, -.B fd_copy -does nothing. - -.B fd_copy -returns 0 on success, -1 on error. -.B fd_copy -does not guarantee that -.I to -will remain open, if it was open, in case of error. -.SH "SEE ALSO" -dup(2), -fd_move(3) @@ -1,9 +1,7 @@ #include <fcntl.h> #include "fd.h" -int fd_copy(to,from) -int to; -int from; +int fd_copy(int to,int from) { if (to == from) return 0; if (fcntl(from,F_GETFL,0) == -1) return -1; diff --git a/fd_move.3 b/fd_move.3 deleted file mode 100644 index 94aa1b7..0000000 --- a/fd_move.3 +++ /dev/null @@ -1,41 +0,0 @@ -.TH fd_move 3 -.SH NAME -fd_move \- renumber a descriptor -.SH SYNTAX -.B #include <fd.h> - -int \fBfd_move\fP(\fIto\fR,\fIfrom\fR); - -int \fIto\fR; -.br -int \fIfrom\fR; -.SH DESCRIPTION -.B fd_move -moves -descriptor -.I from -to descriptor -.IR to . -If -.I to -was already open, -.B fd_move -closes it. -If the move is successful, -.B fd_move -closes -.IR from . -Exception: -if -.I to -and -.I from -are the same number, -.B fd_move -does nothing. - -.B fd_move -returns 0 on success, -1 on error. -.SH "SEE ALSO" -dup(2), -fd_copy(3) @@ -1,8 +1,6 @@ #include "fd.h" -int fd_move(to,from) -int to; -int from; +int fd_move(int to,int from) { if (to == from) return 0; if (fd_copy(to,from) == -1) return -1; diff --git a/find-systype.sh b/find-systype.sh index 16266d3..0955c32 100644 --- a/find-systype.sh +++ b/find-systype.sh @@ -15,6 +15,7 @@ # the idea here is to include ALL useful available information. exec 2>/dev/null + sys="`uname -s | tr '/:[A-Z]' '..[a-z]'`" if [ x"$sys" != x ] then @@ -141,4 +142,18 @@ i686) chip=ppro esac +if $CC -c x86cpuid.c +then + if $LD -o x86cpuid x86cpuid.o + then + x86cpuid="`./x86cpuid | tr /: ..`" + case "$x86cpuid" in + ?*) + chip="$x86cpuid" + ;; + esac + fi +fi +rm -f x86cpuid x86cpuid.o + echo "$oper-:$arch-:$syst-:$chip-:$kern-" | tr ' [A-Z]' '.[a-z]' diff --git a/finger@.1 b/finger@.1 deleted file mode 100644 index 93b6288..0000000 --- a/finger@.1 +++ /dev/null @@ -1,45 +0,0 @@ -.TH finger@ 1 -.SH NAME -finger@ \- get user information from a host -.SH SYNTAX -.B finger@ -[ -.I host -[ -.I user -] -] -.SH DESCRIPTION -.B finger@ -connects to TCP port 79 (Finger) on -.IR host , -sends -.I user -(with an extra CR) -to -.IR host , -and prints any data it receives. -It removes CR and converts unprintable characters to a visible format. -Some computers respond to port 79 with information about -.IR user . - -If -.I user -is not supplied, -.B finger@ -sends a blank line to -.IR host . -Some computers respond with information about -all the users who are logged in. - -If -.I host -is not supplied, -.B finger@ -connects to the local host. -.SH "SEE ALSO" -addcr(1), -cat(1), -delcr(1), -finger(1), -tcpclient(1) diff --git a/fixcr.1 b/fixcr.1 deleted file mode 100644 index ebb8b53..0000000 --- a/fixcr.1 +++ /dev/null @@ -1,11 +0,0 @@ -.TH fixcr 1 -.SH NAME -fixcr \- make sure that there is a CR before each LF -.SH SYNOPSIS -.B fixcr -.SH DESCRIPTION -.B fixcr -inserts CR at the end of each line of input where a CR is not already present. -It does not insert CR at the end of a partial final line. -.SH "SEE ALSO" -addcr(1) diff --git a/fixcr.c b/fixcr.c deleted file mode 100644 index 02b4d7f..0000000 --- a/fixcr.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "substdio.h" -#include "subfd.h" -#include "exit.h" - -void main() -{ - register int n; - register char *x; - char ch; - char lastch = 0; - - for (;;) { - n = substdio_feed(subfdin); - if (n < 0) _exit(111); - if (!n) _exit(0); - x = substdio_PEEK(subfdin); - substdio_SEEK(subfdin,n); - while (n > 0) { - ch = *x++; --n; - if (ch == '\n') if (lastch != '\r') substdio_BPUTC(subfdout,"\r"[0]); - substdio_BPUTC(subfdout,ch); - lastch = ch; - } - } -} diff --git a/fixcrio.c b/fixcrio.c new file mode 100644 index 0000000..dbd4fa4 --- /dev/null +++ b/fixcrio.c @@ -0,0 +1,161 @@ +#include "sig.h" +#include "buffer.h" +#include "strerr.h" +#include "byte.h" +#include "readwrite.h" +#include "exit.h" +#include "iopause.h" +#include "pathexec.h" + +#define FATAL "fixcrio: fatal: " + +char prebuf[256]; + +int leftstatus = 0; +char leftbuf[512]; +int leftlen; +int leftpos; +int leftflagcr = 0; + +int rightstatus = 0; +char rightbuf[512]; +int rightlen; +int rightpos; +int rightflagcr = 0; + +void doit(int fdleft,int fdright) +{ + struct taia stamp; + struct taia deadline; + iopause_fd x[4]; + int xlen; + iopause_fd *io0; + iopause_fd *ioleft; + iopause_fd *io1; + iopause_fd *ioright; + int r; + int i; + char ch; + + for (;;) { + xlen = 0; + + io0 = 0; + if (leftstatus == 0) { + io0 = &x[xlen++]; + io0->fd = 0; + io0->events = IOPAUSE_READ; + } + ioleft = 0; + if (leftstatus == 1) { + ioleft = &x[xlen++]; + ioleft->fd = fdleft; + ioleft->events = IOPAUSE_WRITE; + } + + ioright = 0; + if (rightstatus == 0) { + ioright = &x[xlen++]; + ioright->fd = fdright; + ioright->events = IOPAUSE_READ; + } + io1 = 0; + if (rightstatus == 1) { + io1 = &x[xlen++]; + io1->fd = 1; + io1->events = IOPAUSE_WRITE; + } + + taia_now(&stamp); + taia_uint(&deadline,3600); + taia_add(&deadline,&stamp,&deadline); + iopause(x,xlen,&deadline,&stamp); + + if (io0 && io0->revents) { + r = read(0,prebuf,sizeof prebuf); + if (r <= 0) { + leftstatus = -1; + close(fdleft); + } + else { + leftstatus = 1; + leftpos = 0; + leftlen = 0; + for (i = 0;i < r;++i) { + ch = prebuf[i]; + if (ch == '\n') + if (!leftflagcr) + leftbuf[leftlen++] = '\r'; + leftbuf[leftlen++] = ch; + leftflagcr = (ch == '\r'); + } + } + } + + if (ioleft && ioleft->revents) { + r = write(fdleft,leftbuf + leftpos,leftlen - leftpos); + if (r == -1) break; + leftpos += r; + if (leftpos == leftlen) leftstatus = 0; + } + + if (ioright && ioright->revents) { + r = read(fdright,prebuf,sizeof prebuf); + if (r <= 0) break; + rightstatus = 1; + rightpos = 0; + rightlen = 0; + for (i = 0;i < r;++i) { + ch = prebuf[i]; + if (ch == '\n') + if (!rightflagcr) + rightbuf[rightlen++] = '\r'; + rightbuf[rightlen++] = ch; + rightflagcr = (ch == '\r'); + } + } + + if (io1 && io1->revents) { + r = write(1,rightbuf + rightpos,rightlen - rightpos); + if (r == -1) break; + rightpos += r; + if (rightpos == rightlen) rightstatus = 0; + } + } + + _exit(0); +} + +main(int argc,char **argv,char **envp) +{ + int piin[2]; + int piout[2]; + + if (argc < 2) + strerr_die1x(100,"fixcrio: usage: fixcrio program [ arg ... ]"); + + if (pipe(piin) == -1) + strerr_die2sys(111,FATAL,"unable to create pipe: "); + if (pipe(piout) == -1) + strerr_die2sys(111,FATAL,"unable to create pipe: "); + + switch(fork()) { + case -1: + strerr_die2sys(111,FATAL,"unable to fork: "); + case 0: + sig_ignore(sig_pipe); + close(piin[0]); + close(piout[1]); + doit(piin[1],piout[0]); + } + + close(piin[1]); + close(piout[0]); + if (fd_move(0,piin[0]) == -1) + strerr_die2sys(111,FATAL,"unable to move descriptors: "); + if (fd_move(1,piout[1]) == -1) + strerr_die2sys(111,FATAL,"unable to move descriptors: "); + + pathexec_run(argv[1],argv + 1,envp); + strerr_die4sys(111,FATAL,"unable to run ",argv[1],": "); +} @@ -4,22 +4,22 @@ #define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */ #define FMT_LEN ((char *) 0) /* convenient abbreviation */ -extern unsigned int fmt_uint(); -extern unsigned int fmt_uint0(); -extern unsigned int fmt_xint(); -extern unsigned int fmt_nbbint(); -extern unsigned int fmt_ushort(); -extern unsigned int fmt_xshort(); -extern unsigned int fmt_nbbshort(); -extern unsigned int fmt_ulong(); -extern unsigned int fmt_xlong(); -extern unsigned int fmt_nbblong(); +extern unsigned int fmt_uint(char *,unsigned int); +extern unsigned int fmt_uint0(char *,unsigned int,unsigned int); +extern unsigned int fmt_xint(char *,unsigned int); +extern unsigned int fmt_nbbint(char *,unsigned int,unsigned int,unsigned int,unsigned int); +extern unsigned int fmt_ushort(char *,unsigned short); +extern unsigned int fmt_xshort(char *,unsigned short); +extern unsigned int fmt_nbbshort(char *,unsigned int,unsigned int,unsigned int,unsigned short); +extern unsigned int fmt_ulong(char *,unsigned long); +extern unsigned int fmt_xlong(char *,unsigned long); +extern unsigned int fmt_nbblong(char *,unsigned int,unsigned int,unsigned int,unsigned long); -extern unsigned int fmt_plusminus(); -extern unsigned int fmt_minus(); -extern unsigned int fmt_0x(); +extern unsigned int fmt_plusminus(char *,int); +extern unsigned int fmt_minus(char *,int); +extern unsigned int fmt_0x(char *,int); -extern unsigned int fmt_str(); -extern unsigned int fmt_strn(); +extern unsigned int fmt_str(char *,char *); +extern unsigned int fmt_strn(char *,char *,unsigned int); #endif diff --git a/fmt_str.c b/fmt_str.c deleted file mode 100644 index 48930cf..0000000 --- a/fmt_str.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "fmt.h" - -unsigned int fmt_str(s,t) -register char *s; register char *t; -{ - register unsigned int len; - char ch; - len = 0; - if (s) { while (ch = t[len]) s[len++] = ch; } - else while (t[len]) len++; - return len; -} diff --git a/fmt_ulong.c b/fmt_ulong.c index ab12e8c..db48bfd 100644 --- a/fmt_ulong.c +++ b/fmt_ulong.c @@ -1,6 +1,6 @@ #include "fmt.h" -unsigned int fmt_ulong(s,u) register char *s; register unsigned long u; +unsigned int fmt_ulong(register char *s,register unsigned long u) { register unsigned int len; register unsigned long q; len = 1; q = u; @@ -0,0 +1,9 @@ +#ifndef FORK_H +#define FORK_H + +/* sysdep: -vfork */ + +extern int fork(); +#define vfork fork + +#endif @@ -0,0 +1,9 @@ +#ifndef FORK_H +#define FORK_H + +/* sysdep: +vfork */ + +extern int fork(); +extern int vfork(); + +#endif diff --git a/gen_allocdefs.h b/gen_allocdefs.h index 783a9b1..d025b27 100644 --- a/gen_allocdefs.h +++ b/gen_allocdefs.h @@ -2,7 +2,7 @@ #define GEN_ALLOC_DEFS_H #define GEN_ALLOC_ready(ta,type,field,len,a,i,n,x,base,ta_ready) \ -int ta_ready(x,n) register ta *x; register unsigned int n; \ +int ta_ready(register ta *x,register unsigned int n) \ { register unsigned int i; \ if (x->field) { \ i = x->a; \ @@ -15,7 +15,7 @@ int ta_ready(x,n) register ta *x; register unsigned int n; \ return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); } #define GEN_ALLOC_readyplus(ta,type,field,len,a,i,n,x,base,ta_rplus) \ -int ta_rplus(x,n) register ta *x; register unsigned int n; \ +int ta_rplus(register ta *x,register unsigned int n) \ { register unsigned int i; \ if (x->field) { \ i = x->a; n += x->len; \ @@ -28,7 +28,7 @@ int ta_rplus(x,n) register ta *x; register unsigned int n; \ return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); } #define GEN_ALLOC_append(ta,type,field,len,a,i,n,x,base,ta_rplus,ta_append) \ -int ta_append(x,i) register ta *x; register type *i; \ +int ta_append(register ta *x,register type *i) \ { if (!ta_rplus(x,1)) return 0; x->field[x->len++] = *i; return 1; } #endif diff --git a/getln.3 b/getln.3 deleted file mode 100644 index ffe1953..0000000 --- a/getln.3 +++ /dev/null @@ -1,51 +0,0 @@ -.TH getln 3 -.SH NAME -getln \- read one line of data -.SH SYNTAX -.B #include <getln.h> - -int \fBgetln\fP(&\fIss\fR,&\fIsa\fR,&\fImatch\fR,\fIsep\fR); - -substdio \fIss\fR; -.br -stralloc \fIsa\fR; -.br -int \fImatch\fR; -.br -int \fIsep\fR; -.SH DESCRIPTION -.B getln -reads a line of characters, terminated by a -.I sep -character, -from -.IR ss . -It returns the line in -.I sa -and sets -.I match -to 1. - -If -.B getln -sees end-of-input before it sees -.IR sep , -it returns the partial line in -.I sa -and sets -.I match -to 0. - -.B getln -normally returns 0. -If it runs out of memory, -or encounters an error from -.IR ss , -it returns -1, -setting -.B errno -appropriately. -.SH "SEE ALSO" -stralloc(3), -substdio(3), -getln2(3) @@ -1,13 +1,7 @@ -#include "substdio.h" #include "byte.h" -#include "stralloc.h" #include "getln.h" -int getln(ss,sa,match,sep) -register substdio *ss; -register stralloc *sa; -int *match; -int sep; +int getln(buffer *ss,stralloc *sa,int *match,int sep) { char *cont; unsigned int clen; @@ -1,7 +1,10 @@ #ifndef GETLN_H #define GETLN_H -extern int getln(); -extern int getln2(); +#include "buffer.h" +#include "stralloc.h" + +extern int getln(buffer *,stralloc *,int *,int); +extern int getln2(buffer *,stralloc *,char **,unsigned int *,int); #endif diff --git a/getln2.3 b/getln2.3 deleted file mode 100644 index f95105a..0000000 --- a/getln2.3 +++ /dev/null @@ -1,64 +0,0 @@ -.TH getln2 3 -.SH NAME -getln2 \- read one line of data -.SH SYNTAX -.B #include <getln.h> - -int \fBgetln2\fP(&\fIss\fR,&\fIsa\fR,&\fIcont\fR,&\fIclen\fR,\fIsep\fR); - -substdio \fIss\fR; -.br -stralloc \fIsa\fR; -.br -char *\fIcont\fR; -.br -unsigned int \fIclen\fR; -.br -int \fIsep\fR; -.SH DESCRIPTION -.B getln2 -reads a line of characters, terminated by a -.I sep -character, -from -.IR ss . - -The line is returned in two pieces. -The first piece is stored in -.IR sa . -The second piece is -.IR cont , -a pointer to -.I clen -characters inside the -.I ss -buffer. -The second piece must be copied somewhere else -before -.I ss -is used again. - -If -.B getln2 -sees end-of-input before it sees -.IR sep , -it sets -.I clen -to 0 and does not set -.IR cont . -It puts the partial line into -.IR sa . - -.B getln2 -normally returns 0. -If it runs out of memory, -or encounters an error from -.IR ss , -it returns -1, -setting -.B errno -appropriately. -.SH "SEE ALSO" -stralloc(3), -substdio(3), -getln(3) @@ -1,14 +1,7 @@ -#include "substdio.h" -#include "stralloc.h" #include "byte.h" #include "getln.h" -int getln2(ss,sa,cont,clen,sep) -register substdio *ss; -register stralloc *sa; -/*@out@*/char **cont; -/*@out@*/unsigned int *clen; -int sep; +int getln2(buffer *ss,stralloc *sa,char **cont,unsigned int *clen,int sep) { register char *x; register unsigned int i; @@ -18,14 +11,14 @@ int sep; sa->len = 0; for (;;) { - n = substdio_feed(ss); + n = buffer_feed(ss); if (n < 0) return -1; if (n == 0) { *clen = 0; return 0; } - x = substdio_PEEK(ss); + x = buffer_PEEK(ss); i = byte_chr(x,n,sep); - if (i < n) { substdio_SEEK(ss,*clen = i + 1); *cont = x; return 0; } + if (i < n) { buffer_SEEK(ss,*clen = i + 1); *cont = x; return 0; } if (!stralloc_readyplus(sa,n)) return -1; i = sa->len; - sa->len = i + substdio_get(ss,sa->s + i,n); + sa->len = i + buffer_get(ss,sa->s + i,n); } } diff --git a/hassgact.h1 b/hassgact.h1 new file mode 100644 index 0000000..03c7a9f --- /dev/null +++ b/hassgact.h1 @@ -0,0 +1 @@ +/* sysdep: -sigaction */ diff --git a/hassgact.h2 b/hassgact.h2 new file mode 100644 index 0000000..594d486 --- /dev/null +++ b/hassgact.h2 @@ -0,0 +1,2 @@ +/* sysdep: +sigaction */ +#define HASSIGACTION 1 diff --git a/hassgprm.h1 b/hassgprm.h1 new file mode 100644 index 0000000..4c05fd1 --- /dev/null +++ b/hassgprm.h1 @@ -0,0 +1 @@ +/* sysdep: -sigprocmask */ diff --git a/hassgprm.h2 b/hassgprm.h2 new file mode 100644 index 0000000..d959bc7 --- /dev/null +++ b/hassgprm.h2 @@ -0,0 +1,2 @@ +/* sysdep: +sigprocmask */ +#define HASSIGPROCMASK 1 diff --git a/hasshsgr.h1 b/hasshsgr.h1 new file mode 100644 index 0000000..d11c988 --- /dev/null +++ b/hasshsgr.h1 @@ -0,0 +1 @@ +/* sysdep: -shortsetgroups */ diff --git a/hasshsgr.h2 b/hasshsgr.h2 new file mode 100644 index 0000000..db6a830 --- /dev/null +++ b/hasshsgr.h2 @@ -0,0 +1,2 @@ +/* sysdep: +shortsetgroups */ +#define HASSHORTSETGROUPS 1 diff --git a/haswaitp.h1 b/haswaitp.h1 new file mode 100644 index 0000000..469a7ad --- /dev/null +++ b/haswaitp.h1 @@ -0,0 +1 @@ +/* sysdep: -waitpid */ diff --git a/haswaitp.h2 b/haswaitp.h2 new file mode 100644 index 0000000..a75823a --- /dev/null +++ b/haswaitp.h2 @@ -0,0 +1,2 @@ +/* sysdep: +waitpid */ +#define HASWAITPID 1 @@ -3,61 +3,23 @@ void hier() { h(auto_home,-1,-1,02755); - d(auto_home,"bin",-1,-1,02755); - d(auto_home,"man",-1,-1,02755); - d(auto_home,"man/man1",-1,-1,02755); - d(auto_home,"man/cat1",-1,-1,02755); - d(auto_home,"man/man5",-1,-1,02755); - d(auto_home,"man/cat5",-1,-1,02755); - c(auto_home,"bin","tcpclient",-1,-1,0711); - c(auto_home,"bin","tcpserver",-1,-1,0711); - c(auto_home,"bin","tcprules",-1,-1,0711); - c(auto_home,"bin","tcprulescheck",-1,-1,0711); - c(auto_home,"bin","fixcr",-1,-1,0711); - c(auto_home,"bin","addcr",-1,-1,0711); - c(auto_home,"bin","delcr",-1,-1,0711); + c(auto_home,"bin","tcpserver",-1,-1,0755); + c(auto_home,"bin","tcprules",-1,-1,0755); + c(auto_home,"bin","tcprulescheck",-1,-1,0755); + c(auto_home,"bin","argv0",-1,-1,0755); + c(auto_home,"bin","recordio",-1,-1,0755); + c(auto_home,"bin","tcpclient",-1,-1,0755); c(auto_home,"bin","who@",-1,-1,0755); c(auto_home,"bin","date@",-1,-1,0755); c(auto_home,"bin","finger@",-1,-1,0755); c(auto_home,"bin","http@",-1,-1,0755); c(auto_home,"bin","tcpcat",-1,-1,0755); c(auto_home,"bin","mconnect",-1,-1,0755); - c(auto_home,"bin","mconnect-io",-1,-1,0711); - c(auto_home,"bin","argv0",-1,-1,0711); - c(auto_home,"bin","recordio",-1,-1,0711); - - c(auto_home,"man/man1","tcpclient.1",-1,-1,0644); - c(auto_home,"man/cat1","tcpclient.0",-1,-1,0644); - c(auto_home,"man/man1","tcpserver.1",-1,-1,0644); - c(auto_home,"man/cat1","tcpserver.0",-1,-1,0644); - c(auto_home,"man/man1","tcprules.1",-1,-1,0644); - c(auto_home,"man/cat1","tcprules.0",-1,-1,0644); - c(auto_home,"man/man1","tcprulescheck.1",-1,-1,0644); - c(auto_home,"man/cat1","tcprulescheck.0",-1,-1,0644); - c(auto_home,"man/man1","fixcr.1",-1,-1,0644); - c(auto_home,"man/cat1","fixcr.0",-1,-1,0644); - c(auto_home,"man/man1","addcr.1",-1,-1,0644); - c(auto_home,"man/cat1","addcr.0",-1,-1,0644); - c(auto_home,"man/man1","delcr.1",-1,-1,0644); - c(auto_home,"man/cat1","delcr.0",-1,-1,0644); - c(auto_home,"man/man1","who@.1",-1,-1,0644); - c(auto_home,"man/cat1","who@.0",-1,-1,0644); - c(auto_home,"man/man1","date@.1",-1,-1,0644); - c(auto_home,"man/cat1","date@.0",-1,-1,0644); - c(auto_home,"man/man1","finger@.1",-1,-1,0644); - c(auto_home,"man/cat1","finger@.0",-1,-1,0644); - c(auto_home,"man/man1","http@.1",-1,-1,0644); - c(auto_home,"man/cat1","http@.0",-1,-1,0644); - c(auto_home,"man/man1","tcpcat.1",-1,-1,0644); - c(auto_home,"man/cat1","tcpcat.0",-1,-1,0644); - c(auto_home,"man/man1","mconnect.1",-1,-1,0644); - c(auto_home,"man/cat1","mconnect.0",-1,-1,0644); - c(auto_home,"man/man1","argv0.1",-1,-1,0644); - c(auto_home,"man/cat1","argv0.0",-1,-1,0644); - c(auto_home,"man/man1","recordio.1",-1,-1,0644); - c(auto_home,"man/cat1","recordio.0",-1,-1,0644); - c(auto_home,"man/man5","tcp-environ.5",-1,-1,0644); - c(auto_home,"man/cat5","tcp-environ.0",-1,-1,0644); + c(auto_home,"bin","mconnect-io",-1,-1,0755); + c(auto_home,"bin","addcr",-1,-1,0755); + c(auto_home,"bin","delcr",-1,-1,0755); + c(auto_home,"bin","fixcrio",-1,-1,0755); + c(auto_home,"bin","rblsmtpd",-1,-1,0755); } diff --git a/http@.1 b/http@.1 deleted file mode 100644 index 4861b34..0000000 --- a/http@.1 +++ /dev/null @@ -1,52 +0,0 @@ -.TH http@ 1 -.SH NAME -http@ \- get a web page from a host through HTTP -.SH SYNTAX -.B http@ -[ -.I host -[ -.I page -[ -.I port -] -] -] -.SH DESCRIPTION -.B http@ -connects to -.I port -on -.IR host , -sends -.B GET /\fIpage -(with an extra CR) -to -.IR host , -and prints any data it receives, -removing CR from the end of each line. - -If -.I port -is not supplied, -.B http@ -uses port 80 (HTTP). - -If -.I page -is not supplied, -.B http@ -sends -.B GET / -to -.IR host . - -If -.I host -is not supplied, -.B http@ -connects to the local host. -.SH "SEE ALSO" -addcr(1), -delcr(1), -tcpclient(1) @@ -1,4 +1,6 @@ -echo "GET /${2-}" | HOME/bin/tcpclient -RHl0 -- "${1-0}" "${3-80}" sh -c ' +echo "GET /${2-} HTTP/1.0 +Host: ${1-0}:${3-80} +" | HOME/bin/tcpclient -RHl0 -- "${1-0}" "${3-80}" sh -c ' HOME/bin/addcr >&7 exec HOME/bin/delcr <&6 -' +' | awk '/^$/ { body=1; next } { if (body) print }' @@ -1,4 +1,4 @@ -#include "substdio.h" +#include "buffer.h" #include "strerr.h" #include "error.h" #include "open.h" @@ -44,10 +44,10 @@ int mode; strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",subdir,": "); } -char inbuf[SUBSTDIO_INSIZE]; -char outbuf[SUBSTDIO_OUTSIZE]; -substdio ssin; -substdio ssout; +char inbuf[BUFFER_INSIZE]; +char outbuf[BUFFER_OUTSIZE]; +buffer ssin; +buffer ssout; void c(home,subdir,file,uid,gid,mode) char *home; @@ -66,7 +66,7 @@ int mode; fdin = open_read(file); if (fdin == -1) strerr_die4sys(111,FATAL,"unable to read ",file,": "); - substdio_fdbuf(&ssin,read,fdin,inbuf,sizeof inbuf); + buffer_init(&ssin,read,fdin,inbuf,sizeof inbuf); if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); @@ -76,9 +76,9 @@ int mode; fdout = open_trunc(file); if (fdout == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); - substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof outbuf); + buffer_init(&ssout,write,fdout,outbuf,sizeof outbuf); - switch(substdio_copy(&ssout,&ssin)) { + switch(buffer_copy(&ssout,&ssin)) { case -2: strerr_die4sys(111,FATAL,"unable to read ",file,": "); case -3: @@ -86,7 +86,7 @@ int mode; } close(fdin); - if (substdio_flush(&ssout) == -1) + if (buffer_flush(&ssout) == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); if (fsync(fdout) == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); @@ -118,13 +118,13 @@ int mode; fdout = open_trunc(file); if (fdout == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); - substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof outbuf); + buffer_init(&ssout,write,fdout,outbuf,sizeof outbuf); while (len-- > 0) - if (substdio_put(&ssout,"",1) == -1) + if (buffer_put(&ssout,"",1) == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); - if (substdio_flush(&ssout) == -1) + if (buffer_flush(&ssout) == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); if (fsync(fdout) == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); @@ -137,7 +137,7 @@ int mode; strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": "); } -void main() +main() { fdsourcedir = open_read("."); if (fdsourcedir == -1) diff --git a/instcheck.c b/instcheck.c index d41efda..c945e67 100644 --- a/instcheck.c +++ b/instcheck.c @@ -101,7 +101,7 @@ int mode; perm("",home,"/",file,S_IFREG,uid,gid,mode); } -void main() +main() { hier(); _exit(0); diff --git a/iopause.c b/iopause.c new file mode 100644 index 0000000..b8034de --- /dev/null +++ b/iopause.c @@ -0,0 +1,76 @@ +#include "taia.h" +#include "select.h" +#include "iopause.h" + +void iopause(iopause_fd *x,unsigned int len,struct taia *deadline,struct taia *stamp) +{ + struct taia t; + int millisecs; + double d; + int i; + + if (taia_less(deadline,stamp)) + millisecs = 0; + else { + t = *stamp; + taia_sub(&t,deadline,&t); + d = taia_approx(&t); + if (d > 1000.0) d = 1000.0; + millisecs = d * 1000.0 + 20.0; + } + + for (i = 0;i < len;++i) + x[i].revents = 0; + +#ifdef IOPAUSE_POLL + + poll(x,len,millisecs); + /* XXX: some kernels apparently need x[0] even if len is 0 */ + /* XXX: how to handle EAGAIN? are kernels really this dumb? */ + /* XXX: how to handle EINVAL? when exactly can this happen? */ + +#else +{ + + struct timeval tv; + fd_set rfds; + fd_set wfds; + int nfds; + int fd; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + + nfds = 1; + for (i = 0;i < len;++i) { + fd = x[i].fd; + if (fd < 0) continue; + if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/ + + if (fd >= nfds) nfds = fd + 1; + if (x[i].events & IOPAUSE_READ) FD_SET(fd,&rfds); + if (x[i].events & IOPAUSE_WRITE) FD_SET(fd,&wfds); + } + + tv.tv_sec = millisecs / 1000; + tv.tv_usec = 1000 * (millisecs % 1000); + + if (select(nfds,&rfds,&wfds,(fd_set *) 0,&tv) <= 0) + return; + /* XXX: for EBADF, could seek out and destroy the bad descriptor */ + + for (i = 0;i < len;++i) { + fd = x[i].fd; + if (fd < 0) continue; + if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/ + + if (x[i].events & IOPAUSE_READ) + if (FD_ISSET(fd,&rfds)) x[i].revents |= IOPAUSE_READ; + if (x[i].events & IOPAUSE_WRITE) + if (FD_ISSET(fd,&wfds)) x[i].revents |= IOPAUSE_WRITE; + } + +} +#endif + +} diff --git a/iopause.h1 b/iopause.h1 new file mode 100644 index 0000000..dae0a33 --- /dev/null +++ b/iopause.h1 @@ -0,0 +1,19 @@ +#ifndef IOPAUSE_H +#define IOPAUSE_H + +/* sysdep: -poll */ + +typedef struct { + int fd; + short events; + short revents; +} iopause_fd; + +#define IOPAUSE_READ 1 +#define IOPAUSE_WRITE 4 + +#include "taia.h" + +extern void iopause(iopause_fd *,unsigned int,struct taia *,struct taia *); + +#endif diff --git a/iopause.h2 b/iopause.h2 new file mode 100644 index 0000000..2cf5cf8 --- /dev/null +++ b/iopause.h2 @@ -0,0 +1,18 @@ +#ifndef IOPAUSE_H +#define IOPAUSE_H + +/* sysdep: +poll */ +#define IOPAUSE_POLL + +#include <sys/types.h> +#include <poll.h> + +typedef struct pollfd iopause_fd; +#define IOPAUSE_READ POLLIN +#define IOPAUSE_WRITE POLLOUT + +#include "taia.h" + +extern void iopause(iopause_fd *,unsigned int,struct taia *,struct taia *); + +#endif @@ -1,53 +0,0 @@ -#include "fmt.h" -#include "scan.h" -#include "ip.h" - -unsigned int ip_fmt(s,ip) -char *s; -struct ip_address *ip; -{ - unsigned int len; - unsigned int i; - - len = 0; - i = fmt_ulong(s,(unsigned long) ip->d[0]); len += i; if (s) s += i; - i = fmt_str(s,"."); len += i; if (s) s += i; - i = fmt_ulong(s,(unsigned long) ip->d[1]); len += i; if (s) s += i; - i = fmt_str(s,"."); len += i; if (s) s += i; - i = fmt_ulong(s,(unsigned long) ip->d[2]); len += i; if (s) s += i; - i = fmt_str(s,"."); len += i; if (s) s += i; - i = fmt_ulong(s,(unsigned long) ip->d[3]); len += i; if (s) s += i; - return len; -} - -unsigned int ip_scan(s,ip) -char *s; -struct ip_address *ip; -{ - unsigned int i; - unsigned int len; - unsigned long u; - - len = 0; - i = scan_ulong(s,&u); if (!i) return 0; ip->d[0] = u; s += i; len += i; - if (*s != '.') return 0; ++s; ++len; - i = scan_ulong(s,&u); if (!i) return 0; ip->d[1] = u; s += i; len += i; - if (*s != '.') return 0; ++s; ++len; - i = scan_ulong(s,&u); if (!i) return 0; ip->d[2] = u; s += i; len += i; - if (*s != '.') return 0; ++s; ++len; - i = scan_ulong(s,&u); if (!i) return 0; ip->d[3] = u; s += i; len += i; - return len; -} - -unsigned int ip_scanbracket(s,ip) -char *s; -struct ip_address *ip; -{ - unsigned int len; - - if (*s != '[') return 0; - len = ip_scan(s + 1,ip); - if (!len) return 0; - if (s[len + 1] != ']') return 0; - return len + 2; -} @@ -1,11 +0,0 @@ -#ifndef IP_H -#define IP_H - -struct ip_address { unsigned char d[4]; } ; - -extern unsigned int ip_fmt(); -#define IPFMT 19 -extern unsigned int ip_scan(); -extern unsigned int ip_scanbracket(); - -#endif @@ -0,0 +1,9 @@ +#ifndef IP4_H +#define IP4_H + +extern unsigned int ip4_scan(char *,char *); +extern unsigned int ip4_fmt(char *,char *); + +#define IP4_FMT 20 + +#endif diff --git a/ip4_fmt.c b/ip4_fmt.c new file mode 100644 index 0000000..c605634 --- /dev/null +++ b/ip4_fmt.c @@ -0,0 +1,18 @@ +#include "fmt.h" +#include "ip4.h" + +unsigned int ip4_fmt(char *s,char ip[4]) +{ + unsigned int len; + unsigned int i; + + len = 0; + i = fmt_ulong(s,(unsigned long) (unsigned char) ip[0]); len += i; if (s) s += i; + if (s) *s++ = '.'; ++len; + i = fmt_ulong(s,(unsigned long) (unsigned char) ip[1]); len += i; if (s) s += i; + if (s) *s++ = '.'; ++len; + i = fmt_ulong(s,(unsigned long) (unsigned char) ip[2]); len += i; if (s) s += i; + if (s) *s++ = '.'; ++len; + i = fmt_ulong(s,(unsigned long) (unsigned char) ip[3]); len += i; if (s) s += i; + return len; +} diff --git a/ip4_scan.c b/ip4_scan.c new file mode 100644 index 0000000..7a61371 --- /dev/null +++ b/ip4_scan.c @@ -0,0 +1,19 @@ +#include "scan.h" +#include "ip4.h" + +unsigned int ip4_scan(char *s,char ip[4]) +{ + unsigned int i; + unsigned int len; + unsigned long u; + + len = 0; + i = scan_ulong(s,&u); if (!i) return 0; ip[0] = u; s += i; len += i; + if (*s != '.') return 0; ++s; ++len; + i = scan_ulong(s,&u); if (!i) return 0; ip[1] = u; s += i; len += i; + if (*s != '.') return 0; ++s; ++len; + i = scan_ulong(s,&u); if (!i) return 0; ip[2] = u; s += i; len += i; + if (*s != '.') return 0; ++s; ++len; + i = scan_ulong(s,&u); if (!i) return 0; ip[3] = u; s += i; len += i; + return len; +} diff --git a/ipalloc.c b/ipalloc.c deleted file mode 100644 index 81792d5..0000000 --- a/ipalloc.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "alloc.h" -#include "gen_allocdefs.h" -#include "ip.h" -#include "ipalloc.h" - -GEN_ALLOC_readyplus(ipalloc,struct ip_mx,ix,len,a,i,n,x,10,ipalloc_readyplus) -GEN_ALLOC_append(ipalloc,struct ip_mx,ix,len,a,i,n,x,10,ipalloc_readyplus,ipalloc_append) diff --git a/ipalloc.h b/ipalloc.h deleted file mode 100644 index ad61475..0000000 --- a/ipalloc.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef IPALLOC_H -#define IPALLOC_H - -#include "ip.h" - -struct ip_mx { struct ip_address ip; int pref; } ; - -#include "gen_alloc.h" - -GEN_ALLOC_typedef(ipalloc,struct ip_mx,ix,len,a) -extern int ipalloc_readyplus(); -extern int ipalloc_append(); - -#endif diff --git a/mconnect-io.c b/mconnect-io.c index 6dce003..5cd4ada 100644 --- a/mconnect-io.c +++ b/mconnect-io.c @@ -1,51 +1,52 @@ -#include <signal.h> #include "sig.h" -#include "substdio.h" +#include "wait.h" +#include "fork.h" +#include "buffer.h" #include "strerr.h" #include "readwrite.h" #include "exit.h" char outbuf[512]; -substdio ssout; +buffer bout; char inbuf[512]; -substdio ssin; +buffer bin; -int myread(fd,buf,len) int fd; char *buf; int len; +int myread(int fd,char *buf,int len) { - substdio_flush(&ssout); + buffer_flush(&bout); return read(fd,buf,len); } -void main() +main() { int pid; int wstat; char ch; - sig_pipeignore(); + sig_ignore(sig_pipe); pid = fork(); if (pid == -1) strerr_die2sys(111,"mconnect-io: fatal: ","unable to fork: "); if (!pid) { - substdio_fdbuf(&ssin,myread,0,inbuf,sizeof inbuf); - substdio_fdbuf(&ssout,write,7,outbuf,sizeof outbuf); + buffer_init(&bin,myread,0,inbuf,sizeof inbuf); + buffer_init(&bout,write,7,outbuf,sizeof outbuf); - while (substdio_get(&ssin,&ch,1) == 1) { - if (ch == '\n') substdio_put(&ssout,"\r",1); - substdio_put(&ssout,&ch,1); + while (buffer_get(&bin,&ch,1) == 1) { + if (ch == '\n') buffer_put(&bout,"\r",1); + buffer_put(&bout,&ch,1); } _exit(0); } - substdio_fdbuf(&ssin,myread,6,inbuf,sizeof inbuf); - substdio_fdbuf(&ssout,write,1,outbuf,sizeof outbuf); + buffer_init(&bin,myread,6,inbuf,sizeof inbuf); + buffer_init(&bout,write,1,outbuf,sizeof outbuf); - while (substdio_get(&ssin,&ch,1) == 1) - substdio_put(&ssout,&ch,1); + while (buffer_get(&bin,&ch,1) == 1) + buffer_put(&bout,&ch,1); - kill(pid,SIGTERM); + kill(pid,sig_term); wait_pid(&wstat,pid); _exit(0); diff --git a/mconnect.1 b/mconnect.1 deleted file mode 100644 index 6648367..0000000 --- a/mconnect.1 +++ /dev/null @@ -1,36 +0,0 @@ -.TH mconnect 1 -.SH NAME -mconnect \- connect to the SMTP server on a host -.SH SYNTAX -.B mconnect -[ -.I host -[ -.I port -] -] -.SH DESCRIPTION -.B mconnect -connects to -.I port -on -.IR host . -It sends its input to -.IR host , -adding a CR to each line. -Meanwhile it prints anything it receives from -.IR host . - -If -.I port -is not supplied, -.B mconnect -uses port 25 (SMTP). - -If -.I host -is not supplied, -.B mconnect -connects to the local host. -.SH "SEE ALSO" -tcpclient(1) @@ -1,7 +1,7 @@ #ifndef NDELAY_H #define NDELAY_H -extern int ndelay_on(); -extern int ndelay_off(); +extern int ndelay_on(int); +extern int ndelay_off(int); #endif diff --git a/ndelay_off.c b/ndelay_off.c index 86f8fbf..9daa8cd 100644 --- a/ndelay_off.c +++ b/ndelay_off.c @@ -6,8 +6,7 @@ #define O_NONBLOCK O_NDELAY #endif -int ndelay_off(fd) -int fd; +int ndelay_off(int fd) { return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) & ~O_NONBLOCK); } @@ -6,8 +6,7 @@ #define O_NONBLOCK O_NDELAY #endif -int ndelay_on(fd) -int fd; +int ndelay_on(int fd) { return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) | O_NONBLOCK); } @@ -1,10 +1,10 @@ #ifndef OPEN_H #define OPEN_H -extern int open_read(); -extern int open_excl(); -extern int open_append(); -extern int open_trunc(); -extern int open_write(); +extern int open_read(char *); +extern int open_excl(char *); +extern int open_append(char *); +extern int open_trunc(char *); +extern int open_write(char *); #endif diff --git a/open_read.c b/open_read.c index f503e48..7f5ec8b 100644 --- a/open_read.c +++ b/open_read.c @@ -2,5 +2,5 @@ #include <fcntl.h> #include "open.h" -int open_read(fn) char *fn; +int open_read(char *fn) { return open(fn,O_RDONLY | O_NDELAY); } diff --git a/open_trunc.c b/open_trunc.c index e275085..77b99ef 100644 --- a/open_trunc.c +++ b/open_trunc.c @@ -2,5 +2,5 @@ #include <fcntl.h> #include "open.h" -int open_trunc(fn) char *fn; +int open_trunc(char *fn) { return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644); } diff --git a/open_write.c b/open_write.c new file mode 100644 index 0000000..531b8fe --- /dev/null +++ b/open_write.c @@ -0,0 +1,6 @@ +#include <sys/types.h> +#include <fcntl.h> +#include "open.h" + +int open_write(char *fn) +{ return open(fn,O_WRONLY | O_NDELAY); } diff --git a/openreadclose.c b/openreadclose.c new file mode 100644 index 0000000..d1e2086 --- /dev/null +++ b/openreadclose.c @@ -0,0 +1,16 @@ +#include "error.h" +#include "open.h" +#include "readclose.h" +#include "openreadclose.h" + +int openreadclose(char *fn,stralloc *sa,unsigned int bufsize) +{ + int fd; + fd = open_read(fn); + if (fd == -1) { + if (errno == error_noent) return 0; + return -1; + } + if (readclose(fd,sa,bufsize) == -1) return -1; + return 1; +} diff --git a/openreadclose.h b/openreadclose.h new file mode 100644 index 0000000..99688f4 --- /dev/null +++ b/openreadclose.h @@ -0,0 +1,8 @@ +#ifndef OPENREADCLOSE_H +#define OPENREADCLOSE_H + +#include "stralloc.h" + +extern int openreadclose(char *,stralloc *,unsigned int); + +#endif diff --git a/pathexec.h b/pathexec.h new file mode 100644 index 0000000..6fcbb89 --- /dev/null +++ b/pathexec.h @@ -0,0 +1,8 @@ +#ifndef PATHEXEC_H +#define PATHEXEC_H + +extern void pathexec_run(char *,char **,char **); +extern int pathexec_env(char *,char *); +extern void pathexec(char **); + +#endif diff --git a/pathexec_env.c b/pathexec_env.c new file mode 100644 index 0000000..48bba7e --- /dev/null +++ b/pathexec_env.c @@ -0,0 +1,68 @@ +#include "stralloc.h" +#include "alloc.h" +#include "str.h" +#include "byte.h" +#include "env.h" +#include "pathexec.h" + +static stralloc plus; +static stralloc tmp; + +int pathexec_env(char *s,char *t) +{ + if (!s) return 1; + if (!stralloc_copys(&tmp,s)) return 0; + if (t) { + if (!stralloc_cats(&tmp,"=")) return 0; + if (!stralloc_cats(&tmp,t)) return 0; + } + if (!stralloc_0(&tmp)) return 0; + return stralloc_cat(&plus,&tmp); +} + +void pathexec(char **argv) +{ + char *path; + char **e; + unsigned int elen; + unsigned int i; + unsigned int j; + unsigned int split; + unsigned int t; + + if (!stralloc_cats(&plus,"")) return; + + elen = 0; + for (i = 0;environ[i];++i) + ++elen; + for (i = 0;i < plus.len;++i) + if (!plus.s[i]) + ++elen; + + e = (char **) alloc((elen + 1) * sizeof(char *)); + if (!e) return; + + elen = 0; + for (i = 0;environ[i];++i) + e[elen++] = environ[i]; + + j = 0; + for (i = 0;i < plus.len;++i) + if (!plus.s[i]) { + split = str_chr(plus.s + j,'='); + for (t = 0;t < elen;++t) + if (byte_equal(plus.s + j,split,e[t])) + if (e[t][split] == '=') { + --elen; + e[t] = e[elen]; + break; + } + if (plus.s[j + split]) + e[elen++] = plus.s + j; + j = i + 1; + } + e[elen] = 0; + + pathexec_run(*argv,argv,e); + alloc_free(e); +} diff --git a/pathexec_run.c b/pathexec_run.c new file mode 100644 index 0000000..17837eb --- /dev/null +++ b/pathexec_run.c @@ -0,0 +1,46 @@ +#include "error.h" +#include "stralloc.h" +#include "str.h" +#include "env.h" +#include "pathexec.h" + +static stralloc tmp; + +void pathexec_run(char *file,char **argv,char **envp) +{ + char *path; + unsigned int split; + int savederrno; + + if (file[str_chr(file,'/')]) { + execve(file,argv,envp); + return; + } + + path = env_get("PATH"); + if (!path) path = "/bin:/usr/bin"; + + savederrno = 0; + for (;;) { + split = str_chr(path,':'); + if (!stralloc_copyb(&tmp,path,split)) return; + if (!split) + if (!stralloc_cats(&tmp,".")) return; + if (!stralloc_cats(&tmp,"/")) return; + if (!stralloc_cats(&tmp,file)) return; + if (!stralloc_0(&tmp)) return; + + execve(tmp.s,argv,envp); + if (errno != error_noent) { + savederrno = errno; + if ((errno != error_acces) && (errno != error_perm) && (errno != error_isdir)) return; + } + + if (!path[split]) { + if (savederrno) errno = savederrno; + return; + } + path += split; + path += 1; + } +} @@ -0,0 +1,19 @@ +#include "hasshsgr.h" +#include "prot.h" + +int prot_gid(int gid) +{ +#ifdef HASSHORTSETGROUPS + short x[2]; + x[0] = gid; x[1] = 73; /* catch errors */ + if (setgroups(1,x) == -1) return -1; +#else + if (setgroups(1,&gid) == -1) return -1; +#endif + return setgid(gid); /* _should_ be redundant, but on some systems it isn't */ +} + +int prot_uid(int uid) +{ + return setuid(uid); +} @@ -0,0 +1,7 @@ +#ifndef PROT_H +#define PROT_H + +extern int prot_gid(int); +extern int prot_uid(int); + +#endif diff --git a/rblsmtpd.c b/rblsmtpd.c new file mode 100644 index 0000000..9e3eb09 --- /dev/null +++ b/rblsmtpd.c @@ -0,0 +1,236 @@ +#include "byte.h" +#include "str.h" +#include "scan.h" +#include "fmt.h" +#include "env.h" +#include "exit.h" +#include "sig.h" +#include "buffer.h" +#include "readwrite.h" +#include "sgetopt.h" +#include "strerr.h" +#include "stralloc.h" +#include "commands.h" +#include "pathexec.h" +#include "dns.h" + +#define FATAL "rblsmtpd: fatal: " + +void nomem(void) +{ + strerr_die2x(111,FATAL,"out of memory"); +} +void usage(void) +{ + strerr_die1x(100,"rblsmtpd: usage: rblsmtpd [ -b ] [ -t timeout ] [ -r base ] [ -a base ] smtpd [ arg ... ]"); +} + +char *ip_env; +static stralloc ip_reverse; + +void ip_init(void) +{ + unsigned int i; + unsigned int j; + + ip_env = env_get("TCPREMOTEIP"); + if (!ip_env) ip_env = ""; + + if (!stralloc_copys(&ip_reverse,"")) nomem(); + + i = str_len(ip_env); + while (i) { + for (j = i;j > 0;--j) if (ip_env[j - 1] == '.') break; + if (!stralloc_catb(&ip_reverse,ip_env + j,i - j)) nomem(); + if (!stralloc_cats(&ip_reverse,".")) nomem(); + if (!j) break; + i = j - 1; + } +} + +unsigned long timeout = 60; +int flagrblbounce = 0; +int flagfailclosed = 0; +int flagmustnotbounce = 0; + +int decision = 0; /* 0 undecided, 1 accept, 2 reject, 3 bounce */ +static stralloc text; /* defined if decision is 2 or 3 */ + +static stralloc tmp; + +void rbl(char *base) +{ + int i; + char *altreply = 0; + if (decision) return; + if (!stralloc_copy(&tmp,&ip_reverse)) nomem(); + i = str_chr(base, ':'); + if (base[i]) { + base[i] = 0; + altreply = base+i+1; + } + if (!stralloc_cats(&tmp,base)) nomem(); + if (altreply) { + if (dns_ip4(&text,&tmp) == -1) { + flagmustnotbounce = 1; + if (flagfailclosed) { + if (!stralloc_copys(&text,"temporary RBL lookup error")) nomem(); + decision = 2; + } + return; + } + if (text.len) { + if(!stralloc_copys(&text, "")) nomem(); + while(*altreply) { + char *x; + i = str_chr(altreply, '%'); + if(!stralloc_catb(&text, altreply, i)) nomem(); + if(altreply[i] && + altreply[i+1]=='I' && + altreply[i+2]=='P' && + altreply[i+3]=='%') { + if(!stralloc_catb(&text, ip_env, str_len(ip_env))) nomem(); + altreply+=i+4; + } else if(altreply[i]) { + if(!stralloc_cats(&text, "%")) nomem(); + altreply+=i+1; + } else { + altreply+=i; + } + } + } + } else { + if (dns_txt(&text,&tmp) == -1) { + flagmustnotbounce = 1; + if (flagfailclosed) { + if (!stralloc_copys(&text,"temporary RBL lookup error")) nomem(); + decision = 2; + } + return; + } + } + if (text.len) + if (flagrblbounce) + decision = 3; + else + decision = 2; +} + +void antirbl(char *base) +{ + if (decision) return; + if (!stralloc_copy(&tmp,&ip_reverse)) nomem(); + if (!stralloc_cats(&tmp,base)) nomem(); + if (dns_ip4(&text,&tmp) == -1) { + flagmustnotbounce = 1; + if (!flagfailclosed) + decision = 1; + return; + } + if (text.len) + decision = 1; +} + +char strnum[FMT_ULONG]; +static stralloc message; + +char inspace[64]; buffer in = BUFFER_INIT(read,0,inspace,sizeof inspace); +char outspace[1]; buffer out = BUFFER_INIT(write,1,outspace,sizeof outspace); + +void reject() { buffer_putflush(&out,message.s,message.len); } +void accept() { buffer_putsflush(&out,"250 rblsmtpd.local\r\n"); } +void greet() { buffer_putsflush(&out,"220 rblsmtpd.local\r\n"); } +void quit() { buffer_putsflush(&out,"221 rblsmtpd.local\r\n"); _exit(0); } +void drop() { _exit(0); } + +struct commands smtpcommands[] = { + { "quit", quit, 0 } +, { "helo", accept, 0 } +, { "ehlo", accept, 0 } +, { "mail", accept, 0 } +, { "rset", accept, 0 } +, { "noop", accept, 0 } +, { 0, reject, 0 } +} ; + +void rblsmtpd(void) +{ + int i; + + if (flagmustnotbounce || (decision == 2)) { + if (!stralloc_copys(&message,"451 ")) nomem(); + } + else + if (!stralloc_copys(&message,"553 ")) nomem(); + + if (text.len > 200) text.len = 200; + if (!stralloc_cat(&message,&text)) nomem(); + for (i = 0;i < message.len;++i) + if ((message.s[i] < 32) || (message.s[i] > 126)) + message.s[i] = '?'; + + buffer_puts(buffer_2,"rblsmtpd: "); + buffer_puts(buffer_2,ip_env); + buffer_puts(buffer_2," pid "); + buffer_put(buffer_2,strnum,fmt_ulong(strnum,getpid())); + buffer_puts(buffer_2,": "); + buffer_put(buffer_2,message.s,message.len); + buffer_puts(buffer_2,"\n"); + buffer_flush(buffer_2); + + if (!stralloc_cats(&message,"\r\n")) nomem(); + + if (!timeout) + reject(); + else { + sig_catch(sig_alarm,drop); + alarm(timeout); + greet(); + commands(&in,smtpcommands); + } + _exit(0); +} + +main(int argc,char **argv,char **envp) +{ + int flagwantdefaultrbl = 1; + char *x; + int opt; + + ip_init(); + + x = env_get("RBLSMTPD"); + if (x) { + if (!*x) + decision = 1; + else if (*x == '-') { + if (!stralloc_copys(&text,x + 1)) nomem(); + decision = 3; + } + else { + if (!stralloc_copys(&text,x)) nomem(); + decision = 2; + } + } + + while ((opt = getopt(argc,argv,"bBcCt:r:a:")) != opteof) + switch(opt) { + case 'b': flagrblbounce = 1; break; + case 'B': flagrblbounce = 0; break; + case 'c': flagfailclosed = 1; break; + case 'C': flagfailclosed = 0; break; + case 't': scan_ulong(optarg,&timeout); break; + case 'r': rbl(optarg); flagwantdefaultrbl = 0; break; + case 'a': antirbl(optarg); break; + default: usage(); + } + + argv += optind; + if (!*argv) usage(); + + if (flagwantdefaultrbl) rbl("rbl.maps.vix.com"); + if (decision >= 2) rblsmtpd(); + + pathexec_run(*argv,argv,envp); + strerr_die4sys(111,FATAL,"unable to run ",*argv,": "); +} diff --git a/readclose.c b/readclose.c new file mode 100644 index 0000000..4265c06 --- /dev/null +++ b/readclose.c @@ -0,0 +1,21 @@ +#include "readwrite.h" +#include "error.h" +#include "readclose.h" + +int readclose_append(int fd,stralloc *sa,unsigned int bufsize) +{ + int r; + for (;;) { + if (!stralloc_readyplus(sa,bufsize)) { close(fd); return -1; } + r = read(fd,sa->s + sa->len,bufsize); + if (r == -1) if (errno == error_intr) continue; + if (r <= 0) { close(fd); return r; } + sa->len += r; + } +} + +int readclose(int fd,stralloc *sa,unsigned int bufsize) +{ + if (!stralloc_copys(sa,"")) { close(fd); return -1; } + return readclose_append(fd,sa,bufsize); +} diff --git a/readclose.h b/readclose.h new file mode 100644 index 0000000..49afd6c --- /dev/null +++ b/readclose.h @@ -0,0 +1,9 @@ +#ifndef READCLOSE_H +#define READCLOSE_H + +#include "stralloc.h" + +extern int readclose_append(int,stralloc *,unsigned int); +extern int readclose(int,stralloc *,unsigned int); + +#endif diff --git a/recordio.1 b/recordio.1 deleted file mode 100644 index e056776..0000000 --- a/recordio.1 +++ /dev/null @@ -1,75 +0,0 @@ -.TH recordio 1 -.SH NAME -recordio \- record the input and output of a program -.SH SYNTAX -.B recordio -.I program -[ -.I arg ... -] -.SH DESCRIPTION -.B recordio -runs -.I program -with the given arguments. -It prints lines to stderr -showing the input and output of -.IR program . - -At the beginning of each line on stderr, -.B recordio -inserts the -.I program -process ID, -along with -.B < -for input or -.B > -for output. -At the end of each line it inserts a space, a plus sign, or [EOF]; -a space indicates that there was a newline in the input or output, -and [EOF] indicates the end of input or output. - -.B recordio -prints every packet of input and output immediately. -It does not attempt to combine packets into coherent stderr lines. -For example, - -.EX - recordio sh -c 'cat /dev/fd/8 2>&1' > /dev/null -.EE - -could produce - -.EX - 5135 > cat: /dev/fd/8: Bad file descriptor -.br - 5135 > [EOF] -.EE - -or - -.EX - 5135 > cat: + -.br - 5135 > /dev/fd/8+ -.br - 5135 > : + -.br - 5135 > Bad file descriptor -.br - 5135 > [EOF] -.EE - -.B recordio -uses several lines for long packets -to guarantee that each line is printed atomically to stderr. - -.B recordio -runs as a child of -.IR program . -It exits when it sees the end of -.IR program 's -output. -.SH "SEE ALSO" -tcpserver(1) @@ -1,42 +1,40 @@ #include "sig.h" -#include "substdio.h" +#include "buffer.h" #include "strerr.h" #include "str.h" #include "byte.h" #include "readwrite.h" #include "exit.h" #include "fmt.h" -#include "select.h" +#include "iopause.h" +#include "pathexec.h" #define FATAL "recordio: fatal: " -char pid[FMT_ULONG + 10]; +char pid[FMT_ULONG]; char recordbuf[512]; -substdio ssrecord = SUBSTDIO_FDBUF(write,2,recordbuf,sizeof recordbuf); +buffer ssrecord = BUFFER_INIT(write,2,recordbuf,sizeof recordbuf); -void record(buf,len,direction) -char *buf; -int len; /* 1...256 */ -char *direction; +void record(char *buf,int len,char *direction) /* 1 <= len <= 256 */ { int i; while (len) { - substdio_puts(&ssrecord,pid); - substdio_puts(&ssrecord,direction); + buffer_puts(&ssrecord,pid); + buffer_puts(&ssrecord,direction); i = byte_chr(buf,len,'\n'); - substdio_put(&ssrecord,buf,i); + buffer_put(&ssrecord,buf,i); if (i == len) { - substdio_puts(&ssrecord,"+\n"); - substdio_flush(&ssrecord); + buffer_puts(&ssrecord,"+\n"); + buffer_flush(&ssrecord); return; } - substdio_puts(&ssrecord," \n"); - substdio_flush(&ssrecord); + buffer_puts(&ssrecord," \n"); + buffer_flush(&ssrecord); buf += i + 1; len -= i + 1; } @@ -52,41 +50,60 @@ char rightbuf[256]; int rightlen; int rightpos; -void doit(fdleft,fdright) -int fdleft; /* copy from 0 to fdleft */ -int fdright; /* copy from fdright to 1 */ +void doit(int fdleft,int fdright) /* copy 0 -> fdleft, copy fdright -> 1 */ { - fd_set rfds; - fd_set wfds; - int nfds; + struct taia stamp; + struct taia deadline; + iopause_fd x[4]; + int xlen; + iopause_fd *io0; + iopause_fd *ioleft; + iopause_fd *io1; + iopause_fd *ioright; int r; - nfds = 2; - if (nfds <= fdleft) nfds = fdleft + 1; - if (nfds <= fdright) nfds = fdright + 1; - /* XXX: will overflow select buf if too many fds are open */ - for (;;) { - FD_ZERO(&rfds); - FD_ZERO(&wfds); + xlen = 0; - if (leftstatus == 0) FD_SET(0,&rfds); - if (leftstatus == 1) FD_SET(fdleft,&wfds); + io0 = 0; + if (leftstatus == 0) { + io0 = &x[xlen++]; + io0->fd = 0; + io0->events = IOPAUSE_READ; + } + ioleft = 0; + if (leftstatus == 1) { + ioleft = &x[xlen++]; + ioleft->fd = fdleft; + ioleft->events = IOPAUSE_WRITE; + } - if (rightstatus == 0) FD_SET(fdright,&rfds); - if (rightstatus == 1) FD_SET(1,&wfds); + ioright = 0; + if (rightstatus == 0) { + ioright = &x[xlen++]; + ioright->fd = fdright; + ioright->events = IOPAUSE_READ; + } + io1 = 0; + if (rightstatus == 1) { + io1 = &x[xlen++]; + io1->fd = 1; + io1->events = IOPAUSE_WRITE; + } - if (select(nfds,&rfds,&wfds,(fd_set *) 0,(struct timeval *) 0) == -1) - continue; + taia_now(&stamp); + taia_uint(&deadline,3600); + taia_add(&deadline,&stamp,&deadline); + iopause(x,xlen,&deadline,&stamp); - if (FD_ISSET(0,&rfds)) { + if (io0 && io0->revents) { r = read(0,leftbuf,sizeof leftbuf); if (r <= 0) { leftstatus = -1; close(fdleft); - substdio_puts(&ssrecord,pid); - substdio_puts(&ssrecord," < [EOF]\n"); - substdio_flush(&ssrecord); + buffer_puts(&ssrecord,pid); + buffer_puts(&ssrecord," < [EOF]\n"); + buffer_flush(&ssrecord); } else { leftstatus = 1; leftpos = 0; leftlen = r; @@ -94,28 +111,26 @@ int fdright; /* copy from fdright to 1 */ } } - if (FD_ISSET(fdleft,&wfds)) { + if (ioleft && ioleft->revents) { r = write(fdleft,leftbuf + leftpos,leftlen - leftpos); if (r == -1) break; leftpos += r; if (leftpos == leftlen) leftstatus = 0; } - if (FD_ISSET(fdright,&rfds)) { + if (ioright && ioright->revents) { r = read(fdright,rightbuf,sizeof rightbuf); if (r <= 0) { - substdio_puts(&ssrecord,pid); - substdio_puts(&ssrecord," > [EOF]\n"); - substdio_flush(&ssrecord); + buffer_puts(&ssrecord,pid); + buffer_puts(&ssrecord," > [EOF]\n"); + buffer_flush(&ssrecord); break; } - else { - rightstatus = 1; rightpos = 0; rightlen = r; - record(rightbuf,r," > "); - } + rightstatus = 1; rightpos = 0; rightlen = r; + record(rightbuf,r," > "); } - if (FD_ISSET(1,&wfds)) { + if (io1 && io1->revents) { r = write(1,rightbuf + rightpos,rightlen - rightpos); if (r == -1) break; rightpos += r; @@ -126,14 +141,12 @@ int fdright; /* copy from fdright to 1 */ _exit(0); } -void main(argc,argv) -int argc; -char **argv; +main(int argc,char **argv,char **envp) { int piin[2]; int piout[2]; - pid[fmt_ulong(pid,(unsigned long) getpid())] = 0; + pid[fmt_ulong(pid,getpid())] = 0; if (argc < 2) strerr_die1x(100,"recordio: usage: recordio program [ arg ... ]"); @@ -147,7 +160,7 @@ char **argv; case -1: strerr_die2sys(111,FATAL,"unable to fork: "); case 0: - sig_pipeignore(); + sig_ignore(sig_pipe); close(piin[0]); close(piout[1]); doit(piin[1],piout[0]); @@ -160,6 +173,6 @@ char **argv; if (fd_move(1,piout[1]) == -1) strerr_die2sys(111,FATAL,"unable to move descriptors: "); - execvp(argv[1],argv + 1); + pathexec_run(argv[1],argv + 1,envp); strerr_die4sys(111,FATAL,"unable to run ",argv[1],": "); } diff --git a/remoteinfo.c b/remoteinfo.c index c7abd70..6c437c0 100644 --- a/remoteinfo.c +++ b/remoteinfo.c @@ -1,77 +1,98 @@ -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <fcntl.h> -#include "byte.h" -#include "substdio.h" -#include "ip.h" #include "fmt.h" +#include "buffer.h" +#include "socket.h" +#include "error.h" +#include "iopause.h" #include "timeoutconn.h" -#include "timeoutread.h" -#include "timeoutwrite.h" #include "remoteinfo.h" -static char line[999]; -static int t; +static struct taia now; +static struct taia deadline; -static int mywrite(fd,buf,len) int fd; char *buf; int len; +static int mywrite(int fd,char *buf,int len) { - return timeoutwrite(t,fd,buf,len); + iopause_fd x; + + x.fd = fd; + x.events = IOPAUSE_WRITE; + for (;;) { + taia_now(&now); + iopause(&x,1,&deadline,&now); + if (x.revents) break; + if (taia_less(&deadline,&now)) { + errno = error_timeout; + return -1; + } + } + return write(fd,buf,len); } -static int myread(fd,buf,len) int fd; char *buf; int len; + +static int myread(int fd,char *buf,int len) { - return timeoutread(t,fd,buf,len); + iopause_fd x; + + x.fd = fd; + x.events = IOPAUSE_READ; + for (;;) { + taia_now(&now); + iopause(&x,1,&deadline,&now); + if (x.revents) break; + if (taia_less(&deadline,&now)) { + errno = error_timeout; + return -1; + } + } + return read(fd,buf,len); } -char *remoteinfo_get(ipr,rp,ipl,lp,timeout) -struct ip_address *ipr; -unsigned long rp; -struct ip_address *ipl; -unsigned long lp; -int timeout; +static int doit(stralloc *out,int s,char ipremote[4],uint16 portremote,char iplocal[4],uint16 portlocal,unsigned int timeout) { - char *x; - int s; - struct sockaddr_in sin; - substdio ss; - char buf[32]; - unsigned int len; + buffer b; + char bspace[128]; + char strnum[FMT_ULONG]; int numcolons; char ch; - t = timeout; - - s = socket(AF_INET,SOCK_STREAM,0); - if (s == -1) return 0; - - byte_zero(&sin,sizeof(sin)); - sin.sin_family = AF_INET; - byte_copy(&sin.sin_addr,4,ipl); - sin.sin_port = 0; - if (bind(s,(struct sockaddr *) &sin,sizeof(sin)) == -1) { close(s); return 0; } - if (timeoutconn(s,ipr,113,timeout) == -1) { close(s); return 0; } - fcntl(s,F_SETFL,fcntl(s,F_GETFL,0) & ~O_NDELAY); - - len = 0; - len += fmt_ulong(line + len,rp); - len += fmt_str(line + len," , "); - len += fmt_ulong(line + len,lp); - len += fmt_str(line + len,"\r\n"); - - substdio_fdbuf(&ss,mywrite,s,buf,sizeof buf); - if (substdio_putflush(&ss,line,len) == -1) { close(s); return 0; } - - substdio_fdbuf(&ss,myread,s,buf,sizeof buf); - x = line; + if (socket_bind4(s,iplocal,0) == -1) return -1; + if (timeoutconn(s,ipremote,113,timeout) == -1) return -1; + + buffer_init(&b,mywrite,s,bspace,sizeof bspace); + buffer_put(&b,strnum,fmt_ulong(strnum,portremote)); + buffer_put(&b," , ",3); + buffer_put(&b,strnum,fmt_ulong(strnum,portlocal)); + buffer_put(&b,"\r\n",2); + if (buffer_flush(&b) == -1) return -1; + + buffer_init(&b,myread,s,bspace,sizeof bspace); numcolons = 0; for (;;) { - if (substdio_get(&ss,&ch,1) != 1) { close(s); return 0; } + if (buffer_get(&b,&ch,1) != 1) return -1; if ((ch == ' ') || (ch == '\t') || (ch == '\r')) continue; - if (ch == '\n') break; - if (numcolons < 3) { if (ch == ':') ++numcolons; } - else { *x++ = ch; if (x == line + sizeof(line) - 1) break; } + if (ch == '\n') return 0; + if (numcolons < 3) { + if (ch == ':') ++numcolons; + } + else { + if (!stralloc_append(out,&ch)) return -1; + if (out->len > 256) return 0; + } } - *x = 0; +} + +int remoteinfo(stralloc *out,char ipremote[4],uint16 portremote,char iplocal[4],uint16 portlocal,unsigned int timeout) +{ + int s; + int r; + + if (!stralloc_copys(out,"")) return -1; + + taia_now(&now); + taia_uint(&deadline,timeout); + taia_add(&deadline,&now,&deadline); + + s = socket_tcp(); + if (s == -1) return -1; + r = doit(out,s,ipremote,portremote,iplocal,portlocal,timeout); close(s); - return line; + return r; } diff --git a/remoteinfo.h b/remoteinfo.h index d5d9097..2ca779d 100644 --- a/remoteinfo.h +++ b/remoteinfo.h @@ -1,6 +1,9 @@ #ifndef REMOTEINFO_H #define REMOTEINFO_H -extern char *remoteinfo_get(); +#include "stralloc.h" +#include "uint16.h" + +extern int remoteinfo(stralloc *,char *,uint16,char *,uint16,unsigned int); #endif @@ -19,39 +19,77 @@ tcpclient: unable to connect to 127.0.0.1 port 16: connection refused tcpclient: unable to connect to 127.0.0.1 port 16: connection refused 111 --- tcpclient prints error message with unknown host name -tcpclient: fatal: unable to figure out IP address for nonexistent.local. +tcpclient: fatal: no IP address for nonexistent.local. +111 +--- tcpclient prints error message with unresolvable host name +tcpclient: fatal: temporarily unable to figure out IP address for thislabelistoolongbecausednshasalimitof63charactersinasinglelabel.: protocol error 111 --- tcpserver prints usage message without enough arguments -tcpserver: usage: tcpserver [ -1pPhHrRoOdDqQv ] [ -c limit ] [ -x rules.cdb ] [ -B banner ] [ -g gid ] [ -u uid ] [ -b backlog ] [ -l localname ] [ -t timeout ] host port program +tcpserver: usage: tcpserver [ -1UXpPhHrRoOdDqQv ] [ -c limit ] [ -x rules.cdb ] [ -B banner ] [ -g gid ] [ -u uid ] [ -b backlog ] [ -l localname ] [ -t timeout ] host port program 100 +--- tcpserver -u 1 attempts to set uid to 1 +tcpserver: fatal: unable to set uid: permission denied +111 +--- tcpserver -U reads $UID +tcpserver: fatal: unable to set uid: permission denied +111 +--- tcpserver -g 2 attempts to set gid to 2 +tcpserver: fatal: unable to set gid: permission denied +111 +--- tcpserver -U reads $GID +tcpserver: fatal: unable to set gid: permission denied +111 --- tcpserver prints error message with unknown port name tcpserver: fatal: unable to figure out port number for nonexistentport 111 --- tcpserver prints error message with unknown host name -tcpserver: fatal: unable to figure out IP address for nonexistent.local. +tcpserver: fatal: no IP address for nonexistent.local. +111 +--- tcpserver prints error message with unresolvable host name +tcpserver: fatal: temporarily unable to figure out IP address for thislabelistoolongbecausednshasalimitof63charactersinasinglelabel.: protocol error 111 --- tcpserver prints error message with non-local host name tcpserver: fatal: unable to bind: address not available 111 --- tcpserver sets basic environment variables -PROTO=TCP +bannerPROTO=TCP TCPLOCALHOST=Local TCPLOCALIP=127.0.0.1 TCPLOCALPORT=50016 -TCPREMOTEHOST= +TCPREMOTEHOST=localhost TCPREMOTEIP=127.0.0.1 TCPREMOTEPORT=50017 -TCPREMOTEINFO= +TCPREMOTEINFO=unset +0 +--- tcpclient recognizes -D, -i, -r, -h, -t +bannerPROTO=TCP +TCPLOCALHOST=Local +TCPLOCALIP=127.0.0.1 +TCPLOCALPORT=50016 +TCPREMOTEHOST=localhost +TCPREMOTEIP=127.0.0.1 +TCPREMOTEPORT=50018 +TCPREMOTEINFO=unset 0 --- tcpclient sets basic environment variables PROTO=TCP TCPLOCALHOST=Local TCPLOCALIP=127.0.0.1 -TCPLOCALPORT=50017 -TCPREMOTEHOST= +TCPLOCALPORT=50019 +TCPREMOTEHOST=unset TCPREMOTEIP=127.0.0.1 TCPREMOTEPORT=50016 -TCPREMOTEINFO= +TCPREMOTEINFO=unset +0 +--- tcpclient looks up host names properly +PROTO=TCP +TCPLOCALHOST=localhost +TCPLOCALIP=127.0.0.1 +TCPLOCALPORT=50020 +TCPREMOTEHOST=localhost +TCPREMOTEIP=127.0.0.1 +TCPREMOTEPORT=50016 +TCPREMOTEINFO=unset 0 --- tcpclient -v works tcpclient: connected to 127.0.0.1 port 50016 @@ -60,11 +98,23 @@ ok --- tcpserver prints error message with used port tcpserver: fatal: unable to bind: address already used 111 ---- tcpcat works; tcpserver -B works -bannerok +--- tcpcat works +bannerPROTO=TCP +TCPLOCALHOST=Local +TCPLOCALIP=127.0.0.1 +TCPLOCALPORT=50016 +TCPREMOTEHOST=localhost +TCPREMOTEIP=127.0.0.1 +TCPREMOTEINFO=unset 0 --- mconnect works -bannerok +bannerPROTO=TCP +TCPLOCALHOST=Local +TCPLOCALIP=127.0.0.1 +TCPLOCALPORT=50016 +TCPREMOTEHOST=localhost +TCPREMOTEIP=127.0.0.1 +TCPREMOTEINFO=unset 0 --- tcprules prints usage message without enough arguments tcprules: usage: tcprules rules.cdb rules.tmp @@ -143,6 +193,104 @@ default: allow connection default: allow connection +--- tcprules handles host names +0 +rule =known.edu: +set environment variable which=known +allow connection +rule : +set environment variable which=anybody +allow connection +rule : +set environment variable which=anybody +allow connection +rule =.abuser.edu: +deny connection +rule =.abuser.edu: +deny connection +--- tcprulescheck searches for rules in the proper order +0 +rule xyz@86.75.30.9: +set environment variable which=first +allow connection +rule xyz@86.75.30.9: +set environment variable which=first +allow connection +rule xyz@=one.two.three: +set environment variable which=second +allow connection +rule 86.75.30.9: +set environment variable which=third +allow connection +rule 86.75.30.9: +set environment variable which=third +allow connection +rule 86.75.30.9: +set environment variable which=third +allow connection +rule 86.75.30.9: +set environment variable which=third +allow connection +rule =one.two.three: +set environment variable which=fourth +allow connection +rule =one.two.three: +set environment variable which=fourth +allow connection +rule 86.75.30.: +set environment variable which=fifth +allow connection +rule 86.75.30.: +set environment variable which=fifth +allow connection +rule 86.75.: +set environment variable which=sixth +allow connection +rule 86.75.: +set environment variable which=sixth +allow connection +rule 86.75.: +set environment variable which=sixth +allow connection +rule 86.75.: +set environment variable which=sixth +allow connection +rule 86.: +set environment variable which=seventh +allow connection +rule 86.: +set environment variable which=seventh +allow connection +rule 86.: +set environment variable which=seventh +allow connection +rule 86.: +set environment variable which=seventh +allow connection +rule =.two.three: +set environment variable which=eighth +allow connection +rule =.two.three: +set environment variable which=eighth +allow connection +rule =.three: +set environment variable which=ninth +allow connection +rule =.three: +set environment variable which=ninth +allow connection +rule =: +set environment variable which=tenth +allow connection +rule =: +set environment variable which=tenth +allow connection +rule : +set environment variable which=eleventh +allow connection +rule : +set environment variable which=eleventh +allow connection --- addcr leaves an empty file alone 0 --- addcr leaves a partial final line alone @@ -168,30 +316,18 @@ test --- delcr converts CR CR LF to CR LF test^M 0 ---- delcr removes CR from a partial final line -test0 +--- delcr does not remove CR from a partial final line +test^M0 --- delcr handles a non-CR partial final line test0 --- delcr handles nulls t^@st 0 ---- fixcr leaves an empty file alone -0 ---- fixcr leaves a partial final line alone -test0 ---- fixcr adds CR after the first line -test^M -0 ---- fixcr adds CR after the second line -test^M -test2^M -0 ---- fixcr does not add CR if a line has it -test^M -0 ---- fixcr handles nulls -t^@st^M -0 +--- fixcrio works +^M +hi^M +there^M +bye^M --- recordio works ... < test $ ... > test $ @@ -215,3 +351,85 @@ zero --- argv0 requires arguments argv0: usage: argv0 realname program [ arg ... ] 100 +--- rblsmtpd does not find 127.0.0.1 on the RBL +ok +0 +--- rblsmtpd finds 127.0.0.2 on the RBL +rblsmtpd: 127.0.0.2 pid x: 451 Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2> +220 rblsmtpd.local^M +451 Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>^M +221 rblsmtpd.local^M +0 +--- rblsmtpd -b uses a permanent error code +rblsmtpd: 127.0.0.2 pid x: 553 Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2> +220 rblsmtpd.local^M +553 Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>^M +221 rblsmtpd.local^M +0 +--- rblsmtpd quits after a timeout +rblsmtpd: 127.0.0.2 pid x: 451 Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2> +220 rblsmtpd.local^M +0 +--- rblsmtpd prints an immediate error message with -t0 +rblsmtpd: 127.0.0.2 pid x: 451 Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2> +451 Blackholed - see <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>^M +0 +--- rblsmtpd understands an empty $RBLSMTPD +ok +0 +--- rblsmtpd understands a nonempty $RBLSMTPD +rblsmtpd: 127.0.0.2 pid x: 451 Error +220 rblsmtpd.local^M +451 Error^M +221 rblsmtpd.local^M +0 +--- rblsmtpd understands a permanent $RBLSMTPD +rblsmtpd: 127.0.0.2 pid x: 553 Error +220 rblsmtpd.local^M +553 Error^M +221 rblsmtpd.local^M +0 +--- rblsmtpd understands -r +ok +0 +--- rblsmtpd understands -a +ok +0 +--- tcpserver -1v prints proper messages +50016 +tcpserver: status: 0/2 +tcpserver: status: 1/2 +tcpserver: pid x from 127.0.0.1 +tcpserver: ok x Local:127.0.0.1:50016 localhost:127.0.0.1::x +tcpserver: end x status 0 +tcpserver: status: 0/2 +tcpserver: status: 1/2 +tcpserver: pid x from 127.0.0.1 +tcpserver: ok x Local:127.0.0.1:50016 localhost:127.0.0.1::x +tcpserver: end x status 0 +tcpserver: status: 0/2 +tcpserver: status: 1/2 +tcpserver: pid x from 127.0.0.1 +tcpserver: ok x Local:127.0.0.1:50016 localhost:127.0.0.1::x +tcpserver: end x status 0 +tcpserver: status: 0/2 +tcpserver: status: 1/2 +tcpserver: pid x from 127.0.0.1 +tcpserver: ok x Local:127.0.0.1:50016 localhost:127.0.0.1::x +tcpserver: end x status 0 +tcpserver: status: 0/2 +tcpserver: status: 1/2 +tcpserver: pid x from 127.0.0.1 +tcpserver: ok x Local:127.0.0.1:50016 localhost:127.0.0.1::x +tcpserver: end x status 0 +tcpserver: status: 0/2 +tcpserver: status: 1/2 +tcpserver: pid x from 127.0.0.1 +tcpserver: ok x Local:127.0.0.1:50016 localhost:127.0.0.1::x +tcpserver: end x status 0 +tcpserver: status: 0/2 +tcpserver: status: 1/2 +tcpserver: pid x from 127.0.0.1 +tcpserver: ok x Local:127.0.0.1:50016 localhost:127.0.0.1::x +tcpserver: end x status 0 +tcpserver: status: 0/2 @@ -1 +1 @@ -env - PATH=".:$PATH" sh rts.tests 2>&1 | cat -v +env - PATH="`pwd`:$PATH" sh rts.tests 2>&1 | cat -v @@ -1,40 +1,41 @@ -# Assumes that there is no port named nonexistentport. -# Assumes that there is no listener for TCP port 16 at 127.0.0.1. -# Assumes that there is no listener for TCP port 50016 at 127.0.0.1. -# Assumes that there is no use of TCP port 50017 at 127.0.0.1. -# Assumes that DNS lookup on nonexistent.local. will give hard error. - -# Not tested: -# who@ -# date@ -# finger@ -# http@ -# tcpclient handles temporary DNS errors -# tcpserver handles temporary DNS errors -# tcpclient -i -# tcpclient -r -# tcpclient -h -# tcpclient -d -# tcpclient -D -# tcpclient -T -# tcpclient -t -# tcpserver -1 -# tcpserver -p -# tcpserver -r -# tcpserver -h -# tcpserver -o -# tcpserver -O -# tcpserver -d -# tcpserver -D -# tcpserver -v -# tcpserver -c -# tcpserver -g -# tcpserver -u -# tcpserver -b -# tcpserver -t -# tcpserver -x +# Assumptions: +# We're not running with uid 0 or 1. +# We're not running with gid 0 or 2. +# supervise is installed. +# The DNS cache translates 127.0.0.1<->localhost. +# There is no listener for TCP port 16. +# There is no listener for TCP port 50016. +# There is no use of TCP ports 50017, 50018, 50019, 50020. +rm -rf rts-tmp +mkdir rts-tmp +cd rts-tmp + + +echo '#!/bin/sh + trap "" 13 + echo PROTO="$PROTO" + echo TCPLOCALHOST="${TCPLOCALHOST-unset}" + echo TCPLOCALIP="${TCPLOCALIP-unset}" + echo TCPLOCALPORT="${TCPLOCALPORT-unset}" + echo TCPREMOTEHOST="${TCPREMOTEHOST-unset}" + echo TCPREMOTEIP="${TCPREMOTEIP-unset}" + echo TCPREMOTEPORT="${TCPREMOTEPORT-unset}" + echo TCPREMOTEINFO="${TCPREMOTEINFO-unset}" +' > print +chmod 755 print + +mkdir 50016 +echo '#!/bin/sh +exec tcpserver \ +-c 2 -Bbanner -vo -D -1 -Xx rules.cdb -Rt5 -hp -l Local -b 2 \ +127.0.0.1 50016 ../print +' > 50016/run +chmod 755 50016/run + +supervise 50016 >log 2>&1 & + echo '--- tcpclient prints usage message without enough arguments' tcpclient 0 0; echo $? @@ -59,46 +60,51 @@ tcpclient '[127.000.000.001]' 016 echo wrong; echo $? echo '--- tcpclient prints error message with unknown host name' tcpclient nonexistent.local. 016 echo wrong; echo $? +echo '--- tcpclient prints error message with unresolvable host name' +tcpclient thislabelistoolongbecausednshasalimitof63charactersinasinglelabel. 016 echo wrong; echo $? + echo '--- tcpserver prints usage message without enough arguments' tcpserver 0 0; echo $? +echo '--- tcpserver -u 1 attempts to set uid to 1' +tcpserver -u 1 0 0 echo wrong; echo $? + +echo '--- tcpserver -U reads $UID' +env UID=1 tcpserver -U 0 0 echo wrong; echo $? + +echo '--- tcpserver -g 2 attempts to set gid to 2' +tcpserver -g 2 0 0 echo wrong; echo $? + +echo '--- tcpserver -U reads $GID' +env GID=2 tcpserver -U 0 0 echo wrong; echo $? + echo '--- tcpserver prints error message with unknown port name' tcpserver 0 nonexistentport echo wrong; echo $? echo '--- tcpserver prints error message with unknown host name' tcpserver nonexistent.local. 016 echo wrong; echo $? +echo '--- tcpserver prints error message with unresolvable host name' +tcpserver thislabelistoolongbecausednshasalimitof63charactersinasinglelabel. 016 echo wrong; echo $? + echo '--- tcpserver prints error message with non-local host name' tcpserver 1.2.3.4 016 echo wrong; echo $? -tcpserver -q -R -H -l Local 127.0.0.1 50016 sh -c ' - echo PROTO="$PROTO" - echo TCPLOCALHOST="$TCPLOCALHOST" - echo TCPLOCALIP="$TCPLOCALIP" - echo TCPLOCALPORT="$TCPLOCALPORT" - echo TCPREMOTEHOST="$TCPREMOTEHOST" - echo TCPREMOTEIP="$TCPREMOTEIP" - echo TCPREMOTEPORT="$TCPREMOTEPORT" - echo TCPREMOTEINFO="$TCPREMOTEINFO" -' & -pid=$! -sleep 1 #XXX - echo '--- tcpserver sets basic environment variables' -tcpclient -p 50017 -R -H -l Local 0 50016 sh -c 'cat <&6' +tcpclient -p 50017 -R -H -T 10 -l Local 0 50016 sh -c 'cat <&6' +echo $? + +echo '--- tcpclient recognizes -D, -i, -r, -h, -t' +tcpclient -Di 127.0.0.1 -p 50018 -hrt1 -l Local \ +127.0.0.1 50016 sh -c 'cat <&6' echo $? echo '--- tcpclient sets basic environment variables' -tcpclient -p 50017 -R -H -l Local 0 50016 sh -c ' - echo PROTO="$PROTO" - echo TCPLOCALHOST="$TCPLOCALHOST" - echo TCPLOCALIP="$TCPLOCALIP" - echo TCPLOCALPORT="$TCPLOCALPORT" - echo TCPREMOTEHOST="$TCPREMOTEHOST" - echo TCPREMOTEIP="$TCPREMOTEIP" - echo TCPREMOTEPORT="$TCPREMOTEPORT" - echo TCPREMOTEINFO="$TCPREMOTEINFO" -' +tcpclient -p 50019 -R -H -l Local 0 50016 ./print +echo $? + +echo '--- tcpclient looks up host names properly' +tcpclient -p 50020 -R 0 50016 ./print echo $? echo '--- tcpclient -v works' @@ -109,24 +115,14 @@ echo '--- tcpserver prints error message with used port' tcpserver -R -H -l Local 127.0.0.1 50016 echo wrong echo $? -kill $pid -wait - -tcpserver -B banner -q -R -H -l Local 127.0.0.1 50016 echo ok & -pid=$! -sleep 1 #XXX - -echo '--- tcpcat works; tcpserver -B works' -tcpcat 0 50016 +echo '--- tcpcat works' +tcpcat 0 50016 | grep -v TCPREMOTEPORT echo $? echo '--- mconnect works' -mconnect 0 50016 </dev/null +mconnect 0 50016 </dev/null | grep -v TCPREMOTEPORT echo $? -kill $pid -wait - echo '--- tcprules prints usage message without enough arguments' tcprules test.cdb; echo $? @@ -140,10 +136,10 @@ echo '--- tcprules creates a cdb file' echo 1.2.3.4:deny | tcprules test.cdb test.tmp; echo $? echo '--- tcprulescheck sees deny' -tcprulescheck test.cdb 1.2.3.4; echo $? +env TCPREMOTEIP=1.2.3.4 tcprulescheck test.cdb; echo $? echo '--- tcprulescheck does not apply deny to another host' -tcprulescheck test.cdb 1.2.3.5; echo $? +env TCPREMOTEIP=1.2.3.5 tcprulescheck test.cdb; echo $? echo '--- tcprules replaces a cdb file' echo 'joe@127.0.0.1:allow,which=/first/ @@ -152,38 +148,89 @@ echo 'joe@127.0.0.1:allow,which=/first/ :allow,which==fourth=' | tcprules test.cdb test.tmp; echo $? echo '--- tcprulescheck finds rule with address and info' -tcprulescheck test.cdb 127.0.0.1 joe; echo $? +env TCPREMOTEIP=127.0.0.1 TCPREMOTEINFO=joe tcprulescheck test.cdb; echo $? echo '--- tcprulescheck finds rule with address' -tcprulescheck test.cdb 18.23.0.32 joe ; echo $? +env TCPREMOTEIP=18.23.0.32 TCPREMOTEINFO=joe tcprulescheck test.cdb; echo $? echo '--- tcprulescheck finds one-dot wildcard' -tcprulescheck test.cdb 127.0.0.1 bill; echo $? +env TCPREMOTEIP=127.0.0.1 TCPREMOTEINFO=bill tcprulescheck test.cdb; echo $? echo '--- tcprulescheck finds zero-dot wildcard' -tcprulescheck test.cdb 10.119.75.38 bill; echo $? +env TCPREMOTEIP=10.119.75.39 TCPREMOTEINFO=bill tcprulescheck test.cdb; echo $? echo '--- tcprules handles comments, address ranges, multiple variables' echo '127.0-5.:allow,which=/first/,where=/whatever/ # comment' | tcprules test.cdb test.tmp; echo $? -tcprulescheck test.cdb 127.0.0.1 -tcprulescheck test.cdb 127.1.0.1 -tcprulescheck test.cdb 127.2.0.1 -tcprulescheck test.cdb 127.3.0.1 -tcprulescheck test.cdb 127.4.0.1 -tcprulescheck test.cdb 127.5.0.1 -tcprulescheck test.cdb 127.6.0.1 -tcprulescheck test.cdb 127.7.0.1 -tcprulescheck test.cdb 127.8.0.1 -tcprulescheck test.cdb 127.9.0.1 -tcprulescheck test.cdb 127.10.0.1 +env TCPREMOTEIP=127.0.0.1 tcprulescheck test.cdb +env TCPREMOTEIP=127.1.0.1 tcprulescheck test.cdb +env TCPREMOTEIP=127.2.0.1 tcprulescheck test.cdb +env TCPREMOTEIP=127.3.0.1 tcprulescheck test.cdb +env TCPREMOTEIP=127.4.0.1 tcprulescheck test.cdb +env TCPREMOTEIP=127.5.0.1 tcprulescheck test.cdb +env TCPREMOTEIP=127.6.0.1 tcprulescheck test.cdb +env TCPREMOTEIP=127.7.0.1 tcprulescheck test.cdb +env TCPREMOTEIP=127.8.0.1 tcprulescheck test.cdb +env TCPREMOTEIP=127.9.0.1 tcprulescheck test.cdb +env TCPREMOTEIP=127.10.0.1 tcprulescheck test.cdb + +echo '--- tcprules handles host names' +echo '=known.edu:allow,which=/known/ +=.abuser.edu:deny +:allow,which=/anybody/' | tcprules test.cdb test.tmp; echo $? +env TCPREMOTEIP=1.2.3.4 TCPREMOTEHOST=known.edu tcprulescheck test.cdb +env TCPREMOTEIP=1.2.3.4 TCPREMOTEHOST=random.edu tcprulescheck test.cdb +env TCPREMOTEIP=1.2.3.4 TCPREMOTEHOST=abuser.edu tcprulescheck test.cdb +env TCPREMOTEIP=1.2.3.4 TCPREMOTEHOST=x.abuser.edu tcprulescheck test.cdb +env TCPREMOTEIP=1.2.3.4 TCPREMOTEHOST=x.y.abuser.edu tcprulescheck test.cdb + +echo '--- tcprulescheck searches for rules in the proper order' +echo 'xyz@86.75.30.9:allow,which=/first/ +xyz@=one.two.three:allow,which=/second/ +86.75.30.9:allow,which=/third/ +=one.two.three:allow,which=/fourth/ +86.75.30.:allow,which=/fifth/ +86.75.:allow,which=/sixth/ +86.:allow,which=/seventh/ +=.two.three:allow,which=/eighth/ +=.three:allow,which=/ninth/ +=:allow,which=/tenth/ +:allow,which=/eleventh/ +' | tcprules test.cdb test.tmp; echo $? +env TCPREMOTEIP=86.75.30.9 TCPREMOTEHOST=one.two.three TCPREMOTEINFO=xyz tcprulescheck test.cdb +env TCPREMOTEIP=86.75.30.9 TCPREMOTEINFO=xyz tcprulescheck test.cdb +env TCPREMOTEIP=86.75.30.10 TCPREMOTEHOST=one.two.three TCPREMOTEINFO=xyz tcprulescheck test.cdb +env TCPREMOTEIP=86.75.30.9 TCPREMOTEHOST=one.two.three TCPREMOTEINFO=abc tcprulescheck test.cdb +env TCPREMOTEIP=86.75.30.9 TCPREMOTEINFO=abc tcprulescheck test.cdb +env TCPREMOTEIP=86.75.30.9 TCPREMOTEHOST=one.two.three tcprulescheck test.cdb +env TCPREMOTEIP=86.75.30.9 tcprulescheck test.cdb +env TCPREMOTEIP=86.75.30.10 TCPREMOTEHOST=one.two.three TCPREMOTEINFO=abc tcprulescheck test.cdb +env TCPREMOTEIP=86.75.30.10 TCPREMOTEHOST=one.two.three tcprulescheck test.cdb +env TCPREMOTEIP=86.75.30.10 TCPREMOTEHOST=four.two.three tcprulescheck test.cdb +env TCPREMOTEIP=86.75.30.10 tcprulescheck test.cdb +env TCPREMOTEIP=86.75.20.10 TCPREMOTEHOST=four.two.three TCPREMOTEINFO=abc tcprulescheck test.cdb +env TCPREMOTEIP=86.75.20.10 TCPREMOTEINFO=abc tcprulescheck test.cdb +env TCPREMOTEIP=86.75.20.10 TCPREMOTEHOST=four.two.three tcprulescheck test.cdb +env TCPREMOTEIP=86.75.20.10 tcprulescheck test.cdb +env TCPREMOTEIP=86.85.20.10 TCPREMOTEHOST=four.two.three TCPREMOTEINFO=abc tcprulescheck test.cdb +env TCPREMOTEIP=86.85.20.10 TCPREMOTEINFO=abc tcprulescheck test.cdb +env TCPREMOTEIP=86.85.20.10 TCPREMOTEHOST=four.two.three tcprulescheck test.cdb +env TCPREMOTEIP=86.85.20.10 tcprulescheck test.cdb +env TCPREMOTEIP=96.85.20.10 TCPREMOTEHOST=four.two.three TCPREMOTEINFO=abc tcprulescheck test.cdb +env TCPREMOTEIP=96.85.20.10 TCPREMOTEHOST=four.two.three tcprulescheck test.cdb +env TCPREMOTEIP=96.85.20.10 TCPREMOTEHOST=four.three TCPREMOTEINFO=abc tcprulescheck test.cdb +env TCPREMOTEIP=96.85.20.10 TCPREMOTEHOST=four.three tcprulescheck test.cdb +env TCPREMOTEIP=96.85.20.10 TCPREMOTEHOST=four TCPREMOTEINFO=abc tcprulescheck test.cdb +env TCPREMOTEIP=96.85.20.10 TCPREMOTEHOST=four tcprulescheck test.cdb +env TCPREMOTEIP=96.85.20.10 TCPREMOTEINFO=abc tcprulescheck test.cdb +env TCPREMOTEIP=96.85.20.10 tcprulescheck test.cdb echo '--- addcr leaves an empty file alone' -echo -n '' | addcr; echo $? +echo '' | tr -d '\012' | addcr; echo $? echo '--- addcr leaves a partial final line alone' -echo -n test | addcr; echo $? +echo test | tr -d '\012' | addcr; echo $? echo '--- addcr adds CR after the first line' echo test | addcr; echo $? @@ -195,7 +242,7 @@ echo '--- addcr handles nulls' echo test | tr e '\0' | addcr; echo $? echo '--- delcr leaves an empty file alone' -echo -n '' | delcr; echo $? +echo '' | tr -d '\012' | delcr; echo $? echo '--- delcr leaves a non-CR line alone' echo test | delcr; echo $? @@ -206,32 +253,18 @@ echo testx | tr x '\015' | delcr; echo $? echo '--- delcr converts CR CR LF to CR LF' echo testxx | tr x '\015' | delcr; echo $? -echo '--- delcr removes CR from a partial final line' -echo -n testx | tr x '\015' | delcr; echo $? +echo '--- delcr does not remove CR from a partial final line' +echo testx | tr -d '\012' | tr x '\015' | delcr; echo $? echo '--- delcr handles a non-CR partial final line' -echo -n test | delcr; echo $? +echo test | tr -d '\012' | delcr; echo $? echo '--- delcr handles nulls' echo test | tr e '\0' | delcr; echo $? -echo '--- fixcr leaves an empty file alone' -echo -n '' | fixcr; echo $? - -echo '--- fixcr leaves a partial final line alone' -echo -n test | fixcr; echo $? - -echo '--- fixcr adds CR after the first line' -echo test | fixcr; echo $? - -echo '--- fixcr adds CR after the second line' -( echo test; echo test2 ) | fixcr; echo $? - -echo '--- fixcr does not add CR if a line has it' -echo testx | tr x '\015' | fixcr; echo $? - -echo '--- fixcr handles nulls' -echo test | tr e '\0' | fixcr; echo $? +echo '--- fixcrio works' +( echo ''; echo hi; echo therex ) | tr x '\015' \ +| fixcrio sh -c 'cat; echo bye' | cat echo '--- recordio works' ( echo test; sleep 1 ) | recordio cat 2>&1 >/dev/null \ @@ -243,7 +276,7 @@ test2'; sleep 1 ) | recordio cat 2>&1 >/dev/null \ | sed 's/^[0-9]*/.../' | sed 's/$/$/' echo '--- recordio handles partial final lines' -( echo -n test; sleep 1 ) | recordio cat 2>&1 >/dev/null \ +( echo test | tr -d '\012'; sleep 1 ) | recordio cat 2>&1 >/dev/null \ | sed 's/^[0-9]*/.../' | sed 's/$/$/' echo '--- argv0 works' @@ -252,4 +285,63 @@ argv0 sh zero -c 'echo $0'; echo $? echo '--- argv0 requires arguments' argv0 sh; echo $? + +echo '--- rblsmtpd does not find 127.0.0.1 on the RBL' +( echo help; echo quit ) \ +| ( TCPREMOTEIP=127.0.0.1 rblsmtpd echo ok 2>&1; echo $? ) \ +| sed 's/pid [0-9]*/pid x/' + +echo '--- rblsmtpd finds 127.0.0.2 on the RBL' +( echo help; echo quit ) \ +| ( TCPREMOTEIP=127.0.0.2 rblsmtpd echo whoops 2>&1; echo $? ) \ +| sed 's/pid [0-9]*/pid x/' + +echo '--- rblsmtpd -b uses a permanent error code' +( echo help; echo quit ) \ +| ( TCPREMOTEIP=127.0.0.2 rblsmtpd -b echo whoops 2>&1; echo $? ) \ +| sed 's/pid [0-9]*/pid x/' + +echo '--- rblsmtpd quits after a timeout' +sleep 2 \ +| ( TCPREMOTEIP=127.0.0.2 rblsmtpd -cBt1 echo whoops 2>&1; echo $? ) \ +| sed 's/pid [0-9]*/pid x/' + +echo '--- rblsmtpd prints an immediate error message with -t0' +sleep 2 \ +| ( TCPREMOTEIP=127.0.0.2 rblsmtpd -Ct0 echo whoops 2>&1; echo $? ) \ +| sed 's/pid [0-9]*/pid x/' + +echo '--- rblsmtpd understands an empty $RBLSMTPD' +( echo help; echo quit ) \ +| ( TCPREMOTEIP=127.0.0.2 RBLSMTPD= rblsmtpd echo ok 2>&1; echo $? ) \ +| sed 's/pid [0-9]*/pid x/' + +echo '--- rblsmtpd understands a nonempty $RBLSMTPD' +( echo help; echo quit ) \ +| ( TCPREMOTEIP=127.0.0.2 RBLSMTPD=Error rblsmtpd echo whoops 2>&1; echo $? ) \ +| sed 's/pid [0-9]*/pid x/' + +echo '--- rblsmtpd understands a permanent $RBLSMTPD' +( echo help; echo quit ) \ +| ( TCPREMOTEIP=127.0.0.2 RBLSMTPD=-Error rblsmtpd echo whoops 2>&1; echo $? ) \ +| sed 's/pid [0-9]*/pid x/' + +echo '--- rblsmtpd understands -r' +( echo help; echo quit ) \ +| ( TCPREMOTEIP=127.0.0.2 rblsmtpd -r nonexistent.local echo ok 2>&1; echo $? ) \ +| sed 's/pid [0-9]*/pid x/' + +echo '--- rblsmtpd understands -a' +( echo help; echo quit ) \ +| ( TCPREMOTEIP=127.0.0.2 rblsmtpd -a rbl.maps.vix.com echo ok 2>&1; echo $? ) \ +| sed 's/pid [0-9]*/pid x/' + + +svc -dx 50016 +wait + +echo '--- tcpserver -1v prints proper messages' +sed -e 's/::.*/::x/' -e 's/ [0-9]* / x /' < log + + exit 0 @@ -0,0 +1,100 @@ +#include "alloc.h" +#include "stralloc.h" +#include "open.h" +#include "cdb.h" +#include "rules.h" + +stralloc rules_name = {0}; + +static struct cdb c; + +static int dorule(void (*callback)(char *,unsigned int)) +{ + char *data; + unsigned int datalen; + + switch(cdb_find(&c,rules_name.s,rules_name.len)) { + case -1: return -1; + case 0: return 0; + } + + datalen = cdb_datalen(&c); + data = alloc(datalen); + if (!data) return -1; + if (cdb_read(&c,data,datalen,cdb_datapos(&c)) == -1) { + alloc_free(data); + return -1; + } + + callback(data,datalen); + alloc_free(data); + return 1; +} + +static int doit(void (*callback)(char *,unsigned int),char *ip,char *host,char *info) +{ + int r; + + if (info) { + if (!stralloc_copys(&rules_name,info)) return -1; + if (!stralloc_cats(&rules_name,"@")) return -1; + if (!stralloc_cats(&rules_name,ip)) return -1; + r = dorule(callback); + if (r) return r; + + if (host) { + if (!stralloc_copys(&rules_name,info)) return -1; + if (!stralloc_cats(&rules_name,"@=")) return -1; + if (!stralloc_cats(&rules_name,host)) return -1; + r = dorule(callback); + if (r) return r; + } + } + + if (!stralloc_copys(&rules_name,ip)) return -1; + r = dorule(callback); + if (r) return r; + + if (host) { + if (!stralloc_copys(&rules_name,"=")) return -1; + if (!stralloc_cats(&rules_name,host)) return -1; + r = dorule(callback); + if (r) return r; + } + + if (!stralloc_copys(&rules_name,ip)) return -1; + while (rules_name.len > 0) { + if (ip[rules_name.len - 1] == '.') { + r = dorule(callback); + if (r) return r; + } + --rules_name.len; + } + + if (host) { + while (*host) { + if (*host == '.') { + if (!stralloc_copys(&rules_name,"=")) return -1; + if (!stralloc_cats(&rules_name,host)) return -1; + r = dorule(callback); + if (r) return r; + } + ++host; + } + if (!stralloc_copys(&rules_name,"=")) return -1; + r = dorule(callback); + if (r) return r; + } + + rules_name.len = 0; + return dorule(callback); +} + +int rules(void (*callback)(char *,unsigned int),int fd,char *ip,char *host,char *info) +{ + int r; + cdb_init(&c,fd); + r = doit(callback,ip,host,info); + cdb_free(&c); + return r; +} @@ -0,0 +1,9 @@ +#ifndef RULES_H +#define RULES_H + +#include "stralloc.h" + +extern stralloc rules_name; +extern int rules(void (*)(char *,unsigned int),int,char *,char *,char *); + +#endif @@ -1,28 +1,28 @@ #ifndef SCAN_H #define SCAN_H -extern unsigned int scan_uint(); -extern unsigned int scan_xint(); -extern unsigned int scan_nbbint(); -extern unsigned int scan_ushort(); -extern unsigned int scan_xshort(); -extern unsigned int scan_nbbshort(); -extern unsigned int scan_ulong(); -extern unsigned int scan_xlong(); -extern unsigned int scan_nbblong(); +extern unsigned int scan_uint(char *,unsigned int *); +extern unsigned int scan_xint(char *,unsigned int *); +extern unsigned int scan_nbbint(char *,unsigned int,unsigned int,unsigned int,unsigned int *); +extern unsigned int scan_ushort(char *,unsigned short *); +extern unsigned int scan_xshort(char *,unsigned short *); +extern unsigned int scan_nbbshort(char *,unsigned int,unsigned int,unsigned int,unsigned short *); +extern unsigned int scan_ulong(char *,unsigned long *); +extern unsigned int scan_xlong(char *,unsigned long *); +extern unsigned int scan_nbblong(char *,unsigned int,unsigned int,unsigned int,unsigned long *); -extern unsigned int scan_plusminus(); -extern unsigned int scan_0x(); +extern unsigned int scan_plusminus(char *,int *); +extern unsigned int scan_0x(char *,unsigned int *); -extern unsigned int scan_whitenskip(); -extern unsigned int scan_nonwhitenskip(); -extern unsigned int scan_charsetnskip(); -extern unsigned int scan_noncharsetnskip(); +extern unsigned int scan_whitenskip(char *,unsigned int); +extern unsigned int scan_nonwhitenskip(char *,unsigned int); +extern unsigned int scan_charsetnskip(char *,char *,unsigned int); +extern unsigned int scan_noncharsetnskip(char *,char *,unsigned int); -extern unsigned int scan_strncmp(); -extern unsigned int scan_memcmp(); +extern unsigned int scan_strncmp(char *,char *,unsigned int); +extern unsigned int scan_memcmp(char *,char *,unsigned int); -extern unsigned int scan_long(); -extern unsigned int scan_8long(); +extern unsigned int scan_long(char *,long *); +extern unsigned int scan_8long(char *,unsigned long *); #endif diff --git a/scan_ulong.c b/scan_ulong.c index 27c41ea..69bc3d4 100644 --- a/scan_ulong.c +++ b/scan_ulong.c @@ -1,11 +1,14 @@ #include "scan.h" -unsigned int scan_ulong(s,u) register char *s; register unsigned long *u; +unsigned int scan_ulong(register char *s,register unsigned long *u) { - register unsigned int pos; register unsigned long result; + register unsigned int pos = 0; + register unsigned long result = 0; register unsigned long c; - pos = 0; result = 0; - while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 10) - { result = result * 10 + c; ++pos; } - *u = result; return pos; + while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 10) { + result = result * 10 + c; + ++pos; + } + *u = result; + return pos; } @@ -3,12 +3,12 @@ typedef unsigned long seek_pos; -extern seek_pos seek_cur(); +extern seek_pos seek_cur(int); -extern int seek_set(); -extern int seek_end(); +extern int seek_set(int,seek_pos); +extern int seek_end(int); -extern int seek_trunc(); +extern int seek_trunc(int,seek_pos); #define seek_begin(fd) (seek_set((fd),(seek_pos) 0)) @@ -3,5 +3,5 @@ #define SET 0 /* sigh */ -int seek_set(fd,pos) int fd; seek_pos pos; +int seek_set(int fd,seek_pos pos) { if (lseek(fd,(off_t) pos,SET) == -1) return -1; return 0; } @@ -1,6 +1,8 @@ #ifndef SELECT_H #define SELECT_H +/* sysdep: -sysselect */ + #include <sys/types.h> #include <sys/time.h> extern int select(); @@ -1,6 +1,8 @@ #ifndef SELECT_H #define SELECT_H +/* sysdep: +sysselect */ + #include <sys/types.h> #include <sys/time.h> #include <sys/select.h> diff --git a/sgetopt.3 b/sgetopt.3 deleted file mode 100644 index bde0c2b..0000000 --- a/sgetopt.3 +++ /dev/null @@ -1,28 +0,0 @@ -.TH sgetopt 3 -.SH NAME -sgetopt \- get option character from command line -.SH SYNTAX -.B #include <sgetopt.h> -.SH DESCRIPTION -The -.B sgetopt -library is just like the -.B getopt -library, -except that it prints errors using -.B substdio -rather than -.BR stdio . - -See -.B getopt(3) -for interface details. -.SH VERSION -sgetopt version 1.9, 931201. -.SH AUTHOR -Placed into the public domain by Daniel J. Bernstein. -.SH "SEE ALSO" -getopt(3), -subgetopt(3), -subfd(3), -substdio(3) @@ -1,7 +1,8 @@ /* sgetopt.c, sgetopt.h: (yet another) improved getopt clone, outer layer D. J. Bernstein, djb@pobox.com. -Depends on subgetopt.h, substdio.h, subfd.h. +Depends on subgetopt.h, buffer.h. No system requirements. +19991219: Switched to buffer.h. 19970208: Cleanups. 931201: Baseline. No known patent problems. @@ -9,8 +10,7 @@ No known patent problems. Documentation in sgetopt.3. */ -#include "substdio.h" -#include "subfd.h" +#include "buffer.h" #define SGETOPTNOSHORT #include "sgetopt.h" #define SUBGETOPTNOSHORT @@ -25,10 +25,7 @@ Documentation in sgetopt.3. int opterr = 1; char *optprogname = 0; -int getopt(argc,argv,opts) -int argc; -char **argv; -char *opts; +int getopt(int argc,char **argv,char *opts) { int c; char *s; @@ -42,13 +39,13 @@ char *opts; if (opterr) if (c == '?') { char chp[2]; chp[0] = optproblem; chp[1] = '\n'; - substdio_puts(subfderr,optprogname); + buffer_puts(buffer_2,optprogname); if (argv[optind] && (optind < argc)) - substdio_puts(subfderr,": illegal option -- "); + buffer_puts(buffer_2,": illegal option -- "); else - substdio_puts(subfderr,": option requires an argument -- "); - substdio_put(subfderr,chp,2); - substdio_flush(subfderr); + buffer_puts(buffer_2,": option requires an argument -- "); + buffer_put(buffer_2,chp,2); + buffer_flush(buffer_2); } return c; } @@ -14,7 +14,7 @@ #include "subgetopt.h" -extern int sgetoptmine(); +extern int sgetoptmine(int,char **,char *); extern int sgetopterr; extern char *sgetoptprogname; @@ -0,0 +1,12 @@ +#include <signal.h> +#include "sig.h" + +int sig_alarm = SIGALRM; +int sig_child = SIGCHLD; +int sig_cont = SIGCONT; +int sig_hangup = SIGHUP; +int sig_pipe = SIGPIPE; +int sig_term = SIGTERM; + +void (*sig_defaulthandler)() = SIG_DFL; +void (*sig_ignorehandler)() = SIG_IGN; @@ -1,43 +1,25 @@ #ifndef SIG_H #define SIG_H -extern void sig_catch(); -extern void sig_block(); -extern void sig_unblock(); -extern void sig_blocknone(); -extern void sig_pause(); - -extern void sig_dfl(); - -extern void sig_miscignore(); -extern void sig_bugcatch(); - -extern void sig_pipeignore(); -extern void sig_pipedefault(); - -extern void sig_contblock(); -extern void sig_contunblock(); -extern void sig_contcatch(); -extern void sig_contdefault(); - -extern void sig_termblock(); -extern void sig_termunblock(); -extern void sig_termcatch(); -extern void sig_termdefault(); - -extern void sig_alarmblock(); -extern void sig_alarmunblock(); -extern void sig_alarmcatch(); -extern void sig_alarmdefault(); - -extern void sig_childblock(); -extern void sig_childunblock(); -extern void sig_childcatch(); -extern void sig_childdefault(); - -extern void sig_hangupblock(); -extern void sig_hangupunblock(); -extern void sig_hangupcatch(); -extern void sig_hangupdefault(); +extern int sig_alarm; +extern int sig_child; +extern int sig_cont; +extern int sig_hangup; +extern int sig_pipe; +extern int sig_term; + +extern void (*sig_defaulthandler)(); +extern void (*sig_ignorehandler)(); + +extern void sig_catch(int,void (*)()); +#define sig_ignore(s) (sig_catch((s),sig_ignorehandler)) +#define sig_uncatch(s) (sig_catch((s),sig_defaulthandler)) + +extern void sig_block(int); +extern void sig_unblock(int); +extern void sig_blocknone(void); +extern void sig_pause(void); + +extern void sig_dfl(int); #endif diff --git a/sig_block.c b/sig_block.c index c6b096a..57be036 100644 --- a/sig_block.c +++ b/sig_block.c @@ -2,8 +2,7 @@ #include "sig.h" #include "hassgprm.h" -void sig_block(sig) -int sig; +void sig_block(int sig) { #ifdef HASSIGPROCMASK sigset_t ss; @@ -15,8 +14,7 @@ int sig; #endif } -void sig_unblock(sig) -int sig; +void sig_unblock(int sig) { #ifdef HASSIGPROCMASK sigset_t ss; @@ -28,7 +26,7 @@ int sig; #endif } -void sig_blocknone() +void sig_blocknone(void) { #ifdef HASSIGPROCMASK sigset_t ss; diff --git a/sig_catch.c b/sig_catch.c index 1888765..bdb2bfb 100644 --- a/sig_catch.c +++ b/sig_catch.c @@ -2,9 +2,7 @@ #include "sig.h" #include "hassgact.h" -void sig_catch(sig,f) -int sig; -void (*f)(); +void sig_catch(int sig,void (*f)()) { #ifdef HASSIGACTION struct sigaction sa; diff --git a/sig_child.c b/sig_child.c deleted file mode 100644 index fd5b39b..0000000 --- a/sig_child.c +++ /dev/null @@ -1,7 +0,0 @@ -#include <signal.h> -#include "sig.h" - -void sig_childblock() { sig_block(SIGCHLD); } -void sig_childunblock() { sig_unblock(SIGCHLD); } -void sig_childcatch(f) void (*f)(); { sig_catch(SIGCHLD,f); } -void sig_childdefault() { sig_catch(SIGCHLD,SIG_DFL); } diff --git a/sig_pause.c b/sig_pause.c index 3416734..3dcc7b6 100644 --- a/sig_pause.c +++ b/sig_pause.c @@ -2,7 +2,7 @@ #include "sig.h" #include "hassgprm.h" -void sig_pause() +void sig_pause(void) { #ifdef HASSIGPROCMASK sigset_t ss; diff --git a/sig_pipe.c b/sig_pipe.c deleted file mode 100644 index 594ae7d..0000000 --- a/sig_pipe.c +++ /dev/null @@ -1,5 +0,0 @@ -#include <signal.h> -#include "sig.h" - -void sig_pipeignore() { sig_catch(SIGPIPE,SIG_IGN); } -void sig_pipedefault() { sig_catch(SIGPIPE,SIG_DFL); } diff --git a/sig_term.c b/sig_term.c deleted file mode 100644 index ca72cc3..0000000 --- a/sig_term.c +++ /dev/null @@ -1,7 +0,0 @@ -#include <signal.h> -#include "sig.h" - -void sig_termblock() { sig_block(SIGTERM); } -void sig_termunblock() { sig_unblock(SIGTERM); } -void sig_termcatch(f) void (*f)(); { sig_catch(SIGTERM,f); } -void sig_termdefault() { sig_catch(SIGTERM,SIG_DFL); } diff --git a/socket.h b/socket.h new file mode 100644 index 0000000..80fb260 --- /dev/null +++ b/socket.h @@ -0,0 +1,22 @@ +#ifndef SOCKET_H +#define SOCKET_H + +#include "uint16.h" + +extern int socket_tcp(void); +extern int socket_udp(void); + +extern int socket_connect4(int,char *,uint16); +extern int socket_connected(int); +extern int socket_bind4(int,char *,uint16); +extern int socket_bind4_reuse(int,char *,uint16); +extern int socket_listen(int,int); +extern int socket_accept4(int,char *,uint16 *); +extern int socket_recv4(int,char *,int,char *,uint16 *); +extern int socket_send4(int,char *,int,char *,uint16); +extern int socket_local4(int,char *,uint16 *); +extern int socket_remote4(int,char *,uint16 *); + +extern void socket_tryreservein(int,int); + +#endif diff --git a/socket_accept.c b/socket_accept.c new file mode 100644 index 0000000..22c44d4 --- /dev/null +++ b/socket_accept.c @@ -0,0 +1,21 @@ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "byte.h" +#include "socket.h" + +int socket_accept4(int s,char ip[4],uint16 *port) +{ + struct sockaddr_in sa; + int dummy = sizeof sa; + int fd; + + fd = accept(s,(struct sockaddr *) &sa,&dummy); + if (fd == -1) return -1; + + byte_copy(ip,4,(char *) &sa.sin_addr); + uint16_unpack_big((char *) &sa.sin_port,port); + + return fd; +} diff --git a/socket_bind.c b/socket_bind.c new file mode 100644 index 0000000..20830a4 --- /dev/null +++ b/socket_bind.c @@ -0,0 +1,33 @@ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "byte.h" +#include "socket.h" + +int socket_bind4(int s,char ip[4],uint16 port) +{ + struct sockaddr_in sa; + + byte_zero(&sa,sizeof sa); + sa.sin_family = AF_INET; + uint16_pack_big((char *) &sa.sin_port,port); + byte_copy((char *) &sa.sin_addr,4,ip); + + return bind(s,(struct sockaddr *) &sa,sizeof sa); +} + +int socket_bind4_reuse(int s,char ip[4],uint16 port) +{ + int opt = 1; + setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof opt); + return socket_bind4(s,ip,port); +} + +void socket_tryreservein(int s,int size) +{ + while (size >= 1024) { + if (setsockopt(s,SOL_SOCKET,SO_RCVBUF,&size,sizeof size) == 0) return; + size -= (size >> 5); + } +} diff --git a/socket_conn.c b/socket_conn.c new file mode 100644 index 0000000..35adac4 --- /dev/null +++ b/socket_conn.c @@ -0,0 +1,33 @@ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "readwrite.h" +#include "byte.h" +#include "socket.h" + +int socket_connect4(int s,char ip[4],uint16 port) +{ + struct sockaddr_in sa; + + byte_zero(&sa,sizeof sa); + sa.sin_family = AF_INET; + uint16_pack_big((char *) &sa.sin_port,port); + byte_copy((char *) &sa.sin_addr,4,ip); + + return connect(s,(struct sockaddr *) &sa,sizeof sa); +} + +int socket_connected(int s) +{ + struct sockaddr_in sa; + int dummy; + char ch; + + dummy = sizeof sa; + if (getpeername(s,(struct sockaddr *) &sa,&dummy) == -1) { + read(s,&ch,1); /* sets errno */ + return 0; + } + return 1; +} diff --git a/socket_delay.c b/socket_delay.c new file mode 100644 index 0000000..0e8c860 --- /dev/null +++ b/socket_delay.c @@ -0,0 +1,11 @@ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "socket.h" + +int socket_tcpnodelay(int s) +{ + int opt = 1; + return setsockopt(s,IPPROTO_TCP,1,&opt,sizeof opt); /* 1 == TCP_NODELAY */ +} diff --git a/socket_listen.c b/socket_listen.c new file mode 100644 index 0000000..abdb483 --- /dev/null +++ b/socket_listen.c @@ -0,0 +1,10 @@ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "socket.h" + +int socket_listen(int s,int backlog) +{ + return listen(s,backlog); +} diff --git a/socket_local.c b/socket_local.c new file mode 100644 index 0000000..1473d91 --- /dev/null +++ b/socket_local.c @@ -0,0 +1,17 @@ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "byte.h" +#include "socket.h" + +int socket_local4(int s,char ip[4],uint16 *port) +{ + struct sockaddr_in sa; + int dummy = sizeof sa; + + if (getsockname(s,(struct sockaddr *) &sa,&dummy) == -1) return -1; + byte_copy(ip,4,(char *) &sa.sin_addr); + uint16_unpack_big((char *) &sa.sin_port,port); + return 0; +} diff --git a/socket_opts.c b/socket_opts.c new file mode 100644 index 0000000..ce5d170 --- /dev/null +++ b/socket_opts.c @@ -0,0 +1,10 @@ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "socket.h" + +int socket_ipoptionskill(int s) +{ + return setsockopt(s,IPPROTO_IP,1,(char *) 0,0); /* 1 == IP_OPTIONS */ +} diff --git a/socket_remote.c b/socket_remote.c new file mode 100644 index 0000000..d65d9f8 --- /dev/null +++ b/socket_remote.c @@ -0,0 +1,17 @@ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "byte.h" +#include "socket.h" + +int socket_remote4(int s,char ip[4],uint16 *port) +{ + struct sockaddr_in sa; + int dummy = sizeof sa; + + if (getpeername(s,(struct sockaddr *) &sa,&dummy) == -1) return -1; + byte_copy(ip,4,(char *) &sa.sin_addr); + uint16_unpack_big((char *) &sa.sin_port,port); + return 0; +} diff --git a/socket_tcp.c b/socket_tcp.c new file mode 100644 index 0000000..aada07d --- /dev/null +++ b/socket_tcp.c @@ -0,0 +1,16 @@ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "ndelay.h" +#include "socket.h" + +int socket_tcp(void) +{ + int s; + + s = socket(AF_INET,SOCK_STREAM,0); + if (s == -1) return -1; + if (ndelay_on(s) == -1) { close(s); return -1; } + return s; +} diff --git a/socket_udp.c b/socket_udp.c new file mode 100644 index 0000000..bda4494 --- /dev/null +++ b/socket_udp.c @@ -0,0 +1,16 @@ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include "ndelay.h" +#include "socket.h" + +int socket_udp(void) +{ + int s; + + s = socket(AF_INET,SOCK_DGRAM,0); + if (s == -1) return -1; + if (ndelay_on(s) == -1) { close(s); return -1; } + return s; +} @@ -1,13 +1,13 @@ #ifndef STR_H #define STR_H -extern unsigned int str_copy(); -extern int str_diff(); -extern int str_diffn(); -extern unsigned int str_len(); -extern unsigned int str_chr(); -extern unsigned int str_rchr(); -extern int str_start(); +extern unsigned int str_copy(char *,char *); +extern int str_diff(char *,char *); +extern int str_diffn(char *,char *,unsigned int); +extern unsigned int str_len(char *); +extern unsigned int str_chr(char *,int); +extern unsigned int str_rchr(char *,int); +extern int str_start(char *,char *); #define str_equal(s,t) (!str_diff((s),(t))) @@ -1,8 +1,6 @@ #include "str.h" -unsigned int str_chr(s,c) -register char *s; -int c; +unsigned int str_chr(register char *s,int c) { register char ch; register char *t; diff --git a/str_cpy.c b/str_cpy.c deleted file mode 100644 index 453d790..0000000 --- a/str_cpy.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "str.h" - -unsigned int str_copy(s,t) -register char *s; -register char *t; -{ - register int len; - - len = 0; - for (;;) { - if (!(*s = *t)) return len; ++s; ++t; ++len; - if (!(*s = *t)) return len; ++s; ++t; ++len; - if (!(*s = *t)) return len; ++s; ++t; ++len; - if (!(*s = *t)) return len; ++s; ++t; ++len; - } -} @@ -1,8 +1,6 @@ #include "str.h" -int str_diff(s,t) -register char *s; -register char *t; +int str_diff(register char *s,register char *t) { register char x; diff --git a/str_diffn.c b/str_diffn.c deleted file mode 100644 index 89142f1..0000000 --- a/str_diffn.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "str.h" - -int str_diffn(s,t,len) -register char *s; -register char *t; -unsigned int len; -{ - register char x; - - for (;;) { - if (!len--) return 0; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; - if (!len--) return 0; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; - if (!len--) return 0; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; - if (!len--) return 0; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; - } - return ((int)(unsigned int)(unsigned char) x) - - ((int)(unsigned int)(unsigned char) *t); -} @@ -1,7 +1,6 @@ #include "str.h" -unsigned int str_len(s) -register char *s; +unsigned int str_len(char *s) { register char *t; diff --git a/str_start.c b/str_start.c new file mode 100644 index 0000000..43430bb --- /dev/null +++ b/str_start.c @@ -0,0 +1,13 @@ +#include "str.h" + +int str_start(register char *s,register char *t) +{ + register char x; + + for (;;) { + x = *t++; if (!x) return 1; if (x != *s++) return 0; + x = *t++; if (!x) return 1; if (x != *s++) return 0; + x = *t++; if (!x) return 1; if (x != *s++) return 0; + x = *t++; if (!x) return 1; if (x != *s++) return 0; + } +} diff --git a/stralloc.3 b/stralloc.3 deleted file mode 100644 index 3123521..0000000 --- a/stralloc.3 +++ /dev/null @@ -1,160 +0,0 @@ -.TH stralloc 3 -.SH NAME -stralloc \- dynamically allocated strings -.SH SYNTAX -.B #include <stralloc.h> - -int \fBstralloc_ready\fP(&\fIsa\fR,\fIlen\fR); -.br -int \fBstralloc_readyplus\fP(&\fIsa\fR,\fIlen\fR); - -int \fBstralloc_copy\fP(&\fIsa\fR,&\fIsa2\fR); -.br -int \fBstralloc_copys\fP(&\fIsa\fR,\fIbuf\fR); -.br -int \fBstralloc_copyb\fP(&\fIsa\fR,\fIbuf\fR,\fIlen\fR); - -int \fBstralloc_cat\fP(&\fIsa\fR,&\fIsa2\fR); -.br -int \fBstralloc_cats\fP(&\fIsa\fR,\fIbuf\fR); -.br -int \fBstralloc_catb\fP(&\fIsa\fR,\fIbuf\fR,\fIlen\fR); - -int \fBstralloc_append\fP(&\fIsa\fR,\fIbuf\fR); -.br -int \fBstralloc_0\fP(&\fIsa\fR); - -int \fBstralloc_starts\fP(&\fIsa\fR,\fIbuf\fR); - -stralloc \fIsa\fR = {0}; -.br -stralloc \fIsa2\fR = {0}; -.br -unsigned int \fIlen\fR; -.br -char *\fIbuf\fR; -.SH DESCRIPTION -A -.B stralloc -variable holds a string in dynamically allocated space. -String length is limited only by memory. -String contents are unrestricted. - -The -.B stralloc -structure has three components: -.I sa\fB.s -is a pointer to the string, or 0 if it is not allocated; -.I sa\fB.len -is the number of bytes in the string, if it is allocated; -.I sa\fB.a -is the number of bytes allocated for the string, if it is allocated. -A -.B stralloc -variable should be initialized to {0}, -meaning unallocated. - -.B stralloc_ready -makes sure that -.I sa -has enough space allocated for -.I len -characters. -It allocates extra space if necessary. - -.B stralloc_readyplus -makes sure that -.I sa -has enough space allocated for -.I len -characters more than its current length. -If -.I sa -is unallocated, -.B stralloc_readyplus -is the same as -.BR stralloc_ready . - -.B stralloc_copy -copies -.I sa2 -to -.IR sa , -allocating space if necessary. -Here -.I sa2 -is an allocated -.B stralloc -variable. - -.B stralloc_copys -copies a 0-terminated string, -.IR buf , -to -.IR sa , -without the 0. - -.B stralloc_copyb -copies -.I len -characters from -.I buf -to -.IR sa . - -.B stralloc_cat -appends -.I sa2 -to -.IR sa , -allocating space if necessary. -If -.I sa -is unallocated, -.B stralloc_cat -is the same as -.BR stralloc_copy . - -.B stralloc_cats -and -.B stralloc_catb -are analogous to -.B stralloc_copys -and -.BR stralloc_copyb . - -.B stralloc_append -adds a single character, -.IR *buf , -to -.IR sa , -allocating space if necessary. - -.B stralloc_0 -adds a single 0 character -to -.IR sa . - -.B stralloc_starts -returns 1 if the 0-terminated string -.IR buf , -without the 0, -is a prefix of -.IR sa . -.SH "ERROR HANDLING" -If a -.B stralloc -routine runs out of memory, -it leaves -.I sa -alone and returns 0, -setting -.B errno -appropriately. -On success it returns 1; -this guarantees that -.I sa -is allocated. -.SH "SEE ALSO" -alloc(3), -error(3) @@ -5,25 +5,25 @@ GEN_ALLOC_typedef(stralloc,char,s,len,a) -extern int stralloc_ready(); -extern int stralloc_readyplus(); -extern int stralloc_copy(); -extern int stralloc_cat(); -extern int stralloc_copys(); -extern int stralloc_cats(); -extern int stralloc_copyb(); -extern int stralloc_catb(); -extern int stralloc_append(); /* beware: this takes a pointer to 1 char */ -extern int stralloc_starts(); +extern int stralloc_ready(stralloc *,unsigned int); +extern int stralloc_readyplus(stralloc *,unsigned int); +extern int stralloc_copy(stralloc *,stralloc *); +extern int stralloc_cat(stralloc *,stralloc *); +extern int stralloc_copys(stralloc *,char *); +extern int stralloc_cats(stralloc *,char *); +extern int stralloc_copyb(stralloc *,char *,unsigned int); +extern int stralloc_catb(stralloc *,char *,unsigned int); +extern int stralloc_append(stralloc *,char *); /* beware: this takes a pointer to 1 char */ +extern int stralloc_starts(stralloc *,char *); #define stralloc_0(sa) stralloc_append(sa,"") -extern int stralloc_catulong0(); -extern int stralloc_catlong0(); +extern int stralloc_catulong0(stralloc *,unsigned long,unsigned int); +extern int stralloc_catlong0(stralloc *,long,unsigned int); #define stralloc_catlong(sa,l) (stralloc_catlong0((sa),(l),0)) -#define stralloc_catuint0(sa,i,n) (stralloc_catulong0((sa),(unsigned long) (i),(n))) -#define stralloc_catint0(sa,i,n) (stralloc_catlong0((sa),(long) (i),(n))) -#define stralloc_catint(sa,i) (stralloc_catlong0((sa),(long) (i),0)) +#define stralloc_catuint0(sa,i,n) (stralloc_catulong0((sa),(i),(n))) +#define stralloc_catint0(sa,i,n) (stralloc_catlong0((sa),(i),(n))) +#define stralloc_catint(sa,i) (stralloc_catlong0((sa),(i),0)) #endif diff --git a/stralloc_cat.c b/stralloc_cat.c index efbb112..dd08548 100644 --- a/stralloc_cat.c +++ b/stralloc_cat.c @@ -1,9 +1,7 @@ #include "byte.h" #include "stralloc.h" -int stralloc_cat(sato,safrom) -stralloc *sato; -stralloc *safrom; +int stralloc_cat(stralloc *sato,stralloc *safrom) { return stralloc_catb(sato,safrom->s,safrom->len); } diff --git a/stralloc_catb.c b/stralloc_catb.c index 67dbcc0..b739bed 100644 --- a/stralloc_catb.c +++ b/stralloc_catb.c @@ -1,10 +1,7 @@ #include "stralloc.h" #include "byte.h" -int stralloc_catb(sa,s,n) -stralloc *sa; -char *s; -unsigned int n; +int stralloc_catb(stralloc *sa,char *s,unsigned int n) { if (!sa->s) return stralloc_copyb(sa,s,n); if (!stralloc_readyplus(sa,n + 1)) return 0; diff --git a/stralloc_cats.c b/stralloc_cats.c index d300286..8b11e94 100644 --- a/stralloc_cats.c +++ b/stralloc_cats.c @@ -2,9 +2,7 @@ #include "str.h" #include "stralloc.h" -int stralloc_cats(sa,s) -stralloc *sa; -char *s; +int stralloc_cats(stralloc *sa,char *s) { return stralloc_catb(sa,s,str_len(s)); } diff --git a/stralloc_copy.c b/stralloc_copy.c index 652aed6..02f8c47 100644 --- a/stralloc_copy.c +++ b/stralloc_copy.c @@ -1,9 +1,7 @@ #include "byte.h" #include "stralloc.h" -int stralloc_copy(sato,safrom) -stralloc *sato; -stralloc *safrom; +int stralloc_copy(stralloc *sato,stralloc *safrom) { return stralloc_copyb(sato,safrom->s,safrom->len); } diff --git a/stralloc_opyb.c b/stralloc_opyb.c index ac258b3..46b99fc 100644 --- a/stralloc_opyb.c +++ b/stralloc_opyb.c @@ -1,10 +1,7 @@ #include "stralloc.h" #include "byte.h" -int stralloc_copyb(sa,s,n) -stralloc *sa; -char *s; -unsigned int n; +int stralloc_copyb(stralloc *sa,char *s,unsigned int n) { if (!stralloc_ready(sa,n + 1)) return 0; byte_copy(sa->s,n,s); diff --git a/stralloc_opys.c b/stralloc_opys.c index fdd7807..78594b0 100644 --- a/stralloc_opys.c +++ b/stralloc_opys.c @@ -2,9 +2,7 @@ #include "str.h" #include "stralloc.h" -int stralloc_copys(sa,s) -stralloc *sa; -char *s; +int stralloc_copys(stralloc *sa,char *s) { return stralloc_copyb(sa,s,str_len(s)); } @@ -1,21 +1,19 @@ #ifndef STRERR_H #define STRERR_H -struct strerr - { +struct strerr { struct strerr *who; char *x; char *y; char *z; - } -; +} ; extern struct strerr strerr_sys; -extern void strerr_sysinit(); +extern void strerr_sysinit(void); -extern char *strerr(); -extern void strerr_warn(); -extern void strerr_die(); +extern char *strerr(struct strerr *); +extern void strerr_warn(char *,char *,char *,char *,char *,char *,struct strerr *); +extern void strerr_die(int,char *,char *,char *,char *,char *,char *,struct strerr *); #define STRERR(r,se,a) \ { se.who = 0; se.x = a; se.y = 0; se.z = 0; return r; } @@ -26,55 +24,55 @@ extern void strerr_die(); { se.who = &strerr_sys; se.x = a; se.y = b; se.z = c; return r; } #define strerr_warn6(x1,x2,x3,x4,x5,x6,se) \ -strerr_warn((x1),(x2),(x3),(x4),(x5),(x6),(struct strerr *) (se)) +strerr_warn((x1),(x2),(x3),(x4),(x5),(x6),(se)) #define strerr_warn5(x1,x2,x3,x4,x5,se) \ -strerr_warn((x1),(x2),(x3),(x4),(x5),(char *) 0,(struct strerr *) (se)) +strerr_warn((x1),(x2),(x3),(x4),(x5),0,(se)) #define strerr_warn4(x1,x2,x3,x4,se) \ -strerr_warn((x1),(x2),(x3),(x4),(char *) 0,(char *) 0,(struct strerr *) (se)) +strerr_warn((x1),(x2),(x3),(x4),0,0,(se)) #define strerr_warn3(x1,x2,x3,se) \ -strerr_warn((x1),(x2),(x3),(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se)) +strerr_warn((x1),(x2),(x3),0,0,0,(se)) #define strerr_warn2(x1,x2,se) \ -strerr_warn((x1),(x2),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se)) +strerr_warn((x1),(x2),0,0,0,0,(se)) #define strerr_warn1(x1,se) \ -strerr_warn((x1),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se)) +strerr_warn((x1),0,0,0,0,0,(se)) #define strerr_die6(e,x1,x2,x3,x4,x5,x6,se) \ -strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),(struct strerr *) (se)) +strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),(se)) #define strerr_die5(e,x1,x2,x3,x4,x5,se) \ -strerr_die((e),(x1),(x2),(x3),(x4),(x5),(char *) 0,(struct strerr *) (se)) +strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,(se)) #define strerr_die4(e,x1,x2,x3,x4,se) \ -strerr_die((e),(x1),(x2),(x3),(x4),(char *) 0,(char *) 0,(struct strerr *) (se)) +strerr_die((e),(x1),(x2),(x3),(x4),0,0,(se)) #define strerr_die3(e,x1,x2,x3,se) \ -strerr_die((e),(x1),(x2),(x3),(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se)) +strerr_die((e),(x1),(x2),(x3),0,0,0,(se)) #define strerr_die2(e,x1,x2,se) \ -strerr_die((e),(x1),(x2),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se)) +strerr_die((e),(x1),(x2),0,0,0,0,(se)) #define strerr_die1(e,x1,se) \ -strerr_die((e),(x1),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) (se)) +strerr_die((e),(x1),0,0,0,0,0,(se)) #define strerr_die6sys(e,x1,x2,x3,x4,x5,x6) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),&strerr_sys) #define strerr_die5sys(e,x1,x2,x3,x4,x5) \ -strerr_die((e),(x1),(x2),(x3),(x4),(x5),(char *) 0,&strerr_sys) +strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,&strerr_sys) #define strerr_die4sys(e,x1,x2,x3,x4) \ -strerr_die((e),(x1),(x2),(x3),(x4),(char *) 0,(char *) 0,&strerr_sys) +strerr_die((e),(x1),(x2),(x3),(x4),0,0,&strerr_sys) #define strerr_die3sys(e,x1,x2,x3) \ -strerr_die((e),(x1),(x2),(x3),(char *) 0,(char *) 0,(char *) 0,&strerr_sys) +strerr_die((e),(x1),(x2),(x3),0,0,0,&strerr_sys) #define strerr_die2sys(e,x1,x2) \ -strerr_die((e),(x1),(x2),(char *) 0,(char *) 0,(char *) 0,(char *) 0,&strerr_sys) +strerr_die((e),(x1),(x2),0,0,0,0,&strerr_sys) #define strerr_die1sys(e,x1) \ -strerr_die((e),(x1),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(char *) 0,&strerr_sys) +strerr_die((e),(x1),0,0,0,0,0,&strerr_sys) #define strerr_die6x(e,x1,x2,x3,x4,x5,x6) \ -strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),(struct strerr *) 0) +strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),0) #define strerr_die5x(e,x1,x2,x3,x4,x5) \ -strerr_die((e),(x1),(x2),(x3),(x4),(x5),(char *) 0,(struct strerr *) 0) +strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,0) #define strerr_die4x(e,x1,x2,x3,x4) \ -strerr_die((e),(x1),(x2),(x3),(x4),(char *) 0,(char *) 0,(struct strerr *) 0) +strerr_die((e),(x1),(x2),(x3),(x4),0,0,0) #define strerr_die3x(e,x1,x2,x3) \ -strerr_die((e),(x1),(x2),(x3),(char *) 0,(char *) 0,(char *) 0,(struct strerr *) 0) +strerr_die((e),(x1),(x2),(x3),0,0,0,0) #define strerr_die2x(e,x1,x2) \ -strerr_die((e),(x1),(x2),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) 0) +strerr_die((e),(x1),(x2),0,0,0,0,0) #define strerr_die1x(e,x1) \ -strerr_die((e),(x1),(char *) 0,(char *) 0,(char *) 0,(char *) 0,(char *) 0,(struct strerr *) 0) +strerr_die((e),(x1),0,0,0,0,0,0) #endif diff --git a/strerr_die.c b/strerr_die.c index 6092020..850028b 100644 --- a/strerr_die.c +++ b/strerr_die.c @@ -1,36 +1,30 @@ -#include "substdio.h" -#include "subfd.h" +#include "buffer.h" #include "exit.h" #include "strerr.h" -void strerr_warn(x1,x2,x3,x4,x5,x6,se) -char *x1; char *x2; char *x3; char *x4; char *x5; char *x6; -struct strerr *se; +void strerr_warn(char *x1,char *x2,char *x3,char *x4,char *x5,char *x6,struct strerr *se) { strerr_sysinit(); - if (x1) substdio_puts(subfderr,x1); - if (x2) substdio_puts(subfderr,x2); - if (x3) substdio_puts(subfderr,x3); - if (x4) substdio_puts(subfderr,x4); - if (x5) substdio_puts(subfderr,x5); - if (x6) substdio_puts(subfderr,x6); + if (x1) buffer_puts(buffer_2,x1); + if (x2) buffer_puts(buffer_2,x2); + if (x3) buffer_puts(buffer_2,x3); + if (x4) buffer_puts(buffer_2,x4); + if (x5) buffer_puts(buffer_2,x5); + if (x6) buffer_puts(buffer_2,x6); while(se) { - if (se->x) substdio_puts(subfderr,se->x); - if (se->y) substdio_puts(subfderr,se->y); - if (se->z) substdio_puts(subfderr,se->z); + if (se->x) buffer_puts(buffer_2,se->x); + if (se->y) buffer_puts(buffer_2,se->y); + if (se->z) buffer_puts(buffer_2,se->z); se = se->who; } - substdio_puts(subfderr,"\n"); - substdio_flush(subfderr); + buffer_puts(buffer_2,"\n"); + buffer_flush(buffer_2); } -void strerr_die(e,x1,x2,x3,x4,x5,x6,se) -int e; -char *x1; char *x2; char *x3; char *x4; char *x5; char *x6; -struct strerr *se; +void strerr_die(int e,char *x1,char *x2,char *x3,char *x4,char *x5,char *x6,struct strerr *se) { strerr_warn(x1,x2,x3,x4,x5,x6,se); _exit(e); diff --git a/strerr_sys.c b/strerr_sys.c index 198198b..b484197 100644 --- a/strerr_sys.c +++ b/strerr_sys.c @@ -3,7 +3,7 @@ struct strerr strerr_sys; -void strerr_sysinit() +void strerr_sysinit(void) { strerr_sys.who = 0; strerr_sys.x = error_str(errno); diff --git a/subfd.h b/subfd.h deleted file mode 100644 index bcb2e1e..0000000 --- a/subfd.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef SUBFD_H -#define SUBFD_H - -#include "substdio.h" - -extern substdio *subfdin; -extern substdio *subfdinsmall; -extern substdio *subfdout; -extern substdio *subfdoutsmall; -extern substdio *subfderr; - -extern int subfd_read(); -extern int subfd_readsmall(); - -#endif diff --git a/subfderr.c b/subfderr.c deleted file mode 100644 index 011ab0f..0000000 --- a/subfderr.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "readwrite.h" -#include "substdio.h" -#include "subfd.h" - -char subfd_errbuf[256]; -static substdio it = SUBSTDIO_FDBUF(write,2,subfd_errbuf,256); -substdio *subfderr = ⁢ diff --git a/subfdin.c b/subfdin.c deleted file mode 100644 index a11d323..0000000 --- a/subfdin.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "readwrite.h" -#include "substdio.h" -#include "subfd.h" - -int subfd_read(fd,buf,len) int fd; char *buf; int len; -{ - if (substdio_flush(subfdout) == -1) return -1; - return read(fd,buf,len); -} - -char subfd_inbuf[SUBSTDIO_INSIZE]; -static substdio it = SUBSTDIO_FDBUF(subfd_read,0,subfd_inbuf,SUBSTDIO_INSIZE); -substdio *subfdin = ⁢ diff --git a/subfdout.c b/subfdout.c deleted file mode 100644 index 0aee102..0000000 --- a/subfdout.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "readwrite.h" -#include "substdio.h" -#include "subfd.h" - -char subfd_outbuf[SUBSTDIO_OUTSIZE]; -static substdio it = SUBSTDIO_FDBUF(write,1,subfd_outbuf,SUBSTDIO_OUTSIZE); -substdio *subfdout = ⁢ diff --git a/subgetopt.3 b/subgetopt.3 deleted file mode 100644 index aae03aa..0000000 --- a/subgetopt.3 +++ /dev/null @@ -1,357 +0,0 @@ -.TH subgetopt 3 -.SH NAME -subgetopt \- get option character from command line -.SH SYNTAX -.B #include <subgetopt.h> - -char *\fBsgoptarg\fP; -.br -int \fBsgoptind\fP; -.br -int \fBsgoptpos\fP; -.br -int \fBsgoptdone\fP; -.br -int \fBsgoptproblem\fP; - -int \fBsgopt(\fP\fIargc,argv,opts\fR\fB)\fP; - -int \fIargc\fR; -.br -char **\fIargv\fR; -.br -char *\fIopts\fR; -.SH DESCRIPTION -.B sgopt -returns the next valid command-line option character -from -.IR argv . - -Valid option characters are listed in the -.I opts -string. -.I opts -may be empty. -A character in -.I opts -may be followed by a colon, -in which case it -takes an -.I option argument\fR. -Avoid using the characters ?, :, and \- as option characters. - -Below -.I option argument -is abbreviated -as -.I optarg -and -.I command-line argument -is abbreviated as -.IR cmdarg . - -Options are listed in cmdargs which begin with -a minus sign. -Several options which do not take optargs may be combined -into one cmdarg. - -An option which takes an optarg may be handled in two ways. -If it appears at the very end of a cmdarg, -then the entire next cmdarg is the optarg. -But if there are any characters in the cmdarg -after the option character, -then those characters form the optarg. -The optarg is returned in -.BR sgoptarg . -Next time -.B sgopt -looks at the cmdarg which follows the optarg. - -If a cmdarg does not begin with a hyphen, -or if it is a lone hyphen not followed by any characters, -or if it begins with two hyphens, -then it terminates option processing, -and -.B sgopt -returns an appropriate code. -If there are two hyphens, -.B sgopt -will advance attention to the next cmdarg, -so it can be called again to read further options. -.SH "PROPER USAGE" -.B sgoptproblem -should be used only when -.B sgopt -returns ?. -.B sgoptind -and -.B sgoptpos -are defined all the time. -.B sgoptarg -is defined all the time; -it is null unless -.B sgopt -has just returned an option with optarg. - -.B sgopt -is typically used as follows. - -.EX -#include <subgetopt.h> - -main(argc,argv) int argc; char **argv; { int opt; - -while ((opt = sgopt(argc,argv,"a:s")) != sgoptdone) -.br - switch(opt) { -.br - case 'a': -.br - printf("opt a with optarg %s\\n",sgoptarg); break; -.br - case 's': -.br - printf("opt s with no optarg\\n"); break; -.br - case '?': -.br - if (argv[sgoptind] && (sgoptind < argc)) -.br - printf("illegal opt %c\\n",sgoptproblem); -.br - else -.br - printf("missing arg, opt %c\\n",sgoptproblem); -.br - exit(1); -.br - } - -argv += sgoptind; -.br -while (*argv) printf("argument %s\\n",*argv++); -.br -exit(0); -.br -} -.EE - -The end of the command line is -marked by either -.IR argc , -or a null pointer in -.IR argv , -whichever comes first. -Normally -these two markers coincide, -so it is redundant -to test for -both -.I argv\fB[sgoptind] -and -.B sgoptind < \fIargc\fR. -The above code shows both tests as an illustration. - -.B Multiple option sets: -One useful technique is to call -.B sgopt -with a primary -.I opts -until it returns EOF, -then call -.B sgopt -with a secondary -.I opts -until it returns EOF. -The user can provide primary options, then a double hyphen, -and then secondary options. -No special handling is needed if some or all of the options are -omitted. -The same technique can be used for any number of option sets -in series. - -.B Multiple command lines: -Before parsing a new -.BR argv , -make sure to -set -.B sgoptind -and -.B sgoptpos -back to -1 and 0. -.SH "PARSING STAGES" -.B sgopt -keeps track of its position in -.I argv -with -.B sgoptind -and -.BR sgoptpos , -which are initialized to 1 and 0. -It looks at -.I argv\fB[sgoptind][sgoptpos] -and following characters. - -.B sgopt -indicates -that no more options are available by -returning -.BR sgoptdone , -which is initialized to -.BR SUBGETOPTDONE , -which is defined as \-1. - -.B sgopt -begins by setting -.B optarg -to null. - -.B Ending conditions: -If -.I argv -is null, or -.B sgoptind -is larger than -.IR argc , -or the current cmdarg -.I argv\fB[sgoptind] -is null, -then -.B sgopt -returns -.BR optdone . - -.B Stage one: -If the current character -is zero, -.B sgopt -moves to the beginning of the next cmdarg. -It then checks the ending conditions again. - -.B Stage two: -If -the current position is the begining of the cmdarg, -.B sgopt -checks whether -the current character -is a minus sign. -If not it returns -.BR optdone . -It then -moves -to the next character. -If that character is zero, -.B sgopt -moves -back to the beginning of the cmdarg, -and returns -.BR sgoptdone . -If the character is a minus sign, -.B sgopt -moves to the beginning of the next cmdarg, -and returns -.BR sgoptdone . - -.B Stage three: -.B sgopt -records the current character, -.IR c , -and moves to the next character. -There are three possibilities: -(1) -.I c -is an option character without optarg in -.IR opts , -or -(2) -.I c -is an option character with optarg in -.IR opts , -or -(3) -.I c -does not appear in -.IR opts . - -(1) -If -.I c -appears as an option character without optarg in -.IR opts , -.B sgopt -returns -.IR c . - -(2) -If -.I c -appears as an option character with optarg in -.IR opts , -.B sgopt -sets -.B sgoptarg -to the current position, -and moves to the next cmdarg. -If -.B sgoptarg -is nonempty, -.B sgopt -returns -.IR c . - -Then -.B sgopt -sets -.B sgoptarg -to -the current cmdarg. -If -the current cmdarg is null, -or past -.IR argc , -.B sgopt -sets -.B sgoptproblem -to -.I c -and returns ?. -Otherwise -.B sgopt -moves to the next -argument -and returns -.IR c . - -(2) -If -.I c -does not appear in -.IR opts , -.B sgopt -sets -.B sgoptproblem -to -.I c -and returns ?. -.SH "SYNTAX NOTE" -.B sgopt -is actually a macro abbreviation for -.BR subgetopt . -The external -.B sg -variables are also macros -for -.BR subget . -These macros are defined in -.BR <subgetopt.h> , -unless -.B SUBGETOPTNOSHORT -is defined -when -.B <subgetopt.h> -is included. -.SH VERSION -subgetopt version 0.9, 931129. -.SH AUTHOR -Placed into the public domain by Daniel J. Bernstein. diff --git a/subgetopt.c b/subgetopt.c index dacf376..552c4de 100644 --- a/subgetopt.c +++ b/subgetopt.c @@ -1,14 +1,3 @@ -/* subgetopt.c, subgetopt.h: (yet another) improved getopt clone, inner layer -D. J. Bernstein, djb@pobox.com. -No dependencies. -No system requirements. -19970228: Cleanups. -931129: Adapted from getopt.c. -No known patent problems. - -Documentation in subgetopt.3. -*/ - #define SUBGETOPTNOSHORT #include "subgetopt.h" @@ -25,10 +14,7 @@ char *optarg = 0; int optproblem = 0; int optdone = SUBGETOPTDONE; -int sgopt(argc,argv,opts) -int argc; -char **argv; -char *opts; +int sgopt(int argc,char **argv,char *opts) { int c; char *s; diff --git a/subgetopt.h b/subgetopt.h index d26c62a..b4b63e1 100644 --- a/subgetopt.h +++ b/subgetopt.h @@ -13,7 +13,7 @@ #define SUBGETOPTDONE -1 -extern int subgetopt(); +extern int subgetopt(int,char **,char *); extern char *subgetoptarg; extern int subgetoptind; extern int subgetoptpos; diff --git a/substdi.c b/substdi.c deleted file mode 100644 index 42407a1..0000000 --- a/substdi.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "substdio.h" -#include "byte.h" -#include "error.h" - -static int oneread(op,fd,buf,len) -register int (*op)(); -register int fd; -register char *buf; -register int len; -{ - register int r; - - for (;;) { - r = op(fd,buf,len); - if (r == -1) if (errno == error_intr) continue; - return r; - } -} - -static int getthis(s,buf,len) -register substdio *s; -register char *buf; -register int len; -{ - register int r; - register int q; - - r = s->p; - q = r - len; - if (q > 0) { r = len; s->p = q; } else s->p = 0; - byte_copy(buf,r,s->x + s->n); - s->n += r; - return r; -} - -int substdio_feed(s) -register substdio *s; -{ - register int r; - register int q; - - if (s->p) return s->p; - q = s->n; - r = oneread(s->op,s->fd,s->x,q); - if (r <= 0) return r; - s->p = r; - q -= r; - s->n = q; - if (q > 0) /* damn, gotta shift */ byte_copyr(s->x + q,r,s->x); - return r; -} - -int substdio_bget(s,buf,len) -register substdio *s; -register char *buf; -register int len; -{ - register int r; - - if (s->p > 0) return getthis(s,buf,len); - r = s->n; if (r <= len) return oneread(s->op,s->fd,buf,r); - r = substdio_feed(s); if (r <= 0) return r; - return getthis(s,buf,len); -} - -int substdio_get(s,buf,len) -register substdio *s; -register char *buf; -register int len; -{ - register int r; - - if (s->p > 0) return getthis(s,buf,len); - if (s->n <= len) return oneread(s->op,s->fd,buf,len); - r = substdio_feed(s); if (r <= 0) return r; - return getthis(s,buf,len); -} - -char *substdio_peek(s) -register substdio *s; -{ - return s->x + s->n; -} - -void substdio_seek(s,len) -register substdio *s; -register int len; -{ - s->n += len; - s->p -= len; -} diff --git a/substdio.c b/substdio.c deleted file mode 100644 index d03dff2..0000000 --- a/substdio.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "substdio.h" - -void substdio_fdbuf(s,op,fd,buf,len) -register substdio *s; -register int (*op)(); -register int fd; -register char *buf; -register int len; -{ - s->x = buf; - s->fd = fd; - s->op = op; - s->p = 0; - s->n = len; -} diff --git a/substdio.h b/substdio.h deleted file mode 100644 index c3f7f7d..0000000 --- a/substdio.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef SUBSTDIO_H -#define SUBSTDIO_H - -typedef struct substdio { - char *x; - int p; - int n; - int fd; - int (*op)(); -} substdio; - -#define SUBSTDIO_FDBUF(op,fd,buf,len) { (buf), 0, (len), (fd), (op) } - -extern void substdio_fdbuf(); - -extern int substdio_flush(); -extern int substdio_put(); -extern int substdio_bput(); -extern int substdio_putflush(); -extern int substdio_puts(); -extern int substdio_bputs(); -extern int substdio_putsflush(); - -extern int substdio_get(); -extern int substdio_bget(); -extern int substdio_feed(); - -extern char *substdio_peek(); -extern void substdio_seek(); - -#define substdio_fileno(s) ((s)->fd) - -#define SUBSTDIO_INSIZE 8192 -#define SUBSTDIO_OUTSIZE 8192 - -#define substdio_PEEK(s) ( (s)->x + (s)->n ) -#define substdio_SEEK(s,len) ( ( (s)->p -= (len) ) , ( (s)->n += (len) ) ) - -#define substdio_BPUTC(s,c) \ - ( ((s)->n != (s)->p) \ - ? ( (s)->x[(s)->p++] = (c), 0 ) \ - : substdio_bput((s),&(c),1) \ - ) - -extern int substdio_copy(); - -#endif diff --git a/substdio_copy.c b/substdio_copy.c deleted file mode 100644 index 71cf200..0000000 --- a/substdio_copy.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "substdio.h" - -int substdio_copy(ssout,ssin) -register substdio *ssout; -register substdio *ssin; -{ - register int n; - register char *x; - - for (;;) { - n = substdio_feed(ssin); - if (n < 0) return -2; - if (!n) return 0; - x = substdio_PEEK(ssin); - if (substdio_put(ssout,x,n) == -1) return -3; - substdio_SEEK(ssin,n); - } -} diff --git a/substdo.c b/substdo.c deleted file mode 100644 index fb616f7..0000000 --- a/substdo.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "substdio.h" -#include "str.h" -#include "byte.h" -#include "error.h" - -static int allwrite(op,fd,buf,len) -register int (*op)(); -register int fd; -register char *buf; -register int len; -{ - register int w; - - while (len) { - w = op(fd,buf,len); - if (w == -1) { - if (errno == error_intr) continue; - return -1; /* note that some data may have been written */ - } - if (w == 0) ; /* luser's fault */ - buf += w; - len -= w; - } - return 0; -} - -int substdio_flush(s) -register substdio *s; -{ - register int p; - - p = s->p; - if (!p) return 0; - s->p = 0; - return allwrite(s->op,s->fd,s->x,p); -} - -int substdio_bput(s,buf,len) -register substdio *s; -register char *buf; -register int len; -{ - register int n; - - while (len > (n = s->n - s->p)) { - byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n; - if (substdio_flush(s) == -1) return -1; - } - /* now len <= s->n - s->p */ - byte_copy(s->x + s->p,len,buf); - s->p += len; - return 0; -} - -int substdio_put(s,buf,len) -register substdio *s; -register char *buf; -register int len; -{ - register int n; - - n = s->n; - if (len > n - s->p) { - if (substdio_flush(s) == -1) return -1; - /* now s->p == 0 */ - if (n < SUBSTDIO_OUTSIZE) n = SUBSTDIO_OUTSIZE; - while (len > s->n) { - if (n > len) n = len; - if (allwrite(s->op,s->fd,buf,n) == -1) return -1; - buf += n; - len -= n; - } - } - /* now len <= s->n - s->p */ - byte_copy(s->x + s->p,len,buf); - s->p += len; - return 0; -} - -int substdio_putflush(s,buf,len) -register substdio *s; -register char *buf; -register int len; -{ - if (substdio_flush(s) == -1) return -1; - return allwrite(s->op,s->fd,buf,len); -} - -int substdio_bputs(s,buf) -register substdio *s; -register char *buf; -{ - return substdio_bput(s,buf,str_len(buf)); -} - -int substdio_puts(s,buf) -register substdio *s; -register char *buf; -{ - return substdio_put(s,buf,str_len(buf)); -} - -int substdio_putsflush(s,buf) -register substdio *s; -register char *buf; -{ - return substdio_putflush(s,buf,str_len(buf)); -} @@ -0,0 +1,26 @@ +#ifndef TAI_H +#define TAI_H + +#include "uint64.h" + +struct tai { + uint64 x; +} ; + +#define tai_unix(t,u) ((void) ((t)->x = 4611686018427387914ULL + (uint64) (u))) + +extern void tai_now(struct tai *); + +#define tai_approx(t) ((double) ((t)->x)) + +extern void tai_add(struct tai *,struct tai *,struct tai *); +extern void tai_sub(struct tai *,struct tai *,struct tai *); +#define tai_less(t,u) ((t)->x < (u)->x) + +#define TAI_PACK 8 +extern void tai_pack(char *,struct tai *); +extern void tai_unpack(char *,struct tai *); + +extern void tai_uint(struct tai *,unsigned int); + +#endif diff --git a/tai_pack.c b/tai_pack.c new file mode 100644 index 0000000..5e662cf --- /dev/null +++ b/tai_pack.c @@ -0,0 +1,16 @@ +#include "tai.h" + +void tai_pack(char *s,struct tai *t) +{ + uint64 x; + + x = t->x; + s[7] = x & 255; x >>= 8; + s[6] = x & 255; x >>= 8; + s[5] = x & 255; x >>= 8; + s[4] = x & 255; x >>= 8; + s[3] = x & 255; x >>= 8; + s[2] = x & 255; x >>= 8; + s[1] = x & 255; x >>= 8; + s[0] = x; +} @@ -0,0 +1,33 @@ +#ifndef TAIA_H +#define TAIA_H + +#include "tai.h" + +struct taia { + struct tai sec; + unsigned long nano; /* 0...999999999 */ + unsigned long atto; /* 0...999999999 */ +} ; + +extern void taia_tai(struct taia *,struct tai *); + +extern void taia_now(struct taia *); + +extern double taia_approx(struct taia *); +extern double taia_frac(struct taia *); + +extern void taia_add(struct taia *,struct taia *,struct taia *); +extern void taia_sub(struct taia *,struct taia *,struct taia *); +extern void taia_half(struct taia *,struct taia *); +extern int taia_less(struct taia *,struct taia *); + +#define TAIA_PACK 16 +extern void taia_pack(char *,struct taia *); +extern void taia_unpack(char *,struct taia *); + +#define TAIA_FMTFRAC 19 +extern unsigned int taia_fmtfrac(char *,struct taia *); + +extern void taia_uint(struct taia *,unsigned int); + +#endif diff --git a/taia_add.c b/taia_add.c new file mode 100644 index 0000000..a596cc8 --- /dev/null +++ b/taia_add.c @@ -0,0 +1,18 @@ +#include "taia.h" + +/* XXX: breaks tai encapsulation */ + +void taia_add(struct taia *t,struct taia *u,struct taia *v) +{ + t->sec.x = u->sec.x + v->sec.x; + t->nano = u->nano + v->nano; + t->atto = u->atto + v->atto; + if (t->atto > 999999999UL) { + t->atto -= 1000000000UL; + ++t->nano; + } + if (t->nano > 999999999UL) { + t->nano -= 1000000000UL; + ++t->sec.x; + } +} diff --git a/taia_approx.c b/taia_approx.c new file mode 100644 index 0000000..0c4d0de --- /dev/null +++ b/taia_approx.c @@ -0,0 +1,6 @@ +#include "taia.h" + +double taia_approx(struct taia *t) +{ + return tai_approx(&t->sec) + taia_frac(t); +} diff --git a/taia_frac.c b/taia_frac.c new file mode 100644 index 0000000..89a1aac --- /dev/null +++ b/taia_frac.c @@ -0,0 +1,6 @@ +#include "taia.h" + +double taia_frac(struct taia *t) +{ + return (t->atto * 0.000000001 + t->nano) * 0.000000001; +} diff --git a/taia_less.c b/taia_less.c new file mode 100644 index 0000000..13b7288 --- /dev/null +++ b/taia_less.c @@ -0,0 +1,12 @@ +#include "taia.h" + +/* XXX: breaks tai encapsulation */ + +int taia_less(struct taia *t,struct taia *u) +{ + if (t->sec.x < u->sec.x) return 1; + if (t->sec.x > u->sec.x) return 0; + if (t->nano < u->nano) return 1; + if (t->nano > u->nano) return 0; + return t->atto < u->atto; +} diff --git a/taia_now.c b/taia_now.c new file mode 100644 index 0000000..ccc260d --- /dev/null +++ b/taia_now.c @@ -0,0 +1,12 @@ +#include <sys/types.h> +#include <sys/time.h> +#include "taia.h" + +void taia_now(struct taia *t) +{ + struct timeval now; + gettimeofday(&now,(struct timezone *) 0); + tai_unix(&t->sec,now.tv_sec); + t->nano = 1000 * now.tv_usec + 500; + t->atto = 0; +} diff --git a/taia_pack.c b/taia_pack.c new file mode 100644 index 0000000..1f1b051 --- /dev/null +++ b/taia_pack.c @@ -0,0 +1,20 @@ +#include "taia.h" + +void taia_pack(char *s,struct taia *t) +{ + unsigned long x; + + tai_pack(s,&t->sec); + s += 8; + + x = t->atto; + s[7] = x & 255; x >>= 8; + s[6] = x & 255; x >>= 8; + s[5] = x & 255; x >>= 8; + s[4] = x; + x = t->nano; + s[3] = x & 255; x >>= 8; + s[2] = x & 255; x >>= 8; + s[1] = x & 255; x >>= 8; + s[0] = x; +} diff --git a/taia_sub.c b/taia_sub.c new file mode 100644 index 0000000..7956647 --- /dev/null +++ b/taia_sub.c @@ -0,0 +1,21 @@ +#include "taia.h" + +/* XXX: breaks tai encapsulation */ + +void taia_sub(struct taia *t,struct taia *u,struct taia *v) +{ + unsigned long unano = u->nano; + unsigned long uatto = u->atto; + + t->sec.x = u->sec.x - v->sec.x; + t->nano = unano - v->nano; + t->atto = uatto - v->atto; + if (t->atto > uatto) { + t->atto += 1000000000UL; + --t->nano; + } + if (t->nano > unano) { + t->nano += 1000000000UL; + --t->sec.x; + } +} diff --git a/taia_uint.c b/taia_uint.c new file mode 100644 index 0000000..167936c --- /dev/null +++ b/taia_uint.c @@ -0,0 +1,10 @@ +#include "taia.h" + +/* XXX: breaks tai encapsulation */ + +void taia_uint(struct taia *t,unsigned int s) +{ + t->sec.x = s; + t->nano = 0; + t->atto = 0; +} diff --git a/tcp-environ.5 b/tcp-environ.5 deleted file mode 100644 index b5cb83b..0000000 --- a/tcp-environ.5 +++ /dev/null @@ -1,62 +0,0 @@ -.TH tcp-environ 5 -.SH NAME -tcp-environ \- TCP-related environment variables -.SH DESCRIPTION -The following environment variables -describe a TCP connection. -They are set up by -.BR tcp-env , -.BR tcpclient , -and -.BR tcpserver . -Note that -.BR TCPLOCALHOST , -.BR TCPREMOTEHOST , -and -.B TCPREMOTEINFO -can contain arbitrary characters. -.TP 5 -PROTO -The string -.BR TCP . -.TP 5 -TCPLOCALHOST -The domain name of the local host, -with uppercase letters converted to lowercase. -If there is no currently available domain name -for the local IP address, -.B TCPLOCALHOST -is not set. -.TP 5 -TCPLOCALIP -The IP address of the local host, in dotted-decimal form. -.TP 5 -TCPLOCALPORT -The local TCP port number, in decimal. -.TP 5 -TCPREMOTEHOST -The domain name of the remote host, -with uppercase letters converted to lowercase. -If there is no currently available domain name -for the remote IP address, -.B TCPREMOTEHOST -is not set. -.TP 5 -TCPREMOTEINFO -A connection-specific string, perhaps a username, -supplied by the remote host -via 931/1413/IDENT/TAP. -If the remote host did not supply connection information, -.B TCPREMOTEINFO -is not set. -.TP 5 -TCPREMOTEIP -The IP address of the remote host. -.TP 5 -TCPREMOTEPORT -The remote TCP port number. -.SH "SEE ALSO" -tcpclient(1), -tcpserver(1), -tcp-env(1), -tcp(4) diff --git a/tcpcat.1 b/tcpcat.1 deleted file mode 100644 index 4c51ed5..0000000 --- a/tcpcat.1 +++ /dev/null @@ -1,20 +0,0 @@ -.TH tcpcat 1 -.SH NAME -tcpcat \- print data from a TCP port -.SH SYNTAX -.B tcpcat -.I host -.I port -.SH DESCRIPTION -.B tcpcat -connects to -.I port -on -.I host -and prints any data it receives. - -.B tcpcat -can be used to transfer binary data. -It does no conversions. -.SH "SEE ALSO" -tcpclient(1) diff --git a/tcpclient.1 b/tcpclient.1 deleted file mode 100644 index c60ed34..0000000 --- a/tcpclient.1 +++ /dev/null @@ -1,151 +0,0 @@ -.TH tcpclient 1 -.SH NAME -tcpclient \- create an outgoing TCP connection -.SH SYNOPSIS -.B tcpclient -[ -.B \-hHrRdDqQv -] -[ -.B \-i\fIlocalip -] -[ -.B \-p\fIlocalport -] -[ -.B \-T\fItimeoutconn -] -[ -.B \-l\fIlocalname -] -[ -.B \-t\fItimeoutinfo -] -.I host -.I port -.I program -[ -.I arg ... -] -.SH DESCRIPTION -.B tcpclient -attempts to connect to a TCP server. -If it is successful, it runs -.I program -with the given arguments, -with descriptor 6 reading from the network -and descriptor 7 writing to the network. - -The server's address is given by -.I host -and -.IR port . -.I host -may be 0, referring to the local machine, -or a dotted-decimal IP address, -or a host name; -if a host has several IP addresses, -.B tcpclient -tries each in turn. -.I port -may be a numeric port number -or a port name. - -.B tcpclient -sets up several environment variables, -as described in -.B tcp-environ(5). -.SH OPTIONS -.TP -.B \-i\fIlocalip -Use -.I localip -as the IP address for the local side of the connection; -quit if -.I localip -is not available. -.TP -.B \-p\fIlocalport -Use -.I localport -as the port number for the local side of the connection; -quit if -.I localport -is not available. -.TP -.B \-T\fItimeoutconn -Give up on the -connection attempt -after -.I timeoutconn -seconds. Default: 60. -This timeout applies to each IP address tried. -.TP -.B \-d -(Default.) -Delay sending data for a fraction of a second whenever the -remote host is responding slowly, -to make better use of the network. -.TP -.B \-D -Never delay sending data; -enable TCP_NODELAY. -This is appropriate for interactive connections. -.TP -.B \-q -Quiet. -Do not print any messages. -.TP -.B \-Q -(Default.) -Print error messages. -.TP -.B \-v -Verbose. -Print all available messages. -.SH "DATA-GATHERING OPTIONS" -.TP -.B \-h -(Default.) -Look up the remote host name for -.BR TCPREMOTEHOST . -.TP -.B \-H -Do not look up the remote host name; -unset -.BR TCPREMOTEHOST . -.TP -.B \-l\fIlocalname -Do not look up the local host name; -use -.I localname -for -.BR TCPLOCALHOST . -.TP -.B \-r -(Default.) -Attempt to obtain -.B TCPREMOTEINFO -from the remote host. -.TP -.B \-R -Do not attempt to obtain -.B TCPREMOTEINFO -from the remote host. -.TP -.B \-t\fItimeoutinfo -Give up on the -.B TCPREMOTEINFO -connection attempt -after -.I timeoutinfo -seconds. Default: 26. -.SH "SEE ALSO" -date@(1), -finger@(1), -http@(1), -mconnect(1), -tcpcat(1), -tcpserver(1), -who@(1), -tcp-environ(5) diff --git a/tcpclient.c b/tcpclient.c index cd72663..9f6d7f2 100644 --- a/tcpclient.c +++ b/tcpclient.c @@ -1,47 +1,34 @@ #include <sys/types.h> #include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> #include <netdb.h> - -#include "strerr.h" -#include "stralloc.h" -#include "str.h" -#include "byte.h" #include "sig.h" -#include "fd.h" -#include "ip.h" -#include "ipalloc.h" -#include "case.h" -#include "sgetopt.h" #include "exit.h" -#include "scan.h" +#include "sgetopt.h" +#include "uint16.h" #include "fmt.h" -#include "env.h" -#include "dns.h" +#include "scan.h" +#include "str.h" +#include "ip4.h" +#include "uint16.h" +#include "socket.h" +#include "fd.h" +#include "stralloc.h" +#include "buffer.h" +#include "error.h" +#include "strerr.h" +#include "pathexec.h" +#include "timeoutconn.h" #include "remoteinfo.h" +#include "dns.h" #define FATAL "tcpclient: fatal: " #define CONNECT "tcpclient: unable to connect to " -int verbosity = 1; - -void die2(s,t) char *s; char *t; -{ - if (verbosity) strerr_warn3(FATAL,s,t,0); - _exit(111); -} -void diesys(s) char *s; -{ - if (verbosity) strerr_warn2(FATAL,s,&strerr_sys); - _exit(111); -} -void nomem() +void nomem(void) { - if (verbosity) strerr_warn2(FATAL,"out of memory",0); - _exit(111); + strerr_die2x(111,FATAL,"out of memory"); } -void usage() +void usage(void) { strerr_die1x(100,"tcpclient: usage: tcpclient \ [ -hHrRdDqQv ] \ @@ -53,43 +40,46 @@ void usage() host port program"); } -char temp[IPFMT + FMT_ULONG]; - +int verbosity = 1; int flagdelay = 1; int flagremoteinfo = 1; int flagremotehost = 1; +unsigned long itimeout = 26; +unsigned long ctimeout[2] = { 2, 58 }; + +char iplocal[4] = { 0,0,0,0 }; +uint16 portlocal = 0; char *forcelocal = 0; -unsigned long timeout = 26; -unsigned long timeout2 = 60; - -stralloc tmp = {0}; -ipalloc ia = {0}; - -struct sockaddr_in salocal; -struct ip_address iplocal; -unsigned long portlocal; -struct sockaddr_in saremote; -struct ip_address ipremote; -unsigned long portremote; -char strport[FMT_ULONG]; - -void main(argc,argv) -int argc; -char **argv; + +char ipremote[4]; +uint16 portremote; + +char *hostname; +static stralloc addresses; +static stralloc moreaddresses; + +static stralloc tmp; +static stralloc fqdn; +char strnum[FMT_ULONG]; +char ipstr[IP4_FMT]; + +char seed[128]; + +main(int argc,char **argv) { - int s; - int dummy; + unsigned long u; int opt; - char *hostname; - char *portname; - struct servent *se; + char *x; int j; - - byte_zero(&salocal,sizeof(salocal)); - salocal.sin_family = AF_INET; - salocal.sin_addr.s_addr = INADDR_ANY; - salocal.sin_port = 0; + int s; + int cloop; + + dns_random_init(seed); + close(6); + close(7); + sig_ignore(sig_pipe); + while ((opt = getopt(argc,argv,"dDvqQhHrRi:p:t:T:l:")) != opteof) switch(opt) { case 'd': flagdelay = 1; break; @@ -102,150 +92,133 @@ char **argv; case 'h': flagremotehost = 1; break; case 'R': flagremoteinfo = 0; break; case 'r': flagremoteinfo = 1; break; - case 't': scan_ulong(optarg,&timeout); break; - case 'T': scan_ulong(optarg,&timeout2); break; - case 'i': - if (ip_scan(optarg,&iplocal)) byte_copy(&salocal.sin_addr,4,&iplocal); - break; - case 'p': - scan_ulong(optarg,&portlocal); - salocal.sin_port = htons((unsigned short) portlocal); - break; + case 't': scan_ulong(optarg,&itimeout); break; + case 'T': j = scan_ulong(optarg,&ctimeout[0]); + if (optarg[j] == '+') ++j; + scan_ulong(optarg + j,&ctimeout[1]); + break; + case 'i': if (!ip4_scan(optarg,iplocal)) usage(); break; + case 'p': scan_ulong(optarg,&u); portlocal = u; break; default: usage(); } - argc -= optind; argv += optind; - - hostname = *argv++; + + if (!verbosity) + buffer_2->fd = -1; + + hostname = *argv; if (!hostname) usage(); - portname = *argv++; - if (!portname) usage(); - if (!*argv) usage(); - - close(6); - close(7); - sig_pipeignore(); - - dns_init(1); - - byte_zero(&saremote,sizeof(saremote)); - saremote.sin_family = AF_INET; + if (str_equal(hostname,"")) hostname = "127.0.0.1"; + if (str_equal(hostname,"0")) hostname = "127.0.0.1"; - if (!portname[scan_ulong(portname,&portremote)]) - ; + x = *++argv; + if (!x) usage(); + if (!x[scan_ulong(x,&u)]) + portremote = u; else { - se = getservbyname(portname,"tcp"); - if (!se) die2("unable to figure out port number for ",portname); + struct servent *se; + se = getservbyname(x,"tcp"); + if (!se) + strerr_die3x(111,FATAL,"unable to figure out port number for ",x); portremote = ntohs(se->s_port); /* i continue to be amazed at the stupidity of the s_port interface */ } - strport[fmt_ulong(strport,portremote)] = 0; - - if (str_equal(hostname,"")) hostname = "127.0.0.1"; - if (str_equal(hostname,"0")) hostname = "127.0.0.1"; - - if (!hostname[ip_scan(hostname,&ipremote)]) { - s = socket(AF_INET,SOCK_STREAM,0); - if (s == -1) - diesys("unable to create socket: "); - if (bind(s,(struct sockaddr *) &salocal,sizeof(salocal)) == -1) - diesys("unable to bind: "); - if (timeoutconn(s,&ipremote,portremote,(int) timeout2) == -1) { - temp[ip_fmt(temp,&ipremote)] = 0; - if (verbosity) strerr_warn5(CONNECT,temp," port ",strport,": ",&strerr_sys); - _exit(111); - } + + if (!*++argv) usage(); + + if (!stralloc_copys(&tmp,hostname)) nomem(); + if (dns_ip4_qualify(&addresses,&fqdn,&tmp) == -1) + strerr_die4sys(111,FATAL,"temporarily unable to figure out IP address for ",hostname,": "); + if (addresses.len < 4) + strerr_die3x(111,FATAL,"no IP address for ",hostname); + + if (addresses.len == 4) { + ctimeout[0] += ctimeout[1]; + ctimeout[1] = 0; } - else { - if (!stralloc_copys(&tmp,hostname)) nomem(); - switch(dns_ip(&ia,&tmp)) { - case DNS_SOFT: - die2("temporarily unable to figure out IP address for ",hostname); - case DNS_HARD: - die2("unable to figure out IP address for ",hostname); - case DNS_MEM: nomem(); - } - if (ia.len == 0) - die2("no IP addresses for ",hostname); - for (j = 0;j < ia.len;++j) { - s = socket(AF_INET,SOCK_STREAM,0); + + for (cloop = 0;cloop < 2;++cloop) { + if (!stralloc_copys(&moreaddresses,"")) nomem(); + for (j = 0;j + 4 <= addresses.len;j += 4) { + s = socket_tcp(); if (s == -1) - diesys("unable to create socket: "); - if (bind(s,(struct sockaddr *) &salocal,sizeof(salocal)) == -1) - diesys("unable to bind: "); - byte_copy(&ipremote,4,&ia.ix[j].ip); - if (timeoutconn(s,&ipremote,portremote,(int) timeout2) == 0) break; - temp[ip_fmt(temp,&ipremote)] = 0; - if (verbosity) strerr_warn5(CONNECT,temp," port ",strport,": ",&strerr_sys); + strerr_die2sys(111,FATAL,"unable to create socket: "); + if (socket_bind4(s,iplocal,portlocal) == -1) + strerr_die2sys(111,FATAL,"unable to bind socket: "); + if (timeoutconn(s,addresses.s + j,portremote,ctimeout[cloop]) == 0) + goto CONNECTED; close(s); + if (!cloop && ctimeout[1] && (errno == error_timeout)) { + if (!stralloc_catb(&moreaddresses,addresses.s + j,4)) nomem(); + } + else { + strnum[fmt_ulong(strnum,portremote)] = 0; + ipstr[ip4_fmt(ipstr,addresses.s + j)] = 0; + strerr_warn5(CONNECT,ipstr," port ",strnum,": ",&strerr_sys); + } } - if (j == ia.len) _exit(111); - } - - if (!flagdelay) { - int opt = 1; - setsockopt(s,IPPROTO_TCP,1,&opt,sizeof(opt)); /* 1 == TCP_NODELAY */ - /* if it fails, bummer */ + if (!stralloc_copy(&addresses,&moreaddresses)) nomem(); } - - if (!env_init()) nomem(); - if (!env_put("PROTO=TCP")) nomem(); - if (!env_unset("TCPLOCALHOST")) nomem(); - if (!env_unset("TCPREMOTEHOST")) nomem(); - if (!env_unset("TCPREMOTEINFO")) nomem(); - - dummy = sizeof(salocal); - if (getsockname(s,(struct sockaddr *) &salocal,&dummy) == -1) - diesys("unable to get local address: "); - portlocal = ntohs(salocal.sin_port); - byte_copy(&iplocal,4,&salocal.sin_addr); - - temp[fmt_ulong(temp,portlocal)] = 0; - if (!env_put2("TCPLOCALPORT",temp)) nomem(); - temp[ip_fmt(temp,&iplocal)] = 0; - if (!env_put2("TCPLOCALIP",temp)) nomem(); - if (forcelocal) { - if (!env_put2("TCPLOCALHOST",forcelocal)) nomem(); - } - else - switch(dns_ptr(&tmp,&iplocal)) { - case DNS_MEM: nomem(); - case 0: - if (!stralloc_0(&tmp)) nomem(); - case_lowers(tmp.s); - if (!env_put2("TCPLOCALHOST",tmp.s)) nomem(); + + _exit(111); + + + + CONNECTED: + + if (!flagdelay) + socket_tcpnodelay(s); /* if it fails, bummer */ + + if (!pathexec_env("PROTO","TCP")) nomem(); + + if (socket_local4(s,iplocal,&portlocal) == -1) + strerr_die2sys(111,FATAL,"unable to get local address: "); + + strnum[fmt_ulong(strnum,portlocal)] = 0; + if (!pathexec_env("TCPLOCALPORT",strnum)) nomem(); + ipstr[ip4_fmt(ipstr,iplocal)] = 0; + if (!pathexec_env("TCPLOCALIP",ipstr)) nomem(); + + x = forcelocal; + if (!x) + if (dns_name4(&tmp,iplocal) == 0) { + if (!stralloc_0(&tmp)) nomem(); + x = tmp.s; } - - dummy = sizeof(saremote); - if (getpeername(s,(struct sockaddr *) &saremote,&dummy) == -1) - diesys("unable to get remote address: "); - byte_copy(&ipremote,4,&saremote.sin_addr); - - temp[ip_fmt(temp,&ipremote)] = 0; - if (!env_put2("TCPREMOTEIP",temp)) nomem(); - if (verbosity >= 2) strerr_warn4("tcpclient: connected to ",temp," port ",strport,0); - - if (!env_put2("TCPREMOTEPORT",strport)) nomem(); + if (!pathexec_env("TCPLOCALHOST",x)) nomem(); + + if (socket_remote4(s,ipremote,&portremote) == -1) + strerr_die2sys(111,FATAL,"unable to get remote address: "); + + strnum[fmt_ulong(strnum,portremote)] = 0; + if (!pathexec_env("TCPREMOTEPORT",strnum)) nomem(); + ipstr[ip4_fmt(ipstr,ipremote)] = 0; + if (!pathexec_env("TCPREMOTEIP",ipstr)) nomem(); + if (verbosity >= 2) + strerr_warn4("tcpclient: connected to ",ipstr," port ",strnum,0); + + x = 0; if (flagremotehost) - switch(dns_ptr(&tmp,&ipremote)) { - case DNS_MEM: nomem(); - case 0: - if (!stralloc_0(&tmp)) nomem(); - case_lowers(tmp.s); - if (!env_put2("TCPREMOTEHOST",tmp.s)) nomem(); + if (dns_name4(&tmp,ipremote) == 0) { + if (!stralloc_0(&tmp)) nomem(); + x = tmp.s; } - if (flagremoteinfo) { - char *rinfo; - rinfo = remoteinfo_get(&ipremote,portremote,&iplocal,portlocal,(int) timeout); - if (rinfo) - if (!env_put2("TCPREMOTEINFO",rinfo)) nomem(); - } - - if (fd_move(6,s) == -1) diesys("unable to set up descriptor 6: "); - if (fd_copy(7,6) == -1) diesys("unable to set up descriptor 7: "); - sig_pipedefault(); + if (!pathexec_env("TCPREMOTEHOST",x)) nomem(); + + x = 0; + if (flagremoteinfo) + if (remoteinfo(&tmp,ipremote,portremote,iplocal,portlocal,itimeout) == 0) { + if (!stralloc_0(&tmp)) nomem(); + x = tmp.s; + } + if (!pathexec_env("TCPREMOTEINFO",x)) nomem(); + + if (fd_move(6,s) == -1) + strerr_die2sys(111,FATAL,"unable to set up descriptor 6: "); + if (fd_copy(7,6) == -1) + strerr_die2sys(111,FATAL,"unable to set up descriptor 7: "); + sig_uncatch(sig_pipe); - execvp(*argv,argv); - if (verbosity) strerr_warn4(FATAL,"unable to run ",*argv,": ",&strerr_sys); - _exit(111); + pathexec(argv); + strerr_die4sys(111,FATAL,"unable to run ",*argv,": "); } diff --git a/tcprules.1 b/tcprules.1 deleted file mode 100644 index d2b561c..0000000 --- a/tcprules.1 +++ /dev/null @@ -1,208 +0,0 @@ -.TH tcprules 1 -.SH NAME -tcprules \- compile rules for tcpserver -.SH SYNOPSIS -.B tcprules -.I rules.cdb -.I rules.tmp -.SH OVERVIEW -.B tcpserver -optionally follows rules to decide whether a TCP connection is acceptable. -For example, a rule of - -.EX - 18.23.0.32:deny -.EE - -prohibits connections from IP address 18.23.0.32. - -.B tcprules -reads rules from its standard input -and writes them into -.I rules.cdb -in a binary format suited -for quick access by -.BR tcpserver . - -.B tcprules -can be used while -.B tcpserver -is running: -it ensures that -.I rules.cdb -is updated atomically. -It does this by first writing the rules to -.I rules.tmp -and then moving -.I rules.tmp -on top of -.IR rules.cdb . -If -.I rules.tmp -already exists, it is destroyed. -The directories containing -.I rules.cdb -and -.I rules.tmp -must be writable to -.BR tcprules ; -they must also be on the same filesystem. - -If there is a problem with the input, -.B tcprules -complains and leaves -.I rules.cdb -alone. - -The binary -.I rules.cdb -format is portable across machines. -.SH "RULE FORMAT" -A rule takes up one line. -A file containing rules -may also contain comments: lines beginning with # are ignored. - -Each rule contains an -.BR address , -a colon, -and a list of -.BR instructions , -with no extra spaces. -When -.B tcpserver -receives a connection from that address, -it follows the instructions. -.SH "ADDRESSES" -.B tcpserver -starts by looking for a rule with address -.IR TCPREMOTEINFO\fB@\fITCPREMOTEIP . -If it doesn't find one, or if -.I TCPREMOTEINFO -is not set, it tries the address -.IR TCPREMOTEIP . -If that doesn't work, it tries shorter and shorter prefixes of -.I TCPREMOTEIP -ending with a dot. -If none of them work, it tries the empty string. - -For example, here are some rules: - -.EX - joe@127.0.0.1:first -.br - 18.23.0.32:second -.br - 127.:third -.br - :fourth -.EE - -If -.I TCPREMOTEIP -is -.BR 10.119.75.38 , -.B tcpserver -will follow the -.B fourth -instructions. - -If -.I TCPREMOTEIP -is -.BR 18.23.0.32 , -.B tcpserver -will follow the -.B second -instructions. - -If -.I TCPREMOTEINFO -is -.B bill -and -.I TCPREMOTEIP -is -.BR 127.0.0.1 , -.B tcpserver -will follow the -.B third -instructions. - -If -.I TCPREMOTEINFO -is -.B joe -and -.I TCPREMOTEIP -is -.BR 127.0.0.1 , -.B tcpserver -will follow the -.B first -instructions. -.SH "ADDRESS RANGES" -.B tcprules -treats -.B 1.2.3.37-53:ins -as an abbreviation -for the rules -.BR 1.2.3.37:ins , -.BR 1.2.3.38:ins , -and so on up through -.BR 1.2.3.53:ins . -Similarly, -.BR 10.2-3.:ins -is an abbreviation for -.B 10.2.:ins -and -.BR 10.3.:ins . -.SH "INSTRUCTIONS" -The instructions in a rule must begin with either -.B allow -or -.BR deny . -.B deny -tells -.B tcpserver -to drop the connection without running anything. -For example, the rule - -.EX - :deny -.EE - -tells -.B tcpserver -to drop all connections that aren't handled by more specific rules. - -The instructions may continue with some environment variables, -in the format -.IR ,VAR="VALUE" . -.B tcpserver -adds -.I VAR=VALUE -to the current environment. -For example, - -.EX - 10.0.:allow,RELAYCLIENT="@fix.me" -.EE - -adds -.B RELAYCLIENT=@fix.me -to the environment. -The quotes here may be replaced by any repeated character: - -.EX - 10.0.:allow,RELAYCLIENT=/@fix.me/ -.EE - -Any number of variables may be listed: - -.EX - 127.0.0.1:allow,RELAYCLIENT="",TCPLOCALHOST="movie.edu" -.EE -.SH "SEE ALSO" -tcprulescheck(1), -tcpserver(1), -tcp-environ(5) @@ -1,12 +1,11 @@ #include "strerr.h" #include "stralloc.h" #include "getln.h" -#include "substdio.h" -#include "subfd.h" +#include "buffer.h" #include "exit.h" #include "fmt.h" #include "byte.h" -#include "cdbmss.h" +#include "cdb_make.h" #define FATAL "tcprules: fatal: " @@ -21,36 +20,37 @@ stralloc address = {0}; stralloc data = {0}; stralloc key = {0}; -struct cdbmss cdbmss; +struct cdb_make c; -void die_nomem() { +void nomem(void) +{ strerr_die2x(111,FATAL,"out of memory"); } -void usage() { +void usage(void) +{ strerr_die1x(100,"tcprules: usage: tcprules rules.cdb rules.tmp"); } -void die_bad() { - if (!stralloc_0(&line)) die_nomem(); +void die_bad(void) +{ + if (!stralloc_0(&line)) nomem(); strerr_die3x(100,FATAL,"unable to parse this line: ",line.s); } -void die_write() { +void die_write(void) +{ strerr_die4sys(111,FATAL,"unable to write to ",fntemp,": "); } char strnum[FMT_ULONG]; stralloc sanum = {0}; -void getnum(buf,len,u) -char *buf; -int len; -unsigned long *u; +void getnum(char *buf,int len,unsigned long *u) { - if (!stralloc_copyb(&sanum,buf,len)) die_nomem(); - if (!stralloc_0(&sanum)) die_nomem(); + if (!stralloc_copyb(&sanum,buf,len)) nomem(); + if (!stralloc_0(&sanum)) nomem(); if (sanum.s[scan_ulong(sanum.s,u)]) die_bad(); } -void doaddressdata() +void doaddressdata(void) { int i; int left; @@ -58,38 +58,36 @@ void doaddressdata() unsigned long bot; unsigned long top; - if (byte_chr(address.s,address.len,'@') == address.len) { - i = byte_chr(address.s,address.len,'-'); - if (i < address.len) { - left = byte_rchr(address.s,i,'.'); - if (left == i) left = 0; else ++left; - - ++i; - right = i + byte_chr(address.s + i,address.len - i,'.'); - - getnum(address.s + left,i - 1 - left,&bot); - getnum(address.s + i,right - i,&top); - if (top > 255) top = 255; - - while (bot <= top) { - if (!stralloc_copyb(&key,address.s,left)) die_nomem(); - if (!stralloc_catb(&key,strnum,fmt_ulong(strnum,bot))) die_nomem(); - if (!stralloc_catb(&key,address.s + right,address.len - right)) die_nomem(); - if (cdbmss_add(&cdbmss,key.s,key.len,data.s,data.len) == -1) die_write(); - ++bot; + if (byte_chr(address.s,address.len,'=') == address.len) + if (byte_chr(address.s,address.len,'@') == address.len) { + i = byte_chr(address.s,address.len,'-'); + if (i < address.len) { + left = byte_rchr(address.s,i,'.'); + if (left == i) left = 0; else ++left; + + ++i; + right = i + byte_chr(address.s + i,address.len - i,'.'); + + getnum(address.s + left,i - 1 - left,&bot); + getnum(address.s + i,right - i,&top); + if (top > 255) top = 255; + + while (bot <= top) { + if (!stralloc_copyb(&key,address.s,left)) nomem(); + if (!stralloc_catb(&key,strnum,fmt_ulong(strnum,bot))) nomem(); + if (!stralloc_catb(&key,address.s + right,address.len - right)) nomem(); + if (cdb_make_add(&c,key.s,key.len,data.s,data.len) == -1) die_write(); + ++bot; + } + + return; } - - return; } - } - if (!stralloc_copy(&key,&address)) die_nomem(); - if (cdbmss_add(&cdbmss,key.s,key.len,data.s,data.len) == -1) die_write(); + if (cdb_make_add(&c,address.s,address.len,data.s,data.len) == -1) die_write(); } -void main(argc,argv) -int argc; -char **argv; +main(int argc,char **argv) { int colon; char *x; @@ -106,10 +104,10 @@ char **argv; fd = open_trunc(fntemp); if (fd == -1) strerr_die4sys(111,FATAL,"unable to create ",fntemp,": "); - if (cdbmss_start(&cdbmss,fd) == -1) die_write(); + if (cdb_make_start(&c,fd) == -1) die_write(); while (match) { - if (getln(subfdin,&line,&match,'\n') == -1) + if (getln(buffer_0,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,"unable to read input: "); x = line.s; len = line.len; @@ -128,13 +126,13 @@ char **argv; colon = byte_chr(x,len,':'); if (colon == len) continue; - if (!stralloc_copyb(&address,x,colon)) die_nomem(); - if (!stralloc_copys(&data,"")) die_nomem(); + if (!stralloc_copyb(&address,x,colon)) nomem(); + if (!stralloc_copys(&data,"")) nomem(); x += colon + 1; len -= colon + 1; if ((len >= 4) && byte_equal(x,4,"deny")) { - if (!stralloc_catb(&data,"D",2)) die_nomem(); + if (!stralloc_catb(&data,"D",2)) nomem(); x += 4; len -= 4; } else if ((len >= 5) && byte_equal(x,5,"allow")) { @@ -148,16 +146,16 @@ char **argv; case ',': i = byte_chr(x,len,'='); if (i == len) die_bad(); - if (!stralloc_catb(&data,"+",1)) die_nomem(); - if (!stralloc_catb(&data,x + 1,i)) die_nomem(); + if (!stralloc_catb(&data,"+",1)) nomem(); + if (!stralloc_catb(&data,x + 1,i)) nomem(); x += i + 1; len -= i + 1; if (!len) die_bad(); ch = *x; x += 1; len -= 1; i = byte_chr(x,len,ch); if (i == len) die_bad(); - if (!stralloc_catb(&data,x,i)) die_nomem(); - if (!stralloc_0(&data)) die_nomem(); + if (!stralloc_catb(&data,x,i)) nomem(); + if (!stralloc_0(&data)) nomem(); x += i + 1; len -= i + 1; break; default: @@ -167,7 +165,7 @@ char **argv; doaddressdata(); } - if (cdbmss_finish(&cdbmss) == -1) die_write(); + if (cdb_make_finish(&c) == -1) die_write(); if (fsync(fd) == -1) die_write(); if (close(fd) == -1) die_write(); /* NFS stupidity */ if (rename(fntemp,fn)) diff --git a/tcprulescheck.1 b/tcprulescheck.1 deleted file mode 100644 index 3f0de24..0000000 --- a/tcprulescheck.1 +++ /dev/null @@ -1,25 +0,0 @@ -.TH tcprulescheck 1 -.SH NAME -tcprulescheck \- try out rules for tcpserver -.SH SYNTAX -.B tcprulescheck -.I rules.cdb -.I tcpremoteip -[ -.I tcpremoteinfo -] -.SH DESCRIPTION -.B tcprulescheck -says what -.B tcpserver -will do with a connection from -IP address -.IR tcpremoteip , -following the rules compiled into -.I rules.cdb -by -.BR tcprules . -.SH "SEE ALSO" -tcprules(1), -tcpserver(1), -tcp-environ(5) diff --git a/tcprulescheck.c b/tcprulescheck.c index 2a0eb34..a961d50 100644 --- a/tcprulescheck.c +++ b/tcprulescheck.c @@ -1,104 +1,57 @@ -#include "substdio.h" -#include "subfd.h" +#include "byte.h" +#include "buffer.h" #include "strerr.h" -#include "stralloc.h" -#include "alloc.h" -#include "cdb.h" +#include "env.h" +#include "rules.h" -#define FATAL "tcprulescheck: fatal: " - -char *fnrules; -int fdrules; - -void die_usage() -{ - strerr_die1x(100,"tcprulescheck: usage: tcprulescheck rules.cdb tcpremoteip [ tcpremoteinfo ]"); -} -void die_read() -{ - strerr_die4sys(111,FATAL,"unable to read ",fnrules,": "); -} -void nomem() -{ - strerr_die2x(111,FATAL,"out of memory"); -} - -static stralloc tmp = {0}; - -void dorule() +void found(char *data,unsigned int datalen) { - char *data; - uint32 dlen32; - unsigned int datalen; unsigned int next0; - switch(cdb_seek(fdrules,tmp.s,tmp.len,&dlen32)) { - case -1: die_read(); - case 0: return; - } - - datalen = dlen32; - data = alloc(datalen); - if (!data) nomem(); - if (cdb_bread(fdrules,data,datalen) != 0) die_read(); - - substdio_puts(subfdout,"rule "); - substdio_put(subfdout,tmp.s,tmp.len); - substdio_puts(subfdout,":\n"); + buffer_puts(buffer_1,"rule "); + buffer_put(buffer_1,rules_name.s,rules_name.len); + buffer_puts(buffer_1,":\n"); while ((next0 = byte_chr(data,datalen,0)) < datalen) { switch(data[0]) { case 'D': - substdio_puts(subfdout,"deny connection\n"); - substdio_flush(subfdout); - _exit(0); /* XXX: could still set env vars for logs */ + buffer_puts(buffer_1,"deny connection\n"); + buffer_flush(buffer_1); + _exit(0); case '+': - substdio_puts(subfdout,"set environment variable "); - substdio_puts(subfdout,data + 1); - substdio_puts(subfdout,"\n"); + buffer_puts(buffer_1,"set environment variable "); + buffer_puts(buffer_1,data + 1); + buffer_puts(buffer_1,"\n"); break; } - data += next0 + 1; datalen -= next0 + 1; + ++next0; + data += next0; datalen -= next0; } - substdio_puts(subfdout,"allow connection\n"); - substdio_flush(subfdout); + buffer_puts(buffer_1,"allow connection\n"); + buffer_flush(buffer_1); _exit(0); } -void main(argc,argv) -int argc; -char **argv; +main(int argc,char **argv) { - char *tcpremoteip; - char *tcpremoteinfo; + char *fnrules; + int fd; + char *ip; + char *info; + char *host; fnrules = argv[1]; - if (!fnrules) die_usage(); - - tcpremoteip = argv[2]; - if (!tcpremoteip) die_usage(); - - tcpremoteinfo = argv[3]; + if (!fnrules) + strerr_die1x(100,"tcprulescheck: usage: tcprulescheck rules.cdb"); - fdrules = open_read(fnrules); - if (fdrules == -1) die_read(); - - if (tcpremoteinfo) { - if (!stralloc_copys(&tmp,tcpremoteinfo)) nomem(); - if (!stralloc_cats(&tmp,"@")) nomem(); - if (!stralloc_cats(&tmp,tcpremoteip)) nomem(); - dorule(); - } - - if (!stralloc_copys(&tmp,tcpremoteip)) nomem(); - dorule(); - while (tmp.len > 0) { - if (tcpremoteip[tmp.len - 1] == '.') - dorule(); - --tmp.len; - } + ip = env_get("TCPREMOTEIP"); + if (!ip) ip = "0.0.0.0"; + info = env_get("TCPREMOTEINFO"); + host = env_get("TCPREMOTEHOST"); - dorule(); + fd = open_read(fnrules); + if ((fd == -1) || (rules(found,fd,ip,host,info) == -1)) + strerr_die3sys(111,"tcprulescheck: fatal: unable to read ",fnrules,": "); - substdio_putsflush(subfdout,"default:\nallow connection\n"); + buffer_putsflush(buffer_1,"default:\nallow connection\n"); _exit(0); } diff --git a/tcpserver.1 b/tcpserver.1 deleted file mode 100644 index 04b10f9..0000000 --- a/tcpserver.1 +++ /dev/null @@ -1,244 +0,0 @@ -.TH tcpserver 1 -.SH NAME -tcpserver \- accept incoming TCP connections -.SH SYNOPSIS -.B tcpserver -[ -.B \-1pPhHrRoOdDqQv -] -[ -.B \-c\fIlimit -] -[ -.B \-x\fIrules.cdb -] -[ -.B \-B\fIbanner -] -[ -.B \-g\fIgid -] -[ -.B \-u\fIuid -] -[ -.B \-b\fIbacklog -] -[ -.B \-l\fIlocalname -] -[ -.B \-t\fItimeout -] -.I host -.I port -.I program -[ -.I arg ... -] -.SH DESCRIPTION -.B tcpserver -waits for connections from TCP clients. -For each connection, it runs -.I program -with the given arguments, -with descriptor 0 reading from the network -and descriptor 1 writing to the network. - -The server's address is given by -.I host -and -.IR port . -.I host -can be 0, allowing connections from any host; -or a particular IP address, -allowing connections only to that address; -or a host name, allowing connections to the first IP address -for that host. -.I port -may be a numeric port number -or a port name. -If -.I port -is 0, -.B tcpserver -will choose a free port. - -.B tcpserver -sets up several environment variables, -as described in -.B tcp-environ(5). - -.B tcpserver -exits when it receives SIGTERM. -.SH "OPTIONS" -.TP -.B \-c\fIlimit -Do not handle more than -.I limit -simultaneous connections. -If there are -.I limit -simultaneous copies of -.I program -running, defer acceptance of a new connection -until one copy finishes. -.I limit -must be a positive integer. -Default: 40. -.TP -.B \-x\fIrules.cdb -Follow the rules compiled into -.I rules.cdb -by -.BR tcprules . -These rules may specify setting environment variables -or rejecting connections from bad sources. - -.B tcpserver -does not read -.I rules.cdb -into memory; -you can rerun -.B tcprules -to change -.BR tcpserver 's -behavior on the fly. -.TP -.B \-B\fIbanner -Write -.I banner -to the network immediately after each connection is made. -.B tcpserver -writes -.I banner -before looking up -.BR TCPREMOTEHOST , -before looking up -.BR TCPREMOTEINFO , -and before checking -.IR rules.cdb . - -This feature can be used to reduce latency in protocols -where the client waits for a greeting from the server. -.TP -.B \-g\fIgid -Switch group ID to -.I gid -after preparing to receive connections. -.I gid -must be a positive integer. -.TP -.B \-u\fIuid -Switch user ID to -.I uid -after preparing to receive connections. -.I uid -must be a positive integer. -.TP -.B \-1 -After preparing to receive connections, -print the local port number to standard output. -.TP -.B \-b\fIbacklog -Allow up to -.I backlog -simultaneous SYN_RECEIVEDs. -Default: 20. -On some systems, -.I backlog -is silently limited to 5. -See -.BR listen (2) -for more details. -.TP -.B \-o -Leave IP options alone. -If the client is sending packets along an IP source route, -send packets back along the same route. -.TP -.B \-O -(Default.) -Kill IP options. -A client can still use source routing to connect and to send data, -but packets will be sent back along the default route. -.TP -.B \-d -(Default.) -Delay sending data for a fraction of a second whenever the -remote host is responding slowly, -to make better use of the network. -.TP -.B \-D -Never delay sending data; -enable TCP_NODELAY. -This is appropriate for interactive connections. -.TP -.B \-q -Quiet. -Do not print any messages. -.TP -.B \-Q -(Default.) -Print error messages. -.TP -.B \-v -Verbose. -Print all available messages. -.SH "DATA-GATHERING OPTIONS" -.TP -.B \-p -Paranoid. -After looking up the remote host name, -look up the IP addresses for that name, -and make sure one of them matches -.BR TCPREMOTEIP . -If none of them do, -unset -.BR TCPREMOTEHOST . -.TP -.B \-P -(Default.) -Not paranoid. -.TP -.B \-h -(Default.) -Look up the remote host name and set -.BR TCPREMOTEHOST . -.TP -.B \-H -Do not look up the remote host name. -.TP -.B \-l\fIlocalname -Do not look up the local host name; -use -.I localname -for -.BR TCPLOCALHOST . -.TP -.B \-r -(Default.) -Attempt to obtain -.B TCPREMOTEINFO -from the remote host. -.TP -.B \-R -Do not attempt to obtain -.B TCPREMOTEINFO -from the remote host. -.TP -.B \-t\fItimeout -Give up on the -.B TCPREMOTEINFO -connection attempt -after -.I timeout -seconds. Default: 26. -.SH "SEE ALSO" -argv0(1), -fixcr(1), -recordio(1), -tcpclient(1), -tcprules(1), -listen(2), -tcp-environ(5) diff --git a/tcpserver.c b/tcpserver.c index 012dc36..979a0be 100644 --- a/tcpserver.c +++ b/tcpserver.c @@ -1,66 +1,91 @@ #include <sys/types.h> #include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> #include <netdb.h> - -#include "strerr.h" -#include "substdio.h" -#include "stralloc.h" -#include "alloc.h" -#include "readwrite.h" -#include "fd.h" -#include "sig.h" -#include "wait.h" -#include "ip.h" -#include "ipalloc.h" -#include "dns.h" +#include "uint16.h" #include "str.h" -#include "case.h" #include "byte.h" -#include "sgetopt.h" -#include "remoteinfo.h" -#include "exit.h" -#include "open.h" -#include "scan.h" #include "fmt.h" +#include "scan.h" +#include "ip4.h" +#include "fd.h" +#include "exit.h" #include "env.h" -#include "cdb.h" +#include "prot.h" +#include "open.h" +#include "wait.h" +#include "readwrite.h" +#include "stralloc.h" +#include "alloc.h" +#include "buffer.h" +#include "error.h" +#include "strerr.h" +#include "sgetopt.h" +#include "pathexec.h" +#include "socket.h" +#include "ndelay.h" +#include "remoteinfo.h" +#include "rules.h" +#include "sig.h" +#include "dns.h" -#define FATAL "tcpserver: fatal: " -#define DROP "tcpserver: warning: dropping connection, " int verbosity = 1; +int flagkillopts = 1; +int flagdelay = 1; +char *banner = ""; +int flagremoteinfo = 1; +int flagremotehost = 1; +int flagparanoid = 0; +unsigned long timeout = 26; + +static stralloc tcpremoteinfo; + +uint16 localport; +char localportstr[FMT_ULONG]; +char localip[4]; +char localipstr[IP4_FMT]; +static stralloc localhostsa; +char *localhost = 0; -void die_nomem() +uint16 remoteport; +char remoteportstr[FMT_ULONG]; +char remoteip[4]; +char remoteipstr[IP4_FMT]; +static stralloc remotehostsa; +char *remotehost = 0; + +char strnum[FMT_ULONG]; +char strnum2[FMT_ULONG]; + +static stralloc tmp; +static stralloc fqdn; +static stralloc addresses; + +char bspace[16]; +buffer b; + + + +/* ---------------------------- child */ + +#define DROP "tcpserver: warning: dropping connection, " + +int flagdeny = 0; +int flagallownorules = 0; +char *fnrules = 0; + +void drop_nomem(void) { - if (verbosity) strerr_warn2(FATAL,"out of memory",0); - _exit(111); + strerr_die2sys(111,DROP,"out of memory"); } -void drop_nomem() +void cats(char *s) { - if (verbosity) strerr_warn2(DROP,"out of memory",0); - _exit(111); + if (!stralloc_cats(&tmp,s)) drop_nomem(); } -void usage() +void append(char *ch) { - strerr_warn1("\ -tcpserver: usage: tcpserver \ -[ -1pPhHrRoOdDqQv ] \ -[ -c limit ] \ -[ -x rules.cdb ] \ -[ -B banner ] \ -[ -g gid ] \ -[ -u uid ] \ -[ -b backlog ] \ -[ -l localname ] \ -[ -t timeout ] \ -host port program",0); - _exit(100); + if (!stralloc_append(&tmp,ch)) drop_nomem(); } - -void safeappend(sa,s) -stralloc *sa; -char *s; +void safecats(char *s) { char ch; int i; @@ -72,204 +97,214 @@ char *s; if (ch > 126) ch = '?'; if (ch == '%') ch = '?'; /* logger stupidity */ if (ch == ':') ch = '?'; - if (!stralloc_append(sa,&ch)) drop_nomem(); + append(&ch); } - if (!stralloc_cats(sa,"...")) drop_nomem(); -} - -char strnum[FMT_ULONG]; -char strnum2[FMT_ULONG]; -stralloc tmp = {0}; -ipalloc ia = {0}; - -unsigned long limit = 40; -unsigned long numchildren = 0; - -char tcpremoteip[IPFMT]; -char tcpremoteport[IPFMT]; -char *tcpremoteinfo; -struct sockaddr_in saremote; -struct ip_address ipremote; -unsigned long portremote; - -char tcplocalip[IPFMT]; -char tcplocalport[IPFMT]; -struct sockaddr_in salocal; -struct ip_address iplocal; -unsigned long portlocal; - -int fdrules; -char *fnrules = 0; -int flagdeny = 0; - -void printenv() -{ - char *tcplocalhost; - char *tcpremotehost; - - if (verbosity < 2) return; - - tcplocalhost = env_get("TCPLOCALHOST"); - tcpremotehost = env_get("TCPREMOTEHOST"); - - if (!tcplocalhost) tcplocalhost = ""; - if (!tcpremotehost) tcpremotehost = ""; - - if (!stralloc_copys(&tmp,"tcpserver: ")) drop_nomem(); - if (!stralloc_cats(&tmp,flagdeny ? "deny " : "ok ")) drop_nomem(); - if (!stralloc_catb(&tmp,strnum,fmt_ulong(strnum,getpid()))) drop_nomem(); - if (!stralloc_cats(&tmp," ")) drop_nomem(); - safeappend(&tmp,tcplocalhost); - if (!stralloc_cats(&tmp,":")) drop_nomem(); - safeappend(&tmp,tcplocalip); - if (!stralloc_cats(&tmp,":")) drop_nomem(); - safeappend(&tmp,tcplocalport); - if (!stralloc_cats(&tmp," ")) drop_nomem(); - safeappend(&tmp,tcpremotehost); - if (!stralloc_cats(&tmp,":")) drop_nomem(); - safeappend(&tmp,tcpremoteip); - if (!stralloc_cats(&tmp,":")) drop_nomem(); - safeappend(&tmp,tcpremoteinfo ? tcpremoteinfo : ""); - if (!stralloc_cats(&tmp,":")) drop_nomem(); - safeappend(&tmp,tcpremoteport); - if (!stralloc_0(&tmp)) drop_nomem(); - - strerr_warn1(tmp.s,0); + cats("..."); } - -void printstatus() +void env(char *s,char *t) { - if (verbosity < 2) return; - strnum[fmt_ulong(strnum,numchildren)] = 0; - strnum2[fmt_ulong(strnum2,limit)] = 0; - strerr_warn4("tcpserver: status: ",strnum,"/",strnum2,0); + if (!pathexec_env(s,t)) drop_nomem(); } - -void printpid() +void drop_rules(void) { - if (verbosity < 2) return; - strnum[fmt_ulong(strnum,(unsigned long) getpid())] = 0; - strerr_warn4("tcpserver: pid ",strnum," from ",tcpremoteip,0); + strerr_die4sys(111,DROP,"unable to read ",fnrules,": "); } -char printbuf[16]; -struct substdio print = SUBSTDIO_FDBUF(write,1,printbuf,sizeof(printbuf)); -void printlocalport() +void found(char *data,unsigned int datalen) { - substdio_puts(&print,tcplocalport); - substdio_puts(&print,"\n"); - substdio_flush(&print); -} - -void sigterm() { _exit(0); } + unsigned int next0; + unsigned int split; -void sigchld() -{ - int wstat; - int pid; - - while ((pid = wait_nohang(&wstat)) > 0) { - if (verbosity >= 2) { - strnum[fmt_ulong(strnum,(unsigned long) pid)] = 0; - strnum2[fmt_ulong(strnum2,(unsigned long) wstat)] = 0; - strerr_warn4("tcpserver: end ",strnum," status ",strnum2,0); + while ((next0 = byte_chr(data,datalen,0)) < datalen) { + switch(data[0]) { + case 'D': + flagdeny = 1; + break; + case '+': + split = str_chr(data + 1,'='); + if (data[1 + split] == '=') { + data[1 + split] = 0; + env(data + 1,data + 1 + split + 1); + } + break; } - if (numchildren) --numchildren; printstatus(); + ++next0; + data += next0; datalen -= next0; } } -void drop_rules() +void doit(int t) { - if (verbosity) strerr_warn4(DROP,"unable to read ",fnrules,": ",&strerr_sys); - _exit(111); -} + int j; -int dorule() -{ - char *data; - uint32 dlen32; - unsigned int datalen; - unsigned int next0; + remoteipstr[ip4_fmt(remoteipstr,remoteip)] = 0; - switch(cdb_seek(fdrules,tmp.s,tmp.len,&dlen32)) { - case -1: drop_rules(); - case 0: return 0; + if (verbosity >= 2) { + strnum[fmt_ulong(strnum,getpid())] = 0; + strerr_warn4("tcpserver: pid ",strnum," from ",remoteipstr,0); } - datalen = dlen32; - data = alloc(datalen); - if (!data) drop_nomem(); - if (cdb_bread(fdrules,data,datalen) != 0) drop_rules(); + if (flagkillopts) + socket_ipoptionskill(t); + if (!flagdelay) + socket_tcpnodelay(t); - while ((next0 = byte_chr(data,datalen,0)) < datalen) { - switch(data[0]) { - case 'D': flagdeny = 1; break; - case '+': if (!env_put(data + 1)) drop_nomem(); break; + if (*banner) { + buffer_init(&b,write,t,bspace,sizeof bspace); + if (buffer_putsflush(&b,banner) == -1) + strerr_die2sys(111,DROP,"unable to print banner: "); + } + + if (socket_local4(t,localip,&localport) == -1) + strerr_die2sys(111,DROP,"unable to get local address: "); + + localipstr[ip4_fmt(localipstr,localip)] = 0; + remoteportstr[fmt_ulong(remoteportstr,remoteport)] = 0; + + if (!localhost) + if (dns_name4(&localhostsa,localip) == 0) + if (localhostsa.len) { + if (!stralloc_0(&localhostsa)) drop_nomem(); + localhost = localhostsa.s; + } + env("PROTO","TCP"); + env("TCPLOCALIP",localipstr); + env("TCPLOCALPORT",localportstr); + env("TCPLOCALHOST",localhost); + + if (flagremotehost) + if (dns_name4(&remotehostsa,remoteip) == 0) + if (remotehostsa.len) { + if (flagparanoid) + if (dns_ip4(&tmp,&remotehostsa) == 0) + for (j = 0;j + 4 <= tmp.len;j += 4) + if (byte_equal(remoteip,4,tmp.s + j)) { + flagparanoid = 0; + break; + } + if (!flagparanoid) { + if (!stralloc_0(&remotehostsa)) drop_nomem(); + remotehost = remotehostsa.s; + } + } + env("TCPREMOTEIP",remoteipstr); + env("TCPREMOTEPORT",remoteportstr); + env("TCPREMOTEHOST",remotehost); + + if (flagremoteinfo) { + if (remoteinfo(&tcpremoteinfo,remoteip,remoteport,localip,localport,timeout) == -1) + flagremoteinfo = 0; + if (!stralloc_0(&tcpremoteinfo)) drop_nomem(); + } + env("TCPREMOTEINFO",flagremoteinfo ? tcpremoteinfo.s : 0); + + if (fnrules) { + int fdrules; + fdrules = open_read(fnrules); + if (fdrules == -1) { + if (errno != error_noent) drop_rules(); + if (!flagallownorules) drop_rules(); + } + else { + if (rules(found,fdrules,remoteipstr,remotehost,flagremoteinfo ? tcpremoteinfo.s : 0) == -1) drop_rules(); + close(fdrules); } - data += next0 + 1; datalen -= next0 + 1; } - return 1; -} -void rules() -{ - if (!fnrules) return; + if (verbosity >= 2) { + strnum[fmt_ulong(strnum,getpid())] = 0; + if (!stralloc_copys(&tmp,"tcpserver: ")) drop_nomem(); + safecats(flagdeny ? "deny" : "ok"); + cats(" "); safecats(strnum); + cats(" "); if (localhost) safecats(localhost); + cats(":"); safecats(localipstr); + cats(":"); safecats(localportstr); + cats(" "); if (remotehost) safecats(remotehost); + cats(":"); safecats(remoteipstr); + cats(":"); if (flagremoteinfo) safecats(tcpremoteinfo.s); + cats(":"); safecats(remoteportstr); + cats("\n"); + buffer_putflush(buffer_2,tmp.s,tmp.len); + } - fdrules = open_read(fnrules); - if (fdrules == -1) drop_rules(); + if (flagdeny) _exit(100); +} - if (tcpremoteinfo) { - if (!stralloc_copys(&tmp,tcpremoteinfo)) drop_nomem(); - if (!stralloc_cats(&tmp,"@")) drop_nomem(); - if (!stralloc_cats(&tmp,tcpremoteip)) drop_nomem(); - if (dorule()) goto done; - } - if (!stralloc_copys(&tmp,tcpremoteip)) drop_nomem(); - if (dorule()) goto done; - while (tmp.len > 0) { - if (tcpremoteip[tmp.len - 1] == '.') - if (dorule()) goto done; - --tmp.len; - } - dorule(); +/* ---------------------------- parent */ - done: - close(fdrules); +#define FATAL "tcpserver: fatal: " + +void usage(void) +{ + strerr_warn1("\ +tcpserver: usage: tcpserver \ +[ -1UXpPhHrRoOdDqQv ] \ +[ -c limit ] \ +[ -x rules.cdb ] \ +[ -B banner ] \ +[ -g gid ] \ +[ -u uid ] \ +[ -b backlog ] \ +[ -l localname ] \ +[ -t timeout ] \ +host port program",0); + _exit(100); } -int flagkillopts = 1; -int flagdelay = 1; -int flagremoteinfo = 1; -int flagremotehost = 1; -int flagparanoid = 0; +unsigned long limit = 40; +unsigned long numchildren = 0; + int flag1 = 0; unsigned long backlog = 20; -unsigned long timeout = 26; unsigned long uid = 0; unsigned long gid = 0; -char *forcelocal = 0; -char *banner = ""; +void printstatus(void) +{ + if (verbosity < 2) return; + strnum[fmt_ulong(strnum,numchildren)] = 0; + strnum2[fmt_ulong(strnum2,limit)] = 0; + strerr_warn4("tcpserver: status: ",strnum,"/",strnum2,0); +} -void main(argc,argv) -int argc; -char **argv; +void sigterm() +{ + _exit(0); +} + +void sigchld() +{ + int wstat; + int pid; + + while ((pid = wait_nohang(&wstat)) > 0) { + if (verbosity >= 2) { + strnum[fmt_ulong(strnum,pid)] = 0; + strnum2[fmt_ulong(strnum2,wstat)] = 0; + strerr_warn4("tcpserver: end ",strnum," status ",strnum2,0); + } + if (numchildren) --numchildren; printstatus(); + } +} + +main(int argc,char **argv) { - int s; - int t; - int dummy; - int opt; char *hostname; char *portname; + int opt; struct servent *se; - int j; + char *x; + unsigned long u; + int s; + int t; - while ((opt = getopt(argc,argv,"dDvqQhHrR1x:t:u:g:l:b:B:c:pPoO")) != opteof) + while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx:t:u:g:l:b:B:c:pPoO")) != opteof) switch(opt) { case 'b': scan_ulong(optarg,&backlog); break; case 'c': scan_ulong(optarg,&limit); break; + case 'X': flagallownorules = 1; break; case 'x': fnrules = optarg; break; case 'B': banner = optarg; break; case 'd': flagdelay = 1; break; @@ -286,220 +321,105 @@ char **argv; case 'R': flagremoteinfo = 0; break; case 'r': flagremoteinfo = 1; break; case 't': scan_ulong(optarg,&timeout); break; - case 'g': scan_ulong(optarg,&gid); break; + case 'U': x = env_get("UID"); if (x) scan_ulong(x,&uid); + x = env_get("GID"); if (x) scan_ulong(x,&gid); break; case 'u': scan_ulong(optarg,&uid); break; + case 'g': scan_ulong(optarg,&gid); break; case '1': flag1 = 1; break; - case 'l': forcelocal = optarg; break; + case 'l': localhost = optarg; break; default: usage(); } argc -= optind; argv += optind; + + if (!verbosity) + buffer_2->fd = -1; hostname = *argv++; if (!hostname) usage(); - portname = *argv++; - if (!portname) usage(); - if (!*argv) usage(); - - sig_pipeignore(); - sig_termcatch(sigterm); - sig_childcatch(sigchld); - - dns_init(1); - - byte_zero(&salocal,sizeof(salocal)); - salocal.sin_family = AF_INET; - - if (!portname[scan_ulong(portname,&portlocal)]) - salocal.sin_port = htons((unsigned short) portlocal); - else { - se = getservbyname(portname,"tcp"); - if (!se) { - if (verbosity) strerr_warn3(FATAL,"unable to figure out port number for ",portname,0); - _exit(111); - } - salocal.sin_port = se->s_port; - } - if (str_equal(hostname,"")) hostname = "0.0.0.0"; if (str_equal(hostname,"0")) hostname = "0.0.0.0"; - - if (hostname[ip_scan(hostname,&iplocal)]) { - if (!stralloc_copys(&tmp,hostname)) die_nomem(); - switch(dns_ip(&ia,&tmp)) { - case DNS_MEM: - die_nomem(); - case DNS_HARD: - if (verbosity) strerr_warn3(FATAL,"unable to figure out IP address for ",hostname,0); - _exit(111); - case DNS_SOFT: - if (verbosity) strerr_warn3(FATAL,"temporarily unable to figure out IP address for ",hostname,0); - _exit(111); - } - if (!ia.len) { - if (verbosity) strerr_warn3(FATAL,"no IP addresses for host ",hostname,0); - _exit(111); - } - byte_copy(&iplocal,4,&ia.ix[0].ip); + + x = *argv++; + if (!x) usage(); + if (!x[scan_ulong(x,&u)]) + localport = u; + else { + se = getservbyname(x,"tcp"); + if (!se) + strerr_die3x(111,FATAL,"unable to figure out port number for ",x); + localport = ntohs(se->s_port); } + + if (!*argv) usage(); - byte_copy(&salocal.sin_addr,4,&iplocal); - s = socket(AF_INET,SOCK_STREAM,0); - if (s == -1) { - if (verbosity) strerr_warn2(FATAL,"unable to create socket: ",&strerr_sys); - _exit(111); - } + sig_block(sig_child); + sig_catch(sig_child,sigchld); + sig_catch(sig_term,sigterm); + sig_ignore(sig_pipe); - { - int opt = 1; - setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); - } + if (!stralloc_copys(&tmp,hostname)) + strerr_die2x(111,FATAL,"out of memory"); + if (dns_ip4_qualify(&addresses,&fqdn,&tmp) == -1) + strerr_die4sys(111,FATAL,"temporarily unable to figure out IP address for ",hostname,": "); + if (addresses.len < 4) + strerr_die3x(111,FATAL,"no IP address for ",hostname); + byte_copy(localip,4,addresses.s); + + s = socket_tcp(); + if (s == -1) + strerr_die2sys(111,FATAL,"unable to create socket: "); + if (socket_bind4_reuse(s,localip,localport) == -1) + strerr_die2sys(111,FATAL,"unable to bind: "); + if (socket_local4(s,localip,&localport) == -1) + strerr_die2sys(111,FATAL,"unable to get local address: "); + if (socket_listen(s,backlog) == -1) + strerr_die2sys(111,FATAL,"unable to listen: "); + ndelay_off(s); + + if (gid) if (prot_gid(gid) == -1) + strerr_die2sys(111,FATAL,"unable to set gid: "); + if (uid) if (prot_uid(uid) == -1) + strerr_die2sys(111,FATAL,"unable to set uid: "); - if (bind(s,(struct sockaddr *) &salocal,sizeof(salocal)) == -1) { - if (verbosity) strerr_warn2(FATAL,"unable to bind: ",&strerr_sys); - _exit(111); - } - dummy = sizeof(salocal); - if (getsockname(s,(struct sockaddr *) &salocal,&dummy) == -1) { - if (verbosity) strerr_warn2(FATAL,"unable to get local address: ",&strerr_sys); - _exit(111); - } - if (listen(s,backlog) == -1) { - if (verbosity) strerr_warn2(FATAL,"unable to listen: ",&strerr_sys); - _exit(111); - } - if (gid) if (setgid(gid) == -1) { - if (verbosity) strerr_warn2(FATAL,"unable to set gid: ",&strerr_sys); - _exit(100); + localportstr[fmt_ulong(localportstr,localport)] = 0; + if (flag1) { + buffer_init(&b,write,1,bspace,sizeof bspace); + buffer_puts(&b,localportstr); + buffer_puts(&b,"\n"); + buffer_flush(&b); } - if (uid) if (setuid(uid) == -1) { - if (verbosity) strerr_warn2(FATAL,"unable to set uid: ",&strerr_sys); - _exit(100); - } - - if (!env_init()) die_nomem(); - if (!env_put("PROTO=TCP")) die_nomem(); - if (!env_unset("TCPLOCALHOST")) die_nomem(); - if (!env_unset("TCPREMOTEHOST")) die_nomem(); - if (!env_unset("TCPREMOTEINFO")) die_nomem(); - - if (forcelocal) - if (!env_put2("TCPLOCALHOST",forcelocal)) die_nomem(); - - portlocal = ntohs(salocal.sin_port); - tcplocalport[fmt_ulong(tcplocalport,portlocal)] = 0; - if (!env_put2("TCPLOCALPORT",tcplocalport)) die_nomem(); - if (flag1) printlocalport(); close(0); close(1); - sig_childblock(); + printstatus(); for (;;) { while (numchildren >= limit) sig_pause(); - sig_childunblock(); - - dummy = sizeof(saremote); - t = accept(s,(struct sockaddr *) &saremote,&dummy); - if (t == -1) continue; - portremote = ntohs(saremote.sin_port); - byte_copy(&ipremote,4,&saremote.sin_addr); - - sig_childblock(); + sig_unblock(sig_child); + t = socket_accept4(s,remoteip,&remoteport); + sig_block(sig_child); + + if (t == -1) continue; ++numchildren; printstatus(); switch(fork()) { - case -1: - if (verbosity) strerr_warn2(DROP,"unable to fork: ",&strerr_sys); - --numchildren; printstatus(); - break; case 0: - tcpremoteip[ip_fmt(tcpremoteip,&ipremote)] = 0; - printpid(); - close(s); - if (flagkillopts) { - setsockopt(t,IPPROTO_IP,1,(char *) 0,0); /* 1 == IP_OPTIONS */ - /* if it fails, bummer */ - } - if (!flagdelay) { - int opt = 1; - setsockopt(t,IPPROTO_TCP,1,&opt,sizeof(opt)); /* 1 == TCP_NODELAY */ - /* if it fails, bummer */ - } - - if (*banner) { - substdio ss; - char ssbuf[1]; - substdio_fdbuf(&ss,write,t,ssbuf,sizeof ssbuf); - if (substdio_putsflush(&ss,banner) == -1) { - if (verbosity) strerr_warn2(DROP,"unable to print banner: ",&strerr_sys); - _exit(111); - } - } - - dummy = sizeof(salocal); - if (getsockname(t,(struct sockaddr *) &salocal,&dummy) == -1) { - if (verbosity) strerr_warn2(DROP,"unable to get local address: ",&strerr_sys); - _exit(111); - } - byte_copy(&iplocal,4,&salocal.sin_addr); - - tcplocalip[ip_fmt(tcplocalip,&iplocal)] = 0; - tcpremoteport[fmt_ulong(tcpremoteport,portremote)] = 0; - - if (!env_put2("TCPREMOTEIP",tcpremoteip)) drop_nomem(); - if (!env_put2("TCPLOCALIP",tcplocalip)) drop_nomem(); - if (!env_put2("TCPREMOTEPORT",tcpremoteport)) drop_nomem(); - - if (!forcelocal) - switch(dns_ptr(&tmp,&iplocal)) { - case DNS_MEM: drop_nomem(); - case 0: - if (!stralloc_0(&tmp)) drop_nomem(); - case_lowers(tmp.s); - if (!env_put2("TCPLOCALHOST",tmp.s)) drop_nomem(); - } - - if (flagremotehost) - switch(dns_ptr(&tmp,&ipremote)) { - case DNS_MEM: drop_nomem(); - case 0: - if (flagparanoid) { - if (dns_ip(&ia,&tmp) != 0) break; - for (j = 0;j < ia.len;++j) - if (!byte_diff(&ipremote,4,&ia.ix[j].ip)) - break; - if (j == ia.len) - break; - } - if (!stralloc_0(&tmp)) drop_nomem(); - case_lowers(tmp.s); - if (!env_put2("TCPREMOTEHOST",tmp.s)) drop_nomem(); - } - if (flagremoteinfo) { - tcpremoteinfo = remoteinfo_get(&ipremote,portremote,&iplocal,portlocal,(int) timeout); - if (tcpremoteinfo) - if (!env_put2("TCPREMOTEINFO",tcpremoteinfo)) drop_nomem(); - } - - rules(); - printenv(); - if (flagdeny) _exit(100); - - if ((fd_move(0,t) == -1) || (fd_copy(1,0) == -1)) { - if (verbosity) strerr_warn2(DROP,"unable to set up descriptors: ",&strerr_sys); - _exit(111); - } - sig_childdefault(); - sig_childunblock(); - sig_termdefault(); - sig_pipedefault(); - execvp(*argv,argv); - if (verbosity) strerr_warn4(DROP,"unable to run ",*argv,": ",&strerr_sys); - _exit(111); + doit(t); + if ((fd_move(0,t) == -1) || (fd_copy(1,0) == -1)) + strerr_die2sys(111,DROP,"unable to set up descriptors: "); + sig_uncatch(sig_child); + sig_unblock(sig_child); + sig_uncatch(sig_term); + sig_uncatch(sig_pipe); + pathexec(argv); + strerr_die4sys(111,DROP,"unable to run ",*argv,": "); + case -1: + strerr_warn2(DROP,"unable to fork: ",&strerr_sys); + --numchildren; printstatus(); } close(t); } diff --git a/timeoutconn.c b/timeoutconn.c index 33a16d9..2a8b0aa 100644 --- a/timeoutconn.c +++ b/timeoutconn.c @@ -1,59 +1,34 @@ -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> #include "ndelay.h" -#include "select.h" +#include "socket.h" +#include "iopause.h" #include "error.h" -#include "readwrite.h" -#include "ip.h" -#include "byte.h" #include "timeoutconn.h" -int timeoutconn(s,ip,port,timeout) -int s; -struct ip_address *ip; -unsigned int port; -int timeout; +int timeoutconn(int s,char ip[4],uint16 port,unsigned int timeout) { - char ch; - struct sockaddr_in sin; - char *x; - fd_set wfds; - struct timeval tv; - - byte_zero(&sin,sizeof(sin)); - byte_copy(&sin.sin_addr,4,ip); - x = (char *) &sin.sin_port; - x[1] = port; port >>= 8; x[0] = port; - sin.sin_family = AF_INET; - - if (ndelay_on(s) == -1) return -1; - - /* XXX: could bind s */ - - if (connect(s,(struct sockaddr *) &sin,sizeof(sin)) == 0) { - ndelay_off(s); - return 0; - } - if ((errno != error_inprogress) && (errno != error_wouldblock)) return -1; - - FD_ZERO(&wfds); - FD_SET(s,&wfds); - tv.tv_sec = timeout; tv.tv_usec = 0; - - if (select(s + 1,(fd_set *) 0,&wfds,(fd_set *) 0,&tv) == -1) return -1; - if (FD_ISSET(s,&wfds)) { - int dummy; - dummy = sizeof(sin); - if (getpeername(s,(struct sockaddr *) &sin,&dummy) == -1) { - read(s,&ch,1); - return -1; + struct taia now; + struct taia deadline; + iopause_fd x; + + if (socket_connect4(s,ip,port) == -1) { + if ((errno != error_wouldblock) && (errno != error_inprogress)) return -1; + x.fd = s; + x.events = IOPAUSE_WRITE; + taia_now(&now); + taia_uint(&deadline,timeout); + taia_add(&deadline,&now,&deadline); + for (;;) { + taia_now(&now); + iopause(&x,1,&deadline,&now); + if (x.revents) break; + if (taia_less(&deadline,&now)) { + errno = error_timeout; /* note that connect attempt is continuing */ + return -1; + } } - ndelay_off(s); - return 0; + if (!socket_connected(s)) return -1; } - - errno = error_timeout; /* note that connect attempt is continuing */ - return -1; + + if (ndelay_off(s) == -1) return -1; + return 0; } diff --git a/timeoutconn.h b/timeoutconn.h index 88aab06..7f9dcc9 100644 --- a/timeoutconn.h +++ b/timeoutconn.h @@ -1,6 +1,8 @@ #ifndef TIMEOUTCONN_H #define TIMEOUTCONN_H -extern int timeoutconn(); +#include "uint16.h" + +extern int timeoutconn(int,char *,uint16,unsigned int); #endif diff --git a/timeoutread.c b/timeoutread.c deleted file mode 100644 index c75e29c..0000000 --- a/timeoutread.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "timeoutread.h" -#include "select.h" -#include "error.h" -#include "readwrite.h" - -int timeoutread(t,fd,buf,len) int t; int fd; char *buf; int len; -{ - fd_set rfds; - struct timeval tv; - - tv.tv_sec = t; - tv.tv_usec = 0; - - FD_ZERO(&rfds); - FD_SET(fd,&rfds); - - if (select(fd + 1,&rfds,(fd_set *) 0,(fd_set *) 0,&tv) == -1) return -1; - if (FD_ISSET(fd,&rfds)) return read(fd,buf,len); - - errno = error_timeout; - return -1; -} diff --git a/timeoutread.h b/timeoutread.h deleted file mode 100644 index 20d3bfc..0000000 --- a/timeoutread.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef TIMEOUTREAD_H -#define TIMEOUTREAD_H - -extern int timeoutread(); - -#endif diff --git a/timeoutwrite.c b/timeoutwrite.c deleted file mode 100644 index 516d283..0000000 --- a/timeoutwrite.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "timeoutwrite.h" -#include "select.h" -#include "error.h" -#include "readwrite.h" - -int timeoutwrite(t,fd,buf,len) int t; int fd; char *buf; int len; -{ - fd_set wfds; - struct timeval tv; - - tv.tv_sec = t; - tv.tv_usec = 0; - - FD_ZERO(&wfds); - FD_SET(fd,&wfds); - - if (select(fd + 1,(fd_set *) 0,&wfds,(fd_set *) 0,&tv) == -1) return -1; - if (FD_ISSET(fd,&wfds)) return write(fd,buf,len); - - errno = error_timeout; - return -1; -} diff --git a/timeoutwrite.h b/timeoutwrite.h deleted file mode 100644 index 4725861..0000000 --- a/timeoutwrite.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef TIMEOUTWRITE_H -#define TIMEOUTWRITE_H - -extern int timeoutwrite(); - -#endif @@ -1,4 +1,4 @@ -void main() +main() { #ifdef NeXT printf("nextstep\n"); exit(0); diff --git a/trypoll.c b/trypoll.c new file mode 100644 index 0000000..249824d --- /dev/null +++ b/trypoll.c @@ -0,0 +1,18 @@ +#include <sys/types.h> +#include <fcntl.h> +#include <poll.h> + +main() +{ + struct pollfd x; + + x.fd = open("trypoll.c",O_RDONLY); + if (x.fd == -1) _exit(111); + x.events = POLLIN; + if (poll(&x,1,10) == -1) _exit(1); + if (x.revents != POLLIN) _exit(1); + + /* XXX: try to detect and avoid poll() imitation libraries */ + + _exit(0); +} diff --git a/tryrsolv.c b/tryrsolv.c deleted file mode 100644 index 40ed2d3..0000000 --- a/tryrsolv.c +++ /dev/null @@ -1,7 +0,0 @@ -main() -{ - dn_expand(); - res_init(); - res_query(); - res_search(); -} @@ -1,6 +1,6 @@ #include <signal.h> -void main() +main() { struct sigaction sa; sa.sa_handler = 0; @@ -1,6 +1,6 @@ #include <signal.h> -void main() +main() { sigset_t ss; diff --git a/tryshsgr.c b/tryshsgr.c new file mode 100644 index 0000000..f55ff60 --- /dev/null +++ b/tryshsgr.c @@ -0,0 +1,14 @@ +main() +{ + short x[4]; + + x[0] = x[1] = 1; + if (getgroups(1,x) == 0) if (setgroups(1,x) == -1) _exit(1); + + if (getgroups(1,x) == -1) _exit(1); + if (x[1] != 1) _exit(1); + x[1] = 2; + if (getgroups(1,x) == -1) _exit(1); + if (x[1] != 2) _exit(1); + _exit(0); +} diff --git a/tryulong32.c b/tryulong32.c index a108076..63156e6 100644 --- a/tryulong32.c +++ b/tryulong32.c @@ -1,4 +1,4 @@ -void main() +main() { unsigned long u; u = 1; diff --git a/tryulong64.c b/tryulong64.c new file mode 100644 index 0000000..01965cb --- /dev/null +++ b/tryulong64.c @@ -0,0 +1,11 @@ +main() +{ + unsigned long u; + u = 1; + u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; + u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; + u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; + u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; + if (!u) _exit(1); + _exit(0); +} diff --git a/tryvfork.c b/tryvfork.c new file mode 100644 index 0000000..cc39699 --- /dev/null +++ b/tryvfork.c @@ -0,0 +1,4 @@ +main() +{ + vfork(); +} @@ -1,7 +1,7 @@ #include <sys/types.h> #include <sys/wait.h> -void main() +main() { waitpid(0,0,0); } diff --git a/ucspi-rss.diff b/ucspi-rss.diff new file mode 100644 index 0000000..903125e --- /dev/null +++ b/ucspi-rss.diff @@ -0,0 +1,64 @@ +diff -ruN --exclude conf-* ucspi-tcp-0.88/rblsmtpd.c ucspi-tcp-0.88.fix/rblsmtpd.c +--- ucspi-tcp-0.88/rblsmtpd.c Sat Mar 18 10:18:42 2000 ++++ ucspi-tcp-0.88.fix/rblsmtpd.c Wed Aug 9 16:42:33 2000 +@@ -60,16 +60,54 @@ + + void rbl(char *base) + { ++ int i; ++ char *altreply = 0; + if (decision) return; + if (!stralloc_copy(&tmp,&ip_reverse)) nomem(); ++ i = str_chr(base, ':'); ++ if (base[i]) { ++ base[i] = 0; ++ altreply = base+i+1; ++ } + if (!stralloc_cats(&tmp,base)) nomem(); +- if (dns_txt(&text,&tmp) == -1) { +- flagmustnotbounce = 1; +- if (flagfailclosed) { +- if (!stralloc_copys(&text,"temporary RBL lookup error")) nomem(); +- decision = 2; ++ if (altreply) { ++ if (dns_ip4(&text,&tmp) == -1) { ++ flagmustnotbounce = 1; ++ if (flagfailclosed) { ++ if (!stralloc_copys(&text,"temporary RBL lookup error")) nomem(); ++ decision = 2; ++ } ++ return; ++ } ++ if (text.len) { ++ if(!stralloc_copys(&text, "")) nomem(); ++ while(*altreply) { ++ char *x; ++ i = str_chr(altreply, '%'); ++ if(!stralloc_catb(&text, altreply, i)) nomem(); ++ if(altreply[i] && ++ altreply[i+1]=='I' && ++ altreply[i+2]=='P' && ++ altreply[i+3]=='%') { ++ if(!stralloc_catb(&text, ip_env, str_len(ip_env))) nomem(); ++ altreply+=i+4; ++ } else if(altreply[i]) { ++ if(!stralloc_cats(&text, "%")) nomem(); ++ altreply+=i+1; ++ } else { ++ altreply+=i; ++ } ++ } ++ } ++ } else { ++ if (dns_txt(&text,&tmp) == -1) { ++ flagmustnotbounce = 1; ++ if (flagfailclosed) { ++ if (!stralloc_copys(&text,"temporary RBL lookup error")) nomem(); ++ decision = 2; ++ } ++ return; + } +- return; + } + if (text.len) + if (flagrblbounce) diff --git a/uint16.h b/uint16.h new file mode 100644 index 0000000..34ab9f4 --- /dev/null +++ b/uint16.h @@ -0,0 +1,11 @@ +#ifndef UINT16_H +#define UINT16_H + +typedef unsigned short uint16; + +extern void uint16_pack(char *,uint16); +extern void uint16_pack_big(char *,uint16); +extern void uint16_unpack(char *,uint16 *); +extern void uint16_unpack_big(char *,uint16 *); + +#endif diff --git a/uint16_pack.c b/uint16_pack.c new file mode 100644 index 0000000..17dbfe6 --- /dev/null +++ b/uint16_pack.c @@ -0,0 +1,13 @@ +#include "uint16.h" + +void uint16_pack(char s[2],uint16 u) +{ + s[0] = u & 255; + s[1] = u >> 8; +} + +void uint16_pack_big(char s[2],uint16 u) +{ + s[1] = u & 255; + s[0] = u >> 8; +} diff --git a/uint16_unpack.c b/uint16_unpack.c new file mode 100644 index 0000000..18b5b12 --- /dev/null +++ b/uint16_unpack.c @@ -0,0 +1,23 @@ +#include "uint16.h" + +void uint16_unpack(char s[2],uint16 *u) +{ + uint16 result; + + result = (unsigned char) s[1]; + result <<= 8; + result += (unsigned char) s[0]; + + *u = result; +} + +void uint16_unpack_big(char s[2],uint16 *u) +{ + uint16 result; + + result = (unsigned char) s[0]; + result <<= 8; + result += (unsigned char) s[1]; + + *u = result; +} @@ -3,4 +3,9 @@ typedef unsigned int uint32; +extern void uint32_pack(char *,uint32); +extern void uint32_pack_big(char *,uint32); +extern void uint32_unpack(char *,uint32 *); +extern void uint32_unpack_big(char *,uint32 *); + #endif @@ -3,4 +3,9 @@ typedef unsigned long uint32; +extern void uint32_pack(char *,uint32); +extern void uint32_pack_big(char *,uint32); +extern void uint32_unpack(char *,uint32 *); +extern void uint32_unpack_big(char *,uint32 *); + #endif diff --git a/uint32_pack.c b/uint32_pack.c new file mode 100644 index 0000000..76bc670 --- /dev/null +++ b/uint32_pack.c @@ -0,0 +1,21 @@ +#include "uint32.h" + +void uint32_pack(char s[4],uint32 u) +{ + s[0] = u & 255; + u >>= 8; + s[1] = u & 255; + u >>= 8; + s[2] = u & 255; + s[3] = u >> 8; +} + +void uint32_pack_big(char s[4],uint32 u) +{ + s[3] = u & 255; + u >>= 8; + s[2] = u & 255; + u >>= 8; + s[1] = u & 255; + s[0] = u >> 8; +} diff --git a/uint32_unpack.c b/uint32_unpack.c new file mode 100644 index 0000000..f484644 --- /dev/null +++ b/uint32_unpack.c @@ -0,0 +1,31 @@ +#include "uint32.h" + +void uint32_unpack(char s[4],uint32 *u) +{ + uint32 result; + + result = (unsigned char) s[3]; + result <<= 8; + result += (unsigned char) s[2]; + result <<= 8; + result += (unsigned char) s[1]; + result <<= 8; + result += (unsigned char) s[0]; + + *u = result; +} + +void uint32_unpack_big(char s[4],uint32 *u) +{ + uint32 result; + + result = (unsigned char) s[0]; + result <<= 8; + result += (unsigned char) s[1]; + result <<= 8; + result += (unsigned char) s[2]; + result <<= 8; + result += (unsigned char) s[3]; + + *u = result; +} diff --git a/uint64.h1 b/uint64.h1 new file mode 100644 index 0000000..206fc09 --- /dev/null +++ b/uint64.h1 @@ -0,0 +1,8 @@ +#ifndef UINT64_H +#define UINT64_H + +/* sysdep: -ulong64 */ + +typedef unsigned long long uint64; + +#endif diff --git a/uint64.h2 b/uint64.h2 new file mode 100644 index 0000000..8a0f315 --- /dev/null +++ b/uint64.h2 @@ -0,0 +1,8 @@ +#ifndef UINT64_H +#define UINT64_H + +/* sysdep: +ulong64 */ + +typedef unsigned long uint64; + +#endif @@ -1,93 +0,0 @@ -.TH wait 3 -.SH NAME -wait \- check child process status -.SH SYNTAX -.B #include <wait.h> - -int \fBwait_nohang\fP(&\fIwstat\fR); -.br -int \fBwait_stop\fP(&\fIwstat\fR); -.br -int \fBwait_stopnohang\fP(&\fIwstat\fR); -.br -int \fBwait_pid\fP(&\fIwstat\fR,\fIpid\fR); - -int \fBwait_exitcode\fP(\fIwstat\fR); -.br -int \fBwait_crashed\fP(\fIwstat\fR); -.br -int \fBwait_stopped\fP(\fIwstat\fR); -.br -int \fBwait_stopsig\fP(\fIwstat\fR); - -int \fIpid\fR; -.br -int \fIwstat\fR; -.SH DESCRIPTION -.B wait_nohang -looks for zombies (child processes that have exited). -If it sees a zombie, -it eliminates the zombie, -puts the zombie's exit status into -.IR wstat , -and returns the zombie's process ID. -If there are several zombies, -.B wait_nohang -picks one. -If there are children but no zombies, -.B wait_nohang -returns 0. -If there are no children, -.B wait_nohang -returns -1, -setting -.B errno -appropriately. - -.B wait_stopnohang -is similar to -.BR wait_nohang , -but it also looks for children that have stopped. - -.B wait_stop -is similar to -.BR wait_stopnohang , -but if there are children it will pause waiting for one of them -to stop or exit. - -.B wait_pid -waits for child process -.I pid -to exit. -It eliminates any zombie that shows up in the meantime, -discarding the exit status. - -.B wait_stop -and -.B wait_pid -retry upon -.BR error_intr . -.SH "STATUS PARSING" -If the child stopped, -.B wait_stopped -is nonzero; -.B wait_stopsig -is the signal that caused the child to stop. - -If the child exited by crashing, -.B wait_stopped -is zero; -.B wait_crashed -is nonzero. - -If the child exited normally, -.B wait_stopped -is zero; -.B wait_crashed -is zero; -and -.B wait_exitcode -is the child's exit code. -.SH "SEE ALSO" -wait(2), -error(3) diff --git a/warn-shsgr b/warn-shsgr new file mode 100644 index 0000000..37c351e --- /dev/null +++ b/warn-shsgr @@ -0,0 +1,3 @@ +Oops. Your getgroups() returned 0, and setgroups() failed; this means +that I can't reliably do my shsgr test. Please either ``make'' as root +or ``make'' while you're in one or more supplementary groups. @@ -1,32 +0,0 @@ -.TH who@ 1 -.SH NAME -who@ \- print list of active users on a host -.SH SYNTAX -.B who@ -[ -.I host -] -.SH DESCRIPTION -.B who@ -connects to TCP port 11 (Systat) on -.I host -and prints any data it receives. -It removes CR and converts unprintable characters to a visible format. - -If -.I host -is not supplied, -.B who@ -connects to the local host. - -Some computers respond to port 11 with a list of active users. -For example, they may be running - -.EX - tcpserver 0 11 who & -.EE -.SH "SEE ALSO" -cat(1), -delcr(1), -tcpclient(1), -tcpserver(1) diff --git a/x86cpuid.c b/x86cpuid.c new file mode 100644 index 0000000..900d7d5 --- /dev/null +++ b/x86cpuid.c @@ -0,0 +1,38 @@ +#include <signal.h> + +void nope() +{ + exit(1); +} + +main() +{ + unsigned long x[4]; + unsigned long y[4]; + int i; + int j; + char c; + + signal(SIGILL,nope); + + x[0] = 0; + x[1] = 0; + x[2] = 0; + x[3] = 0; + + asm volatile(".byte 15;.byte 162" : "=a"(x[0]),"=b"(x[1]),"=c"(x[3]),"=d"(x[2]) : "0"(0) ); + if (!x[0]) return 0; + asm volatile(".byte 15;.byte 162" : "=a"(y[0]),"=b"(y[1]),"=c"(y[2]),"=d"(y[3]) : "0"(1) ); + + for (i = 1;i < 4;++i) + for (j = 0;j < 4;++j) { + c = x[i] >> (8 * j); + if (c < 32) c = 32; + if (c > 126) c = 126; + putchar(c); + } + + printf("-%08x-%08x\n",y[0],y[3]); + + return 0; +} diff --git a/ööööööööööö b/ööööööööööö new file mode 100644 index 0000000..d11c988 --- /dev/null +++ b/ööööööööööö @@ -0,0 +1 @@ +/* sysdep: -shortsetgroups */ |