summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Marler <jmarler@debian.org>2001-06-27 17:50:48 -0500
committerDmitry Bogatov <KAction@debian.org>2018-11-29 05:18:29 +0000
commita2409046e935d6971367976483a3d92b6d00b23a (patch)
treeda67333d390a1de30f5a7bb5ebfc2da8661d9dbf
parent69ad798f290402999778ca0d4e147f98fe7e45e8 (diff)
parentb19ff825af9758fa905bf0ba29bbff66fa66cd50 (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--BLURB31
-rw-r--r--CHANGES200
-rw-r--r--FILES292
-rw-r--r--INSTALL22
-rw-r--r--Makefile901
-rw-r--r--README164
-rw-r--r--SYSDEPS5
-rw-r--r--TARGETS245
-rw-r--r--TCP45
-rw-r--r--THANKS122
-rw-r--r--TODO9
-rw-r--r--UCSPI131
-rw-r--r--VERSION2
-rw-r--r--addcr.122
-rw-r--r--addcr.c15
-rw-r--r--alloc.362
-rw-r--r--alloc.c2
-rw-r--r--argv0.147
-rw-r--r--argv0.c7
-rw-r--r--auto-str.c17
-rw-r--r--buffer.c10
-rw-r--r--buffer.h56
-rw-r--r--buffer_0.c12
-rw-r--r--buffer_1.c6
-rw-r--r--buffer_2.c6
-rw-r--r--buffer_copy.c16
-rw-r--r--buffer_get.c67
-rw-r--r--buffer_put.c88
-rw-r--r--case.3100
-rw-r--r--case.h12
-rw-r--r--case_diffb.c18
-rw-r--r--case_diffs.c17
-rw-r--r--case_lowers.c12
-rw-r--r--cdb.362
-rw-r--r--cdb.c136
-rw-r--r--cdb.h33
-rw-r--r--cdb_hash.c17
-rw-r--r--cdb_make.c153
-rw-r--r--cdb_make.h39
-rw-r--r--cdb_seek.c95
-rw-r--r--cdb_unpack.c12
-rw-r--r--cdbmake.h35
-rw-r--r--cdbmake_add.c117
-rw-r--r--cdbmake_hash.c10
-rw-r--r--cdbmake_pack.c11
-rw-r--r--cdbmss.c65
-rw-r--r--cdbmss.h16
-rw-r--r--chkshsgr.c10
-rw-r--r--choose.sh18
-rw-r--r--commands.c39
-rw-r--r--commands.h12
-rw-r--r--conf-cc2
-rw-r--r--conf-home4
-rw-r--r--conf-ld2
-rw-r--r--date@.132
-rw-r--r--debian/changelog35
-rw-r--r--debian/control2
-rw-r--r--debian/control.real6
-rw-r--r--debian/copyright2
-rw-r--r--debian/postinst7
-rw-r--r--debian/prerm5
-rwxr-xr-xdebian/rules47
-rw-r--r--debian/src.postinst6
-rw-r--r--debian/src.prerm5
-rw-r--r--delcr.130
-rw-r--r--delcr.c20
-rw-r--r--dns.c400
-rw-r--r--dns.h88
-rw-r--r--dns_dfd.c69
-rw-r--r--dns_domain.c61
-rw-r--r--dns_dtda.c35
-rw-r--r--dns_ip.c75
-rw-r--r--dns_ipq.c71
-rw-r--r--dns_name.c48
-rw-r--r--dns_nd.c24
-rw-r--r--dns_packet.c77
-rw-r--r--dns_random.c62
-rw-r--r--dns_rcip.c82
-rw-r--r--dns_rcrw.c130
-rw-r--r--dns_resolve.c29
-rw-r--r--dns_sortip.c20
-rw-r--r--dns_transmit.c364
-rw-r--r--dns_txt.c59
-rw-r--r--env.331
-rw-r--r--env.c116
-rw-r--r--env.h13
-rw-r--r--envread.c30
-rw-r--r--error.345
-rw-r--r--error.c21
-rw-r--r--error.h7
-rw-r--r--error_str.319
-rw-r--r--error_str.c15
-rw-r--r--fd.h4
-rw-r--r--fd_copy.344
-rw-r--r--fd_copy.c4
-rw-r--r--fd_move.341
-rw-r--r--fd_move.c4
-rw-r--r--find-systype.sh15
-rw-r--r--finger@.145
-rw-r--r--fixcr.111
-rw-r--r--fixcr.c25
-rw-r--r--fixcrio.c161
-rw-r--r--fmt.h30
-rw-r--r--fmt_str.c12
-rw-r--r--fmt_ulong.c2
-rw-r--r--fork.h19
-rw-r--r--fork.h29
-rw-r--r--gen_allocdefs.h6
-rw-r--r--getln.351
-rw-r--r--getln.c8
-rw-r--r--getln.h7
-rw-r--r--getln2.364
-rw-r--r--getln2.c17
-rw-r--r--hassgact.h11
-rw-r--r--hassgact.h22
-rw-r--r--hassgprm.h11
-rw-r--r--hassgprm.h22
-rw-r--r--hasshsgr.h11
-rw-r--r--hasshsgr.h22
-rw-r--r--haswaitp.h11
-rw-r--r--haswaitp.h22
-rw-r--r--hier.c60
-rw-r--r--http@.152
-rw-r--r--http@.sh6
-rw-r--r--install.c26
-rw-r--r--instcheck.c2
-rw-r--r--iopause.c76
-rw-r--r--iopause.h119
-rw-r--r--iopause.h218
-rw-r--r--ip.c53
-rw-r--r--ip.h11
-rw-r--r--ip4.h9
-rw-r--r--ip4_fmt.c18
-rw-r--r--ip4_scan.c19
-rw-r--r--ipalloc.c7
-rw-r--r--ipalloc.h14
-rw-r--r--mconnect-io.c37
-rw-r--r--mconnect.136
-rw-r--r--ndelay.h4
-rw-r--r--ndelay_off.c3
-rw-r--r--ndelay_on.c (renamed from ndelay.c)3
-rw-r--r--open.h10
-rw-r--r--open_read.c2
-rw-r--r--open_trunc.c2
-rw-r--r--open_write.c6
-rw-r--r--openreadclose.c16
-rw-r--r--openreadclose.h8
-rw-r--r--pathexec.h8
-rw-r--r--pathexec_env.c68
-rw-r--r--pathexec_run.c46
-rw-r--r--prot.c19
-rw-r--r--prot.h7
-rw-r--r--rblsmtpd.c236
-rw-r--r--readclose.c21
-rw-r--r--readclose.h9
-rw-r--r--recordio.175
-rw-r--r--recordio.c121
-rw-r--r--remoteinfo.c135
-rw-r--r--remoteinfo.h5
-rw-r--r--rts.exp280
-rw-r--r--rts.sh2
-rw-r--r--rts.tests318
-rw-r--r--rules.c100
-rw-r--r--rules.h9
-rw-r--r--scan.h38
-rw-r--r--scan_ulong.c15
-rw-r--r--seek.h8
-rw-r--r--seek_set.c2
-rw-r--r--select.h12
-rw-r--r--select.h22
-rw-r--r--sgetopt.328
-rw-r--r--sgetopt.c21
-rw-r--r--sgetopt.h2
-rw-r--r--sig.c12
-rw-r--r--sig.h58
-rw-r--r--sig_block.c8
-rw-r--r--sig_catch.c4
-rw-r--r--sig_child.c7
-rw-r--r--sig_pause.c2
-rw-r--r--sig_pipe.c5
-rw-r--r--sig_term.c7
-rw-r--r--socket.h22
-rw-r--r--socket_accept.c21
-rw-r--r--socket_bind.c33
-rw-r--r--socket_conn.c33
-rw-r--r--socket_delay.c11
-rw-r--r--socket_listen.c10
-rw-r--r--socket_local.c17
-rw-r--r--socket_opts.c10
-rw-r--r--socket_remote.c17
-rw-r--r--socket_tcp.c16
-rw-r--r--socket_udp.c16
-rw-r--r--str.h14
-rw-r--r--str_chr.c4
-rw-r--r--str_cpy.c16
-rw-r--r--str_diff.c4
-rw-r--r--str_diffn.c18
-rw-r--r--str_len.c3
-rw-r--r--str_start.c13
-rw-r--r--stralloc.3160
-rw-r--r--stralloc.h30
-rw-r--r--stralloc_cat.c4
-rw-r--r--stralloc_catb.c5
-rw-r--r--stralloc_cats.c4
-rw-r--r--stralloc_copy.c4
-rw-r--r--stralloc_opyb.c5
-rw-r--r--stralloc_opys.c4
-rw-r--r--strerr.h60
-rw-r--r--strerr_die.c34
-rw-r--r--strerr_sys.c2
-rw-r--r--subfd.h15
-rw-r--r--subfderr.c7
-rw-r--r--subfdin.c13
-rw-r--r--subfdout.c7
-rw-r--r--subgetopt.3357
-rw-r--r--subgetopt.c16
-rw-r--r--subgetopt.h2
-rw-r--r--substdi.c91
-rw-r--r--substdio.c15
-rw-r--r--substdio.h47
-rw-r--r--substdio_copy.c18
-rw-r--r--substdo.c108
-rw-r--r--tai.h26
-rw-r--r--tai_pack.c16
-rw-r--r--taia.h33
-rw-r--r--taia_add.c18
-rw-r--r--taia_approx.c6
-rw-r--r--taia_frac.c6
-rw-r--r--taia_less.c12
-rw-r--r--taia_now.c12
-rw-r--r--taia_pack.c20
-rw-r--r--taia_sub.c21
-rw-r--r--taia_uint.c10
-rw-r--r--tcp-environ.562
-rw-r--r--tcpcat.120
-rw-r--r--tcpclient.1151
-rw-r--r--tcpclient.c349
-rw-r--r--tcprules.1208
-rw-r--r--tcprules.c104
-rw-r--r--tcprulescheck.125
-rw-r--r--tcprulescheck.c115
-rw-r--r--tcpserver.1244
-rw-r--r--tcpserver.c694
-rw-r--r--timeoutconn.c77
-rw-r--r--timeoutconn.h4
-rw-r--r--timeoutread.c22
-rw-r--r--timeoutread.h6
-rw-r--r--timeoutwrite.c22
-rw-r--r--timeoutwrite.h6
-rw-r--r--trycpp.c2
-rw-r--r--trypoll.c18
-rw-r--r--tryrsolv.c7
-rw-r--r--trysgact.c2
-rw-r--r--trysgprm.c2
-rw-r--r--tryshsgr.c14
-rw-r--r--tryulong32.c2
-rw-r--r--tryulong64.c11
-rw-r--r--tryvfork.c4
-rw-r--r--trywaitp.c2
-rw-r--r--ucspi-rss.diff64
-rw-r--r--uint16.h11
-rw-r--r--uint16_pack.c13
-rw-r--r--uint16_unpack.c23
-rw-r--r--uint32.h15
-rw-r--r--uint32.h25
-rw-r--r--uint32_pack.c21
-rw-r--r--uint32_unpack.c31
-rw-r--r--uint64.h18
-rw-r--r--uint64.h28
-rw-r--r--wait.393
-rw-r--r--warn-shsgr3
-rw-r--r--who@.132
-rw-r--r--x86cpuid.c38
-rw-r--r--ööööööööööö1
274 files changed, 6125 insertions, 6485 deletions
diff --git a/BLURB b/BLURB
deleted file mode 100644
index 5ebd648..0000000
--- a/BLURB
+++ /dev/null
@@ -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.
diff --git a/CHANGES b/CHANGES
index 7044271..f21a528 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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.
diff --git a/FILES b/FILES
index afea10b..cfb38a5 100644
--- a/FILES
+++ b/FILES
@@ -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.
diff --git a/Makefile b/Makefile
index 41a9c98..a67b0cb 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/README b/README
index 8d6ea52..2d6ab86 100644
--- a/README
+++ b/README
@@ -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
diff --git a/SYSDEPS b/SYSDEPS
index f855826..e024e62 100644
--- a/SYSDEPS
+++ b/SYSDEPS
@@ -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
diff --git a/TARGETS b/TARGETS
index 71d3880..4d1f2a0 100644
--- a/TARGETS
+++ b/TARGETS
@@ -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
diff --git a/TCP b/TCP
deleted file mode 100644
index 1d31ca0..0000000
--- a/TCP
+++ /dev/null
@@ -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.
diff --git a/THANKS b/THANKS
deleted file mode 100644
index f600e73..0000000
--- a/THANKS
+++ /dev/null
@@ -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
diff --git a/TODO b/TODO
index 04a4a7a..f620416 100644
--- a/TODO
+++ b/TODO
@@ -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?
diff --git a/UCSPI b/UCSPI
deleted file mode 100644
index 07e6db4..0000000
--- a/UCSPI
+++ /dev/null
@@ -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.
diff --git a/VERSION b/VERSION
index fe81b98..2b47df0 100644
--- a/VERSION
+++ b/VERSION
@@ -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)
diff --git a/addcr.c b/addcr.c
index a452450..e8b69e3 100644
--- a/addcr.c
+++ b/addcr.c
@@ -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)
diff --git a/alloc.c b/alloc.c
index c661453..0e2d4cd 100644
--- a/alloc.c
+++ b/alloc.c
@@ -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)
diff --git a/argv0.c b/argv0.c
index de60616..2a0e936 100644
--- a/argv0.c
+++ b/argv0.c
@@ -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],": ");
}
diff --git a/auto-str.c b/auto-str.c
index acc3d60..0e793a2 100644
--- a/auto-str.c
+++ b/auto-str.c
@@ -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 = &it;
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 = &it;
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 = &it;
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));
+}
diff --git a/case.3 b/case.3
deleted file mode 100644
index 58bd724..0000000
--- a/case.3
+++ /dev/null
@@ -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)
diff --git a/case.h b/case.h
index 35a2434..93458d7 100644
--- a/case.h
+++ b/case.h
@@ -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;
- }
-}
diff --git a/cdb.3 b/cdb.3
deleted file mode 100644
index a85b34c..0000000
--- a/cdb.3
+++ /dev/null
@@ -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)
diff --git a/cdb.c b/cdb.c
new file mode 100644
index 0000000..b09d3a5
--- /dev/null
+++ b/cdb.c
@@ -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);
+}
diff --git a/cdb.h b/cdb.h
index 571e5d6..ff99810 100644
--- a/cdb.h
+++ b/cdb.h
@@ -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
diff --git a/cdb_hash.c b/cdb_hash.c
index 8238020..d8e3cb8 100644
--- a/cdb_hash.c
+++ b/cdb_hash.c
@@ -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
diff --git a/conf-cc b/conf-cc
index 0f29a89..7f41e18 100644
--- a/conf-cc
+++ b/conf-cc
@@ -1,3 +1,3 @@
-cc -O2 -g
+gcc -O2
This will be used to compile .c files.
diff --git a/conf-home b/conf-home
index 4265705..d203db0 100644
--- a/conf-home
+++ b/conf-home
@@ -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.
diff --git a/conf-ld b/conf-ld
index ef1fd70..59a0de7 100644
--- a/conf-ld
+++ b/conf-ld
@@ -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)
diff --git a/delcr.c b/delcr.c
index 09b9ff3..ab47860 100644
--- a/delcr.c
+++ b/delcr.c
@@ -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);
}
}
}
diff --git a/dns.c b/dns.c
deleted file mode 100644
index ed42787..0000000
--- a/dns.c
+++ /dev/null
@@ -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;
-}
diff --git a/dns.h b/dns.h
index bca9490..0948b1a 100644
--- a/dns.h
+++ b/dns.h
@@ -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;
+}
diff --git a/env.3 b/env.3
deleted file mode 100644
index 53a5f89..0000000
--- a/env.3
+++ /dev/null
@@ -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)
diff --git a/env.c b/env.c
index 05d527b..430203e 100644
--- a/env.c
+++ b/env.c
@@ -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;
}
diff --git a/env.h b/env.h
index 9befc79..777873a 100644
--- a/env.h
+++ b/env.h
@@ -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)
diff --git a/error.c b/error.c
index d51304f..ea16ff9 100644
--- a/error.c
+++ b/error.c
@@ -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
diff --git a/error.h b/error.h
index 01bd3dc..d5f3c7e 100644
--- a/error.h
+++ b/error.h
@@ -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
diff --git a/fd.h b/fd.h
index c3d6e3e..e9c08d6 100644
--- a/fd.h
+++ b/fd.h
@@ -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)
diff --git a/fd_copy.c b/fd_copy.c
index b9f7167..aa5e55e 100644
--- a/fd_copy.c
+++ b/fd_copy.c
@@ -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)
diff --git a/fd_move.c b/fd_move.c
index 1aa557f..821ee95 100644
--- a/fd_move.c
+++ b/fd_move.c
@@ -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],": ");
+}
diff --git a/fmt.h b/fmt.h
index ba2fe16..6fd8fef 100644
--- a/fmt.h
+++ b/fmt.h
@@ -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;
diff --git a/fork.h1 b/fork.h1
new file mode 100644
index 0000000..ddd589d
--- /dev/null
+++ b/fork.h1
@@ -0,0 +1,9 @@
+#ifndef FORK_H
+#define FORK_H
+
+/* sysdep: -vfork */
+
+extern int fork();
+#define vfork fork
+
+#endif
diff --git a/fork.h2 b/fork.h2
new file mode 100644
index 0000000..7c1b0b9
--- /dev/null
+++ b/fork.h2
@@ -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)
diff --git a/getln.c b/getln.c
index c5cb097..489621c 100644
--- a/getln.c
+++ b/getln.c
@@ -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;
diff --git a/getln.h b/getln.h
index cf4f934..3cae45f 100644
--- a/getln.h
+++ b/getln.h
@@ -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)
diff --git a/getln2.c b/getln2.c
index 9e576e9..bf622a4 100644
--- a/getln2.c
+++ b/getln2.c
@@ -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
diff --git a/hier.c b/hier.c
index f7882d0..5663ada 100644
--- a/hier.c
+++ b/hier.c
@@ -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)
diff --git a/http@.sh b/http@.sh
index 59fee56..039be03 100644
--- a/http@.sh
+++ b/http@.sh
@@ -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 }'
diff --git a/install.c b/install.c
index bf8afb6..605fed3 100644
--- a/install.c
+++ b/install.c
@@ -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
diff --git a/ip.c b/ip.c
deleted file mode 100644
index 5528ad5..0000000
--- a/ip.c
+++ /dev/null
@@ -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;
-}
diff --git a/ip.h b/ip.h
deleted file mode 100644
index b99002f..0000000
--- a/ip.h
+++ /dev/null
@@ -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
diff --git a/ip4.h b/ip4.h
new file mode 100644
index 0000000..64a7c1e
--- /dev/null
+++ b/ip4.h
@@ -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)
diff --git a/ndelay.h b/ndelay.h
index 68c6bce..60b788c 100644
--- a/ndelay.h
+++ b/ndelay.h
@@ -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);
}
diff --git a/ndelay.c b/ndelay_on.c
index 438d1d8..eccd8c8 100644
--- a/ndelay.c
+++ b/ndelay_on.c
@@ -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);
}
diff --git a/open.h b/open.h
index c903113..2963fa7 100644
--- a/open.h
+++ b/open.h
@@ -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;
+ }
+}
diff --git a/prot.c b/prot.c
new file mode 100644
index 0000000..0a8a373
--- /dev/null
+++ b/prot.c
@@ -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);
+}
diff --git a/prot.h b/prot.h
new file mode 100644
index 0000000..7dd0503
--- /dev/null
+++ b/prot.h
@@ -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)
diff --git a/recordio.c b/recordio.c
index 09277d9..a3ee03c 100644
--- a/recordio.c
+++ b/recordio.c
@@ -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
diff --git a/rts.exp b/rts.exp
index fbea93b..242d7cf 100644
--- a/rts.exp
+++ b/rts.exp
@@ -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
diff --git a/rts.sh b/rts.sh
index 50bee30..c71e839 100644
--- a/rts.sh
+++ b/rts.sh
@@ -1 +1 @@
-env - PATH=".:$PATH" sh rts.tests 2>&1 | cat -v
+env - PATH="`pwd`:$PATH" sh rts.tests 2>&1 | cat -v
diff --git a/rts.tests b/rts.tests
index ba8477b..8c23929 100644
--- a/rts.tests
+++ b/rts.tests
@@ -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
diff --git a/rules.c b/rules.c
new file mode 100644
index 0000000..1840360
--- /dev/null
+++ b/rules.c
@@ -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;
+}
diff --git a/rules.h b/rules.h
new file mode 100644
index 0000000..15d9b90
--- /dev/null
+++ b/rules.h
@@ -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
diff --git a/scan.h b/scan.h
index 8329300..758138c 100644
--- a/scan.h
+++ b/scan.h
@@ -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;
}
diff --git a/seek.h b/seek.h
index 964fba3..06aad97 100644
--- a/seek.h
+++ b/seek.h
@@ -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))
diff --git a/seek_set.c b/seek_set.c
index f540664..d08d4f3 100644
--- a/seek_set.c
+++ b/seek_set.c
@@ -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; }
diff --git a/select.h1 b/select.h1
index 32d0968..fe725b6 100644
--- a/select.h1
+++ b/select.h1
@@ -1,6 +1,8 @@
#ifndef SELECT_H
#define SELECT_H
+/* sysdep: -sysselect */
+
#include <sys/types.h>
#include <sys/time.h>
extern int select();
diff --git a/select.h2 b/select.h2
index eb4b8fe..2bc2044 100644
--- a/select.h2
+++ b/select.h2
@@ -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)
diff --git a/sgetopt.c b/sgetopt.c
index a8bffc0..bdd0f14 100644
--- a/sgetopt.c
+++ b/sgetopt.c
@@ -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;
}
diff --git a/sgetopt.h b/sgetopt.h
index 5f89127..739203c 100644
--- a/sgetopt.h
+++ b/sgetopt.h
@@ -14,7 +14,7 @@
#include "subgetopt.h"
-extern int sgetoptmine();
+extern int sgetoptmine(int,char **,char *);
extern int sgetopterr;
extern char *sgetoptprogname;
diff --git a/sig.c b/sig.c
new file mode 100644
index 0000000..0368bcc
--- /dev/null
+++ b/sig.c
@@ -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;
diff --git a/sig.h b/sig.h
index 9c3a28c..bc522e4 100644
--- a/sig.h
+++ b/sig.h
@@ -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;
+}
diff --git a/str.h b/str.h
index e00773c..ab4aedd 100644
--- a/str.h
+++ b/str.h
@@ -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)))
diff --git a/str_chr.c b/str_chr.c
index 3691826..886d6b6 100644
--- a/str_chr.c
+++ b/str_chr.c
@@ -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;
- }
-}
diff --git a/str_diff.c b/str_diff.c
index 18f8927..037dcdf 100644
--- a/str_diff.c
+++ b/str_diff.c
@@ -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);
-}
diff --git a/str_len.c b/str_len.c
index 2d2f88b..5bd3f62 100644
--- a/str_len.c
+++ b/str_len.c
@@ -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)
diff --git a/stralloc.h b/stralloc.h
index 2feb7d0..7866812 100644
--- a/stralloc.h
+++ b/stralloc.h
@@ -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));
}
diff --git a/strerr.h b/strerr.h
index d18e833..702f588 100644
--- a/strerr.h
+++ b/strerr.h
@@ -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 = &it;
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 = &it;
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 = &it;
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));
-}
diff --git a/tai.h b/tai.h
new file mode 100644
index 0000000..28ee9e6
--- /dev/null
+++ b/tai.h
@@ -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;
+}
diff --git a/taia.h b/taia.h
new file mode 100644
index 0000000..f4c0ca7
--- /dev/null
+++ b/taia.h
@@ -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)
diff --git a/tcprules.c b/tcprules.c
index 1264fea..a684ac5 100644
--- a/tcprules.c
+++ b/tcprules.c
@@ -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
diff --git a/trycpp.c b/trycpp.c
index d7d83ad..3ab455b 100644
--- a/trycpp.c
+++ b/trycpp.c
@@ -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();
-}
diff --git a/trysgact.c b/trysgact.c
index 263cb21..98a4b20 100644
--- a/trysgact.c
+++ b/trysgact.c
@@ -1,6 +1,6 @@
#include <signal.h>
-void main()
+main()
{
struct sigaction sa;
sa.sa_handler = 0;
diff --git a/trysgprm.c b/trysgprm.c
index ed28857..2797eea 100644
--- a/trysgprm.c
+++ b/trysgprm.c
@@ -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();
+}
diff --git a/trywaitp.c b/trywaitp.c
index 7e73bfa..64d807e 100644
--- a/trywaitp.c
+++ b/trywaitp.c
@@ -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;
+}
diff --git a/uint32.h1 b/uint32.h1
index 6599aa0..68d7231 100644
--- a/uint32.h1
+++ b/uint32.h1
@@ -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
diff --git a/uint32.h2 b/uint32.h2
index 716430d..b5c7f40 100644
--- a/uint32.h2
+++ b/uint32.h2
@@ -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
diff --git a/wait.3 b/wait.3
deleted file mode 100644
index 8c41f4b..0000000
--- a/wait.3
+++ /dev/null
@@ -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.
diff --git a/who@.1 b/who@.1
deleted file mode 100644
index 0c13f84..0000000
--- a/who@.1
+++ /dev/null
@@ -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 */