Merge common socket code
diff --git a/common/network/Socket.cxx b/common/network/Socket.cxx
new file mode 100644
index 0000000..9dd8bfe
--- /dev/null
+++ b/common/network/Socket.cxx
@@ -0,0 +1,183 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * 
+ * This 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 software 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 software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WIN32
+//#include <io.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#define errorNumber WSAGetLastError()
+#else
+#define errorNumber errno
+#define closesocket close
+#include <sys/socket.h>
+#endif
+
+#include <unistd.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <network/Socket.h>
+
+using namespace network;
+
+// -=- Socket initialisation
+static bool socketsInitialised = false;
+void network::initSockets() {
+  if (socketsInitialised)
+    return;
+#ifdef WIN32
+  WORD requiredVersion = MAKEWORD(2,0);
+  WSADATA initResult;
+  
+  if (WSAStartup(requiredVersion, &initResult) != 0)
+    throw SocketException("unable to initialise Winsock2", errorNumber);
+#else
+  signal(SIGPIPE, SIG_IGN);
+#endif
+  socketsInitialised = true;
+}
+
+bool network::isSocketListening(int sock)
+{
+  int listening = 0;
+  socklen_t listening_size = sizeof(listening);
+  if (getsockopt(sock, SOL_SOCKET, SO_ACCEPTCONN,
+                 (char *)&listening, &listening_size) < 0)
+    return false;
+  return listening != 0;
+}
+
+Socket::Socket(int fd)
+  : instream(0), outstream(0),
+    isShutdown_(false), queryConnection(false)
+{
+  initSockets();
+  setFd(fd);
+}
+
+Socket::Socket()
+  : instream(0), outstream(0),
+    isShutdown_(false), queryConnection(false)
+{
+  initSockets();
+}
+
+Socket::~Socket()
+{
+  if (instream && outstream)
+    closesocket(getFd());
+  delete instream;
+  delete outstream;
+}
+
+// if shutdown() is overridden then the override MUST call on to here
+void Socket::shutdown()
+{
+  isShutdown_ = true;
+  ::shutdown(getFd(), 2);
+}
+
+bool Socket::isShutdown() const
+{
+  return isShutdown_;
+}
+
+// Was there a "?" in the ConnectionFilter used to accept this Socket?
+void Socket::setRequiresQuery()
+{
+  queryConnection = true;
+}
+
+bool Socket::requiresQuery() const
+{
+  return queryConnection;
+}
+
+void Socket::setFd(int fd)
+{
+#ifndef WIN32
+  // - By default, close the socket on exec()
+  fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+  instream = new rdr::FdInStream(fd);
+  outstream = new rdr::FdOutStream(fd);
+  isShutdown_ = false;
+}
+
+SocketListener::SocketListener(int fd)
+  : fd(fd), filter(0)
+{
+  initSockets();
+}
+
+SocketListener::SocketListener()
+  : fd(-1), filter(0)
+{
+  initSockets();
+}
+
+SocketListener::~SocketListener()
+{
+  if (fd != -1)
+    closesocket(fd);
+}
+
+void SocketListener::shutdown()
+{
+#ifdef WIN32
+  closesocket(fd);
+  fd = -1;
+#else
+  ::shutdown(fd, 2);
+#endif
+}
+
+Socket* SocketListener::accept() {
+  int new_sock = -1;
+
+  // Accept an incoming connection
+  if ((new_sock = ::accept(fd, 0, 0)) < 0)
+    throw SocketException("unable to accept new connection", errorNumber);
+
+  // Create the socket object & check connection is allowed
+  Socket* s = createSocket(new_sock);
+  if (filter && !filter->verifyConnection(s)) {
+    delete s;
+    return NULL;
+  }
+
+  return s;
+}
+
+void SocketListener::listen(int sock)
+{
+  // - Set it to be a listening socket
+  if (::listen(sock, 5) < 0) {
+    int e = errorNumber;
+    closesocket(sock);
+    throw SocketException("unable to set socket to listening mode", e);
+  }
+
+  fd = sock;
+}