Putting Python-specific GUSI modifications under CVS.
diff --git a/Mac/GUSI-mods/into-include/GUSI.h b/Mac/GUSI-mods/into-include/GUSI.h
new file mode 100644
index 0000000..07ce429
--- /dev/null
+++ b/Mac/GUSI-mods/into-include/GUSI.h
@@ -0,0 +1,366 @@
+/*********************************************************************
+Project	:	GUSI				-	Grand Unified Socket Interface
+File		:	GUSI.h			-	Socket calls
+Author	:	Matthias Neeracher
+Language	:	MPW C/C++
+
+$Log$
+Revision 1.1  1998/08/18 14:52:33  jack
+Putting Python-specific GUSI modifications under CVS.
+
+Revision 1.2  1994/12/31  01:45:54  neeri
+Fix alignment.
+
+Revision 1.1  1994/02/25  02:56:49  neeri
+Initial revision
+
+Revision 0.15  1993/06/27  00:00:00  neeri
+f?truncate
+
+Revision 0.14  1993/06/20  00:00:00  neeri
+Changed sa_constr_ppc
+
+Revision 0.13  1993/02/14  00:00:00  neeri
+AF_PAP
+
+Revision 0.12  1992/12/08  00:00:00  neeri
+getcwd()
+
+Revision 0.11  1992/11/15  00:00:00  neeri
+remove netdb.h definitions
+
+Revision 0.10  1992/09/26  00:00:00  neeri
+Separate dirent and stat
+
+Revision 0.9  1992/09/12  00:00:00  neeri
+Hostname stuff
+
+Revision 0.8  1992/09/07  00:00:00  neeri
+readlink()
+
+Revision 0.7  1992/08/03  00:00:00  neeri
+sa_constr_ppc
+
+Revision 0.6  1992/07/21  00:00:00  neeri
+sockaddr_atlk_sym
+
+Revision 0.5  1992/06/26  00:00:00  neeri
+choose()
+
+Revision 0.4  1992/05/18  00:00:00  neeri
+PPC stuff
+
+Revision 0.3  1992/04/27  00:00:00  neeri
+getsockopt()
+
+Revision 0.2  1992/04/19  00:00:00  neeri
+C++ compatibility
+
+Revision 0.1  1992/04/17  00:00:00  neeri
+bzero()
+
+*********************************************************************/
+
+#ifndef _GUSI_
+#define _GUSI_
+
+#include <sys/types.h>
+
+/* Feel free to increase FD_SETSIZE as needed */
+#define GUSI_MAX_FD	FD_SETSIZE
+
+#include <sys/cdefs.h>
+#include <compat.h>
+#include <sys/ioctl.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <Types.h>
+#include <Events.h>
+#include <Files.h>
+#include <AppleTalk.h>
+#include <CTBUtilities.h>
+#include <Packages.h>
+#include <PPCToolBox.h>
+#include <StandardFile.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <machine/endian.h>
+
+typedef enum spin_msg {
+	SP_MISC,				/* some weird thing, usually just return immediately if you get this */
+	SP_SELECT,			/* in a select call */
+	SP_NAME,				/* getting a host by name */
+	SP_ADDR,				/* getting a host by address */
+	SP_STREAM_READ,	/* Stream read call */
+	SP_STREAM_WRITE,	/* Stream write call */
+	SP_DGRAM_READ,		/* Datagram read call */
+	SP_DGRAM_WRITE,	/* Datagram write call */
+	SP_SLEEP,			/* sleeping, passes ticks left to sleep */
+	SP_AUTO_SPIN		/* Autospin, passes argument to SpinCursor */
+} spin_msg;
+
+typedef int (*GUSISpinFn)(spin_msg msg, long param);
+typedef void (*GUSIEvtHandler)(EventRecord * ev);
+typedef GUSIEvtHandler	GUSIEvtTable[24];
+
+/*
+ * Address families, defined in sys/socket.h
+ *
+ 
+#define	AF_UNSPEC		 0		// unspecified
+#define	AF_UNIX			 1		// local to host (pipes, portals)
+#define	AF_INET			 2		// internetwork: UDP, TCP, etc.
+#define	AF_CTB			 3		// Apple Comm Toolbox (not yet supported)
+#define	AF_FILE			 4		// Normal File I/O (used internally)
+#define	AF_PPC			 5		// PPC Toolbox
+#define	AF_PAP			 6		// Printer Access Protocol (client only)
+#define	AF_APPLETALK	16		// Apple Talk
+
+*/
+
+#define	ATALK_SYMADDR 272		/* Symbolic Address for AppleTalk 			*/
+
+/*
+ * Some Implementations of GUSI require you to call GUSISetup for the
+ * socket families you'd like to have defined. It's a good idea to call
+ * this for *all* implementations.
+ *
+ * GUSIDefaultSetup() will include all socket families.
+ *
+ * Never call any of the GUSIwithXXX routines directly.
+ */
+
+__BEGIN_DECLS
+void GUSIwithAppleTalkSockets();
+void GUSIwithInternetSockets();
+void GUSIwithPAPSockets();
+void GUSIwithPPCSockets();
+void GUSIwithUnixSockets();
+void GUSIwithSIOUXSockets();
+void GUSIwithMPWSockets();
+
+void GUSISetup(void (*socketfamily)());
+void GUSIDefaultSetup();
+void GUSILoadConfiguration(Handle);
+__END_DECLS
+/*
+ * Types,  defined in sys/socket.h
+ *
+
+#define	SOCK_STREAM		 1		// stream socket 
+#define	SOCK_DGRAM		 2		// datagram socket
+
+*/
+
+/*
+ * Defined in sys/un.h
+ *
+ 
+struct sockaddr_un {
+	short		sun_family;
+	char 		sun_path[108];
+};
+
+*/
+
+#ifndef PRAGMA_ALIGN_SUPPORTED
+#error Apple had some fun with the conditional macros again
+#endif
+
+#if PRAGMA_ALIGN_SUPPORTED
+#pragma options align=mac68k
+#endif
+
+struct sockaddr_atlk {
+	short			family;
+	AddrBlock	addr;
+};
+
+struct sockaddr_atlk_sym {
+	short			family;
+	EntityName	name;
+};
+
+struct sockaddr_ppc {
+	short					family;
+	LocationNameRec	location;
+	PPCPortRec			port;
+};
+
+/* Definitions for choose() */
+
+#define 	CHOOSE_DEFAULT	1		/*	Use *name as default name						*/
+#define	CHOOSE_NEW		2		/* Choose new entity name, not existing one	*/
+#define	CHOOSE_DIR		4		/* Choose a directory name, not a file 		*/
+
+typedef struct {
+	short			numTypes;
+	SFTypeList	types;
+} sa_constr_file;
+
+typedef struct {
+	short			numTypes;
+	NLType		types;
+} sa_constr_atlk;
+
+/* Definitions for sa_constr_ppc */
+
+#define PPC_CON_NEWSTYLE		0x8000	/* Required */
+#define PPC_CON_MATCH_NAME		0x0001	/* Match name */
+#define PPC_CON_MATCH_TYPE 	0x0002 	/* Match port type */
+#define PPC_CON_MATCH_NBP		0x0004	/* Match NBP type */
+
+typedef struct	{
+	short			flags;
+	Str32			nbpType;
+	PPCPortRec	match;
+} sa_constr_ppc;
+
+#if PRAGMA_ALIGN_SUPPORTED
+#pragma options align=reset
+#endif
+
+__BEGIN_DECLS
+/* 
+ * IO/Socket stuff, defined elsewhere (unistd.h, sys/socket.h
+ *
+
+int socket(int domain, int type, short protocol);
+int bind(int s, void *name, int namelen);
+int connect(int s, void *addr, int addrlen);
+int listen(int s, int qlen);
+int accept(int s, void *addr, int *addrlen);
+int close(int s);
+int read(int s, char *buffer, unsigned buflen);
+int readv(int s, struct iovec *iov, int count);
+int recv(int s, void *buffer, int buflen, int flags);
+int recvfrom(int s, void *buffer, int buflen, int flags, void *from, int *fromlen);
+int recvmsg(int s,struct msghdr *msg,int flags);
+int write(int s, const char *buffer, unsigned buflen);
+int writev(int s, struct iovec *iov, int count);
+int send(int s, void *buffer, int buflen, int flags);
+int sendto (int s, void *buffer, int buflen, int flags, void *to, int tolen);
+int sendmsg(int s,struct msghdr *msg,int flags);
+int select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
+int getdtablesize(void);
+int getsockname(int s, void *name, int *namelen);
+int getpeername(int s, struct sockaddr *name, int *namelen);
+int shutdown(int s, int how);
+int fcntl(int s, unsigned int cmd, int arg);
+int dup(int s);
+int dup2(int s, int s1);
+int ioctl(int d, unsigned int request, long *argp);
+int getsockopt(int s, int level, int optname, char *optval, int * optlen);
+int setsockopt(int s, int level, int optname, char *optval, int optlen);
+int isatty(int);
+int remove(const char *filename);
+int rename(const char *oldname, const char *newname);
+int creat(const char*);
+int faccess(char*, unsigned int, long*);
+long lseek(int, long, int);
+int open(const char*, int);
+int unlink(char*);
+int symlink(char* linkto, char* linkname);
+int readlink(char* path, char* buf, int bufsiz);
+int truncate(char *path, long length);
+int ftruncate(int fd, long length);
+int chdir(char * path);
+int mkdir(char * path);
+int rmdir(char * path);
+char * getcwd(char * buf, int size);
+*/
+
+/* 
+ * Defined in stdio.h
+ */
+ 
+#ifdef __MWERKS__
+void fsetfileinfo (char *filename, unsigned long newcreator, unsigned long newtype);
+#endif
+
+void fgetfileinfo (char *filename, unsigned long * creator, unsigned long * type);
+
+#ifdef __MWERKS__
+FILE *fdopen(int fd, const char *mode);
+int fwalk(int (*func)(FILE * stream));
+#endif
+
+int choose(
+		int 		domain,
+		int 		type,
+		char * 	prompt,
+		void * 	constraint,
+		int 		flags,
+		void * 	name,
+		int * 	namelen);
+
+/* 
+ * Hostname routines, defined in netdb.h
+ *
+ 
+struct hostent * gethostbyname(char *name);
+struct hostent * gethostbyaddr(struct in_addr *addrP, int, int);
+int gethostname(char *machname, long buflen);
+struct servent * getservbyname (char * name, char * proto);
+struct protoent * getprotobyname(char * name);
+
+*/
+
+char * inet_ntoa(struct in_addr inaddr);
+struct in_addr inet_addr(char *address);
+
+/* 
+ * GUSI supports a number of hooks. Every one of them has a different prototype, but needs
+ * to be passed as a GUSIHook
+ */
+
+typedef enum {
+	GUSI_SpinHook,	/* A GUSISpinFn, to be called when a call blocks */
+	GUSI_ExecHook, /* Boolean (*hook)(const GUSIFileRef & ref), decides if file is executable */
+	GUSI_FTypeHook,/* Boolean (*hook)(const FSSpec & spec) sets a default file type */
+	GUSI_SpeedHook /* A long integer, to be added to the cursor spin variable */
+} GUSIHookCode;
+
+typedef void (*GUSIHook)(void);
+void GUSISetHook(GUSIHookCode code, GUSIHook hook);
+GUSIHook GUSIGetHook(GUSIHookCode code);
+
+/* 
+ * What to do when a routine blocks
+ */
+
+/* Defined for compatibility */
+#define GUSISetSpin(routine)	GUSISetHook(GUSI_SpinHook, (GUSIHook)routine)
+#define GUSIGetSpin()			(GUSISpinFn) GUSIGetHook(GUSI_SpinHook)
+
+int GUSISetEvents(GUSIEvtTable table);
+GUSIEvtHandler * GUSIGetEvents(void);
+
+extern GUSIEvtHandler	GUSISIOWEvents[];
+
+#define SIGPIPE	13
+#define SIGALRM	14
+
+/* 
+ * BSD memory routines, defined in compat.h
+ *
+
+#define index(a, b)						strchr(a, b)
+#define rindex(a, b)						strrchr(a, b)
+#define bzero(from, len) 				memset(from, 0, len)
+#define bcopy(from, to, len)			memcpy(to, from, len)
+#define bcmp(s1, s2, len)				memcmp(s1, s2, len)
+#define bfill(from, len, x)			memset(from, x, len)
+
+ */
+
+__END_DECLS
+
+#endif /* !_GUSI_ */
diff --git a/Mac/GUSI-mods/into-include/GUSI_P.h b/Mac/GUSI-mods/into-include/GUSI_P.h
new file mode 100644
index 0000000..1bc5523
--- /dev/null
+++ b/Mac/GUSI-mods/into-include/GUSI_P.h
@@ -0,0 +1,471 @@
+/*********************************************************************
+Project	:	GUSI				-	Grand Unified Socket Interface
+File		:	GUSI_P.h			-	Private stuff
+Author	:	Matthias Neeracher
+Language	:	MPW C/C++
+
+$Log$
+Revision 1.1  1998/08/18 14:52:33  jack
+Putting Python-specific GUSI modifications under CVS.
+
+Revision 1.3  1994/12/31  01:30:26  neeri
+Reorganize filename dispatching.
+
+Revision 1.2  1994/08/10  00:41:05  neeri
+Sanitized for universal headers.
+
+Revision 1.1  1994/02/25  02:57:01  neeri
+Initial revision
+
+Revision 0.22  1993/07/17  00:00:00  neeri
+GUSIRingBuffer::proc -> defproc
+
+Revision 0.21  1993/07/17  00:00:00  neeri
+GUSIO_MAX_DOMAIN -> AF_MAX
+
+Revision 0.20  1993/06/27  00:00:00  neeri
+Socket::{pre,post}_select
+
+Revision 0.19  1993/06/27  00:00:00  neeri
+Socket::ftruncate
+
+Revision 0.18  1993/02/09  00:00:00  neeri
+Socket::lurking, Socket::lurkdescr
+
+Revision 0.17  1993/01/31  00:00:00  neeri
+GUSIConfiguration::daemon
+
+Revision 0.16  1993/01/17  00:00:00  neeri
+Destructors for Socketdomain
+
+Revision 0.15  1993/01/17  00:00:00  neeri
+SAFESPIN
+
+Revision 0.14  1993/01/03  00:00:00  neeri
+GUSIConfig
+
+Revision 0.13  1992/09/24  00:00:00  neeri
+Include GUSIRsrc_P.h
+
+Revision 0.12  1992/09/13  00:00:00  neeri
+SPINVOID didn't return
+
+Revision 0.11  1992/08/30  00:00:00  neeri
+AppleTalkIdentity()
+
+Revision 0.10  1992/08/03  00:00:00  neeri
+RingBuffer
+
+Revision 0.9  1992/07/30  00:00:00  neeri
+Initializer Features
+
+Revision 0.8  1992/07/26  00:00:00  neeri
+UnixSockets.choose()
+
+Revision 0.7  1992/07/13  00:00:00  neeri
+Make AppleTalkSockets global
+
+Revision 0.6  1992/06/27  00:00:00  neeri
+choose(), hasNewSF
+
+Revision 0.5  1992/06/07  00:00:00  neeri
+Feature
+
+Revision 0.4  1992/05/21  00:00:00  neeri
+Implemented select()
+
+Revision 0.3  1992/04/19  00:00:00  neeri
+C++ rewrite
+
+Revision 0.2  1992/04/18  00:00:00  neeri
+changed read/write/send/recv dispatchers
+
+Revision 0.1  1992/04/18  00:00:00  neeri
+ppc Domain
+
+*********************************************************************/
+
+#ifndef __GUSI_P__
+#define __GUSI_P__
+
+#define __useAppleExts__
+
+#include <GUSI.h>
+#include <GUSIRsrc_P.h>
+#include <TFileSpec.h>
+
+
+#include <sys/errno.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+
+extern "C" {
+
+#include <stdio.h>
+#include <string.h>
+
+int 		GUSI_error(int err);
+void *	GUSI_error_nil(int err);
+}
+
+#include <Memory.h>
+#include <Gestalt.h>
+#include <Traps.h>
+#include <AppleEvents.h>
+#include <Processes.h>
+#include <MixedMode.h>
+
+#if MSLGUSI
+using namespace std;
+#endif
+
+#if GENERATING68K
+#pragma segment GUSI
+#endif
+
+#define GUSI_MAX_DOMAIN			AF_MAX
+#define DEFAULT_BUFFER_SIZE	4096
+
+/*
+ *	In use and shutdown status.
+ */
+#define	SOCK_STATUS_USED		0x1		/* Used socket table entry */
+#define	SOCK_STATUS_NOREAD	0x2		/* No more reading allowed from socket */
+#define	SOCK_STATUS_NOWRITE	0x4		/* No more writing allowed to socket */
+
+/*
+ *	Socket connection states.
+ */
+#define	SOCK_STATE_NO_STREAM		0	/* Socket doesn't have a MacTCP stream yet */
+#define	SOCK_STATE_UNCONNECTED	1	/* Socket is unconnected. */
+#define	SOCK_STATE_LISTENING		2	/* Socket is listening for connection. */
+#define	SOCK_STATE_LIS_CON		3	/* Socket is in transition from listen to connected. */
+#define	SOCK_STATE_CONNECTING	4	/* Socket is initiating a connection. */
+#define	SOCK_STATE_CONNECTED		5	/* Socket is connected. */
+#define	SOCK_STATE_CLOSING      6	/* Socket is closing */
+#define	SOCK_STATE_LIS_CLOSE    7	/* Socket closed while listening */
+
+#define		min(a,b)				( (a) < (b) ? (a) : (b))
+#define		max(a,b)				( (a) > (b) ? (a) : (b))
+
+extern GUSISpinFn GUSISpin;
+extern "C" int GUSIDefaultSpin(spin_msg, long);
+extern int GUSICheckAlarm();
+
+#define GUSI_INTERRUPT(mesg,param)	(GUSICheckAlarm() || (GUSISpin && (*GUSISpin)(mesg,param)))
+
+/* SPIN returns a -1 on user cancel for fn returning integers */
+#define		SPIN(cond,mesg,param)							\
+					do {												\
+						if (GUSI_INTERRUPT(mesg,param))		\
+							return GUSI_error(EINTR);			\
+					} while(cond)
+
+/* SPINP returns a NULL on user cancel, for fn returning pointers */				
+#define		SPINP(cond,mesg,param)							\
+					do {												\
+						if (GUSI_INTERRUPT(mesg,param)) {	\
+							GUSI_error(EINTR);					\
+							return NULL;							\
+						}												\
+					} while(cond)
+
+/* SPINVOID just returns on user cancel, for fn returning void */				
+#define		SPINVOID(cond,mesg,param)						\
+					do {												\
+						if (GUSI_INTERRUPT(mesg,param)) {	\
+								GUSI_error(EINTR);				\
+								return;								\
+							}											\
+					} while(cond)
+					
+/* SAFESPIN doesn't return, you have to check errno */				
+#define		SAFESPIN(cond,mesg,param)						\
+					do {												\
+						if (GUSI_INTERRUPT(mesg,param)) {	\
+							GUSI_error(EINTR);					\
+							break;									\
+						} else										\
+							errno = 0;								\
+					} while(cond)
+
+//
+// Library functions are never allowed to clear errno, so we have to save
+//
+class ErrnoSaver {
+public:
+	ErrnoSaver()  { fSavedErrno = ::errno; ::errno = 0; 	}
+	~ErrnoSaver() { if (!::errno) ::errno = fSavedErrno;  }
+private:
+	int fSavedErrno;
+};
+
+#define SAVE_AND_CLEAR_ERRNO	ErrnoSaver saveErrno
+			
+class SocketTable;
+
+#if PRAGMA_ALIGN_SUPPORTED
+#pragma options align=mac68k
+#endif
+
+class Socket {
+	friend class SocketTable;
+	
+	short			refCount;
+protected:
+					Socket();
+public:
+	virtual int	bind(void * name, int namelen);
+	virtual int connect(void * address, int addrlen);
+	virtual int listen(int qlen);
+	virtual Socket * accept(void * address, int * addrlen);
+	virtual int	read(void * buffer, int buflen);
+	virtual int write(void * buffer, int buflen);
+	virtual int recvfrom(void * buffer, int buflen, int flags, void * from, int * fromlen);
+	virtual int sendto(void * buffer, int buflen, int flags, void * to, int tolen);
+	virtual int getsockname(void * name, int * namelen);
+	virtual int getpeername(void * name, int * namelen);
+	virtual int getsockopt(int level, int optname, void *optval, int * optlen);
+	virtual int setsockopt(int level, int optname, void *optval, int optlen);
+	virtual int	fcntl(unsigned int cmd, int arg);
+	virtual int	ioctl(unsigned int request, void *argp);
+	virtual int	fstat(struct stat * buf);
+	virtual long lseek(long offset, int whence);
+	virtual int ftruncate(long offset);
+	virtual int	isatty();
+	virtual int shutdown(int how);
+	virtual void pre_select(Boolean wantRead, Boolean wantWrite, Boolean wantExcept);
+	virtual int select(Boolean * canRead, Boolean * canWrite, Boolean * exception);
+	virtual void post_select(Boolean wantRead, Boolean wantWrite, Boolean wantExcept);
+	virtual 		~Socket();
+	
+	void operator++()	{	++refCount;							}
+	void operator--()	{	if (!--refCount) delete this;	}
+};
+
+
+#if PRAGMA_ALIGN_SUPPORTED
+#pragma options align=reset
+#endif
+
+class SocketDomain {
+	static SocketDomain *		domains[GUSI_MAX_DOMAIN];
+	static ProcessSerialNumber	process;
+protected:
+	SocketDomain(int domain);
+	virtual ~SocketDomain();
+public:
+	inline static SocketDomain *	Domain(int domain);
+	static void Ready();
+	
+	// Optionally override the following
+	
+	virtual Socket * socket(int type, short protocol);
+	
+	// Optionally override the following
+	
+	virtual int socketpair(int type, short protocol, Socket * sockets[]);
+	
+	// Optionally define the following
+	
+	virtual int choose(
+						int 		type, 
+						char * 	prompt, 
+						void * 	constraint,		
+						int 		flags,
+ 						void * 	name, 
+						int * 	namelen);
+	
+	// Never override the following
+	
+	void DontStrip();
+};
+
+class SocketTable {
+	Socket *	sockets[GUSI_MAX_FD];
+	Boolean	needsConsole;
+public:
+	SocketTable();
+	~SocketTable();
+	
+	void		InitConsole();
+	int		Install(Socket * sock, int start = 0);
+	int		Remove(int fd);
+	Socket * operator[](int fd);
+};
+
+struct GUSISuffix {
+	char 		suffix[4];
+	OSType	suffType;
+	OSType	suffCreator;
+};
+
+#if PRAGMA_ALIGN_SUPPORTED
+#pragma options align=mac68k
+#endif
+
+//
+// I learned the hard way not to rely on bit field alignments
+//
+
+struct GUSIConfigRsrc {
+	OSType			defaultType;
+	OSType			defaultCreator;
+	
+	char				autoSpin;
+	unsigned char	flags;
+	
+	OSType			version;
+	short				numSuffices;
+	GUSISuffix 		suffices[1];
+};
+
+#if PRAGMA_ALIGN_SUPPORTED
+#pragma options align=reset
+#endif
+
+struct GUSIConfiguration {
+	OSType			defaultType;
+	OSType			defaultCreator;
+	
+	char				autoSpin;
+	
+	Boolean	 		noChdir;		// Set current directory without chdir()
+	Boolean 			accurStat;	// Return # of subdirectories + 2 in st_nlink
+	Boolean	 		hasConsole;	// Do we have our own console ?
+	Boolean			noAutoInitGraf;	// Never automatically do InitGraf
+	Boolean			sharedOpen;	// Open files with shared permissions
+	Boolean			sigPipe;		// raise SIGPIPE on write to closed socket
+	Boolean			noAppleEvents; // Don't solicit AppleEvents for MPW tools
+	Boolean			delayConsole;	// Do not open console until needed
+	
+	OSType			version;
+	short				numSuffices;
+	GUSISuffix *	suffices;
+	
+	GUSIConfiguration();
+	void GUSILoadConfiguration(Handle config);
+	
+	void SetDefaultFType(const TFileSpec & name) const;
+	void DoAutoSpin() const;
+	void AutoInitGraf()	const {	if (!noAutoInitGraf) DoAutoInitGraf();	}
+	void DoAutoInitGraf() const;
+	Boolean DelayConsole() const;
+private:
+	static Boolean firstTime;
+	static short	we;
+};
+
+extern GUSIConfiguration	GUSIConfig;
+extern SocketTable					Sockets;
+
+typedef pascal OSErr (*OSErrInitializer)();
+typedef pascal void  (*voidInitializer)();
+
+class Feature {
+	Boolean	good;
+public:
+	Feature(unsigned short trapNum, TrapType tTyp);
+	Feature(OSType type, long value);
+	Feature(OSType type, long mask, long value);
+	Feature(const Feature & precondition, OSErrInitializer init);
+	Feature(OSErrInitializer init);
+	Feature(const Feature & precondition, voidInitializer init);
+	Feature(voidInitializer init);
+	Feature(const Feature & cond1, const Feature & cond2);
+
+	operator void*() const {	return (void *) good;	}
+};
+
+extern Feature hasMakeFSSpec;
+extern Feature hasAlias;
+extern Feature hasNewSF;
+extern Feature hasProcessMgr;
+extern Feature hasCRM;
+extern Feature hasCTB;
+extern Feature hasStdNBP;
+extern Feature hasCM;
+extern Feature hasFT;
+extern Feature hasTM;
+extern Feature	hasPPC;
+extern Feature hasRevisedTimeMgr;
+
+class ScattGath	{
+	Handle			scratch;
+protected:
+	void *			buf;
+	int						len;
+	int						count;
+	const struct iovec *	io;
+
+	ScattGath(const struct iovec *iov, int cnt);
+	virtual ~ScattGath();
+public:
+	void *			buffer()			{	return buf;			}
+	int				buflen()			{	return len;			}
+	int				length(int l)	{	return len = l;	}
+	operator void *()					{	return buf;			}
+};
+
+class Scatterer : public ScattGath {
+public:
+	Scatterer(const struct iovec *iov, int count);
+	virtual ~Scatterer();
+};
+
+class Gatherer : public ScattGath {
+public:
+	Gatherer(const struct iovec *iov, int count);
+	virtual ~Gatherer();
+};
+
+typedef pascal void (*Deferred)(void *);
+
+class RingBuffer {
+	// Valid bytes are between consume and produce
+	// Free bytes are between produce and consume
+	// bytes between endbuf-spare and endbuf are neither
+	Ptr		buffer;
+	Ptr		endbuf;
+	Ptr 		consume;
+	Ptr		produce;
+	u_short	free;
+	u_short	valid;
+	u_short	spare;
+	Boolean	lock;
+	Deferred	defproc;
+	void *	arg;
+	
+public:
+				RingBuffer(u_short bufsiz);
+				~RingBuffer();
+	
+	Ptr		Producer(long & len);			//	Find continuous memory for producer
+	Ptr		Consumer(long & len);			//	Find continuous memory for consumer
+	void		Validate(long len);				// Validate this, unallocate rest
+	void 		Invalidate(long len);
+	void		Produce(Ptr from, long & len);//	Allocate, copy & validate
+	void		Consume(Ptr to, long & len);	// Copy & invalidate
+	
+	long		Free()								{ return free;									}		
+	long		Valid()								{ return valid;								}
+	
+	void 		Defer()								{ lock = true;									}
+	void 		Undefer()							{ lock = false; if (defproc) defproc(arg);}
+	Boolean	Locked()								{ return lock;									}
+	void		Later(Deferred def, void * ar){ defproc = def; arg = ar;					}
+	
+	operator void *()								{ return buffer;								}
+};
+
+Boolean GUSIInterrupt();
+
+Boolean CopyIconFamily(short srcResFile, short srcID, short dstResFile, short dstID);
+
+pascal OSErr PPCInit_P();
+
+OSErr AppleTalkIdentity(short & net, short & node);
+
+void CopyC2PStr(const char * cstr, StringPtr pstr);
+
+#endif
diff --git a/Mac/GUSI-mods/into-src/GUSI.r b/Mac/GUSI-mods/into-src/GUSI.r
new file mode 100644
index 0000000..6da7fd6
--- /dev/null
+++ b/Mac/GUSI-mods/into-src/GUSI.r
@@ -0,0 +1,168 @@
+/*********************************************************************
+Project	:	GUSI				-	Grand Unified Socket Interface
+File		:	GUSI.r			-	Include this
+Author	:	Matthias Neeracher
+Language	:	MPW Rez 3.0
+
+$Log$
+Revision 1.1  1998/08/18 14:52:37  jack
+Putting Python-specific GUSI modifications under CVS.
+
+Revision 1.3  1994/12/30  19:33:34  neeri
+Enlargened message box for select folder dialog.
+
+Revision 1.2  1994/08/10  00:34:18  neeri
+Sanitized for universal headers.
+
+Revision 1.1  1994/02/25  02:12:04  neeri
+Initial revision
+
+Revision 0.5  1993/05/21  00:00:00  neeri
+suffixes
+
+Revision 0.4  1993/01/31  00:00:00  neeri
+Daemon
+
+Revision 0.3  1993/01/03  00:00:00  neeri
+autoSpin
+
+Revision 0.2  1992/09/24  00:00:00  neeri
+Don't include CKID, create GUSIRsrc_P.h
+
+Revision 0.1  1992/07/13  00:00:00  neeri
+.rsrc
+
+*********************************************************************/
+
+#include "Types.r"
+#include "GUSIRsrc_P.h"
+
+include "GUSI.rsrc" not 'ckid';
+
+/* Define a resource ('GU…I', GUSIRsrcID) to override GUSI defaults 		
+	To avoid having to change the Rez file every time I introduce another
+	feature, the preprocessor variable GUSI_PREF_VERSION by default keeps
+	everything compatible with version 1.0.2. Just define GUSI_PREF_VERSION
+	to be the version you want to use.
+*/
+
+#ifndef GUSI_PREF_VERSION
+#define GUSI_PREF_VERSION '0102'
+#endif
+
+type 'GU…I' {
+	literal longint	text 	=	'TEXT';	/* Type for creat'ed files 				*/
+	literal longint	mpw	=	'MPS ';	/* Creator for creat'ed files  			*/
+	byte 		noAutoSpin, autoSpin;		/* Automatically spin cursor ?			*/
+#if GUSI_PREF_VERSION > '0102'
+	boolean 	useChdir, dontUseChdir;		/* Use chdir() ?							*/
+	boolean	approxStat, accurateStat;	/* statbuf.st_nlink = # of subdirectories ? */
+#if GUSI_PREF_VERSION >= '0181'
+	boolean	noDelayConsole, DelayConsole;	/* Delay opening console window until needed? */
+	fill		bit[1];
+#else
+	boolean	noTCPDaemon, isTCPDaemon;	/* Inetd client ?							*/
+	boolean	noUDPDaemon, isUDPDaemon;
+#endif
+#if GUSI_PREF_VERSION >= '0150'
+#if GUSI_PREF_VERSION >= '0181'
+	boolean	wantAppleEvents, noAppleEvents; /* Always solicit AppleEvents */
+#else
+	boolean	noConsole, hasConsole;		/* Are we providing our own dev:console ? (Obsolete) */
+#endif
+#if GUSI_PREF_VERSION >= '0180'
+	boolean	autoInitGraf, noAutoInitGraf;	/* Automatically do InitGraf ? */
+	boolean	exclusiveOpen, sharedOpen;	/* Shared open() ? 							*/
+	boolean	noSigPipe, sigPipe;			/* raise SIGPIPE on write to closed PIPE */
+#else
+	fill 		bit[3];
+#endif
+#else
+	fill 		bit[4];
+#endif
+	literal longint = GUSI_PREF_VERSION;
+#if GUSI_PREF_VERSION >= '0120'
+	integer = $$Countof(SuffixArray);
+	wide array SuffixArray {
+			literal longint;					/* Suffix of file */
+			literal longint;					/* Type for file */
+			literal longint;					/* Creator for file */
+	};
+#endif
+#endif
+};
+
+type 'TMPL' {
+	wide array {
+		pstring;
+		literal longint;
+	};
+};
+
+resource 'TMPL' (GUSIRsrcID, "GU…I") {
+	{
+		"Type of created files",		'TNAM',
+		"Creator of created files",	'TNAM',
+		"Automatically spin cursor", 	'DBYT',
+#if GUSI_PREF_VERSION > '0102'
+		"Not using chdir()",				'BBIT',
+		"Accurate stat()",				'BBIT',
+		"TCP daemon",						'BBIT',
+		"UDP daemon",						'BBIT',
+#if GUSI_PREF_VERSION >= '0150'
+		"Own Console",						'BBIT',
+#else
+		"Reserved",							'BBIT',
+#endif
+#if GUSI_PREF_VERSION >= '0180'
+		"Don't initialize QuickDraw",	'BBIT',
+		"Open files shared",				'BBIT',
+		"Raise SIGPIPE",					'BBIT',
+#else
+		"Reserved",							'BBIT',
+		"Reserved",							'BBIT',
+		"Reserved",							'BBIT',
+#endif
+		"Version (don't change)",		'TNAM',		
+#if GUSI_PREF_VERSION >= '0120'
+		"NumSuffices",						'OCNT',
+		"*****",								'LSTC',
+		"Suffix",							'TNAM',
+		"Type for suffix",				'TNAM',
+		"Creator for suffix",			'TNAM',
+		"*****",								'LSTE',
+#endif
+#endif		
+	}
+};
+
+resource 'DLOG' (GUSIRsrcID, "Get Directory") {
+	{0, 0, 217, 348}, 
+	dBoxProc, 
+	invisible, 
+	noGoAway, 
+	0x0, 
+	10240, 
+	"",
+	alertPositionMainScreen
+};
+
+resource 'DITL' (GUSIRsrcID, "Get Directory") {
+	{
+		{ 142, 256,  160, 336},	Button		{enabled,"Open"},
+		{1152,  59, 1232,  77},	Button		{enabled,"Hidden"},
+		{ 193, 256,  211, 336},	Button		{enabled,"Cancel"},
+		{  43, 232,   63, 347},	UserItem		{disabled},
+		{  72, 256,   90, 336},	Button		{enabled,"Eject"},
+		{  97, 256,  115, 336},	Button		{enabled,"Drive"},
+		{  43,  12,  189, 230},	UserItem		{enabled},
+		{  43, 229,  189, 246},	UserItem		{enabled},
+		{ 128, 252,  129, 340},	UserItem		{disabled},
+		{1044,  20, 1145, 116},	StaticText	{disabled,""},
+		{ 167, 256,  185, 336},	Button		{enabled,"Directory"},
+		{   0,  30,   18, 215},	Button		{enabled,"Select Current Directory:"},
+		{ 200,  20, 1145, 222},	StaticText	{disabled,"Select a Folder"}
+	}
+};
+
+
diff --git a/Mac/GUSI-mods/into-src/GUSIDispatch.cp b/Mac/GUSI-mods/into-src/GUSIDispatch.cp
new file mode 100644
index 0000000..86941cb
--- /dev/null
+++ b/Mac/GUSI-mods/into-src/GUSIDispatch.cp
@@ -0,0 +1,1434 @@
+/*********************************************************************
+Project	:	GUSI				-	Grand Unified Socket Interface
+File	:	GUSIDispatch.cp-	Dispatch calls to their correct recipient
+Author	:	Matthias Neeracher
+Language:	MPW C/C++
+
+$Log$
+Revision 1.1  1998/08/18 14:52:37  jack
+Putting Python-specific GUSI modifications under CVS.
+
+Revision 1.4  1994/12/30  19:48:09  neeri
+Remove (theoretical) support for pre-System 6 systems.
+Remove built-in support for INETd.
+Fix problems in connection with ROM PowerPC library.
+Move open() to GUSIFileDispatch.cp.
+Support AF_UNSPEC domains.
+More work on spinning performance.
+
+Revision 1.3  1994/08/10  00:30:30  neeri
+Sanitized for universal headers.
+Prevent overly fast spinning.
+
+Revision 1.2  1994/05/01  23:47:34  neeri
+Extend fflush() kludge.
+Define _lastbuf for MPW 3.2 compatibility.
+
+Revision 1.1  1994/02/25  02:28:36  neeri
+Initial revision
+
+Revision 0.27  1993/11/24  00:00:00  neeri
+Flush stdio before closing
+
+Revision 0.26  1993/11/22  00:00:00  neeri
+Extend two time loser for EBADF
+
+Revision 0.25  1993/11/12  00:00:00  neeri
+Two time loser workaround for flush bug
+
+Revision 0.24  1993/06/27  00:00:00  neeri
+{pre,post}_select
+
+Revision 0.23  1993/06/27  00:00:00  neeri
+ftruncate
+
+Revision 0.22  1993/06/20  00:00:00  neeri
+Further subtleties in console handling 
+
+Revision 0.21  1993/05/21  00:00:00  neeri
+Suffixes
+
+Revision 0.20  1993/05/15  00:00:00  neeri
+Try to keep errno always set on error returns
+
+Revision 0.19  1993/05/13  00:00:00  neeri
+Limit Search for configuration resource to application
+
+Revision 0.18  1993/01/31  00:00:00  neeri
+Introducing daemons (pleased to meet you, hope you guess my name)
+
+Revision 0.17  1993/01/17  00:00:00  neeri
+Be more careful about user aborts.
+
+Revision 0.16  1993/01/03  00:00:00  neeri
+GUSIConfiguration
+
+Revision 0.15  1992/11/25  00:00:00  neeri
+Still trying to get standard descriptors for standalone programs right. sigh.
+
+Revision 0.14  1992/10/05  00:00:00  neeri
+Small fix in event dispatching
+
+Revision 0.13  1992/09/12  00:00:00  neeri
+getdtablesize()
+
+Revision 0.12  1992/08/30  00:00:00  neeri
+Move hasPPC to GUSIPPC.cp, AppleTalkIdentity
+
+Revision 0.11  1992/08/05  00:00:00  neeri
+Change the way standard I/O channels are opened
+
+Revision 0.10  1992/08/03  00:00:00  neeri
+Move Scatter/Gather to GUSIBuffer.cp
+
+Revision 0.9  1992/07/30  00:00:00  neeri
+Features with initializers
+
+Revision 0.8  1992/07/13  00:00:00  neeri
+hasProcessMgr
+
+Revision 0.7  1992/06/27  00:00:00  neeri
+choose(), hasNewSF
+
+Revision 0.6  1992/06/06  00:00:00  neeri
+Feature
+
+Revision 0.5  1992/04/19  00:00:00  neeri
+C++ Rewrite
+
+Revision 0.4  1992/04/18  00:00:00  neeri
+Changed read/write/send/recv dispatchers
+
+Revision 0.3  1992/04/17  00:00:00  neeri
+Spin routines
+
+Revision 0.2  1992/04/16  00:00:00  neeri
+User interrupt stuff
+
+Revision 0.1  1992/03/31  00:00:00  neeri
+unix domain socket calls
+
+*********************************************************************/
+
+#include "GUSIFile_P.h"
+#include "GUSIMPW_P.h"
+#include <SetJmp.h>
+#include <Signal.h>
+#include <CursorCtl.h>
+#include <Resources.h>
+#include <Events.h> 
+#include <Windows.h>
+#include <Finder.h>
+#include <Script.h>
+#include <Events.h>
+#include <Traps.h>
+#include <CommResources.h>
+#include <CTBUtilities.h>
+#include <Connections.h>
+#include <FileTransfers.h>
+#include <Terminals.h>
+#include <EPPC.h>
+#include <PLStringFuncs.h>
+#include <LowMem.h>
+#include <Processes.h>
+
+#if GENERATINGCFM
+#include <CodeFragments.h>
+#endif
+
+#pragma segment GUSI
+
+/***************************** Globals ******************************/
+
+GUSIConfiguration GUSIConfig;		// Change the order of these declarations
+SocketTable					Sockets;			// 	and you'll regret it (ARM §12.6.1)
+GUSISpinFn 					GUSISpin 	= GUSIDefaultSpin;
+GUSIExecFn					GUSIExec	= GUSIDefaultExec;
+GUSIFTypeFn					GUSIFType	= (GUSIFTypeFn)0;
+long						gGUSISpeed	= 1;
+static GUSIEvtHandler *	evtHandler	= nil;
+static short				evtMask		= 0;
+static int					errorSock	= -1;
+static int					errorType	= 0;
+static int					errorCount	= 0;
+const int					errorMax		= 3;
+Boolean						CatchStdIO	= false;
+
+Feature 	hasMakeFSSpec(
+				gestaltFSAttr,
+				(1<<gestaltHasFSSpecCalls),
+				(1<<gestaltHasFSSpecCalls));
+Feature 	hasAlias(
+				gestaltAliasMgrAttr,
+				(1<<gestaltAliasMgrPresent),
+				(1<<gestaltAliasMgrPresent));
+Feature	hasNewSF(
+				gestaltStandardFileAttr,
+				(1<<gestaltStandardFile58),
+				(1<<gestaltStandardFile58));
+Feature 	hasProcessMgr(
+				gestaltOSAttr,
+				(1<<gestaltLaunchControl),
+				(1<<gestaltLaunchControl));
+Feature hasCRM_P(
+				gestaltCRMAttr,
+				(1<<gestaltCRMPresent),
+				(1<<gestaltCRMPresent));
+Feature hasCRM(hasCRM_P, InitCRM);
+Feature hasCTB(hasCRM, InitCTBUtilities);
+Feature hasStdNBP_P(
+				gestaltStdNBPAttr,
+				(1<<gestaltStdNBPPresent),
+				(1<<gestaltStdNBPPresent));
+Feature hasStdNBP(hasCTB, hasStdNBP_P);
+Feature hasAppleEvents(
+				gestaltAppleEventsAttr,
+				(1<<gestaltAppleEventsPresent),
+				(1<<gestaltAppleEventsPresent));
+Feature hasRevisedTimeMgr(
+			gestaltTimeMgrVersion,
+			2L);
+
+/*********************** Error propagation ************************/
+
+#ifdef GUSI_DISPATCH
+inline
+#endif
+int GUSI_error(int err)
+{
+	if (err)
+		errno =	err;
+
+	return -1;
+}
+
+#ifdef GUSI_DISPATCH
+inline
+#endif
+void * GUSI_error_nil(int err)
+{
+	if (err)
+		errno =	err;
+
+	return nil;
+}
+
+/*********************** GUSIConfiguration members ************************/
+
+#ifndef GUSI_DISPATCH
+
+Boolean 	GUSIConfiguration::firstTime = false;
+short		GUSIConfiguration::we;
+
+void GUSIConfiguration::GUSILoadConfiguration(Handle h)
+{
+	typedef 	GUSIConfigRsrc **	GUSIConfHdl;		
+	GUSIConfHdl config 		=	GUSIConfHdl(h);
+	long		confSize	=	config ? GetHandleSize(Handle(config)) : 0;
+	
+	if (confSize < 4 || !(defaultType = (*config)->defaultType))
+		defaultType	=	'TEXT';
+	if (confSize < 8 || !(defaultCreator = (*config)->defaultCreator))
+		defaultCreator	=	'MPS ';
+	if (confSize < 9) 
+		autoSpin	=	1;			// do automatic spin on read/write
+	else
+		autoSpin = (*config)->autoSpin;
+			
+	if (confSize < 14)
+		version = '0102';
+	else
+		version = (*config)->version;
+
+	if (confSize < 10) {
+		noChdir			=	false;	// Use chdir()
+		accurStat		=	false;	// st_nlink = # of entries + 2
+		hasConsole		=	false;
+		noAutoInitGraf	= 	false;
+		sharedOpen		=	false;
+		sigPipe			=	false;
+		noAppleEvents	= 	false;
+		delayConsole		=	false;
+	} else {
+		noChdir			=	((*config)->flags & 0x80) != 0;
+		accurStat		=	((*config)->flags & 0x40) != 0;
+		hasConsole		=	version >= '0150' && version <= '0180' && ((*config)->flags & 0x08) != 0;
+		delayConsole	=	version >= '0181' && ((*config)->flags & 0x20) != 0;
+		noAppleEvents	=	version >= '0181' && ((*config)->flags & 0x08) != 0;
+		noAutoInitGraf	=	version >= '0174' && ((*config)->flags & 0x04) != 0;
+		sharedOpen		=	version >= '0174' && ((*config)->flags & 0x02) != 0;
+		sigPipe			=	version >= '0174' && ((*config)->flags & 0x01) != 0;
+	}
+	
+	if (version < '0120' || confSize < 16)
+		numSuffices = 0;
+	else
+		numSuffices = (*config)->numSuffices;
+	
+	if (!numSuffices)
+		suffices = nil;
+	else if (suffices = new GUSISuffix[numSuffices]) {
+		HLock((Handle)config);
+		memcpy(suffices, (*config)->suffices, numSuffices*sizeof(GUSISuffix));
+		for (int i=0; i<numSuffices; i++)
+			for (int j=0; j<4; j++)
+				if (((char *) (suffices+i))[j] == ' ')
+					((char *) (suffices+i))[j] = 0;
+	}
+}
+
+GUSIConfiguration::GUSIConfiguration()
+{
+	short	oldResFile = CurResFile();
+	
+	if (!firstTime)
+		we = oldResFile;
+	else
+		UseResFile(we);
+		
+	Handle config 	=	Get1Resource('GU…I', GUSIRsrcID);
+	GUSILoadConfiguration(config);	
+	if (!firstTime) {
+		firstTime	=	true;
+		
+		if (!noChdir)
+			chdir(":");
+	} else
+		UseResFile(oldResFile);
+	
+	ReleaseResource((Handle)config);
+}
+
+void GUSIConfiguration::SetDefaultFType(const TFileSpec & name) const
+{
+	FInfo	info;	
+
+	// 
+	// Custom hook if existing
+	//
+	if (GUSIFType && GUSIFType(name))
+		return;
+	
+	//
+	// Otherwise default behaviour
+	//
+	if (HGetFInfo(name.vRefNum, name.parID, name.name, &info))
+		return;
+
+	Ptr dot = PLstrrchr(name.name, '.');
+	
+	if (dot && (name.name[0] - (dot-Ptr(name.name))) <= 4) {
+		char searchsuffix[5];
+		
+		strncpy(searchsuffix, dot+1, name.name[0] - (dot-Ptr(name.name)));
+		
+		for (int i = 0; i<numSuffices; i++)
+			if (!strncmp(suffices[i].suffix, searchsuffix, 4)) {
+				info.fdType 	=	suffices[i].suffType;
+				info.fdCreator	=	suffices[i].suffCreator;
+				
+				goto determined;
+			}
+	}
+
+	info.fdType 	=	defaultType;
+	info.fdCreator	=	defaultCreator;
+	info.fdFlags	&= ~kHasBeenInited;
+
+determined:	
+	HSetFInfo(name.vRefNum, name.parID, name.name, &info);
+}
+
+void GUSIConfiguration::DoAutoInitGraf() const
+{
+	if (*(GrafPtr **) LMGetCurrentA5() != &qd.thePort)
+		InitGraf(&qd.thePort);
+	const_cast<GUSIConfiguration *>(this)->noAutoInitGraf	=	true;
+}
+
+#endif // GUSI_DISPATCH
+
+inline void GUSIConfiguration::DoAutoSpin() const 
+{
+	if (autoSpin)
+		SAFESPIN(0, SP_AUTO_SPIN, autoSpin);
+}
+
+Boolean GUSIConfiguration::DelayConsole() const
+{
+	return delayConsole;
+}
+
+/************************ Handle nonstandard consoles *************************/
+
+#ifndef GUSI_DISPATCH
+
+static void InitConsole()
+{
+	if (MPWDomain::stdopen) {
+		for (int i = 0; i < 3; i++) {
+			Socket * sock = 	MPWDomain::stdopen(i);
+
+			if (sock)
+				Sockets.Install(sock);
+		}
+	} else {
+		if (open("dev:console", O_RDONLY) < 0)
+			open("dev:null", O_RDONLY);
+		if (open("dev:console", O_WRONLY) < 0)
+			open("dev:null", O_WRONLY);
+		if (open("dev:console", O_WRONLY) < 0)
+			open("dev:null", O_WRONLY); 
+	}
+}
+
+void SocketTable::InitConsole()
+{
+	if (needsConsole) {
+		needsConsole = false;
+		::InitConsole();
+	}
+}
+
+#endif // GUSI_DISPATCH
+
+/************************ External routines *************************/
+
+int getdtablesize()
+{
+	return GUSI_MAX_FD;
+}
+
+int socket(int domain, int type, int protocol)
+{
+	SocketDomain *	dom;
+	Socket * 		sock;
+	int				fd;
+
+	Sockets.InitConsole();
+	
+	if (dom = SocketDomain::Domain(domain))
+		if (sock = dom->socket(type, protocol))
+			if ((fd = Sockets.Install(sock)) != -1)
+				return fd;
+			else
+				delete sock;
+
+	if (!errno)
+		return GUSI_error(ENOMEM);
+	else
+		return -1;
+}
+
+int socketpair(int domain, int type, int protocol, int * sv)
+{
+	SocketDomain *	dom;
+	Socket * 		sock[2];
+
+	Sockets.InitConsole();
+	
+	if (dom = SocketDomain::Domain(domain))
+		if (!dom->socketpair(type, protocol, sock))
+			if ((sv[0] = Sockets.Install(sock[0])) != -1)
+				if ((sv[1] = Sockets.Install(sock[1])) != -1)
+					return 0;
+				else {
+					Sockets.Remove(sv[0]);
+					
+					goto failInstall;
+				}
+			else {
+failInstall:
+				delete sock[0];
+				delete sock[1];
+			}
+		
+	if (!errno)
+		return GUSI_error(ENOMEM);
+	else
+		return -1;
+}
+
+int pipe(int * fd)
+{
+	GUSIwithUnixSockets();
+	
+	if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd))
+		return -1;
+	shutdown(fd[0], 1);
+	shutdown(fd[1], 0);
+	
+	return 0;
+}
+
+int choose(int domain, int type, char * prompt, void * constraint, int flags, void * name, int * namelen)
+{
+	SocketDomain *	dom;
+
+	if (dom = SocketDomain::Domain(domain))
+		return dom->choose(type, prompt, constraint, flags, name, namelen);
+
+	return -1;
+}
+
+int bind(int s, const struct sockaddr *name, int namelen)
+{
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->bind((void *) name, namelen) : -1;
+}
+
+int connect(int s, const struct sockaddr *addr, int addrlen)
+{
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->connect((void *) addr, addrlen) : -1;
+}
+
+int listen(int s, int qlen)
+{
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->listen(qlen) : -1;
+}
+
+int accept(int s, struct sockaddr *addr, int *addrlen)
+{
+	Socket *	sock	=	Sockets[s];
+
+	if (sock)
+		if (sock	= sock->accept(addr, addrlen))
+			if ((s = Sockets.Install(sock)) != -1)
+				return s;
+			else
+				delete sock;
+
+	return -1;
+}
+
+int close(int s)
+{
+	errorSock	=	-1;
+	
+	return Sockets.Remove(s);
+}
+
+#ifdef __MWERKS__
+int read(int s, char *buffer, int buflen)
+#else
+int read(int s, char *buffer, unsigned buflen)
+#endif
+{
+	GUSIConfig.DoAutoSpin();
+	
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->read(buffer, (unsigned) buflen) : -1;
+}
+
+int readv(int s, const struct iovec *iov, int count)
+{
+	GUSIConfig.DoAutoSpin();
+	
+	Socket *	sock	=	Sockets[s];
+
+	if (sock)	{
+		Scatterer	scatt(iov, count);
+
+		if (scatt)
+			return scatt.length(sock->read(scatt.buffer(), scatt.buflen()));
+		else
+			return GUSI_error(ENOMEM);
+	} else
+		return -1;
+}
+
+int recv(int s, void *buffer, int buflen, int flags)
+{
+	GUSIConfig.DoAutoSpin();
+	
+	int 		fromlen 	=	0;
+	Socket *	sock		=	Sockets[s];
+
+	return sock ? sock->recvfrom(buffer, buflen, flags, nil, &fromlen) : -1;
+}
+
+int recvfrom(int s, void *buffer, int buflen, int flags, struct sockaddr *from, int *fromlen)
+{
+	GUSIConfig.DoAutoSpin();
+	
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->recvfrom(buffer, buflen, flags, from, fromlen) : -1;
+}
+
+int recvmsg(int s, struct msghdr *msg, int flags)
+{
+	GUSIConfig.DoAutoSpin();
+	
+	Socket *	sock	=	Sockets[s];
+
+	if (sock)	{
+		Scatterer	scatt((struct iovec *)msg->msg_iov, msg->msg_iovlen);
+
+		if (scatt)
+			return
+				scatt.length(
+					sock->recvfrom(
+						scatt.buffer(),
+						scatt.buflen(),
+						flags,
+						msg->msg_name,
+						(int *)&msg->msg_namelen));
+		else
+			return GUSI_error(ENOMEM);
+	} else
+		return -1;
+}
+
+#ifdef __MWERKS__
+int write(int s, const char *buffer, int buflen)
+#else
+int write(int s, const char *buffer, unsigned buflen)
+#endif
+{
+	/* fflush() in the MPW stdio library doesn't take no for an answer.
+		Our workaround is to treat a second subsequent ESHUTDOWN or EBADF as 
+		an invitation to lie by pretending the write worked.
+	*/
+	
+	int	len;
+	
+	GUSIConfig.DoAutoSpin();
+	
+	Socket *	sock	=	Sockets[s];
+
+	if (sock && (len = sock->write((char *) buffer, (unsigned) buflen)) != -1)
+		return len;
+		
+	switch (errno) {
+	case EINTR:
+	case EWOULDBLOCK:
+	case EINPROGRESS:
+	case EALREADY:
+		break;
+	default:
+		if (GUSIConfig.sigPipe)
+			raise(SIGPIPE);
+		if (errorSock == s && errorType == errno) {
+			if (++errorCount == errorMax) {
+				errorSock = -1;
+			
+				return buflen;
+			}
+		} else {
+			errorSock = s;
+			errorType = errno;
+			errorCount= 1;
+		}
+	}
+	return -1;
+}
+
+static int HandleWriteErrors(int retval)
+{
+	if (retval == -1)
+		switch (errno) {
+		case EINTR:
+		case EWOULDBLOCK:
+		case EINPROGRESS:
+		case EALREADY:
+			break;
+		default:
+			if (GUSIConfig.sigPipe)
+				raise(SIGPIPE);
+			break;
+		}
+	
+	return retval;
+}
+
+int writev(int s, const struct iovec *iov, int count)
+{
+	GUSIConfig.DoAutoSpin();
+	
+	Socket *	sock	=	Sockets[s];
+
+	if (sock)	{
+		Gatherer	gath(iov, count);
+
+		if (gath)
+			return HandleWriteErrors(gath.length(sock->write(gath.buffer(), gath.buflen())));
+		else
+			return GUSI_error(ENOMEM);
+	} else
+		return -1;
+}
+
+int send(int s, const void *buffer, int buflen, int flags)
+{
+	GUSIConfig.DoAutoSpin();
+	
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? HandleWriteErrors(sock->sendto((void *)buffer, buflen, flags, nil, 0)) : -1;
+}
+
+int sendto(int s, const void *buffer, int buflen, int flags, const struct sockaddr *to, int tolen)
+{
+	GUSIConfig.DoAutoSpin();
+	
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? HandleWriteErrors(sock->sendto((void *)buffer, buflen, flags, (void *) to, tolen)) : -1;
+}
+
+int sendmsg(int s, const struct msghdr *msg, int flags)
+{
+	GUSIConfig.DoAutoSpin();
+	
+	Socket *	sock	=	Sockets[s];
+
+	if (sock)	{
+		Gatherer	gath((struct iovec *) msg->msg_iov, msg->msg_iovlen);
+
+		if (gath)
+			return
+				HandleWriteErrors(gath.length(
+					sock->sendto(
+						gath.buffer(),
+						gath.buflen(),
+						flags,
+						msg->msg_name,
+						msg->msg_namelen)));
+		else
+			return GUSI_error(ENOMEM);
+	} else
+		return -1;
+}
+
+int select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
+{
+	Socket	*	sock;
+	long 			count;
+	int 			s;
+	long 			starttime, waittime;
+	fd_set 		rd, wd, ed;
+	Boolean		r,w,e;
+	Boolean *	canRead;
+	Boolean *	canWrite;
+	Boolean *	exception;
+
+	count = 0;
+	FD_ZERO(&rd);
+	FD_ZERO(&wd);
+	FD_ZERO(&ed);
+
+	if (timeout)
+		waittime =  timeout->tv_sec*60 + timeout->tv_usec/16666;
+	else
+		waittime =	2000000000;	// Slightly more than a year; close enough to "no timeout"
+		
+	starttime = LMGetTicks();
+
+	// Check files for kosherness
+
+	for (s = 0; s < width ; ++s)
+		if (	(readfds && FD_ISSET(s,readfds))
+			||	(writefds && FD_ISSET(s,writefds))
+			||	(exceptfds && FD_ISSET(s,exceptfds))
+		)
+			if (!Sockets[s])
+				return GUSI_error(EBADF);
+	
+	for (s = 0; s < width ; ++s)
+		if (sock = Sockets[s]) {
+			r = readfds && FD_ISSET(s,readfds);
+			w = writefds && FD_ISSET(s,writefds);
+			e = exceptfds && FD_ISSET(s,exceptfds);
+
+			if (r || w || e)
+				sock->pre_select(r, w, e);
+		}
+		
+	do {
+		for (s = 0; s < width ; ++s)  {
+			if (sock = Sockets[s]) {
+				r = false;
+				w = false;
+				e = false;
+
+				canRead = (readfds && FD_ISSET(s,readfds)) ? &r : nil;
+				canWrite = (writefds && FD_ISSET(s,writefds)) ? &w : nil;
+				exception = (exceptfds && FD_ISSET(s,exceptfds)) ? &e : nil;
+
+				if (canRead || canWrite || exception)	{
+					count	+= sock->select(canRead, canWrite, exception);
+
+					if (r)
+						FD_SET(s,&rd);
+					if (w)
+						FD_SET(s,&wd);
+					if (e)
+						FD_SET(s,&ed);
+				}
+			}
+		}
+		if (count)
+			break;
+
+		SAVE_AND_CLEAR_ERRNO;
+		SAFESPIN(false, SP_SELECT, waittime);
+
+		if (errno) {
+			count = -1;
+			
+			break;
+		}
+	}  while (LMGetTicks() - starttime < waittime);
+
+	for (s = 0; s < width ; ++s)
+		if (sock = Sockets[s]) {
+			r = readfds && FD_ISSET(s,readfds);
+			w = writefds && FD_ISSET(s,writefds);
+			e = exceptfds && FD_ISSET(s,exceptfds);
+
+			if (r || w || e)
+				sock->post_select(r, w, e);
+		}
+		
+	if (count < 0)
+		return GUSI_error(EINTR);
+		
+	if (readfds)
+		*readfds = rd;
+	if (writefds)
+		*writefds = wd;
+	if (exceptfds)
+		*exceptfds = ed;
+
+	return count;
+}
+
+int getsockname(int s, struct sockaddr *name, int *namelen)
+{
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->getsockname(name, namelen) : -1;
+}
+
+int getpeername(int s, struct sockaddr *name, int *namelen)
+{
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->getpeername(name, namelen) : -1;
+}
+
+int shutdown(int s, int how)
+{
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->shutdown(how) : -1;
+}
+
+int fcntl(int s, unsigned int cmd, int arg)
+{
+	Socket *	sock	=	Sockets[s];
+
+	if (sock)
+		return (cmd == F_DUPFD) ? Sockets.Install(sock, arg) : sock->fcntl(cmd, arg);
+	else
+		return -1;
+}
+
+int dup(int s)
+{
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? Sockets.Install(sock) : -1;
+}
+
+int dup2(int s, int s1)
+{
+	Socket *	sock	=	Sockets[s];
+
+	if (!sock)
+		return -1;
+
+	if (Sockets[s1])
+		Sockets.Remove(s1);
+
+	return Sockets.Install(sock, s1);
+}
+
+int ioctl(int s, unsigned int request, long *argp)
+{
+	Socket *	sock	=	Sockets[s];
+
+	if (!sock)
+		return -1;
+	
+	return sock->ioctl(request, argp);
+}
+
+int getsockopt(int s, int level, int optname, void *optval, int * optlen)
+{
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->getsockopt(level, optname, optval, optlen) : -1;
+}
+
+int setsockopt(int s, int level, int optname, const void *optval, int optlen)
+{
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->setsockopt(level, optname, (void *) optval, optlen) : -1;
+}
+
+int fstat(int s, struct stat * buf)
+{
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->fstat(buf) : -1;
+}
+
+long lseek(int s, long offset, int whence)
+{
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->lseek(offset, whence) : -1;
+}
+
+int ftruncate(int s, long offset)
+{
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->ftruncate(offset) : -1;
+}
+
+int isatty(int s)
+{
+	Socket *	sock	=	Sockets[s];
+
+	return sock ? sock->isatty() : -1;
+}
+
+void GUSISetHook(GUSIHookCode code, GUSIHook hook)
+{
+	switch (code) {
+	case GUSI_SpinHook:
+		GUSISpin = (GUSISpinFn) hook;
+		break;
+	case GUSI_ExecHook:
+		GUSIExec = (GUSIExecFn) hook;
+		break;
+	case GUSI_FTypeHook:
+		GUSIFType = (GUSIFTypeFn) hook;
+		break;
+	case GUSI_SpeedHook:
+		gGUSISpeed = (long) hook;
+		break;
+	}
+}
+
+GUSIHook GUSIGetHook(GUSIHookCode code)
+{
+	switch (code) {
+	case GUSI_SpinHook:
+		return (GUSIHook) GUSISpin;
+	case GUSI_ExecHook:
+		return (GUSIHook) GUSIExec;
+	case GUSI_FTypeHook:
+		return (GUSIHook) GUSIFType;
+	case GUSI_SpeedHook:
+		return (GUSIHook) gGUSISpeed;
+		break;
+	default:
+		return (GUSIHook) nil;
+	}
+}
+
+int GUSISetEvents(GUSIEvtTable table)
+{
+	short	evt;
+
+	evtHandler	=	table;
+	evtMask		=	0;
+
+	for (evt = 0; evt<16; ++evt)
+		if (evtHandler[evt])
+			evtMask	|=	1 << evt;
+
+	return 0;
+}
+
+GUSIEvtHandler * GUSIGetEvents(void)
+{
+	return evtHandler;
+}
+
+/*********************** SocketDomain members ***********************/
+
+#ifndef GUSI_DISPATCH
+
+SocketDomain *			SocketDomain::domains[GUSI_MAX_DOMAIN];
+ProcessSerialNumber	SocketDomain::process;
+
+SocketDomain * SocketDomain::Domain(int domain)
+{
+	if (domain < 0 || domain >= GUSI_MAX_DOMAIN || !domains[domain])	{
+		GUSI_error(EINVAL);
+
+		return nil;
+	} else
+		return domains[domain];
+}
+
+void SocketDomain::Ready()
+{
+	if (hasProcessMgr)
+		WakeUpProcess(&process);
+}
+
+SocketDomain::SocketDomain(int domain)
+{
+#ifdef PREVENT_DUPLICATE_DOMAINS
+	if (domains[domain])	{
+		Str63	msg;
+
+		sprintf((char *) msg+1, "Duplicate declaration for domain %d\n", domain);
+		msg[0] = (unsigned char)strlen((char *) msg+1);
+
+		DebugStr(msg);
+	}
+#endif
+	if (domain)									// Ignore AF_UNSPEC domains
+		domains[domain]	=	this;
+	
+	if (hasProcessMgr && !process.highLongOfPSN && !process.lowLongOfPSN)
+		GetCurrentProcess(&process);
+}
+
+SocketDomain::~SocketDomain()
+{
+}
+
+// Default implementations of socket() just returns an error
+
+Socket * SocketDomain::socket(int, short)
+{
+	GUSI_error(EOPNOTSUPP);
+
+	return nil;
+}
+
+// Same with socketpair
+
+int SocketDomain::socketpair(int, short, Socket **)
+{
+	return GUSI_error(EOPNOTSUPP);
+}
+
+
+int SocketDomain::choose(int, char *, void *, int, void *, int *)
+{
+	return GUSI_error(EOPNOTSUPP);
+}
+
+void SocketDomain::DontStrip()
+{
+}
+
+/*********************** SocketTable members ************************/
+
+static void FlushStdio()
+{
+	fwalk(fflush);
+}
+
+SocketTable::SocketTable()
+{
+	atexit(FlushStdio);
+	
+	needsConsole = true;
+}
+	
+int SocketTable::Install(Socket * sock, int start)
+{
+	short	fd;
+
+	if (start<0 || start >= GUSI_MAX_FD)
+		return GUSI_error(EINVAL);
+
+	for (fd=start; fd<GUSI_MAX_FD; ++fd)
+		if (!sockets[fd])	{
+			sockets[fd] = sock;
+		
+			++sock->refCount;
+			return fd;
+		}
+
+	return GUSI_error(EMFILE);
+}
+
+int SocketTable::Remove(int fd)
+{
+	Socket *	sock;
+
+	InitConsole();
+
+	if (fd<0 || fd >= GUSI_MAX_FD || !(sock = sockets[fd]))
+		return GUSI_error(EBADF);
+
+	sockets[fd] 	=	nil;
+
+	if (!--sock->refCount)
+		delete sock;
+
+	return 0;
+}
+
+Socket * SocketTable::operator[](int fd)
+{
+	Socket * sock;
+
+	InitConsole();
+	
+	if (fd<0 || fd >= GUSI_MAX_FD || !(sock = sockets[fd]))	{
+		GUSI_error(EBADF);
+
+		return nil;
+	} else
+		return sock;
+}
+
+#ifndef powerc
+#pragma far_code
+#endif
+
+SocketTable::~SocketTable()
+{
+	int i;
+
+	// Flush stdio files (necessary to flush buffers)
+
+	fwalk(fflush);
+
+	// If we didn't need a console so far, we certainly don't need one now!
+	// Doing this further up would be dangerous for small write only apps
+	
+	needsConsole = false;
+
+	// Now close stdio files, just to be sure
+
+	fwalk(fclose);
+
+	// Close all files
+
+	for (i = 0; i<GUSI_MAX_FD; ++i)
+		if (sockets[i])
+			close(i);
+}
+
+#endif // GUSI_DISPATCH
+
+/********************** sleep()/alarm() ***********************/
+
+static long	GUSIAlarm = 0;
+
+int GUSICheckAlarm()
+{
+	if (GUSIAlarm && LMGetTicks() > GUSIAlarm) {
+		GUSIAlarm = 0;
+		raise(SIGALRM);
+		
+		return 1;
+	} else
+		return 0;
+}
+
+u_int	 alarm(u_int seconds)
+{
+	long remaining = GUSIAlarm ? (LMGetTicks() - GUSIAlarm) / 60 : 0;
+	
+	GUSIAlarm = seconds ? LMGetTicks() + 60 * seconds : 0;
+	
+	return (remaining < 0) ? 0 : (u_int) remaining;
+}
+
+static u_int DoSleep(long ticks)
+{
+	long wakeup = LMGetTicks() + ticks;
+	
+	SAFESPIN(wakeup > LMGetTicks(), SP_SLEEP, wakeup - LMGetTicks());
+	
+	long remaining = (LMGetTicks() - wakeup) / 60;
+	
+	return (remaining < 0) ? 0 : (u_int) remaining;
+}
+
+u_int sleep(u_int seconds) 
+{
+	return DoSleep(seconds * 60);
+}
+
+void usleep(u_int useconds)
+{
+	DoSleep((useconds * 3) / 50000);
+}
+
+/********************** Default spin function ***********************/
+
+#ifndef GUSI_DISPATCH
+
+#ifndef powerc
+#pragma smart_code
+#endif
+
+/* Borrowed from tech note 263 */
+
+#define kMaskModifiers  	0xFE00     	// we need the modifiers without the
+                                   		// command key for KeyTrans
+#define kMaskVirtualKey 	0x0000FF00 	// get virtual key from event message
+                                   		// for KeyTrans
+#define kUpKeyMask      	0x0080
+#define kShiftWord      	8          	// we shift the virtual key to mask it
+                                   		// into the keyCode for KeyTrans
+#define kMaskASCII1     	0x00FF0000 	// get the key out of the ASCII1 byte
+#define kMaskASCII2     	0x000000FF 	// get the key out of the ASCII2 byte
+#define kPeriod         	0x2E       	// ascii for a period
+
+static Boolean CmdPeriod(EventRecord *theEvent)
+{
+  	Boolean  fTimeToQuit;
+  	short    keyCode;
+  	long     virtualKey, keyInfo, lowChar, highChar, keyCId;
+  	UInt32	state;
+  	Handle   hKCHR;
+	Ptr 		KCHRPtr;
+
+	fTimeToQuit = false;
+
+	if (((*theEvent).what == keyDown) || ((*theEvent).what == autoKey)) {
+
+		// see if the command key is down.  If it is, find out the ASCII
+		// equivalent for the accompanying key.
+
+		if ((*theEvent).modifiers & cmdKey ) {
+
+			virtualKey = ((*theEvent).message & kMaskVirtualKey) >> kShiftWord;
+			// And out the command key and Or in the virtualKey
+			keyCode    = short(((*theEvent).modifiers & kMaskModifiers) | virtualKey);
+			state      = 0;
+
+			hKCHR = nil;  /* set this to nil before starting */
+		 	KCHRPtr = (Ptr)GetScriptManagerVariable(smKCHRCache);
+
+			if ( !KCHRPtr ) {
+				keyCId = GetScriptVariable(short(GetScriptManagerVariable(smKeyScript)), smScriptKeys);
+
+				hKCHR   = GetResource('KCHR',short(keyCId));
+				KCHRPtr = *hKCHR;
+			}
+
+			if (KCHRPtr) {
+				keyInfo = KeyTrans(KCHRPtr, keyCode, &state);
+				if (hKCHR)
+					ReleaseResource(hKCHR);
+			} else
+				keyInfo = (*theEvent).message;
+
+			lowChar =  keyInfo &  kMaskASCII2;
+			highChar = (keyInfo & kMaskASCII1) >> 16;
+			if (lowChar == kPeriod || highChar == kPeriod)
+				fTimeToQuit = true;
+
+		}  // end the command key is down
+	}  // end key down event
+
+	return( fTimeToQuit );
+}
+
+Boolean GUSIInterrupt()
+{
+	EvQElPtr		eventQ;
+
+	for (eventQ = (EvQElPtr) LMGetEventQueue()->qHead; eventQ; )
+		if (CmdPeriod((EventRecord *) &eventQ->evtQWhat))
+			return true;
+		else
+			eventQ = (EvQElPtr)eventQ->qLink;
+	
+	return false;
+}
+
+int StandAlone = 1;
+long gGUSISpinControl = 0;
+
+int GUSIDefaultSpin(spin_msg msg, long arg)
+{
+	static Boolean			inForeground	=	true;
+	WindowPtr				win;
+	EventRecord				ev;
+	long					sleepTime	=	6;	// 1/10 of a second by default
+	short					mask 		= 	osMask|highLevelEventMask|mDownMask|evtMask;
+
+	GUSIConfig.AutoInitGraf();
+	
+	if (inForeground) {
+		register long contrib = (msg == SP_AUTO_SPIN) ? arg : gGUSISpeed;
+		gGUSISpinControl += contrib;
+		// Tweak when a spin point has been overshot
+		RotateCursor((gGUSISpinControl & 31) < contrib ? 32 : gGUSISpinControl);
+	}
+
+	if (GUSIInterrupt())
+		goto interrupt;
+
+	if (!StandAlone && inForeground)		// For MPW tools, SpinCursor already calls WNE
+		if (!GUSIConfig.noAppleEvents)			// but it no longer reports AppleEvents
+			mask = highLevelEventMask|evtMask;
+		else
+			return 0;								
+		
+	switch (msg) {
+	case SP_SLEEP:
+	case SP_SELECT:
+		if (arg >= sleepTime)				// Only sleep if patience guaranteed
+			break;
+		// Otherwise, fall through	
+	case SP_AUTO_SPIN:
+		sleepTime = 0;
+		break;
+	default:
+		break;
+	}
+	
+	if (WaitNextEvent(mask, &ev, sleepTime, nil))
+		switch (ev.what) {
+		case mouseDown:
+			if (!evtHandler || !evtHandler[mouseDown])
+				if (FindWindow(ev.where, &win) == inSysWindow)
+					SystemClick(&ev, win);
+
+			break;
+		case osEvt:
+			if (ev.message & 1)
+				inForeground	=	true;
+			else
+				inForeground	=	false;
+			break;
+		case kHighLevelEvent:
+			if (!evtHandler || !evtHandler[kHighLevelEvent])
+				if (hasAppleEvents)				// actually pretty likely, if we get HL Events
+					AEProcessAppleEvent(&ev);	// Ignore errors
+			break;
+		default:
+			break;
+		}
+
+	if (ev.what >= 0 && ev.what < 24 && evtHandler && evtHandler[ev.what])
+		evtHandler[ev.what](&ev);
+
+	return 0;
+
+interrupt:
+	FlushEvents(-1, 0);
+
+	return -1;
+}
+
+/************************** Feature members **************************/
+
+Feature::Feature(unsigned short trapNum, TrapType tTyp)
+{
+	good =
+		NGetTrapAddress(trapNum, tTyp) != NGetTrapAddress(_Unimplemented, ToolTrap);
+}
+
+Feature::Feature(OSType type, long value)
+{
+	long		attr;
+
+	good = (!Gestalt(type, &attr) && (attr >= value));
+}
+
+Feature::Feature(OSType type, long mask, long value)
+{
+	long		attr;
+
+	good = (!Gestalt(type, &attr) && ((attr & mask) == value));
+}
+
+Feature::Feature(const Feature & precondition, OSErrInitializer init)
+{
+	good	=	precondition && !init();
+}
+
+Feature::Feature(OSErrInitializer init)
+{
+	good	=	!init();
+}
+
+Feature::Feature(const Feature & precondition, voidInitializer init)
+{
+	if (precondition)	{
+		good = true;
+		init();
+	} else
+		good = false;
+}
+
+Feature::Feature(voidInitializer init)
+{
+	good = true;
+	init();
+}
+
+Feature::Feature(const Feature & cond1, const Feature & cond2)
+{
+	good = cond1 && cond2;
+}
+
+OSErr AppleTalkIdentity(short & net, short & node)
+{
+	static short	mynet;
+	static short	mynode;
+	static OSErr	err = 1;
+
+	if (err == 1)
+		if (!(err = MPPOpen()))
+			err = GetNodeAddress(&mynode, &mynet);
+
+
+	net	=	mynet;
+	node	=	mynode;
+
+	return err;
+}
+
+/************************** Setup suppport **************************/
+
+/* Pray that the following function never inlines GUSISetup */
+
+void GUSIDefaultSetup()
+{
+	GUSISetup(GUSIwithAppleTalkSockets);
+	GUSISetup(GUSIwithInternetSockets);
+	GUSISetup(GUSIwithPAPSockets);
+	GUSISetup(GUSIwithPPCSockets);
+	GUSISetup(GUSIwithUnixSockets);
+	GUSISetup(GUSIwithSIOUXSockets);
+}
+
+void GUSISetup(void (*proc)())
+{
+	proc();
+}
+
+void GUSILoadConfiguration(Handle hdl)
+{
+	GUSIConfig.GUSILoadConfiguration(hdl);
+}
+
+#endif // GUSI_DISPATCH
diff --git a/Mac/GUSI-mods/into-src/GUSINetDB.cp b/Mac/GUSI-mods/into-src/GUSINetDB.cp
new file mode 100644
index 0000000..bc435b6
--- /dev/null
+++ b/Mac/GUSI-mods/into-src/GUSINetDB.cp
@@ -0,0 +1,579 @@
+/*********************************************************************
+Project	:	GUSI				-	Grand Unified Socket Interface
+File		:	GUSINetDB.cp	-	Convert internet names to adresses
+Author	:	Matthias Neeracher
+
+	This file was derived from the socket library by
+
+		Charlie Reiman	<creiman@ncsa.uiuc.edu> and
+		Tom Milligan	<milligan@madhaus.utcs.utoronto.ca>
+
+Language	:	MPW C++
+
+$Log$
+Revision 1.1  1998/08/18 14:52:38  jack
+Putting Python-specific GUSI modifications under CVS.
+
+Revision 1.3  1994/08/10  00:07:30  neeri
+Sanitized for universal headers.
+
+Revision 1.2  1994/05/01  23:43:31  neeri
+getservbyname() without /etc/services would fail.
+
+Revision 1.1  1994/02/25  02:29:36  neeri
+Initial revision
+
+Revision 0.5  1993/10/31  00:00:00  neeri
+Deferred opening of resolver
+
+Revision 0.4  1993/07/29  00:00:00  neeri
+Real getservent code (adapted from Sak Wathanasin)
+
+Revision 0.3  1993/01/19  00:00:00  neeri
+Can't set aliases to NULL.
+
+Revision 0.2  1992/11/21  00:00:00  neeri
+Remove force_active
+
+Revision 0.1  1992/09/14  00:00:00  neeri
+Maybe it works, maybe it doesn't
+
+*********************************************************************/
+
+#include "GUSIINET_P.h"
+
+#include "TFileSpec.h"
+#include "Folders.h"
+#include "PLStringFuncs.h"
+
+#ifdef __MWERKS__
+//
+// I disapprove of the way dnr.c is written
+// This disapproval gets stronger with every version
+//
+#include "dnr.c"
+#pragma require_prototypes reset
+#pragma cplusplus reset
+#endif
+
+#if GENERATING68K
+#pragma segment GUSIINET
+#endif
+
+static pascal void DNRDone(struct hostInfo *, Boolean * done)
+{
+	*done = true;
+}
+
+#if GENERATINGCFM
+RoutineDescriptor	uDNRDone = 
+		BUILD_ROUTINE_DESCRIPTOR(uppResultProcInfo, DNRDone);
+#else
+#define uDNRDone DNRDone
+#endif
+
+int h_errno;
+
+/*
+ *   Gethostbyname and gethostbyaddr each return a pointer to an
+ *   object with the following structure describing an Internet
+ *   host referenced by name or by address, respectively. This
+ *   structure contains the information obtained from the MacTCP
+ *   name server.
+ *
+ *   struct    hostent
+ *   {
+ *        char *h_name;
+ *        char **h_aliases;
+ *        int  h_addrtype;
+ *        int  h_length;
+ *        char **h_addr_list;
+ *   };
+ *   #define   h_addr  h_addr_list[0]
+ *
+ *   The members of this structure are:
+ *
+ *   h_name       Official name of the host.
+ *
+ *   h_aliases    A zero terminated array of alternate names for the host.
+ *
+ *   h_addrtype   The type of address being  returned; always AF_INET.
+ *
+ *   h_length     The length, in bytes, of the address.
+ *
+ *   h_addr_list  A zero terminated array of network addresses for the host.
+ *
+ *   Error return status from gethostbyname and gethostbyaddr  is
+ *   indicated by return of a null pointer.  The external integer
+ *   h_errno may then  be checked  to  see  whether  this  is  a
+ *   temporary  failure  or  an  invalid  or  unknown  host.  The
+ *   routine herror  can  be  used  to  print  an error  message
+ *   describing the failure.  If its argument string is non-NULL,
+ *   it is printed, followed by a colon and a space.   The  error
+ *   message is printed with a trailing newline.
+ *
+ *   h_errno can have the following values:
+ *
+ *     HOST_NOT_FOUND  No such host is known.
+ *
+ *     TRY_AGAIN	This is usually a temporary error and
+ *					means   that  the  local  server  did  not
+ *					receive a response from  an  authoritative
+ *					server.   A  retry at some later time may
+ *					succeed.
+ *
+ *     NO_RECOVERY	Some unexpected server failure was encountered.
+ *	 				This is a non-recoverable error.
+ *
+ *     NO_DATA		The requested name is valid but  does  not
+ *					have   an IP  address;  this  is not  a
+ *					temporary error. This means that the  name
+ *					is known  to the name server but there is
+ *					no address  associated  with  this  name.
+ *					Another type of request to the name server
+ *					using this domain name will result in  an
+ *					answer;  for example, a mail-forwarder may
+ *					be registered for this domain.
+ *					(NOT GENERATED BY THIS IMPLEMENTATION)
+ */
+
+static struct hostInfo macHost;
+
+#define MAXALIASES 0
+static char *aliasPtrs[MAXALIASES+1] = {NULL};
+static ip_addr *addrPtrs[NUM_ALT_ADDRS+1];
+
+static struct hostent  unixHost =
+{
+	macHost.cname,
+	aliasPtrs,
+	AF_INET,
+	sizeof(ip_addr),
+	(char **) addrPtrs
+};
+
+inline struct in_addr make_in_addr(ip_addr addr)
+{
+	struct in_addr	res;
+
+	res.s_addr	=	addr;
+
+	return res;
+}
+
+struct hostent * gethostbyname(char *name)
+{
+	Boolean done;
+	int i;
+
+	if (!strcmp(name, "localhost")) {
+		in_addr ipaddr;
+
+		ipaddr	=	make_in_addr(ip_addr(gethostid()));
+
+		if (ipaddr.s_addr)
+			return gethostbyaddr((char *) &ipaddr, sizeof(in_addr), AF_INET);
+
+		h_errno = HOST_NOT_FOUND;
+			
+		return NULL;
+	}
+	
+	if (INETSockets.Resolver()) {
+		h_errno = NO_RECOVERY;	
+		return NULL;
+	}
+	
+	for (i=0; i<NUM_ALT_ADDRS; i++)
+		macHost.addr[i] = 0;
+
+	done = false;
+
+	if (StrToAddr(name, &macHost, ResultUPP(&uDNRDone), (char *) &done) == cacheFault)
+		SPINP(!done,SP_NAME,0L);
+
+	switch (macHost.rtnCode) {
+	case noErr: break;
+
+	case nameSyntaxErr:	h_errno = HOST_NOT_FOUND;	return(NULL);
+	case cacheFault:		h_errno = NO_RECOVERY;		return(NULL);
+	case noResultProc:	h_errno = NO_RECOVERY;		return(NULL);
+	case noNameServer:	h_errno = HOST_NOT_FOUND;	return(NULL);
+	case authNameErr:		h_errno = HOST_NOT_FOUND;	return(NULL);
+	case noAnsErr:			h_errno = TRY_AGAIN;			return(NULL);
+	case dnrErr:			h_errno = NO_RECOVERY;		return(NULL);
+	case outOfMemory:		h_errno = TRY_AGAIN;			return(NULL);
+	default:					h_errno = NO_RECOVERY;		return(NULL);
+	}
+
+	/* was the 'name' an IP address? */
+	if (macHost.cname[0] == 0) {
+		h_errno = HOST_NOT_FOUND;
+		return(NULL);
+	}
+
+	/* for some reason there is a dot at the end of the name */
+	i = int(strlen(macHost.cname)) - 1;
+	if (macHost.cname[i] == '.')
+		macHost.cname[i] = 0;
+
+	for (i=0; i<NUM_ALT_ADDRS && macHost.addr[i]!=0; i++)
+		addrPtrs[i] =	(ip_addr *) &macHost.addr[i];
+
+	addrPtrs[i] = NULL;
+
+	return &unixHost;
+}
+
+struct hostent * gethostbyaddr(const char *addrP, int, int)
+{
+	Boolean	done;
+	int 		i;
+
+	if (INETSockets.Resolver()) {
+		h_errno = NO_RECOVERY;	
+		return NULL;
+	}
+
+	for (i=0; i<NUM_ALT_ADDRS; i++)
+		macHost.addr[i] = 0;
+
+	done = false;
+
+	ip_addr addr = FIX_LOOPBACK(*(ip_addr *)addrP);
+	
+	if (AddrToName(addr, &macHost, ResultUPP(&uDNRDone), (char *) &done) == cacheFault)
+		SPINP(!done,SP_ADDR,0L);
+
+	switch (macHost.rtnCode) {
+	case noErr: 			break;
+
+	case cacheFault:		h_errno = NO_RECOVERY;		return(NULL);
+	case noNameServer:	h_errno = HOST_NOT_FOUND;	return(NULL);
+	case authNameErr:		h_errno = HOST_NOT_FOUND;	return(NULL);
+	case noAnsErr:			h_errno = TRY_AGAIN;			return(NULL);
+	case dnrErr:			h_errno = NO_RECOVERY;		return(NULL);
+	case outOfMemory:		h_errno = TRY_AGAIN;			return(NULL);
+	default:					h_errno = NO_RECOVERY;		return(NULL);
+	}
+
+	/* for some reason there is a dot at the end of the name */
+	i = int(strlen(macHost.cname)) - 1;
+	if (macHost.cname[i] == '.')
+		macHost.cname[i] = 0;
+
+	/* For some reason, the IP address usually seems to be set to 0 */
+	if (!macHost.addr[0])
+		macHost.addr[0] = addr;
+		
+	for (i=0; i<NUM_ALT_ADDRS; i++)
+		addrPtrs[i] = (ip_addr *) &macHost.addr[i];
+
+	addrPtrs[NUM_ALT_ADDRS] = NULL;
+
+	return &unixHost;
+}
+
+char * inet_ntoa(struct in_addr inaddr)
+{
+	if (INETSockets.Resolver()) {
+		h_errno = NO_RECOVERY;	
+		return NULL;
+	}
+	
+	(void) AddrToStr(inaddr.s_addr, macHost.cname);
+
+	return macHost.cname;
+}
+
+struct in_addr inet_addr(char *address)
+{
+	if (INETSockets.Resolver()) {
+		h_errno = NO_RECOVERY;	
+		return make_in_addr(0xFFFFFFFF);
+	}
+	
+	if (StrToAddr(address,&macHost,NULL,NULL) != noErr)
+		return make_in_addr(0xFFFFFFFF);
+
+	/* was the 'address' really a name? */
+	if (macHost.cname[0] != 0)
+		return make_in_addr(0xFFFFFFFF);
+
+	return make_in_addr(macHost.addr[0]);
+}
+
+/*
+ * gethostid()
+ *
+ * Get internet address of current host
+ */
+
+long gethostid()
+{
+	static long sHostID = 0;
+	if (sHostID)
+		return sHostID;
+	
+	struct GetAddrParamBlock pbr;
+		
+	pbr.ioCRefNum 	= INETSockets.Driver();
+	pbr.csCode 		= ipctlGetAddr;
+
+	if (PBControlSync(ParmBlkPtr(&pbr)))
+		return 0;
+	else
+		return sHostID = (long)pbr.ourAddress;
+}
+
+/*
+ * gethostname()
+ *
+ * Try to get my host name from DNR. If it fails, just return my
+ * IP address as ASCII. This is non-standard, but it's a mac,
+ * what do you want me to do?
+ */
+
+int gethostname(char *machname, int buflen)
+{
+	static char * sHostName = nil;
+	
+	if (!sHostName) {
+		in_addr ipaddr;
+		struct	hostent *hp;
+
+		ipaddr	=	make_in_addr(ip_addr(gethostid()));
+
+		if (!ipaddr.s_addr) 					// TCP/IP not up at all
+			return GUSI_error(ENETDOWN);
+		
+		hp = gethostbyaddr((char *) &ipaddr, sizeof(in_addr), AF_INET);
+
+		if (!hp) {
+			// No good name
+			if (buflen < 16)						// Not enough space
+				return GUSI_error(EINVAL);	
+			sprintf(machname, "%d.%d.%d.%d",
+							ipaddr.s_addr>>24,
+							ipaddr.s_addr>>16 & 0xff,
+							ipaddr.s_addr>>8 & 0xff,
+							ipaddr.s_addr & 0xff);
+			return 0;
+		} else {
+			// We only cache satisfactory replies in sHostName
+			sHostName = new char[strlen(hp->h_name)+1];
+			strcpy(sHostName, hp->h_name);
+		}
+	}
+	strncpy(machname, sHostName, unsigned(buflen));
+	machname[buflen-1] = 0;  /* extra safeguard */
+
+	return 0;
+}
+
+
+/*
+ *	getservbybname()
+ *
+ */
+
+static char * servlist[] =
+{
+	"echo   		  7/udp",
+	"discard   	  9/udp",
+	"time   		 37/udp",
+	"domain   	 53/udp",
+	"sunrpc   	111/udp",
+	"tftp  		 69/udp",
+	"biff   		512/udp",
+	"who   		513/udp",
+	"talk   		517/udp",
+	"ftp-data  	 20/tcp",
+	"ftp  		 21/tcp",
+	"telnet  	 23/tcp",
+	"smtp  		 25/tcp",
+	"time  		 37/tcp",
+	"whois  		 43/tcp",
+	"domain 	 	 53/tcp",
+	"hostnames  101/tcp",
+	"nntp   		119/tcp",
+	"finger  	 79/tcp",
+	"ntp   		123/tcp",
+	"uucp   		540/tcp",
+	NULL
+};
+
+static char 				servline[128];
+static struct servent	serv;
+static FILE * 				servfil;
+static int					servptr;
+static char *				servalias[8];
+static int					servstay = 0;
+
+void setservent(int stayopen)
+{
+	if (servfil && servfil != (FILE *) -1) {
+		rewind(servfil);
+	}
+	servptr	= 0;
+	servstay = servstay || stayopen;
+}
+
+void endservent()
+{
+	if (servfil && servfil != (FILE *) -1) {
+		fclose(servfil);
+		servfil = NULL;
+	}
+	
+	servstay = 0;
+}
+
+struct servent *  getservent()
+{
+	char *	p;
+	int		aliascount;
+	
+	if (!servfil) {
+		TFileSpec serv;
+		
+		if (!FindFolder(
+				kOnSystemDisk, 
+				kPreferencesFolderType, 
+				kDontCreateFolder, 
+				&serv.vRefNum,
+				&serv.parID)
+		) {
+			PLstrcpy(serv.name, (StringPtr) "\p/etc/services");
+		
+			if (servfil = fopen(serv.FullPath(), "r"))
+				goto retry;
+		}	
+		servfil 	= (FILE *) -1;
+		servptr	= 0;
+	}
+	
+retry:
+	if (servfil == (FILE *) -1)
+		if (!servlist[servptr])
+			return (struct servent *) NULL;
+		else
+			strcpy(servline, servlist[servptr++]);
+	else if (!(fgets(servline, 128, servfil)))
+		return (struct servent *) NULL;
+		
+	if (p = strpbrk(servline, "#\n\r"))
+		*p = 0;
+	if (!servline[0])
+		goto retry;
+	
+	if (!(serv.s_name = strtok(servline, " \t")))
+		goto retry;
+		
+	if (!(p = strtok(NULL, " \t")))
+		goto retry;
+	
+	if (!(serv.s_proto = strpbrk(p, "/,")))
+		goto retry;
+		
+	*serv.s_proto++ 	= 0;
+	serv.s_port 		= htons(atoi(p));
+	serv.s_aliases 	= servalias;
+	
+	for (aliascount = 0; aliascount < 7; ) 
+		if (!(servalias[aliascount++] = strtok(NULL, " \t")))
+			break;
+	
+	servalias[aliascount] = NULL;
+	
+	return &serv;
+}
+
+struct servent * getservbyname(const char * name, const char * proto)
+{
+	struct servent * 	ent;
+	char ** 				al;
+	setservent(0);
+	
+	while (ent = getservent()) {
+		if (!strcmp(name, ent->s_name))
+			goto haveName;
+		
+		for (al = ent->s_aliases; *al; ++al)
+			if (!strcmp(name, *al))
+				goto haveName;
+		
+		continue;
+haveName:
+		if (!proto || !strcmp(proto, ent->s_proto))
+			break;
+	}
+	
+	if (!servstay)
+		endservent();
+	
+	return ent;
+}
+
+struct servent * getservbyport(int port, const char * proto)
+{
+	struct servent * ent;
+	
+	setservent(0);
+	
+	while (ent = getservent())
+		if (port == ent->s_port && (!proto || !strcmp(proto, ent->s_proto)))
+			break;
+	
+	if (!servstay)
+		endservent();
+	
+	return ent;
+}
+
+static	char	tcp[] = "tcp";
+static	char	udp[] = "udp";
+#define	MAX_PROTOENT			10
+static 	struct protoent		protoents[MAX_PROTOENT];
+static 	int						protoent_count=0;
+
+struct protoent * getprotobyname(const char * name)
+{
+	struct protoent *pe;
+
+	pe = &protoents[protoent_count];
+	if (strcmp(name, "udp") == 0) {
+		pe->p_name = udp;
+		pe->p_proto = IPPROTO_UDP;
+	} else if (strcmp (name, "tcp") == 0)  {
+		pe->p_name = tcp;
+		pe->p_proto = IPPROTO_TCP;
+	} else {
+		errno = EPROTONOSUPPORT;
+		return NULL;
+	}
+	pe->p_aliases = aliasPtrs;
+	protoent_count = (protoent_count +1) % MAX_PROTOENT;
+	return pe;
+}
+
+struct protoent * getprotobynumber(int proto)
+{
+	struct protoent *pe;
+
+	pe = &protoents[protoent_count];
+	if (proto == IPPROTO_UDP) {
+		pe->p_name = udp;
+		pe->p_proto = IPPROTO_UDP;
+	} else if (proto == IPPROTO_TCP)  {
+		pe->p_name = tcp;
+		pe->p_proto = IPPROTO_TCP;
+	} else {
+		errno = EPROTONOSUPPORT;
+		return NULL;
+	}
+	pe->p_aliases = aliasPtrs;
+	protoent_count = (protoent_count +1) % MAX_PROTOENT;
+	return pe;
+}
+
diff --git a/Mac/GUSI-mods/into-src/GUSISIOUX.cp b/Mac/GUSI-mods/into-src/GUSISIOUX.cp
new file mode 100644
index 0000000..24b98b0
--- /dev/null
+++ b/Mac/GUSI-mods/into-src/GUSISIOUX.cp
@@ -0,0 +1,246 @@
+/*********************************************************************
+Project	:	GUSI				-	Grand unified socket interface
+File		:	GUSISIOUX.cp	-	Interface to Metrowerks SIOUX library
+Author	:	Matthias Neeracher
+Language	:	MPW C/C++
+
+$Log$
+Revision 1.1  1998/08/18 14:52:38  jack
+Putting Python-specific GUSI modifications under CVS.
+
+*********************************************************************/
+
+#include <GUSIFile_P.h>
+#include <ioctl.h>
+#include <console.h>
+
+#include <Events.h>
+#include <LowMem.h>
+
+/************************ SIOUXSocket members ************************/
+
+/* This declaration lies about the return type */
+extern "C" void SIOUXHandleOneEvent(EventRecord *userevent);
+
+GUSIEvtHandler	GUSISIOUXEvents[]	=	{
+	SIOUXHandleOneEvent,		// nullEvent
+	
+	SIOUXHandleOneEvent,		// mouseDown
+	SIOUXHandleOneEvent,		// mouseUp
+	nil,							// keyDown
+	nil,
+	
+	nil,							// autoKey
+	SIOUXHandleOneEvent,		// updateEvt
+	SIOUXHandleOneEvent,		// diskEvt
+	SIOUXHandleOneEvent,		// activateEvt
+	
+	nil,
+	nil,
+	nil,
+	nil,
+	
+	nil,
+	nil,
+	SIOUXHandleOneEvent,		// osEvt
+	nil,
+	
+	nil,
+	nil,
+	nil,
+	nil,
+	
+	nil,
+	nil,
+	nil,
+};
+
+/************************ Declaration of SIOUXSocket ************************/
+
+class SIOUXSocket : public Socket	{		
+	friend class SIOUXSocketDomain;	
+	
+					SIOUXSocket();
+					
+	virtual 		~SIOUXSocket();
+protected:
+	int			initialized;
+	void			DoInitialize(void);
+public:
+	virtual int	read(void * buffer, int buflen);
+	virtual int write(void * buffer, int buflen);
+	virtual int select(Boolean * canRead, Boolean * canWrite, Boolean * exception);
+	virtual int	ioctl(unsigned int request, void *argp);
+	virtual int	isatty();
+};	
+
+class SIOUXSocketDomain : public FileSocketDomain {
+	SIOUXSocket *	singleton;
+public:
+	SIOUXSocketDomain()	:	FileSocketDomain(AF_UNSPEC, true, false), singleton(nil)	{	}
+	
+	virtual Boolean Yours(const GUSIFileRef & ref, Request request);
+	virtual Socket * open(const GUSIFileRef & ref, int oflag);
+};
+
+#if GENERATING68K
+#pragma segment SIOUX
+#endif
+
+/************************ SIOUXSocket members ************************/
+
+void SIOUXSocket::DoInitialize()
+{
+	if ( initialized ) return;
+	initialized++;
+	InstallConsole(0);
+	GUSISetEvents(GUSISIOUXEvents);
+}
+
+SIOUXSocket::SIOUXSocket()
+{
+	initialized = 0;
+	if ( !GUSIConfig.DelayConsole() )
+		DoInitialize();
+}
+
+SIOUXSocket::~SIOUXSocket()
+{
+	RemoveConsole();
+}
+
+int SIOUXSocket::ioctl(unsigned int request, void *)
+{
+	if ( !initialized) DoInitialize();
+	switch (request)	{
+	case FIOINTERACTIVE:
+		return 0;
+	default:
+		return GUSI_error(EOPNOTSUPP);
+	}
+}
+
+int SIOUXSocket::read(void * buffer, int buflen)
+{
+	if ( !initialized) DoInitialize();
+	fflush(stdout);
+	
+	return ReadCharsFromConsole((char *) buffer, buflen);
+}
+
+int SIOUXSocket::write(void * buffer, int buflen)
+{
+	if ( !initialized) DoInitialize();
+	return WriteCharsToConsole((char *) buffer, buflen);
+}
+
+static Boolean input_pending()
+{
+	QHdrPtr eventQueue = LMGetEventQueue();
+	EvQElPtr element = (EvQElPtr)eventQueue->qHead;
+	
+	// now, count the number of pending keyDown events.
+	while (element != nil) {
+		if (element->evtQWhat == keyDown || element->evtQWhat == autoKey)
+			return true;
+		element = (EvQElPtr)element->qLink;
+	}
+	
+	return false;
+}
+
+int SIOUXSocket::select(Boolean * canRead, Boolean * canWrite, Boolean * exception)
+{
+	int		goodies 	= 	0;
+		
+	if ( !initialized) DoInitialize();
+	fflush(stdout);
+	
+	if (canRead) 
+		if (*canRead = input_pending())
+			++goodies;
+	
+	if (canWrite) {
+		*canWrite = true;
+		++goodies;
+	}
+	
+	if (exception)
+		*exception = false;
+	
+	return goodies;
+}
+
+int SIOUXSocket::isatty()
+{
+	return 1;
+}
+
+/********************* SIOUXSocketDomain members **********************/
+
+#ifdef MSLGUSI
+#ifndef SFIOGUSI
+	extern void GUSISetupMSLSIOUX();
+#endif
+#endif
+
+extern "C" void GUSIwithSIOUXSockets()
+{
+	static SIOUXSocketDomain	SIOUXSockets;
+	SIOUXSockets.DontStrip();
+#ifdef MSLGUSI
+#ifndef SFIOGUSI
+	GUSISetupMSLSIOUX();
+#endif
+#endif
+}
+
+Boolean SIOUXSocketDomain::Yours(const GUSIFileRef & ref, FileSocketDomain::Request request)
+{
+	if (ref.spec || (request != willOpen && request != willStat))
+		return false;
+	
+	switch (ref.name[4] | 0x20) {
+	case 's':
+		if ((ref.name[5] | 0x20) != 't' || (ref.name[6] | 0x20) != 'd')
+			return false;
+		switch (ref.name[7] | 0x20) {
+		case 'i':
+			if ((ref.name[8] | 0x20) != 'n' || ref.name[9])
+				return false;
+			return true;
+		case 'o':
+			if ((ref.name[8] | 0x20) != 'u' || (ref.name[9] | 0x20) != 't' || ref.name[10])
+				return false;
+			return true;
+		case 'e':
+			if ((ref.name[8] | 0x20) != 'r' || (ref.name[9] | 0x20) != 'r' || ref.name[10])
+				return false;
+			return true;
+		default:
+			return false;
+		}
+	case 'c':
+		if (	(ref.name[5] | 0x20) != 'o' || (ref.name[6] | 0x20) != 'n'
+			|| (ref.name[7] | 0x20) != 's' || (ref.name[8] | 0x20) != 'o'
+			|| (ref.name[9] | 0x20) != 'l' || (ref.name[10] | 0x20) != 'e')
+			return false;
+		switch (ref.name[11]) {
+		case 0:
+			return true;
+		default:
+			return false;
+		}
+	default:
+		return false;
+	}
+}
+
+Socket * SIOUXSocketDomain::open(const GUSIFileRef &, int)
+{
+	if (!singleton)
+		singleton = new SIOUXSocket();
+	++*singleton;
+	
+	return singleton;
+}