changeset 4:fe6bca95afa7

Makefile.in contains updated files required
author Matt Johnston <matt@ucc.asn.au>
date Tue, 01 Jun 2004 02:46:09 +0000
parents
children bc6477a6c393
files CHANGES INSTALL LICENSE MULTI Makefile.in README SMALL TODO agentfwd.h algo.h atomicio.c atomicio.h auth.h authpasswd.h authpubkey.h bignum.c bignum.h buffer.c buffer.h channel.h chansession.h cli_algo.c common-algo.c common-channel.c common-chansession.c common-kex.c common-packet.c common-session.c compat.c compat.h config.guess config.sub configure.in dbmulti.c dbutil.c dbutil.h debian/README.Debian debian/changelog debian/compat debian/conffiles debian/control debian/copyright.in debian/dirs debian/docs debian/dropbear.default debian/dropbear.init debian/postinst debian/postrm debian/rules debug.h dropbearconvert.c dropbearkey.c dss.c dss.h filelist.txt gendss.c gendss.h genrsa.c genrsa.h includes.h install-sh kex.h keyimport.c keyimport.h localtcpfwd.c localtcpfwd.h loginrec.c loginrec.h main.c options.h packet.h progressmeter.c progressmeter.h queue.c queue.h random.c random.h remotetcpfwd.c remotetcpfwd.h rsa.c rsa.h runopts.h scp.c scpmisc.c scpmisc.h service.h session.h signkey.c signkey.h ssh.h sshpty.c sshpty.h svr-agentfwd.c svr-algo.c svr-auth.c svr-authpasswd.c svr-authpubkey.c svr-chansession.c svr-kex.c svr-packet.c svr-runopts.c svr-service.c svr-session.c tcpfwd.c tcpfwd.h termcodes.c termcodes.h x11fwd.c x11fwd.h
diffstat 107 files changed, 23306 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CHANGES	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,252 @@
+0.41 - Mon Jan 19 2004 22:40:19 +0800
+
+- Fix in configure so that cross-compiling works, thanks to numerous people for
+  reporting and testing
+
+- Terminal mode parsing now handles empty terminal mode strings (sent by
+  Windows ssh.com clients), thanks to Ricardo Derbes for the report
+
+- Handling is improved for users with no shell specified in /etc/passwd,
+  thanks again to Ricardo Derbes
+
+- Fix for compiling with --disable-syslog, thanks to gordonfh
+
+- Various minor fixes allow scp to work with irix, thanks to Paul Marinceu for
+  fixing it up
+
+- Use <stropts.h> not <sys/stropts.h>, since the former seems more common
+
+0.40 - Tue Jan 13 2004 21:05:19 +0800
+
+- Remote TCP forwarding (-R) style implemented
+
+- Local and remote TCP forwarding can each be disabled at runtime (-k and -j
+  switches)
+
+- Fix for problems detecting openpty() with uClibc - many thanks to various
+  people for reporting and testing fixes, including (in random order) Cristian
+  Ionescu-Idbohrn, James Ewing, Steve Dover, Thomas Lundquist and Frederic
+  Lavernhe
+
+- Improved portability for IRIX, thanks to Paul Marinceu
+
+- AIX and HPUX portability fixes, thanks to Darren Tucker for patches
+
+- prngd should now work correctly, thanks to Darren Tucker for the patch
+
+- scp compilation on systems without strlcpy() is fixed, thanks to Peter
+  Jannesen and David Muse for reporting it (independently and simultaneously :)
+
+- Merged in new LibTomCrypt 0.92 and LibTomMath 0.28
+
+0.39 - Tue Dec 16 2003 15:19:19 +0800
+
+- Better checking of key lengths and parameters for DSS and RSA auth
+
+- Print fingerprint of keys used for pubkey auth
+
+- More consistent logging of usernames and IPs
+
+- Added option to disable password auth (or just for root) at runtime
+
+- Avoid including bignum functions which don't give much speed benefit but
+  take up binary size
+
+- Added a stripped down version of OpenSSH's scp binary
+
+- Added additional supporting functions for Irix, thanks to Paul Marinceu
+
+- Don't check for unused libraries in configure script
+
+- Removed trailing comma in algorithm lists (thanks to Mihnea Stoenescu)
+
+- Fixed up channel close handling, always send close packet in response
+  (also thanks to Mihnea Stoenescu)
+
+- Various makefile improvements for cross-compiling, thanks to Friedrich
+  Lobenstock and Mihnea Stoenescu
+
+- Use daemon() function if available (or our own copy) rather than separate
+  code (thanks to Fr�d�ric Lavernhe for the report and debugging, and Bernard
+  Blackham for his suggestion on what to look at)
+
+- Fixed up support for first_kex_packet_follows, required to talk to ssh.com
+  clients. Thanks to Marian Stagarescu for the bug report.
+
+- Avoid using MAXPATHLEN, pointer from Ian Morris
+
+- Improved input sanity checking
+
+0.38 - Sat Oct 11 2003 16:28:13 +0800
+
+- Default hostkey path changed to /etc/dropbear/dropbear_{rsa,dss}_host_key
+  rather than /etc/dropbear_{rsa,dss}_host_key
+
+- Added SMALL and MULTI text files which have info on compiling for multiple
+  binaries or small binaries
+
+- Allow for commandline definition of some options.h settings
+  (without warnings)
+
+- Be more careful handling EINTR
+
+- More fixes for channel closing
+
+- Added multi-binary support
+
+- Improved logging of IPs, now get logged in all cases
+
+- Don't chew cpu when waiting for version identification string, also
+  make sure that we kick off people if they don't auth within 5 minutes.
+
+- Various small fixes, warnings etc
+
+- Display MOTD if requested - suggested by
+  Trent Lloyd <lathiat at sixlabs.org> and
+  Zach White <zwhite at darkstar.frop.org>
+
+- sftp support works (relies on OpenSSH sftp binary or similar)
+
+- Added --disable-shadow option (requested by the floppyfw guys)
+
+0.37 - Wed Sept 24 2003 19:42:12 +0800
+
+- Various portability fixes, fixes for Solaris 9, Tru64 5.1, Mac OS X 10.2,
+  AIX, BSDs
+
+- Updated LibTomMath to 0.27 and LibTomCrypt to 0.90
+
+- Renamed util.{c,h} to dbutil.{c,h} to avoid conflicts with system util.h
+
+- Added some small changes so it'll work with AIX (plus Linux Affinity).
+  Thanks to Shig for them.
+
+- Improved the closing messages, so a clean exit is "Exited normally"
+
+- Added some more robust integer/size checking in buffer.c as a backstop for
+  integer overflows
+
+- X11 forwarding fixed for OSX, path for xauth changed to /usr/X11R6/bin/xauth
+
+- Channel code handles closing more nicely, doesn't sit waiting for an extra
+  keystroke on BSD/OSX platforms, and data is flushed fully before closing
+  child processes (thanks to 
+  Cristian Ionescu-Idbohrn <cristian.ionescu-idbohrn at axis.com> for
+  pointing that out).
+
+- Changed "DISABLE_TCPFWD" to "ENABLE_TCPFWD" (and for x11/auth) so
+  "disable DISABLE_TCPWD" isn't so confusing.
+
+- Fix authorized_keys handling (don't crash on too-long keys, and
+  use fgetc not getc to avoid strange macro-related issues), thanks to
+  Cristian Ionescu-Idbohrn <cristian.ionescu-idbohrn at axis.com> 
+  and Steve Rodgers <hwstar at cox.net> for reporting and testing.
+
+- Fixes to the README with regard to uClibc systems, thanks to 
+  Cristian Ionescu-Idbohrn <cristian.ionescu-idbohrn at axis.com>,
+  as well as general improvements to documentation (split README/INSTALL)
+
+- Fixed up some compilation problems with dropbearconvert/dropbearkey if
+  DSS or RSA were disabled, reported by Patrik Karlsson <patrik at cqure.net>
+
+- Fix double-free bug for hostkeys, reported by
+  Vincent Sanders <vince at kyllikki.org>
+
+- Fix up missing \ns from dropbearconvert help message,
+  thanks to Mordy Ovits <movits at bloomberg.com> for the patch
+
+0.36 - Tue August 19 2003 12:16:23 +0800
+
+- Fix uninitialised temporary variable in DSS signing code
+  (thanks to Matthew Franz <mdfranz at io.com> for reporting, and the authors
+  of Valgrind for making it easy to track down)
+- Fix remote version-string parsing error
+  (thanks to Bernard Blackham <bernard at blackham.com.au> for noticing)
+- Improved host-algorithm-matching algorithm in algo.c
+- Decreased MAX_STRING_LEN to a more realistic value
+- Fix incorrect version (0.34) in this CHANGES file for the previous release.
+
+0.35 - Sun August 17 2003 05:37:47 +0800
+
+- Fix for remotely exploitable format string buffer overflow.
+  (thanks to Joel Eriksson <je at bitnux.com>)
+
+0.34 - Fri August 15 2003 15:10:00 +0800
+
+- Made syslog optional, both at compile time and as a compile option
+  (suggested by Laurent Bercot <ska at skarnet.org>)
+- Fixup for bad base64 parsing in authorized_keys
+  (noticed by Davyd Madeley <davyd at zdlcomputing.com>)
+- Added initial tcp forwarding code, only -L (local) at this stage
+- Improved "make install" with DESTDIR and changing ownership seperately,
+  don't check for setpgrp on Linux for crosscompiling.
+  (from Erik Andersen <andersen at codepoet.org>)
+- More commenting, fix minor compile warnings, make return values more
+  consistent etc
+- Various signedness fixes
+- Can listen on multiple ports
+- added option to disable openpty with configure script,
+  (from K.-P. Kirchd�rfer <kapeka at epost.de>)
+- Various cleanups to bignum code
+  (thanks to Tom St Denis <tomstdenis at iahu.ca>)
+- Fix compile error when disabling RSA
+  (from Marc Kleine-Budde <kleine-budde at gmx.de>)
+- Other cleanups, splitting large functions for packet and kex handling etc
+
+0.33 - Sun June 22 2003 22:24:12 +0800
+
+- Fixed some invalid assertions in the channel code, fixing the server dying
+  when forwarding X11 connections.
+- Add dropbearconvert to convert to/from OpenSSH host keys and Dropbear keys
+- RSA keys now keep p and q parameters for compatibility -- old Dropbear keys
+  still work, but can't be converted to OpenSSH etc.
+- Debian packaging directory added, thanks to 
+  Grahame (grahame at angrygoats.net)
+- 'install' target added to the makefile
+- general tidying, improve consistency of functions etc
+- If RSA or DSS hostkeys don't exist, that algorithm won't be used.
+- Improved RSA and DSS key generation, more efficient and fixed some minor bugs
+  (thanks to Tom St Denis for the advice)
+- Merged new versions of LibTomCrypt (0.86) and LibTomMath (0.21)
+
+0.32 - Sat May 24 2003 12:44:11 +0800
+
+- Don't compile unused code from libtomcrypt (test vectors etc)
+- Updated to libtommath 0.17 and libtomcrypt 0.83. New libtommath results
+  in smaller binary size, due to not linking unrequired code
+- X11 forwarding added
+- Agent forwarding added (for OpenSSH.com ssh client/agent)
+- Fix incorrect buffer freeing when banners are used
+- Hostname resolution works
+- Various minor bugfixes/code size improvements etc
+
+0.31 - Fri May 9 2003 17:57:16 +0800
+
+- Improved syslog messages - IP logging etc
+- Strip control characters from log messages (specified username currently)
+- Login recording (utmp/wtmp) support, so last/w/who work - taken from OpenSSH
+- Shell is started as a proper login shell, so /etc/profile etc is sourced
+- Ptys work on Solaris (2.8 x86 tested) now
+- Fixed bug in specifying the rsa hostkey
+- Fixed bug in compression code, could trigger if compression resulted in
+  larger output than input (uncommon but possible).
+
+0.30 - Thu Apr 17 2003 18:46:15 +0800
+
+- SECURITY: buffer.c had bad checking for buffer increment length - fixed
+- channel code now closes properly on EOF - scp processes don't hang around
+- syslog support added - improved auth/login/failure messages
+- general code tidying, made return codes more consistent
+- Makefile fixed for dependencies and makes libtomcrypt as well
+- Implemented sending SSH_MSG_UNIMPLEMENTED :)
+
+0.29 - Wed Apr 9 2003
+
+- Fixed a stupid bug in 0.28 release, 'newstr = strdup(oldstr)',
+  not 'newstr=oldstr'
+
+0.28 - Sun Apr 6 2003
+
+- Initial public release
+
+Development was started in October 2002
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/INSTALL	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,108 @@
+Basic Dropbear build instructions:
+
+- First, edit options.h to choose user-defined features to choose, such as
+  which ciphers/hashes you want, which forwarding you want, etc.
+
+- Edit debug.h if you want any debug options
+
+- Now configure Dropbear's host-specific options
+  (if you are using a cvs copy, "autoconf; autoheader" first)
+
+./configure      (optionally with --disable-zlib or --disable-syslog,
+                  or --help for other options)
+
+- Then compile and optionally install Dropbear:
+
+(the Makefile requires GNU make, if you want to make it portable, send me
+ some patches)
+
+make
+make install     (installs to /usr/local/sbin, /usr/local/bin by default)
+
+You need to generate server keys, this is one-off:
+./dropbearkey -t rsa -f dropbear_rsa_host_key
+./dropbearkey -t dss -f dropbear_dss_host_key
+
+or alternatively convert OpenSSH keys to Dropbear:
+./dropbearconvert openssh dropbear /etc/ssh/ssh_host_dsa_key dropbear_dss_host_key
+
+And you can now run the server.
+./dropbear
+
+or './dropbear -h' to get options.
+
+If the server is run as non-root, you most likely won't be able to allocate a
+pty, and you cannot login as any user other than that running the daemon
+(obviously). Shadow passwords will also be unusable as non-root.
+
+The Dropbear distribution includes a standalone version of OpenSSH's scp
+program. You can compile it with "make scp", you may want to change the path
+of the ssh binary, specified near the top of the scp.c file. By default
+the progress meter isn't compiled in to save space, you can enable it with
+"make scp-progress".
+
+============================================================================
+
+Compiling with uClibc:
+
+Firstly, make sure you have at least uclibc 0.9.17, as getusershell() in prior
+versions is broken. Also note that you may get strange issues if your uClibc
+headers don't match the library you are running with, ie the headers might
+say that shadow password support exists, but the libraries don't have it.
+
+To compile for uClibc the following should work:
+
+rm config.cache
+CC=i386-uclib-gcc ./configure --disable-zlib
+make clean
+make
+make strip
+
+... and that should be it. You can use "make static" to make statically linked 
+binaries, and it is advisable to strip the binaries too. If you're looking
+to make a small binary, you should remove unneeded ciphers and MD5, by 
+editing options.h
+
+It is possible to compile zlib in, by copying zlib.h and zconf.h into a
+subdirectory (ie zlibincludes), and 
+
+export CFLAGS="-Izlibincludes -I../zlibincludes"
+export LDFLAGS=/usr/lib/libz.a
+
+before ./configure and make.
+
+If you disable zlib, you must explicitly disable compression for the client -
+OpenSSH is possibly buggy in this regard, it seems you need to disable it
+globally in ~/.ssh/config, not just in the host entry in that file.
+
+You may want to manually disable lastlog recording when using uClibc, configure
+with --disable-lastlog.
+
+One common problem is pty allocation. There are a number of types of pty allocation which can be used -- if they work properly, the end result is the same for each type. Running configure should detect the best type to use automatically, however for some embedded systems, this may be incorrect. Some things to note:
+
+    If your system expects /dev/pts to be mounted (this is a uClibc option),
+	make sure that it is.
+
+	Make sure that your libc headers match the library version you are using.
+
+	If openpty() is being used (HAVE_OPENPTY defined in config.h) and it fails,
+	you can try compiling with --disable-openpty. You will probably then need
+	to create all the /dev/pty?? and /dev/tty?? devices, which can be
+	problematic for devfs. In general, openpty() is the best way to allocate
+	PTYs, so it's best to try and get it working.
+
+
+============================================================================
+
+Public key auth:
+
+You can use ~/.ssh/authorized_keys in the same way as with OpenSSH, just put
+the key entries in that file. They should be of the form:
+
+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAwVa6M6cGVmUcLl2cFzkxEoJd06Ub4bVDsYrWvXhvUV+ZAM9uGuewZBDoAqNKJxoIn0Hyd0Nk/yU99UVv6NWV/5YSHtnf35LKds56j7cuzoQpFIdjNwdxAN0PCET/MG8qyskG/2IE2DPNIaJ3Wy+Ws4IZEgdJgPlTYUBWWtCWOGc= someone@hostname
+
+You must make sure that ~/.ssh, and the key file, are only writable by the
+user.
+
+NOTE: Dropbear ignores authorized_keys options such as those described in the
+OpenSSH sshd manpage, and will not allow a login for these keys. 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LICENSE	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,82 @@
+The majority of code is written by Matt Johnston, under the following license:
+
+Copyright (c) 2002,2003 Matt Johnston
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+=====
+
+LibTomCrypt and LibTomMath are (c) Tom St Denis, under TDCAL (Tom Doesn't Care
+About Licenses) some files are from public domain sources, see
+libtomcrypt/legal.txt
+
+=====
+
+sshpty.c is taken from OpenSSH 3.5p1, 
+  Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
+                     All rights reserved
+ "As far as I am concerned, the code I have written for this software
+  can be used freely for any purpose.  Any derived versions of this
+  software must be clearly marked as such, and if the derived work is
+  incompatible with the protocol description in the RFC file, it must be
+  called by a name other than "ssh" or "Secure Shell". "
+
+=====
+
+loginrec.c
+loginrec.h
+atomicio.h
+atomicio.c
+and strlcat() (included in util.c) are from OpenSSH 3.6.1p2, and are licensed
+under the 2 point BSD license.
+
+loginrec is written primarily by Andre Lucas, atomicio.c by Theo de Raadt.
+
+strlcat() is (c) Todd C. Miller
+
+=====
+
+Import code in keyimport.c is modified from PuTTY's import.c, licensed as
+follows:
+
+PuTTY is copyright 1997-2003 Simon Tatham.
+
+Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+Justin Bradford, and CORE SDI S.A.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation files
+(the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MULTI	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,31 @@
+Multi-binary compilation
+========================
+
+To compile for systems without much space (floppy distributions etc), you
+can create a single binary. This will save disk space by avoiding repeated
+code between the three components (dropbear, dropbearkey, dropbearconvert).
+If you are familiar with "busybox", it's the same principle.
+
+To use the multi-purpose binary, firstly enable the "#define DROPBEAR_MULTI"
+line in options.h
+
+Then enable which of the binaries you want to compile, also in options.h
+(by default these are all enabled).
+
+You should then "make clean" (if you compiled previously), then
+
+"make dropbearmulti"
+
+("make dropbearmultistatic" will make a static binary).
+
+To use the binary, symlink it from the desired executable:
+
+ln -s dropbearmulti dropbear
+
+then execute as normal:
+
+./dropbear <options here>
+
+"make install" doesn't currently work for multi-binary configuration, however
+in most situations where it is being used, the target and build systems will
+differ.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile.in	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,164 @@
+LTC=libtomcrypt/libtomcrypt.a
+LTM=libtommath/libtommath.a
+
+COMMONOBJS=dbutil.o common-session.o common-packet.o common-algo.o buffer.o \
+		common-kex.o dss.o bignum.o \
+		signkey.o rsa.o random.o common-channel.o \
+		common-chansession.o queue.o termcodes.o runopts.o \
+		loginrec.o atomicio.o x11fwd.o agentfwd.o localtcpfwd.o compat.o \
+		remotetcpfwd.o tcpfwd.o
+
+SVROBJS=svr-kex.o svr-packet.o svr-algo.o svr-auth.o sshpty.o \
+		svr-authpasswd.o svr-authpubkey.o svr-session.o svr-service.o \
+		svr-chansession.o svr-runopts.o svr-agentfwd.o
+
+CLIOBJS=
+
+OBJS=$(COMMONOBJS) $(SVROBJS)
+
+DROPBEAROBJS=main.o
+
+DROPBEARKEYOBJS=dropbearkey.o gendss.o genrsa.o
+
+CONVERTOBJS=dropbearconvert.o keyimport.o
+
+SCPOBJS=scp.o progressmeter.o atomicio.o scpmisc.o
+
+HEADERS=options.h dbutil.h session.h packet.h algo.h ssh.h buffer.h kex.h \
+		dss.h bignum.h signkey.h rsa.h random.h service.h auth.h authpasswd.h \
+		debug.h channel.h chansession.h debug.h config.h queue.h sshpty.h \
+		termcodes.h gendss.h genrsa.h authpubkey.h runopts.h includes.h \
+		loginrec.h atomicio.h x11fwd.h agentfwd.h localtcpfwd.h compat.h \
+		remotetcpfwd.h tcpfwd.h
+
+ALLOBJS=$(OBJS) $(DROPBEARKEYOBJS) $(DROPBEAROBJS)
+
+prefix=@prefix@
+exec_prefix=${prefix}
+bindir=${exec_prefix}/bin
+sbindir=${exec_prefix}/sbin
+
+CC=@CC@
+LD=@CC@
+AR=@AR@
+RANLIB=@RANLIB@
+STRIP=@STRIP@
+INSTALL=@INSTALL@
+CFLAGS=-Ilibtomcrypt @CFLAGS@
+LIBS=$(LTC) $(LTM) @LIBS@
+LDFLAGS=@LDFLAGS@
+
+# these are exported so that libtomcrypt's makefile will use them
+export CC
+export CFLAGS
+export RANLIB AR STRIP
+
+all: dropbear dropbearkey dropbearconvert
+	@echo
+	@echo Run \"make strip\" if you want stripped binaries,
+	@echo or \"make install\" to install to ${prefix}
+
+strip:
+	-$(STRIP) dropbear
+	-$(STRIP) dropbearkey
+	-$(STRIP) dropbearconvert
+
+install: all
+	$(INSTALL) -d -m 755 $(DESTDIR)$(sbindir)
+	$(INSTALL) -d -m 755 $(DESTDIR)$(bindir)
+	$(INSTALL) -m 755 dropbear $(DESTDIR)$(sbindir)
+	$(INSTALL) -m 755 dropbearkey $(DESTDIR)$(bindir)
+	$(INSTALL) -m 755 dropbearconvert $(DESTDIR)$(bindir)
+	# chown might fail, so do it separately to the install
+	-chown root $(DESTDIR)$(sbindir)/dropbear
+	-chgrp 0 $(DESTDIR)$(sbindir)/dropbear
+	-chown root $(DESTDIR)$(bindir)/dropbearkey
+	-chgrp 0 $(DESTDIR)$(bindir)/dropbearkey
+	-chown root $(DESTDIR)$(bindir)/dropbearconvert
+	-chgrp 0 $(DESTDIR)$(bindir)/dropbearconvert
+
+
+static: dropbear-static dropbearkey-static dropbearconvert-static
+
+$(ALLOBJS): $(HEADERS) Makefile
+
+dropbear: $(DROPBEAROBJS) $(OBJS) $(HEADERS) Makefile $(LTC) $(LTM)
+	$(LD) $(LDFLAGS) -o dropbear $(DROPBEAROBJS) $(OBJS) $(LIBS)
+
+dropbear-static: $(DROPBEAROBJS) $(OBJS) $(HEADERS) Makefile  $(LTC) $(LTM)
+	$(LD) $(LDFLAGS) -o staticdropbear $(DROPBEAROBJS) $(OBJS) $(LIBS) -static
+
+dropbearkey: $(OBJS) $(HEADERS) Makefile $(DROPBEARKEYOBJS) $(LTC) $(LTM)
+	$(LD) $(LDFLAGS) -o dropbearkey $(DROPBEARKEYOBJS) \
+		$(OBJS) $(LIBS)
+
+dropbearkey-static: $(OBJS) $(HEADERS) Makefile $(DROPBEARKEYOBJS) $(LTC) $(LTM)
+	$(LD) $(LDFLAGS) -o staticdropbearkey $(DROPBEARKEYOBJS) \
+		$(OBJS) $(LIBS) -static
+
+dropbearconvert: $(OBJS) $(HEADERS) Makefile $(CONVERTOBJS) $(LTC) $(LTM)
+	$(LD) $(LDFLAGS) -o dropbearconvert $(CONVERTOBJS) $(OBJS) $(LIBS)
+
+dropbearconvert-static: $(OBJS) $(HEADERS) Makefile $(CONVERTOBJS) $(LTC) $(LTM)
+	$(LD) $(LDFLAGS) -o staticdropbearconvert $(CONVERTOBJS) $(OBJS) $(LIBS) \
+		-static
+
+multi: dropbearmulti
+
+dropbearmulti: $(HEADERS) $(OBJS) $(LTC) $(LTM) $(CONVERTOBJS) \
+				$(DROPBEARKEYOBJS) $(DROPBEAROBJS) dbmulti.o
+	$(LD) $(LDFLAGS) -o dropbearmulti $(OBJS) $(LTM) $(LTM) $(CONVERTOBJS) \
+			$(DROPBEARKEYOBJS) $(DROPBEAROBJS) dbmulti.o $(LIBS)
+	@echo "You should now create symlinks to the programs you have included"
+	@echo "ie 'ln -s dropbearmulti dropbear'"
+
+dropbearmultistatic: $(HEADERS) $(OBJS) $(LTC) $(LTM) $(CONVERTOBJS) \
+						$(DROPBEARKEYOBJS) $(DROPBEAROBJS) dbmulti.o
+	$(LD) $(LDFLAGS) -o staticdropbearmulti $(OBJS) $(LTM) $(LTM) \
+			$(CONVERTOBJS) $(DROPBEARKEYOBJS) $(DROPBEAROBJS) \
+			dbmulti.o $(LIBS) -static
+	@echo "You should now create symlinks to the programs you have included"
+	@echo "ie 'ln -s dropbearmultistatic dropbear'"
+
+stripmulti: dropbearmulti
+	-$(STRIP) dropbearmulti
+
+
+scp: $(SCPOBJS) Makefile
+	$(LD) $(LDFLAGS) -o $@ $(SCPOBJS)
+
+# gnumake before 3.80 is broken. So this is uglyish
+scp-progress: atomicio.o scpmisc.o $(HEADERS) Makefile
+	-rm scp.o progressmeter.o
+	$(MAKE) CFLAGS="$(CFLAGS) -DPROGRESS_METER" scp.o progressmeter.o
+	$(LD) $(LDFLAGS) -o $@ $(SCPOBJS)
+
+scpstatic: $(SCPOBJS) $(HEADERS) Makefile
+	$(LD) $(LDFLAGS) -o $@ $(SCPOBJS) -static
+
+$(LTC): $(HEADERS)
+	cd libtomcrypt && $(MAKE) clean && $(MAKE)
+
+$(LTM): $(HEADERS)
+	cd libtommath && $(MAKE)
+
+ltc-clean:
+	cd libtomcrypt && $(MAKE) clean
+
+ltm-clean:
+	cd libtommath && $(MAKE) clean
+
+sizes: dropbear
+	objdump -t dropbear|grep ".text"|cut -d "." -f 2|sort -rn
+
+clean: ltc-clean ltm-clean
+	-rm -f dropbear dropbear dropbearkey staticdropbear staticdropbearkey
+	-rm -f dropbearconvert staticdropbearconvert scp scp-progress scpstatic
+	-rm -f dropbearmulti dropbearmultistatic
+	-rm -f *.o *.da *.bb *.bbg *.prof 
+
+distclean: clean tidy
+	-rm -f Makefile config.h
+
+tidy:
+	-rm -f *~ *.gcov */*~
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,14 @@
+This is Dropbear, a smallish SSH 2 server.
+
+INSTALL has compilation instructions.
+
+MULTI has instructions on making a multi-purpose binary (ie a single binary
+which performs multiple tasks, to save disk space)
+
+SMALL has some tips on creating small binaries.
+
+See TODO for a few of the things I know need looking at, and please contact
+me if you have any questions/bugs found/features/ideas/comments etc :)
+
+Matt Johnston
[email protected]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SMALL	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,42 @@
+Tips for a small system:
+
+The following are set in options.h
+
+- You can safely disable blowfish and twofish ciphers, and MD5 hmac, without
+  affecting interoperability
+
+- If you're compiling statically, you can turn off host lookups
+
+- You can disable either password or public-key authentication, though note
+  that the IETF draft states that pubkey authentication is required.
+
+- Similarly with DSS and RSA, you can disable one of these if you know that
+  all clients will be able to support a particular one. The IETF draft
+  states that DSS is required, however you may prefer to use RSA. 
+  DON'T disable either of these on systems where you aren't 100% sure about
+  who will be connecting and what clients they will be using.
+
+- Disabling the MOTD code and SFTP-SERVER may save a small amount of codesize
+
+- You can disable x11, tcp and agent forwarding as desired. None of these are
+  essential, although agent-forwarding is often useful even on firewall boxes.
+
+If you are compiling statically, you may want to disable zlib, as it will use
+a few tens of kB of binary-size (./configure --disable-zlib).
+
+You can create a combined binary, see the file MULTI, which will put all
+the functions into one binary, avoiding repeated code.
+
+If you're compiling with gcc, you might want to look at gcc's options for
+stripping unused code. The relevant vars to set before configure are:
+
+LDFLAGS=-Wl,--gc-sections
+CFLAGS="-ffunction-sections -fdata-sections"
+
+You can also experiment with optimisation flags such as -Os, note that in some
+cases these flags actually seem to increase size, so experiment before
+deciding.
+
+Of course using small C libraries such as uClibc and dietlibc can also help.
+
+If you have any queries, mail me and I'll see if I can help.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TODO	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,27 @@
+Current:
+
+Things which need doing:
+
+- Make options.h generated from configure perhaps?
+
+- investigate self-pipe?
+- fix agent fwd problems
+- improve channel window adjustment algorithm (circular buffering)
+
+- Don't use pregenerated AES tables
+
+- check PRNG
+- check that there aren't timing issues with valid/invalid user authentication
+  feedback.
+
+- IP6 (binding to :: takes over ipv4 as well, sigh. If anyone wants to suggest
+  a clean way (ie no V4MAPPED or setsockopt things) please let me know :)
+- Binding to different interfaces (see ipv6 probably)
+
+- PAM ??
+- inetd
+- possible RSA blinding? need to check whether this is vuln to timing attacks
+- CTR mode, SSH_MSG_IGNORE sending to improve CBC security
+- DH Group Exchange possibly
+
+- fix scp.c for IRIX
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agentfwd.h	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,44 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+#ifndef _AGENTFWD_H_
+#define _AGENTFWD_H_
+#ifndef DISABLE_AGENTFWD
+
+#include "includes.h"
+#include "chansession.h"
+#include "channel.h"
+
+int agentreq(struct ChanSess * chansess);
+int agentaccept(struct ChanSess * chansess);
+void agentcleanup(struct ChanSess * chansess);
+void agentsetauth(struct ChanSess *chansess);
+void agentset(struct ChanSess *chansess);
+
+#ifdef __hpux
+#define seteuid(a)       setresuid(-1, (a), -1)
+#define setegid(a)       setresgid(-1, (a), -1)
+#endif
+
+#endif /* DROPBEAR_AGENTFWD */
+#endif /* _AGENTFWD_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/algo.h	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,75 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#ifndef _ALGO_H_
+
+#define _ALGO_H_
+
+#include "includes.h"
+#include "buffer.h"
+
+struct Algo_Type {
+
+	unsigned char *name; /* identifying name */
+	char val; /* a value for this cipher, or -1 for invalid */
+	void *data; /* algorithm specific data */
+	unsigned usable : 1; /* whether we can use this algorithm */
+
+};
+
+typedef struct Algo_Type algo_type;
+
+/* lists mapping ssh types of algorithms to internal values */
+extern algo_type sshkex[];
+extern algo_type sshhostkey[];
+extern algo_type sshciphers[];
+extern algo_type sshhashes[];
+extern algo_type sshcompress[];
+
+extern const struct dropbear_cipher dropbear_nocipher;
+extern const struct dropbear_hash dropbear_nohash;
+
+struct dropbear_cipher {
+	const struct _cipher_descriptor *cipherdesc;
+	unsigned long keysize;
+	unsigned char blocksize;
+};
+
+struct dropbear_hash {
+	const struct _hash_descriptor *hashdesc;
+	unsigned long keysize;
+	unsigned char hashsize;
+};
+
+void crypto_init();
+int have_algo(char* algo, size_t algolen, algo_type algos[]);
+void buf_put_algolist(buffer * buf, algo_type localalgos[]);
+
+algo_type * common_buf_match_algo(buffer* buf, algo_type localalgos[],
+		int *goodguess);
+algo_type * svr_buf_match_algo(buffer* buf, algo_type localalgos[],
+		int *goodguess);
+algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[]);
+
+#endif /* _ALGO_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atomicio.c	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,64 @@
+/*
+ * Copied from OpenSSH 3.6.1p2, required for loginrec.c
+ * 
+ * Copyright (c) 1995,1999 Theo de Raadt.  All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Taken from OpenSSH for use with the loginrec code */
+
+/* RCSID("$OpenBSD: atomicio.c,v 1.10 2001/05/08 22:48:07 markus Exp $"); */
+
+#include "atomicio.h"
+
+/*
+ * ensure all of data on socket comes through. f==read || f==write
+ */
+ssize_t
+atomicio(f, fd, _s, n)
+	ssize_t (*f) ();
+	int fd;
+	void *_s;
+	size_t n;
+{
+	char *s = _s;
+	ssize_t res, pos = 0;
+
+	while (n > pos) {
+		res = (f) (fd, s + pos, n - pos);
+		switch (res) {
+		case -1:
+#ifdef EWOULDBLOCK
+			if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
+#else
+			if (errno == EINTR || errno == EAGAIN)
+#endif
+				continue;
+		case 0:
+			return (res);
+		default:
+			pos += res;
+		}
+	}
+	return (pos);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/atomicio.h	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,36 @@
+
+/*
+ * Copied from OpenSSH 3.6.1p2, required for loginrec.c
+ *
+ * $OpenBSD: atomicio.h,v 1.4 2001/06/26 06:32:46 itojun Exp $
+ *
+ * Copyright (c) 1995,1999 Theo de Raadt.  All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+
+/*
+ * Ensure all of data on socket comes through. f==read || f==write
+ */
+ssize_t	atomicio(ssize_t (*)(), int, void *, size_t);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/auth.h	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,63 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#ifndef _AUTH_H_
+#define _AUTH_H_
+
+#include "includes.h"
+
+void authinitialise();
+
+void recv_msg_userauth_request();
+void send_msg_userauth_failure(int partial, int incrfail);
+void send_msg_userauth_success();
+
+#define MAX_USERNAME_LEN 25 /* arbitrary for the moment */
+
+#define AUTH_TYPE_PUBKEY	1 << 0
+#define AUTH_TYPE_PASSWORD	1 << 1
+
+/* auth types, "none" means we should return list of acceptable types */
+#define AUTH_METHOD_NONE	"none"
+#define AUTH_METHOD_NONE_LEN 4
+#define AUTH_METHOD_PUBKEY "publickey"
+#define AUTH_METHOD_PUBKEY_LEN 9
+#define AUTH_METHOD_PASSWORD "password"
+#define AUTH_METHOD_PASSWORD_LEN 8
+
+struct AuthState {
+
+	char *username; /* This is the username the client presents to check. It
+					   is updated each run through, used for auth checking */
+	char *printableuser; /* stripped of control chars, used for logs etc */
+	struct passwd * pw;
+	unsigned char authtypes; /* Flags indicating which auth types are still 
+								valid */
+	unsigned int failcount; /* Number of (failed) authentication attempts.*/
+	unsigned authdone : 1; /* 0 if we haven't authed, 1 if we have */
+
+
+};
+
+#endif /* _AUTH_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/authpasswd.h	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,33 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#ifndef _AUTH_PASSWD_
+#define _AUTH_PASSWD_
+
+#ifdef DROPBEAR_PASSWORD_AUTH
+
+void passwordauth();
+
+#endif /* DROPBEAR_PASSWORD_AUTH */
+#endif /* _AUTH_PASSWD_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/authpubkey.h	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,33 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#ifndef _PUBKEY_AUTH_
+#define _PUBKEY_AUTH_
+
+#ifdef DROPBEAR_PUBKEY_AUTH
+
+void pubkeyauth();
+
+#endif /* DROPBEAR_PUBKEY_AUTH */
+#endif /* _PUBKEY_AUTH_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bignum.c	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,94 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+/* Contains helper functions for mp_int handling */
+
+#include "includes.h"
+#include "dbutil.h"
+
+/* wrapper for mp_init, failing fatally on errors (memory allocation) */
+void m_mp_init(mp_int *mp) {
+
+	if (mp_init(mp) != MP_OKAY) {
+		dropbear_exit("mem alloc error");
+	}
+}
+
+/* simplified duplication of bn_mp_multi's mp_init_multi, but die fatally
+ * on error */
+void m_mp_init_multi(mp_int *mp, ...) 
+{
+    mp_int* cur_arg = mp;
+    va_list args;
+
+    va_start(args, mp);        /* init args to next argument from caller */
+    while (cur_arg != NULL) {
+        if (mp_init(cur_arg) != MP_OKAY) {
+			dropbear_exit("mem alloc error");
+        }
+        cur_arg = va_arg(args, mp_int*);
+    }
+    va_end(args);
+}
+
+/* convert an unsigned mp into an array of bytes, malloced.
+ * This array must be freed after use, len contains the length of the array,
+ * if len != NULL */
+unsigned char* mptobytes(mp_int *mp, int *len) {
+	
+	unsigned char* ret;
+	int size;
+
+	size = mp_unsigned_bin_size(mp);
+	ret = m_malloc(size);
+	if (mp_to_unsigned_bin(mp, ret) != MP_OKAY) {
+		dropbear_exit("mem alloc error");
+	}
+	if (len != NULL) {
+		*len = size;
+	}
+	return ret;
+}
+
+void bytestomp(mp_int *mp, unsigned char* bytes, unsigned int len) {
+
+	if (mp_read_unsigned_bin(mp, bytes, len) != MP_OKAY) {
+		dropbear_exit("mem alloc error");
+	}
+}
+
+/* hash the ssh representation of the mp_int mp */
+void sha1_process_mp(hash_state *hs, mp_int *mp) {
+
+	int i;
+	buffer * buf;
+
+	buf = buf_new(512 + 20); /* max buffer is a 4096 bit key, 
+								plus header + some leeway*/
+	buf_putmpint(buf, mp);
+	i = buf->pos;
+	buf_setpos(buf, 0);
+	sha1_process(hs, buf_getptr(buf, i), i);
+	buf_free(buf);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bignum.h	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,36 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#ifndef _BIGNUM_H_
+#define _BIGNUM_H_
+
+#include "includes.h"
+
+void m_mp_init(mp_int *mp);
+void m_mp_init_multi(mp_int *mp, ...);
+unsigned char* mptobytes(mp_int *mp, int *len);
+void bytestomp(mp_int *mp, unsigned char* bytes, unsigned int len);
+void sha1_process_mp(hash_state *hs, mp_int *mp);
+
+#endif /* _BIGNUM_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buffer.c	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,325 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+/* Buffer handling routines, designed to avoid overflows/using invalid data */
+
+#include "includes.h"
+#include "dbutil.h"
+#include "buffer.h"
+
+/* Prevent integer overflows when incrementing buffer position/length.
+ * Calling functions should check arguments first, but this provides a
+ * backstop */
+#define BUF_MAX_INCR 1000000000
+#define BUF_MAX_SIZE 1000000000
+
+/* avoid excessively large numbers, > 5000 bit */
+#define BUF_MAX_MPINT (5000 / 8)
+
+/* Create (malloc) a new buffer of size */
+buffer* buf_new(unsigned int size) {
+
+	buffer* buf;
+	
+	if (size > BUF_MAX_SIZE) {
+		dropbear_exit("buf->size too big");
+	}
+
+	buf = (buffer*)m_malloc(sizeof(buffer));
+
+	if (size > 0) {
+		buf->data = (unsigned char*)m_malloc(size);
+	} else {
+		buf->data = NULL;
+	}
+
+	buf->size = size;
+	buf->pos = 0;
+	buf->len = 0;
+
+	return buf;
+
+}
+
+/* free the buffer's data and the buffer itself */
+void buf_free(buffer* buf) {
+
+	m_free(buf->data)
+	m_free(buf);
+}
+
+/* overwrite the contents of the buffer to clear it */
+void buf_burn(buffer* buf) {
+	
+	m_burn(buf->data, buf->size);
+
+}
+
+/* resize a buffer, pos and len will be repositioned if required */
+void buf_resize(buffer *buf, unsigned int newsize) {
+
+	if (newsize > BUF_MAX_SIZE) {
+		dropbear_exit("buf->size too big");
+	}
+
+	buf->data = m_realloc(buf->data, newsize);
+	buf->size = newsize;
+	buf->len = MIN(newsize, buf->len);
+	buf->pos = MIN(newsize, buf->pos);
+
+}
+
+/* Create a copy of buf, allocating required memory etc. */
+/* The new buffer is sized the same as the length of the source buffer. */
+buffer* buf_newcopy(buffer* buf) {
+	
+	buffer* ret;
+
+	ret = buf_new(buf->len);
+	ret->len = buf->len;
+	memcpy(ret->data, buf->data, buf->len);
+	return ret;
+}
+
+/* Set the length of the buffer */
+void buf_setlen(buffer* buf, unsigned int len) {
+	if (len > buf->size) {
+		dropbear_exit("bad buf_setlen");
+	}
+	buf->len = len;
+}
+
+/* Increment the length of the buffer */
+void buf_incrlen(buffer* buf, unsigned int incr) {
+	if (incr > BUF_MAX_INCR || buf->len + incr > buf->size) {
+		dropbear_exit("bad buf_incrlen");
+	}
+	buf->len += incr;
+}
+/* Set the position of the buffer */
+void buf_setpos(buffer* buf, unsigned int pos) {
+
+	if (pos > buf->len) {
+		dropbear_exit("bad buf_setpos");
+	}
+	buf->pos = pos;
+}
+
+/* increment the postion by incr, increasing the buffer length if required */
+void buf_incrwritepos(buffer* buf, unsigned int incr) {
+	if (incr > BUF_MAX_INCR || buf->pos + incr > buf->size) {
+		dropbear_exit("bad buf_incrwritepos");
+	}
+	buf->pos += incr;
+	if (buf->pos > buf->len) {
+		buf->len = buf->pos;
+	}
+}
+
+/* increment the position by incr, negative values are allowed, to
+ * decrement the pos*/
+void buf_incrpos(buffer* buf,  int incr) {
+	if (incr > BUF_MAX_INCR ||
+			(unsigned int)((int)buf->pos + incr) > buf->len 
+			|| ((int)buf->pos + incr) < 0) {
+		dropbear_exit("bad buf_incrpos");
+	}
+	buf->pos += incr;
+}
+
+/* Get a byte from the buffer and increment the pos */
+unsigned char buf_getbyte(buffer* buf) {
+
+	if (buf->pos >= buf->len) {
+		dropbear_exit("bad buf_getbyte");
+	}
+	return buf->data[buf->pos++];
+}
+
+/* put a byte, incrementing the length if required */
+void buf_putbyte(buffer* buf, unsigned char val) {
+
+	if (buf->pos >= buf->len) {
+		buf_incrlen(buf, 1);
+	}
+	buf->data[buf->pos] = val;
+	buf->pos++;
+}
+
+/* returns an in-place pointer to the buffer, checking that
+ * the next len bytes from that position can be used */
+unsigned char* buf_getptr(buffer* buf, unsigned int len) {
+
+	if (buf->pos + len > buf->len) {
+		dropbear_exit("bad buf_getptr");
+	}
+	return &buf->data[buf->pos];
+}
+
+/* like buf_getptr, but checks against total size, not used length.
+ * This allows writing past the used length, but not past the size */
+unsigned char* buf_getwriteptr(buffer* buf, unsigned int len) {
+
+	if (buf->pos + len > buf->size) {
+		dropbear_exit("bad buf_getwriteptr");
+	}
+	return &buf->data[buf->pos];
+}
+
+/* Return a null-terminated string, it is malloced, so must be free()ed
+ * Note that the string isn't checked for null bytes, hence the retlen
+ * may be longer than what is returned by strlen */
+unsigned char* buf_getstring(buffer* buf, unsigned int *retlen) {
+
+	unsigned int len;
+	unsigned char* ret;
+	len = buf_getint(buf);
+	if (len > MAX_STRING_LEN) {
+		dropbear_exit("string too long");
+	}
+
+	if (retlen != NULL) {
+		*retlen = len;
+	}
+	ret = m_malloc(len+1);
+	memcpy(ret, buf_getptr(buf, len), len);
+	buf_incrpos(buf, len);
+	ret[len] = '\0';
+
+	return ret;
+}
+
+/* Just increment the buffer position the same as if we'd used buf_getstring,
+ * but don't bother copying/malloc()ing for it */
+void buf_eatstring(buffer *buf) {
+
+	buf_incrpos( buf, buf_getint(buf) );
+}
+
+/* Get an uint32 from the buffer and increment the pos */
+unsigned int buf_getint(buffer* buf) {
+	unsigned int ret;
+
+	LOAD32H(ret, buf_getptr(buf, 4));
+	buf_incrpos(buf, 4);
+	return ret;
+}
+
+/* put a 32bit uint into the buffer, incr bufferlen & pos if required */
+void buf_putint(buffer* buf, int unsigned val) {
+
+	STORE32H(val, buf_getwriteptr(buf, 4));
+	buf_incrwritepos(buf, 4);
+
+}
+
+/* put a SSH style string into the buffer, increasing buffer len if required */
+void buf_putstring(buffer* buf, const unsigned char* str, unsigned int len) {
+	
+	buf_putint(buf, len);
+	buf_putbytes(buf, str, len);
+
+}
+
+/* put the set of len bytes into the buffer, incrementing the pos, increasing
+ * len if required */
+void buf_putbytes(buffer *buf, const unsigned char *bytes, unsigned int len) {
+	memcpy(buf_getwriteptr(buf, len), bytes, len);
+	buf_incrwritepos(buf, len);
+}
+	
+
+/* for our purposes we only need positive (or 0) numbers, so will
+ * fail if we get negative numbers */
+void buf_putmpint(buffer* buf, mp_int * mp) {
+
+	unsigned int len, pad = 0;
+	TRACE(("enter buf_putmpint"));
+
+	assert(mp != NULL);
+
+	if (SIGN(mp) == MP_NEG) {
+		dropbear_exit("negative bignum");
+	}
+
+	/* zero check */
+	if (USED(mp) == 1 && DIGIT(mp, 0) == 0) {
+		len = 0;
+	} else {
+		/* SSH spec requires padding for mpints with the MSB set, this code
+		 * implements it */
+		len = mp_count_bits(mp);
+		/* if the top bit of MSB is set, we need to pad */
+		pad = (len%8 == 0) ? 1 : 0;
+		len = len / 8 + 1; /* don't worry about rounding, we need it for
+							  padding anyway when len%8 == 0 */
+
+	}
+
+	/* store the length */
+	buf_putint(buf, len);
+	
+	/* store the actual value */
+	if (len > 0) {
+		if (pad) {
+			buf_putbyte(buf, 0x00);
+		}
+		if (mp_to_unsigned_bin(mp, buf_getwriteptr(buf, len-pad)) != MP_OKAY) {
+			dropbear_exit("mpint error");
+		}
+		buf_incrwritepos(buf, len-pad);
+	}
+
+	TRACE(("leave buf_putmpint"));
+}
+
+/* Retrieve an mp_int from the buffer.
+ * Will fail for -ve since they shouldn't be required here.
+ * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
+int buf_getmpint(buffer* buf, mp_int* mp) {
+
+	unsigned int len;
+	len = buf_getint(buf);
+	
+	if (len == 0) {
+		mp_zero(mp);
+		return DROPBEAR_SUCCESS;
+	}
+
+	if (len > BUF_MAX_MPINT) {
+		return DROPBEAR_FAILURE;
+	}
+
+	/* check for negative */
+	if (*buf_getptr(buf, 1) & (1 << (CHAR_BIT-1))) {
+		return DROPBEAR_FAILURE;
+	}
+
+	if (mp_read_unsigned_bin(mp, buf_getptr(buf, len), len) != MP_OKAY) {
+		return DROPBEAR_FAILURE;
+	}
+
+	buf_incrpos(buf, len);
+	return DROPBEAR_SUCCESS;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buffer.h	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,65 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#ifndef _BUFFER_H_
+
+#define _BUFFER_H_
+
+#include "includes.h"
+
+struct buf {
+
+	unsigned char * data;
+	unsigned int len; /* the used size */
+	unsigned int pos;
+	unsigned int size; /* the memory size */
+
+};
+
+typedef struct buf buffer;
+
+buffer * buf_new(unsigned int size);
+void buf_resize(buffer *buf, unsigned int newsize);
+void buf_free(buffer* buf);
+void buf_burn(buffer* buf);
+buffer* buf_newcopy(buffer* buf);
+void buf_setlen(buffer* buf, unsigned int len);
+void buf_incrlen(buffer* buf, unsigned int incr);
+void buf_setpos(buffer* buf, unsigned int pos);
+void buf_incrpos(buffer* buf, int incr); /* -ve is ok, to go backwards */
+void buf_incrwritepos(buffer* buf, unsigned int incr);
+unsigned char buf_getbyte(buffer* buf);
+void buf_putbyte(buffer* buf, unsigned char val);
+unsigned char* buf_getptr(buffer* buf, unsigned int len);
+unsigned char* buf_getwriteptr(buffer* buf, unsigned int len);
+unsigned char* buf_getstring(buffer* buf, unsigned int *retlen);
+void buf_eatstring(buffer *buf);
+void buf_putint(buffer* buf, unsigned int val);
+void buf_putstring(buffer* buf, const unsigned char* str, unsigned int len);
+void buf_putbytes(buffer *buf, const unsigned char *bytes, unsigned int len);
+void buf_putmpint(buffer* buf, mp_int * mp);
+int buf_getmpint(buffer* buf, mp_int* mp);
+unsigned int buf_getint(buffer* buf);
+
+#endif /* _BUFFER_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/channel.h	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,122 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#ifndef _CHANNEL_H_
+#define _CHANNEL_H_
+
+#include "includes.h"
+#include "buffer.h"
+
+/* channel->type values */
+#define CHANNEL_ID_NONE 0
+#define CHANNEL_ID_SESSION 1
+#define CHANNEL_ID_X11 2
+#define CHANNEL_ID_AGENT 3
+#define CHANNEL_ID_TCPDIRECT 4
+#define CHANNEL_ID_TCPFORWARDED 5
+
+#define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED    1
+#define SSH_OPEN_CONNECT_FAILED                 2
+#define SSH_OPEN_UNKNOWN_CHANNEL_TYPE           3
+#define SSH_OPEN_RESOURCE_SHORTAGE              4
+
+#define MAX_CHANNELS 60 /* simple mem restriction, includes each tcp/x11
+							connection, so can't be _too_ small */
+
+#define CHAN_EXTEND_SIZE 3 /* how many extra slots to add when we need more */
+
+#define RECV_MAXWINDOW 6000 /* tweak */
+#define RECV_MAXPACKET 1400 /* tweak */
+#define RECV_MINWINDOW 19000 /* when we get below this, we send a windowadjust */
+
+/* a simpler way to define that we need code for listeners */
+#if !defined(DISABLE_X11FWD) || !defined(DISABLE_AUTHFWD) || \
+	!defined(DISABLE_REMOTETCPFWD)
+#define USE_LISTENERS
+#endif
+
+struct ChanType;
+
+struct Channel {
+
+	unsigned int index; /* the local channel index */
+	unsigned int remotechan;
+	unsigned int recvwindow, transwindow;
+	unsigned int recvmaxpacket, transmaxpacket;
+	void* typedata; /* a pointer to type specific data */
+	int infd; /* stdin for the program, we write to this */
+	int outfd; /* stdout for the program, we read from this */
+	int errfd; /* stdout for a program. This doesn't really fit here,
+				  but makes the code a lot tidyer without being too bad. This
+				  is -1 for channels which don't requre it. Currently only
+				  a 'session' without a pty will use it */
+	buffer *writebuf; /* data for the program */
+
+	int sentclosed, recvclosed;
+
+	/* this is set when we receive/send a channel eof packet */
+	int recveof, senteof;
+
+	int initconn; /* used for TCP forwarding, whether the channel has been
+					 fully initialised */
+
+	struct ChanType* type;
+
+};
+
+struct ChanType {
+
+	int sepfds; /* Whether this channel has seperate pipes for in/out or not */
+	char *name;
+	int (*inithandler)(struct Channel*);
+	int (*checkclose)(struct Channel*);
+	void (*reqhandler)(struct Channel*);
+	void (*closehandler)(struct Channel*);
+
+};
+
+void chaninitialise();
+void chancleanup();
+void setchannelfds(fd_set *readfd, fd_set *writefd);
+void channelio(fd_set *readfd, fd_set *writefd);
+struct Channel* newchannel(unsigned int remotechan, struct ChanType *type, 
+		unsigned int transwindow, unsigned int transmaxpacket);
+
+void recv_msg_channel_open();
+void recv_msg_channel_request();
+void send_msg_channel_failure(struct Channel *channel);
+void send_msg_channel_success(struct Channel *channel);
+void recv_msg_channel_data();
+void recv_msg_channel_window_adjust();
+void recv_msg_channel_close();
+void recv_msg_channel_eof();
+
+#ifdef USE_LISTENERS
+int send_msg_channel_open_init(int fd, struct ChanType *type,
+		const char * typestring);
+void recv_msg_channel_open_confirmation();
+void recv_msg_channel_open_failure();
+#endif
+
+#endif /* _CHANNEL_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/chansession.h	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,89 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#ifndef _CHANSESSION_H_
+#define _CHANSESSION_H_
+
+#include "loginrec.h"
+#include "channel.h"
+
+struct ChanSess {
+
+	unsigned char * cmd; /* command to exec */
+	pid_t pid; /* child process pid */
+
+	/* pty details */
+	int master; /* the master terminal fd*/
+	int slave;
+	unsigned char * tty;
+	unsigned char * term;
+	unsigned int termw, termh, termc, termr; /* width, height, col, rows */
+
+	/* exit details */
+	int exited;
+	int exitstatus;
+	int exitsignal;
+	unsigned char exitcore;
+	
+#ifndef DISABLE_X11FWD
+	int x11fd; /* set to -1 to indicate forwarding not established */
+	int x11port;
+	char * x11authprot;
+	char * x11authcookie;
+	unsigned int x11screennum;
+	unsigned char x11singleconn;
+#endif
+
+#ifndef DISABLE_AGENTFWD
+	int agentfd;
+	char * agentfile;
+	char * agentdir;
+#endif
+};
+
+struct ChildPid {
+	pid_t pid;
+	struct ChanSess * chansess;
+};
+
+
+void newchansess(struct Channel * channel);
+void chansessionrequest(struct Channel * channel);
+void closechansess(struct Channel * channel);
+void svr_chansessinitialise();
+void send_msg_chansess_exitstatus(struct Channel * channel,
+		struct ChanSess * chansess);
+void send_msg_chansess_exitsignal(struct Channel * channel,
+		struct ChanSess * chansess);
+void addnewvar(const char* param, const char* var);
+
+
+struct SigMap {
+	int signal;
+	char* name;
+};
+
+extern const struct SigMap signames[];
+
+#endif /* _CHANSESSION_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli_algo.c	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,92 @@
+/*
+ * Dropbear - a SSH2 server
+ * SSH client implementation
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * Copyright (c) 2004 by Mihnea Stoenescu
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#include "algo.h"
+#include "dbutil.h"
+
+
+/*
+ * The chosen [encryption | MAC | compression] algorithm to each 
+ * direction MUST be the first algorithm  on the client's list
+ * that is also on the server's list.
+ */
+algo_type * cli_buf_match_algo(buffer* buf, algo_type localalgos[]) {
+
+	unsigned char * algolist = NULL;
+	unsigned char * remotealgos[MAX_PROPOSED_ALGO];
+	unsigned int len;
+	unsigned int count, i, j;
+	algo_type * ret = NULL;
+
+	/* get the comma-separated list from the buffer ie "algo1,algo2,algo3" */
+	algolist = buf_getstring(buf, &len);
+	TRACE(("cli_buf_match_algo: %s", algolist));
+	if (len > MAX_PROPOSED_ALGO*(MAX_NAME_LEN+1)) {
+		goto out; /* just a sanity check, no other use */
+	}
+
+	/* remotealgos will contain a list of the strings parsed out */
+	/* We will have at least one string (even if it's just "") */
+	remotealgos[0] = algolist;
+	count = 1;
+	/* Iterate through, replacing ','s with NULs, to split it into
+	 * words. */
+	for (i = 0; i < len; i++) {
+		if (algolist[i] == '\0') {
+			/* someone is trying something strange */
+			goto out;
+		}
+		if (algolist[i] == ',') {
+			algolist[i] = '\0';
+			remotealgos[count] = &algolist[i+1];
+			count++;
+		}
+		if (count == MAX_PROPOSED_ALGO) {
+			break;
+		}
+	}
+
+	/* iterate and find the first match */
+
+	for (j = 0; localalgos[j].name != NULL; j++) {
+		if (localalgos[j].usable) {
+		len = strlen(localalgos[j].name);
+			for (i = 0; i < count; i++) {
+				if (len == strlen(remotealgos[i]) 
+						&& strncmp(localalgos[j].name, 
+							remotealgos[i], len) == 0) {
+					ret = &localalgos[j];
+					goto out;
+				}
+			}
+		}
+	}
+
+out:
+	m_free(algolist);
+	return ret;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common-algo.c	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,206 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#include "algo.h"
+#include "dbutil.h"
+
+/* This file (algo.c) organises the ciphers which can be used, and is used to
+ * decide which ciphers/hashes/compression/signing to use during key exchange*/
+
+/* Mappings for ciphers, parameters are
+   {&cipher_desc, keysize, blocksize} */
+
+#ifdef DROPBEAR_AES128_CBC
+const struct dropbear_cipher dropbear_aes128 = 
+	{&rijndael_desc, 16, 16};
+#endif
+#ifdef DROPBEAR_BLOWFISH_CBC
+const struct dropbear_cipher dropbear_blowfish = 
+	{&blowfish_desc, 16, 8};
+#endif
+#ifdef DROPBEAR_TWOFISH128_CBC
+const struct dropbear_cipher dropbear_twofish128 = 
+	{&twofish_desc, 16, 16};
+#endif
+#ifdef DROPBEAR_3DES_CBC
+const struct dropbear_cipher dropbear_3des = 
+	{&des3_desc, 24, 8};
+#endif
+
+/* used to indicate no encryption, as defined in rfc2410 */
+const struct dropbear_cipher dropbear_nocipher =
+	{NULL, 16, 8}; 
+
+/* Mapping of ssh hashes to libtomcrypt hashes, including keysize etc.
+   {&hash_desc, keysize, hashsize} */
+
+#ifdef DROPBEAR_SHA1_HMAC
+const struct dropbear_hash dropbear_sha1 = 
+	{&sha1_desc, 20, 20};
+#endif
+#ifdef DROPBEAR_MD5_HMAC
+const struct dropbear_hash dropbear_md5 = 
+	{&md5_desc, 16, 16};
+#endif
+
+const struct dropbear_hash dropbear_nohash =
+	{NULL, 16, 0}; /* used initially */
+	
+
+/* The following map ssh names to internal values */
+
+algo_type sshciphers[] = {
+#ifdef DROPBEAR_AES128_CBC
+	{"aes128-cbc", 0, (void*)&dropbear_aes128, 1},
+#endif
+#ifdef DROPBEAR_BLOWFISH_CBC
+	{"blowfish-cbc", 0, (void*)&dropbear_blowfish, 1},
+#endif
+#ifdef DROPBEAR_TWOFISH128_CBC
+	{"twofish-cbc", 0, (void*)&dropbear_twofish128, 1},
+#endif
+#ifdef DROPBEAR_3DES_CBC
+	{"3des-cbc", 0, (void*)&dropbear_3des, 1},
+#endif
+	{NULL, 0, NULL, 0}
+};
+
+algo_type sshhashes[] = {
+#ifdef DROPBEAR_SHA1_HMAC
+	{"hmac-sha1", 0, (void*)&dropbear_sha1, 1},
+#endif
+#ifdef DROPBEAR_MD5_HMAC
+	{"hmac-md5", 0, (void*)&dropbear_md5, 1},
+#endif
+	{NULL, 0, NULL, 0}
+};
+
+algo_type sshcompress[] = {
+	{"none", DROPBEAR_COMP_NONE, NULL, 1},
+#ifndef DISABLE_ZLIB
+	{"zlib", DROPBEAR_COMP_ZLIB, NULL, 1},
+#endif
+	{NULL, 0, NULL, 0}
+};
+
+algo_type sshhostkey[] = {
+#ifdef DROPBEAR_RSA
+	{"ssh-rsa", DROPBEAR_SIGNKEY_RSA, NULL, 1},
+#endif
+#ifdef DROPBEAR_DSS
+	{"ssh-dss", DROPBEAR_SIGNKEY_DSS, NULL, 1},
+#endif
+	{NULL, 0, NULL, 0}
+};
+
+algo_type sshkex[] = {
+	{"diffie-hellman-group1-sha1", DROPBEAR_KEX_DH_GROUP1, NULL, 1},
+	{NULL, 0, NULL, 0}
+};
+
+
+/* Register the compiled in ciphers.
+ * This should be run before using any of the ciphers/hashes */
+void crypto_init() {
+
+	const struct _cipher_descriptor *regciphers[] = {
+#ifdef DROPBEAR_AES128_CBC
+		&rijndael_desc,
+#endif
+#ifdef DROPBEAR_BLOWFISH_CBC
+		&blowfish_desc,
+#endif
+#ifdef DROPBEAR_TWOFISH128_CBC
+		&twofish_desc,
+#endif
+#ifdef DROPBEAR_3DES_CBC
+		&des3_desc,
+#endif
+		NULL
+	};
+
+	const struct _hash_descriptor *reghashes[] = {
+		/* we need sha1 for hostkey stuff regardless */
+		&sha1_desc,
+#ifdef DROPBEAR_MD5_HMAC
+		&md5_desc,
+#endif
+		NULL
+	};	
+	int i;
+	
+	for (i = 0; regciphers[i] != NULL; i++) {
+		if (register_cipher(regciphers[i]) == -1) {
+			dropbear_exit("error registering crypto");
+		}
+	}
+
+	for (i = 0; reghashes[i] != NULL; i++) {
+		if (register_hash(reghashes[i]) == -1) {
+			dropbear_exit("error registering crypto");
+		}
+	}
+}
+
+/* algolen specifies the length of algo, algos is our local list to match
+ * against.
+ * Returns DROPBEAR_SUCCESS if we have a match for algo, DROPBEAR_FAILURE
+ * otherwise */
+int have_algo(char* algo, size_t algolen, algo_type algos[]) {
+
+	int i;
+
+	for (i = 0; algos[i].name != NULL; i++) {
+		if (strlen(algos[i].name) == algolen
+				&& (strncmp(algos[i].name, algo, algolen) == 0)) {
+			return DROPBEAR_SUCCESS;
+		}
+	}
+
+	return DROPBEAR_FAILURE;
+}
+
+
+
+/* Output a comma separated list of algorithms to a buffer */
+void buf_put_algolist(buffer * buf, algo_type localalgos[]) {
+
+	unsigned int pos = 0, i, len;
+	char str[50]; /* enough for local algo storage */
+
+	for (i = 0; localalgos[i].name != NULL; i++) {
+		if (localalgos[i].usable) {
+			/* Avoid generating a trailing comma */
+			if (pos)
+			    str[pos++] = ',';
+			len = strlen(localalgos[i].name);
+			memcpy(&str[pos], localalgos[i].name, len);
+			pos += len;
+		}
+	}
+	str[pos]=0;
+	/* Debug this */
+	TRACE(("buf_put_algolist: %s", str));
+	buf_putstring(buf, str, pos);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common-channel.c	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,1008 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+/* Handle the multiplexed channels, such as sessions, x11, agent connections */
+
+#include "includes.h"
+#include "session.h"
+#include "packet.h"
+#include "ssh.h"
+#include "buffer.h"
+#include "dbutil.h"
+#include "channel.h"
+#include "ssh.h"
+#include "localtcpfwd.h"
+#include "remotetcpfwd.h"
+#include "tcpfwd.h"
+
+static void send_msg_channel_open_failure(unsigned int remotechan, int reason,
+		const unsigned char *text, const unsigned char *lang);
+static void send_msg_channel_open_confirmation(struct Channel* channel,
+		unsigned int recvwindow, 
+		unsigned int recvmaxpacket);
+static void writechannel(struct Channel *channel);
+static void send_msg_channel_window_adjust(struct Channel *channel, 
+		unsigned int incr);
+static void send_msg_channel_data(struct Channel *channel, int isextended,
+		unsigned int exttype);
+static void send_msg_channel_eof(struct Channel *channel);
+static void send_msg_channel_close(struct Channel *channel);
+static void removechannel(struct Channel *channel);
+static void deletechannel(struct Channel *channel);
+static void checkinitdone(struct Channel *channel);
+static void checkclose(struct Channel *channel);
+
+static void closeinfd(struct Channel * channel);
+static void closeoutfd(struct Channel * channel, int fd);
+static void closechanfd(struct Channel *channel, int fd, int how);
+
+#define FD_UNINIT (-2)
+#define FD_CLOSED (-1)
+
+/* Initialise all the channels */
+void chaninitialise(struct ChanType *chantypes[]) {
+
+	/* may as well create space for a single channel */
+	ses.channels = (struct Channel**)m_malloc(sizeof(struct Channel*));
+	ses.chansize = 1;
+	ses.channels[0] = NULL;
+
+	ses.chantypes = chantypes;
+
+#ifdef USING_TCP_LISTENERS
+	tcp_fwd_initialise();
+#endif
+
+}
+
+/* Clean up channels, freeing allocated memory */
+void chancleanup() {
+
+	unsigned int i;
+
+	TRACE(("enter chancleanup"));
+	for (i = 0; i < ses.chansize; i++) {
+		if (ses.channels[i] != NULL) {
+			TRACE(("channel %d closing", i));
+			removechannel(ses.channels[i]);
+		}
+	}
+	m_free(ses.channels);
+	TRACE(("leave chancleanup"));
+}
+
+/* Create a new channel entry, send a reply confirm or failure */
+/* If remotechan, transwindow and transmaxpacket are not know (for a new
+ * outgoing connection, with them to be filled on confirmation), they should
+ * all be set to 0 */
+struct Channel* newchannel(unsigned int remotechan, struct ChanType *type, 
+		unsigned int transwindow, unsigned int transmaxpacket) {
+
+	struct Channel * newchan;
+	unsigned int i, j;
+
+	TRACE(("enter newchannel"));
+	
+	/* first see if we can use existing channels */
+	for (i = 0; i < ses.chansize; i++) {
+		if (ses.channels[i] == NULL) {
+			break;
+		}
+	}
+
+	/* otherwise extend the list */
+	if (i == ses.chansize) {
+		if (ses.chansize >= MAX_CHANNELS) {
+			TRACE(("leave newchannel: max chans reached"));
+			return NULL;
+		}
+
+		/* extend the channels */
+		ses.channels = (struct Channel**)m_realloc(ses.channels,
+				(ses.chansize+CHAN_EXTEND_SIZE)*sizeof(struct Channel*));
+
+		ses.chansize += CHAN_EXTEND_SIZE;
+
+		/* set the new channels to null */
+		for (j = i; j < ses.chansize; j++) {
+			ses.channels[j] = NULL;
+		}
+
+	}
+	
+	newchan = (struct Channel*)m_malloc(sizeof(struct Channel));
+	newchan->type = type;
+	newchan->index = i;
+	newchan->sentclosed = newchan->recvclosed = 0;
+	newchan->senteof = newchan->recveof = 0;
+
+	newchan->remotechan = remotechan;
+	newchan->transwindow = transwindow;
+	newchan->transmaxpacket = transmaxpacket;
+	
+	newchan->typedata = NULL;
+	newchan->infd = FD_UNINIT;
+	newchan->outfd = FD_UNINIT;
+	newchan->errfd = FD_CLOSED; /* this isn't always set to start with */
+	newchan->initconn = 0;
+
+	newchan->writebuf = buf_new(RECV_MAXWINDOW);
+	newchan->recvwindow = RECV_MAXWINDOW;
+	newchan->recvmaxpacket = RECV_MAXPACKET;
+
+	ses.channels[i] = newchan;
+
+	TRACE(("leave newchannel"));
+
+	return newchan;
+}
+
+/* Get the channel structure corresponding to a channel number */
+static struct Channel* getchannel(unsigned int chan) {
+	if (chan >= ses.chansize || ses.channels[chan] == NULL) {
+		return NULL;
+	}
+	return ses.channels[chan];
+}
+
+/* Iterate through the channels, performing IO if available */
+void channelio(fd_set *readfd, fd_set *writefd) {
+
+	struct Channel *channel;
+	unsigned int i;
+
+	/* iterate through all the possible channels */
+	for (i = 0; i < ses.chansize; i++) {
+
+		channel = ses.channels[i];
+		if (channel == NULL) {
+			/* only process in-use channels */
+			continue;
+		}
+
+		/* read from program/pipe stdout */
+		if (channel->outfd >= 0 && FD_ISSET(channel->outfd, readfd)) {
+			send_msg_channel_data(channel, 0, 0);
+		}
+
+		/* read from program/pipe stderr */
+		if (channel->errfd >= 0 && FD_ISSET(channel->errfd, readfd)) {
+				send_msg_channel_data(channel, 1, SSH_EXTENDED_DATA_STDERR);
+		}
+
+		/* if we can read from the infd, it might be closed, so we try to
+		 * see if it has errors */
+		if (channel->infd >= 0 && channel->infd != channel->outfd
+				&& FD_ISSET(channel->infd, readfd)) {
+			int ret;
+			ret = write(channel->infd, NULL, 0);
+			if (ret < 0 && errno != EINTR && errno != EAGAIN) {
+				closeinfd(channel);
+			}
+		}
+
+		/* write to program/pipe stdin */
+		if (channel->infd >= 0 && FD_ISSET(channel->infd, writefd)) {
+			if (channel->initconn) {
+				checkinitdone(channel);
+				continue; /* Important not to use the channel after
+							 checkinitdone(), as it may be NULL */
+			} else {
+				writechannel(channel);
+			}
+		}
+	
+		/* now handle any of the channel-closing type stuff */
+		checkclose(channel);
+
+	} /* foreach channel */
+
+	/* Not channel specific */
+#ifdef USING_TCP_LISTENERS
+		handle_tcp_fwd(readfd);
+#endif
+}
+
+
+/* do all the EOF/close type stuff checking for a channel */
+static void checkclose(struct Channel *channel) {
+
+	if (!channel->sentclosed) {
+
+		/* check for exited - currently only used for server sessions,
+		 * if the shell has exited etc */
+		if (channel->type->checkclose) {
+			if (channel->type->checkclose(channel)) {
+				closeinfd(channel);
+			}
+		}
+
+		if (!channel->senteof
+			&& channel->outfd == FD_CLOSED 
+			&& channel->errfd == FD_CLOSED) {
+			send_msg_channel_eof(channel);
+		}
+
+		if (channel->infd == FD_CLOSED
+				&& channel->outfd == FD_CLOSED
+				&& channel->errfd == FD_CLOSED) {
+			send_msg_channel_close(channel);
+		}
+	}
+
+	/* When either party wishes to terminate the channel, it sends
+	 * SSH_MSG_CHANNEL_CLOSE.  Upon receiving this message, a party MUST
+	 * send back a SSH_MSG_CHANNEL_CLOSE unless it has already sent this
+	 * message for the channel.  The channel is considered closed for a
+	 * party when it has both sent and received SSH_MSG_CHANNEL_CLOSE, and
+	 * the party may then reuse the channel number.  A party MAY send
+	 * SSH_MSG_CHANNEL_CLOSE without having sent or received
+	 * SSH_MSG_CHANNEL_EOF. 
+	 * (from draft-ietf-secsh-connect)
+	 */
+	if (channel->recvclosed) {
+		if (! channel->sentclosed) {
+			TRACE(("Sending MSG_CHANNEL_CLOSE in response to same."));
+			send_msg_channel_close(channel);
+		}
+		removechannel(channel);
+	}
+}
+
+
+/* Check whether a deferred (EINPROGRESS) connect() was successful, and
+ * if so, set up the channel properly. Otherwise, the channel is cleaned up, so
+ * it is important that the channel reference isn't used after a call to this
+ * function */
+static void checkinitdone(struct Channel *channel) {
+
+	int val;
+	socklen_t vallen = sizeof(val);
+
+	TRACE(("enter checkinitdone"));
+
+	if (getsockopt(channel->infd, SOL_SOCKET, SO_ERROR, &val, &vallen)
+			|| val != 0) {
+		close(channel->infd);
+		deletechannel(channel);
+		TRACE(("leave checkinitdone: fail"));
+	} else {
+		channel->outfd = channel->infd;
+		channel->initconn = 0;
+		TRACE(("leave checkinitdone: success"));
+	}
+}
+
+
+
+/* Send the close message and set the channel as closed */
+static void send_msg_channel_close(struct Channel *channel) {
+
+	TRACE(("enter send_msg_channel_close"));
+	/* XXX server */
+	if (channel->type->closehandler) {
+		channel->type->closehandler(channel);
+	}
+#if 0
+	if (channel->type == CHANNEL_ID_SESSION) {
+		send_exitsignalstatus(channel);
+
+		closechansess(channel);
+	}
+#endif
+	
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_CLOSE);
+	buf_putint(ses.writepayload, channel->remotechan);
+
+	encrypt_packet();
+
+	channel->senteof = 1;
+	channel->sentclosed = 1;
+	TRACE(("leave send_msg_channel_close"));
+}
+
+/* call this when trans/eof channels are closed */
+static void send_msg_channel_eof(struct Channel *channel) {
+
+	TRACE(("enter send_msg_channel_eof"));
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_EOF);
+	buf_putint(ses.writepayload, channel->remotechan);
+
+	encrypt_packet();
+
+	channel->senteof = 1;
+
+	TRACE(("leave send_msg_channel_eof"));
+}
+
+/* Called to write data out to the server side of a channel (eg a shell or a
+ * program.
+ * Only called when we know we can write to a channel, writes as much as
+ * possible */
+static void writechannel(struct Channel* channel) {
+
+	int len, maxlen;
+	buffer *buf;
+
+	TRACE(("enter writechannel"));
+
+	buf = channel->writebuf;
+	maxlen = buf->len - buf->pos;
+
+	len = write(channel->infd, buf_getptr(buf, maxlen), maxlen);
+	if (len <= 0) {
+		if (len < 0 && errno != EINTR) {
+			/* no more to write */
+			closeinfd(channel);
+		}
+		TRACE(("leave writechannel: len <= 0"));
+		return;
+	}
+	
+	if (len == maxlen) {
+		buf_setpos(buf, 0);
+		buf_setlen(buf, 0);
+
+		if (channel->recveof) {
+			/* we're closing up */
+			closeinfd(channel);
+			return;
+			TRACE(("leave writechannel: recveof set"));
+		}
+
+		/* extend the window if we're at the end*/
+		/* TODO - this is inefficient */
+		send_msg_channel_window_adjust(channel, buf->size
+				- channel->recvwindow);
+		channel->recvwindow = buf->size;
+	} else {
+		buf_incrpos(buf, len);
+	}
+	TRACE(("leave writechannel"));
+}
+
+/* Set the file descriptors for the main select in session.c
+ * This avoid channels which don't have any window available, are closed, etc*/
+void setchannelfds(fd_set *readfd, fd_set *writefd) {
+	
+	unsigned int i;
+	struct Channel * channel;
+	
+	for (i = 0; i < ses.chansize; i++) {
+
+		channel = ses.channels[i];
+		if (channel == NULL) {
+			continue;
+		}
+
+		/* stdout and stderr */
+		if (channel->transwindow > 0) {
+
+			/* stdout */
+			if (channel->outfd >= 0) {
+				/* there's space to read more from the program */
+				FD_SET(channel->outfd, readfd);
+			}
+			/* stderr */
+			if (channel->errfd >= 0) {
+					FD_SET(channel->errfd, readfd);
+			}
+		}
+
+		if (channel->infd >= 0 && channel->infd != channel->outfd) {
+			FD_SET(channel->infd, readfd);
+		}
+
+		/* stdin */
+		if (channel->infd >= 0 &&
+				(channel->writebuf->pos < channel->writebuf->len ||
+				 channel->initconn)) {
+			/* there's space to write more to the program */
+			FD_SET(channel->infd, writefd);
+		}
+
+	} /* foreach channel */
+
+#ifdef USING_TCP_LISTENERS
+	set_tcp_fwd_fds(readfd);
+#endif
+
+}
+
+/* handle the channel EOF event, by closing the channel filedescriptor. The
+ * channel isn't closed yet, it is left until the incoming (from the program
+ * etc) FD is also EOF */
+void recv_msg_channel_eof() {
+
+	unsigned int chan;
+	struct Channel * channel;
+
+	TRACE(("enter recv_msg_channel_eof"));
+
+	chan = buf_getint(ses.payload);
+	channel = getchannel(chan);
+
+	if (channel == NULL) {
+		dropbear_exit("EOF for unknown channel");
+	}
+
+	channel->recveof = 1;
+	if (channel->writebuf->len == 0) {
+		closeinfd(channel);
+	}
+
+	TRACE(("leave recv_msg_channel_eof"));
+}
+
+
+/* Handle channel closure(), respond in kind and close the channels */
+void recv_msg_channel_close() {
+
+	unsigned int chan;
+	struct Channel * channel;
+
+	TRACE(("enter recv_msg_channel_close"));
+
+	chan = buf_getint(ses.payload);
+	TRACE(("close channel = %d", chan));
+	channel = getchannel(chan);
+
+	if (channel == NULL) {
+		/* disconnect ? */
+		dropbear_exit("Close for unknown channel");
+	}
+
+	channel->recveof = 1;
+	channel->recvclosed = 1;
+
+	if (channel->sentclosed) {
+		removechannel(channel);
+	}
+
+	TRACE(("leave recv_msg_channel_close"));
+}
+
+/* Remove a channel entry, this is only executed after both sides have sent
+ * channel close */
+static void removechannel(struct Channel * channel) {
+
+	TRACE(("enter removechannel"));
+	TRACE(("channel index is %d", channel->index));
+
+	buf_free(channel->writebuf);
+
+	/* close the FDs in case they haven't been done
+	 * yet (ie they were shutdown etc */
+	close(channel->infd);
+	close(channel->outfd);
+	if (channel->errfd >= 0) {
+		close(channel->errfd);
+	}
+
+	deletechannel(channel);
+
+	TRACE(("leave removechannel"));
+}
+
+/* Remove a channel entry */
+static void deletechannel(struct Channel *channel) {
+
+	ses.channels[channel->index] = NULL;
+	m_free(channel);
+	
+}
+
+
+/* Handle channel specific requests, passing off to corresponding handlers
+ * such as chansession or x11fwd */
+void recv_msg_channel_request() {
+
+	unsigned int chan;
+	struct Channel *channel;
+
+	TRACE(("enter recv_msg_channel_request"));
+	
+	chan = buf_getint(ses.payload);
+	channel = getchannel(chan);
+
+	if (channel == NULL) {
+		/* disconnect ? */
+		dropbear_exit("Unknown channel");
+	}
+
+	TRACE(("chan type is %d", channel->type));
+
+	if (channel->type->reqhandler) {
+		channel->type->reqhandler(channel);
+	} else {
+		send_msg_channel_failure(channel);
+	}
+
+#if 0
+	/* handle according to channel type */
+	switch (channel->type) {
+
+		case CHANNEL_ID_SESSION:
+			TRACE(("continue recv_msg_channel_request: session request"));
+			/* XXX server */
+			/* Here we need to do things channel-specific style. Function 
+			 * pointer callbacks perhaps */
+			chansessionrequest(channel);
+			break;
+
+		default:
+			send_msg_channel_failure(channel);
+	}
+#endif
+
+	TRACE(("leave recv_msg_channel_request"));
+
+}
+
+/* Reads data from the server's program/shell/etc, and puts it in a
+ * channel_data packet to send.
+ * chan is the remote channel, isextended is 0 if it is normal data, 1
+ * if it is extended data. if it is extended, then the type is in
+ * exttype */
+static void send_msg_channel_data(struct Channel *channel, int isextended,
+		unsigned int exttype) {
+
+	buffer *buf;
+	int len;
+	unsigned int maxlen;
+	int fd;
+
+/*	TRACE(("enter send_msg_channel_data"));
+	TRACE(("extended = %d type = %d", isextended, exttype));*/
+
+	CHECKCLEARTOWRITE();
+
+	assert(!channel->sentclosed);
+
+	if (isextended) {
+		fd = channel->errfd;
+	} else {
+		fd = channel->outfd;
+	}
+	assert(fd >= 0);
+
+	maxlen = MIN(channel->transwindow, channel->transmaxpacket);
+	/* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and 
+	 * exttype if is extended */
+	maxlen = MIN(maxlen, 
+			ses.writepayload->size - 1 - 4 - 4 - (isextended ? 4 : 0));
+	if (maxlen == 0) {
+		TRACE(("leave send_msg_channel_data: no window"));
+		return; /* the data will get written later */
+	}
+
+	/* read the data */
+	buf = buf_new(maxlen);
+	len = read(fd, buf_getwriteptr(buf, maxlen), maxlen);
+	if (len <= 0) {
+		/* on error/eof, send eof */
+		if (len == 0 || errno != EINTR) {
+			closeoutfd(channel, fd);
+			TRACE(("leave send_msg_channel_data: read err"));
+		}
+		buf_free(buf);
+		return;
+	}
+	buf_incrlen(buf, len);
+
+	buf_putbyte(ses.writepayload, 
+			isextended ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA);
+	buf_putint(ses.writepayload, channel->remotechan);
+
+	if (isextended) {
+		buf_putint(ses.writepayload, exttype);
+	}
+
+	buf_putstring(ses.writepayload, buf_getptr(buf, len), len);
+	buf_free(buf);
+
+	channel->transwindow -= len;
+
+	encrypt_packet();
+	TRACE(("leave send_msg_channel_data"));
+}
+
+
+/* when we receive channel data, put it in a buffer for writing to the program/
+ * shell etc */
+void recv_msg_channel_data() {
+
+	unsigned int chan;
+	struct Channel * channel;
+	unsigned int datalen;
+	unsigned int pos;
+	unsigned int maxdata;
+
+	TRACE(("enter recv_msg_channel_data"));
+	
+	chan = buf_getint(ses.payload);
+	channel = getchannel(chan);
+	if (channel == NULL) {
+		dropbear_exit("Unknown channel");
+	}
+
+	if (channel->recveof) {
+		dropbear_exit("received data after eof");
+	}
+
+ 	if (channel->infd < 0) {
+		dropbear_exit("received data with bad infd");
+	}
+
+	datalen = buf_getint(ses.payload);
+
+	/* if the client is going to send us more data than we've allocated, then 
+	 * it has ignored the windowsize, so we "MAY ignore all extra data" */
+	maxdata = channel->writebuf->size - channel->writebuf->pos;
+	if (datalen > maxdata) {
+		TRACE(("Warning: recv_msg_channel_data: extra data past window"));
+		datalen = maxdata;
+	}
+
+	/* write to the buffer - we always append to the end of the buffer */
+	pos = channel->writebuf->pos;
+	buf_setpos(channel->writebuf, channel->writebuf->len);
+	memcpy(buf_getwriteptr(channel->writebuf, datalen), 
+			buf_getptr(ses.payload, datalen), datalen);
+	buf_incrwritepos(channel->writebuf, datalen);
+	buf_setpos(channel->writebuf, pos); /* revert pos */
+
+	channel->recvwindow -= datalen;
+
+	/* matt - this might be for later */
+/*	if (channel->recvwindow < RECV_MINWINDOW) {
+		send_msg_channel_window_adjust(channel, 
+				RECV_MAXWINDOW - channel->recvwindow);
+		channel->recvwindow = RECV_MAXWINDOW;
+	}*/
+
+	TRACE(("leave recv_msg_channel_data"));
+}
+
+/* Increment the outgoing data window for a channel - the remote end limits
+ * the amount of data which may be transmitted, this window is decremented
+ * as data is sent, and incremented upon receiving window-adjust messages */
+void recv_msg_channel_window_adjust() {
+
+	unsigned int chan;
+	struct Channel * channel;
+	unsigned int incr;
+	
+	chan = buf_getint(ses.payload);
+	channel = getchannel(chan);
+
+	if (channel == NULL) {
+		dropbear_exit("Unknown channel");
+	}
+	
+	incr = buf_getint(ses.payload);
+	TRACE(("received window increment %d", incr));
+	incr = MIN(incr, MAX_TRANS_WIN_INCR);
+	
+	channel->transwindow += incr;
+	channel->transwindow = MIN(channel->transwindow, MAX_TRANS_WINDOW);
+
+}
+
+/* Increment the incoming data window for a channel, and let the remote
+ * end know */
+static void send_msg_channel_window_adjust(struct Channel* channel, 
+		unsigned int incr) {
+
+	TRACE(("sending window adjust %d", incr));
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_WINDOW_ADJUST);
+	buf_putint(ses.writepayload, channel->remotechan);
+	buf_putint(ses.writepayload, incr);
+
+	encrypt_packet();
+}
+	
+/* Handle a new channel request, performing any channel-type-specific setup */
+/* XXX server */
+void recv_msg_channel_open() {
+
+	unsigned char *type;
+	unsigned int typelen;
+	unsigned int remotechan, transwindow, transmaxpacket;
+	struct Channel *channel;
+	struct ChanType *chantype;
+	unsigned int errtype = SSH_OPEN_UNKNOWN_CHANNEL_TYPE;
+	int ret;
+
+
+	TRACE(("enter recv_msg_channel_open"));
+
+	/* get the packet contents */
+	type = buf_getstring(ses.payload, &typelen);
+
+	remotechan = buf_getint(ses.payload);
+	transwindow = buf_getint(ses.payload);
+	transwindow = MIN(transwindow, MAX_TRANS_WINDOW);
+	transmaxpacket = buf_getint(ses.payload);
+	transmaxpacket = MIN(transmaxpacket, MAX_TRANS_PAYLOAD_LEN);
+
+	/* figure what type of packet it is */
+	if (typelen > MAX_NAME_LEN) {
+		goto failure;
+	}
+
+	/* Get the channel type. This will depend if it is a client or a server,
+	 * so we iterate through the connection-specific list which was 
+	 * set up when the connection started */
+	for (chantype = ses.chantypes[0]; chantype != NULL; chantype++) {
+		if (strcmp(type, chantype->name) == 0) {
+			break;
+		}
+	}
+
+	if (chantype == NULL) {
+		goto failure;
+	}
+
+	/* create the channel */
+	channel = newchannel(remotechan, chantype, transwindow, transmaxpacket);
+
+	if (channel == NULL) {
+		goto failure;
+	}
+
+	if (channel->type->inithandler) {
+		ret = channel->type->inithandler(channel);
+		if (ret >= 0) {
+			errtype = ret;
+			deletechannel(channel);
+			goto failure;
+		}
+	}
+
+#if 0
+	/* type specific initialisation */
+	if (typeval == CHANNEL_ID_SESSION) {
+		newchansess(channel);
+#ifndef DISABLE_LOCALTCPFWD
+	} else if (typeval == CHANNEL_ID_TCPDIRECT) {
+		if (ses.opts->nolocaltcp) {
+			errtype = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
+		} else if (newtcpdirect(channel) == DROPBEAR_FAILURE) {
+			errtype = SSH_OPEN_CONNECT_FAILED;
+			deletechannel(channel);
+			goto failure;
+		}
+#endif
+	}
+#endif
+
+	/* success */
+	send_msg_channel_open_confirmation(channel, channel->recvwindow,
+			channel->recvmaxpacket);
+	goto cleanup;
+
+failure:
+	send_msg_channel_open_failure(remotechan, errtype, "", "");
+
+cleanup:
+	m_free(type);
+
+	TRACE(("leave recv_msg_channel_open"));
+}
+
+/* Send a failure message */
+void send_msg_channel_failure(struct Channel *channel) {
+
+	TRACE(("enter send_msg_channel_failure"));
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_FAILURE);
+	buf_putint(ses.writepayload, channel->remotechan);
+
+	encrypt_packet();
+	TRACE(("leave send_msg_channel_failure"));
+}
+
+/* Send a success message */
+void send_msg_channel_success(struct Channel *channel) {
+
+	TRACE(("enter send_msg_channel_success"));
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_SUCCESS);
+	buf_putint(ses.writepayload, channel->remotechan);
+
+	encrypt_packet();
+	TRACE(("leave send_msg_channel_success"));
+}
+
+/* Send a channel open failure message, with a corresponding reason
+ * code (usually resource shortage or unknown chan type) */
+static void send_msg_channel_open_failure(unsigned int remotechan, 
+		int reason, const unsigned char *text, const unsigned char *lang) {
+
+	TRACE(("enter send_msg_channel_open_failure"));
+	CHECKCLEARTOWRITE();
+	
+	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_FAILURE);
+	buf_putint(ses.writepayload, remotechan);
+	buf_putint(ses.writepayload, reason);
+	buf_putstring(ses.writepayload, text, strlen((char*)text));
+	buf_putstring(ses.writepayload, lang, strlen((char*)lang));
+
+	encrypt_packet();
+	TRACE(("leave send_msg_channel_open_failure"));
+}
+
+/* Confirm a channel open, and let the remote end know what number we've
+ * allocated and the receive parameters */
+static void send_msg_channel_open_confirmation(struct Channel* channel,
+		unsigned int recvwindow, 
+		unsigned int recvmaxpacket) {
+
+	TRACE(("enter send_msg_channel_open_confirmation"));
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
+	buf_putint(ses.writepayload, channel->remotechan);
+	buf_putint(ses.writepayload, channel->index);
+	buf_putint(ses.writepayload, recvwindow);
+	buf_putint(ses.writepayload, recvmaxpacket);
+
+	encrypt_packet();
+	TRACE(("leave send_msg_channel_open_confirmation"));
+}
+
+#ifdef USE_LISTENERS
+/* Create a new channel, and start the open request. This is intended
+ * for X11, agent, tcp forwarding, and should be filled with channel-specific
+ * options, with the calling function calling encrypt_packet() after
+ * completion. It is mandatory for the caller to encrypt_packet() if
+ * DROPBEAR_SUCCESS is returned */
+int send_msg_channel_open_init(int fd, struct ChanType *type,
+		const char * typestring) {
+
+	struct Channel* chan;
+
+	TRACE(("enter send_msg_channel_open_init()"));
+	chan = newchannel(0, type, 0, 0);
+	if (!chan) {
+		TRACE(("leave send_msg_channel_open_init() - FAILED in newchannel()"));
+		return DROPBEAR_FAILURE;
+	}
+
+	/* set fd non-blocking */
+	if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
+		TRACE(("leave send_msg_channel_open_init() - FAILED in fcntl()"));
+		return DROPBEAR_FAILURE;
+	}
+
+	chan->infd = chan->outfd = fd;
+	ses.maxfd = MAX(ses.maxfd, fd);
+
+	/* now open the channel connection */
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN);
+	buf_putstring(ses.writepayload, typestring, strlen(typestring));
+	buf_putint(ses.writepayload, chan->index);
+	buf_putint(ses.writepayload, RECV_MAXWINDOW);
+	buf_putint(ses.writepayload, RECV_MAXPACKET);
+
+	TRACE(("leave send_msg_channel_open_init()"));
+	return DROPBEAR_SUCCESS;
+}
+
+/* Confirmation that our channel open request (for forwardings) was 
+ * successful*/
+void recv_msg_channel_open_confirmation() {
+
+	unsigned int chan;
+	struct Channel * channel;
+
+	TRACE(("enter recv_msg_channel_open_confirmation"));
+	chan = buf_getint(ses.payload);
+
+	channel = getchannel(chan);
+	if (channel == NULL) {
+		dropbear_exit("Unknown channel");
+	}
+
+	channel->remotechan =  buf_getint(ses.payload);
+	channel->transwindow = buf_getint(ses.payload);
+	channel->transmaxpacket = buf_getint(ses.payload);
+
+	TRACE(("leave recv_msg_channel_open_confirmation"));
+}
+
+/* Notification that our channel open request failed */
+void recv_msg_channel_open_failure() {
+
+	unsigned int chan;
+	struct Channel * channel;
+	chan = buf_getbyte(ses.payload);
+
+	channel = getchannel(chan);
+	if (channel == NULL) {
+		dropbear_exit("Unknown channel");
+	}
+
+	removechannel(channel);
+}
+
+/* close a stdout/stderr fd */
+static void closeoutfd(struct Channel * channel, int fd) {
+
+	/* don't close it if it is the same as infd,
+	 * unless infd is already set -1 */
+	TRACE(("enter closeoutfd"));
+	closechanfd(channel, fd, 0);
+	TRACE(("leave closeoutfd"));
+}
+
+/* close a stdin fd */
+static void closeinfd(struct Channel * channel) {
+
+	TRACE(("enter closeinfd"));
+	closechanfd(channel, channel->infd, 1);
+	TRACE(("leave closeinfd"));
+}
+
+/* close a fd, how is 0 for stdout/stderr, 1 for stdin */
+static void closechanfd(struct Channel *channel, int fd, int how) {
+
+	int closein = 0, closeout = 0;
+
+	/* XXX server */
+	if (channel->type->sepfds) {
+		shutdown(fd, how);
+		if (how == 0) {
+			closeout = 1;
+		} else {
+			closein = 1;
+		}
+	} else {
+		close(fd);
+		closein = closeout = 1;
+	}
+
+	if (closeout && fd == channel->errfd) {
+		channel->errfd = FD_CLOSED;
+	}
+	if (closeout && fd == channel->outfd) {
+		channel->outfd = FD_CLOSED;
+	}
+	if (closein && fd == channel->infd) {
+		channel->infd = FD_CLOSED;
+	}
+}
+
+#endif /* USE_LISTENERS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common-chansession.c	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,43 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#include "chansession.h"
+
+/* Mapping of signal values to ssh signal strings */
+const extern struct SigMap signames[] = {
+	{SIGABRT, "ABRT"},
+	{SIGALRM, "ALRM"},
+	{SIGFPE, "FPE"},
+	{SIGHUP, "HUP"},
+	{SIGILL, "ILL"},
+	{SIGINT, "INT"},
+	{SIGKILL, "KILL"},
+	{SIGPIPE, "PIPE"},
+	{SIGQUIT, "QUIT"},
+	{SIGSEGV, "SEGV"},
+	{SIGTERM, "TERM"},
+	{SIGUSR1, "USR1"},
+	{SIGUSR2, "USR2"},
+	{0, NULL}
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common-kex.c	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,458 @@
+/*
+ * Dropbear - a SSH2 server
+ * SSH client implementation
+ *
+ * This code is copied from the larger file "kex.c" 
+ * some functions are verbatim, others are generalized --mihnea
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * Portions Copyright (c) 2004 by Mihnea Stoenescu
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#include "includes.h"
+#include "dbutil.h"
+#include "algo.h"
+#include "buffer.h"
+#include "session.h"
+#include "kex.h"
+#include "ssh.h"
+#include "packet.h"
+#include "bignum.h"
+#include "random.h"
+
+/* diffie-hellman-group1-sha1 value for p */
+const unsigned char dh_p_val[] = {
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
+    0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+	0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
+	0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+	0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
+	0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+	0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
+	0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+	0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
+	0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+const int DH_G_VAL = 2;
+
+static void gen_new_keys();
+#ifndef DISABLE_ZLIB
+static void gen_new_zstreams();
+#endif
+/* helper function for gen_new_keys */
+static void hashkeys(unsigned char *out, int outlen, 
+		const hash_state * hs, unsigned const char X);
+
+
+/* Send our list of algorithms we can use */
+void send_msg_kexinit() {
+
+	CHECKCLEARTOWRITE();
+	buf_putbyte(ses.writepayload, SSH_MSG_KEXINIT);
+
+	/* cookie */
+	genrandom(buf_getwriteptr(ses.writepayload, 16), 16);
+	buf_incrwritepos(ses.writepayload, 16);
+
+	/* kex algos */
+	buf_put_algolist(ses.writepayload, sshkex);
+
+	/* server_host_key_algorithms */
+	buf_put_algolist(ses.writepayload, sshhostkey);
+
+	/* encryption_algorithms_client_to_server */
+	buf_put_algolist(ses.writepayload, sshciphers);
+
+	/* encryption_algorithms_server_to_client */
+	buf_put_algolist(ses.writepayload, sshciphers);
+
+	/* mac_algorithms_client_to_server */
+	buf_put_algolist(ses.writepayload, sshhashes);
+
+	/* mac_algorithms_server_to_client */
+	buf_put_algolist(ses.writepayload, sshhashes);
+
+	/* compression_algorithms_client_to_server */
+	buf_put_algolist(ses.writepayload, sshcompress);
+
+	/* compression_algorithms_server_to_client */
+	buf_put_algolist(ses.writepayload, sshcompress);
+
+	/* languages_client_to_server */
+	buf_putstring(ses.writepayload, "", 0);
+
+	/* languages_server_to_client */
+	buf_putstring(ses.writepayload, "", 0);
+
+	/* first_kex_packet_follows - unimplemented for now */
+	buf_putbyte(ses.writepayload, 0x00);
+
+	/* reserved unit32 */
+	buf_putint(ses.writepayload, 0);
+
+	/* set up transmitted kex packet buffer for hashing. 
+	 * This is freed after the end of the kex */
+	ses.transkexinit = buf_newcopy(ses.writepayload);
+
+	encrypt_packet();
+	ses.dataallowed = 0; /* don't send other packets during kex */
+
+	TRACE(("DATAALLOWED=0"));
+	TRACE(("-> KEXINIT"));
+	ses.kexstate.sentkexinit = 1;
+}
+
+/* *** NOTE regarding (send|recv)_msg_newkeys *** 
+ * Changed by mihnea from the original kex.c to set dataallowed after a 
+ * completed key exchange, no matter the order in which it was performed.
+ * This enables client mode without affecting server functionality.
+ */
+
+/* Bring new keys into use after a key exchange, and let the client know*/
+void send_msg_newkeys() {
+
+	TRACE(("enter send_msg_newkeys"));
+
+	/* generate the kexinit request */
+	CHECKCLEARTOWRITE();
+	buf_putbyte(ses.writepayload, SSH_MSG_NEWKEYS);
+	encrypt_packet();
+	
+
+	/* set up our state */
+	if (ses.kexstate.recvnewkeys) {
+		TRACE(("while RECVNEWKEYS=1"));
+		gen_new_keys();
+		kexinitialise(); /* we've finished with this kex */
+		TRACE((" -> DATAALLOWED=1"));
+		ses.dataallowed = 1; /* we can send other packets again now */
+	} else {
+		ses.kexstate.sentnewkeys = 1;
+		TRACE(("SENTNEWKEYS=1"));
+	}
+
+	TRACE(("-> MSG_NEWKEYS"));
+	TRACE(("leave send_msg_newkeys"));
+}
+
+/* Bring the new keys into use after a key exchange */
+void recv_msg_newkeys() {
+
+	TRACE(("<- MSG_NEWKEYS"));
+	TRACE(("enter recv_msg_newkeys"));
+
+	/* simply check if we've sent SSH_MSG_NEWKEYS, and if so,
+	 * switch to the new keys */
+	if (ses.kexstate.sentnewkeys) {
+		TRACE(("while SENTNEWKEYS=1"));
+		gen_new_keys();
+		kexinitialise(); /* we've finished with this kex */
+	    TRACE((" -> DATAALLOWED=1"));
+	    ses.dataallowed = 1; /* we can send other packets again now */
+	} else {
+		TRACE(("RECVNEWKEYS=1"));
+		ses.kexstate.recvnewkeys = 1;
+	}
+	
+	TRACE(("leave recv_msg_newkeys"));
+}
+
+
+/* Duplicated verbatim from kex.c --mihnea */
+void kexinitialise() {
+
+	struct timeval tv;
+
+	TRACE(("kexinitialise()"));
+
+	/* sent/recv'd MSG_KEXINIT */
+	ses.kexstate.sentkexinit = 0;
+	ses.kexstate.recvkexinit = 0;
+
+	/* sent/recv'd MSG_NEWKEYS */
+	ses.kexstate.recvnewkeys = 0;
+	ses.kexstate.sentnewkeys = 0;
+
+	/* first_packet_follows */
+	/* TODO - currently not handled */
+	ses.kexstate.firstfollows = 0;
+
+	ses.kexstate.datatrans = 0;
+	ses.kexstate.datarecv = 0;
+
+	if (gettimeofday(&tv, 0) < 0) {
+		dropbear_exit("Error getting time");
+	}
+	ses.kexstate.lastkextime = tv.tv_sec;
+
+}
+
+/* Helper function for gen_new_keys, creates a hash. It makes a copy of the
+ * already initialised hash_state hs, which should already have processed
+ * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc.
+ * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated.
+ * The output will only be expanded once, since that is all that is required
+ * (for 3DES and SHA, with 24 and 20 bytes respectively). 
+ *
+ * See Section 5.2 of the IETF secsh Transport Draft for details */
+
+/* Duplicated verbatim from kex.c --mihnea */
+static void hashkeys(unsigned char *out, int outlen, 
+		const hash_state * hs, const unsigned char X) {
+
+	hash_state hs2;
+	unsigned char k2[SHA1_HASH_SIZE]; /* used to extending */
+
+	memcpy(&hs2, hs, sizeof(hash_state));
+	sha1_process(&hs2, &X, 1);
+	sha1_process(&hs2, ses.session_id, SHA1_HASH_SIZE);
+	sha1_done(&hs2, out);
+	if (SHA1_HASH_SIZE < outlen) {
+		/* need to extend */
+		memcpy(&hs2, hs, sizeof(hash_state));
+		sha1_process(&hs2, out, SHA1_HASH_SIZE);
+		sha1_done(&hs2, k2);
+		memcpy(&out[SHA1_HASH_SIZE], k2, outlen - SHA1_HASH_SIZE);
+	}
+}
+
+/* Generate the actual encryption/integrity keys, using the results of the
+ * key exchange, as specified in section 5.2 of the IETF secsh-transport
+ * draft. This occurs after the DH key-exchange.
+ *
+ * ses.newkeys is the new set of keys which are generated, these are only
+ * taken into use after both sides have sent a newkeys message */
+
+/* Originally from kex.c, generalized for cli/svr mode --mihnea */
+static void gen_new_keys() {
+
+	unsigned char C2S_IV[MAX_IV_LEN];
+	unsigned char C2S_key[MAX_KEY_LEN];
+	unsigned char S2C_IV[MAX_IV_LEN];
+	unsigned char S2C_key[MAX_KEY_LEN];
+	/* unsigned char key[MAX_KEY_LEN]; */
+	unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key;
+
+	hash_state hs;
+	unsigned int C2S_keysize, S2C_keysize;
+	char mactransletter, macrecvletter; /* Client or server specific */
+
+	TRACE(("enter gen_new_keys"));
+	/* the dh_K and hash are the start of all hashes, we make use of that */
+
+	sha1_init(&hs);
+	sha1_process_mp(&hs, ses.dh_K);
+	mp_clear(ses.dh_K);
+	m_free(ses.dh_K);
+	sha1_process(&hs, ses.hash, SHA1_HASH_SIZE);
+	m_burn(ses.hash, SHA1_HASH_SIZE);
+
+	hashkeys(C2S_IV, SHA1_HASH_SIZE, &hs, 'A');
+	hashkeys(S2C_IV, SHA1_HASH_SIZE, &hs, 'B');
+
+	if (IS_DROPBEAR_CLIENT) {
+	    trans_IV	= C2S_IV;
+	    recv_IV		= S2C_IV;
+	    trans_key	= C2S_key;
+	    recv_key	= S2C_key;
+	    C2S_keysize = ses.newkeys->trans_algo_crypt->keysize;
+	    S2C_keysize = ses.newkeys->recv_algo_crypt->keysize;
+		mactransletter = 'E';
+		macrecvletter = 'F';
+	} else {
+	    trans_IV	= S2C_IV;
+	    recv_IV		= C2S_IV;
+	    trans_key	= S2C_key;
+	    recv_key	= C2S_key;
+	    C2S_keysize = ses.newkeys->recv_algo_crypt->keysize;
+	    S2C_keysize = ses.newkeys->trans_algo_crypt->keysize;
+		mactransletter = 'F';
+		macrecvletter = 'E';
+	}
+
+	hashkeys(C2S_key, C2S_keysize, &hs, 'C');
+	hashkeys(S2C_key, S2C_keysize, &hs, 'D');
+
+	if (cbc_start(
+		find_cipher(ses.newkeys->recv_algo_crypt->cipherdesc->name),
+			recv_IV, recv_key, 
+			ses.newkeys->recv_algo_crypt->keysize, 0, 
+			&ses.newkeys->recv_symmetric_struct) != CRYPT_OK) {
+		dropbear_exit("crypto error");
+	}
+
+	if (cbc_start(
+		find_cipher(ses.newkeys->trans_algo_crypt->cipherdesc->name),
+			trans_IV, trans_key, 
+			ses.newkeys->trans_algo_crypt->keysize, 0, 
+			&ses.newkeys->trans_symmetric_struct) != CRYPT_OK) {
+		dropbear_exit("crypto error");
+	}
+	
+	/* MAC keys */
+	hashkeys(ses.newkeys->transmackey, 
+			ses.newkeys->trans_algo_mac->keysize, &hs, mactransletter);
+	hashkeys(ses.newkeys->recvmackey, 
+			ses.newkeys->recv_algo_mac->keysize, &hs, macrecvletter);
+
+#ifndef DISABLE_ZLIB
+	gen_new_zstreams();
+#endif
+	
+	/* Switch over to the new keys */
+	m_burn(ses.keys, sizeof(struct key_context));
+	m_free(ses.keys);
+	ses.keys = ses.newkeys;
+	ses.newkeys = NULL;
+
+	TRACE(("leave gen_new_keys"));
+}
+
+#ifndef DISABLE_ZLIB
+/* Set up new zlib compression streams, close the old ones. Only
+ * called from gen_new_keys() */
+static void gen_new_zstreams() {
+
+	/* create new zstreams */
+	if (ses.newkeys->recv_algo_comp == DROPBEAR_COMP_ZLIB) {
+		ses.newkeys->recv_zstream = (z_streamp)m_malloc(sizeof(z_stream));
+		ses.newkeys->recv_zstream->zalloc = Z_NULL;
+		ses.newkeys->recv_zstream->zfree = Z_NULL;
+		
+		if (inflateInit(ses.newkeys->recv_zstream) != Z_OK) {
+			dropbear_exit("zlib error");
+		}
+	} else {
+		ses.newkeys->recv_zstream = NULL;
+	}
+
+	if (ses.newkeys->trans_algo_comp == DROPBEAR_COMP_ZLIB) {
+		ses.newkeys->trans_zstream = (z_streamp)m_malloc(sizeof(z_stream));
+		ses.newkeys->trans_zstream->zalloc = Z_NULL;
+		ses.newkeys->trans_zstream->zfree = Z_NULL;
+	
+		if (deflateInit(ses.newkeys->trans_zstream, Z_DEFAULT_COMPRESSION) 
+				!= Z_OK) {
+			dropbear_exit("zlib error");
+		}
+	} else {
+		ses.newkeys->trans_zstream = NULL;
+	}
+	
+	/* clean up old keys */
+	if (ses.keys->recv_zstream != NULL) {
+		if (inflateEnd(ses.keys->recv_zstream) == Z_STREAM_ERROR) {
+			/* Z_DATA_ERROR is ok, just means that stream isn't ended */
+			dropbear_exit("crypto error");
+		}
+		m_free(ses.keys->recv_zstream);
+	}
+	if (ses.keys->trans_zstream != NULL) {
+		if (deflateEnd(ses.keys->trans_zstream) == Z_STREAM_ERROR) {
+			/* Z_DATA_ERROR is ok, just means that stream isn't ended */
+			dropbear_exit("crypto error");
+		}
+		m_free(ses.keys->trans_zstream);
+	}
+}
+#endif
+
+
+/* Executed upon receiving a kexinit message from the client to initiate
+ * key exchange. If we haven't already done so, we send the list of our
+ * preferred algorithms. The client's requested algorithms are processed,
+ * and we calculate the first portion of the key-exchange-hash for used
+ * later in the key exchange. No response is sent, as the client should
+ * initiate the diffie-hellman key exchange */
+
+/* Originally from kex.c, generalized for cli/svr mode --mihnea  */
+/* Belongs in common_kex.c where it should be moved after review */
+void recv_msg_kexinit() {
+	
+	TRACE(("<- KEXINIT"));
+	TRACE(("enter recv_msg_kexinit"));
+	
+	/* start the kex hash */
+	ses.kexhashbuf = buf_new(MAX_KEXHASHBUF);
+
+	if (!ses.kexstate.sentkexinit) {
+		/* we need to send a kex packet */
+		send_msg_kexinit();
+		TRACE(("continue recv_msg_kexinit: sent kexinit"));
+	}
+
+
+	if (IS_DROPBEAR_CLIENT) {
+
+	/* read the peer's choice of algos */
+		cli_read_kex();
+
+	/* V_C, the client's version string (CR and NL excluded) */
+	    buf_putstring(ses.kexhashbuf,
+			(unsigned char*)LOCAL_IDENT, strlen(LOCAL_IDENT));
+	/* V_S, the server's version string (CR and NL excluded) */
+	    buf_putstring(ses.kexhashbuf, 
+			ses.remoteident, strlen((char*)ses.remoteident));
+
+	/* I_C, the payload of the client's SSH_MSG_KEXINIT */
+	    buf_putstring(ses.kexhashbuf,
+			buf_getptr(ses.transkexinit, ses.transkexinit->len),
+			ses.transkexinit->len);
+	/* I_S, the payload of the server's SSH_MSG_KEXINIT */
+	    buf_setpos(ses.payload, 0);
+	    buf_putstring(ses.kexhashbuf,
+			buf_getptr(ses.payload, ses.payload->len),
+			ses.payload->len);
+
+	} else {
+
+	/* read the peer's choice of algos */
+		svr_read_kex();
+	/* V_C, the client's version string (CR and NL excluded) */
+	    buf_putstring(ses.kexhashbuf, 
+			ses.remoteident, strlen((char*)ses.remoteident));
+	/* V_S, the server's version string (CR and NL excluded) */
+	    buf_putstring(ses.kexhashbuf,
+			(unsigned char*)LOCAL_IDENT, strlen(LOCAL_IDENT));
+
+	/* I_C, the payload of the client's SSH_MSG_KEXINIT */
+	    buf_setpos(ses.payload, 0);
+	    buf_putstring(ses.kexhashbuf,
+			buf_getptr(ses.payload, ses.payload->len),
+			ses.payload->len);
+	/* I_S, the payload of the server's SSH_MSG_KEXINIT */
+	    buf_putstring(ses.kexhashbuf,
+			buf_getptr(ses.transkexinit, ses.transkexinit->len),
+			ses.transkexinit->len);
+	}
+
+	buf_free(ses.transkexinit);
+	ses.transkexinit = NULL;
+	/* the rest of ses.kexhashbuf will be done after DH exchange */
+
+	ses.kexstate.recvkexinit = 1;
+//	ses.expecting = SSH_MSG_KEXDH_INIT;
+	ses.expecting = 0;
+
+	TRACE(("leave recv_msg_kexinit"));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common-packet.c	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,620 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#include "includes.h"
+#include "packet.h"
+#include "session.h"
+#include "dbutil.h"
+#include "ssh.h"
+#include "algo.h"
+#include "buffer.h"
+#include "kex.h"
+#include "random.h"
+#include "service.h"
+#include "auth.h"
+#include "channel.h"
+
+static void read_packet_init();
+static void writemac(buffer * outputbuffer, buffer * clearwritebuf);
+static int checkmac(buffer* hashbuf, buffer* readbuf);
+
+#define ZLIB_COMPRESS_INCR 20 /* this is 12 bytes + 0.1% of 8000 bytes */
+#define ZLIB_DECOMPRESS_INCR 100
+#ifndef DISABLE_ZLIB
+static buffer* buf_decompress(buffer* buf, unsigned int len);
+static void buf_compress(buffer * dest, buffer * src, unsigned int len);
+#endif
+
+/* non-blocking function writing out a current encrypted packet */
+void write_packet() {
+
+	int len, written;
+	buffer * writebuf;
+	
+	TRACE(("enter write_packet"));
+	assert(!isempty(&ses.writequeue));
+
+	/* Get the next buffer in the queue of encrypted packets to write*/
+	writebuf = (buffer*)examine(&ses.writequeue);
+
+	len = writebuf->len - writebuf->pos;
+	assert(len > 0);
+	/* Try to write as much as possible */
+	written = write(ses.sock, buf_getptr(writebuf, len), len);
+
+	if (written < 0) {
+		if (errno == EINTR) {
+			TRACE(("leave writepacket: EINTR"));
+			return;
+		} else {
+			dropbear_exit("error writing");
+		}
+	} 
+
+	if (written == 0) {
+		session_remoteclosed();
+	}
+
+	if (written == len) {
+		/* We've finished with the packet, free it */
+		dequeue(&ses.writequeue);
+		buf_free(writebuf);
+	} else {
+		/* More packet left to write, leave it in the queue for later */
+		buf_incrpos(writebuf, written);
+	}
+
+	TRACE(("leave write_packet"));
+}
+
+/* Non-blocking function reading available portion of a packet into the
+ * ses's buffer, decrypting the length if encrypted, decrypting the
+ * full portion if possible */
+void read_packet() {
+
+	int len;
+	unsigned int maxlen;
+	unsigned char blocksize;
+
+	TRACE(("enter read_packet"));
+	blocksize = ses.keys->recv_algo_crypt->blocksize;
+	
+	if (ses.readbuf == NULL || ses.readbuf->len < blocksize) {
+		/* In the first blocksize of a packet */
+
+		/* Read the first blocksize of the packet, so we can decrypt it and
+		 * find the length of the whole packet */
+		read_packet_init();
+
+		/* If we don't have the length of decryptreadbuf, we didn't read
+		 * a whole blocksize and should exit */
+		if (ses.decryptreadbuf->len == 0) {
+			TRACE(("leave read_packet: packetinit done"));
+			return;
+		}
+	}
+
+	/* Attempt to read the remainder of the packet, note that there
+	 * mightn't be any available (EAGAIN) */
+	assert(ses.readbuf != NULL);
+	maxlen = ses.readbuf->len - ses.readbuf->pos;
+	len = read(ses.sock, buf_getptr(ses.readbuf, maxlen), maxlen);
+
+	if (len == 0) {
+		session_remoteclosed();
+	}
+
+	if (len < 0) {
+		if (errno == EINTR || errno == EAGAIN) {
+			TRACE(("leave read_packet: EINTR or EAGAIN"));
+			return;
+		} else {
+			dropbear_exit("error reading: %s", strerror(errno));
+		}
+	}
+
+	buf_incrpos(ses.readbuf, len);
+
+	if ((unsigned int)len == maxlen) {
+		/* The whole packet has been read */
+		decrypt_packet();
+		/* The main select() loop process_packet() to
+		 * handle the packet contents... */
+	}
+	TRACE(("leave read_packet"));
+}
+
+/* Function used to read the initial portion of a packet, and determine the
+ * length. Only called during the first BLOCKSIZE of a packet. */
+static void read_packet_init() {
+
+	unsigned int maxlen;
+	int len;
+	unsigned char blocksize;
+	unsigned char macsize;
+
+
+	blocksize = ses.keys->recv_algo_crypt->blocksize;
+	macsize = ses.keys->recv_algo_mac->hashsize;
+
+	if (ses.readbuf == NULL) {
+		/* start of a new packet */
+		ses.readbuf = buf_new(INIT_READBUF);
+		assert(ses.decryptreadbuf == NULL);
+		ses.decryptreadbuf = buf_new(blocksize);
+	}
+
+	maxlen = blocksize - ses.readbuf->pos;
+			
+	/* read the rest of the packet if possible */
+	len = read(ses.sock, buf_getwriteptr(ses.readbuf, maxlen),
+			maxlen);
+	if (len == 0) {
+		session_remoteclosed();
+	}
+	if (len < 0) {
+		if (errno == EINTR) {
+			TRACE(("leave read_packet_init: EINTR"));
+			return;
+		}
+		dropbear_exit("error reading: %s", strerror(errno));
+	}
+
+	buf_incrwritepos(ses.readbuf, len);
+
+	if ((unsigned int)len != maxlen) {
+		/* don't have enough bytes to determine length, get next time */
+		return;
+	}
+
+	/* now we have the first block, need to get packet length, so we decrypt
+	 * the first block (only need first 4 bytes) */
+	buf_setpos(ses.readbuf, 0);
+	if (ses.keys->recv_algo_crypt->cipherdesc == NULL) {
+		/* copy it */
+		memcpy(buf_getwriteptr(ses.decryptreadbuf, blocksize),
+				buf_getptr(ses.readbuf, blocksize),
+				blocksize);
+	} else {
+		/* decrypt it */
+		if (cbc_decrypt(buf_getptr(ses.readbuf, blocksize), 
+					buf_getwriteptr(ses.decryptreadbuf,blocksize),
+					&ses.keys->recv_symmetric_struct) != CRYPT_OK) {
+			dropbear_exit("error decrypting");
+		}
+	}
+	buf_setlen(ses.decryptreadbuf, blocksize);
+	len = buf_getint(ses.decryptreadbuf) + 4 + macsize;
+
+	buf_setpos(ses.readbuf, blocksize);
+
+	/* check packet length */
+	if ((len > MAX_PACKET_LEN) ||
+		(len < MIN_PACKET_LEN + macsize) ||
+		((len - macsize) % blocksize != 0)) {
+		dropbear_exit("bad packet size");
+	}
+
+	buf_resize(ses.readbuf, len);
+	buf_setlen(ses.readbuf, len);
+
+}
+
+/* handle the received packet */
+void decrypt_packet() {
+
+	unsigned char blocksize;
+	unsigned char macsize;
+	unsigned int padlen;
+	unsigned int len;
+
+	TRACE(("enter decrypt_packet"));
+	blocksize = ses.keys->recv_algo_crypt->blocksize;
+	macsize = ses.keys->recv_algo_mac->hashsize;
+
+	ses.kexstate.datarecv += ses.readbuf->len;
+
+	/* we've already decrypted the first blocksize in read_packet_init */
+	buf_setpos(ses.readbuf, blocksize);
+
+	buf_resize(ses.decryptreadbuf, ses.readbuf->len - macsize);
+	buf_setlen(ses.decryptreadbuf, ses.decryptreadbuf->size);
+	buf_setpos(ses.decryptreadbuf, blocksize);
+
+	/* decrypt if encryption is set, memcpy otherwise */
+	if (ses.keys->recv_algo_crypt->cipherdesc == NULL) {
+		/* copy it */
+		len = ses.readbuf->len - macsize - blocksize;
+		memcpy(buf_getwriteptr(ses.decryptreadbuf, len),
+				buf_getptr(ses.readbuf, len), len);
+	} else {
+		/* decrypt */
+		while (ses.readbuf->pos < ses.readbuf->len - macsize) {
+			if (cbc_decrypt(buf_getptr(ses.readbuf, blocksize), 
+						buf_getwriteptr(ses.decryptreadbuf, blocksize),
+						&ses.keys->recv_symmetric_struct) != CRYPT_OK) {
+				dropbear_exit("error decrypting");
+			}
+			buf_incrpos(ses.readbuf, blocksize);
+			buf_incrwritepos(ses.decryptreadbuf, blocksize);
+		}
+	}
+
+	/* check the hmac */
+	buf_setpos(ses.readbuf, ses.readbuf->len - macsize);
+	if (checkmac(ses.readbuf, ses.decryptreadbuf) != DROPBEAR_SUCCESS) {
+		dropbear_exit("Integrity error");
+	}
+
+	/* readbuf no longer required */
+	buf_free(ses.readbuf);
+	ses.readbuf = NULL;
+
+	/* get padding length */
+	buf_setpos(ses.decryptreadbuf, PACKET_PADDING_OFF);
+	padlen = buf_getbyte(ses.decryptreadbuf);
+		
+	/* payload length */
+	/* - 4 - 1 is for LEN and PADLEN values */
+	len = ses.decryptreadbuf->len - padlen - 4 - 1;
+	if ((len > MAX_PAYLOAD_LEN) || (len < 1)) {
+		dropbear_exit("bad packet size");
+	}
+
+	buf_setpos(ses.decryptreadbuf, PACKET_PAYLOAD_OFF);
+
+#ifndef DISABLE_ZLIB
+	if (ses.keys->recv_algo_comp == DROPBEAR_COMP_ZLIB) {
+		/* decompress */
+		ses.payload = buf_decompress(ses.decryptreadbuf, len);
+
+	} else 
+#endif
+	{
+		/* copy payload */
+		ses.payload = buf_new(len);
+		memcpy(ses.payload->data, buf_getptr(ses.decryptreadbuf, len), len);
+		buf_incrlen(ses.payload, len);
+	}
+
+	buf_free(ses.decryptreadbuf);
+	ses.decryptreadbuf = NULL;
+	buf_setpos(ses.payload, 0);
+
+	ses.recvseq++;
+
+	TRACE(("leave decrypt_packet"));
+}
+
+/* Checks the mac in hashbuf, for the data in readbuf.
+ * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
+static int checkmac(buffer* macbuf, buffer* sourcebuf) {
+
+	unsigned char macsize;
+	hmac_state hmac;
+	unsigned char tempbuf[MAX_MAC_LEN];
+	unsigned long hashsize;
+	int len;
+
+	macsize = ses.keys->recv_algo_mac->hashsize;
+
+	if (macsize == 0) {
+		return DROPBEAR_SUCCESS;
+	}
+
+	/* calculate the mac */
+	if (hmac_init(&hmac, 
+				find_hash(ses.keys->recv_algo_mac->hashdesc->name), 
+				ses.keys->recvmackey, 
+				ses.keys->recv_algo_mac->keysize) 
+				!= CRYPT_OK) {
+		dropbear_exit("HMAC error");
+	}
+	
+	/* sequence number */
+	STORE32H(ses.recvseq, tempbuf);
+	if (hmac_process(&hmac, tempbuf, 4) != CRYPT_OK) {
+		dropbear_exit("HMAC error");
+	}
+
+	buf_setpos(sourcebuf, 0);
+	len = sourcebuf->len;
+	if (hmac_process(&hmac, buf_getptr(sourcebuf, len), len) != CRYPT_OK) {
+		dropbear_exit("HMAC error");
+	}
+
+	hashsize = sizeof(tempbuf);
+	if (hmac_done(&hmac, tempbuf, &hashsize) != CRYPT_OK) {
+		dropbear_exit("HMAC error");
+	}
+
+	/* compare the hash */
+	if (memcmp(tempbuf, buf_getptr(macbuf, macsize), macsize) != 0) {
+		return DROPBEAR_FAILURE;
+	} else {
+		return DROPBEAR_SUCCESS;
+	}
+}
+
+#ifndef DISABLE_ZLIB
+/* returns a pointer to a newly created buffer */
+static buffer* buf_decompress(buffer* buf, unsigned int len) {
+
+	int result;
+	buffer * ret;
+	z_streamp zstream;
+
+	zstream = ses.keys->recv_zstream;
+	ret = buf_new(len);
+
+	zstream->avail_in = len;
+	zstream->next_in = buf_getptr(buf, len);
+
+	/* decompress the payload, incrementally resizing the output buffer */
+	while (1) {
+
+		zstream->avail_out = ret->size - ret->pos;
+		zstream->next_out = buf_getwriteptr(ret, zstream->avail_out);
+
+		result = inflate(zstream, Z_SYNC_FLUSH);
+
+		buf_setlen(ret, ret->size - zstream->avail_out);
+		buf_setpos(ret, ret->len);
+
+		if (result != Z_BUF_ERROR && result != Z_OK) {
+			dropbear_exit("zlib error");
+		}
+
+		if (zstream->avail_in == 0 &&
+		   		(zstream->avail_out != 0 || result == Z_BUF_ERROR)) {
+			/* we can only exit if avail_out hasn't all been used,
+			 * and there's no remaining input */
+			return ret;
+		}
+
+		if (zstream->avail_out == 0) {
+			buf_resize(ret, ret->size + ZLIB_DECOMPRESS_INCR);
+		}
+	}
+}
+#endif
+
+
+
+/* This must be called directly after receiving the unimplemented packet.
+ * Isn't the most clean implementation, it relies on packet processing
+ * occurring directly after decryption. This is reasonably valid, since
+ * there is only a single decryption buffer */
+void recv_unimplemented() {
+
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_UNIMPLEMENTED);
+	/* the decryption routine increments the sequence number, we must
+	 * decrement */
+	buf_putint(ses.writepayload, ses.recvseq - 1);
+
+	encrypt_packet();
+}
+	
+/* encrypt the writepayload, putting into writebuf, ready for write_packet()
+ * to put on the wire */
+void encrypt_packet() {
+
+	unsigned char padlen;
+	unsigned char blocksize, macsize;
+	buffer * writebuf; /* the packet which will go on the wire */
+	buffer * clearwritebuf; /* unencrypted, possibly compressed */
+	
+	TRACE(("enter encrypt_packet()"));
+	TRACE(("encrypt_packet type is %d", ses.writepayload->data[0]));
+	blocksize = ses.keys->trans_algo_crypt->blocksize;
+	macsize = ses.keys->trans_algo_mac->hashsize;
+
+	/* Encrypted packet len is payload+5, then worst case is if we are 3 away
+	 * from a blocksize multiple. In which case we need to pad to the
+	 * multiple, then add another blocksize (or MIN_PACKET_LEN) */
+	clearwritebuf = buf_new((ses.writepayload->len+4+1) + MIN_PACKET_LEN + 3
+#ifndef DISABLE_ZLIB
+			+ ZLIB_COMPRESS_INCR /* bit of a kludge, but we can't know len*/
+#endif
+			);
+	buf_setlen(clearwritebuf, PACKET_PAYLOAD_OFF);
+	buf_setpos(clearwritebuf, PACKET_PAYLOAD_OFF);
+
+	buf_setpos(ses.writepayload, 0);
+
+#ifndef DISABLE_ZLIB
+	/* compression */
+	if (ses.keys->trans_algo_comp == DROPBEAR_COMP_ZLIB) {
+		buf_compress(clearwritebuf, ses.writepayload, ses.writepayload->len);
+	} else
+#endif
+	{
+		memcpy(buf_getwriteptr(clearwritebuf, ses.writepayload->len),
+				buf_getptr(ses.writepayload, ses.writepayload->len),
+				ses.writepayload->len);
+		buf_incrwritepos(clearwritebuf, ses.writepayload->len);
+	}
+
+	/* finished with payload */
+	buf_setpos(ses.writepayload, 0);
+	buf_setlen(ses.writepayload, 0);
+
+	/* length of padding - packet length must be a multiple of blocksize,
+	 * with a minimum of 4 bytes of padding */
+	padlen = blocksize - (clearwritebuf->len) % blocksize;
+	if (padlen < 4) {
+		padlen += blocksize;
+	}
+	/* check for min packet length */
+	if (clearwritebuf->len + padlen < MIN_PACKET_LEN) {
+		padlen += blocksize;
+	}
+
+	buf_setpos(clearwritebuf, 0);
+	/* packet length excluding the packetlength uint32 */
+	buf_putint(clearwritebuf, clearwritebuf->len + padlen - 4);
+
+	/* padding len */
+	buf_putbyte(clearwritebuf, padlen);
+	/* actual padding */
+	buf_setpos(clearwritebuf, clearwritebuf->len);
+	buf_incrlen(clearwritebuf, padlen);
+	genrandom(buf_getptr(clearwritebuf, padlen), padlen);
+
+	/* do the actual encryption */
+	buf_setpos(clearwritebuf, 0);
+	/* create a new writebuffer, this is freed when it has been put on the 
+	 * wire by writepacket() */
+	writebuf = buf_new(clearwritebuf->len + macsize);
+
+	if (ses.keys->trans_algo_crypt->cipherdesc == NULL) {
+		/* copy it */
+		memcpy(buf_getwriteptr(writebuf, clearwritebuf->len),
+				buf_getptr(clearwritebuf, clearwritebuf->len),
+				clearwritebuf->len);
+		buf_incrwritepos(writebuf, clearwritebuf->len);
+	} else {
+		/* encrypt it */
+		while (clearwritebuf->pos < clearwritebuf->len) {
+			if (cbc_encrypt(buf_getptr(clearwritebuf, blocksize),
+						buf_getwriteptr(writebuf, blocksize),
+						&ses.keys->trans_symmetric_struct) != CRYPT_OK) {
+				dropbear_exit("error encrypting");
+			}
+			buf_incrpos(clearwritebuf, blocksize);
+			buf_incrwritepos(writebuf, blocksize);
+		}
+	}
+
+	/* now add a hmac and we're done */
+	writemac(writebuf, clearwritebuf);
+
+	/* clearwritebuf is finished with */
+	buf_free(clearwritebuf);
+
+	/* enqueue the packet for sending */
+	buf_setpos(writebuf, 0);
+	enqueue(&ses.writequeue, (void*)writebuf);
+
+	/* Update counts */
+	ses.kexstate.datatrans += writebuf->len;
+	ses.transseq++;
+
+	TRACE(("leave encrypt_packet()"));
+}
+
+
+/* Create the packet mac, and append H(seqno|clearbuf) to the output */
+static void writemac(buffer * outputbuffer, buffer * clearwritebuf) {
+
+	int macsize;
+	unsigned char seqbuf[4];
+	unsigned long hashsize;
+	hmac_state hmac;
+
+	TRACE(("enter writemac"));
+
+	macsize = ses.keys->trans_algo_mac->hashsize;
+
+	if (macsize > 0) {
+		/* calculate the mac */
+		if (hmac_init(&hmac, 
+					find_hash(ses.keys->trans_algo_mac->hashdesc->name), 
+					ses.keys->transmackey, 
+					ses.keys->trans_algo_mac->keysize) != CRYPT_OK) {
+			dropbear_exit("HMAC error");
+		}
+	
+		/* sequence number */
+		STORE32H(ses.transseq, seqbuf);
+		if (hmac_process(&hmac, seqbuf, 4) != CRYPT_OK) {
+			dropbear_exit("HMAC error");
+		}
+	
+		/* the actual contents */
+		buf_setpos(clearwritebuf, 0);
+		if (hmac_process(&hmac, 
+					buf_getptr(clearwritebuf, 
+						clearwritebuf->len),
+					clearwritebuf->len) != CRYPT_OK) {
+			dropbear_exit("HMAC error");
+		}
+	
+		hashsize = macsize;
+		if (hmac_done(&hmac, buf_getwriteptr(outputbuffer, macsize), &hashsize) 
+				!= CRYPT_OK) {
+			dropbear_exit("HMAC error");
+		}
+		buf_incrwritepos(outputbuffer, macsize);
+	}
+	TRACE(("leave writemac"));
+}
+
+#ifndef DISABLE_ZLIB
+/* compresses len bytes from src, outputting to dest (starting from the
+ * respective current positions. */
+static void buf_compress(buffer * dest, buffer * src, unsigned int len) {
+
+	unsigned int endpos = src->pos + len;
+	int result;
+
+	TRACE(("enter buf_compress"));
+
+	while (1) {
+
+		ses.keys->trans_zstream->avail_in = endpos - src->pos;
+		ses.keys->trans_zstream->next_in = 
+			buf_getptr(src, ses.keys->trans_zstream->avail_in);
+
+		ses.keys->trans_zstream->avail_out = dest->size - dest->pos;
+		ses.keys->trans_zstream->next_out =
+			buf_getwriteptr(dest, ses.keys->trans_zstream->avail_out);
+
+		result = deflate(ses.keys->trans_zstream, Z_SYNC_FLUSH);
+
+		buf_setpos(src, endpos - ses.keys->trans_zstream->avail_in);
+		buf_setlen(dest, dest->size - ses.keys->trans_zstream->avail_out);
+		buf_setpos(dest, dest->len);
+
+		if (result != Z_OK) {
+			dropbear_exit("zlib error");
+		}
+
+		if (ses.keys->trans_zstream->avail_in == 0) {
+			break;
+		}
+
+		assert(ses.keys->trans_zstream->avail_out == 0);
+
+		/* the buffer has been filled, we must extend. This only happens in
+		 * unusual circumstances where the data grows in size after deflate(),
+		 * but it is possible */
+		buf_resize(dest, dest->size + ZLIB_COMPRESS_INCR);
+
+	}
+	TRACE(("leave buf_compress"));
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common-session.c	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,267 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#include "includes.h"
+#include "session.h"
+#include "dbutil.h"
+#include "packet.h"
+#include "algo.h"
+#include "buffer.h"
+#include "dss.h"
+#include "ssh.h"
+#include "random.h"
+#include "kex.h"
+#include "channel.h"
+#include "atomicio.h"
+
+struct sshsession ses;
+
+/* need to know if the session struct has been initialised, this way isn't the
+ * cleanest, but works OK */
+int sessinitdone = 0;
+
+/* this is set when we get SIGINT or SIGTERM, the handler is in main.c */
+int exitflag = 0;
+
+static int ident_readln(int fd, char* buf, int count);
+
+
+void(*session_remoteclosed)() = NULL;
+
+
+/* called only at the start of a session, set up initial state */
+void common_session_init(int sock, runopts *opts) {
+
+	TRACE(("enter session_init"));
+
+	ses.remoteaddr = NULL;
+	ses.remotehost = NULL;
+
+	ses.sock = sock;
+	ses.maxfd = sock;
+
+	ses.opts = opts;
+
+	ses.connecttimeout = 0;
+	
+	kexinitialise(); /* initialise the kex state */
+	chaninitialise(); /* initialise the channel state */
+
+	ses.writepayload = buf_new(MAX_TRANS_PAYLOAD_LEN);
+	ses.transseq = 0;
+
+	ses.readbuf = NULL;
+	ses.decryptreadbuf = NULL;
+	ses.payload = NULL;
+	ses.recvseq = 0;
+
+	ses.expecting = SSH_MSG_KEXINIT;
+	ses.dataallowed = 0; /* don't send data yet, we'll wait until after kex */
+	ses.ignorenext = 0;
+
+	/* set all the algos to none */
+	ses.keys = (struct key_context*)m_malloc(sizeof(struct key_context));
+	ses.newkeys = NULL;
+	ses.keys->recv_algo_crypt = &dropbear_nocipher;
+	ses.keys->trans_algo_crypt = &dropbear_nocipher;
+	
+	ses.keys->recv_algo_mac = &dropbear_nohash;
+	ses.keys->trans_algo_mac = &dropbear_nohash;
+
+	ses.keys->algo_kex = -1;
+	ses.keys->algo_hostkey = -1;
+	ses.keys->recv_algo_comp = DROPBEAR_COMP_NONE;
+	ses.keys->trans_algo_comp = DROPBEAR_COMP_NONE;
+
+#ifndef DISABLE_ZLIB
+	ses.keys->recv_zstream = NULL;
+	ses.keys->trans_zstream = NULL;
+#endif
+
+	/* key exchange buffers */
+	ses.session_id = NULL;
+	ses.kexhashbuf = NULL;
+	ses.transkexinit = NULL;
+	ses.dh_K = NULL;
+	ses.remoteident = NULL;
+
+
+	TRACE(("leave session_init"));
+}
+
+/* clean up a session on exit */
+void common_session_cleanup() {
+	
+	TRACE(("enter session_cleanup"));
+	
+	/* we can't cleanup if we don't know the session state */
+	if (!sessinitdone) {
+		TRACE(("leave session_cleanup: !sessinitdone"));
+		return;
+	}
+	
+	m_free(ses.session_id);
+	freerunopts(ses.opts);
+	m_burn(ses.keys, sizeof(struct key_context));
+	m_free(ses.keys);
+
+	chancleanup();
+
+	TRACE(("leave session_cleanup"));
+}
+
+/* Check all timeouts which are required. Currently these are the time for
+ * user authentication, and the automatic rekeying. */
+void checktimeouts() {
+
+	struct timeval tv;
+	long secs;
+
+	if (gettimeofday(&tv, 0) < 0) {
+		dropbear_exit("Error getting time");
+	}
+
+	secs = tv.tv_sec;
+	
+	if (ses.connecttimeout != 0 && secs > ses.connecttimeout) {
+			dropbear_close("Timeout before auth");
+	}
+
+	/* we can't rekey if we haven't done remote ident exchange yet */
+	if (ses.remoteident == NULL) {
+		return;
+	}
+
+	if (!ses.kexstate.sentkexinit
+			&& (secs - ses.kexstate.lastkextime >= KEX_REKEY_TIMEOUT
+			|| ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA)){
+		TRACE(("rekeying after timeout or max data reached"));
+		send_msg_kexinit();
+	}
+}
+void session_identification() {
+
+	/* max length of 255 chars */
+	char linebuf[256];
+	int len = 0;
+	char done = 0;
+
+	/* write our version string, this blocks */
+	if (atomicio(write, ses.sock, LOCAL_IDENT "\r\n",
+				strlen(LOCAL_IDENT "\r\n")) == DROPBEAR_FAILURE) {
+		dropbear_exit("Error writing ident string");
+	}
+
+	len = ident_readln(ses.sock, linebuf, 256);
+	if (len >= 4 && memcmp(linebuf, "SSH-", 4) == 0) {
+		/* start of line matches */
+		done = 1;
+	}
+
+	if (!done) {
+		dropbear_exit("Failed to get client version");
+	} else {
+		/* linebuf is already null terminated */
+		ses.remoteident = m_malloc(len);
+		memcpy(ses.remoteident, linebuf, len);
+	}
+
+	TRACE(("remoteident: %s", ses.remoteident));
+
+}
+
+/* returns the length including null-terminating zero on success,
+ * or -1 on failure */
+static int ident_readln(int fd, char* buf, int count) {
+	
+	char in;
+	int pos = 0;
+	int num = 0;
+	fd_set fds;
+	struct timeval timeout;
+
+	TRACE(("enter ident_readln"));
+
+	if (count < 1) {
+		return -1;
+	}
+
+	FD_ZERO(&fds);
+
+	/* select since it's a non-blocking fd */
+	
+	/* leave space to null-terminate */
+	while (pos < count-1) {
+
+		FD_SET(fd, &fds);
+
+		timeout.tv_sec = 1;
+		timeout.tv_usec = 0;
+		if (select(fd+1, &fds, NULL, NULL, &timeout) < 0) {
+			if (errno == EINTR) {
+				continue;
+			}
+			TRACE(("leave ident_readln: select error"));
+			return -1;
+		}
+
+		checktimeouts();
+		
+		/* Have to go one byte at a time, since we don't want to read past
+		 * the end, and have to somehow shove bytes back into the normal
+		 * packet reader */
+		if (FD_ISSET(fd, &fds)) {
+			num = read(fd, &in, 1);
+			/* a "\n" is a newline, "\r" we want to read in and keep going
+			 * so that it won't be read as part of the next line */
+			if (num < 0) {
+				/* error */
+				if (errno == EINTR) {
+					continue; /* not a real error */
+				}
+				TRACE(("leave ident_readln: read error"));
+				return -1;
+			}
+			if (num == 0) {
+				/* EOF */
+				TRACE(("leave ident_readln: EOF"));
+				return -1;
+			}
+			if (in == '\n') {
+				/* end of ident string */
+				break;
+			}
+			/* we don't want to include '\r's */
+			if (in != '\r') {
+				buf[pos] = in;
+				pos++;
+			}
+		}
+	}
+
+	buf[pos] = '\0';
+	TRACE(("leave ident_readln: return %d", pos+1));
+	return pos+1;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compat.c	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,281 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * strlcat() is copyright as follows:
+ * Copyright (c) 1998 Todd C. Miller <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * daemon() and getusershell() is copyright as follows:
+ *
+ * Copyright (c) 1990, 1993
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+		* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+*
+* Modifications for Dropbear to getusershell() are by Paul Marinceu
+*/
+
+#include "includes.h"
+
+#ifndef HAVE_GETUSERSHELL
+static char **curshell, **shells, *strings;
+static char **initshells();
+#endif
+
+#ifndef HAVE_STRLCPY
+/* Implemented by matt as specified in freebsd 4.7 manpage.
+ * We don't require great speed, is simply for use with sshpty code */
+size_t strlcpy(char *dst, const char *src, size_t size) {
+
+	size_t i;
+
+	/* this is undefined, though size==0 -> return 0 */
+	if (size < 1) {
+		return 0;
+	}
+
+	for (i = 0; i < size-1; i++) {
+		if (src[i] == '\0') {
+			break;
+		} else {
+			dst[i] = src[i];
+		}
+	}
+
+	dst[i] = '\0';
+	return strlen(src);
+
+}
+#endif /* HAVE_STRLCPY */
+
+#ifndef HAVE_STRLCAT
+/* taken from openbsd-compat for OpenSSH 3.6.1p1 */
+/* "$OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $"
+ *
+ * Appends src to string dst of size siz (unlike strncat, siz is the
+ * full size of dst, not space left).  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
+ * If retval >= siz, truncation occurred.
+ */
+	size_t
+strlcat(dst, src, siz)
+	char *dst;
+	const char *src;
+	size_t siz;
+{
+	register char *d = dst;
+	register const char *s = src;
+	register size_t n = siz;
+	size_t dlen;
+
+	/* Find the end of dst and adjust bytes left but don't go past end */
+	while (n-- != 0 && *d != '\0')
+		d++;
+	dlen = d - dst;
+	n = siz - dlen;
+
+	if (n == 0)
+		return(dlen + strlen(s));
+	while (*s != '\0') {
+		if (n != 1) {
+			*d++ = *s;
+			n--;
+		}
+		s++;
+	}
+	*d = '\0';
+
+	return(dlen + (s - src));	/* count does not include NUL */
+}
+#endif /* HAVE_STRLCAT */
+
+#ifndef HAVE_DAEMON
+/* From NetBSD - daemonise a process */
+
+int daemon(int nochdir, int noclose) {
+
+	int fd;
+
+	switch (fork()) {
+		case -1:
+			return (-1);
+		case 0:
+			break;
+		default:
+			_exit(0);
+	}
+
+	if (setsid() == -1)
+		return -1;
+
+	if (!nochdir)
+		(void)chdir("/");
+
+	if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+		(void)dup2(fd, STDIN_FILENO);
+		(void)dup2(fd, STDOUT_FILENO);
+		(void)dup2(fd, STDERR_FILENO);
+		if (fd > STDERR_FILENO)
+			(void)close(fd);
+	}
+	return 0;
+}
+#endif /* HAVE_DAEMON */
+
+#ifndef HAVE_BASENAME
+
+char *basename(char *path) {
+
+	char *foo = strrchr(path, '/');
+	return ++foo;
+}
+
+#endif /* HAVE_BASENAME */
+
+#ifndef HAVE_GETUSERSHELL
+
+/*
+ * Get a list of shells from /etc/shells, if it exists.
+ */
+char * getusershell() {
+	char *ret;
+
+	if (curshell == NULL)
+		curshell = initshells();
+	ret = *curshell;
+	if (ret != NULL)
+		curshell++;
+	return (ret);
+}
+
+void endusershell() {
+
+	if (shells != NULL)
+		free(shells);
+	shells = NULL;
+	if (strings != NULL)
+		free(strings);
+	strings = NULL;
+	curshell = NULL;
+}
+
+void setusershell() {
+	curshell = initshells();
+}
+
+static char **initshells() {
+	/* don't touch this list. */
+	const char *okshells[] = { "/bin/sh", "/bin/csh", NULL };
+	register char **sp, *cp;
+	register FILE *fp;
+	struct stat statb;
+	int flen;
+
+	if (shells != NULL)
+		free(shells);
+	shells = NULL;
+	if (strings != NULL)
+		free(strings);
+	strings = NULL;
+	if ((fp = fopen("/etc/shells", "rc")) == NULL)
+		return (char **) okshells;
+	if (fstat(fileno(fp), &statb) == -1) {
+		(void)fclose(fp);
+		return (char **) okshells;
+	}
+	if ((strings = malloc((u_int)statb.st_size + 1)) == NULL) {
+		(void)fclose(fp);
+		return (char **) okshells;
+	}
+	shells = calloc((unsigned)statb.st_size / 3, sizeof (char *));
+	if (shells == NULL) {
+		(void)fclose(fp);
+		free(strings);
+		strings = NULL;
+		return (char **) okshells;
+	}
+	sp = shells;
+	cp = strings;
+	flen = statb.st_size;
+	while (fgets(cp, flen - (cp - strings), fp) != NULL) {
+		while (*cp != '#' && *cp != '/' && *cp != '\0')
+			cp++;
+		if (*cp == '#' || *cp == '\0')
+			continue;
+		*sp++ = cp;
+		while (!isspace(*cp) && *cp != '#' && *cp != '\0')
+			cp++;
+		*cp++ = '\0';
+	}
+	*sp = NULL;
+	(void)fclose(fp);
+	return (shells);
+}
+
+#endif /* HAVE_GETUSERSHELL */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/compat.h	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,32 @@
+#ifndef _COMPAT_H_
+#define _COMPAT_H_
+
+#include "includes.h"
+
+#ifndef HAVE_STRLCPY
+size_t strlcpy(char *dst, const char *src, size_t size);
+#endif
+
+#ifndef HAVE_STRLCAT
+size_t strlcat(char *dst, const char *src, size_t siz);
+#endif
+
+#ifndef HAVE_DAEMON
+int daemon(int nochdir, int noclose);
+#endif
+
+#ifndef HAVE_BASENAME
+char *basename(const char* path);
+#endif
+
+#ifndef HAVE_GETUSERSHELL
+char *getusershell();
+void setusershell();
+void endusershell();
+#endif
+
+#ifndef _PATH_DEVNULL
+#define _PATH_DEVNULL "/dev/null"
+#endif
+
+#endif /* _COMPAT_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config.guess	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,1391 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2003-05-19'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <[email protected]>.
+# Please send patches to <[email protected]>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <[email protected]>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# ([email protected] 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mipseb-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	if test $UNAME_RELEASE = "V4.0"; then
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+	fi
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# [email protected] (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7 && exit 0 ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c \
+	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && exit 0
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    # avoid double evaluation of $set_cc_for_build
+	    test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    *:UNICOS/mp:*:*)
+	echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 
+	exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*|*:GNU/FreeBSD:*:*)
+	# Determine whether the default compiler uses glibc.
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#if __GLIBC__ >= 2
+	LIBC=gnu
+	#else
+	LIBC=
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    x86:Interix*:3*)
+	echo i586-pc-interix3
+	exit 0 ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit 0 ;;
+    M68*:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <[email protected]>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <[email protected]>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From [email protected].
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    *:VOS:*:*)
+	# From [email protected].
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	case `uname -p` in
+	    *86) UNAME_PROCESSOR=i686 ;;
+	    powerpc) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <[email protected]> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config.sub	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,1492 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2003-05-09'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <[email protected]>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <[email protected]>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k \
+	| m32r | m68000 | m68k | m88k | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| msp430 \
+	| ns16k | ns32k \
+	| openrisc | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* \
+	| m32r-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| msp430-* \
+	| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+	| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+	| xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	mmix*)
+		basic_machine=mmix-knuth
+		os=-mmixware
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nv1)
+		basic_machine=nv1-cray
+		os=-unicosmp
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	or32 | or32-*)
+		basic_machine=or32-unknown
+		os=-coff
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2)
+		basic_machine=i686-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+        tic4x | c4x*)
+		basic_machine=tic4x-unknown
+		os=-coff
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configure.in	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,489 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+# This Autoconf file was cobbled from various locations.
+
+AC_PREREQ(2.50)
+AC_INIT(buffer.c)
+
+OLDCFLAGS=$CFLAGS
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_MAKE_SET
+
+if test -z "$LD" ; then
+	LD=$CC
+fi
+AC_SUBST(LD)	
+
+if test -z "$OLDCFLAGS" && test "$GCC" = "yes"; then
+	AC_MSG_RESULT(No \$CFLAGS set... using "-Os -W -Wall for GCC")
+	CFLAGS="-Os -W -Wall"
+fi
+
+# Host specific options
+# this isn't a definitive list of hosts, they are just added as required
+AC_CANONICAL_HOST
+
+case "$host" in
+
+*-*-linux*)
+	no_ptmx_check=1
+	;;
+
+*-*-solaris*)
+	CFLAGS="$CFLAGS -I/usr/local/include"
+	LDFLAGS="$LDFLAGS -L/usr/local/lib -R/usr/local/lib"
+	conf_lastlog_location="/var/adm/lastlog"
+	AC_MSG_CHECKING(for obsolete utmp and wtmp in solaris2.x)
+	sol2ver=`echo "$host"| sed -e 's/.*[[0-9]]\.//'`
+	if test "$sol2ver" -ge 8; then
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(DISABLE_UTMP,,Disable utmp)
+		AC_DEFINE(DISABLE_WTMP,,Disable wtmp)
+	else
+		AC_MSG_RESULT(no)
+	fi
+	AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket")
+	AC_CHECK_LIB(nsl, yp_match, LIBS="$LIBS -lnsl")
+	;;
+
+*-*-aix*)
+	AC_DEFINE(AIX,,Using AIX)
+	;;
+	
+*-*-hpux*)
+	LIBS="$LIBS -lsec"
+	;;
+esac
+
+AC_CHECK_TOOL(AR, ar, :)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+AC_CHECK_TOOL(INSTALL, install, :)
+
+dnl Can't use login() or logout() with uclibc
+AC_CHECK_DECL(__UCLIBC__, 
+	[
+	no_loginfunc_check=1
+	AC_MSG_RESULT(Using uClibc - login() and logout() probably don't work, so we won't use them.)
+	],,,)
+
+# Checks for libraries.
+AC_CHECK_LIB(crypt, crypt, LIBS="$LIBS -lcrypt")
+
+# Check if zlib is needed
+AC_ARG_WITH(zlib,
+	[  --with-zlib=PATH        Use zlib in PATH],
+	[
+		# option is given
+		if test -d "$withval/lib"; then
+			LDFLAGS="-L${withval}/lib ${LDFLAGS}"
+		else
+			LDFLAGS="-L${withval} ${LDFLAGS}"
+		fi
+		if test -d "$withval/include"; then
+			CPPFLAGS="-I${withval}/include ${CPPFLAGS}"
+		else
+			CPPFLAGS="-I${withval} ${CPPFLAGS}"
+		fi
+	]
+)
+
+AC_ARG_ENABLE(zlib,
+	[  --disable-zlib          Don't include zlib support],
+	[
+		if test "x$enableval" = "xno"; then
+			AC_DEFINE(DISABLE_ZLIB,, Use zlib)
+			AC_MSG_RESULT(Disabling zlib)
+		else
+			AC_CHECK_LIB(z, deflate, , AC_MSG_ERROR([*** zlib missing - install first or check config.log ***]))
+			AC_MSG_RESULT(Enabling zlib)
+		fi
+	],
+	[
+		# if not disabled, check for zlib
+		AC_CHECK_LIB(z, deflate, , AC_MSG_ERROR([*** zlib missing - install first or check config.log ***]))
+		AC_MSG_RESULT(Enabling zlib)
+	]
+)
+
+AC_ARG_ENABLE(openpty,
+	[  --disable-openpty       Don't use openpty, use alternative method],
+	[
+		if test "x$enableval" = "xno"; then
+			AC_MSG_RESULT(Not using openpty)
+		else
+			AC_MSG_RESULT(Using openpty if available)
+			AC_SEARCH_LIBS(openpty, util, [AC_DEFINE(HAVE_OPENPTY,,Have openpty() function)])
+		fi
+	],
+	[
+		AC_MSG_RESULT(Using openpty if available)
+		AC_SEARCH_LIBS(openpty, util, [AC_DEFINE(HAVE_OPENPTY)])
+	]
+)
+		
+
+AC_ARG_ENABLE(syslog,
+	[  --disable-syslog        Don't include syslog support],
+	[
+		if test "x$enableval" = "xno"; then
+			AC_DEFINE(DISABLE_SYSLOG,, Using syslog)
+			AC_MSG_RESULT(Disabling syslog)
+		else
+			AC_MSG_RESULT(Enabling syslog)
+		fi
+	],
+	[
+		AC_MSG_RESULT(Enabling syslog)
+	]
+)
+
+AC_ARG_ENABLE(shadow,
+	[  --disable-shadow        Don't use shadow passwords (if available)],
+	[
+		if test "x$enableval" = "xno"; then
+			AC_MSG_RESULT(Not using shadow passwords)
+		else
+			AC_CHECK_HEADERS([shadow.h])
+			AC_MSG_RESULT(Using shadow passwords if available)
+		fi
+	],
+	[
+		AC_CHECK_HEADERS([shadow.h])
+		AC_MSG_RESULT(Using shadow passwords if available)
+	]
+)
+			
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS([fcntl.h limits.h netinet/in.h netinet/tcp.h stdlib.h string.h sys/socket.h sys/time.h termios.h unistd.h crypt.h pty.h ioctl.h libutil.h libgen.h inttypes.h stropts.h utmp.h utmpx.h lastlog.h paths.h util.h netdb.h sys/dirent.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_UID_T
+AC_TYPE_MODE_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+
+AC_CHECK_TYPES([uint16_t, u_int16_t, struct sockaddr_storage])
+AC_CHECK_TYPE([socklen_t], ,[
+	AC_MSG_CHECKING([for socklen_t equivalent])
+	AC_CACHE_VAL([curl_cv_socklen_t_equiv],
+	[
+	# Systems have either "struct sockaddr *" or
+	# "void *" as the second argument to getpeername
+	curl_cv_socklen_t_equiv=
+	for arg2 in "struct sockaddr" void; do
+		for t in int size_t unsigned long "unsigned long"; do
+		AC_TRY_COMPILE([
+			#include <sys/types.h>
+			#include <sys/socket.h>
+
+			int getpeername (int, $arg2 *, $t *);
+		],[
+			$t len;
+			getpeername(0,0,&len);
+		],[
+			curl_cv_socklen_t_equiv="$t"
+			break
+		])
+		done
+	done
+
+	if test "x$curl_cv_socklen_t_equiv" = x; then
+		AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+	fi
+	])
+	AC_MSG_RESULT($curl_cv_socklen_t_equiv)
+	AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv,
+			[type to use in place of socklen_t if not defined])],
+	[#include <sys/types.h>
+	#include <sys/socket.h>])
+
+
+# for loginrec.c
+
+AC_CHECK_MEMBERS([struct utmp.ut_host, struct utmp.ut_pid, struct utmp.ut_type, struct utmp.ut_tv, struct utmp.ut_id, struct utmp.ut_addr, struct utmp.ut_addr_v6, struct utmp.ut_exit, struct utmp.ut_time],,,[
+#include <sys/types.h>
+#if HAVE_UTMP_H
+#include <utmp.h>
+#endif
+])
+
+AC_CHECK_MEMBERS([struct utmpx.ut_host, struct utmpx.ut_syslen, struct utmpx.ut_type, struct utmpx.ut_id, struct utmpx.ut_addr, struct utmpx.ut_addr_v6, struct utmpx.ut_time, struct utmpx.ut_tv],,,[
+#include <sys/types.h>
+#if HAVE_UTMPX_H
+#include <utmpx.h>
+#endif
+])
+
+AC_CHECK_FUNCS(endutent getutent getutid getutline pututline setutent)
+AC_CHECK_FUNCS(utmpname)
+AC_CHECK_FUNCS(endutxent getutxent getutxid getutxline pututxline )
+AC_CHECK_FUNCS(setutxent utmpxname)
+AC_CHECK_FUNCS(logout updwtmp logwtmp)
+
+dnl Added from OpenSSH 3.6.1p2's configure.ac
+
+dnl allow user to disable some login recording features
+AC_ARG_ENABLE(lastlog,
+	[  --disable-lastlog       Disable use of lastlog even if detected [no]],
+	[ AC_DEFINE(DISABLE_LASTLOG,,Disable use of lastlog()) ]
+)
+AC_ARG_ENABLE(utmp,
+	[  --disable-utmp          Disable use of utmp even if detected [no]],
+	[ AC_DEFINE(DISABLE_UTMP,,Disable use of utmp) ]
+)
+AC_ARG_ENABLE(utmpx,
+	[  --disable-utmpx         Disable use of utmpx even if detected [no]],
+	[ AC_DEFINE(DISABLE_UTMPX,,Disable use of utmpx) ]
+)
+AC_ARG_ENABLE(wtmp,
+	[  --disable-wtmp          Disable use of wtmp even if detected [no]],
+	[ AC_DEFINE(DISABLE_WTMP,,Disable use of wtmp) ]
+)
+AC_ARG_ENABLE(wtmpx,
+	[  --disable-wtmpx         Disable use of wtmpx even if detected [no]],
+	[ AC_DEFINE(DISABLE_WTMPX,,Disable use of wtmpx) ]
+)
+AC_ARG_ENABLE(loginfunc,
+	[  --disable-loginfunc     Disable use of login() etc. [no]],
+	[ no_loginfunc_check=1
+	AC_MSG_RESULT(Not using login() etc) ]
+)
+AC_ARG_ENABLE(pututline,
+	[  --disable-pututline     Disable use of pututline() etc. ([uw]tmp) [no]],
+	[ AC_DEFINE(DISABLE_PUTUTLINE,,Disable use of pututline()) ]
+)
+AC_ARG_ENABLE(pututxline,
+	[  --disable-pututxline    Disable use of pututxline() etc. ([uw]tmpx) [no]],
+	[ AC_DEFINE(DISABLE_PUTUTXLINE,,Disable use of pututxline()) ]
+)
+AC_ARG_WITH(lastlog,
+  [  --with-lastlog=FILE|DIR specify lastlog location [common locations]],
+	[
+		if test "x$withval" = "xno" ; then	
+			AC_DEFINE(DISABLE_LASTLOG)
+		else
+			conf_lastlog_location=$withval
+		fi
+	]
+)
+
+if test -z "$no_loginfunc_check"; then
+	dnl    Checks for libutil functions (login(), logout() etc, not openpty() )
+	AC_SEARCH_LIBS(login, util bsd, [AC_DEFINE(HAVE_LOGIN,,Have login() function)])
+	AC_CHECK_FUNCS(logout updwtmp logwtmp)
+fi
+
+dnl lastlog, [uw]tmpx? detection
+dnl  NOTE: set the paths in the platform section to avoid the
+dnl   need for command-line parameters
+dnl lastlog and [uw]tmp are subject to a file search if all else fails
+
+dnl lastlog detection
+dnl  NOTE: the code itself will detect if lastlog is a directory
+AC_MSG_CHECKING([if your system defines LASTLOG_FILE])
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <utmp.h>
+#ifdef HAVE_LASTLOG_H
+#  include <lastlog.h>
+#endif
+#ifdef HAVE_PATHS_H
+#  include <paths.h>
+#endif
+#ifdef HAVE_LOGIN_H
+# include <login.h>
+#endif
+	],
+	[ char *lastlog = LASTLOG_FILE; ],
+	[ AC_MSG_RESULT(yes) ],
+	[
+		AC_MSG_RESULT(no)
+		AC_MSG_CHECKING([if your system defines _PATH_LASTLOG])
+		AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <utmp.h>
+#ifdef HAVE_LASTLOG_H
+#  include <lastlog.h>
+#endif
+#ifdef HAVE_PATHS_H
+#  include <paths.h>
+#endif
+		],
+		[ char *lastlog = _PATH_LASTLOG; ],
+		[ AC_MSG_RESULT(yes) ],
+		[
+			AC_MSG_RESULT(no)
+			system_lastlog_path=no
+		])
+	]
+)
+
+if test -z "$conf_lastlog_location"; then
+	if test x"$system_lastlog_path" = x"no" ; then
+		for f in /var/log/lastlog /usr/adm/lastlog /var/adm/lastlog /etc/security/lastlog ; do
+				if (test -d "$f" || test -f "$f") ; then
+					conf_lastlog_location=$f
+				fi
+		done
+		if test -z "$conf_lastlog_location"; then
+			AC_MSG_WARN([** Cannot find lastlog **])
+			dnl Don't define DISABLE_LASTLOG - that means we don't try wtmp/wtmpx
+		fi
+	fi
+fi
+
+if test -n "$conf_lastlog_location"; then
+	AC_DEFINE_UNQUOTED(CONF_LASTLOG_FILE, "$conf_lastlog_location", lastlog file location)
+fi	
+
+dnl utmp detection
+AC_MSG_CHECKING([if your system defines UTMP_FILE])
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <utmp.h>
+#ifdef HAVE_PATHS_H
+#  include <paths.h>
+#endif
+	],
+	[ char *utmp = UTMP_FILE; ],
+	[ AC_MSG_RESULT(yes) ],
+	[ AC_MSG_RESULT(no)
+	  system_utmp_path=no ]
+)
+if test -z "$conf_utmp_location"; then
+	if test x"$system_utmp_path" = x"no" ; then
+		for f in /etc/utmp /usr/adm/utmp /var/run/utmp; do
+			if test -f $f ; then
+				conf_utmp_location=$f
+			fi
+		done
+		if test -z "$conf_utmp_location"; then
+			AC_DEFINE(DISABLE_UTMP)
+		fi
+	fi
+fi
+if test -n "$conf_utmp_location"; then
+	AC_DEFINE_UNQUOTED(CONF_UTMP_FILE, "$conf_utmp_location", utmp file location)
+fi	
+
+dnl wtmp detection
+AC_MSG_CHECKING([if your system defines WTMP_FILE])
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <utmp.h>
+#ifdef HAVE_PATHS_H
+#  include <paths.h>
+#endif
+	],
+	[ char *wtmp = WTMP_FILE; ],
+	[ AC_MSG_RESULT(yes) ],
+	[ AC_MSG_RESULT(no)
+	  system_wtmp_path=no ]
+)
+if test -z "$conf_wtmp_location"; then
+	if test x"$system_wtmp_path" = x"no" ; then
+		for f in /usr/adm/wtmp /var/log/wtmp; do
+			if test -f $f ; then
+				conf_wtmp_location=$f
+			fi
+		done
+		if test -z "$conf_wtmp_location"; then
+			AC_DEFINE(DISABLE_WTMP)
+		fi
+	fi
+fi
+if test -n "$conf_wtmp_location"; then
+	AC_DEFINE_UNQUOTED(CONF_WTMP_FILE, "$conf_wtmp_location", wtmp file location)
+fi	
+
+
+dnl utmpx detection - I don't know any system so perverse as to require
+dnl  utmpx, but not define UTMPX_FILE (ditto wtmpx.) No doubt it's out
+dnl  there, though.
+AC_MSG_CHECKING([if your system defines UTMPX_FILE])
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <utmp.h>
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif
+#ifdef HAVE_PATHS_H
+#  include <paths.h>
+#endif
+	],
+	[ char *utmpx = UTMPX_FILE; ],
+	[ AC_MSG_RESULT(yes) ],
+	[ AC_MSG_RESULT(no)
+	  system_utmpx_path=no ]
+)
+if test -z "$conf_utmpx_location"; then
+	if test x"$system_utmpx_path" = x"no" ; then
+		AC_DEFINE(DISABLE_UTMPX)
+	fi
+else
+	AC_DEFINE_UNQUOTED(CONF_UTMPX_FILE, "$conf_utmpx_location", utmpx file location)
+fi	
+
+dnl wtmpx detection
+AC_MSG_CHECKING([if your system defines WTMPX_FILE])
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <utmp.h>
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif
+#ifdef HAVE_PATHS_H
+#  include <paths.h>
+#endif
+	],
+	[ char *wtmpx = WTMPX_FILE; ],
+	[ AC_MSG_RESULT(yes) ],
+	[ AC_MSG_RESULT(no)
+	  system_wtmpx_path=no ]
+)
+if test -z "$conf_wtmpx_location"; then
+	if test x"$system_wtmpx_path" = x"no" ; then
+		AC_DEFINE(DISABLE_WTMPX)
+	fi
+else
+	AC_DEFINE_UNQUOTED(CONF_WTMPX_FILE, "$conf_wtmpx_location", wtmpx file location)
+fi	
+
+# Checks for library functions.
+AC_PROG_GCC_TRADITIONAL
+AC_FUNC_MEMCMP
+AC_FUNC_SELECT_ARGTYPES
+AC_TYPE_SIGNAL
+AC_CHECK_FUNCS([dup2 getspnam getusershell memset putenv select socket strdup clearenv strlcpy strlcat daemon basename _getpty ])
+
+AC_SEARCH_LIBS(basename, gen, AC_DEFINE(HAVE_BASENAME))
+
+# Solaris needs ptmx
+if test -z "$no_ptmx_check" ; then
+	if test x"$cross_compiling" = x"no" ; then
+		AC_CHECK_FILE("/dev/ptmx", AC_DEFINE(USE_DEV_PTMX,,Use /dev/ptmx))
+	else
+		AC_MSG_RESULT(Not checking for /dev/ptmx, we're cross-compiling)
+	fi
+fi
+
+if test -z "$no_ptc_check" ; then
+	if test x"$cross_compiling" = x"no" ; then
+		AC_CHECK_FILE("/dev/ptc", AC_DEFINE(HAVE_DEV_PTS_AND_PTC,,Use /dev/ptc & /dev/pts))
+	else
+		AC_MSG_RESULT(Not checking for /dev/ptc & /dev/pts\, we're cross-compiling)
+	fi
+fi
+
+AC_CONFIG_HEADER(config.h)
+AC_OUTPUT(Makefile)
+AC_MSG_RESULT()
+AC_MSG_RESULT(Now edit options.h to choose features.)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dbmulti.c	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,48 @@
+#include "includes.h"
+
+/* definitions are cleanest if we just put them here */
+int dropbear_main(int argc, char ** argv);
+int dropbearkey_main(int argc, char ** argv);
+int dropbearconvert_main(int argc, char ** argv);
+
+int main(int argc, char ** argv) {
+
+	char * progname;
+
+	if (argc > 0) {
+		/* figure which form we're being called as */
+		progname = basename(argv[0]);
+
+#ifdef DBMULTI_DROPBEAR
+		if (strcmp(progname, "dropbear") == 0) {
+			return dropbear_main(argc, argv);
+		}
+#endif
+#ifdef DBMULTI_KEY
+		if (strcmp(progname, "dropbearkey") == 0) {
+			return dropbearkey_main(argc, argv);
+		}
+#endif
+#ifdef DBMULTI_CONVERT
+		if (strcmp(progname, "dropbearconvert") == 0) {
+			return dropbearconvert_main(argc, argv);
+		}
+#endif
+	}
+
+	fprintf(stderr, "Dropbear multi-purpose version %s\n"
+			"Make a symlink pointing at this binary with one of the following names:\n"
+#ifdef DBMULTI_DROPBEAR
+			"'dropbear' - the Dropbear server\n"
+#endif
+#ifdef DBMULTI_KEY
+			"'dropbearkey' - the key generator\n"
+#endif
+#ifdef DBMULTI_CONVERT
+			"'dropbearconvert' - the key converter\n"
+#endif
+			,
+			DROPBEAR_VERSION);
+	exit(1);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dbutil.c	Tue Jun 01 02:46:09 2004 +0000
@@ -0,0 +1,296 @@
+/*
+ * Dropbear - a SSH2 server
+ * 
+ * Copyright (c) 2002,2003 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * strlcat() is copyright as follows:
+ * Copyright (c) 1998 Todd C. Miller <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "includes.h"
+#include "dbutil.h"
+#include "buffer.h"
+#include "session.h"
+#include "atomicio.h"
+
+#define MAX_FMT 100
+
+void (*_dropbear_exit)(int exitcode, const char* format, va_list param) = NULL;
+void (*_dropbear_log)(int priority, const char* format, va_list param) = NULL;
+
+int usingsyslog = 0; /* set by runopts, but required externally to sessions */