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;
+}