diff options
218 files changed, 9151 insertions, 0 deletions
diff --git a/ucspi-tcp-0.88/CHANGES b/ucspi-tcp-0.88/CHANGES new file mode 100644 index 0000000..f21a528 --- /dev/null +++ b/ucspi-tcp-0.88/CHANGES @@ -0,0 +1,148 @@ +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/ucspi-tcp-0.88/FILES b/ucspi-tcp-0.88/FILES new file mode 100644 index 0000000..cfb38a5 --- /dev/null +++ b/ucspi-tcp-0.88/FILES @@ -0,0 +1,218 @@ +README +TODO +CHANGES +VERSION +FILES +SYSDEPS +TARGETS +Makefile +conf-cc +conf-ld +conf-home +tcpserver.c +tcprules.c +tcprulescheck.c +recordio.c +argv0.c +tcpclient.c +date@.sh +finger@.sh +http@.sh +who@.sh +tcpcat.sh +mconnect.sh +mconnect-io.c +addcr.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 +alloc.c +alloc.h +alloc_re.c +auto-str.c +auto_home.h +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 +byte_cr.c +byte_diff.c +byte_rchr.c +byte_zero.c +case.h +case_diffb.c +case_diffs.c +cdb.c +cdb.h +cdb_hash.c +cdb_make.c +cdb_make.h +chkshsgr.c +choose.sh +commands.c +commands.h +dns.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 +env.h +error.c +error.h +error_str.c +exit.h +fd.h +fd_copy.c +fd_move.c +find-systype.sh +fmt.h +fmt_ulong.c +fork.h1 +fork.h2 +gen_alloc.h +gen_allocdefs.h +getln.c +getln.h +getln2.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_off.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 +sgetopt.c +sgetopt.h +sig.c +sig.h +sig_block.c +sig_catch.c +sig_pause.c +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_cat.c +stralloc_catb.c +stralloc_cats.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 +uint32_pack.c +uint32_unpack.c +uint64.h1 +uint64.h2 +wait.h +wait_nohang.c +wait_pid.c +warn-auto.sh +warn-shsgr +x86cpuid.c diff --git a/ucspi-tcp-0.88/Makefile b/ucspi-tcp-0.88/Makefile new file mode 100644 index 0000000..a67b0cb --- /dev/null +++ b/ucspi-tcp-0.88/Makefile @@ -0,0 +1,837 @@ +# Don't edit Makefile! Use conf-* for configuration. + +SHELL=/bin/sh + +default: it + +addcr: \ +load addcr.o unix.a byte.a + ./load addcr unix.a byte.a + +addcr.o: \ +compile addcr.c buffer.h exit.h + ./compile addcr.c + +alloc.o: \ +compile alloc.c alloc.h error.h + ./compile alloc.c + +alloc_re.o: \ +compile alloc_re.c alloc.h byte.h + ./compile alloc_re.c + +argv0: \ +load argv0.o unix.a byte.a + ./load argv0 unix.a byte.a + +argv0.o: \ +compile argv0.c pathexec.h strerr.h + ./compile argv0.c + +auto-str: \ +load auto-str.o unix.a byte.a + ./load auto-str unix.a byte.a + +auto-str.o: \ +compile auto-str.c buffer.h readwrite.h exit.h + ./compile auto-str.c + +auto_home.c: \ +auto-str conf-home + ./auto-str auto_home `head -1 conf-home` > auto_home.c + +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 + +byte_copy.o: \ +compile byte_copy.c byte.h + ./compile byte_copy.c + +byte_cr.o: \ +compile byte_cr.c byte.h + ./compile byte_cr.c + +byte_diff.o: \ +compile byte_diff.c byte.h + ./compile byte_diff.c + +byte_rchr.o: \ +compile byte_rchr.c byte.h + ./compile byte_rchr.c + +byte_zero.o: \ +compile byte_zero.c byte.h + ./compile byte_zero.c + +case_diffb.o: \ +compile case_diffb.c case.h + ./compile case_diffb.c + +case_diffs.o: \ +compile case_diffs.c case.h + ./compile case_diffs.c + +cdb.a: \ +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_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 + +check: \ +it instcheck + ./instcheck + +chkshsgr: \ +load chkshsgr.o + ./load chkshsgr + +chkshsgr.o: \ +compile chkshsgr.c exit.h + ./compile chkshsgr.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 + +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 + ( cat warn-auto.sh; \ + echo exec "`head -1 conf-cc`" '-c $${1+"$$@"}' \ + ) > compile + chmod 755 compile + +date@: \ +warn-auto.sh date@.sh conf-home + cat warn-auto.sh date@.sh \ + | sed s}HOME}"`head -1 conf-home`"}g \ + > date@ + chmod 755 date@ + +delcr: \ +load delcr.o unix.a byte.a + ./load delcr unix.a byte.a + +delcr.o: \ +compile delcr.c buffer.h exit.h + ./compile delcr.c + +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 env.h + ./compile env.c + +error.o: \ +compile error.c error.h + ./compile error.c + +error_str.o: \ +compile error_str.c error.h + ./compile error_str.c + +fd_copy.o: \ +compile fd_copy.c fd.h + ./compile fd_copy.c + +fd_move.o: \ +compile fd_move.c fd.h + ./compile fd_move.c + +finger@: \ +warn-auto.sh finger@.sh conf-home + cat warn-auto.sh finger@.sh \ + | sed s}HOME}"`head -1 conf-home`"}g \ + > finger@ + chmod 755 finger@ + +fixcrio: \ +load fixcrio.o time.a unix.a byte.a + ./load fixcrio time.a unix.a byte.a + +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 + +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 byte.h getln.h buffer.h stralloc.h gen_alloc.h + ./compile getln.c + +getln2.o: \ +compile getln2.c byte.h getln.h buffer.h stralloc.h gen_alloc.h + ./compile getln2.c + +hassgact.h: \ +choose compile load trysgact.c hassgact.h1 hassgact.h2 + ./choose cl trysgact hassgact.h1 hassgact.h2 > hassgact.h + +hassgprm.h: \ +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: \ +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 + ./compile hier.c + +http@: \ +warn-auto.sh http@.sh conf-home + cat warn-auto.sh http@.sh \ + | sed s}HOME}"`head -1 conf-home`"}g \ + > http@ + chmod 755 http@ + +install: \ +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 buffer.h strerr.h error.h open.h readwrite.h exit.h + ./compile install.c + +instcheck: \ +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 + +iopause.h: \ +choose compile trypoll.c iopause.h1 iopause.h2 + ./choose clr trypoll iopause.h1 iopause.h2 > iopause.h + +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: \ +prog install instcheck + +load: \ +warn-auto.sh conf-ld + ( cat warn-auto.sh; \ + echo 'main="$$1"; shift'; \ + echo exec "`head -1 conf-ld`" \ + '-o "$$main" "$$main".o $${1+"$$@"}' \ + ) > load + chmod 755 load + +makelib: \ +warn-auto.sh systype + ( cat warn-auto.sh; \ + echo 'main="$$1"; shift'; \ + echo 'rm -f "$$main"'; \ + echo 'ar cr "$$main" $${1+"$$@"}'; \ + case "`cat systype`" in \ + sunos-5.*) ;; \ + unix_sv*) ;; \ + irix64-*) ;; \ + irix-*) ;; \ + dgux-*) ;; \ + hp-ux-*) ;; \ + sco*) ;; \ + *) echo 'ranlib "$$main"' ;; \ + esac \ + ) > makelib + chmod 755 makelib + +mconnect: \ +warn-auto.sh mconnect.sh conf-home + cat warn-auto.sh mconnect.sh \ + | sed s}HOME}"`head -1 conf-home`"}g \ + > mconnect + chmod 755 mconnect + +mconnect-io: \ +load mconnect-io.o unix.a byte.a + ./load mconnect-io unix.a byte.a + +mconnect-io.o: \ +compile mconnect-io.c sig.h wait.h fork.h buffer.h strerr.h \ +readwrite.h exit.h + ./compile mconnect-io.c + +ndelay_off.o: \ +compile ndelay_off.c ndelay.h + ./compile ndelay_off.c + +ndelay_on.o: \ +compile ndelay_on.c ndelay.h + ./compile ndelay_on.c + +open_read.o: \ +compile open_read.c open.h + ./compile open_read.c + +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: \ +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 time.a unix.a byte.a + ./load recordio time.a unix.a byte.a + +recordio.o: \ +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 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: \ +warn-auto.sh rts.sh conf-home + cat warn-auto.sh rts.sh \ + | sed s}HOME}"`head -1 conf-home`"}g \ + > 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_set.o: \ +compile seek_set.c seek.h + ./compile seek_set.c + +select.h: \ +choose compile trysysel.c select.h1 select.h2 + ./choose c trysysel select.h1 select.h2 > select.h + +setup: \ +it install + ./install + +sgetopt.o: \ +compile sgetopt.c buffer.h sgetopt.h subgetopt.h subgetopt.h + ./compile sgetopt.c + +sig.o: \ +compile sig.c sig.h + ./compile sig.c + +sig_block.o: \ +compile sig_block.c sig.h hassgprm.h + ./compile sig_block.c + +sig_catch.o: \ +compile sig_catch.c sig.h hassgact.h + ./compile sig_catch.c + +sig_pause.o: \ +compile sig_pause.c sig.h hassgprm.h + ./compile sig_pause.c + +socket.lib: \ +trylsock.c compile load + ( ( ./compile trylsock.c && \ + ./load trylsock -lsocket -lnsl ) >/dev/null 2>&1 \ + && echo -lsocket -lnsl || exit 0 ) > socket.lib + rm -f trylsock.o trylsock + +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_diff.o: \ +compile str_diff.c str.h + ./compile str_diff.c + +str_len.o: \ +compile str_len.c str.h + ./compile str_len.c + +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 + ./compile stralloc_cat.c + +stralloc_catb.o: \ +compile stralloc_catb.c stralloc.h gen_alloc.h byte.h + ./compile stralloc_catb.c + +stralloc_cats.o: \ +compile stralloc_cats.c byte.h str.h stralloc.h gen_alloc.h + ./compile stralloc_cats.c + +stralloc_copy.o: \ +compile stralloc_copy.c byte.h stralloc.h gen_alloc.h + ./compile stralloc_copy.c + +stralloc_eady.o: \ +compile stralloc_eady.c alloc.h stralloc.h gen_alloc.h \ +gen_allocdefs.h + ./compile stralloc_eady.c + +stralloc_opyb.o: \ +compile stralloc_opyb.c stralloc.h gen_alloc.h byte.h + ./compile stralloc_opyb.c + +stralloc_opys.o: \ +compile stralloc_opys.c byte.h str.h stralloc.h gen_alloc.h + ./compile stralloc_opys.c + +stralloc_pend.o: \ +compile stralloc_pend.c alloc.h stralloc.h gen_alloc.h \ +gen_allocdefs.h + ./compile stralloc_pend.c + +strerr_die.o: \ +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 + +subgetopt.o: \ +compile subgetopt.c subgetopt.h + ./compile subgetopt.c + +systype: \ +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 + +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 + cat warn-auto.sh tcpcat.sh \ + | sed s}HOME}"`head -1 conf-home`"}g \ + > tcpcat + chmod 755 tcpcat + +tcpclient: \ +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 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 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 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 rules.o cdb.a unix.a byte.a + ./load tcprulescheck rules.o cdb.a unix.a byte.a + +tcprulescheck.o: \ +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 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 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 socket.h uint16.h iopause.h taia.h \ +tai.h uint64.h error.h timeoutconn.h uint16.h + ./compile timeoutconn.c + +uint16_pack.o: \ +compile uint16_pack.c uint16.h + ./compile uint16_pack.c + +uint16_unpack.o: \ +compile uint16_unpack.c uint16.h + ./compile uint16_unpack.c + +uint32.h: \ +tryulong32.c compile load uint32.h1 uint32.h2 + ( ( ./compile tryulong32.c && ./load tryulong32 && \ + ./tryulong32 ) >/dev/null 2>&1 \ + && cat uint32.h2 || cat uint32.h1 ) > uint32.h + rm -f tryulong32.o tryulong32 + +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 + ./compile wait_nohang.c + +wait_pid.o: \ +compile wait_pid.c error.h haswaitp.h + ./compile wait_pid.c + +who@: \ +warn-auto.sh who@.sh conf-home + cat warn-auto.sh who@.sh \ + | sed s}HOME}"`head -1 conf-home`"}g \ + > who@ + chmod 755 who@ diff --git a/ucspi-tcp-0.88/README b/ucspi-tcp-0.88/README new file mode 100644 index 0000000..2d6ab86 --- /dev/null +++ b/ucspi-tcp-0.88/README @@ -0,0 +1,7 @@ +ucspi-tcp 0.88, beta. +20000318 +Copyright 2000 +D. J. Bernstein + +ucspi-tcp home page: http://cr.yp.to/ucspi-tcp.html +Installation instructions: http://cr.yp.to/ucspi-tcp/install.html diff --git a/ucspi-tcp-0.88/SYSDEPS b/ucspi-tcp-0.88/SYSDEPS new file mode 100644 index 0000000..e024e62 --- /dev/null +++ b/ucspi-tcp-0.88/SYSDEPS @@ -0,0 +1,12 @@ +VERSION +systype +fork.h +hassgact.h +hassgprm.h +hasshsgr.h +haswaitp.h +iopause.h +select.h +socket.lib +uint32.h +uint64.h diff --git a/ucspi-tcp-0.88/TARGETS b/ucspi-tcp-0.88/TARGETS new file mode 100644 index 0000000..4d1f2a0 --- /dev/null +++ b/ucspi-tcp-0.88/TARGETS @@ -0,0 +1,171 @@ +load +compile +choose +iopause.h +uint64.h +tcpserver.o +uint32.h +rules.o +remoteinfo.o +timeoutconn.o +systype +makelib +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 +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 +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 +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 +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 +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 +addcr.o +addcr +delcr.o +delcr +fixcrio.o +fixcrio +rblsmtpd.o +commands.o +rblsmtpd +rts +prog +install.o +hier.o +auto-str.o +auto-str +auto_home.c +auto_home.o +install +instcheck.o +instcheck +it +setup +check diff --git a/ucspi-tcp-0.88/TODO b/ucspi-tcp-0.88/TODO new file mode 100644 index 0000000..f620416 --- /dev/null +++ b/ucspi-tcp-0.88/TODO @@ -0,0 +1,3 @@ +inetd.conf conversion tools +pre-forking version of tcpserver? +rule directory in tcpserver? diff --git a/ucspi-tcp-0.88/VERSION b/ucspi-tcp-0.88/VERSION new file mode 100644 index 0000000..2b47df0 --- /dev/null +++ b/ucspi-tcp-0.88/VERSION @@ -0,0 +1 @@ +ucspi-tcp 0.88 diff --git a/ucspi-tcp-0.88/addcr.c b/ucspi-tcp-0.88/addcr.c new file mode 100644 index 0000000..e8b69e3 --- /dev/null +++ b/ucspi-tcp-0.88/addcr.c @@ -0,0 +1,22 @@ +#include "buffer.h" +#include "exit.h" + +main() +{ + register int n; + register char *x; + char ch; + + for (;;) { + n = buffer_feed(buffer_0); + if (n < 0) _exit(111); + if (!n) _exit(0); + x = buffer_PEEK(buffer_0); + buffer_SEEK(buffer_0,n); + while (n > 0) { + ch = *x++; --n; + if (ch == '\n') buffer_PUTC(buffer_1,"\r"[0]); + buffer_PUTC(buffer_1,ch); + } + } +} diff --git a/ucspi-tcp-0.88/alloc.c b/ucspi-tcp-0.88/alloc.c new file mode 100644 index 0000000..0e2d4cd --- /dev/null +++ b/ucspi-tcp-0.88/alloc.c @@ -0,0 +1,32 @@ +#include "alloc.h" +#include "error.h" +extern char *malloc(); +extern void free(); + +#define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */ +#define SPACE 2048 /* must be multiple of ALIGNMENT */ + +typedef union { char irrelevant[ALIGNMENT]; double d; } aligned; +static aligned realspace[SPACE / ALIGNMENT]; +#define space ((char *) realspace) +static unsigned int avail = SPACE; /* multiple of ALIGNMENT; 0<=avail<=SPACE */ + +/*@null@*//*@out@*/char *alloc(n) +unsigned int n; +{ + char *x; + n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */ + if (n <= avail) { avail -= n; return space + avail; } + x = malloc(n); + if (!x) errno = error_nomem; + return x; +} + +void alloc_free(x) +char *x; +{ + if (x >= space) + if (x < space + SPACE) + return; /* XXX: assuming that pointers are flat */ + free(x); +} diff --git a/ucspi-tcp-0.88/alloc.h b/ucspi-tcp-0.88/alloc.h new file mode 100644 index 0000000..1b1d893 --- /dev/null +++ b/ucspi-tcp-0.88/alloc.h @@ -0,0 +1,8 @@ +#ifndef ALLOC_H +#define ALLOC_H + +extern /*@null@*//*@out@*/char *alloc(); +extern void alloc_free(); +extern int alloc_re(); + +#endif diff --git a/ucspi-tcp-0.88/alloc_re.c b/ucspi-tcp-0.88/alloc_re.c new file mode 100644 index 0000000..feb8b49 --- /dev/null +++ b/ucspi-tcp-0.88/alloc_re.c @@ -0,0 +1,17 @@ +#include "alloc.h" +#include "byte.h" + +int alloc_re(x,m,n) +char **x; +unsigned int m; +unsigned int n; +{ + char *y; + + y = alloc(n); + if (!y) return 0; + byte_copy(y,m,*x); + alloc_free(*x); + *x = y; + return 1; +} diff --git a/ucspi-tcp-0.88/argv0.c b/ucspi-tcp-0.88/argv0.c new file mode 100644 index 0000000..2a0e936 --- /dev/null +++ b/ucspi-tcp-0.88/argv0.c @@ -0,0 +1,10 @@ +#include "pathexec.h" +#include "strerr.h" + +main(int argc,char **argv,char **envp) +{ + if (argc < 3) + strerr_die1x(100,"argv0: usage: argv0 realname program [ arg ... ]"); + pathexec_run(argv[1],argv + 2,envp); + strerr_die4sys(111,"argv0: fatal: ","unable to run ",argv[1],": "); +} diff --git a/ucspi-tcp-0.88/auto-str.c b/ucspi-tcp-0.88/auto-str.c new file mode 100644 index 0000000..0e793a2 --- /dev/null +++ b/ucspi-tcp-0.88/auto-str.c @@ -0,0 +1,41 @@ +#include "buffer.h" +#include "readwrite.h" +#include "exit.h" + +char bspace[256]; +buffer b = BUFFER_INIT(write,1,bspace,sizeof bspace); + +void puts(char *s) +{ + if (buffer_puts(&b,s) == -1) _exit(111); +} + +main(int argc,char **argv) +{ + char *name; + char *value; + unsigned char ch; + char octal[4]; + + name = argv[1]; + if (!name) _exit(100); + value = argv[2]; + if (!value) _exit(100); + + puts("char "); + puts(name); + puts("[] = \"\\\n"); + + while (ch = *value++) { + puts("\\"); + octal[3] = 0; + octal[2] = '0' + (ch & 7); ch >>= 3; + octal[1] = '0' + (ch & 7); ch >>= 3; + octal[0] = '0' + (ch & 7); + puts(octal); + } + + puts("\\\n\";\n"); + if (buffer_flush(&b) == -1) _exit(111); + _exit(0); +} diff --git a/ucspi-tcp-0.88/auto_home.h b/ucspi-tcp-0.88/auto_home.h new file mode 100644 index 0000000..a756cd0 --- /dev/null +++ b/ucspi-tcp-0.88/auto_home.h @@ -0,0 +1,6 @@ +#ifndef AUTO_HOME_H +#define AUTO_HOME_H + +extern char auto_home[]; + +#endif diff --git a/ucspi-tcp-0.88/buffer.c b/ucspi-tcp-0.88/buffer.c new file mode 100644 index 0000000..f44a697 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/buffer.h b/ucspi-tcp-0.88/buffer.h new file mode 100644 index 0000000..12539b3 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/buffer_0.c b/ucspi-tcp-0.88/buffer_0.c new file mode 100644 index 0000000..6c5365a --- /dev/null +++ b/ucspi-tcp-0.88/buffer_0.c @@ -0,0 +1,12 @@ +#include "readwrite.h" +#include "buffer.h" + +int buffer_0_read(fd,buf,len) int fd; char *buf; int len; +{ + if (buffer_flush(buffer_1) == -1) return -1; + return read(fd,buf,len); +} + +char buffer_0_space[BUFFER_INSIZE]; +static buffer it = BUFFER_INIT(buffer_0_read,0,buffer_0_space,sizeof buffer_0_space); +buffer *buffer_0 = ⁢ diff --git a/ucspi-tcp-0.88/buffer_1.c b/ucspi-tcp-0.88/buffer_1.c new file mode 100644 index 0000000..3104e22 --- /dev/null +++ b/ucspi-tcp-0.88/buffer_1.c @@ -0,0 +1,6 @@ +#include "readwrite.h" +#include "buffer.h" + +char buffer_1_space[BUFFER_OUTSIZE]; +static buffer it = BUFFER_INIT(write,1,buffer_1_space,sizeof buffer_1_space); +buffer *buffer_1 = ⁢ diff --git a/ucspi-tcp-0.88/buffer_2.c b/ucspi-tcp-0.88/buffer_2.c new file mode 100644 index 0000000..297825c --- /dev/null +++ b/ucspi-tcp-0.88/buffer_2.c @@ -0,0 +1,6 @@ +#include "readwrite.h" +#include "buffer.h" + +char buffer_2_space[256]; +static buffer it = BUFFER_INIT(write,2,buffer_2_space,sizeof buffer_2_space); +buffer *buffer_2 = ⁢ diff --git a/ucspi-tcp-0.88/buffer_copy.c b/ucspi-tcp-0.88/buffer_copy.c new file mode 100644 index 0000000..dc4d4b1 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/buffer_get.c b/ucspi-tcp-0.88/buffer_get.c new file mode 100644 index 0000000..937b75e --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/buffer_put.c b/ucspi-tcp-0.88/buffer_put.c new file mode 100644 index 0000000..a05e1f5 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/byte.h b/ucspi-tcp-0.88/byte.h new file mode 100644 index 0000000..de06c69 --- /dev/null +++ b/ucspi-tcp-0.88/byte.h @@ -0,0 +1,13 @@ +#ifndef BYTE_H +#define BYTE_H + +extern unsigned int byte_chr(); +extern unsigned int byte_rchr(); +extern void byte_copy(); +extern void byte_copyr(); +extern int byte_diff(); +extern void byte_zero(); + +#define byte_equal(s,n,t) (!byte_diff((s),(n),(t))) + +#endif diff --git a/ucspi-tcp-0.88/byte_chr.c b/ucspi-tcp-0.88/byte_chr.c new file mode 100644 index 0000000..f81dde8 --- /dev/null +++ b/ucspi-tcp-0.88/byte_chr.c @@ -0,0 +1,20 @@ +#include "byte.h" + +unsigned int byte_chr(s,n,c) +char *s; +register unsigned int n; +int c; +{ + register char ch; + register char *t; + + ch = c; + t = s; + for (;;) { + if (!n) break; if (*t == ch) break; ++t; --n; + if (!n) break; if (*t == ch) break; ++t; --n; + if (!n) break; if (*t == ch) break; ++t; --n; + if (!n) break; if (*t == ch) break; ++t; --n; + } + return t - s; +} diff --git a/ucspi-tcp-0.88/byte_copy.c b/ucspi-tcp-0.88/byte_copy.c new file mode 100644 index 0000000..eaad11b --- /dev/null +++ b/ucspi-tcp-0.88/byte_copy.c @@ -0,0 +1,14 @@ +#include "byte.h" + +void byte_copy(to,n,from) +register char *to; +register unsigned int n; +register char *from; +{ + for (;;) { + if (!n) return; *to++ = *from++; --n; + if (!n) return; *to++ = *from++; --n; + if (!n) return; *to++ = *from++; --n; + if (!n) return; *to++ = *from++; --n; + } +} diff --git a/ucspi-tcp-0.88/byte_cr.c b/ucspi-tcp-0.88/byte_cr.c new file mode 100644 index 0000000..3e7a1d5 --- /dev/null +++ b/ucspi-tcp-0.88/byte_cr.c @@ -0,0 +1,16 @@ +#include "byte.h" + +void byte_copyr(to,n,from) +register char *to; +register unsigned int n; +register char *from; +{ + to += n; + from += n; + for (;;) { + if (!n) return; *--to = *--from; --n; + if (!n) return; *--to = *--from; --n; + if (!n) return; *--to = *--from; --n; + if (!n) return; *--to = *--from; --n; + } +} diff --git a/ucspi-tcp-0.88/byte_diff.c b/ucspi-tcp-0.88/byte_diff.c new file mode 100644 index 0000000..cdbd760 --- /dev/null +++ b/ucspi-tcp-0.88/byte_diff.c @@ -0,0 +1,16 @@ +#include "byte.h" + +int byte_diff(s,n,t) +register char *s; +register unsigned int n; +register char *t; +{ + for (;;) { + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + } + return ((int)(unsigned int)(unsigned char) *s) + - ((int)(unsigned int)(unsigned char) *t); +} diff --git a/ucspi-tcp-0.88/byte_rchr.c b/ucspi-tcp-0.88/byte_rchr.c new file mode 100644 index 0000000..476bc22 --- /dev/null +++ b/ucspi-tcp-0.88/byte_rchr.c @@ -0,0 +1,23 @@ +#include "byte.h" + +unsigned int byte_rchr(s,n,c) +char *s; +register unsigned int n; +int c; +{ + register char ch; + register char *t; + register char *u; + + ch = c; + t = s; + u = 0; + for (;;) { + if (!n) break; if (*t == ch) u = t; ++t; --n; + if (!n) break; if (*t == ch) u = t; ++t; --n; + if (!n) break; if (*t == ch) u = t; ++t; --n; + if (!n) break; if (*t == ch) u = t; ++t; --n; + } + if (!u) u = t; + return u - s; +} diff --git a/ucspi-tcp-0.88/byte_zero.c b/ucspi-tcp-0.88/byte_zero.c new file mode 100644 index 0000000..92009ba --- /dev/null +++ b/ucspi-tcp-0.88/byte_zero.c @@ -0,0 +1,13 @@ +#include "byte.h" + +void byte_zero(s,n) +char *s; +register unsigned int n; +{ + for (;;) { + if (!n) break; *s++ = 0; --n; + if (!n) break; *s++ = 0; --n; + if (!n) break; *s++ = 0; --n; + if (!n) break; *s++ = 0; --n; + } +} diff --git a/ucspi-tcp-0.88/case.h b/ucspi-tcp-0.88/case.h new file mode 100644 index 0000000..93458d7 --- /dev/null +++ b/ucspi-tcp-0.88/case.h @@ -0,0 +1,13 @@ +#ifndef CASE_H +#define CASE_H + +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))) + +#endif diff --git a/ucspi-tcp-0.88/case_diffb.c b/ucspi-tcp-0.88/case_diffb.c new file mode 100644 index 0000000..967af56 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/case_diffs.c b/ucspi-tcp-0.88/case_diffs.c new file mode 100644 index 0000000..2575184 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/cdb.c b/ucspi-tcp-0.88/cdb.c new file mode 100644 index 0000000..b09d3a5 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/cdb.h b/ucspi-tcp-0.88/cdb.h new file mode 100644 index 0000000..ff99810 --- /dev/null +++ b/ucspi-tcp-0.88/cdb.h @@ -0,0 +1,37 @@ +/* Public domain. */ + +#ifndef CDB_H +#define CDB_H + +#include "uint32.h" + +#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); + +#define cdb_datapos(c) ((c)->dpos) +#define cdb_datalen(c) ((c)->dlen) + +#endif diff --git a/ucspi-tcp-0.88/cdb_hash.c b/ucspi-tcp-0.88/cdb_hash.c new file mode 100644 index 0000000..d8e3cb8 --- /dev/null +++ b/ucspi-tcp-0.88/cdb_hash.c @@ -0,0 +1,21 @@ +/* Public domain. */ + +#include "cdb.h" + +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 = CDB_HASHSTART; + while (len) { + h = cdb_hashadd(h,*buf++); + --len; + } + return h; +} diff --git a/ucspi-tcp-0.88/cdb_make.c b/ucspi-tcp-0.88/cdb_make.c new file mode 100644 index 0000000..6d1bd03 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/cdb_make.h b/ucspi-tcp-0.88/cdb_make.h new file mode 100644 index 0000000..b8bbe4d --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/chkshsgr.c b/ucspi-tcp-0.88/chkshsgr.c new file mode 100644 index 0000000..4c7fc83 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/choose.sh b/ucspi-tcp-0.88/choose.sh new file mode 100644 index 0000000..feff2da --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/commands.c b/ucspi-tcp-0.88/commands.c new file mode 100644 index 0000000..b2dc77d --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/commands.h b/ucspi-tcp-0.88/commands.h new file mode 100644 index 0000000..f5fb8fb --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/conf-cc b/ucspi-tcp-0.88/conf-cc new file mode 100644 index 0000000..7f41e18 --- /dev/null +++ b/ucspi-tcp-0.88/conf-cc @@ -0,0 +1,3 @@ +gcc -O2 + +This will be used to compile .c files. diff --git a/ucspi-tcp-0.88/conf-home b/ucspi-tcp-0.88/conf-home new file mode 100644 index 0000000..5b6b574 --- /dev/null +++ b/ucspi-tcp-0.88/conf-home @@ -0,0 +1,4 @@ +/usr/local + +This is the ucspi-tcp home directory. Programs will be installed in +.../bin. diff --git a/ucspi-tcp-0.88/conf-ld b/ucspi-tcp-0.88/conf-ld new file mode 100644 index 0000000..59a0de7 --- /dev/null +++ b/ucspi-tcp-0.88/conf-ld @@ -0,0 +1,3 @@ +gcc -s + +This will be used to link .o files into an executable. diff --git a/ucspi-tcp-0.88/date@.sh b/ucspi-tcp-0.88/date@.sh new file mode 100644 index 0000000..79bbe0c --- /dev/null +++ b/ucspi-tcp-0.88/date@.sh @@ -0,0 +1 @@ +HOME/bin/tcpclient -RHl0 -- "${1-0}" 13 sh -c 'exec HOME/bin/delcr <&6' | cat -v diff --git a/ucspi-tcp-0.88/delcr.c b/ucspi-tcp-0.88/delcr.c new file mode 100644 index 0000000..ab47860 --- /dev/null +++ b/ucspi-tcp-0.88/delcr.c @@ -0,0 +1,37 @@ +#include "buffer.h" +#include "exit.h" + +main() +{ + register int n; + register char *x; + char ch; + register int flagcr = 0; + + for (;;) { + n = buffer_feed(buffer_0); + if (n < 0) _exit(111); + if (!n) { + if (flagcr) buffer_PUTC(buffer_1,"\r"[0]); + buffer_flush(buffer_1); + _exit(0); + } + x = buffer_PEEK(buffer_0); + buffer_SEEK(buffer_0,n); + + while (n > 0) { + ch = *x++; --n; + if (!flagcr) { + if (ch == '\r') { flagcr = 1; continue; } + buffer_PUTC(buffer_1,ch); + continue; + } + if (ch != '\n') { + buffer_PUTC(buffer_1,"\r"[0]); + if (ch == '\r') continue; + } + flagcr = 0; + buffer_PUTC(buffer_1,ch); + } + } +} diff --git a/ucspi-tcp-0.88/dns.h b/ucspi-tcp-0.88/dns.h new file mode 100644 index 0000000..0948b1a --- /dev/null +++ b/ucspi-tcp-0.88/dns.h @@ -0,0 +1,84 @@ +#ifndef DNS_H +#define DNS_H + +#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/ucspi-tcp-0.88/dns_dfd.c b/ucspi-tcp-0.88/dns_dfd.c new file mode 100644 index 0000000..14a29d8 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_domain.c b/ucspi-tcp-0.88/dns_domain.c new file mode 100644 index 0000000..f898485 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_dtda.c b/ucspi-tcp-0.88/dns_dtda.c new file mode 100644 index 0000000..00b41a1 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_ip.c b/ucspi-tcp-0.88/dns_ip.c new file mode 100644 index 0000000..fb0526c --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_ipq.c b/ucspi-tcp-0.88/dns_ipq.c new file mode 100644 index 0000000..8181ab7 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_name.c b/ucspi-tcp-0.88/dns_name.c new file mode 100644 index 0000000..dcb10c7 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_nd.c b/ucspi-tcp-0.88/dns_nd.c new file mode 100644 index 0000000..279d74d --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_packet.c b/ucspi-tcp-0.88/dns_packet.c new file mode 100644 index 0000000..04a2cc8 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_random.c b/ucspi-tcp-0.88/dns_random.c new file mode 100644 index 0000000..b9892b4 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_rcip.c b/ucspi-tcp-0.88/dns_rcip.c new file mode 100644 index 0000000..2356c8b --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_rcrw.c b/ucspi-tcp-0.88/dns_rcrw.c new file mode 100644 index 0000000..6f215ac --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_resolve.c b/ucspi-tcp-0.88/dns_resolve.c new file mode 100644 index 0000000..3365c00 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_sortip.c b/ucspi-tcp-0.88/dns_sortip.c new file mode 100644 index 0000000..af9b235 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_transmit.c b/ucspi-tcp-0.88/dns_transmit.c new file mode 100644 index 0000000..df12826 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/dns_txt.c b/ucspi-tcp-0.88/dns_txt.c new file mode 100644 index 0000000..263b641 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/env.c b/ucspi-tcp-0.88/env.c new file mode 100644 index 0000000..430203e --- /dev/null +++ b/ucspi-tcp-0.88/env.c @@ -0,0 +1,15 @@ +#include "str.h" +#include "env.h" + +extern /*@null@*/char *env_get(char *s) +{ + int i; + unsigned int len; + + 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/ucspi-tcp-0.88/env.h b/ucspi-tcp-0.88/env.h new file mode 100644 index 0000000..777873a --- /dev/null +++ b/ucspi-tcp-0.88/env.h @@ -0,0 +1,8 @@ +#ifndef ENV_H +#define ENV_H + +extern char **environ; + +extern /*@null@*/char *env_get(char *); + +#endif diff --git a/ucspi-tcp-0.88/error.c b/ucspi-tcp-0.88/error.c new file mode 100644 index 0000000..ea16ff9 --- /dev/null +++ b/ucspi-tcp-0.88/error.c @@ -0,0 +1,116 @@ +#include <errno.h> +#include "error.h" + +/* warning: as coverage improves here, should update error_{str,temp} */ + +int error_intr = +#ifdef EINTR +EINTR; +#else +-1; +#endif + +int error_nomem = +#ifdef ENOMEM +ENOMEM; +#else +-2; +#endif + +int error_noent = +#ifdef ENOENT +ENOENT; +#else +-3; +#endif + +int error_txtbsy = +#ifdef ETXTBSY +ETXTBSY; +#else +-4; +#endif + +int error_io = +#ifdef EIO +EIO; +#else +-5; +#endif + +int error_exist = +#ifdef EEXIST +EEXIST; +#else +-6; +#endif + +int error_timeout = +#ifdef ETIMEDOUT +ETIMEDOUT; +#else +-7; +#endif + +int error_inprogress = +#ifdef EINPROGRESS +EINPROGRESS; +#else +-8; +#endif + +int error_wouldblock = +#ifdef EWOULDBLOCK +EWOULDBLOCK; +#else +-9; +#endif + +int error_again = +#ifdef EAGAIN +EAGAIN; +#else +-10; +#endif + +int error_pipe = +#ifdef EPIPE +EPIPE; +#else +-11; +#endif + +int error_perm = +#ifdef EPERM +EPERM; +#else +-12; +#endif + +int error_acces = +#ifdef EACCES +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/ucspi-tcp-0.88/error.h b/ucspi-tcp-0.88/error.h new file mode 100644 index 0000000..d5f3c7e --- /dev/null +++ b/ucspi-tcp-0.88/error.h @@ -0,0 +1,26 @@ +#ifndef ERROR_H +#define ERROR_H + +extern int errno; + +extern int error_intr; +extern int error_nomem; +extern int error_noent; +extern int error_txtbsy; +extern int error_io; +extern int error_exist; +extern int error_timeout; +extern int error_inprogress; +extern int error_wouldblock; +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(int); +extern int error_temp(int); + +#endif diff --git a/ucspi-tcp-0.88/error_str.c b/ucspi-tcp-0.88/error_str.c new file mode 100644 index 0000000..c999ab0 --- /dev/null +++ b/ucspi-tcp-0.88/error_str.c @@ -0,0 +1,269 @@ +#include <errno.h> +#include "error.h" + +#define X(e,s) if (i == e) return s; + +char *error_str(int i) +{ + X(0,"no error") + X(error_intr,"interrupted system call") + X(error_nomem,"out of memory") + X(error_noent,"file does not exist") + X(error_txtbsy,"text busy") + X(error_io,"input/output error") + X(error_exist,"file already exists") + X(error_timeout,"timed out") + X(error_inprogress,"operation in progress") + X(error_again,"temporary failure") + X(error_wouldblock,"input/output would block") + 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 E2BIG + X(E2BIG,"argument list too long") +#endif +#ifdef ENOEXEC + X(ENOEXEC,"exec format error") +#endif +#ifdef EBADF + X(EBADF,"file descriptor not open") +#endif +#ifdef ECHILD + X(ECHILD,"no child processes") +#endif +#ifdef EDEADLK + X(EDEADLK,"operation would cause deadlock") +#endif +#ifdef EFAULT + X(EFAULT,"bad address") +#endif +#ifdef ENOTBLK + X(ENOTBLK,"not a block device") +#endif +#ifdef EBUSY + X(EBUSY,"device busy") +#endif +#ifdef EXDEV + X(EXDEV,"cross-device link") +#endif +#ifdef ENODEV + X(ENODEV,"device does not support operation") +#endif +#ifdef ENOTDIR + X(ENOTDIR,"not a directory") +#endif +#ifdef EINVAL + X(EINVAL,"invalid argument") +#endif +#ifdef ENFILE + X(ENFILE,"system cannot open more files") +#endif +#ifdef EMFILE + X(EMFILE,"process cannot open more files") +#endif +#ifdef ENOTTY + X(ENOTTY,"not a tty") +#endif +#ifdef EFBIG + X(EFBIG,"file too big") +#endif +#ifdef ENOSPC + X(ENOSPC,"out of disk space") +#endif +#ifdef ESPIPE + X(ESPIPE,"unseekable descriptor") +#endif +#ifdef EROFS + X(EROFS,"read-only file system") +#endif +#ifdef EMLINK + X(EMLINK,"too many links") +#endif +#ifdef EDOM + X(EDOM,"input out of range") +#endif +#ifdef ERANGE + X(ERANGE,"output out of range") +#endif +#ifdef EALREADY + X(EALREADY,"operation already in progress") +#endif +#ifdef ENOTSOCK + X(ENOTSOCK,"not a socket") +#endif +#ifdef EDESTADDRREQ + X(EDESTADDRREQ,"destination address required") +#endif +#ifdef EMSGSIZE + X(EMSGSIZE,"message too long") +#endif +#ifdef EPROTOTYPE + X(EPROTOTYPE,"incorrect protocol type") +#endif +#ifdef ENOPROTOOPT + X(ENOPROTOOPT,"protocol not available") +#endif +#ifdef EPROTONOSUPPORT + X(EPROTONOSUPPORT,"protocol not supported") +#endif +#ifdef ESOCKTNOSUPPORT + X(ESOCKTNOSUPPORT,"socket type not supported") +#endif +#ifdef EOPNOTSUPP + X(EOPNOTSUPP,"operation not supported") +#endif +#ifdef EPFNOSUPPORT + X(EPFNOSUPPORT,"protocol family not supported") +#endif +#ifdef EAFNOSUPPORT + X(EAFNOSUPPORT,"address family not supported") +#endif +#ifdef EADDRINUSE + X(EADDRINUSE,"address already used") +#endif +#ifdef EADDRNOTAVAIL + X(EADDRNOTAVAIL,"address not available") +#endif +#ifdef ENETDOWN + X(ENETDOWN,"network down") +#endif +#ifdef ENETUNREACH + X(ENETUNREACH,"network unreachable") +#endif +#ifdef ENETRESET + X(ENETRESET,"network reset") +#endif +#ifdef ECONNABORTED + X(ECONNABORTED,"connection aborted") +#endif +#ifdef ECONNRESET + X(ECONNRESET,"connection reset") +#endif +#ifdef ENOBUFS + X(ENOBUFS,"out of buffer space") +#endif +#ifdef EISCONN + X(EISCONN,"already connected") +#endif +#ifdef ENOTCONN + X(ENOTCONN,"not connected") +#endif +#ifdef ESHUTDOWN + X(ESHUTDOWN,"socket shut down") +#endif +#ifdef ETOOMANYREFS + X(ETOOMANYREFS,"too many references") +#endif +#ifdef ECONNREFUSED + X(ECONNREFUSED,"connection refused") +#endif +#ifdef ELOOP + X(ELOOP,"symbolic link loop") +#endif +#ifdef ENAMETOOLONG + X(ENAMETOOLONG,"file name too long") +#endif +#ifdef EHOSTDOWN + X(EHOSTDOWN,"host down") +#endif +#ifdef EHOSTUNREACH + X(EHOSTUNREACH,"host unreachable") +#endif +#ifdef ENOTEMPTY + X(ENOTEMPTY,"directory not empty") +#endif +#ifdef EPROCLIM + X(EPROCLIM,"too many processes") +#endif +#ifdef EUSERS + X(EUSERS,"too many users") +#endif +#ifdef EDQUOT + X(EDQUOT,"disk quota exceeded") +#endif +#ifdef ESTALE + X(ESTALE,"stale NFS file handle") +#endif +#ifdef EREMOTE + X(EREMOTE,"too many levels of remote in path") +#endif +#ifdef EBADRPC + X(EBADRPC,"RPC structure is bad") +#endif +#ifdef ERPCMISMATCH + X(ERPCMISMATCH,"RPC version mismatch") +#endif +#ifdef EPROGUNAVAIL + X(EPROGUNAVAIL,"RPC program unavailable") +#endif +#ifdef EPROGMISMATCH + X(EPROGMISMATCH,"program version mismatch") +#endif +#ifdef EPROCUNAVAIL + X(EPROCUNAVAIL,"bad procedure for program") +#endif +#ifdef ENOLCK + X(ENOLCK,"no locks available") +#endif +#ifdef ENOSYS + X(ENOSYS,"system call not available") +#endif +#ifdef EFTYPE + X(EFTYPE,"bad file type") +#endif +#ifdef EAUTH + X(EAUTH,"authentication error") +#endif +#ifdef ENEEDAUTH + X(ENEEDAUTH,"not authenticated") +#endif +#ifdef ENOSTR + X(ENOSTR,"not a stream device") +#endif +#ifdef ETIME + X(ETIME,"timer expired") +#endif +#ifdef ENOSR + X(ENOSR,"out of stream resources") +#endif +#ifdef ENOMSG + X(ENOMSG,"no message of desired type") +#endif +#ifdef EBADMSG + X(EBADMSG,"bad message type") +#endif +#ifdef EIDRM + X(EIDRM,"identifier removed") +#endif +#ifdef ENONET + X(ENONET,"machine not on network") +#endif +#ifdef ERREMOTE + X(ERREMOTE,"object not local") +#endif +#ifdef ENOLINK + X(ENOLINK,"link severed") +#endif +#ifdef EADV + X(EADV,"advertise error") +#endif +#ifdef ESRMNT + X(ESRMNT,"srmount error") +#endif +#ifdef ECOMM + X(ECOMM,"communication error") +#endif +#ifdef EMULTIHOP + X(EMULTIHOP,"multihop attempted") +#endif +#ifdef EREMCHG + X(EREMCHG,"remote address changed") +#endif + return "unknown error"; +} diff --git a/ucspi-tcp-0.88/exit.h b/ucspi-tcp-0.88/exit.h new file mode 100644 index 0000000..39011c8 --- /dev/null +++ b/ucspi-tcp-0.88/exit.h @@ -0,0 +1,6 @@ +#ifndef EXIT_H +#define EXIT_H + +extern void _exit(); + +#endif diff --git a/ucspi-tcp-0.88/fd.h b/ucspi-tcp-0.88/fd.h new file mode 100644 index 0000000..e9c08d6 --- /dev/null +++ b/ucspi-tcp-0.88/fd.h @@ -0,0 +1,7 @@ +#ifndef FD_H +#define FD_H + +extern int fd_copy(int,int); +extern int fd_move(int,int); + +#endif diff --git a/ucspi-tcp-0.88/fd_copy.c b/ucspi-tcp-0.88/fd_copy.c new file mode 100644 index 0000000..aa5e55e --- /dev/null +++ b/ucspi-tcp-0.88/fd_copy.c @@ -0,0 +1,11 @@ +#include <fcntl.h> +#include "fd.h" + +int fd_copy(int to,int from) +{ + if (to == from) return 0; + if (fcntl(from,F_GETFL,0) == -1) return -1; + close(to); + if (fcntl(from,F_DUPFD,to) == -1) return -1; + return 0; +} diff --git a/ucspi-tcp-0.88/fd_move.c b/ucspi-tcp-0.88/fd_move.c new file mode 100644 index 0000000..821ee95 --- /dev/null +++ b/ucspi-tcp-0.88/fd_move.c @@ -0,0 +1,9 @@ +#include "fd.h" + +int fd_move(int to,int from) +{ + if (to == from) return 0; + if (fd_copy(to,from) == -1) return -1; + close(from); + return 0; +} diff --git a/ucspi-tcp-0.88/find-systype.sh b/ucspi-tcp-0.88/find-systype.sh new file mode 100644 index 0000000..0955c32 --- /dev/null +++ b/ucspi-tcp-0.88/find-systype.sh @@ -0,0 +1,159 @@ +# oper-:arch-:syst-:chip-:kern- +# oper = operating system type; e.g., sunos-4.1.4 +# arch = machine language; e.g., sparc +# syst = which binaries can run; e.g., sun4 +# chip = chip model; e.g., micro-2-80 +# kern = kernel version; e.g., sun4m +# dependence: arch --- chip +# \ \ +# oper --- syst --- kern +# so, for example, syst is interpreted in light of oper, but chip is not. +# anyway, no slashes, no extra colons, no uppercase letters. +# the point of the extra -'s is to ease parsing: can add hierarchies later. +# e.g., *:i386-*:*:pentium-*:* would handle pentium-100 as well as pentium, +# and i386-486 (486s do have more instructions, you know) as well as i386. +# 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 + unamer="`uname -r | tr /: ..`" + unamem="`uname -m | tr /: ..`" + unamev="`uname -v | tr /: ..`" + + case "$sys" in + bsd.os) + # in bsd 4.4, uname -v does not have useful info. + # in bsd 4.4, uname -m is arch, not chip. + oper="$sys-$unamer" + arch="$unamem" + syst="" + chip="`sysctl -n hw.model`" + kern="" + ;; + freebsd) + # see above about bsd 4.4 + oper="$sys-$unamer" + arch="$unamem" + syst="" + chip="`sysctl -n hw.model`" # hopefully + kern="" + ;; + netbsd) + # see above about bsd 4.4 + oper="$sys-$unamer" + arch="$unamem" + syst="" + chip="`sysctl -n hw.model`" # hopefully + kern="" + ;; + linux) + # as in bsd 4.4, uname -v does not have useful info. + oper="$sys-$unamer" + syst="" + chip="$unamem" + kern="" + case "$chip" in + i386|i486|i586|i686) + arch="i386" + ;; + alpha) + arch="alpha" + ;; + esac + ;; + aix) + # naturally IBM has to get uname -r and uname -v backwards. dorks. + oper="$sys-$unamev-$unamer" + arch="`arch | tr /: ..`" + syst="" + chip="$unamem" + kern="" + ;; + sunos) + oper="$sys-$unamer-$unamev" + arch="`(uname -p || mach) | tr /: ..`" + syst="`arch | tr /: ..`" + chip="$unamem" # this is wrong; is there any way to get the real info? + kern="`arch -k | tr /: ..`" + ;; + unix_sv) + oper="$sys-$unamer-$unamev" + arch="`uname -m`" + syst="" + chip="$unamem" + kern="" + ;; + *) + oper="$sys-$unamer-$unamev" + arch="`arch | tr /: ..`" + syst="" + chip="$unamem" + kern="" + ;; + esac +else + $CC -c trycpp.c + $LD -o trycpp trycpp.o + case `./trycpp` in + nextstep) + oper="nextstep-`hostinfo | sed -n 's/^[ ]*NeXT Mach \([^:]*\):.*$/\1/p'`" + arch="`hostinfo | sed -n 's/^Processor type: \(.*\) (.*)$/\1/p' | tr /: ..`" + syst="" + chip="`hostinfo | sed -n 's/^Processor type: .* (\(.*\))$/\1/p' | tr ' /:' '...'`" + kern="" + ;; + *) + oper="unknown" + arch="" + syst="" + chip="" + kern="" + ;; + esac + rm -f trycpp.o trycpp +fi + +case "$chip" in +80486) + # let's try to be consistent here. (BSD/OS) + chip=i486 + ;; +i486DX) + # respect the hyphen hierarchy. (FreeBSD) + chip=i486-dx + ;; +i486.DX2) + # respect the hyphen hierarchy. (FreeBSD) + chip=i486-dx2 + ;; +Intel.586) + # no, you nitwits, there is no such chip. (NeXTStep) + chip=pentium + ;; +i586) + # no, you nitwits, there is no such chip. (Linux) + chip=pentium + ;; +i686) + # STOP SAYING THAT! (Linux) + 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/ucspi-tcp-0.88/finger@.sh b/ucspi-tcp-0.88/finger@.sh new file mode 100644 index 0000000..ea8bf79 --- /dev/null +++ b/ucspi-tcp-0.88/finger@.sh @@ -0,0 +1,4 @@ +echo "${2-}" | HOME/bin/tcpclient -RHl0 -- "${1-0}" 79 sh -c ' + HOME/bin/addcr >&7 + exec HOME/bin/delcr <&6 +' | cat -v diff --git a/ucspi-tcp-0.88/fixcrio.c b/ucspi-tcp-0.88/fixcrio.c new file mode 100644 index 0000000..dbd4fa4 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/fmt.h b/ucspi-tcp-0.88/fmt.h new file mode 100644 index 0000000..6fd8fef --- /dev/null +++ b/ucspi-tcp-0.88/fmt.h @@ -0,0 +1,25 @@ +#ifndef FMT_H +#define FMT_H + +#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(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(char *,int); +extern unsigned int fmt_minus(char *,int); +extern unsigned int fmt_0x(char *,int); + +extern unsigned int fmt_str(char *,char *); +extern unsigned int fmt_strn(char *,char *,unsigned int); + +#endif diff --git a/ucspi-tcp-0.88/fmt_ulong.c b/ucspi-tcp-0.88/fmt_ulong.c new file mode 100644 index 0000000..db48bfd --- /dev/null +++ b/ucspi-tcp-0.88/fmt_ulong.c @@ -0,0 +1,13 @@ +#include "fmt.h" + +unsigned int fmt_ulong(register char *s,register unsigned long u) +{ + register unsigned int len; register unsigned long q; + len = 1; q = u; + while (q > 9) { ++len; q /= 10; } + if (s) { + s += len; + do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0 */ + } + return len; +} diff --git a/ucspi-tcp-0.88/fork.h1 b/ucspi-tcp-0.88/fork.h1 new file mode 100644 index 0000000..ddd589d --- /dev/null +++ b/ucspi-tcp-0.88/fork.h1 @@ -0,0 +1,9 @@ +#ifndef FORK_H +#define FORK_H + +/* sysdep: -vfork */ + +extern int fork(); +#define vfork fork + +#endif diff --git a/ucspi-tcp-0.88/fork.h2 b/ucspi-tcp-0.88/fork.h2 new file mode 100644 index 0000000..7c1b0b9 --- /dev/null +++ b/ucspi-tcp-0.88/fork.h2 @@ -0,0 +1,9 @@ +#ifndef FORK_H +#define FORK_H + +/* sysdep: +vfork */ + +extern int fork(); +extern int vfork(); + +#endif diff --git a/ucspi-tcp-0.88/gen_alloc.h b/ucspi-tcp-0.88/gen_alloc.h new file mode 100644 index 0000000..b94a956 --- /dev/null +++ b/ucspi-tcp-0.88/gen_alloc.h @@ -0,0 +1,7 @@ +#ifndef GEN_ALLOC_H +#define GEN_ALLOC_H + +#define GEN_ALLOC_typedef(ta,type,field,len,a) \ + typedef struct ta { type *field; unsigned int len; unsigned int a; } ta; + +#endif diff --git a/ucspi-tcp-0.88/gen_allocdefs.h b/ucspi-tcp-0.88/gen_allocdefs.h new file mode 100644 index 0000000..d025b27 --- /dev/null +++ b/ucspi-tcp-0.88/gen_allocdefs.h @@ -0,0 +1,34 @@ +#ifndef GEN_ALLOC_DEFS_H +#define GEN_ALLOC_DEFS_H + +#define GEN_ALLOC_ready(ta,type,field,len,a,i,n,x,base,ta_ready) \ +int ta_ready(register ta *x,register unsigned int n) \ +{ register unsigned int i; \ + if (x->field) { \ + i = x->a; \ + if (n > i) { \ + x->a = base + n + (n >> 3); \ + if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \ + x->a = i; return 0; } \ + return 1; } \ + x->len = 0; \ + 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(register ta *x,register unsigned int n) \ +{ register unsigned int i; \ + if (x->field) { \ + i = x->a; n += x->len; \ + if (n > i) { \ + x->a = base + n + (n >> 3); \ + if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \ + x->a = i; return 0; } \ + return 1; } \ + x->len = 0; \ + 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(register ta *x,register type *i) \ +{ if (!ta_rplus(x,1)) return 0; x->field[x->len++] = *i; return 1; } + +#endif diff --git a/ucspi-tcp-0.88/getln.c b/ucspi-tcp-0.88/getln.c new file mode 100644 index 0000000..489621c --- /dev/null +++ b/ucspi-tcp-0.88/getln.c @@ -0,0 +1,14 @@ +#include "byte.h" +#include "getln.h" + +int getln(buffer *ss,stralloc *sa,int *match,int sep) +{ + char *cont; + unsigned int clen; + + if (getln2(ss,sa,&cont,&clen,sep) == -1) return -1; + if (!clen) { *match = 0; return 0; } + if (!stralloc_catb(sa,cont,clen)) return -1; + *match = 1; + return 0; +} diff --git a/ucspi-tcp-0.88/getln.h b/ucspi-tcp-0.88/getln.h new file mode 100644 index 0000000..3cae45f --- /dev/null +++ b/ucspi-tcp-0.88/getln.h @@ -0,0 +1,10 @@ +#ifndef GETLN_H +#define GETLN_H + +#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/ucspi-tcp-0.88/getln2.c b/ucspi-tcp-0.88/getln2.c new file mode 100644 index 0000000..bf622a4 --- /dev/null +++ b/ucspi-tcp-0.88/getln2.c @@ -0,0 +1,24 @@ +#include "byte.h" +#include "getln.h" + +int getln2(buffer *ss,stralloc *sa,char **cont,unsigned int *clen,int sep) +{ + register char *x; + register unsigned int i; + int n; + + if (!stralloc_ready(sa,0)) return -1; + sa->len = 0; + + for (;;) { + n = buffer_feed(ss); + if (n < 0) return -1; + if (n == 0) { *clen = 0; return 0; } + x = buffer_PEEK(ss); + i = byte_chr(x,n,sep); + 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 + buffer_get(ss,sa->s + i,n); + } +} diff --git a/ucspi-tcp-0.88/hassgact.h1 b/ucspi-tcp-0.88/hassgact.h1 new file mode 100644 index 0000000..03c7a9f --- /dev/null +++ b/ucspi-tcp-0.88/hassgact.h1 @@ -0,0 +1 @@ +/* sysdep: -sigaction */ diff --git a/ucspi-tcp-0.88/hassgact.h2 b/ucspi-tcp-0.88/hassgact.h2 new file mode 100644 index 0000000..594d486 --- /dev/null +++ b/ucspi-tcp-0.88/hassgact.h2 @@ -0,0 +1,2 @@ +/* sysdep: +sigaction */ +#define HASSIGACTION 1 diff --git a/ucspi-tcp-0.88/hassgprm.h1 b/ucspi-tcp-0.88/hassgprm.h1 new file mode 100644 index 0000000..4c05fd1 --- /dev/null +++ b/ucspi-tcp-0.88/hassgprm.h1 @@ -0,0 +1 @@ +/* sysdep: -sigprocmask */ diff --git a/ucspi-tcp-0.88/hassgprm.h2 b/ucspi-tcp-0.88/hassgprm.h2 new file mode 100644 index 0000000..d959bc7 --- /dev/null +++ b/ucspi-tcp-0.88/hassgprm.h2 @@ -0,0 +1,2 @@ +/* sysdep: +sigprocmask */ +#define HASSIGPROCMASK 1 diff --git a/ucspi-tcp-0.88/hasshsgr.h1 b/ucspi-tcp-0.88/hasshsgr.h1 new file mode 100644 index 0000000..d11c988 --- /dev/null +++ b/ucspi-tcp-0.88/hasshsgr.h1 @@ -0,0 +1 @@ +/* sysdep: -shortsetgroups */ diff --git a/ucspi-tcp-0.88/hasshsgr.h2 b/ucspi-tcp-0.88/hasshsgr.h2 new file mode 100644 index 0000000..db6a830 --- /dev/null +++ b/ucspi-tcp-0.88/hasshsgr.h2 @@ -0,0 +1,2 @@ +/* sysdep: +shortsetgroups */ +#define HASSHORTSETGROUPS 1 diff --git a/ucspi-tcp-0.88/haswaitp.h1 b/ucspi-tcp-0.88/haswaitp.h1 new file mode 100644 index 0000000..469a7ad --- /dev/null +++ b/ucspi-tcp-0.88/haswaitp.h1 @@ -0,0 +1 @@ +/* sysdep: -waitpid */ diff --git a/ucspi-tcp-0.88/haswaitp.h2 b/ucspi-tcp-0.88/haswaitp.h2 new file mode 100644 index 0000000..a75823a --- /dev/null +++ b/ucspi-tcp-0.88/haswaitp.h2 @@ -0,0 +1,2 @@ +/* sysdep: +waitpid */ +#define HASWAITPID 1 diff --git a/ucspi-tcp-0.88/hier.c b/ucspi-tcp-0.88/hier.c new file mode 100644 index 0000000..5663ada --- /dev/null +++ b/ucspi-tcp-0.88/hier.c @@ -0,0 +1,25 @@ +#include "auto_home.h" + +void hier() +{ + h(auto_home,-1,-1,02755); + d(auto_home,"bin",-1,-1,02755); + + 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,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/ucspi-tcp-0.88/http@.sh b/ucspi-tcp-0.88/http@.sh new file mode 100644 index 0000000..039be03 --- /dev/null +++ b/ucspi-tcp-0.88/http@.sh @@ -0,0 +1,6 @@ +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/ucspi-tcp-0.88/install.c b/ucspi-tcp-0.88/install.c new file mode 100644 index 0000000..605fed3 --- /dev/null +++ b/ucspi-tcp-0.88/install.c @@ -0,0 +1,149 @@ +#include "buffer.h" +#include "strerr.h" +#include "error.h" +#include "open.h" +#include "readwrite.h" +#include "exit.h" + +extern void hier(); + +#define FATAL "install: fatal: " + +int fdsourcedir = -1; + +void h(home,uid,gid,mode) +char *home; +int uid; +int gid; +int mode; +{ + if (mkdir(home,0700) == -1) + if (errno != error_exist) + strerr_die4sys(111,FATAL,"unable to mkdir ",home,": "); + if (chown(home,uid,gid) == -1) + strerr_die4sys(111,FATAL,"unable to chown ",home,": "); + if (chmod(home,mode) == -1) + strerr_die4sys(111,FATAL,"unable to chmod ",home,": "); +} + +void d(home,subdir,uid,gid,mode) +char *home; +char *subdir; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (mkdir(subdir,0700) == -1) + if (errno != error_exist) + strerr_die6sys(111,FATAL,"unable to mkdir ",home,"/",subdir,": "); + if (chown(subdir,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown ",home,"/",subdir,": "); + if (chmod(subdir,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",subdir,": "); +} + +char inbuf[BUFFER_INSIZE]; +char outbuf[BUFFER_OUTSIZE]; +buffer ssin; +buffer ssout; + +void c(home,subdir,file,uid,gid,mode) +char *home; +char *subdir; +char *file; +int uid; +int gid; +int mode; +{ + int fdin; + int fdout; + + if (fchdir(fdsourcedir) == -1) + strerr_die2sys(111,FATAL,"unable to switch back to source directory: "); + + fdin = open_read(file); + if (fdin == -1) + strerr_die4sys(111,FATAL,"unable to read ",file,": "); + buffer_init(&ssin,read,fdin,inbuf,sizeof inbuf); + + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (chdir(subdir) == -1) + strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); + + fdout = open_trunc(file); + if (fdout == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + buffer_init(&ssout,write,fdout,outbuf,sizeof outbuf); + + switch(buffer_copy(&ssout,&ssin)) { + case -2: + strerr_die4sys(111,FATAL,"unable to read ",file,": "); + case -3: + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + } + + close(fdin); + 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,": "); + if (close(fdout) == -1) /* NFS silliness */ + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + + if (chown(file,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown .../",subdir,"/",file,": "); + if (chmod(file,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": "); +} + +void z(home,subdir,file,len,uid,gid,mode) +char *home; +char *subdir; +char *file; +int len; +int uid; +int gid; +int mode; +{ + int fdout; + + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (chdir(subdir) == -1) + strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); + + fdout = open_trunc(file); + if (fdout == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + buffer_init(&ssout,write,fdout,outbuf,sizeof outbuf); + + while (len-- > 0) + if (buffer_put(&ssout,"",1) == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + + 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,": "); + if (close(fdout) == -1) /* NFS silliness */ + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + + if (chown(file,uid,gid) == -1) + strerr_die6sys(111,FATAL,"unable to chown .../",subdir,"/",file,": "); + if (chmod(file,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": "); +} + +main() +{ + fdsourcedir = open_read("."); + if (fdsourcedir == -1) + strerr_die2sys(111,FATAL,"unable to open current directory: "); + + umask(077); + hier(); + _exit(0); +} diff --git a/ucspi-tcp-0.88/instcheck.c b/ucspi-tcp-0.88/instcheck.c new file mode 100644 index 0000000..c945e67 --- /dev/null +++ b/ucspi-tcp-0.88/instcheck.c @@ -0,0 +1,108 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include "strerr.h" +#include "error.h" +#include "readwrite.h" +#include "exit.h" + +extern void hier(); + +#define FATAL "instcheck: fatal: " +#define WARNING "instcheck: warning: " + +void perm(prefix1,prefix2,prefix3,file,type,uid,gid,mode) +char *prefix1; +char *prefix2; +char *prefix3; +char *file; +int type; +int uid; +int gid; +int mode; +{ + struct stat st; + + if (stat(file,&st) == -1) { + if (errno == error_noent) + strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," does not exist",0); + else + strerr_warn4(WARNING,"unable to stat .../",file,": ",&strerr_sys); + return; + } + + if ((uid != -1) && (st.st_uid != uid)) + strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong owner",0); + if ((gid != -1) && (st.st_gid != gid)) + strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong group",0); + if ((st.st_mode & 07777) != mode) + strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong permissions",0); + if ((st.st_mode & S_IFMT) != type) + strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong type",0); +} + +void h(home,uid,gid,mode) +char *home; +int uid; +int gid; +int mode; +{ + perm("","","",home,S_IFDIR,uid,gid,mode); +} + +void d(home,subdir,uid,gid,mode) +char *home; +char *subdir; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + perm("",home,"/",subdir,S_IFDIR,uid,gid,mode); +} + +void p(home,fifo,uid,gid,mode) +char *home; +char *fifo; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + perm("",home,"/",fifo,S_IFIFO,uid,gid,mode); +} + +void c(home,subdir,file,uid,gid,mode) +char *home; +char *subdir; +char *file; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (chdir(subdir) == -1) + strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); + perm(".../",subdir,"/",file,S_IFREG,uid,gid,mode); +} + +void z(home,file,len,uid,gid,mode) +char *home; +char *file; +int len; +int uid; +int gid; +int mode; +{ + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + perm("",home,"/",file,S_IFREG,uid,gid,mode); +} + +main() +{ + hier(); + _exit(0); +} diff --git a/ucspi-tcp-0.88/iopause.c b/ucspi-tcp-0.88/iopause.c new file mode 100644 index 0000000..b8034de --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/iopause.h1 b/ucspi-tcp-0.88/iopause.h1 new file mode 100644 index 0000000..dae0a33 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/iopause.h2 b/ucspi-tcp-0.88/iopause.h2 new file mode 100644 index 0000000..2cf5cf8 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/ip4.h b/ucspi-tcp-0.88/ip4.h new file mode 100644 index 0000000..64a7c1e --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/ip4_fmt.c b/ucspi-tcp-0.88/ip4_fmt.c new file mode 100644 index 0000000..c605634 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/ip4_scan.c b/ucspi-tcp-0.88/ip4_scan.c new file mode 100644 index 0000000..7a61371 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/mconnect-io.c b/ucspi-tcp-0.88/mconnect-io.c new file mode 100644 index 0000000..5cd4ada --- /dev/null +++ b/ucspi-tcp-0.88/mconnect-io.c @@ -0,0 +1,53 @@ +#include "sig.h" +#include "wait.h" +#include "fork.h" +#include "buffer.h" +#include "strerr.h" +#include "readwrite.h" +#include "exit.h" + +char outbuf[512]; +buffer bout; + +char inbuf[512]; +buffer bin; + +int myread(int fd,char *buf,int len) +{ + buffer_flush(&bout); + return read(fd,buf,len); +} + +main() +{ + int pid; + int wstat; + char ch; + + sig_ignore(sig_pipe); + + pid = fork(); + if (pid == -1) strerr_die2sys(111,"mconnect-io: fatal: ","unable to fork: "); + + if (!pid) { + buffer_init(&bin,myread,0,inbuf,sizeof inbuf); + buffer_init(&bout,write,7,outbuf,sizeof outbuf); + + while (buffer_get(&bin,&ch,1) == 1) { + if (ch == '\n') buffer_put(&bout,"\r",1); + buffer_put(&bout,&ch,1); + } + _exit(0); + } + + buffer_init(&bin,myread,6,inbuf,sizeof inbuf); + buffer_init(&bout,write,1,outbuf,sizeof outbuf); + + while (buffer_get(&bin,&ch,1) == 1) + buffer_put(&bout,&ch,1); + + kill(pid,sig_term); + wait_pid(&wstat,pid); + + _exit(0); +} diff --git a/ucspi-tcp-0.88/mconnect.sh b/ucspi-tcp-0.88/mconnect.sh new file mode 100644 index 0000000..9629b90 --- /dev/null +++ b/ucspi-tcp-0.88/mconnect.sh @@ -0,0 +1 @@ +exec HOME/bin/tcpclient -RHl0 -- "${1-0}" "${2-25}" HOME/bin/mconnect-io diff --git a/ucspi-tcp-0.88/ndelay.h b/ucspi-tcp-0.88/ndelay.h new file mode 100644 index 0000000..60b788c --- /dev/null +++ b/ucspi-tcp-0.88/ndelay.h @@ -0,0 +1,7 @@ +#ifndef NDELAY_H +#define NDELAY_H + +extern int ndelay_on(int); +extern int ndelay_off(int); + +#endif diff --git a/ucspi-tcp-0.88/ndelay_off.c b/ucspi-tcp-0.88/ndelay_off.c new file mode 100644 index 0000000..9daa8cd --- /dev/null +++ b/ucspi-tcp-0.88/ndelay_off.c @@ -0,0 +1,12 @@ +#include <sys/types.h> +#include <fcntl.h> +#include "ndelay.h" + +#ifndef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif + +int ndelay_off(int fd) +{ + return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) & ~O_NONBLOCK); +} diff --git a/ucspi-tcp-0.88/ndelay_on.c b/ucspi-tcp-0.88/ndelay_on.c new file mode 100644 index 0000000..eccd8c8 --- /dev/null +++ b/ucspi-tcp-0.88/ndelay_on.c @@ -0,0 +1,12 @@ +#include <sys/types.h> +#include <fcntl.h> +#include "ndelay.h" + +#ifndef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif + +int ndelay_on(int fd) +{ + return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) | O_NONBLOCK); +} diff --git a/ucspi-tcp-0.88/open.h b/ucspi-tcp-0.88/open.h new file mode 100644 index 0000000..2963fa7 --- /dev/null +++ b/ucspi-tcp-0.88/open.h @@ -0,0 +1,10 @@ +#ifndef OPEN_H +#define OPEN_H + +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/ucspi-tcp-0.88/open_read.c b/ucspi-tcp-0.88/open_read.c new file mode 100644 index 0000000..7f5ec8b --- /dev/null +++ b/ucspi-tcp-0.88/open_read.c @@ -0,0 +1,6 @@ +#include <sys/types.h> +#include <fcntl.h> +#include "open.h" + +int open_read(char *fn) +{ return open(fn,O_RDONLY | O_NDELAY); } diff --git a/ucspi-tcp-0.88/open_trunc.c b/ucspi-tcp-0.88/open_trunc.c new file mode 100644 index 0000000..77b99ef --- /dev/null +++ b/ucspi-tcp-0.88/open_trunc.c @@ -0,0 +1,6 @@ +#include <sys/types.h> +#include <fcntl.h> +#include "open.h" + +int open_trunc(char *fn) +{ return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644); } diff --git a/ucspi-tcp-0.88/open_write.c b/ucspi-tcp-0.88/open_write.c new file mode 100644 index 0000000..531b8fe --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/openreadclose.c b/ucspi-tcp-0.88/openreadclose.c new file mode 100644 index 0000000..d1e2086 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/openreadclose.h b/ucspi-tcp-0.88/openreadclose.h new file mode 100644 index 0000000..99688f4 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/pathexec.h b/ucspi-tcp-0.88/pathexec.h new file mode 100644 index 0000000..6fcbb89 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/pathexec_env.c b/ucspi-tcp-0.88/pathexec_env.c new file mode 100644 index 0000000..48bba7e --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/pathexec_run.c b/ucspi-tcp-0.88/pathexec_run.c new file mode 100644 index 0000000..17837eb --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/prot.c b/ucspi-tcp-0.88/prot.c new file mode 100644 index 0000000..0a8a373 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/prot.h b/ucspi-tcp-0.88/prot.h new file mode 100644 index 0000000..7dd0503 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/rblsmtpd.c b/ucspi-tcp-0.88/rblsmtpd.c new file mode 100644 index 0000000..cc8ba2e --- /dev/null +++ b/ucspi-tcp-0.88/rblsmtpd.c @@ -0,0 +1,198 @@ +#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 ] [ -R ] [ -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) +{ + if (decision) return; + if (!stralloc_copy(&tmp,&ip_reverse)) nomem(); + 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; + } + 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/ucspi-tcp-0.88/readclose.c b/ucspi-tcp-0.88/readclose.c new file mode 100644 index 0000000..4265c06 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/readclose.h b/ucspi-tcp-0.88/readclose.h new file mode 100644 index 0000000..49afd6c --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/readwrite.h b/ucspi-tcp-0.88/readwrite.h new file mode 100644 index 0000000..2a64968 --- /dev/null +++ b/ucspi-tcp-0.88/readwrite.h @@ -0,0 +1,7 @@ +#ifndef READWRITE_H +#define READWRITE_H + +extern int read(); +extern int write(); + +#endif diff --git a/ucspi-tcp-0.88/recordio.c b/ucspi-tcp-0.88/recordio.c new file mode 100644 index 0000000..a3ee03c --- /dev/null +++ b/ucspi-tcp-0.88/recordio.c @@ -0,0 +1,178 @@ +#include "sig.h" +#include "buffer.h" +#include "strerr.h" +#include "str.h" +#include "byte.h" +#include "readwrite.h" +#include "exit.h" +#include "fmt.h" +#include "iopause.h" +#include "pathexec.h" + +#define FATAL "recordio: fatal: " + +char pid[FMT_ULONG]; + +char recordbuf[512]; +buffer ssrecord = BUFFER_INIT(write,2,recordbuf,sizeof recordbuf); + +void record(char *buf,int len,char *direction) /* 1 <= len <= 256 */ +{ + int i; + + while (len) { + buffer_puts(&ssrecord,pid); + buffer_puts(&ssrecord,direction); + + i = byte_chr(buf,len,'\n'); + buffer_put(&ssrecord,buf,i); + + if (i == len) { + buffer_puts(&ssrecord,"+\n"); + buffer_flush(&ssrecord); + return; + } + + buffer_puts(&ssrecord," \n"); + buffer_flush(&ssrecord); + buf += i + 1; + len -= i + 1; + } +} + +int leftstatus = 0; +char leftbuf[256]; +int leftlen; +int leftpos; + +int rightstatus = 0; +char rightbuf[256]; +int rightlen; +int rightpos; + +void doit(int fdleft,int fdright) /* copy 0 -> fdleft, copy fdright -> 1 */ +{ + 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; + + 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,leftbuf,sizeof leftbuf); + if (r <= 0) { + leftstatus = -1; + close(fdleft); + buffer_puts(&ssrecord,pid); + buffer_puts(&ssrecord," < [EOF]\n"); + buffer_flush(&ssrecord); + } + else { + leftstatus = 1; leftpos = 0; leftlen = r; + record(leftbuf,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,rightbuf,sizeof rightbuf); + if (r <= 0) { + buffer_puts(&ssrecord,pid); + buffer_puts(&ssrecord," > [EOF]\n"); + buffer_flush(&ssrecord); + break; + } + rightstatus = 1; rightpos = 0; rightlen = r; + record(rightbuf,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]; + + pid[fmt_ulong(pid,getpid())] = 0; + + if (argc < 2) + strerr_die1x(100,"recordio: usage: recordio 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/ucspi-tcp-0.88/remoteinfo.c b/ucspi-tcp-0.88/remoteinfo.c new file mode 100644 index 0000000..6c437c0 --- /dev/null +++ b/ucspi-tcp-0.88/remoteinfo.c @@ -0,0 +1,98 @@ +#include "fmt.h" +#include "buffer.h" +#include "socket.h" +#include "error.h" +#include "iopause.h" +#include "timeoutconn.h" +#include "remoteinfo.h" + +static struct taia now; +static struct taia deadline; + +static int mywrite(int fd,char *buf,int 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(int fd,char *buf,int 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); +} + +static int doit(stralloc *out,int s,char ipremote[4],uint16 portremote,char iplocal[4],uint16 portlocal,unsigned int timeout) +{ + buffer b; + char bspace[128]; + char strnum[FMT_ULONG]; + int numcolons; + char ch; + + 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 (buffer_get(&b,&ch,1) != 1) return -1; + if ((ch == ' ') || (ch == '\t') || (ch == '\r')) continue; + 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; + } + } +} + +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 r; +} diff --git a/ucspi-tcp-0.88/remoteinfo.h b/ucspi-tcp-0.88/remoteinfo.h new file mode 100644 index 0000000..2ca779d --- /dev/null +++ b/ucspi-tcp-0.88/remoteinfo.h @@ -0,0 +1,9 @@ +#ifndef REMOTEINFO_H +#define REMOTEINFO_H + +#include "stralloc.h" +#include "uint16.h" + +extern int remoteinfo(stralloc *,char *,uint16,char *,uint16,unsigned int); + +#endif diff --git a/ucspi-tcp-0.88/rts.exp b/ucspi-tcp-0.88/rts.exp new file mode 100644 index 0000000..242d7cf --- /dev/null +++ b/ucspi-tcp-0.88/rts.exp @@ -0,0 +1,435 @@ +--- tcpclient prints usage message without enough arguments +tcpclient: usage: tcpclient [ -hHrRdDqQv ] [ -i localip ] [ -p localport ] [ -T timeoutconn ] [ -l localname ] [ -t timeoutinfo ] host port program +100 +--- tcpclient prints error message with unknown port name +tcpclient: fatal: unable to figure out port number for nonexistentport +111 +--- tcpclient prints error message when connection fails +tcpclient: unable to connect to 127.0.0.1 port 16: connection refused +111 +--- tcpclient -q does not print error message when connection fails +111 +--- tcpclient understands empty host name as synonym for 0 +tcpclient: unable to connect to 127.0.0.1 port 16: connection refused +111 +--- tcpclient understands unbracketed IP address +tcpclient: unable to connect to 127.0.0.1 port 16: connection refused +111 +--- tcpclient understands bracketed IP address +tcpclient: unable to connect to 127.0.0.1 port 16: connection refused +111 +--- tcpclient prints error message with unknown host name +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 [ -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: 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 +bannerPROTO=TCP +TCPLOCALHOST=Local +TCPLOCALIP=127.0.0.1 +TCPLOCALPORT=50016 +TCPREMOTEHOST=localhost +TCPREMOTEIP=127.0.0.1 +TCPREMOTEPORT=50017 +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=50019 +TCPREMOTEHOST=unset +TCPREMOTEIP=127.0.0.1 +TCPREMOTEPORT=50016 +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 +ok +0 +--- tcpserver prints error message with used port +tcpserver: fatal: unable to bind: address already used +111 +--- 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 +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 +100 +--- tcprules prints error message if it cannot create tmp +tcprules: fatal: unable to create /dev/nonexistent/tmp: file does not exist +111 +--- tcprules prints error message if it cannot move tmp to cdb +tcprules: fatal: unable to move test.tmp to /dev/nonexistent/cdb: file does not exist +111 +--- tcprules creates a cdb file +0 +--- tcprulescheck sees deny +rule 1.2.3.4: +deny connection +0 +--- tcprulescheck does not apply deny to another host +default: +allow connection +0 +--- tcprules replaces a cdb file +0 +--- tcprulescheck finds rule with address and info +rule joe@127.0.0.1: +set environment variable which=first +allow connection +0 +--- tcprulescheck finds rule with address +rule 18.23.0.32: +set environment variable which=second +allow connection +0 +--- tcprulescheck finds one-dot wildcard +rule 127.: +set environment variable which=third +allow connection +0 +--- tcprulescheck finds zero-dot wildcard +rule : +set environment variable which=fourth +allow connection +0 +--- tcprules handles comments, address ranges, multiple variables +0 +rule 127.0.: +set environment variable which=first +set environment variable where=whatever +allow connection +rule 127.1.: +set environment variable which=first +set environment variable where=whatever +allow connection +rule 127.2.: +set environment variable which=first +set environment variable where=whatever +allow connection +rule 127.3.: +set environment variable which=first +set environment variable where=whatever +allow connection +rule 127.4.: +set environment variable which=first +set environment variable where=whatever +allow connection +rule 127.5.: +set environment variable which=first +set environment variable where=whatever +allow connection +default: +allow connection +default: +allow connection +default: +allow connection +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 +test0 +--- addcr adds CR after the first line +test^M +0 +--- addcr adds CR after the second line +test^M +test2^M +0 +--- addcr handles nulls +t^@st^M +0 +--- delcr leaves an empty file alone +0 +--- delcr leaves a non-CR line alone +test +0 +--- delcr removes CR if a line has it +test +0 +--- delcr converts CR CR LF to CR LF +test^M +0 +--- 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 +--- fixcrio works +^M +hi^M +there^M +bye^M +--- recordio works +... < test $ +... > test $ +... < [EOF]$ +... > [EOF]$ +--- recordio handles multiple-line packets +... < test $ +... < test2 $ +... > test $ +... > test2 $ +... < [EOF]$ +... > [EOF]$ +--- recordio handles partial final lines +... < test+$ +... > test+$ +... < [EOF]$ +... > [EOF]$ +--- argv0 works +zero +0 +--- 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/ucspi-tcp-0.88/rts.sh b/ucspi-tcp-0.88/rts.sh new file mode 100644 index 0000000..c71e839 --- /dev/null +++ b/ucspi-tcp-0.88/rts.sh @@ -0,0 +1 @@ +env - PATH="`pwd`:$PATH" sh rts.tests 2>&1 | cat -v diff --git a/ucspi-tcp-0.88/rts.tests b/ucspi-tcp-0.88/rts.tests new file mode 100644 index 0000000..8c23929 --- /dev/null +++ b/ucspi-tcp-0.88/rts.tests @@ -0,0 +1,347 @@ +# 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 $? + +echo '--- tcpclient prints error message with unknown port name' +tcpclient 0 nonexistentport echo wrong; echo $? + +echo '--- tcpclient prints error message when connection fails' +tcpclient 0 016 echo wrong; echo $? + +echo '--- tcpclient -q does not print error message when connection fails' +tcpclient -q 0 016 echo wrong; echo $? + +echo '--- tcpclient understands empty host name as synonym for 0' +tcpclient '' 016 echo wrong; echo $? + +echo '--- tcpclient understands unbracketed IP address' +tcpclient '127.000.000.001' 016 echo wrong; echo $? + +echo '--- tcpclient understands bracketed IP address' +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 $? + +echo '--- tcpserver sets basic environment variables' +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 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' +tcpclient -v -R -H -l Local 0 50016 echo ok +echo $? + +echo '--- tcpserver prints error message with used port' +tcpserver -R -H -l Local 127.0.0.1 50016 echo wrong +echo $? + +echo '--- tcpcat works' +tcpcat 0 50016 | grep -v TCPREMOTEPORT +echo $? + +echo '--- mconnect works' +mconnect 0 50016 </dev/null | grep -v TCPREMOTEPORT +echo $? + +echo '--- tcprules prints usage message without enough arguments' +tcprules test.cdb; echo $? + +echo '--- tcprules prints error message if it cannot create tmp' +echo 1.2.3.4:deny | tcprules test.cdb /dev/nonexistent/tmp; echo $? + +echo '--- tcprules prints error message if it cannot move tmp to cdb' +echo 1.2.3.4:deny | tcprules /dev/nonexistent/cdb test.tmp; echo $? + +echo '--- tcprules creates a cdb file' +echo 1.2.3.4:deny | tcprules test.cdb test.tmp; echo $? + +echo '--- tcprulescheck sees deny' +env TCPREMOTEIP=1.2.3.4 tcprulescheck test.cdb; echo $? + +echo '--- tcprulescheck does not apply deny to another host' +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/ +18.23.0.32:allow,which="second" +127.:allow,which=+third+ +:allow,which==fourth=' | tcprules test.cdb test.tmp; echo $? + +echo '--- tcprulescheck finds rule with address and info' +env TCPREMOTEIP=127.0.0.1 TCPREMOTEINFO=joe tcprulescheck test.cdb; echo $? + +echo '--- tcprulescheck finds rule with address' +env TCPREMOTEIP=18.23.0.32 TCPREMOTEINFO=joe tcprulescheck test.cdb; echo $? + +echo '--- tcprulescheck finds one-dot wildcard' +env TCPREMOTEIP=127.0.0.1 TCPREMOTEINFO=bill tcprulescheck test.cdb; echo $? + +echo '--- tcprulescheck finds zero-dot wildcard' +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 $? +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 '' | tr -d '\012' | addcr; echo $? + +echo '--- addcr leaves a partial final line alone' +echo test | tr -d '\012' | addcr; echo $? + +echo '--- addcr adds CR after the first line' +echo test | addcr; echo $? + +echo '--- addcr adds CR after the second line' +( echo test; echo test2 ) | addcr; echo $? + +echo '--- addcr handles nulls' +echo test | tr e '\0' | addcr; echo $? + +echo '--- delcr leaves an empty file alone' +echo '' | tr -d '\012' | delcr; echo $? + +echo '--- delcr leaves a non-CR line alone' +echo test | delcr; echo $? + +echo '--- delcr removes CR if a line has it' +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 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 test | tr -d '\012' | delcr; echo $? + +echo '--- delcr handles nulls' +echo test | tr e '\0' | delcr; 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 \ +| sed 's/^[0-9]*/.../' | sed 's/$/$/' + +echo '--- recordio handles multiple-line packets' +( echo 'test +test2'; sleep 1 ) | recordio cat 2>&1 >/dev/null \ +| sed 's/^[0-9]*/.../' | sed 's/$/$/' + +echo '--- recordio handles partial final lines' +( echo test | tr -d '\012'; sleep 1 ) | recordio cat 2>&1 >/dev/null \ +| sed 's/^[0-9]*/.../' | sed 's/$/$/' + +echo '--- argv0 works' +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/ucspi-tcp-0.88/rules.c b/ucspi-tcp-0.88/rules.c new file mode 100644 index 0000000..1840360 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/rules.h b/ucspi-tcp-0.88/rules.h new file mode 100644 index 0000000..15d9b90 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/scan.h b/ucspi-tcp-0.88/scan.h new file mode 100644 index 0000000..758138c --- /dev/null +++ b/ucspi-tcp-0.88/scan.h @@ -0,0 +1,28 @@ +#ifndef SCAN_H +#define SCAN_H + +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(char *,int *); +extern unsigned int scan_0x(char *,unsigned int *); + +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(char *,char *,unsigned int); +extern unsigned int scan_memcmp(char *,char *,unsigned int); + +extern unsigned int scan_long(char *,long *); +extern unsigned int scan_8long(char *,unsigned long *); + +#endif diff --git a/ucspi-tcp-0.88/scan_ulong.c b/ucspi-tcp-0.88/scan_ulong.c new file mode 100644 index 0000000..69bc3d4 --- /dev/null +++ b/ucspi-tcp-0.88/scan_ulong.c @@ -0,0 +1,14 @@ +#include "scan.h" + +unsigned int scan_ulong(register char *s,register unsigned long *u) +{ + register unsigned int pos = 0; + register unsigned long result = 0; + register unsigned long c; + while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 10) { + result = result * 10 + c; + ++pos; + } + *u = result; + return pos; +} diff --git a/ucspi-tcp-0.88/seek.h b/ucspi-tcp-0.88/seek.h new file mode 100644 index 0000000..06aad97 --- /dev/null +++ b/ucspi-tcp-0.88/seek.h @@ -0,0 +1,15 @@ +#ifndef SEEK_H +#define SEEK_H + +typedef unsigned long seek_pos; + +extern seek_pos seek_cur(int); + +extern int seek_set(int,seek_pos); +extern int seek_end(int); + +extern int seek_trunc(int,seek_pos); + +#define seek_begin(fd) (seek_set((fd),(seek_pos) 0)) + +#endif diff --git a/ucspi-tcp-0.88/seek_set.c b/ucspi-tcp-0.88/seek_set.c new file mode 100644 index 0000000..d08d4f3 --- /dev/null +++ b/ucspi-tcp-0.88/seek_set.c @@ -0,0 +1,7 @@ +#include <sys/types.h> +#include "seek.h" + +#define SET 0 /* sigh */ + +int seek_set(int fd,seek_pos pos) +{ if (lseek(fd,(off_t) pos,SET) == -1) return -1; return 0; } diff --git a/ucspi-tcp-0.88/select.h1 b/ucspi-tcp-0.88/select.h1 new file mode 100644 index 0000000..fe725b6 --- /dev/null +++ b/ucspi-tcp-0.88/select.h1 @@ -0,0 +1,10 @@ +#ifndef SELECT_H +#define SELECT_H + +/* sysdep: -sysselect */ + +#include <sys/types.h> +#include <sys/time.h> +extern int select(); + +#endif diff --git a/ucspi-tcp-0.88/select.h2 b/ucspi-tcp-0.88/select.h2 new file mode 100644 index 0000000..2bc2044 --- /dev/null +++ b/ucspi-tcp-0.88/select.h2 @@ -0,0 +1,11 @@ +#ifndef SELECT_H +#define SELECT_H + +/* sysdep: +sysselect */ + +#include <sys/types.h> +#include <sys/time.h> +#include <sys/select.h> +extern int select(); + +#endif diff --git a/ucspi-tcp-0.88/sgetopt.c b/ucspi-tcp-0.88/sgetopt.c new file mode 100644 index 0000000..bdd0f14 --- /dev/null +++ b/ucspi-tcp-0.88/sgetopt.c @@ -0,0 +1,51 @@ +/* sgetopt.c, sgetopt.h: (yet another) improved getopt clone, outer layer +D. J. Bernstein, djb@pobox.com. +Depends on subgetopt.h, buffer.h. +No system requirements. +19991219: Switched to buffer.h. +19970208: Cleanups. +931201: Baseline. +No known patent problems. + +Documentation in sgetopt.3. +*/ + +#include "buffer.h" +#define SGETOPTNOSHORT +#include "sgetopt.h" +#define SUBGETOPTNOSHORT +#include "subgetopt.h" + +#define getopt sgetoptmine +#define optind subgetoptind +#define opterr sgetopterr +#define optproblem subgetoptproblem +#define optprogname sgetoptprogname + +int opterr = 1; +char *optprogname = 0; + +int getopt(int argc,char **argv,char *opts) +{ + int c; + char *s; + + if (!optprogname) { + optprogname = *argv; + if (!optprogname) optprogname = ""; + for (s = optprogname;*s;++s) if (*s == '/') optprogname = s + 1; + } + c = subgetopt(argc,argv,opts); + if (opterr) + if (c == '?') { + char chp[2]; chp[0] = optproblem; chp[1] = '\n'; + buffer_puts(buffer_2,optprogname); + if (argv[optind] && (optind < argc)) + buffer_puts(buffer_2,": illegal option -- "); + else + buffer_puts(buffer_2,": option requires an argument -- "); + buffer_put(buffer_2,chp,2); + buffer_flush(buffer_2); + } + return c; +} diff --git a/ucspi-tcp-0.88/sgetopt.h b/ucspi-tcp-0.88/sgetopt.h new file mode 100644 index 0000000..739203c --- /dev/null +++ b/ucspi-tcp-0.88/sgetopt.h @@ -0,0 +1,21 @@ +#ifndef SGETOPT_H +#define SGETOPT_H + +#ifndef SGETOPTNOSHORT +#define getopt sgetoptmine +#define optarg subgetoptarg +#define optind subgetoptind +#define optpos subgetoptpos +#define opterr sgetopterr +#define optproblem subgetoptproblem +#define optprogname sgetoptprogname +#define opteof subgetoptdone +#endif + +#include "subgetopt.h" + +extern int sgetoptmine(int,char **,char *); +extern int sgetopterr; +extern char *sgetoptprogname; + +#endif diff --git a/ucspi-tcp-0.88/sig.c b/ucspi-tcp-0.88/sig.c new file mode 100644 index 0000000..0368bcc --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/sig.h b/ucspi-tcp-0.88/sig.h new file mode 100644 index 0000000..bc522e4 --- /dev/null +++ b/ucspi-tcp-0.88/sig.h @@ -0,0 +1,25 @@ +#ifndef SIG_H +#define SIG_H + +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/ucspi-tcp-0.88/sig_block.c b/ucspi-tcp-0.88/sig_block.c new file mode 100644 index 0000000..57be036 --- /dev/null +++ b/ucspi-tcp-0.88/sig_block.c @@ -0,0 +1,38 @@ +#include <signal.h> +#include "sig.h" +#include "hassgprm.h" + +void sig_block(int sig) +{ +#ifdef HASSIGPROCMASK + sigset_t ss; + sigemptyset(&ss); + sigaddset(&ss,sig); + sigprocmask(SIG_BLOCK,&ss,(sigset_t *) 0); +#else + sigblock(1 << (sig - 1)); +#endif +} + +void sig_unblock(int sig) +{ +#ifdef HASSIGPROCMASK + sigset_t ss; + sigemptyset(&ss); + sigaddset(&ss,sig); + sigprocmask(SIG_UNBLOCK,&ss,(sigset_t *) 0); +#else + sigsetmask(sigsetmask(~0) & ~(1 << (sig - 1))); +#endif +} + +void sig_blocknone(void) +{ +#ifdef HASSIGPROCMASK + sigset_t ss; + sigemptyset(&ss); + sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0); +#else + sigsetmask(0); +#endif +} diff --git a/ucspi-tcp-0.88/sig_catch.c b/ucspi-tcp-0.88/sig_catch.c new file mode 100644 index 0000000..bdb2bfb --- /dev/null +++ b/ucspi-tcp-0.88/sig_catch.c @@ -0,0 +1,16 @@ +#include <signal.h> +#include "sig.h" +#include "hassgact.h" + +void sig_catch(int sig,void (*f)()) +{ +#ifdef HASSIGACTION + struct sigaction sa; + sa.sa_handler = f; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(sig,&sa,(struct sigaction *) 0); +#else + signal(sig,f); /* won't work under System V, even nowadays---dorks */ +#endif +} diff --git a/ucspi-tcp-0.88/sig_pause.c b/ucspi-tcp-0.88/sig_pause.c new file mode 100644 index 0000000..3dcc7b6 --- /dev/null +++ b/ucspi-tcp-0.88/sig_pause.c @@ -0,0 +1,14 @@ +#include <signal.h> +#include "sig.h" +#include "hassgprm.h" + +void sig_pause(void) +{ +#ifdef HASSIGPROCMASK + sigset_t ss; + sigemptyset(&ss); + sigsuspend(&ss); +#else + sigpause(0); +#endif +} diff --git a/ucspi-tcp-0.88/socket.h b/ucspi-tcp-0.88/socket.h new file mode 100644 index 0000000..80fb260 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/socket_accept.c b/ucspi-tcp-0.88/socket_accept.c new file mode 100644 index 0000000..22c44d4 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/socket_bind.c b/ucspi-tcp-0.88/socket_bind.c new file mode 100644 index 0000000..20830a4 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/socket_conn.c b/ucspi-tcp-0.88/socket_conn.c new file mode 100644 index 0000000..35adac4 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/socket_delay.c b/ucspi-tcp-0.88/socket_delay.c new file mode 100644 index 0000000..0e8c860 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/socket_listen.c b/ucspi-tcp-0.88/socket_listen.c new file mode 100644 index 0000000..abdb483 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/socket_local.c b/ucspi-tcp-0.88/socket_local.c new file mode 100644 index 0000000..1473d91 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/socket_opts.c b/ucspi-tcp-0.88/socket_opts.c new file mode 100644 index 0000000..ce5d170 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/socket_remote.c b/ucspi-tcp-0.88/socket_remote.c new file mode 100644 index 0000000..d65d9f8 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/socket_tcp.c b/ucspi-tcp-0.88/socket_tcp.c new file mode 100644 index 0000000..aada07d --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/socket_udp.c b/ucspi-tcp-0.88/socket_udp.c new file mode 100644 index 0000000..bda4494 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/str.h b/ucspi-tcp-0.88/str.h new file mode 100644 index 0000000..ab4aedd --- /dev/null +++ b/ucspi-tcp-0.88/str.h @@ -0,0 +1,14 @@ +#ifndef STR_H +#define STR_H + +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))) + +#endif diff --git a/ucspi-tcp-0.88/str_chr.c b/ucspi-tcp-0.88/str_chr.c new file mode 100644 index 0000000..886d6b6 --- /dev/null +++ b/ucspi-tcp-0.88/str_chr.c @@ -0,0 +1,17 @@ +#include "str.h" + +unsigned int str_chr(register char *s,int c) +{ + register char ch; + register char *t; + + ch = c; + t = s; + for (;;) { + if (!*t) break; if (*t == ch) break; ++t; + if (!*t) break; if (*t == ch) break; ++t; + if (!*t) break; if (*t == ch) break; ++t; + if (!*t) break; if (*t == ch) break; ++t; + } + return t - s; +} diff --git a/ucspi-tcp-0.88/str_diff.c b/ucspi-tcp-0.88/str_diff.c new file mode 100644 index 0000000..037dcdf --- /dev/null +++ b/ucspi-tcp-0.88/str_diff.c @@ -0,0 +1,15 @@ +#include "str.h" + +int str_diff(register char *s,register char *t) +{ + register char x; + + for (;;) { + x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + 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/ucspi-tcp-0.88/str_len.c b/ucspi-tcp-0.88/str_len.c new file mode 100644 index 0000000..5bd3f62 --- /dev/null +++ b/ucspi-tcp-0.88/str_len.c @@ -0,0 +1,14 @@ +#include "str.h" + +unsigned int str_len(char *s) +{ + register char *t; + + t = s; + for (;;) { + if (!*t) return t - s; ++t; + if (!*t) return t - s; ++t; + if (!*t) return t - s; ++t; + if (!*t) return t - s; ++t; + } +} diff --git a/ucspi-tcp-0.88/str_start.c b/ucspi-tcp-0.88/str_start.c new file mode 100644 index 0000000..43430bb --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/stralloc.h b/ucspi-tcp-0.88/stralloc.h new file mode 100644 index 0000000..7866812 --- /dev/null +++ b/ucspi-tcp-0.88/stralloc.h @@ -0,0 +1,29 @@ +#ifndef STRALLOC_H +#define STRALLOC_H + +#include "gen_alloc.h" + +GEN_ALLOC_typedef(stralloc,char,s,len,a) + +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(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),(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/ucspi-tcp-0.88/stralloc_cat.c b/ucspi-tcp-0.88/stralloc_cat.c new file mode 100644 index 0000000..dd08548 --- /dev/null +++ b/ucspi-tcp-0.88/stralloc_cat.c @@ -0,0 +1,7 @@ +#include "byte.h" +#include "stralloc.h" + +int stralloc_cat(stralloc *sato,stralloc *safrom) +{ + return stralloc_catb(sato,safrom->s,safrom->len); +} diff --git a/ucspi-tcp-0.88/stralloc_catb.c b/ucspi-tcp-0.88/stralloc_catb.c new file mode 100644 index 0000000..b739bed --- /dev/null +++ b/ucspi-tcp-0.88/stralloc_catb.c @@ -0,0 +1,12 @@ +#include "stralloc.h" +#include "byte.h" + +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; + byte_copy(sa->s + sa->len,n,s); + sa->len += n; + sa->s[sa->len] = 'Z'; /* ``offensive programming'' */ + return 1; +} diff --git a/ucspi-tcp-0.88/stralloc_cats.c b/ucspi-tcp-0.88/stralloc_cats.c new file mode 100644 index 0000000..8b11e94 --- /dev/null +++ b/ucspi-tcp-0.88/stralloc_cats.c @@ -0,0 +1,8 @@ +#include "byte.h" +#include "str.h" +#include "stralloc.h" + +int stralloc_cats(stralloc *sa,char *s) +{ + return stralloc_catb(sa,s,str_len(s)); +} diff --git a/ucspi-tcp-0.88/stralloc_copy.c b/ucspi-tcp-0.88/stralloc_copy.c new file mode 100644 index 0000000..02f8c47 --- /dev/null +++ b/ucspi-tcp-0.88/stralloc_copy.c @@ -0,0 +1,7 @@ +#include "byte.h" +#include "stralloc.h" + +int stralloc_copy(stralloc *sato,stralloc *safrom) +{ + return stralloc_copyb(sato,safrom->s,safrom->len); +} diff --git a/ucspi-tcp-0.88/stralloc_eady.c b/ucspi-tcp-0.88/stralloc_eady.c new file mode 100644 index 0000000..3a31f4b --- /dev/null +++ b/ucspi-tcp-0.88/stralloc_eady.c @@ -0,0 +1,6 @@ +#include "alloc.h" +#include "stralloc.h" +#include "gen_allocdefs.h" + +GEN_ALLOC_ready(stralloc,char,s,len,a,i,n,x,30,stralloc_ready) +GEN_ALLOC_readyplus(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus) diff --git a/ucspi-tcp-0.88/stralloc_opyb.c b/ucspi-tcp-0.88/stralloc_opyb.c new file mode 100644 index 0000000..46b99fc --- /dev/null +++ b/ucspi-tcp-0.88/stralloc_opyb.c @@ -0,0 +1,11 @@ +#include "stralloc.h" +#include "byte.h" + +int stralloc_copyb(stralloc *sa,char *s,unsigned int n) +{ + if (!stralloc_ready(sa,n + 1)) return 0; + byte_copy(sa->s,n,s); + sa->len = n; + sa->s[n] = 'Z'; /* ``offensive programming'' */ + return 1; +} diff --git a/ucspi-tcp-0.88/stralloc_opys.c b/ucspi-tcp-0.88/stralloc_opys.c new file mode 100644 index 0000000..78594b0 --- /dev/null +++ b/ucspi-tcp-0.88/stralloc_opys.c @@ -0,0 +1,8 @@ +#include "byte.h" +#include "str.h" +#include "stralloc.h" + +int stralloc_copys(stralloc *sa,char *s) +{ + return stralloc_copyb(sa,s,str_len(s)); +} diff --git a/ucspi-tcp-0.88/stralloc_pend.c b/ucspi-tcp-0.88/stralloc_pend.c new file mode 100644 index 0000000..a3443b8 --- /dev/null +++ b/ucspi-tcp-0.88/stralloc_pend.c @@ -0,0 +1,5 @@ +#include "alloc.h" +#include "stralloc.h" +#include "gen_allocdefs.h" + +GEN_ALLOC_append(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus,stralloc_append) diff --git a/ucspi-tcp-0.88/strerr.h b/ucspi-tcp-0.88/strerr.h new file mode 100644 index 0000000..702f588 --- /dev/null +++ b/ucspi-tcp-0.88/strerr.h @@ -0,0 +1,78 @@ +#ifndef STRERR_H +#define STRERR_H + +struct strerr { + struct strerr *who; + char *x; + char *y; + char *z; +} ; + +extern struct strerr strerr_sys; +extern void strerr_sysinit(void); + +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; } + +#define STRERR_SYS(r,se,a) \ +{ se.who = &strerr_sys; se.x = a; se.y = 0; se.z = 0; return r; } +#define STRERR_SYS3(r,se,a,b,c) \ +{ 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),(se)) +#define strerr_warn5(x1,x2,x3,x4,x5,se) \ +strerr_warn((x1),(x2),(x3),(x4),(x5),0,(se)) +#define strerr_warn4(x1,x2,x3,x4,se) \ +strerr_warn((x1),(x2),(x3),(x4),0,0,(se)) +#define strerr_warn3(x1,x2,x3,se) \ +strerr_warn((x1),(x2),(x3),0,0,0,(se)) +#define strerr_warn2(x1,x2,se) \ +strerr_warn((x1),(x2),0,0,0,0,(se)) +#define strerr_warn1(x1,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),(se)) +#define strerr_die5(e,x1,x2,x3,x4,x5,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),0,0,(se)) +#define strerr_die3(e,x1,x2,x3,se) \ +strerr_die((e),(x1),(x2),(x3),0,0,0,(se)) +#define strerr_die2(e,x1,x2,se) \ +strerr_die((e),(x1),(x2),0,0,0,0,(se)) +#define strerr_die1(e,x1,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),0,&strerr_sys) +#define strerr_die4sys(e,x1,x2,x3,x4) \ +strerr_die((e),(x1),(x2),(x3),(x4),0,0,&strerr_sys) +#define strerr_die3sys(e,x1,x2,x3) \ +strerr_die((e),(x1),(x2),(x3),0,0,0,&strerr_sys) +#define strerr_die2sys(e,x1,x2) \ +strerr_die((e),(x1),(x2),0,0,0,0,&strerr_sys) +#define strerr_die1sys(e,x1) \ +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),0) +#define strerr_die5x(e,x1,x2,x3,x4,x5) \ +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),0,0,0) +#define strerr_die3x(e,x1,x2,x3) \ +strerr_die((e),(x1),(x2),(x3),0,0,0,0) +#define strerr_die2x(e,x1,x2) \ +strerr_die((e),(x1),(x2),0,0,0,0,0) +#define strerr_die1x(e,x1) \ +strerr_die((e),(x1),0,0,0,0,0,0) + +#endif diff --git a/ucspi-tcp-0.88/strerr_die.c b/ucspi-tcp-0.88/strerr_die.c new file mode 100644 index 0000000..850028b --- /dev/null +++ b/ucspi-tcp-0.88/strerr_die.c @@ -0,0 +1,31 @@ +#include "buffer.h" +#include "exit.h" +#include "strerr.h" + +void strerr_warn(char *x1,char *x2,char *x3,char *x4,char *x5,char *x6,struct strerr *se) +{ + strerr_sysinit(); + + 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) 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; + } + + buffer_puts(buffer_2,"\n"); + buffer_flush(buffer_2); +} + +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/ucspi-tcp-0.88/strerr_sys.c b/ucspi-tcp-0.88/strerr_sys.c new file mode 100644 index 0000000..b484197 --- /dev/null +++ b/ucspi-tcp-0.88/strerr_sys.c @@ -0,0 +1,12 @@ +#include "error.h" +#include "strerr.h" + +struct strerr strerr_sys; + +void strerr_sysinit(void) +{ + strerr_sys.who = 0; + strerr_sys.x = error_str(errno); + strerr_sys.y = ""; + strerr_sys.z = ""; +} diff --git a/ucspi-tcp-0.88/subgetopt.c b/ucspi-tcp-0.88/subgetopt.c new file mode 100644 index 0000000..552c4de --- /dev/null +++ b/ucspi-tcp-0.88/subgetopt.c @@ -0,0 +1,65 @@ +#define SUBGETOPTNOSHORT +#include "subgetopt.h" + +#define sgopt subgetopt +#define optind subgetoptind +#define optpos subgetoptpos +#define optarg subgetoptarg +#define optproblem subgetoptproblem +#define optdone subgetoptdone + +int optind = 1; +int optpos = 0; +char *optarg = 0; +int optproblem = 0; +int optdone = SUBGETOPTDONE; + +int sgopt(int argc,char **argv,char *opts) +{ + int c; + char *s; + + optarg = 0; + if (!argv || (optind >= argc) || !argv[optind]) return optdone; + if (optpos && !argv[optind][optpos]) { + ++optind; + optpos = 0; + if ((optind >= argc) || !argv[optind]) return optdone; + } + if (!optpos) { + if (argv[optind][0] != '-') return optdone; + ++optpos; + c = argv[optind][1]; + if ((c == '-') || (c == 0)) { + if (c) ++optind; + optpos = 0; + return optdone; + } + /* otherwise c is reassigned below */ + } + c = argv[optind][optpos]; + ++optpos; + s = opts; + while (*s) { + if (c == *s) { + if (s[1] == ':') { + optarg = argv[optind] + optpos; + ++optind; + optpos = 0; + if (!*optarg) { + optarg = argv[optind]; + if ((optind >= argc) || !optarg) { /* argument past end */ + optproblem = c; + return '?'; + } + ++optind; + } + } + return c; + } + ++s; + if (*s == ':') ++s; + } + optproblem = c; + return '?'; +} diff --git a/ucspi-tcp-0.88/subgetopt.h b/ucspi-tcp-0.88/subgetopt.h new file mode 100644 index 0000000..b4b63e1 --- /dev/null +++ b/ucspi-tcp-0.88/subgetopt.h @@ -0,0 +1,24 @@ +#ifndef SUBGETOPT_H +#define SUBGETOPT_H + +#ifndef SUBGETOPTNOSHORT +#define sgopt subgetopt +#define sgoptarg subgetoptarg +#define sgoptind subgetoptind +#define sgoptpos subgetoptpos +#define sgoptproblem subgetoptproblem +#define sgoptprogname subgetoptprogname +#define sgoptdone subgetoptdone +#endif + +#define SUBGETOPTDONE -1 + +extern int subgetopt(int,char **,char *); +extern char *subgetoptarg; +extern int subgetoptind; +extern int subgetoptpos; +extern int subgetoptproblem; +extern char *subgetoptprogname; +extern int subgetoptdone; + +#endif diff --git a/ucspi-tcp-0.88/tai.h b/ucspi-tcp-0.88/tai.h new file mode 100644 index 0000000..28ee9e6 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/tai_pack.c b/ucspi-tcp-0.88/tai_pack.c new file mode 100644 index 0000000..5e662cf --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/taia.h b/ucspi-tcp-0.88/taia.h new file mode 100644 index 0000000..f4c0ca7 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/taia_add.c b/ucspi-tcp-0.88/taia_add.c new file mode 100644 index 0000000..a596cc8 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/taia_approx.c b/ucspi-tcp-0.88/taia_approx.c new file mode 100644 index 0000000..0c4d0de --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/taia_frac.c b/ucspi-tcp-0.88/taia_frac.c new file mode 100644 index 0000000..89a1aac --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/taia_less.c b/ucspi-tcp-0.88/taia_less.c new file mode 100644 index 0000000..13b7288 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/taia_now.c b/ucspi-tcp-0.88/taia_now.c new file mode 100644 index 0000000..ccc260d --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/taia_pack.c b/ucspi-tcp-0.88/taia_pack.c new file mode 100644 index 0000000..1f1b051 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/taia_sub.c b/ucspi-tcp-0.88/taia_sub.c new file mode 100644 index 0000000..7956647 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/taia_uint.c b/ucspi-tcp-0.88/taia_uint.c new file mode 100644 index 0000000..167936c --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/tcpcat.sh b/ucspi-tcp-0.88/tcpcat.sh new file mode 100644 index 0000000..2825411 --- /dev/null +++ b/ucspi-tcp-0.88/tcpcat.sh @@ -0,0 +1 @@ +exec HOME/bin/tcpclient -RHl0 -- "${1-0}" "${2-17}" sh -c 'exec cat <&6' diff --git a/ucspi-tcp-0.88/tcpclient.c b/ucspi-tcp-0.88/tcpclient.c new file mode 100644 index 0000000..9f6d7f2 --- /dev/null +++ b/ucspi-tcp-0.88/tcpclient.c @@ -0,0 +1,224 @@ +#include <sys/types.h> +#include <sys/param.h> +#include <netdb.h> +#include "sig.h" +#include "exit.h" +#include "sgetopt.h" +#include "uint16.h" +#include "fmt.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 " + +void nomem(void) +{ + strerr_die2x(111,FATAL,"out of memory"); +} +void usage(void) +{ + strerr_die1x(100,"tcpclient: usage: tcpclient \ +[ -hHrRdDqQv ] \ +[ -i localip ] \ +[ -p localport ] \ +[ -T timeoutconn ] \ +[ -l localname ] \ +[ -t timeoutinfo ] \ +host port program"); +} + +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; + +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) +{ + unsigned long u; + int opt; + char *x; + int j; + 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; + case 'D': flagdelay = 0; break; + case 'v': verbosity = 2; break; + case 'q': verbosity = 0; break; + case 'Q': verbosity = 1; break; + case 'l': forcelocal = optarg; break; + case 'H': flagremotehost = 0; break; + case 'h': flagremotehost = 1; break; + case 'R': flagremoteinfo = 0; break; + case 'r': flagremoteinfo = 1; 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(); + } + argv += optind; + + if (!verbosity) + buffer_2->fd = -1; + + hostname = *argv; + if (!hostname) usage(); + if (str_equal(hostname,"")) hostname = "127.0.0.1"; + if (str_equal(hostname,"0")) hostname = "127.0.0.1"; + + x = *++argv; + if (!x) usage(); + if (!x[scan_ulong(x,&u)]) + portremote = u; + else { + 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 */ + } + + 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; + } + + 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) + 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 (!stralloc_copy(&addresses,&moreaddresses)) 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; + } + 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) + if (dns_name4(&tmp,ipremote) == 0) { + if (!stralloc_0(&tmp)) nomem(); + x = tmp.s; + } + 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); + + pathexec(argv); + strerr_die4sys(111,FATAL,"unable to run ",*argv,": "); +} diff --git a/ucspi-tcp-0.88/tcprules.c b/ucspi-tcp-0.88/tcprules.c new file mode 100644 index 0000000..a684ac5 --- /dev/null +++ b/ucspi-tcp-0.88/tcprules.c @@ -0,0 +1,175 @@ +#include "strerr.h" +#include "stralloc.h" +#include "getln.h" +#include "buffer.h" +#include "exit.h" +#include "fmt.h" +#include "byte.h" +#include "cdb_make.h" + +#define FATAL "tcprules: fatal: " + +unsigned long linenum = 0; +char *fntemp; +char *fn; + +stralloc line = {0}; +int match = 1; + +stralloc address = {0}; +stralloc data = {0}; +stralloc key = {0}; + +struct cdb_make c; + +void nomem(void) +{ + strerr_die2x(111,FATAL,"out of memory"); +} +void usage(void) +{ + strerr_die1x(100,"tcprules: usage: tcprules rules.cdb rules.tmp"); +} +void die_bad(void) +{ + if (!stralloc_0(&line)) nomem(); + strerr_die3x(100,FATAL,"unable to parse this line: ",line.s); +} +void die_write(void) +{ + strerr_die4sys(111,FATAL,"unable to write to ",fntemp,": "); +} + +char strnum[FMT_ULONG]; +stralloc sanum = {0}; + +void getnum(char *buf,int len,unsigned long *u) +{ + 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) +{ + int i; + int left; + int right; + unsigned long bot; + unsigned long top; + + 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; + } + } + + if (cdb_make_add(&c,address.s,address.len,data.s,data.len) == -1) die_write(); +} + +main(int argc,char **argv) +{ + int colon; + char *x; + int len; + int fd; + int i; + char ch; + + fn = argv[1]; + if (!fn) usage(); + fntemp = argv[2]; + if (!fntemp) usage(); + + fd = open_trunc(fntemp); + if (fd == -1) + strerr_die4sys(111,FATAL,"unable to create ",fntemp,": "); + if (cdb_make_start(&c,fd) == -1) die_write(); + + while (match) { + if (getln(buffer_0,&line,&match,'\n') == -1) + strerr_die2sys(111,FATAL,"unable to read input: "); + + x = line.s; len = line.len; + + if (!len) break; + if (x[0] == '#') continue; + if (x[0] == '\n') continue; + + while (len) { + ch = x[len - 1]; + if (ch != '\n') if (ch != ' ') if (ch != '\t') break; + --len; + } + line.len = len; /* for die_bad() */ + + colon = byte_chr(x,len,':'); + if (colon == len) continue; + + 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)) nomem(); + x += 4; len -= 4; + } + else if ((len >= 5) && byte_equal(x,5,"allow")) { + x += 5; len -= 5; + } + else + die_bad(); + + while (len) + switch(*x) { + case ',': + i = byte_chr(x,len,'='); + if (i == len) die_bad(); + 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)) nomem(); + if (!stralloc_0(&data)) nomem(); + x += i + 1; len -= i + 1; + break; + default: + die_bad(); + } + + doaddressdata(); + } + + 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)) + strerr_die6sys(111,FATAL,"unable to move ",fntemp," to ",fn,": "); + + _exit(0); +} diff --git a/ucspi-tcp-0.88/tcprulescheck.c b/ucspi-tcp-0.88/tcprulescheck.c new file mode 100644 index 0000000..a961d50 --- /dev/null +++ b/ucspi-tcp-0.88/tcprulescheck.c @@ -0,0 +1,57 @@ +#include "byte.h" +#include "buffer.h" +#include "strerr.h" +#include "env.h" +#include "rules.h" + +void found(char *data,unsigned int datalen) +{ + unsigned int next0; + + 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': + buffer_puts(buffer_1,"deny connection\n"); + buffer_flush(buffer_1); + _exit(0); + case '+': + buffer_puts(buffer_1,"set environment variable "); + buffer_puts(buffer_1,data + 1); + buffer_puts(buffer_1,"\n"); + break; + } + ++next0; + data += next0; datalen -= next0; + } + buffer_puts(buffer_1,"allow connection\n"); + buffer_flush(buffer_1); + _exit(0); +} + +main(int argc,char **argv) +{ + char *fnrules; + int fd; + char *ip; + char *info; + char *host; + + fnrules = argv[1]; + if (!fnrules) + strerr_die1x(100,"tcprulescheck: usage: tcprulescheck rules.cdb"); + + ip = env_get("TCPREMOTEIP"); + if (!ip) ip = "0.0.0.0"; + info = env_get("TCPREMOTEINFO"); + host = env_get("TCPREMOTEHOST"); + + fd = open_read(fnrules); + if ((fd == -1) || (rules(found,fd,ip,host,info) == -1)) + strerr_die3sys(111,"tcprulescheck: fatal: unable to read ",fnrules,": "); + + buffer_putsflush(buffer_1,"default:\nallow connection\n"); + _exit(0); +} diff --git a/ucspi-tcp-0.88/tcpserver.c b/ucspi-tcp-0.88/tcpserver.c new file mode 100644 index 0000000..979a0be --- /dev/null +++ b/ucspi-tcp-0.88/tcpserver.c @@ -0,0 +1,426 @@ +#include <sys/types.h> +#include <sys/param.h> +#include <netdb.h> +#include "uint16.h" +#include "str.h" +#include "byte.h" +#include "fmt.h" +#include "scan.h" +#include "ip4.h" +#include "fd.h" +#include "exit.h" +#include "env.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" + +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; + +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) +{ + strerr_die2sys(111,DROP,"out of memory"); +} +void cats(char *s) +{ + if (!stralloc_cats(&tmp,s)) drop_nomem(); +} +void append(char *ch) +{ + if (!stralloc_append(&tmp,ch)) drop_nomem(); +} +void safecats(char *s) +{ + char ch; + int i; + + for (i = 0;i < 100;++i) { + ch = s[i]; + if (!ch) return; + if (ch < 33) ch = '?'; + if (ch > 126) ch = '?'; + if (ch == '%') ch = '?'; /* logger stupidity */ + if (ch == ':') ch = '?'; + append(&ch); + } + cats("..."); +} +void env(char *s,char *t) +{ + if (!pathexec_env(s,t)) drop_nomem(); +} +void drop_rules(void) +{ + strerr_die4sys(111,DROP,"unable to read ",fnrules,": "); +} + +void found(char *data,unsigned int datalen) +{ + unsigned int next0; + unsigned int split; + + 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; + } + ++next0; + data += next0; datalen -= next0; + } +} + +void doit(int t) +{ + int j; + + remoteipstr[ip4_fmt(remoteipstr,remoteip)] = 0; + + if (verbosity >= 2) { + strnum[fmt_ulong(strnum,getpid())] = 0; + strerr_warn4("tcpserver: pid ",strnum," from ",remoteipstr,0); + } + + if (flagkillopts) + socket_ipoptionskill(t); + if (!flagdelay) + socket_tcpnodelay(t); + + 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); + } + } + + 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); + } + + if (flagdeny) _exit(100); +} + + + +/* ---------------------------- parent */ + +#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); +} + +unsigned long limit = 40; +unsigned long numchildren = 0; + +int flag1 = 0; +unsigned long backlog = 20; +unsigned long uid = 0; +unsigned long gid = 0; + +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 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) +{ + char *hostname; + char *portname; + int opt; + struct servent *se; + char *x; + unsigned long u; + int s; + int t; + + 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; + case 'D': flagdelay = 0; break; + case 'v': verbosity = 2; break; + case 'q': verbosity = 0; break; + case 'Q': verbosity = 1; break; + case 'P': flagparanoid = 0; break; + case 'p': flagparanoid = 1; break; + case 'O': flagkillopts = 1; break; + case 'o': flagkillopts = 0; break; + case 'H': flagremotehost = 0; break; + case 'h': flagremotehost = 1; break; + case 'R': flagremoteinfo = 0; break; + case 'r': flagremoteinfo = 1; break; + case 't': scan_ulong(optarg,&timeout); 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': localhost = optarg; break; + default: usage(); + } + argc -= optind; + argv += optind; + + if (!verbosity) + buffer_2->fd = -1; + + hostname = *argv++; + if (!hostname) usage(); + if (str_equal(hostname,"")) hostname = "0.0.0.0"; + if (str_equal(hostname,"0")) hostname = "0.0.0.0"; + + 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(); + + sig_block(sig_child); + sig_catch(sig_child,sigchld); + sig_catch(sig_term,sigterm); + sig_ignore(sig_pipe); + + 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: "); + + + 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); + } + + close(0); + close(1); + printstatus(); + + for (;;) { + while (numchildren >= limit) sig_pause(); + + sig_unblock(sig_child); + t = socket_accept4(s,remoteip,&remoteport); + sig_block(sig_child); + + if (t == -1) continue; + ++numchildren; printstatus(); + + switch(fork()) { + case 0: + close(s); + 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/ucspi-tcp-0.88/timeoutconn.c b/ucspi-tcp-0.88/timeoutconn.c new file mode 100644 index 0000000..2a8b0aa --- /dev/null +++ b/ucspi-tcp-0.88/timeoutconn.c @@ -0,0 +1,34 @@ +#include "ndelay.h" +#include "socket.h" +#include "iopause.h" +#include "error.h" +#include "timeoutconn.h" + +int timeoutconn(int s,char ip[4],uint16 port,unsigned int timeout) +{ + 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; + } + } + if (!socket_connected(s)) return -1; + } + + if (ndelay_off(s) == -1) return -1; + return 0; +} diff --git a/ucspi-tcp-0.88/timeoutconn.h b/ucspi-tcp-0.88/timeoutconn.h new file mode 100644 index 0000000..7f9dcc9 --- /dev/null +++ b/ucspi-tcp-0.88/timeoutconn.h @@ -0,0 +1,8 @@ +#ifndef TIMEOUTCONN_H +#define TIMEOUTCONN_H + +#include "uint16.h" + +extern int timeoutconn(int,char *,uint16,unsigned int); + +#endif diff --git a/ucspi-tcp-0.88/trycpp.c b/ucspi-tcp-0.88/trycpp.c new file mode 100644 index 0000000..3ab455b --- /dev/null +++ b/ucspi-tcp-0.88/trycpp.c @@ -0,0 +1,7 @@ +main() +{ +#ifdef NeXT + printf("nextstep\n"); exit(0); +#endif + printf("unknown\n"); exit(0); +} diff --git a/ucspi-tcp-0.88/trylsock.c b/ucspi-tcp-0.88/trylsock.c new file mode 100644 index 0000000..fbce408 --- /dev/null +++ b/ucspi-tcp-0.88/trylsock.c @@ -0,0 +1,4 @@ +main() +{ + ; +} diff --git a/ucspi-tcp-0.88/trypoll.c b/ucspi-tcp-0.88/trypoll.c new file mode 100644 index 0000000..249824d --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/trysgact.c b/ucspi-tcp-0.88/trysgact.c new file mode 100644 index 0000000..98a4b20 --- /dev/null +++ b/ucspi-tcp-0.88/trysgact.c @@ -0,0 +1,10 @@ +#include <signal.h> + +main() +{ + struct sigaction sa; + sa.sa_handler = 0; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(0,&sa,(struct sigaction *) 0); +} diff --git a/ucspi-tcp-0.88/trysgprm.c b/ucspi-tcp-0.88/trysgprm.c new file mode 100644 index 0000000..2797eea --- /dev/null +++ b/ucspi-tcp-0.88/trysgprm.c @@ -0,0 +1,10 @@ +#include <signal.h> + +main() +{ + sigset_t ss; + + sigemptyset(&ss); + sigaddset(&ss,SIGCHLD); + sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0); +} diff --git a/ucspi-tcp-0.88/tryshsgr.c b/ucspi-tcp-0.88/tryshsgr.c new file mode 100644 index 0000000..f55ff60 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/trysysel.c b/ucspi-tcp-0.88/trysysel.c new file mode 100644 index 0000000..f6ed055 --- /dev/null +++ b/ucspi-tcp-0.88/trysysel.c @@ -0,0 +1,8 @@ +#include <sys/types.h> +#include <sys/time.h> +#include <sys/select.h> /* SVR4 silliness */ + +void foo() +{ + ; +} diff --git a/ucspi-tcp-0.88/tryulong32.c b/ucspi-tcp-0.88/tryulong32.c new file mode 100644 index 0000000..63156e6 --- /dev/null +++ b/ucspi-tcp-0.88/tryulong32.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(0); + _exit(1); +} diff --git a/ucspi-tcp-0.88/tryulong64.c b/ucspi-tcp-0.88/tryulong64.c new file mode 100644 index 0000000..01965cb --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/tryvfork.c b/ucspi-tcp-0.88/tryvfork.c new file mode 100644 index 0000000..cc39699 --- /dev/null +++ b/ucspi-tcp-0.88/tryvfork.c @@ -0,0 +1,4 @@ +main() +{ + vfork(); +} diff --git a/ucspi-tcp-0.88/trywaitp.c b/ucspi-tcp-0.88/trywaitp.c new file mode 100644 index 0000000..64d807e --- /dev/null +++ b/ucspi-tcp-0.88/trywaitp.c @@ -0,0 +1,7 @@ +#include <sys/types.h> +#include <sys/wait.h> + +main() +{ + waitpid(0,0,0); +} diff --git a/ucspi-tcp-0.88/uint16.h b/ucspi-tcp-0.88/uint16.h new file mode 100644 index 0000000..34ab9f4 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/uint16_pack.c b/ucspi-tcp-0.88/uint16_pack.c new file mode 100644 index 0000000..17dbfe6 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/uint16_unpack.c b/ucspi-tcp-0.88/uint16_unpack.c new file mode 100644 index 0000000..18b5b12 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/uint32.h1 b/ucspi-tcp-0.88/uint32.h1 new file mode 100644 index 0000000..68d7231 --- /dev/null +++ b/ucspi-tcp-0.88/uint32.h1 @@ -0,0 +1,11 @@ +#ifndef UINT32_H +#define UINT32_H + +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/ucspi-tcp-0.88/uint32.h2 b/ucspi-tcp-0.88/uint32.h2 new file mode 100644 index 0000000..b5c7f40 --- /dev/null +++ b/ucspi-tcp-0.88/uint32.h2 @@ -0,0 +1,11 @@ +#ifndef UINT32_H +#define UINT32_H + +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/ucspi-tcp-0.88/uint32_pack.c b/ucspi-tcp-0.88/uint32_pack.c new file mode 100644 index 0000000..76bc670 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/uint32_unpack.c b/ucspi-tcp-0.88/uint32_unpack.c new file mode 100644 index 0000000..f484644 --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/uint64.h1 b/ucspi-tcp-0.88/uint64.h1 new file mode 100644 index 0000000..206fc09 --- /dev/null +++ b/ucspi-tcp-0.88/uint64.h1 @@ -0,0 +1,8 @@ +#ifndef UINT64_H +#define UINT64_H + +/* sysdep: -ulong64 */ + +typedef unsigned long long uint64; + +#endif diff --git a/ucspi-tcp-0.88/uint64.h2 b/ucspi-tcp-0.88/uint64.h2 new file mode 100644 index 0000000..8a0f315 --- /dev/null +++ b/ucspi-tcp-0.88/uint64.h2 @@ -0,0 +1,8 @@ +#ifndef UINT64_H +#define UINT64_H + +/* sysdep: +ulong64 */ + +typedef unsigned long uint64; + +#endif diff --git a/ucspi-tcp-0.88/wait.h b/ucspi-tcp-0.88/wait.h new file mode 100644 index 0000000..cdb77c3 --- /dev/null +++ b/ucspi-tcp-0.88/wait.h @@ -0,0 +1,14 @@ +#ifndef WAIT_H +#define WAIT_H + +extern int wait_pid(); +extern int wait_nohang(); +extern int wait_stop(); +extern int wait_stopnohang(); + +#define wait_crashed(w) ((w) & 127) +#define wait_exitcode(w) ((w) >> 8) +#define wait_stopsig(w) ((w) >> 8) +#define wait_stopped(w) (((w) & 127) == 127) + +#endif diff --git a/ucspi-tcp-0.88/wait_nohang.c b/ucspi-tcp-0.88/wait_nohang.c new file mode 100644 index 0000000..bea2774 --- /dev/null +++ b/ucspi-tcp-0.88/wait_nohang.c @@ -0,0 +1,12 @@ +#include <sys/types.h> +#include <sys/wait.h> +#include "haswaitp.h" + +int wait_nohang(wstat) int *wstat; +{ +#ifdef HASWAITPID + return waitpid(-1,wstat,WNOHANG); +#else + return wait3(wstat,WNOHANG,(struct rusage *) 0); +#endif +} diff --git a/ucspi-tcp-0.88/wait_pid.c b/ucspi-tcp-0.88/wait_pid.c new file mode 100644 index 0000000..d7a7e84 --- /dev/null +++ b/ucspi-tcp-0.88/wait_pid.c @@ -0,0 +1,39 @@ +#include <sys/types.h> +#include <sys/wait.h> +#include "error.h" +#include "haswaitp.h" + +#ifdef HASWAITPID + +int wait_pid(wstat,pid) int *wstat; int pid; +{ + int r; + + do + r = waitpid(pid,wstat,0); + while ((r == -1) && (errno == error_intr)); + return r; +} + +#else + +/* XXX untested */ +/* XXX breaks down with more than two children */ +static int oldpid = 0; +static int oldwstat; /* defined if(oldpid) */ + +int wait_pid(wstat,pid) int *wstat; int pid; +{ + int r; + + if (pid == oldpid) { *wstat = oldwstat; oldpid = 0; return pid; } + + do { + r = wait(wstat); + if ((r != pid) && (r != -1)) { oldwstat = *wstat; oldpid = r; continue; } + } + while ((r == -1) && (errno == error_intr)); + return r; +} + +#endif diff --git a/ucspi-tcp-0.88/warn-auto.sh b/ucspi-tcp-0.88/warn-auto.sh new file mode 100644 index 0000000..36d2313 --- /dev/null +++ b/ucspi-tcp-0.88/warn-auto.sh @@ -0,0 +1,2 @@ +#!/bin/sh +# WARNING: This file was auto-generated. Do not edit! diff --git a/ucspi-tcp-0.88/warn-shsgr b/ucspi-tcp-0.88/warn-shsgr new file mode 100644 index 0000000..37c351e --- /dev/null +++ b/ucspi-tcp-0.88/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/ucspi-tcp-0.88/who@.sh b/ucspi-tcp-0.88/who@.sh new file mode 100644 index 0000000..5c7550f --- /dev/null +++ b/ucspi-tcp-0.88/who@.sh @@ -0,0 +1 @@ +HOME/bin/tcpclient -RHl0 -- "${1-0}" 11 sh -c 'exec HOME/bin/delcr <&6' | cat -v diff --git a/ucspi-tcp-0.88/x86cpuid.c b/ucspi-tcp-0.88/x86cpuid.c new file mode 100644 index 0000000..900d7d5 --- /dev/null +++ b/ucspi-tcp-0.88/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; +} |