aboutsummaryrefslogtreecommitdiff
path: root/nxcomp/ChannelEndPoint.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'nxcomp/ChannelEndPoint.cpp')
-rw-r--r--nxcomp/ChannelEndPoint.cpp245
1 files changed, 245 insertions, 0 deletions
diff --git a/nxcomp/ChannelEndPoint.cpp b/nxcomp/ChannelEndPoint.cpp
new file mode 100644
index 000000000..cb35e52d2
--- /dev/null
+++ b/nxcomp/ChannelEndPoint.cpp
@@ -0,0 +1,245 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2015 Qindel Formacion y Servicios SL. */
+/* */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License Version 2, as */
+/* published by the Free Software Foundation. */
+/* */
+/* This program is distributed in the hope that it will be useful, but */
+/* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA- */
+/* BILITY 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, you can request a copy to Qindel */
+/* or write to the Free Software Foundation, Inc., 59 Temple Place, Suite */
+/* 330, Boston, MA 02111-1307 USA */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "ChannelEndPoint.h"
+
+#include "NXalert.h"
+
+ChannelEndPoint::ChannelEndPoint(const char *spec)
+ : defaultTCPPort_(0), defaultTCPInterface_(0),
+ defaultUnixPath_(NULL) {
+ spec_ = (spec ? strdup(spec) : NULL);
+}
+
+void
+ChannelEndPoint::setSpec(const char *spec) {
+ if (spec_) free(spec_);
+
+ if (spec && strlen(spec))
+ spec_ = strdup(spec);
+ else
+ spec_ = NULL;
+}
+
+void
+ChannelEndPoint::setSpec(int port) {
+ if (port >= 0) {
+ char tmp[20];
+ sprintf(tmp, "%d", port);
+ setSpec(tmp);
+ }
+ else setSpec((char*)NULL);
+}
+
+void
+ChannelEndPoint::setDefaultTCPPort(long port) {
+ defaultTCPPort_ = port;
+}
+
+void
+ChannelEndPoint::setDefaultTCPInterface(int publicInterface) {
+ defaultTCPInterface_ = publicInterface;
+}
+
+void
+ChannelEndPoint::setDefaultUnixPath(char *path) {
+ if (defaultUnixPath_) free(defaultUnixPath_);
+
+ if (path && strlen(path))
+ defaultUnixPath_ = strdup(path);
+ else
+ defaultUnixPath_ = NULL;
+}
+
+void
+ChannelEndPoint::disable() { setSpec("0"); }
+
+bool
+ChannelEndPoint::specIsPort(long *port) const {
+ if (port) *port = 0;
+ long p = -1;
+ if (spec_) {
+ char *end;
+ p = strtol(spec_, &end, 10);
+ if ((end == spec_) || (*end != '\0'))
+ return false;
+ }
+
+ if (port) *port = p;
+ return true;
+}
+
+bool
+ChannelEndPoint::getUnixPath(char **unixPath) const {
+
+ if (unixPath) *unixPath = 0;
+
+ long p;
+ char *path = NULL;
+
+ if (specIsPort(&p)) {
+ if (p != 1) return false;
+ }
+ else if (spec_ && (strncmp("unix:", spec_, 5) == 0)) {
+ path = spec_ + 5;
+ }
+ else
+ return false;
+
+ if (!path || (*path == '\0')) {
+ path = defaultUnixPath_;
+ if (!path)
+ return false;
+ }
+
+ if (unixPath)
+ *unixPath = strdup(path);
+
+ return true;
+}
+
+// FIXME!!!
+static const char *
+getComputerName() {
+ //
+ // Strangely enough, under some Windows OSes SMB
+ // service doesn't bind to localhost. Fall back
+ // to localhost if can't find computer name in
+ // the environment. In future we should try to
+ // bind to localhost and then try the other IPs.
+ //
+
+ const char *hostname = NULL;
+
+ #ifdef __CYGWIN32__
+
+ hostname = getenv("COMPUTERNAME");
+
+ #endif
+
+ if (hostname == NULL)
+ {
+ hostname = "localhost";
+ }
+
+ return hostname;
+}
+
+bool
+ChannelEndPoint::getTCPHostAndPort(char **host, long *port) const {
+ long p;
+ char *h = NULL;
+ ssize_t h_len;
+
+ if (host) *host = NULL;
+ if (port) *port = 0;
+
+ if (specIsPort(&p)) {
+ h_len = 0;
+ }
+ else if (spec_ && (strncmp("tcp:", spec_, 4) == 0)) {
+ h = spec_ + 4;
+ char *colon = strrchr(h, ':');
+ if (colon) {
+ char *end;
+ h_len = colon++ - h;
+ p = strtol(colon, &end, 10);
+ if ((end == colon) || (*end != '\0'))
+ return false;
+ }
+ else {
+ h_len = strlen(h);
+ p = 1;
+ }
+ }
+ else
+ return false;
+
+ if (p == 1) p = defaultTCPPort_;
+ if (p < 1) return false;
+
+ if (port)
+ *port = p;
+
+ if (host)
+ *host = ( h_len
+ ? strndup(h, h_len)
+ : strdup(defaultTCPInterface_ ? getComputerName() : "localhost"));
+
+ return true;
+}
+
+bool
+ChannelEndPoint::enabled() const {
+ return (getUnixPath() || getTCPHostAndPort());
+}
+
+long ChannelEndPoint::getTCPPort() const {
+ long port;
+ if (getTCPHostAndPort(NULL, &port)) return port;
+ return -1;
+}
+
+bool
+ChannelEndPoint::validateSpec() {
+ return (specIsPort() || getUnixPath() || getTCPHostAndPort());
+}
+
+ChannelEndPoint &ChannelEndPoint::operator=(const ChannelEndPoint &other) {
+ char *old;
+ defaultTCPPort_ = other.defaultTCPPort_;
+ defaultTCPInterface_ = other.defaultTCPInterface_;
+ old = defaultUnixPath_;
+ defaultUnixPath_ = (other.defaultUnixPath_ ? strdup(other.defaultUnixPath_) : NULL);
+ free(old);
+ old = spec_;
+ spec_ = (other.spec_ ? strdup(other.spec_) : NULL);
+ free(old);
+ return *this;
+}
+
+std::ostream& operator<<(std::ostream& os, const ChannelEndPoint& endPoint) {
+ if (endPoint.enabled()) {
+ char *unixPath, *host;
+ long port;
+ if (endPoint.getUnixPath(&unixPath)) {
+ os << "unix:" << unixPath;
+ free(unixPath);
+ }
+ else if (endPoint.getTCPHostAndPort(&host, &port)) {
+ os << "tcp:" << host << ":" << port;
+ free(host);
+ }
+ else {
+ os << "(invalid)";
+ }
+ }
+ else {
+ os << "(disabled)";
+ }
+ return os;
+}