mirror of
https://github.com/debauchee/barrier.git
synced 2026-02-13 23:25:27 +08:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 773a0081e3 | |||
| 8b69f9fe03 | |||
| 0b2dfd80e2 | |||
| c7569f8af7 | |||
|
|
b8ad9b8aba | ||
| 9ab77545ee | |||
| f4301a7618 | |||
| f299558cdf | |||
| 7fd6711829 | |||
| b43581c2f5 | |||
| bd4c214c39 | |||
| 642eb33446 | |||
|
|
0b5ca57b9c | ||
| a7fb1b56f6 | |||
| 5e19820425 | |||
| 9e7792e2ae | |||
| 42a8f69050 | |||
| 1734e6d7f6 | |||
| 6c4199b11a | |||
| 767188799e | |||
| e6d0f40a36 | |||
| 129e61a33a | |||
| 4c04f39685 | |||
| 131a19d478 | |||
| 6c5acdd552 | |||
| d81054ab6e | |||
| 1be86a9248 | |||
| ea025f5958 | |||
| 6e5b340bcc | |||
| 451bd72b30 | |||
| c16fd089f6 | |||
| 96627f4f07 | |||
| c5e70af09a | |||
| 72cc7e3d89 | |||
| fe818a4955 | |||
| ecfa7d7d1c | |||
|
|
9a2d61cbb5 | ||
| 24987e0694 |
1
_config.yml
Normal file
1
_config.yml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
theme: jekyll-theme-slate
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required (VERSION 3.4)
|
cmake_minimum_required (VERSION 3.4)
|
||||||
|
|
||||||
set (BARRIER_VERSION_MAJOR 2)
|
set (BARRIER_VERSION_MAJOR 2)
|
||||||
set (BARRIER_VERSION_MINOR 0)
|
set (BARRIER_VERSION_MINOR 1)
|
||||||
set (BARRIER_VERSION_PATCH 0)
|
set (BARRIER_VERSION_PATCH 0)
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -44,24 +44,24 @@ if (NOT DEFINED BARRIER_REVISION)
|
|||||||
if (DEFINED ENV{GIT_COMMIT})
|
if (DEFINED ENV{GIT_COMMIT})
|
||||||
string (SUBSTRING $ENV{GIT_COMMIT} 0 8 BARRIER_REVISION)
|
string (SUBSTRING $ENV{GIT_COMMIT} 0 8 BARRIER_REVISION)
|
||||||
else()
|
else()
|
||||||
execute_process (
|
find_program (GIT_BINARY git)
|
||||||
COMMAND git rev-parse --short=8 HEAD
|
if (NOT GIT_BINARY STREQUAL "GIT_BINARY-NOTFOUND")
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
execute_process (
|
||||||
OUTPUT_VARIABLE BARRIER_REVISION
|
COMMAND git rev-parse --short=8 HEAD
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
)
|
OUTPUT_VARIABLE BARRIER_REVISION
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (DEFINED BARRIER_REVISION)
|
string(LENGTH "${BARRIER_REVISION}" BARRIER_REVISION_LENGTH)
|
||||||
string(LENGTH ${BARRIER_REVISION} BARRIER_REVISION_LENGTH)
|
if (NOT BARRIER_REVISION_LENGTH EQUAL 8 OR NOT BARRIER_REVISION MATCHES "^[a-f0-9]+")
|
||||||
if (NOT ((BARRIER_REVISION MATCHES "^[a-f0-9]+") AND (BARRIER_REVISION_LENGTH EQUAL "8")))
|
set (BARRIER_REVISION "00000000")
|
||||||
message (FATAL_ERROR "BARRIER_REVISION ('${BARRIER_REVISION}') should be a short commit hash")
|
message (WARNING "revision not found. setting to ${BARRIER_REVISION}")
|
||||||
endif()
|
|
||||||
unset (BARRIER_REVISION_LENGTH)
|
|
||||||
else()
|
|
||||||
set (BARRIER_REVISION "0badc0de")
|
|
||||||
endif()
|
endif()
|
||||||
|
unset (BARRIER_REVISION_LENGTH)
|
||||||
|
|
||||||
if (DEFINED ENV{BUILD_NUMBER})
|
if (DEFINED ENV{BUILD_NUMBER})
|
||||||
set (BARRIER_BUILD_NUMBER $ENV{BUILD_NUMBER})
|
set (BARRIER_BUILD_NUMBER $ENV{BUILD_NUMBER})
|
||||||
|
|||||||
1
dist/rpm/barrier.spec.in
vendored
1
dist/rpm/barrier.spec.in
vendored
@@ -18,7 +18,6 @@ Work seamlessly across Windows, macOS and Linux.
|
|||||||
%{_bindir}/barrier
|
%{_bindir}/barrier
|
||||||
%{_bindir}/barrierc
|
%{_bindir}/barrierc
|
||||||
%{_bindir}/barriers
|
%{_bindir}/barriers
|
||||||
%{_bindir}/syntool
|
|
||||||
%attr(644,-,-) %{_datarootdir}/applications/barrier.desktop
|
%attr(644,-,-) %{_datarootdir}/applications/barrier.desktop
|
||||||
%attr(644,-,-) %{_datarootdir}/icons/hicolor/scalable/apps/barrier.svg
|
%attr(644,-,-) %{_datarootdir}/icons/hicolor/scalable/apps/barrier.svg
|
||||||
|
|
||||||
|
|||||||
2
dist/wix/Product.wxs
vendored
2
dist/wix/Product.wxs
vendored
@@ -60,8 +60,6 @@
|
|||||||
<fire:FirewallException Id="ServerFirewallException" IgnoreFailure="yes" Name="$(var.Name)" Scope="any"/>
|
<fire:FirewallException Id="ServerFirewallException" IgnoreFailure="yes" Name="$(var.Name)" Scope="any"/>
|
||||||
</File>
|
</File>
|
||||||
<File Source="$(var.BinPath)/barrierc.exe"/>
|
<File Source="$(var.BinPath)/barrierc.exe"/>
|
||||||
<File Source="$(var.BinPath)/syntool.exe"/>
|
|
||||||
<File Source="$(var.BinPath)/synwinhk.dll"/>
|
|
||||||
<File Source="$(var.OpenSSLBinPath)/libeay32.dll"/>
|
<File Source="$(var.OpenSSLBinPath)/libeay32.dll"/>
|
||||||
<File Source="$(var.OpenSSLBinPath)/ssleay32.dll"/>
|
<File Source="$(var.OpenSSLBinPath)/ssleay32.dll"/>
|
||||||
<File Source="$(var.OpenSSLBinPath)/openssl.exe"/>
|
<File Source="$(var.OpenSSLBinPath)/openssl.exe"/>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
|
||||||
.TH BARRIERC "1" "March 2018" "barrierc 2.0.0, protocol version 1.6" "User Commands"
|
.TH BARRIERC "1" "May 2018" "barrierc 2.1.0-snapshot" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
barrierc \- Barrier Keyboard/Mouse Client
|
barrierc \- Barrier Keyboard/Mouse Client
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -59,9 +59,10 @@ display version information and exit.
|
|||||||
.PP
|
.PP
|
||||||
Default options are marked with a *
|
Default options are marked with a *
|
||||||
.PP
|
.PP
|
||||||
The server address is of the form: [<hostname>][:<port>]. The hostname
|
The server address is of the form: [<hostname>][:<port>]. The hostname
|
||||||
must be the address or hostname of the server. The port overrides the
|
must be the address or hostname of the server. Placing brackets around
|
||||||
default port, 24800.
|
an IPv6 address is required when also specifying a port number and
|
||||||
|
optional otherwise. The default port number is 24800.
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
Copyright \(co 2018 Debauchee Open Source Group
|
Copyright \(co 2018 Debauchee Open Source Group
|
||||||
.br
|
.br
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
|
||||||
.TH BARRIERS "1" "March 2018" "barriers 2.0.0, protocol version 1.6" "User Commands"
|
.TH BARRIERS "1" "May 2018" "barriers 2.1.0-snapshot" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
barriers \- Barrier Keyboard/Mouse Server
|
barriers \- Barrier Keyboard/Mouse Server
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -63,13 +63,14 @@ Default options are marked with a *
|
|||||||
.PP
|
.PP
|
||||||
The argument for \fB\-\-address\fR is of the form: [<hostname>][:<port>]. The
|
The argument for \fB\-\-address\fR is of the form: [<hostname>][:<port>]. The
|
||||||
hostname must be the address or hostname of an interface on the system.
|
hostname must be the address or hostname of an interface on the system.
|
||||||
The default is to listen on all interfaces. The port overrides the
|
Placing brackets around an IPv6 address is required when also specifying
|
||||||
default port, 24800.
|
a port number and optional otherwise. The default is to listen on all
|
||||||
|
interfaces using port number 24800.
|
||||||
.PP
|
.PP
|
||||||
If no configuration file pathname is provided then the first of the
|
If no configuration file pathname is provided then the first of the
|
||||||
following to load successfully sets the configuration:
|
following to load successfully sets the configuration:
|
||||||
.IP
|
.IP
|
||||||
$HOME/.barrier.conf
|
$HOME/.local/share/barrier/barrier.conf
|
||||||
\fI\,/etc/barrier.conf\/\fP
|
\fI\,/etc/barrier.conf\/\fP
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
Copyright \(co 2018 Debauchee Open Source Group
|
Copyright \(co 2018 Debauchee Open Source Group
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Type=Application
|
Type=Application
|
||||||
Version=1.0
|
|
||||||
Name=Barrier
|
Name=Barrier
|
||||||
Comment=Keyboard and mouse sharing solution
|
Comment=Keyboard and mouse sharing solution
|
||||||
Path=/usr/bin
|
Exec=barrier
|
||||||
Exec=/usr/bin/barrier
|
|
||||||
Icon=barrier
|
Icon=barrier
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Categories=Utility;
|
Categories=Utility;
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
[Desktop Entry]
|
|
||||||
Type=Application
|
|
||||||
Version=1.0
|
|
||||||
Name=Barrier
|
|
||||||
Comment=Keyboard and mouse sharing solution
|
|
||||||
Path=/usr/bin
|
|
||||||
Exec=/usr/bin/barrier2
|
|
||||||
Icon=barrier
|
|
||||||
Terminal=false
|
|
||||||
Categories=Utility;
|
|
||||||
Keywords=keyboard;mouse;sharing;network;share;
|
|
||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
add_subdirectory(barrierc)
|
add_subdirectory(barrierc)
|
||||||
add_subdirectory(barriers)
|
add_subdirectory(barriers)
|
||||||
add_subdirectory(syntool)
|
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
add_subdirectory(barrierd)
|
add_subdirectory(barrierd)
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
# barrier -- mouse and keyboard sharing utility
|
|
||||||
# Copyright (C) 2014-2016 Symless Ltd.
|
|
||||||
#
|
|
||||||
# This package is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# found in the file LICENSE that should have accompanied this file.
|
|
||||||
#
|
|
||||||
# This package is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
file(GLOB headers "*.h")
|
|
||||||
file(GLOB sources "*.cpp")
|
|
||||||
|
|
||||||
add_executable(syntool ${sources})
|
|
||||||
target_link_libraries(syntool
|
|
||||||
synlib arch base client common io ipc mt net platform server ${libs} ${OPENSSL_LIBS})
|
|
||||||
|
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
|
||||||
install (TARGETS syntool DESTINATION ${BARRIER_BUNDLE_BINARY_DIR})
|
|
||||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|
||||||
install (TARGETS syntool DESTINATION bin)
|
|
||||||
endif()
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2014-2016 Symless Ltd.
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "barrier/ToolApp.h"
|
|
||||||
#include "arch/Arch.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
#if SYSAPI_WIN32
|
|
||||||
// record window instance for tray icon, etc
|
|
||||||
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ToolApp app;
|
|
||||||
return app.run(argc, argv);
|
|
||||||
}
|
|
||||||
@@ -45,6 +45,8 @@ if (HAVE_X11)
|
|||||||
target_link_libraries (barrier X11)
|
target_link_libraries (barrier X11)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries (barrier common)
|
||||||
|
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||||
install (TARGETS barrier DESTINATION ${BARRIER_BUNDLE_BINARY_DIR})
|
install (TARGETS barrier DESTINATION ${BARRIER_BUNDLE_BINARY_DIR})
|
||||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2015-2016 Symless Ltd.
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "CoreInterface.h"
|
|
||||||
|
|
||||||
#include "CommandProcess.h"
|
|
||||||
#include "QUtility.h"
|
|
||||||
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QtGlobal>
|
|
||||||
#include <QDir>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
static const char kCoreBinary[] = "syntool";
|
|
||||||
|
|
||||||
#ifdef Q_WS_WIN
|
|
||||||
static const char kSerialKeyFilename[] = "Barrier.subkey";
|
|
||||||
#else
|
|
||||||
static const char kSerialKeyFilename[] = ".barrier.subkey";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CoreInterface::CoreInterface()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CoreInterface::getProfileDir()
|
|
||||||
{
|
|
||||||
QStringList args("--get-profile-dir");
|
|
||||||
return run(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CoreInterface::getInstalledDir()
|
|
||||||
{
|
|
||||||
QStringList args("--get-installed-dir");
|
|
||||||
return run(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CoreInterface::getArch()
|
|
||||||
{
|
|
||||||
QStringList args("--get-arch");
|
|
||||||
return run(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CoreInterface::getSerialKeyFilePath()
|
|
||||||
{
|
|
||||||
QString filename = getProfileDir() + QDir::separator() + kSerialKeyFilename;
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CoreInterface::notifyUpdate (QString const& fromVersion,
|
|
||||||
QString const& toVersion,
|
|
||||||
QString const& serialKey) {
|
|
||||||
QStringList args("--notify-update");
|
|
||||||
QString input(fromVersion + ":" + toVersion + ":" + serialKey);
|
|
||||||
input.append("\n");
|
|
||||||
return run(args, input);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CoreInterface::notifyActivation(const QString& identity)
|
|
||||||
{
|
|
||||||
QStringList args("--notify-activation");
|
|
||||||
|
|
||||||
QString input(identity + ":" + hash(getFirstMacAddress()));
|
|
||||||
QString os= getOSInformation();
|
|
||||||
if (!os.isEmpty()) {
|
|
||||||
input.append(":").append(os);
|
|
||||||
}
|
|
||||||
input.append("\n");
|
|
||||||
|
|
||||||
return run(args, input);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CoreInterface::run(const QStringList& args, const QString& input)
|
|
||||||
{
|
|
||||||
QString program(
|
|
||||||
QCoreApplication::applicationDirPath()
|
|
||||||
+ "/" + kCoreBinary);
|
|
||||||
|
|
||||||
CommandProcess commandProcess(program, args, input);
|
|
||||||
return commandProcess.run();
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2015-2016 Symless Ltd.
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
class CoreInterface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CoreInterface();
|
|
||||||
|
|
||||||
QString getProfileDir();
|
|
||||||
QString getInstalledDir();
|
|
||||||
QString getArch();
|
|
||||||
QString getSerialKeyFilePath();
|
|
||||||
QString notifyActivation(const QString& identity);
|
|
||||||
QString notifyUpdate (QString const& fromVersion,
|
|
||||||
QString const& toVersion,
|
|
||||||
QString const& serialKey);
|
|
||||||
QString run(const QStringList& args, const QString& input = "");
|
|
||||||
};
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#include "Fingerprint.h"
|
#include "Fingerprint.h"
|
||||||
|
|
||||||
#include "CoreInterface.h"
|
#include "common/DataDirectories.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
@@ -125,8 +125,7 @@ void Fingerprint::persistDirectory()
|
|||||||
|
|
||||||
QString Fingerprint::directoryPath()
|
QString Fingerprint::directoryPath()
|
||||||
{
|
{
|
||||||
CoreInterface coreInterface;
|
auto profileDir = QString::fromStdString(DataDirectories::profile());
|
||||||
QString profileDir = coreInterface.getProfileDir();
|
|
||||||
|
|
||||||
return QString("%1/%2")
|
return QString("%1/%2")
|
||||||
.arg(profileDir)
|
.arg(profileDir)
|
||||||
|
|||||||
@@ -21,9 +21,6 @@
|
|||||||
|
|
||||||
class Fingerprint
|
class Fingerprint
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
Fingerprint(const QString& filename);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void trust(const QString& fingerprintText, bool append = true);
|
void trust(const QString& fingerprintText, bool append = true);
|
||||||
bool isTrusted(const QString& fingerprintText);
|
bool isTrusted(const QString& fingerprintText);
|
||||||
@@ -32,15 +29,14 @@ public:
|
|||||||
QString filePath() const;
|
QString filePath() const;
|
||||||
bool fileExists() const;
|
bool fileExists() const;
|
||||||
|
|
||||||
public:
|
|
||||||
static Fingerprint local();
|
static Fingerprint local();
|
||||||
static Fingerprint trustedServers();
|
static Fingerprint trustedServers();
|
||||||
static Fingerprint trustedClients();
|
static Fingerprint trustedClients();
|
||||||
static QString directoryPath();
|
static QString directoryPath();
|
||||||
static QString localFingerprint();
|
|
||||||
static bool localFingerprintExists();
|
|
||||||
static void persistDirectory();
|
static void persistDirectory();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Fingerprint(const QString& filename);
|
||||||
|
|
||||||
QString m_Filename;
|
QString m_Filename;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "ProcessorArch.h"
|
#include "ProcessorArch.h"
|
||||||
#include "SslCertificate.h"
|
#include "SslCertificate.h"
|
||||||
#include "ShutdownCh.h"
|
#include "ShutdownCh.h"
|
||||||
|
#include "common/DataDirectories.h"
|
||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
@@ -72,6 +73,8 @@ static const char* barrierIconFiles[] =
|
|||||||
":/res/icons/16x16/barrier-transfering.png"
|
":/res/icons/16x16/barrier-transfering.png"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char* barrierLargeIcon = ":/res/icons/256x256/barrier.ico";
|
||||||
|
|
||||||
MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
|
MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
|
||||||
m_Settings(settings),
|
m_Settings(settings),
|
||||||
m_AppConfig(&appConfig),
|
m_AppConfig(&appConfig),
|
||||||
@@ -104,7 +107,7 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
|
|||||||
setAttribute(Qt::WA_X11NetWmWindowTypeDialog, true);
|
setAttribute(Qt::WA_X11NetWmWindowTypeDialog, true);
|
||||||
|
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
setWindowIcon(QIcon(barrierLargeIcon));
|
||||||
createMenuBar();
|
createMenuBar();
|
||||||
loadSettings();
|
loadSettings();
|
||||||
initConnections();
|
initConnections();
|
||||||
@@ -285,13 +288,8 @@ void MainWindow::saveSettings()
|
|||||||
|
|
||||||
void MainWindow::setIcon(qBarrierState state)
|
void MainWindow::setIcon(qBarrierState state)
|
||||||
{
|
{
|
||||||
QIcon icon;
|
|
||||||
icon.addFile(barrierIconFiles[state]);
|
|
||||||
|
|
||||||
setWindowIcon(icon);
|
|
||||||
|
|
||||||
if (m_pTrayIcon)
|
if (m_pTrayIcon)
|
||||||
m_pTrayIcon->setIcon(icon);
|
m_pTrayIcon->setIcon(QIcon(barrierIconFiles[state]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::trayActivated(QSystemTrayIcon::ActivationReason reason)
|
void MainWindow::trayActivated(QSystemTrayIcon::ActivationReason reason)
|
||||||
@@ -503,7 +501,7 @@ void MainWindow::startBarrier()
|
|||||||
// launched the process (e.g. when launched with elevation). setting the
|
// launched the process (e.g. when launched with elevation). setting the
|
||||||
// profile dir on launch ensures it uses the same profile dir is used
|
// profile dir on launch ensures it uses the same profile dir is used
|
||||||
// no matter how its relaunched.
|
// no matter how its relaunched.
|
||||||
args << "--profile-dir" << getProfileRootForArg();
|
args << "--profile-dir" << QString::fromStdString("\"" + DataDirectories::profile() + "\"");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((barrierType() == barrierClient && !clientArgs(args, app))
|
if ((barrierType() == barrierClient && !clientArgs(args, app))
|
||||||
@@ -583,7 +581,7 @@ bool MainWindow::clientArgs(QStringList& args, QString& app)
|
|||||||
if (m_pCheckBoxAutoConfig->isChecked()) {
|
if (m_pCheckBoxAutoConfig->isChecked()) {
|
||||||
if (m_pComboServerList->count() != 0) {
|
if (m_pComboServerList->count() != 0) {
|
||||||
QString serverIp = m_pComboServerList->currentText();
|
QString serverIp = m_pComboServerList->currentText();
|
||||||
args << serverIp + ":" + QString::number(appConfig().port());
|
args << "[" + serverIp + "]:" + QString::number(appConfig().port());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -597,7 +595,7 @@ bool MainWindow::clientArgs(QStringList& args, QString& app)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
args << m_pLineEditHostname->text() + ":" + QString::number(appConfig().port());
|
args << "[" + m_pLineEditHostname->text() + "]:" + QString::number(appConfig().port());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -639,8 +637,10 @@ QString MainWindow::configFilename()
|
|||||||
|
|
||||||
QString MainWindow::address()
|
QString MainWindow::address()
|
||||||
{
|
{
|
||||||
QString i = appConfig().networkInterface();
|
QString address = appConfig().networkInterface();
|
||||||
return (!i.isEmpty() ? i : "") + ":" + QString::number(appConfig().port());
|
if (!address.isEmpty())
|
||||||
|
address = "[" + address + "]";
|
||||||
|
return address + ":" + QString::number(appConfig().port());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MainWindow::appPath(const QString& name)
|
QString MainWindow::appPath(const QString& name)
|
||||||
@@ -1252,21 +1252,6 @@ void MainWindow::bonjourInstallFinished()
|
|||||||
m_pCheckBoxAutoConfig->setChecked(true);
|
m_pCheckBoxAutoConfig->setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MainWindow::getProfileRootForArg()
|
|
||||||
{
|
|
||||||
CoreInterface coreInterface;
|
|
||||||
QString dir = coreInterface.getProfileDir();
|
|
||||||
|
|
||||||
// HACK: strip our app name since we're returning the root dir.
|
|
||||||
#if defined(Q_OS_WIN)
|
|
||||||
dir.replace("\\Barrier", "");
|
|
||||||
#else
|
|
||||||
dir.replace("/.barrier", "");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return QString("\"%1\"").arg(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::windowStateChanged()
|
void MainWindow::windowStateChanged()
|
||||||
{
|
{
|
||||||
if (windowState() == Qt::WindowMinimized && appConfig().getMinimizeToTray())
|
if (windowState() == Qt::WindowMinimized && appConfig().getMinimizeToTray())
|
||||||
|
|||||||
@@ -166,7 +166,6 @@ public slots:
|
|||||||
bool isBonjourRunning();
|
bool isBonjourRunning();
|
||||||
void downloadBonjour();
|
void downloadBonjour();
|
||||||
void promptAutoConfig();
|
void promptAutoConfig();
|
||||||
QString getProfileRootForArg();
|
|
||||||
void checkConnected(const QString& line);
|
void checkConnected(const QString& line);
|
||||||
void checkFingerprint(const QString& line);
|
void checkFingerprint(const QString& line);
|
||||||
void restartBarrier();
|
void restartBarrier();
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
#include "SettingsDialog.h"
|
#include "SettingsDialog.h"
|
||||||
|
|
||||||
#include "CoreInterface.h"
|
|
||||||
#include "BarrierLocale.h"
|
#include "BarrierLocale.h"
|
||||||
#include "QBarrierApplication.h"
|
#include "QBarrierApplication.h"
|
||||||
#include "QUtility.h"
|
#include "QUtility.h"
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "ui_SettingsDialogBase.h"
|
#include "ui_SettingsDialogBase.h"
|
||||||
#include "BarrierLocale.h"
|
#include "BarrierLocale.h"
|
||||||
#include "CoreInterface.h"
|
|
||||||
|
|
||||||
class AppConfig;
|
class AppConfig;
|
||||||
|
|
||||||
@@ -43,7 +42,6 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase
|
|||||||
private:
|
private:
|
||||||
AppConfig& m_appConfig;
|
AppConfig& m_appConfig;
|
||||||
BarrierLocale m_Locale;
|
BarrierLocale m_Locale;
|
||||||
CoreInterface m_CoreInterface;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_m_pComboLanguage_currentIndexChanged(int index);
|
void on_m_pComboLanguage_currentIndexChanged(int index);
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
#include "SetupWizard.h"
|
#include "SetupWizard.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "WebClient.h"
|
|
||||||
#include "QBarrierApplication.h"
|
#include "QBarrierApplication.h"
|
||||||
#include "QUtility.h"
|
#include "QUtility.h"
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SslCertificate.h"
|
#include "SslCertificate.h"
|
||||||
|
|
||||||
#include "Fingerprint.h"
|
#include "Fingerprint.h"
|
||||||
|
#include "common/DataDirectories.h"
|
||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@@ -37,7 +37,7 @@ static const char kConfigFile[] = "barrier.conf";
|
|||||||
SslCertificate::SslCertificate(QObject *parent) :
|
SslCertificate::SslCertificate(QObject *parent) :
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
m_ProfileDir = m_CoreInterface.getProfileDir();
|
m_ProfileDir = QString::fromStdString(DataDirectories::profile());
|
||||||
if (m_ProfileDir.isEmpty()) {
|
if (m_ProfileDir.isEmpty()) {
|
||||||
emit error(tr("Failed to get profile directory."));
|
emit error(tr("Failed to get profile directory."));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreInterface.h"
|
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class SslCertificate : public QObject
|
class SslCertificate : public QObject
|
||||||
@@ -43,5 +41,4 @@ private:
|
|||||||
private:
|
private:
|
||||||
QString m_ProfileDir;
|
QString m_ProfileDir;
|
||||||
QString m_ToolOutput;
|
QString m_ToolOutput;
|
||||||
CoreInterface m_CoreInterface;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2015-2016 Symless Ltd.
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "WebClient.h"
|
|
||||||
|
|
||||||
#include "QUtility.h"
|
|
||||||
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
bool
|
|
||||||
WebClient::getEdition (int& edition, QString& errorOut) {
|
|
||||||
QString responseJson = request();
|
|
||||||
|
|
||||||
/* TODO: This is horrible and should be ripped out as soon as we move
|
|
||||||
* to Qt 5. See issue #5630
|
|
||||||
*/
|
|
||||||
|
|
||||||
QRegExp resultRegex(".*\"result\".*:.*(true|false).*");
|
|
||||||
if (resultRegex.exactMatch (responseJson)) {
|
|
||||||
QString boolString = resultRegex.cap(1);
|
|
||||||
if (boolString == "true") {
|
|
||||||
QRegExp editionRegex(".*\"edition\".*:.*\"([^\"]+)\".*");
|
|
||||||
if (editionRegex.exactMatch(responseJson)) {
|
|
||||||
QString e = editionRegex.cap(1);
|
|
||||||
edition = e.toInt();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
throw std::runtime_error ("Unrecognised server response.");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
errorOut = tr("Login failed. Invalid email address or password.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
QRegExp errorRegex(".*\"error\".*:.*\"([^\"]+)\".*");
|
|
||||||
if (errorRegex.exactMatch (responseJson)) {
|
|
||||||
errorOut = errorRegex.cap(1).replace("\\n", "\n");
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
throw std::runtime_error ("Unrecognised server response.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
WebClient::setEmail (QString email, QString& errorOut) {
|
|
||||||
if (email.isEmpty()) {
|
|
||||||
errorOut = tr("Your email address cannot be left blank.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_Email = email;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
WebClient::setPassword (QString password, QString&) {
|
|
||||||
m_Password = password;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString
|
|
||||||
WebClient::request() {
|
|
||||||
QStringList args("--login-auth");
|
|
||||||
QString credentials (m_Email + ":" + hash(m_Password) + "\n");
|
|
||||||
return m_CoreInterface.run (args, credentials);
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2015-2016 Symless Ltd.
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WEBCLIENT_H
|
|
||||||
#define WEBCLIENT_H
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
#include "CoreInterface.h"
|
|
||||||
|
|
||||||
class QMessageBox;
|
|
||||||
class QWidget;
|
|
||||||
class QStringList;
|
|
||||||
|
|
||||||
class WebClient : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool getEdition (int& edition, QString& errorOut);
|
|
||||||
bool setEmail (QString email, QString& errorOut);
|
|
||||||
bool setPassword (QString password, QString& errorOut);
|
|
||||||
signals:
|
|
||||||
void error(QString e);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString request();
|
|
||||||
|
|
||||||
QString m_Email;
|
|
||||||
QString m_Password;
|
|
||||||
CoreInterface m_CoreInterface;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // WEBCLIENT_H
|
|
||||||
@@ -40,7 +40,6 @@
|
|||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
# include "arch/win32/ArchConsoleWindows.h"
|
# include "arch/win32/ArchConsoleWindows.h"
|
||||||
# include "arch/win32/ArchDaemonWindows.h"
|
# include "arch/win32/ArchDaemonWindows.h"
|
||||||
# include "arch/win32/ArchFileWindows.h"
|
|
||||||
# include "arch/win32/ArchLogWindows.h"
|
# include "arch/win32/ArchLogWindows.h"
|
||||||
# include "arch/win32/ArchMiscWindows.h"
|
# include "arch/win32/ArchMiscWindows.h"
|
||||||
# include "arch/win32/ArchMultithreadWindows.h"
|
# include "arch/win32/ArchMultithreadWindows.h"
|
||||||
@@ -54,7 +53,6 @@
|
|||||||
#elif SYSAPI_UNIX
|
#elif SYSAPI_UNIX
|
||||||
# include "arch/unix/ArchConsoleUnix.h"
|
# include "arch/unix/ArchConsoleUnix.h"
|
||||||
# include "arch/unix/ArchDaemonUnix.h"
|
# include "arch/unix/ArchDaemonUnix.h"
|
||||||
# include "arch/unix/ArchFileUnix.h"
|
|
||||||
# include "arch/unix/ArchLogUnix.h"
|
# include "arch/unix/ArchLogUnix.h"
|
||||||
# if HAVE_PTHREAD
|
# if HAVE_PTHREAD
|
||||||
# include "arch/unix/ArchMultithreadPosix.h"
|
# include "arch/unix/ArchMultithreadPosix.h"
|
||||||
@@ -86,7 +84,6 @@ typically at the beginning of \c main().
|
|||||||
*/
|
*/
|
||||||
class Arch : public ARCH_CONSOLE,
|
class Arch : public ARCH_CONSOLE,
|
||||||
public ARCH_DAEMON,
|
public ARCH_DAEMON,
|
||||||
public ARCH_FILE,
|
|
||||||
public ARCH_LOG,
|
public ARCH_LOG,
|
||||||
public ARCH_MULTITHREAD,
|
public ARCH_MULTITHREAD,
|
||||||
public ARCH_NETWORK,
|
public ARCH_NETWORK,
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2012-2016 Symless Ltd.
|
|
||||||
* Copyright (C) 2002 Chris Schoeneman
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/IInterface.h"
|
|
||||||
#include "common/stdstring.h"
|
|
||||||
#include "base/String.h"
|
|
||||||
|
|
||||||
//! Interface for architecture dependent file system operations
|
|
||||||
/*!
|
|
||||||
This interface defines the file system operations required by
|
|
||||||
barrier. Each architecture must implement this interface.
|
|
||||||
*/
|
|
||||||
class IArchFile : public IInterface {
|
|
||||||
public:
|
|
||||||
//! @name manipulators
|
|
||||||
//@{
|
|
||||||
|
|
||||||
//! Extract base name
|
|
||||||
/*!
|
|
||||||
Find the base name in the given \c pathname.
|
|
||||||
*/
|
|
||||||
virtual const char* getBasename(const char* pathname) = 0;
|
|
||||||
|
|
||||||
//! Get user's home directory
|
|
||||||
/*!
|
|
||||||
Returns the user's home directory. Returns the empty string if
|
|
||||||
this cannot be determined.
|
|
||||||
*/
|
|
||||||
virtual std::string getUserDirectory() = 0;
|
|
||||||
|
|
||||||
//! Get system directory
|
|
||||||
/*!
|
|
||||||
Returns the ussystem configuration file directory.
|
|
||||||
*/
|
|
||||||
virtual std::string getSystemDirectory() = 0;
|
|
||||||
|
|
||||||
//! Get installed directory
|
|
||||||
/*!
|
|
||||||
Returns the directory in which Barrier is installed.
|
|
||||||
*/
|
|
||||||
virtual std::string getInstalledDirectory() = 0;
|
|
||||||
|
|
||||||
//! Get log directory
|
|
||||||
/*!
|
|
||||||
Returns the log file directory.
|
|
||||||
*/
|
|
||||||
virtual std::string getLogDirectory() = 0;
|
|
||||||
|
|
||||||
//! Get plugins directory
|
|
||||||
/*!
|
|
||||||
Returns the plugin files directory. If no plugin directory is set,
|
|
||||||
this will return the plugin folder within the user's profile.
|
|
||||||
*/
|
|
||||||
virtual std::string getPluginDirectory() = 0;
|
|
||||||
|
|
||||||
//! Get user's profile directory
|
|
||||||
/*!
|
|
||||||
Returns the user's profile directory. If no profile directory is set,
|
|
||||||
this will return the user's profile according to the operating system,
|
|
||||||
which will depend on which user launched the program.
|
|
||||||
*/
|
|
||||||
virtual std::string getProfileDirectory() = 0;
|
|
||||||
|
|
||||||
//! Concatenate path components
|
|
||||||
/*!
|
|
||||||
Concatenate pathname components with a directory separator
|
|
||||||
between them. This should not check if the resulting path
|
|
||||||
is longer than allowed by the system; we'll rely on the
|
|
||||||
system calls to tell us that.
|
|
||||||
*/
|
|
||||||
virtual std::string concatPath(
|
|
||||||
const std::string& prefix,
|
|
||||||
const std::string& suffix) = 0;
|
|
||||||
|
|
||||||
//@}
|
|
||||||
//! Set the user's profile directory
|
|
||||||
/*
|
|
||||||
Returns the user's profile directory.
|
|
||||||
*/
|
|
||||||
virtual void setProfileDirectory(const String& s) = 0;
|
|
||||||
|
|
||||||
//@}
|
|
||||||
//! Set the user's plugin directory
|
|
||||||
/*
|
|
||||||
Returns the user's plugin directory.
|
|
||||||
*/
|
|
||||||
virtual void setPluginDirectory(const String& s) = 0;
|
|
||||||
};
|
|
||||||
@@ -64,6 +64,7 @@ public:
|
|||||||
enum EAddressFamily {
|
enum EAddressFamily {
|
||||||
kUNKNOWN,
|
kUNKNOWN,
|
||||||
kINET,
|
kINET,
|
||||||
|
kINET6,
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Supported socket types
|
//! Supported socket types
|
||||||
|
|||||||
@@ -1,163 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2012-2016 Symless Ltd.
|
|
||||||
* Copyright (C) 2002 Chris Schoeneman
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "arch/unix/ArchFileUnix.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
//
|
|
||||||
// ArchFileUnix
|
|
||||||
//
|
|
||||||
|
|
||||||
ArchFileUnix::ArchFileUnix()
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
ArchFileUnix::~ArchFileUnix()
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
const char*
|
|
||||||
ArchFileUnix::getBasename(const char* pathname)
|
|
||||||
{
|
|
||||||
if (pathname == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* basename = strrchr(pathname, '/');
|
|
||||||
if (basename != NULL) {
|
|
||||||
return basename + 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return pathname;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileUnix::getUserDirectory()
|
|
||||||
{
|
|
||||||
char* buffer = NULL;
|
|
||||||
std::string dir;
|
|
||||||
#if HAVE_GETPWUID_R
|
|
||||||
struct passwd pwent;
|
|
||||||
struct passwd* pwentp;
|
|
||||||
#if defined(_SC_GETPW_R_SIZE_MAX)
|
|
||||||
long size = sysconf(_SC_GETPW_R_SIZE_MAX);
|
|
||||||
if (size == -1) {
|
|
||||||
size = BUFSIZ;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
long size = BUFSIZ;
|
|
||||||
#endif
|
|
||||||
buffer = new char[size];
|
|
||||||
getpwuid_r(getuid(), &pwent, buffer, size, &pwentp);
|
|
||||||
#else
|
|
||||||
struct passwd* pwentp = getpwuid(getuid());
|
|
||||||
#endif
|
|
||||||
if (pwentp != NULL && pwentp->pw_dir != NULL) {
|
|
||||||
dir = pwentp->pw_dir;
|
|
||||||
}
|
|
||||||
delete[] buffer;
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileUnix::getSystemDirectory()
|
|
||||||
{
|
|
||||||
return "/etc";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileUnix::getInstalledDirectory()
|
|
||||||
{
|
|
||||||
#if WINAPI_XWINDOWS
|
|
||||||
return "/usr/bin";
|
|
||||||
#else
|
|
||||||
return "/Applications/Barrier.app/Contents/MacOS";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileUnix::getLogDirectory()
|
|
||||||
{
|
|
||||||
return "/var/log";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileUnix::getPluginDirectory()
|
|
||||||
{
|
|
||||||
if (!m_pluginDirectory.empty()) {
|
|
||||||
return m_pluginDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if WINAPI_XWINDOWS
|
|
||||||
return getProfileDirectory().append("/plugins");
|
|
||||||
#else
|
|
||||||
return getProfileDirectory().append("/Plugins");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileUnix::getProfileDirectory()
|
|
||||||
{
|
|
||||||
String dir;
|
|
||||||
if (!m_profileDirectory.empty()) {
|
|
||||||
dir = m_profileDirectory;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#if WINAPI_XWINDOWS
|
|
||||||
dir = getUserDirectory().append("/.barrier");
|
|
||||||
#else
|
|
||||||
dir = getUserDirectory().append("/Library/Application Support/Barrier");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return dir;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileUnix::concatPath(const std::string& prefix,
|
|
||||||
const std::string& suffix)
|
|
||||||
{
|
|
||||||
std::string path;
|
|
||||||
path.reserve(prefix.size() + 1 + suffix.size());
|
|
||||||
path += prefix;
|
|
||||||
if (path.size() == 0 || path[path.size() - 1] != '/') {
|
|
||||||
path += '/';
|
|
||||||
}
|
|
||||||
path += suffix;
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ArchFileUnix::setProfileDirectory(const String& s)
|
|
||||||
{
|
|
||||||
m_profileDirectory = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ArchFileUnix::setPluginDirectory(const String& s)
|
|
||||||
{
|
|
||||||
m_pluginDirectory = s;
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2012-2016 Symless Ltd.
|
|
||||||
* Copyright (C) 2002 Chris Schoeneman
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "arch/IArchFile.h"
|
|
||||||
|
|
||||||
#define ARCH_FILE ArchFileUnix
|
|
||||||
|
|
||||||
//! Unix implementation of IArchFile
|
|
||||||
class ArchFileUnix : public IArchFile {
|
|
||||||
public:
|
|
||||||
ArchFileUnix();
|
|
||||||
virtual ~ArchFileUnix();
|
|
||||||
|
|
||||||
// IArchFile overrides
|
|
||||||
virtual const char* getBasename(const char* pathname);
|
|
||||||
virtual std::string getUserDirectory();
|
|
||||||
virtual std::string getSystemDirectory();
|
|
||||||
virtual std::string getInstalledDirectory();
|
|
||||||
virtual std::string getLogDirectory();
|
|
||||||
virtual std::string getPluginDirectory();
|
|
||||||
virtual std::string getProfileDirectory();
|
|
||||||
virtual std::string concatPath(const std::string& prefix,
|
|
||||||
const std::string& suffix);
|
|
||||||
virtual void setProfileDirectory(const String& s);
|
|
||||||
virtual void setPluginDirectory(const String& s);
|
|
||||||
|
|
||||||
private:
|
|
||||||
String m_profileDirectory;
|
|
||||||
String m_pluginDirectory;
|
|
||||||
};
|
|
||||||
@@ -52,7 +52,8 @@
|
|||||||
|
|
||||||
static const int s_family[] = {
|
static const int s_family[] = {
|
||||||
PF_UNSPEC,
|
PF_UNSPEC,
|
||||||
PF_INET
|
PF_INET,
|
||||||
|
PF_INET6,
|
||||||
};
|
};
|
||||||
static const int s_type[] = {
|
static const int s_type[] = {
|
||||||
SOCK_DGRAM,
|
SOCK_DGRAM,
|
||||||
@@ -112,6 +113,11 @@ ArchNetworkBSD::newSocket(EAddressFamily family, ESocketType type)
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
setBlockingOnSocket(fd, false);
|
setBlockingOnSocket(fd, false);
|
||||||
|
if (family == kINET6) {
|
||||||
|
int flag = 0;
|
||||||
|
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) != 0)
|
||||||
|
throwError(errno);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
close(fd);
|
close(fd);
|
||||||
@@ -191,7 +197,7 @@ ArchNetworkBSD::bindSocket(ArchSocket s, ArchNetAddress addr)
|
|||||||
assert(s != NULL);
|
assert(s != NULL);
|
||||||
assert(addr != NULL);
|
assert(addr != NULL);
|
||||||
|
|
||||||
if (bind(s->m_fd, &addr->m_addr, addr->m_len) == -1) {
|
if (bind(s->m_fd, TYPED_ADDR(struct sockaddr, addr), addr->m_len) == -1) {
|
||||||
throwError(errno);
|
throwError(errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,7 +230,7 @@ ArchNetworkBSD::acceptSocket(ArchSocket s, ArchNetAddress* addr)
|
|||||||
|
|
||||||
// accept on socket
|
// accept on socket
|
||||||
ACCEPT_TYPE_ARG3 len = (ACCEPT_TYPE_ARG3)((*addr)->m_len);
|
ACCEPT_TYPE_ARG3 len = (ACCEPT_TYPE_ARG3)((*addr)->m_len);
|
||||||
int fd = accept(s->m_fd, &(*addr)->m_addr, &len);
|
int fd = accept(s->m_fd, TYPED_ADDR(struct sockaddr, (*addr)), &len);
|
||||||
(*addr)->m_len = (socklen_t)len;
|
(*addr)->m_len = (socklen_t)len;
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
int err = errno;
|
int err = errno;
|
||||||
@@ -266,7 +272,7 @@ ArchNetworkBSD::connectSocket(ArchSocket s, ArchNetAddress addr)
|
|||||||
assert(s != NULL);
|
assert(s != NULL);
|
||||||
assert(addr != NULL);
|
assert(addr != NULL);
|
||||||
|
|
||||||
if (connect(s->m_fd, &addr->m_addr, addr->m_len) == -1) {
|
if (connect(s->m_fd, TYPED_ADDR(struct sockaddr, addr), addr->m_len) == -1) {
|
||||||
if (errno == EISCONN) {
|
if (errno == EISCONN) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -645,15 +651,22 @@ ArchNetworkBSD::newAnyAddr(EAddressFamily family)
|
|||||||
// fill it in
|
// fill it in
|
||||||
switch (family) {
|
switch (family) {
|
||||||
case kINET: {
|
case kINET: {
|
||||||
struct sockaddr_in* ipAddr =
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
memset(ipAddr, 0, sizeof(struct sockaddr_in));
|
||||||
ipAddr->sin_family = AF_INET;
|
ipAddr->sin_family = AF_INET;
|
||||||
ipAddr->sin_port = 0;
|
|
||||||
ipAddr->sin_addr.s_addr = INADDR_ANY;
|
ipAddr->sin_addr.s_addr = INADDR_ANY;
|
||||||
addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
|
addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kINET6: {
|
||||||
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||||
|
memset(ipAddr, 0, sizeof(struct sockaddr_in6));
|
||||||
|
ipAddr->sin6_family = AF_INET6;
|
||||||
|
memcpy(&ipAddr->sin6_addr, &in6addr_any, sizeof(in6addr_any));
|
||||||
|
addr->m_len = (socklen_t)sizeof(struct sockaddr_in6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
delete addr;
|
delete addr;
|
||||||
assert(0 && "invalid family");
|
assert(0 && "invalid family");
|
||||||
@@ -677,48 +690,31 @@ ArchNetworkBSD::nameToAddr(const std::string& name)
|
|||||||
// allocate address
|
// allocate address
|
||||||
ArchNetAddressImpl* addr = new ArchNetAddressImpl;
|
ArchNetAddressImpl* addr = new ArchNetAddressImpl;
|
||||||
|
|
||||||
// try to convert assuming an IPv4 dot notation address
|
char ipstr[INET6_ADDRSTRLEN];
|
||||||
struct sockaddr_in inaddr;
|
struct addrinfo hints;
|
||||||
memset(&inaddr, 0, sizeof(inaddr));
|
struct addrinfo *p;
|
||||||
if (inet_aton(name.c_str(), &inaddr.sin_addr) != 0) {
|
int ret;
|
||||||
// it's a dot notation address
|
|
||||||
addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
|
|
||||||
inaddr.sin_family = AF_INET;
|
|
||||||
inaddr.sin_port = 0;
|
|
||||||
memcpy(&addr->m_addr, &inaddr, addr->m_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
memset(&hints, 0, sizeof(hints));
|
||||||
// mutexed address lookup (ugh)
|
hints.ai_family = AF_UNSPEC;
|
||||||
ARCH->lockMutex(m_mutex);
|
|
||||||
struct hostent* info = gethostbyname(name.c_str());
|
|
||||||
if (info == NULL) {
|
|
||||||
ARCH->unlockMutex(m_mutex);
|
|
||||||
delete addr;
|
|
||||||
throwNameError(h_errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy over address (only IPv4 currently supported)
|
ARCH->lockMutex(m_mutex);
|
||||||
if (info->h_addrtype == AF_INET) {
|
if ((ret = getaddrinfo(name.c_str(), NULL, &hints, &p)) != 0) {
|
||||||
addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
|
|
||||||
inaddr.sin_family = info->h_addrtype;
|
|
||||||
inaddr.sin_port = 0;
|
|
||||||
memcpy(&inaddr.sin_addr, info->h_addr_list[0],
|
|
||||||
sizeof(inaddr.sin_addr));
|
|
||||||
memcpy(&addr->m_addr, &inaddr, addr->m_len);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ARCH->unlockMutex(m_mutex);
|
|
||||||
delete addr;
|
|
||||||
throw XArchNetworkNameUnsupported(
|
|
||||||
"The requested name is valid but "
|
|
||||||
"does not have a supported address family");
|
|
||||||
}
|
|
||||||
|
|
||||||
// done with static buffer
|
|
||||||
ARCH->unlockMutex(m_mutex);
|
ARCH->unlockMutex(m_mutex);
|
||||||
|
delete addr;
|
||||||
|
throwNameError(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->ai_family == AF_INET) {
|
||||||
|
addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
|
||||||
|
} else {
|
||||||
|
addr->m_len = (socklen_t)sizeof(struct sockaddr_in6);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&addr->m_addr, p->ai_addr, addr->m_len);
|
||||||
|
freeaddrinfo(p);
|
||||||
|
ARCH->unlockMutex(m_mutex);
|
||||||
|
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -737,15 +733,17 @@ ArchNetworkBSD::addrToName(ArchNetAddress addr)
|
|||||||
|
|
||||||
// mutexed name lookup (ugh)
|
// mutexed name lookup (ugh)
|
||||||
ARCH->lockMutex(m_mutex);
|
ARCH->lockMutex(m_mutex);
|
||||||
struct hostent* info = gethostbyaddr(&addr->m_addr,
|
char host[1024];
|
||||||
addr->m_len, addr->m_addr.sa_family);
|
char service[20];
|
||||||
if (info == NULL) {
|
int ret = getnameinfo(TYPED_ADDR(struct sockaddr, addr), addr->m_len, host,
|
||||||
|
sizeof(host), service, sizeof(service), 0);
|
||||||
|
if (ret != 0) {
|
||||||
ARCH->unlockMutex(m_mutex);
|
ARCH->unlockMutex(m_mutex);
|
||||||
throwNameError(h_errno);
|
throwNameError(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
// save (primary) name
|
// save (primary) name
|
||||||
std::string name = info->h_name;
|
std::string name = host;
|
||||||
|
|
||||||
// done with static buffer
|
// done with static buffer
|
||||||
ARCH->unlockMutex(m_mutex);
|
ARCH->unlockMutex(m_mutex);
|
||||||
@@ -760,14 +758,22 @@ ArchNetworkBSD::addrToString(ArchNetAddress addr)
|
|||||||
|
|
||||||
switch (getAddrFamily(addr)) {
|
switch (getAddrFamily(addr)) {
|
||||||
case kINET: {
|
case kINET: {
|
||||||
struct sockaddr_in* ipAddr =
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
|
||||||
ARCH->lockMutex(m_mutex);
|
ARCH->lockMutex(m_mutex);
|
||||||
std::string s = inet_ntoa(ipAddr->sin_addr);
|
std::string s = inet_ntoa(ipAddr->sin_addr);
|
||||||
ARCH->unlockMutex(m_mutex);
|
ARCH->unlockMutex(m_mutex);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kINET6: {
|
||||||
|
char strAddr[INET6_ADDRSTRLEN];
|
||||||
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||||
|
ARCH->lockMutex(m_mutex);
|
||||||
|
inet_ntop(AF_INET6, &ipAddr->sin6_addr, strAddr, INET6_ADDRSTRLEN);
|
||||||
|
ARCH->unlockMutex(m_mutex);
|
||||||
|
return strAddr;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0 && "unknown address family");
|
assert(0 && "unknown address family");
|
||||||
return "";
|
return "";
|
||||||
@@ -779,9 +785,11 @@ ArchNetworkBSD::getAddrFamily(ArchNetAddress addr)
|
|||||||
{
|
{
|
||||||
assert(addr != NULL);
|
assert(addr != NULL);
|
||||||
|
|
||||||
switch (addr->m_addr.sa_family) {
|
switch (addr->m_addr.ss_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
return kINET;
|
return kINET;
|
||||||
|
case AF_INET6:
|
||||||
|
return kINET6;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return kUNKNOWN;
|
return kUNKNOWN;
|
||||||
@@ -795,12 +803,17 @@ ArchNetworkBSD::setAddrPort(ArchNetAddress addr, int port)
|
|||||||
|
|
||||||
switch (getAddrFamily(addr)) {
|
switch (getAddrFamily(addr)) {
|
||||||
case kINET: {
|
case kINET: {
|
||||||
struct sockaddr_in* ipAddr =
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
|
||||||
ipAddr->sin_port = htons(port);
|
ipAddr->sin_port = htons(port);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kINET6: {
|
||||||
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||||
|
ipAddr->sin6_port = htons(port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0 && "unknown address family");
|
assert(0 && "unknown address family");
|
||||||
break;
|
break;
|
||||||
@@ -814,11 +827,15 @@ ArchNetworkBSD::getAddrPort(ArchNetAddress addr)
|
|||||||
|
|
||||||
switch (getAddrFamily(addr)) {
|
switch (getAddrFamily(addr)) {
|
||||||
case kINET: {
|
case kINET: {
|
||||||
struct sockaddr_in* ipAddr =
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
|
||||||
return ntohs(ipAddr->sin_port);
|
return ntohs(ipAddr->sin_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kINET6: {
|
||||||
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||||
|
return ntohs(ipAddr->sin6_port);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0 && "unknown address family");
|
assert(0 && "unknown address family");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -832,12 +849,17 @@ ArchNetworkBSD::isAnyAddr(ArchNetAddress addr)
|
|||||||
|
|
||||||
switch (getAddrFamily(addr)) {
|
switch (getAddrFamily(addr)) {
|
||||||
case kINET: {
|
case kINET: {
|
||||||
struct sockaddr_in* ipAddr =
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
|
||||||
return (ipAddr->sin_addr.s_addr == INADDR_ANY &&
|
return (ipAddr->sin_addr.s_addr == INADDR_ANY &&
|
||||||
addr->m_len == (socklen_t)sizeof(struct sockaddr_in));
|
addr->m_len == (socklen_t)sizeof(struct sockaddr_in));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kINET6: {
|
||||||
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||||
|
return (memcmp(&ipAddr->sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
|
||||||
|
addr->m_len == (socklen_t)sizeof(struct sockaddr_in6));
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0 && "unknown address family");
|
assert(0 && "unknown address family");
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ typedef int socklen_t;
|
|||||||
typedef char optval_t;
|
typedef char optval_t;
|
||||||
|
|
||||||
#define ARCH_NETWORK ArchNetworkBSD
|
#define ARCH_NETWORK ArchNetworkBSD
|
||||||
|
#define TYPED_ADDR(type_, addr_) (reinterpret_cast<type_*>(&addr_->m_addr))
|
||||||
|
|
||||||
class ArchSocketImpl {
|
class ArchSocketImpl {
|
||||||
public:
|
public:
|
||||||
@@ -50,8 +51,8 @@ public:
|
|||||||
ArchNetAddressImpl() : m_len(sizeof(m_addr)) { }
|
ArchNetAddressImpl() : m_len(sizeof(m_addr)) { }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct sockaddr m_addr;
|
struct sockaddr_storage m_addr;
|
||||||
socklen_t m_len;
|
socklen_t m_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Berkeley (BSD) sockets implementation of IArchNetwork
|
//! Berkeley (BSD) sockets implementation of IArchNetwork
|
||||||
|
|||||||
@@ -1,203 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2012-2016 Symless Ltd.
|
|
||||||
* Copyright (C) 2002 Chris Schoeneman
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "arch/win32/ArchFileWindows.h"
|
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <shlobj.h>
|
|
||||||
#include <tchar.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
//
|
|
||||||
// ArchFileWindows
|
|
||||||
//
|
|
||||||
|
|
||||||
ArchFileWindows::ArchFileWindows()
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
ArchFileWindows::~ArchFileWindows()
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
const char*
|
|
||||||
ArchFileWindows::getBasename(const char* pathname)
|
|
||||||
{
|
|
||||||
if (pathname == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for last slash
|
|
||||||
const char* basename = strrchr(pathname, '/');
|
|
||||||
if (basename != NULL) {
|
|
||||||
++basename;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
basename = pathname;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for last backslash
|
|
||||||
const char* basename2 = strrchr(pathname, '\\');
|
|
||||||
if (basename2 != NULL && basename2 > basename) {
|
|
||||||
basename = basename2 + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return basename;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileWindows::getUserDirectory()
|
|
||||||
{
|
|
||||||
// try %HOMEPATH%
|
|
||||||
TCHAR dir[MAX_PATH];
|
|
||||||
DWORD size = sizeof(dir) / sizeof(TCHAR);
|
|
||||||
DWORD result = GetEnvironmentVariable(_T("HOMEPATH"), dir, size);
|
|
||||||
if (result != 0 && result <= size) {
|
|
||||||
// sanity check -- if dir doesn't appear to start with a
|
|
||||||
// drive letter and isn't a UNC name then don't use it
|
|
||||||
// FIXME -- allow UNC names
|
|
||||||
if (dir[0] != '\0' && (dir[1] == ':' ||
|
|
||||||
((dir[0] == '\\' || dir[0] == '/') &&
|
|
||||||
(dir[1] == '\\' || dir[1] == '/')))) {
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the location of the personal files. that's as close to
|
|
||||||
// a home directory as we're likely to find.
|
|
||||||
ITEMIDLIST* idl;
|
|
||||||
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_PERSONAL, &idl))) {
|
|
||||||
TCHAR* path = NULL;
|
|
||||||
if (SHGetPathFromIDList(idl, dir)) {
|
|
||||||
DWORD attr = GetFileAttributes(dir);
|
|
||||||
if (attr != 0xffffffff && (attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
|
||||||
path = dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
IMalloc* shalloc;
|
|
||||||
if (SUCCEEDED(SHGetMalloc(&shalloc))) {
|
|
||||||
shalloc->Free(idl);
|
|
||||||
shalloc->Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path != NULL) {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// use root of C drive as a default
|
|
||||||
return "C:";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileWindows::getSystemDirectory()
|
|
||||||
{
|
|
||||||
// get windows directory
|
|
||||||
char dir[MAX_PATH];
|
|
||||||
if (GetWindowsDirectory(dir, sizeof(dir)) != 0) {
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// can't get it. use C:\ as a default.
|
|
||||||
return "C:";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileWindows::getInstalledDirectory()
|
|
||||||
{
|
|
||||||
char fileNameBuffer[MAX_PATH];
|
|
||||||
GetModuleFileName(NULL, fileNameBuffer, MAX_PATH);
|
|
||||||
std::string fileName(fileNameBuffer);
|
|
||||||
size_t lastSlash = fileName.find_last_of("\\");
|
|
||||||
fileName = fileName.substr(0, lastSlash);
|
|
||||||
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileWindows::getLogDirectory()
|
|
||||||
{
|
|
||||||
return getInstalledDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileWindows::getPluginDirectory()
|
|
||||||
{
|
|
||||||
if (!m_pluginDirectory.empty()) {
|
|
||||||
return m_pluginDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string dir = getProfileDirectory();
|
|
||||||
dir.append("\\Plugins");
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileWindows::getProfileDirectory()
|
|
||||||
{
|
|
||||||
String dir;
|
|
||||||
if (!m_profileDirectory.empty()) {
|
|
||||||
dir = m_profileDirectory;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
TCHAR result[MAX_PATH];
|
|
||||||
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, result))) {
|
|
||||||
dir = result;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dir = getUserDirectory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK: append program name, this seems wrong.
|
|
||||||
dir.append("\\Barrier");
|
|
||||||
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string
|
|
||||||
ArchFileWindows::concatPath(const std::string& prefix,
|
|
||||||
const std::string& suffix)
|
|
||||||
{
|
|
||||||
std::string path;
|
|
||||||
path.reserve(prefix.size() + 1 + suffix.size());
|
|
||||||
path += prefix;
|
|
||||||
if (path.size() == 0 ||
|
|
||||||
(path[path.size() - 1] != '\\' &&
|
|
||||||
path[path.size() - 1] != '/')) {
|
|
||||||
path += '\\';
|
|
||||||
}
|
|
||||||
path += suffix;
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ArchFileWindows::setProfileDirectory(const String& s)
|
|
||||||
{
|
|
||||||
m_profileDirectory = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ArchFileWindows::setPluginDirectory(const String& s)
|
|
||||||
{
|
|
||||||
m_pluginDirectory = s;
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2012-2016 Symless Ltd.
|
|
||||||
* Copyright (C) 2002 Chris Schoeneman
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "arch/IArchFile.h"
|
|
||||||
|
|
||||||
#define ARCH_FILE ArchFileWindows
|
|
||||||
|
|
||||||
//! Win32 implementation of IArchFile
|
|
||||||
class ArchFileWindows : public IArchFile {
|
|
||||||
public:
|
|
||||||
ArchFileWindows();
|
|
||||||
virtual ~ArchFileWindows();
|
|
||||||
|
|
||||||
// IArchFile overrides
|
|
||||||
virtual const char* getBasename(const char* pathname);
|
|
||||||
virtual std::string getUserDirectory();
|
|
||||||
virtual std::string getSystemDirectory();
|
|
||||||
virtual std::string getInstalledDirectory();
|
|
||||||
virtual std::string getLogDirectory();
|
|
||||||
virtual std::string getPluginDirectory();
|
|
||||||
virtual std::string getProfileDirectory();
|
|
||||||
virtual std::string concatPath(const std::string& prefix,
|
|
||||||
const std::string& suffix);
|
|
||||||
virtual void setProfileDirectory(const String& s);
|
|
||||||
virtual void setPluginDirectory(const String& s);
|
|
||||||
|
|
||||||
private:
|
|
||||||
String m_profileDirectory;
|
|
||||||
String m_pluginDirectory;
|
|
||||||
};
|
|
||||||
@@ -26,7 +26,8 @@
|
|||||||
|
|
||||||
static const int s_family[] = {
|
static const int s_family[] = {
|
||||||
PF_UNSPEC,
|
PF_UNSPEC,
|
||||||
PF_INET
|
PF_INET,
|
||||||
|
PF_INET6,
|
||||||
};
|
};
|
||||||
static const int s_type[] = {
|
static const int s_type[] = {
|
||||||
SOCK_DGRAM,
|
SOCK_DGRAM,
|
||||||
@@ -156,7 +157,7 @@ ArchNetworkWinsock::initModule(HMODULE module)
|
|||||||
setfunc(startup, WSAStartup, int(PASCAL FAR*)(WORD, LPWSADATA));
|
setfunc(startup, WSAStartup, int(PASCAL FAR*)(WORD, LPWSADATA));
|
||||||
|
|
||||||
// startup network library
|
// startup network library
|
||||||
WORD version = MAKEWORD(2 /*major*/, 0 /*minor*/);
|
WORD version = MAKEWORD(2 /*major*/, 2 /*minor*/);
|
||||||
WSADATA data;
|
WSADATA data;
|
||||||
int err = startup(version, &data);
|
int err = startup(version, &data);
|
||||||
if (data.wVersion != version) {
|
if (data.wVersion != version) {
|
||||||
@@ -212,6 +213,11 @@ ArchNetworkWinsock::newSocket(EAddressFamily family, ESocketType type)
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
setBlockingOnSocket(fd, false);
|
setBlockingOnSocket(fd, false);
|
||||||
|
if (family == kINET6) {
|
||||||
|
int flag = 0;
|
||||||
|
if (setsockopt_winsock(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) == SOCKET_ERROR)
|
||||||
|
throwError(getsockerror_winsock());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
close_winsock(fd);
|
close_winsock(fd);
|
||||||
@@ -294,7 +300,7 @@ ArchNetworkWinsock::bindSocket(ArchSocket s, ArchNetAddress addr)
|
|||||||
assert(s != NULL);
|
assert(s != NULL);
|
||||||
assert(addr != NULL);
|
assert(addr != NULL);
|
||||||
|
|
||||||
if (bind_winsock(s->m_socket, &addr->m_addr, addr->m_len) == SOCKET_ERROR) {
|
if (bind_winsock(s->m_socket, TYPED_ADDR(struct sockaddr, addr), addr->m_len) == SOCKET_ERROR) {
|
||||||
throwError(getsockerror_winsock());
|
throwError(getsockerror_winsock());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -317,10 +323,10 @@ ArchNetworkWinsock::acceptSocket(ArchSocket s, ArchNetAddress* const addr)
|
|||||||
|
|
||||||
// create new socket and temporary address
|
// create new socket and temporary address
|
||||||
ArchSocketImpl* socket = new ArchSocketImpl;
|
ArchSocketImpl* socket = new ArchSocketImpl;
|
||||||
ArchNetAddress tmp = ArchNetAddressImpl::alloc(sizeof(struct sockaddr));
|
ArchNetAddress tmp = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in6));
|
||||||
|
|
||||||
// accept on socket
|
// accept on socket
|
||||||
SOCKET fd = accept_winsock(s->m_socket, &tmp->m_addr, &tmp->m_len);
|
SOCKET fd = accept_winsock(s->m_socket, TYPED_ADDR(struct sockaddr, tmp), &tmp->m_len);
|
||||||
if (fd == INVALID_SOCKET) {
|
if (fd == INVALID_SOCKET) {
|
||||||
int err = getsockerror_winsock();
|
int err = getsockerror_winsock();
|
||||||
delete socket;
|
delete socket;
|
||||||
@@ -368,7 +374,7 @@ ArchNetworkWinsock::connectSocket(ArchSocket s, ArchNetAddress addr)
|
|||||||
assert(s != NULL);
|
assert(s != NULL);
|
||||||
assert(addr != NULL);
|
assert(addr != NULL);
|
||||||
|
|
||||||
if (connect_winsock(s->m_socket, &addr->m_addr,
|
if (connect_winsock(s->m_socket, TYPED_ADDR(struct sockaddr, addr),
|
||||||
addr->m_len) == SOCKET_ERROR) {
|
addr->m_len) == SOCKET_ERROR) {
|
||||||
if (getsockerror_winsock() == WSAEISCONN) {
|
if (getsockerror_winsock() == WSAEISCONN) {
|
||||||
return true;
|
return true;
|
||||||
@@ -678,13 +684,22 @@ ArchNetworkWinsock::newAnyAddr(EAddressFamily family)
|
|||||||
switch (family) {
|
switch (family) {
|
||||||
case kINET: {
|
case kINET: {
|
||||||
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in));
|
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in));
|
||||||
struct sockaddr_in* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||||
|
memset(ipAddr, 0, sizeof(struct sockaddr_in));
|
||||||
ipAddr->sin_family = AF_INET;
|
ipAddr->sin_family = AF_INET;
|
||||||
ipAddr->sin_port = 0;
|
|
||||||
ipAddr->sin_addr.s_addr = INADDR_ANY;
|
ipAddr->sin_addr.s_addr = INADDR_ANY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kINET6: {
|
||||||
|
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in6));
|
||||||
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||||
|
memset(ipAddr, 0, sizeof(struct sockaddr_in6));
|
||||||
|
ipAddr->sin6_family = AF_INET6;
|
||||||
|
memcpy(&ipAddr->sin6_addr, &in6addr_any, sizeof(in6addr_any));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0 && "invalid family");
|
assert(0 && "invalid family");
|
||||||
}
|
}
|
||||||
@@ -705,41 +720,31 @@ ArchNetAddress
|
|||||||
ArchNetworkWinsock::nameToAddr(const std::string& name)
|
ArchNetworkWinsock::nameToAddr(const std::string& name)
|
||||||
{
|
{
|
||||||
// allocate address
|
// allocate address
|
||||||
ArchNetAddressImpl* addr = NULL;
|
|
||||||
|
|
||||||
// try to convert assuming an IPv4 dot notation address
|
ArchNetAddressImpl* addr = new ArchNetAddressImpl;
|
||||||
struct sockaddr_in inaddr;
|
|
||||||
memset(&inaddr, 0, sizeof(inaddr));
|
struct addrinfo hints;
|
||||||
inaddr.sin_family = AF_INET;
|
struct addrinfo *p;
|
||||||
inaddr.sin_port = 0;
|
memset(&hints, 0, sizeof(hints));
|
||||||
inaddr.sin_addr.s_addr = inet_addr_winsock(name.c_str());
|
hints.ai_family = AF_UNSPEC;
|
||||||
if (inaddr.sin_addr.s_addr != INADDR_NONE) {
|
int ret = -1;
|
||||||
// it's a dot notation address
|
|
||||||
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in));
|
ARCH->lockMutex(m_mutex);
|
||||||
memcpy(TYPED_ADDR(void, addr), &inaddr, addr->m_len);
|
if ((ret = getaddrinfo(name.c_str(), NULL, &hints, &p)) != 0) {
|
||||||
|
ARCH->unlockMutex(m_mutex);
|
||||||
|
delete addr;
|
||||||
|
throwNameError(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
if (p->ai_family == AF_INET) {
|
||||||
// address lookup
|
addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
|
||||||
struct hostent* info = gethostbyname_winsock(name.c_str());
|
} else {
|
||||||
if (info == NULL) {
|
addr->m_len = (socklen_t)sizeof(struct sockaddr_in6);
|
||||||
throwNameError(getsockerror_winsock());
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy over address (only IPv4 currently supported)
|
|
||||||
if (info->h_addrtype == AF_INET) {
|
|
||||||
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in));
|
|
||||||
memcpy(&inaddr.sin_addr, info->h_addr_list[0],
|
|
||||||
sizeof(inaddr.sin_addr));
|
|
||||||
memcpy(TYPED_ADDR(void, addr), &inaddr, addr->m_len);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw XArchNetworkNameUnsupported(
|
|
||||||
"The requested name is valid but "
|
|
||||||
"does not have a supported address family");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(&addr->m_addr, p->ai_addr, addr->m_len);
|
||||||
|
freeaddrinfo(p);
|
||||||
|
ARCH->unlockMutex(m_mutex);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,16 +761,17 @@ ArchNetworkWinsock::addrToName(ArchNetAddress addr)
|
|||||||
{
|
{
|
||||||
assert(addr != NULL);
|
assert(addr != NULL);
|
||||||
|
|
||||||
// name lookup
|
char host[1024];
|
||||||
struct hostent* info = gethostbyaddr_winsock(
|
char service[20];
|
||||||
reinterpret_cast<const char FAR*>(&addr->m_addr),
|
int ret = getnameinfo(TYPED_ADDR(struct sockaddr, addr), addr->m_len, host, sizeof(host), service, sizeof(service), 0);
|
||||||
addr->m_len, addr->m_addr.sa_family);
|
|
||||||
if (info == NULL) {
|
if (ret != NULL) {
|
||||||
throwNameError(getsockerror_winsock());
|
throwNameError(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return (primary) name
|
// return (primary) name
|
||||||
return info->h_name;
|
std::string name = host;
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
@@ -775,11 +781,17 @@ ArchNetworkWinsock::addrToString(ArchNetAddress addr)
|
|||||||
|
|
||||||
switch (getAddrFamily(addr)) {
|
switch (getAddrFamily(addr)) {
|
||||||
case kINET: {
|
case kINET: {
|
||||||
struct sockaddr_in* ipAddr =
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
|
||||||
return inet_ntoa_winsock(ipAddr->sin_addr);
|
return inet_ntoa_winsock(ipAddr->sin_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kINET6: {
|
||||||
|
char strAddr[INET6_ADDRSTRLEN];
|
||||||
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||||
|
inet_ntop(AF_INET6, &ipAddr->sin6_addr, strAddr, INET6_ADDRSTRLEN);
|
||||||
|
return strAddr;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0 && "unknown address family");
|
assert(0 && "unknown address family");
|
||||||
return "";
|
return "";
|
||||||
@@ -791,10 +803,13 @@ ArchNetworkWinsock::getAddrFamily(ArchNetAddress addr)
|
|||||||
{
|
{
|
||||||
assert(addr != NULL);
|
assert(addr != NULL);
|
||||||
|
|
||||||
switch (addr->m_addr.sa_family) {
|
switch (addr->m_addr.ss_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
return kINET;
|
return kINET;
|
||||||
|
|
||||||
|
case AF_INET6:
|
||||||
|
return kINET6;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return kUNKNOWN;
|
return kUNKNOWN;
|
||||||
}
|
}
|
||||||
@@ -807,9 +822,14 @@ ArchNetworkWinsock::setAddrPort(ArchNetAddress addr, int port)
|
|||||||
|
|
||||||
switch (getAddrFamily(addr)) {
|
switch (getAddrFamily(addr)) {
|
||||||
case kINET: {
|
case kINET: {
|
||||||
struct sockaddr_in* ipAddr =
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
ipAddr->sin_port = htons_winsock(static_cast<u_short>(port));
|
||||||
ipAddr->sin_port = htons_winsock(port);
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case kINET6: {
|
||||||
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||||
|
ipAddr->sin6_port = htons_winsock(static_cast<u_short>(port));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -826,11 +846,15 @@ ArchNetworkWinsock::getAddrPort(ArchNetAddress addr)
|
|||||||
|
|
||||||
switch (getAddrFamily(addr)) {
|
switch (getAddrFamily(addr)) {
|
||||||
case kINET: {
|
case kINET: {
|
||||||
struct sockaddr_in* ipAddr =
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
|
||||||
return ntohs_winsock(ipAddr->sin_port);
|
return ntohs_winsock(ipAddr->sin_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kINET6: {
|
||||||
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||||
|
return ntohs_winsock(ipAddr->sin6_port);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0 && "unknown address family");
|
assert(0 && "unknown address family");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -844,12 +868,17 @@ ArchNetworkWinsock::isAnyAddr(ArchNetAddress addr)
|
|||||||
|
|
||||||
switch (getAddrFamily(addr)) {
|
switch (getAddrFamily(addr)) {
|
||||||
case kINET: {
|
case kINET: {
|
||||||
struct sockaddr_in* ipAddr =
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
|
||||||
reinterpret_cast<struct sockaddr_in*>(&addr->m_addr);
|
|
||||||
return (addr->m_len == sizeof(struct sockaddr_in) &&
|
return (addr->m_len == sizeof(struct sockaddr_in) &&
|
||||||
ipAddr->sin_addr.s_addr == INADDR_ANY);
|
ipAddr->sin_addr.s_addr == INADDR_ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kINET6: {
|
||||||
|
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||||
|
return (addr->m_len == sizeof(struct sockaddr_in) &&
|
||||||
|
memcmp(&ipAddr->sin6_addr, &in6addr_any, sizeof(in6addr_any))== 0);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0 && "unknown address family");
|
assert(0 && "unknown address family");
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -18,8 +18,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <ws2tcpip.h>
|
||||||
// declare no functions in winsock2
|
// declare no functions in winsock2
|
||||||
|
#ifndef INCL_WINSOCK_API_PROTOTYPES
|
||||||
#define INCL_WINSOCK_API_PROTOTYPES 0
|
#define INCL_WINSOCK_API_PROTOTYPES 0
|
||||||
|
#endif
|
||||||
#define INCL_WINSOCK_API_TYPEDEFS 0
|
#define INCL_WINSOCK_API_TYPEDEFS 0
|
||||||
|
|
||||||
#include "arch/IArchNetwork.h"
|
#include "arch/IArchNetwork.h"
|
||||||
@@ -30,6 +33,8 @@
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
|
|
||||||
#define ARCH_NETWORK ArchNetworkWinsock
|
#define ARCH_NETWORK ArchNetworkWinsock
|
||||||
|
|
||||||
class ArchSocketImpl {
|
class ArchSocketImpl {
|
||||||
@@ -45,8 +50,8 @@ public:
|
|||||||
static ArchNetAddressImpl* alloc(size_t);
|
static ArchNetAddressImpl* alloc(size_t);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int m_len;
|
int m_len;
|
||||||
struct sockaddr m_addr;
|
struct sockaddr_storage m_addr;
|
||||||
};
|
};
|
||||||
#define ADDR_HDR_SIZE offsetof(ArchNetAddressImpl, m_addr)
|
#define ADDR_HDR_SIZE offsetof(ArchNetAddressImpl, m_addr)
|
||||||
#define TYPED_ADDR(type_, addr_) (reinterpret_cast<type_*>(&addr_->m_addr))
|
#define TYPED_ADDR(type_, addr_) (reinterpret_cast<type_*>(&addr_->m_addr))
|
||||||
|
|||||||
@@ -21,9 +21,7 @@
|
|||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
#include "common/Version.h"
|
#include "common/Version.h"
|
||||||
#include "barrier/protocol_types.h"
|
#include "barrier/protocol_types.h"
|
||||||
#include "arch/Arch.h"
|
|
||||||
#include "base/XBase.h"
|
#include "base/XBase.h"
|
||||||
#include "arch/XArch.h"
|
|
||||||
#include "base/log_outputters.h"
|
#include "base/log_outputters.h"
|
||||||
#include "barrier/XBarrier.h"
|
#include "barrier/XBarrier.h"
|
||||||
#include "barrier/ArgsBase.h"
|
#include "barrier/ArgsBase.h"
|
||||||
@@ -32,9 +30,9 @@
|
|||||||
#include "ipc/IpcMessage.h"
|
#include "ipc/IpcMessage.h"
|
||||||
#include "ipc/Ipc.h"
|
#include "ipc/Ipc.h"
|
||||||
#include "base/EventQueue.h"
|
#include "base/EventQueue.h"
|
||||||
|
#include "common/DataDirectories.h"
|
||||||
|
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
#include "arch/win32/ArchMiscWindows.h"
|
|
||||||
#include "base/IEventQueue.h"
|
#include "base/IEventQueue.h"
|
||||||
#include "base/TMethodJob.h"
|
#include "base/TMethodJob.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -81,18 +79,9 @@ App::~App()
|
|||||||
void
|
void
|
||||||
App::version()
|
App::version()
|
||||||
{
|
{
|
||||||
char buffer[500];
|
std::cout << argsBase().m_exename << " " << kVersion << std::endl;
|
||||||
sprintf(
|
std::cout <<"Protocol version " << kProtocolMajorVersion << "." << kProtocolMinorVersion << std::endl;
|
||||||
buffer,
|
std::cout << kCopyright << std::endl;
|
||||||
"%s %s, protocol version %d.%d\n%s",
|
|
||||||
argsBase().m_pname,
|
|
||||||
kVersion,
|
|
||||||
kProtocolMajorVersion,
|
|
||||||
kProtocolMinorVersion,
|
|
||||||
kCopyright
|
|
||||||
);
|
|
||||||
|
|
||||||
std::cout << buffer << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -175,13 +164,12 @@ App::initApp(int argc, const char** argv)
|
|||||||
// parse command line
|
// parse command line
|
||||||
parseArgs(argc, argv);
|
parseArgs(argc, argv);
|
||||||
|
|
||||||
ARCH->setProfileDirectory(argsBase().m_profileDirectory);
|
DataDirectories::profile(argsBase().m_profileDirectory);
|
||||||
ARCH->setPluginDirectory(argsBase().m_pluginDirectory);
|
|
||||||
|
|
||||||
// set log filter
|
// set log filter
|
||||||
if (!CLOG->setFilter(argsBase().m_logFilter)) {
|
if (!CLOG->setFilter(argsBase().m_logFilter)) {
|
||||||
LOG((CLOG_PRINT "%s: unrecognized log level `%s'" BYE,
|
LOG((CLOG_PRINT "%s: unrecognized log level `%s'" BYE,
|
||||||
argsBase().m_pname, argsBase().m_logFilter, argsBase().m_pname));
|
argsBase().m_exename.c_str(), argsBase().m_logFilter, argsBase().m_exename.c_str()));
|
||||||
m_bye(kExitArgs);
|
m_bye(kExitArgs);
|
||||||
}
|
}
|
||||||
loggingFilterWarning();
|
loggingFilterWarning();
|
||||||
|
|||||||
@@ -21,10 +21,10 @@
|
|||||||
#include "barrier/App.h"
|
#include "barrier/App.h"
|
||||||
#include "barrier/ServerArgs.h"
|
#include "barrier/ServerArgs.h"
|
||||||
#include "barrier/ClientArgs.h"
|
#include "barrier/ClientArgs.h"
|
||||||
#include "barrier/ToolArgs.h"
|
|
||||||
#include "barrier/ArgsBase.h"
|
#include "barrier/ArgsBase.h"
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
#include "base/String.h"
|
#include "base/String.h"
|
||||||
|
#include "common/PathUtilities.h"
|
||||||
|
|
||||||
#ifdef WINAPI_MSWINDOWS
|
#ifdef WINAPI_MSWINDOWS
|
||||||
#include <VersionHelpers.h>
|
#include <VersionHelpers.h>
|
||||||
@@ -62,7 +62,7 @@ ArgParser::parseServerArgs(ServerArgs& args, int argc, const char* const* argv)
|
|||||||
args.m_configFile = argv[++i];
|
args.m_configFile = argv[++i];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_pname, argv[i], args.m_pname));
|
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_exename.c_str(), argv[i], args.m_exename.c_str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ ArgParser::parseClientArgs(ClientArgs& args, int argc, const char* const* argv)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_pname, argv[i], args.m_pname));
|
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_exename.c_str(), argv[i], args.m_exename.c_str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ ArgParser::parseClientArgs(ClientArgs& args, int argc, const char* const* argv)
|
|||||||
// exactly one non-option argument (server-address)
|
// exactly one non-option argument (server-address)
|
||||||
if (i == argc) {
|
if (i == argc) {
|
||||||
LOG((CLOG_PRINT "%s: a server address or name is required" BYE,
|
LOG((CLOG_PRINT "%s: a server address or name is required" BYE,
|
||||||
args.m_pname, args.m_pname));
|
args.m_exename.c_str(), args.m_exename.c_str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,46 +171,6 @@ ArgParser::parsePlatformArg(ArgsBase& argsBase, const int& argc, const char* con
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv)
|
|
||||||
{
|
|
||||||
for (int i = 1; i < argc; ++i) {
|
|
||||||
if (isArg(i, argc, argv, NULL, "--get-active-desktop", 0)) {
|
|
||||||
args.m_printActiveDesktopName = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--login-auth", 0)) {
|
|
||||||
args.m_loginAuthenticate = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--get-installed-dir", 0)) {
|
|
||||||
args.m_getInstalledDir = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--get-profile-dir", 0)) {
|
|
||||||
args.m_getProfileDir = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--get-arch", 0)) {
|
|
||||||
args.m_getArch = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--notify-activation", 0)) {
|
|
||||||
args.m_notifyActivation = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--notify-update", 0)) {
|
|
||||||
args.m_notifyUpdate = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ArgParser::parseGenericArgs(int argc, const char* const* argv, int& i)
|
ArgParser::parseGenericArgs(int argc, const char* const* argv, int& i)
|
||||||
{
|
{
|
||||||
@@ -353,7 +313,7 @@ ArgParser::isArg(
|
|||||||
// match. check args left.
|
// match. check args left.
|
||||||
if (argi + minRequiredParameters >= argc) {
|
if (argi + minRequiredParameters >= argc) {
|
||||||
LOG((CLOG_PRINT "%s: missing arguments for `%s'" BYE,
|
LOG((CLOG_PRINT "%s: missing arguments for `%s'" BYE,
|
||||||
argsBase().m_pname, argv[argi], argsBase().m_pname));
|
argsBase().m_exename.c_str(), argv[argi], argsBase().m_exename.c_str()));
|
||||||
argsBase().m_shouldExit = true;
|
argsBase().m_shouldExit = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -496,7 +456,7 @@ void
|
|||||||
ArgParser::updateCommonArgs(const char* const* argv)
|
ArgParser::updateCommonArgs(const char* const* argv)
|
||||||
{
|
{
|
||||||
argsBase().m_name = ARCH->getHostName();
|
argsBase().m_name = ARCH->getHostName();
|
||||||
argsBase().m_pname = ARCH->getBasename(argv[0]);
|
argsBase().m_exename = PathUtilities::basename(argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -510,7 +470,7 @@ ArgParser::checkUnexpectedArgs()
|
|||||||
LOG((CLOG_ERR
|
LOG((CLOG_ERR
|
||||||
"the --daemon argument is not supported on windows. "
|
"the --daemon argument is not supported on windows. "
|
||||||
"instead, install %s as a service (--service install)",
|
"instead, install %s as a service (--service install)",
|
||||||
argsBase().m_pname));
|
argsBase().m_exename.c_str()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
class ServerArgs;
|
class ServerArgs;
|
||||||
class ClientArgs;
|
class ClientArgs;
|
||||||
class ToolArgs;
|
|
||||||
class ArgsBase;
|
class ArgsBase;
|
||||||
class App;
|
class App;
|
||||||
|
|
||||||
@@ -34,7 +33,6 @@ public:
|
|||||||
bool parseServerArgs(ServerArgs& args, int argc, const char* const* argv);
|
bool parseServerArgs(ServerArgs& args, int argc, const char* const* argv);
|
||||||
bool parseClientArgs(ClientArgs& args, int argc, const char* const* argv);
|
bool parseClientArgs(ClientArgs& args, int argc, const char* const* argv);
|
||||||
bool parsePlatformArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i);
|
bool parsePlatformArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i);
|
||||||
bool parseToolArgs(ToolArgs& args, int argc, const char* const* argv);
|
|
||||||
bool parseGenericArgs(int argc, const char* const* argv, int& i);
|
bool parseGenericArgs(int argc, const char* const* argv, int& i);
|
||||||
bool parseDeprecatedArgs(int argc, const char* const* argv, int& i);
|
bool parseDeprecatedArgs(int argc, const char* const* argv, int& i);
|
||||||
void setArgsBase(ArgsBase& argsBase) { m_argsBase = &argsBase; }
|
void setArgsBase(ArgsBase& argsBase) { m_argsBase = &argsBase; }
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ m_disableXInitThreads(false),
|
|||||||
m_backend(false),
|
m_backend(false),
|
||||||
m_restartable(true),
|
m_restartable(true),
|
||||||
m_noHooks(false),
|
m_noHooks(false),
|
||||||
m_pname(NULL),
|
|
||||||
m_logFilter(NULL),
|
m_logFilter(NULL),
|
||||||
m_logFile(NULL),
|
m_logFile(NULL),
|
||||||
m_display(NULL),
|
m_display(NULL),
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public:
|
|||||||
bool m_backend;
|
bool m_backend;
|
||||||
bool m_restartable;
|
bool m_restartable;
|
||||||
bool m_noHooks;
|
bool m_noHooks;
|
||||||
const char* m_pname;
|
std::string m_exename;
|
||||||
const char* m_logFilter;
|
const char* m_logFilter;
|
||||||
const char* m_logFile;
|
const char* m_logFile;
|
||||||
const char* m_display;
|
const char* m_display;
|
||||||
|
|||||||
@@ -40,10 +40,7 @@
|
|||||||
#include "base/TMethodJob.h"
|
#include "base/TMethodJob.h"
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
#include "common/Version.h"
|
#include "common/Version.h"
|
||||||
|
#include "common/PathUtilities.h"
|
||||||
#if SYSAPI_WIN32
|
|
||||||
#include "arch/win32/ArchMiscWindows.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if WINAPI_MSWINDOWS
|
#if WINAPI_MSWINDOWS
|
||||||
#include "platform/MSWindowsScreen.h"
|
#include "platform/MSWindowsScreen.h"
|
||||||
@@ -98,7 +95,7 @@ ClientApp::parseArgs(int argc, const char* const* argv)
|
|||||||
// Priddy.
|
// Priddy.
|
||||||
if (!args().m_restartable || e.getError() == XSocketAddress::kBadPort) {
|
if (!args().m_restartable || e.getError() == XSocketAddress::kBadPort) {
|
||||||
LOG((CLOG_PRINT "%s: %s" BYE,
|
LOG((CLOG_PRINT "%s: %s" BYE,
|
||||||
args().m_pname, e.what(), args().m_pname));
|
args().m_exename.c_str(), e.what(), args().m_exename.c_str()));
|
||||||
m_bye(kExitFailed);
|
m_bye(kExitFailed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,14 +113,14 @@ ClientApp::help()
|
|||||||
" --display <display> connect to the X server at <display>\n" \
|
" --display <display> connect to the X server at <display>\n" \
|
||||||
" --no-xinitthreads do not call XInitThreads()\n"
|
" --no-xinitthreads do not call XInitThreads()\n"
|
||||||
#else
|
#else
|
||||||
# define WINAPI_ARG
|
# define WINAPI_ARG ""
|
||||||
# define WINAPI_INFO
|
# define WINAPI_INFO ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::ostringstream buffer;
|
std::ostringstream buffer;
|
||||||
buffer << "Start the barrier client and connect to a remote server component." << std::endl
|
buffer << "Start the barrier client and connect to a remote server component." << std::endl
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< "Usage: " << args().m_pname << " [--yscroll <delta>]" << WINAPI_ARG << HELP_SYS_ARGS
|
<< "Usage: " << args().m_exename << " [--yscroll <delta>]" << WINAPI_ARG << HELP_SYS_ARGS
|
||||||
<< HELP_COMMON_ARGS << " <server-address>" << std::endl
|
<< HELP_COMMON_ARGS << " <server-address>" << std::endl
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< "Options:" << std::endl
|
<< "Options:" << std::endl
|
||||||
@@ -134,9 +131,10 @@ ClientApp::help()
|
|||||||
<< std::endl
|
<< std::endl
|
||||||
<< "Default options are marked with a *" << std::endl
|
<< "Default options are marked with a *" << std::endl
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< "The server address is of the form: [<hostname>][:<port>]. The hostname" << std::endl
|
<< "The server address is of the form: [<hostname>][:<port>]. The hostname" << std::endl
|
||||||
<< "must be the address or hostname of the server. The port overrides the" << std::endl
|
<< "must be the address or hostname of the server. Placing brackets around" << std::endl
|
||||||
<< "default port, " << kDefaultPort << "." << std::endl;
|
<< "an IPv6 address is required when also specifying a port number and " << std::endl
|
||||||
|
<< "optional otherwise. The default port number is " << kDefaultPort << "." << std::endl;
|
||||||
|
|
||||||
LOG((CLOG_PRINT "%s", buffer.str().c_str()));
|
LOG((CLOG_PRINT "%s", buffer.str().c_str()));
|
||||||
}
|
}
|
||||||
@@ -519,7 +517,7 @@ ClientApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc
|
|||||||
{
|
{
|
||||||
// general initialization
|
// general initialization
|
||||||
m_serverAddress = new NetworkAddress;
|
m_serverAddress = new NetworkAddress;
|
||||||
args().m_pname = ARCH->getBasename(argv[0]);
|
args().m_exename = PathUtilities::basename(argv[0]);
|
||||||
|
|
||||||
// install caller's output filter
|
// install caller's output filter
|
||||||
if (outputter != NULL) {
|
if (outputter != NULL) {
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
#include "base/TMethodEventJob.h"
|
#include "base/TMethodEventJob.h"
|
||||||
#include "common/Version.h"
|
#include "common/Version.h"
|
||||||
|
#include "common/DataDirectories.h"
|
||||||
|
#include "common/PathUtilities.h"
|
||||||
|
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
#include "arch/win32/ArchMiscWindows.h"
|
#include "arch/win32/ArchMiscWindows.h"
|
||||||
@@ -99,7 +101,7 @@ ServerApp::parseArgs(int argc, const char* const* argv)
|
|||||||
}
|
}
|
||||||
catch (XSocketAddress& e) {
|
catch (XSocketAddress& e) {
|
||||||
LOG((CLOG_PRINT "%s: %s" BYE,
|
LOG((CLOG_PRINT "%s: %s" BYE,
|
||||||
args().m_pname, e.what(), args().m_pname));
|
args().m_exename.c_str(), e.what(), args().m_exename.c_str()));
|
||||||
m_bye(kExitArgs);
|
m_bye(kExitArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,14 +119,14 @@ ServerApp::help()
|
|||||||
" --display <display> connect to the X server at <display>\n" \
|
" --display <display> connect to the X server at <display>\n" \
|
||||||
" --no-xinitthreads do not call XInitThreads()\n"
|
" --no-xinitthreads do not call XInitThreads()\n"
|
||||||
#else
|
#else
|
||||||
# define WINAPI_ARGS
|
# define WINAPI_ARGS ""
|
||||||
# define WINAPI_INFO
|
# define WINAPI_INFO ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::ostringstream buffer;
|
std::ostringstream buffer;
|
||||||
buffer << "Start the barrier server component." << std::endl
|
buffer << "Start the barrier server component." << std::endl
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< "Usage: " << args().m_pname
|
<< "Usage: " << args().m_exename
|
||||||
<< " [--address <address>]"
|
<< " [--address <address>]"
|
||||||
<< " [--config <pathname>]"
|
<< " [--config <pathname>]"
|
||||||
<< WINAPI_ARGS << HELP_SYS_ARGS << HELP_COMMON_ARGS << std::endl
|
<< WINAPI_ARGS << HELP_SYS_ARGS << HELP_COMMON_ARGS << std::endl
|
||||||
@@ -137,13 +139,14 @@ ServerApp::help()
|
|||||||
<< std::endl
|
<< std::endl
|
||||||
<< "The argument for --address is of the form: [<hostname>][:<port>]. The" << std::endl
|
<< "The argument for --address is of the form: [<hostname>][:<port>]. The" << std::endl
|
||||||
<< "hostname must be the address or hostname of an interface on the system." << std::endl
|
<< "hostname must be the address or hostname of an interface on the system." << std::endl
|
||||||
<< "The default is to listen on all interfaces. The port overrides the" << std::endl
|
<< "Placing brackets around an IPv6 address is required when also specifying " << std::endl
|
||||||
<< "default port, " << kDefaultPort << "." << std::endl
|
<< "a port number and optional otherwise. The default is to listen on all" << std::endl
|
||||||
|
<< "interfaces using port number " << kDefaultPort << "." << std::endl
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< "If no configuration file pathname is provided then the first of the" << std::endl
|
<< "If no configuration file pathname is provided then the first of the" << std::endl
|
||||||
<< "following to load successfully sets the configuration:" << std::endl
|
<< "following to load successfully sets the configuration:" << std::endl
|
||||||
<< " $HOME/" << USR_CONFIG_NAME << std::endl
|
<< " " << PathUtilities::concat(DataDirectories::profile(), SYS_CONFIG_NAME) << std::endl
|
||||||
<< " " << ARCH->concatPath(ARCH->getSystemDirectory(), SYS_CONFIG_NAME) << std::endl;
|
<< " " << PathUtilities::concat(DataDirectories::systemconfig(), SYS_CONFIG_NAME) << std::endl;
|
||||||
|
|
||||||
LOG((CLOG_PRINT "%s", buffer.str().c_str()));
|
LOG((CLOG_PRINT "%s", buffer.str().c_str()));
|
||||||
}
|
}
|
||||||
@@ -180,11 +183,10 @@ ServerApp::loadConfig()
|
|||||||
|
|
||||||
// load the default configuration if no explicit file given
|
// load the default configuration if no explicit file given
|
||||||
else {
|
else {
|
||||||
// get the user's home directory
|
String path = DataDirectories::profile();
|
||||||
String path = ARCH->getUserDirectory();
|
|
||||||
if (!path.empty()) {
|
if (!path.empty()) {
|
||||||
// complete path
|
// complete path
|
||||||
path = ARCH->concatPath(path, USR_CONFIG_NAME);
|
path = PathUtilities::concat(path, USR_CONFIG_NAME);
|
||||||
|
|
||||||
// now try loading the user's configuration
|
// now try loading the user's configuration
|
||||||
if (loadConfig(path)) {
|
if (loadConfig(path)) {
|
||||||
@@ -194,9 +196,9 @@ ServerApp::loadConfig()
|
|||||||
}
|
}
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
// try the system-wide config file
|
// try the system-wide config file
|
||||||
path = ARCH->getSystemDirectory();
|
path = DataDirectories::systemconfig();
|
||||||
if (!path.empty()) {
|
if (!path.empty()) {
|
||||||
path = ARCH->concatPath(path, SYS_CONFIG_NAME);
|
path = PathUtilities::concat(path, SYS_CONFIG_NAME);
|
||||||
if (loadConfig(path)) {
|
if (loadConfig(path)) {
|
||||||
loaded = true;
|
loaded = true;
|
||||||
args().m_configFile = path;
|
args().m_configFile = path;
|
||||||
@@ -206,7 +208,7 @@ ServerApp::loadConfig()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
LOG((CLOG_PRINT "%s: no configuration available", args().m_pname));
|
LOG((CLOG_PRINT "%s: no configuration available", args().m_exename.c_str()));
|
||||||
m_bye(kExitConfig);
|
m_bye(kExitConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -505,6 +507,16 @@ ServerApp::openServerScreen()
|
|||||||
return screen;
|
return screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* const family_string(IArchNetwork::EAddressFamily family)
|
||||||
|
{
|
||||||
|
if (family == IArchNetwork::kINET)
|
||||||
|
return "IPv4";
|
||||||
|
if (family == IArchNetwork::kINET6)
|
||||||
|
// assume IPv6 sockets are setup to support IPv4 traffic as well
|
||||||
|
return "IPv4/IPv6";
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ServerApp::startServer()
|
ServerApp::startServer()
|
||||||
{
|
{
|
||||||
@@ -530,13 +542,15 @@ ServerApp::startServer()
|
|||||||
double retryTime;
|
double retryTime;
|
||||||
ClientListener* listener = NULL;
|
ClientListener* listener = NULL;
|
||||||
try {
|
try {
|
||||||
listener = openClientListener(args().m_config->getBarrierAddress());
|
auto listenAddress = args().m_config->getBarrierAddress();
|
||||||
|
auto family = family_string(ARCH->getAddrFamily(listenAddress.getAddress()));
|
||||||
|
listener = openClientListener(listenAddress);
|
||||||
m_server = openServer(*args().m_config, m_primaryClient);
|
m_server = openServer(*args().m_config, m_primaryClient);
|
||||||
listener->setServer(m_server);
|
listener->setServer(m_server);
|
||||||
m_server->setListener(listener);
|
m_server->setListener(listener);
|
||||||
m_listener = listener;
|
m_listener = listener;
|
||||||
updateStatus();
|
updateStatus();
|
||||||
LOG((CLOG_NOTE "started server, waiting for clients"));
|
LOG((CLOG_NOTE "started server (%s), waiting for clients", family));
|
||||||
m_serverState = kStarted;
|
m_serverState = kStarted;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -779,7 +793,7 @@ ServerApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc
|
|||||||
// general initialization
|
// general initialization
|
||||||
m_barrierAddress = new NetworkAddress;
|
m_barrierAddress = new NetworkAddress;
|
||||||
args().m_config = new Config(m_events);
|
args().m_config = new Config(m_events);
|
||||||
args().m_pname = ARCH->getBasename(argv[0]);
|
args().m_exename = PathUtilities::basename(argv[0]);
|
||||||
|
|
||||||
// install caller's output filter
|
// install caller's output filter
|
||||||
if (outputter != NULL) {
|
if (outputter != NULL) {
|
||||||
|
|||||||
@@ -1,205 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2014-2016 Symless Ltd.
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "barrier/ToolApp.h"
|
|
||||||
|
|
||||||
#include "barrier/ArgParser.h"
|
|
||||||
#include "arch/Arch.h"
|
|
||||||
#include "base/Log.h"
|
|
||||||
#include "base/String.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#if SYSAPI_WIN32
|
|
||||||
#include "platform/MSWindowsSession.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define JSON_URL "https://symless.com/account/json/"
|
|
||||||
|
|
||||||
enum {
|
|
||||||
kErrorOk,
|
|
||||||
kErrorArgs,
|
|
||||||
kErrorException,
|
|
||||||
kErrorUnknown
|
|
||||||
};
|
|
||||||
|
|
||||||
UInt32
|
|
||||||
ToolApp::run(int argc, char** argv)
|
|
||||||
{
|
|
||||||
if (argc <= 1) {
|
|
||||||
std::cerr << "no args" << std::endl;
|
|
||||||
return kErrorArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
ArgParser argParser(this);
|
|
||||||
bool result = argParser.parseToolArgs(m_args, argc, argv);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
m_bye(kExitArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_args.m_printActiveDesktopName) {
|
|
||||||
#if SYSAPI_WIN32
|
|
||||||
MSWindowsSession session;
|
|
||||||
String name = session.getActiveDesktopName();
|
|
||||||
if (name.empty()) {
|
|
||||||
LOG((CLOG_CRIT "failed to get active desktop name"));
|
|
||||||
return kExitFailed;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
String output = barrier::string::sprintf("activeDesktop:%s", name.c_str());
|
|
||||||
LOG((CLOG_INFO "%s", output.c_str()));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (m_args.m_loginAuthenticate) {
|
|
||||||
loginAuth();
|
|
||||||
}
|
|
||||||
else if (m_args.m_getInstalledDir) {
|
|
||||||
std::cout << ARCH->getInstalledDirectory() << std::endl;
|
|
||||||
}
|
|
||||||
else if (m_args.m_getProfileDir) {
|
|
||||||
std::cout << ARCH->getProfileDirectory() << std::endl;
|
|
||||||
}
|
|
||||||
else if (m_args.m_getArch) {
|
|
||||||
std::cout << ARCH->getPlatformName() << std::endl;
|
|
||||||
}
|
|
||||||
else if (m_args.m_notifyUpdate) {
|
|
||||||
notifyUpdate();
|
|
||||||
}
|
|
||||||
else if (m_args.m_notifyActivation) {
|
|
||||||
notifyActivation();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw XBarrier("Nothing to do");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception& e) {
|
|
||||||
LOG((CLOG_CRIT "An error occurred: %s\n", e.what()));
|
|
||||||
return kExitFailed;
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
LOG((CLOG_CRIT "An unknown error occurred.\n"));
|
|
||||||
return kExitFailed;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if WINAPI_XWINDOWS
|
|
||||||
// HACK: avoid sigsegv on linux
|
|
||||||
m_bye(kErrorOk);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return kErrorOk;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ToolApp::help()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ToolApp::loginAuth()
|
|
||||||
{
|
|
||||||
String credentials;
|
|
||||||
std::cin >> credentials;
|
|
||||||
|
|
||||||
std::vector<String> parts = barrier::string::splitString(credentials, ':');
|
|
||||||
size_t count = parts.size();
|
|
||||||
|
|
||||||
if (count == 2 ) {
|
|
||||||
String email = parts[0];
|
|
||||||
String password = parts[1];
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << JSON_URL << "auth/";
|
|
||||||
ss << "?email=" << ARCH->internet().urlEncode(email);
|
|
||||||
ss << "&password=" << password;
|
|
||||||
|
|
||||||
std::cout << ARCH->internet().get(ss.str()) << std::endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw XBarrier("Invalid credentials.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ToolApp::notifyUpdate()
|
|
||||||
{
|
|
||||||
String data;
|
|
||||||
std::cin >> data;
|
|
||||||
|
|
||||||
std::vector<String> parts = barrier::string::splitString(data, ':');
|
|
||||||
size_t count = parts.size();
|
|
||||||
|
|
||||||
if (count == 3) {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << JSON_URL << "notify/update";
|
|
||||||
ss << "?from=" << parts[0];
|
|
||||||
ss << "&to=" << parts[1];
|
|
||||||
|
|
||||||
std::cout << ARCH->internet().get(ss.str()) << std::endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw XBarrier("Invalid update data.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ToolApp::notifyActivation()
|
|
||||||
{
|
|
||||||
String info;
|
|
||||||
std::cin >> info;
|
|
||||||
|
|
||||||
std::vector<String> parts = barrier::string::splitString(info, ':');
|
|
||||||
size_t count = parts.size();
|
|
||||||
|
|
||||||
if (count == 3 || count == 4) {
|
|
||||||
String action = parts[0];
|
|
||||||
String identity = parts[1];
|
|
||||||
String macHash = parts[2];
|
|
||||||
String os;
|
|
||||||
|
|
||||||
if (count == 4) {
|
|
||||||
os = parts[3];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
os = ARCH->getOSName();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << JSON_URL << "notify/";
|
|
||||||
ss << "?action=" << action;
|
|
||||||
ss << "&identity=" << ARCH->internet().urlEncode(identity);
|
|
||||||
ss << "&mac=" << ARCH->internet().urlEncode(macHash);
|
|
||||||
ss << "&os=" << ARCH->internet().urlEncode(ARCH->getOSName());
|
|
||||||
ss << "&arch=" << ARCH->internet().urlEncode(ARCH->getPlatformName());
|
|
||||||
|
|
||||||
try {
|
|
||||||
std::cout << ARCH->internet().get(ss.str()) << std::endl;
|
|
||||||
}
|
|
||||||
catch (std::exception& e) {
|
|
||||||
LOG((CLOG_NOTE "An error occurred during notification: %s\n", e.what()));
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
LOG((CLOG_NOTE "An unknown error occurred during notification.\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG((CLOG_NOTE "notification failed"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2014-2016 Symless Ltd.
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "barrier/App.h"
|
|
||||||
#include "barrier/ToolArgs.h"
|
|
||||||
#include "common/basic_types.h"
|
|
||||||
|
|
||||||
class ToolApp : public MinimalApp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UInt32 run(int argc, char** argv);
|
|
||||||
void help();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void loginAuth();
|
|
||||||
void notifyActivation();
|
|
||||||
void notifyUpdate();
|
|
||||||
|
|
||||||
private:
|
|
||||||
ToolArgs m_args;
|
|
||||||
};
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2014-2016 Symless Ltd.
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "barrier/ToolArgs.h"
|
|
||||||
|
|
||||||
ToolArgs::ToolArgs() :
|
|
||||||
m_printActiveDesktopName(false),
|
|
||||||
m_loginAuthenticate(false),
|
|
||||||
m_getInstalledDir(false),
|
|
||||||
m_getProfileDir(false),
|
|
||||||
m_getArch(false),
|
|
||||||
m_notifyActivation(false),
|
|
||||||
m_notifyUpdate(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* barrier -- mouse and keyboard sharing utility
|
|
||||||
* Copyright (C) 2014-2016 Symless Ltd.
|
|
||||||
*
|
|
||||||
* This package is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* found in the file LICENSE that should have accompanied this file.
|
|
||||||
*
|
|
||||||
* This package is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "base/String.h"
|
|
||||||
|
|
||||||
class ToolArgs {
|
|
||||||
public:
|
|
||||||
ToolArgs();
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool m_printActiveDesktopName;
|
|
||||||
bool m_loginAuthenticate;
|
|
||||||
bool m_getInstalledDir;
|
|
||||||
bool m_getProfileDir;
|
|
||||||
bool m_getArch;
|
|
||||||
bool m_notifyActivation;
|
|
||||||
bool m_notifyUpdate;
|
|
||||||
};
|
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "base/EventQueue.h"
|
#include "base/EventQueue.h"
|
||||||
#include "base/log_outputters.h"
|
#include "base/log_outputters.h"
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
|
#include "common/DataDirectories.h"
|
||||||
|
|
||||||
#include "arch/win32/ArchMiscWindows.h"
|
#include "arch/win32/ArchMiscWindows.h"
|
||||||
#include "arch/win32/XArchWindows.h"
|
#include "arch/win32/XArchWindows.h"
|
||||||
@@ -41,6 +42,7 @@
|
|||||||
#include "platform/MSWindowsDebugOutputter.h"
|
#include "platform/MSWindowsDebugOutputter.h"
|
||||||
#include "platform/MSWindowsWatchdog.h"
|
#include "platform/MSWindowsWatchdog.h"
|
||||||
#include "platform/MSWindowsEventQueueBuffer.h"
|
#include "platform/MSWindowsEventQueueBuffer.h"
|
||||||
|
#include "platform/MSWindowsUtil.h"
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
@@ -130,8 +132,10 @@ DaemonApp::run(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (foreground) {
|
if (foreground) {
|
||||||
// run process in foreground instead of daemonizing.
|
// add a console to catch Ctrl+C and run process in foreground
|
||||||
// useful for debugging.
|
// instead of daemonizing. useful for debugging.
|
||||||
|
if (IsDebuggerPresent())
|
||||||
|
AllocConsole();
|
||||||
mainLoop(false);
|
mainLoop(false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -239,14 +243,10 @@ DaemonApp::foregroundError(const char* message)
|
|||||||
std::string
|
std::string
|
||||||
DaemonApp::logFilename()
|
DaemonApp::logFilename()
|
||||||
{
|
{
|
||||||
string logFilename;
|
string logFilename = ARCH->setting("LogFilename");
|
||||||
logFilename = ARCH->setting("LogFilename");
|
if (logFilename.empty())
|
||||||
if (logFilename.empty()) {
|
logFilename = DataDirectories::global() + "\\" + LOG_FILENAME;
|
||||||
logFilename = ARCH->getLogDirectory();
|
MSWindowsUtil::createDirectory(logFilename, true);
|
||||||
logFilename.append("/");
|
|
||||||
logFilename.append(LOG_FILENAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
return logFilename;
|
return logFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -147,7 +147,9 @@ Client::connect()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create the socket
|
// create the socket
|
||||||
IDataSocket* socket = m_socketFactory->create(m_useSecureNetwork);
|
IDataSocket* socket = m_socketFactory->create(
|
||||||
|
ARCH->getAddrFamily(m_serverAddress.getAddress()),
|
||||||
|
m_useSecureNetwork);
|
||||||
m_socket = dynamic_cast<TCPSocket*>(socket);
|
m_socket = dynamic_cast<TCPSocket*>(socket);
|
||||||
|
|
||||||
// filter socket messages, including a packetizing filter
|
// filter socket messages, including a packetizing filter
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ ServerProxy::~ServerProxy()
|
|||||||
setKeepAliveRate(-1.0);
|
setKeepAliveRate(-1.0);
|
||||||
m_events->removeHandler(m_events->forIStream().inputReady(),
|
m_events->removeHandler(m_events->forIStream().inputReady(),
|
||||||
m_stream->getEventTarget());
|
m_stream->getEventTarget());
|
||||||
|
m_events->removeHandler(m_events->forClipboard().clipboardSending(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -17,8 +17,24 @@
|
|||||||
file(GLOB headers "*.h")
|
file(GLOB headers "*.h")
|
||||||
file(GLOB sources "*.cpp")
|
file(GLOB sources "*.cpp")
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
file(GLOB arch_headers "win32/*.h")
|
||||||
|
file(GLOB arch_sources "win32/*.cpp")
|
||||||
|
elseif (UNIX)
|
||||||
|
file(GLOB arch_headers "unix/*.h")
|
||||||
|
file(GLOB arch_sources "unix/*.cpp")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(APPEND headers ${arch_headers})
|
||||||
|
list(APPEND sources ${arch_sources})
|
||||||
|
|
||||||
if (BARRIER_ADD_HEADERS)
|
if (BARRIER_ADD_HEADERS)
|
||||||
list(APPEND sources ${headers})
|
list(APPEND sources ${headers})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(common STATIC ${sources})
|
add_library(common STATIC ${sources})
|
||||||
|
|
||||||
|
if (HAVE_GETPWUID_R)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_GETPWUID_R=1")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|||||||
41
src/lib/common/DataDirectories.h
Normal file
41
src/lib/common/DataDirectories.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* barrier -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2018 Debauchee Open Source Group
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class DataDirectories
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const std::string& profile();
|
||||||
|
static const std::string& profile(const std::string& path);
|
||||||
|
|
||||||
|
static const std::string& global();
|
||||||
|
static const std::string& global(const std::string& path);
|
||||||
|
|
||||||
|
static const std::string& systemconfig();
|
||||||
|
static const std::string& systemconfig(const std::string& path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// static class
|
||||||
|
DataDirectories() {}
|
||||||
|
|
||||||
|
static std::string _profile;
|
||||||
|
static std::string _global;
|
||||||
|
static std::string _systemconfig;
|
||||||
|
};
|
||||||
23
src/lib/common/DataDirectories_static.cpp
Normal file
23
src/lib/common/DataDirectories_static.cpp
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* barrier -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2018 Debauchee Open Source Group
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "DataDirectories.h"
|
||||||
|
|
||||||
|
// static member
|
||||||
|
std::string DataDirectories::_profile;
|
||||||
|
std::string DataDirectories::_global;
|
||||||
|
std::string DataDirectories::_systemconfig;
|
||||||
75
src/lib/common/PathUtilities.cpp
Normal file
75
src/lib/common/PathUtilities.cpp
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* barrier -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2018 Debauchee Open Source Group
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
These functions cover the vast majority of cases for different paths across
|
||||||
|
windows and unixes. They are not, however, fullproof and probably don't cover
|
||||||
|
fringe cases very well. The library below might be used as an alternative if
|
||||||
|
these implementations prove to be insufficient. As the library's readme states
|
||||||
|
it is simply a temporary band-aid until std::filesystem is integrated (C++17
|
||||||
|
has it in std::experimental) and this class should also be treated as such.
|
||||||
|
|
||||||
|
https://github.com/wjakob/filesystem/
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PathUtilities.h"
|
||||||
|
|
||||||
|
// keep the default platform delimiter as the first in the list
|
||||||
|
#ifdef _WIN32
|
||||||
|
static const char *Delimiters = "\\/";
|
||||||
|
#else
|
||||||
|
static const char *Delimiters = "/";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const char DefaultDelimiter = Delimiters[0];
|
||||||
|
|
||||||
|
std::string PathUtilities::basename(const std::string& path)
|
||||||
|
{
|
||||||
|
return path.substr(path.find_last_of(Delimiters) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PathUtilities::concat(const std::string& left, const std::string& right)
|
||||||
|
{
|
||||||
|
// although npos is usually (-1) we can't count on that so handle it explicitly
|
||||||
|
auto leftEnd = left.find_last_not_of(Delimiters);
|
||||||
|
if (leftEnd == std::string::npos)
|
||||||
|
leftEnd = 0;
|
||||||
|
else
|
||||||
|
++leftEnd;
|
||||||
|
auto rightStart = right.find_first_not_of(Delimiters, 0);
|
||||||
|
if (rightStart == std::string::npos) {
|
||||||
|
// both left/right are empty
|
||||||
|
if (left.size() == 0 && right.size() == 0)
|
||||||
|
return "";
|
||||||
|
// right is full of delims, left is okay
|
||||||
|
if (leftEnd > 0)
|
||||||
|
return left.substr(0, leftEnd);
|
||||||
|
// both left/right useless but at least one has delims
|
||||||
|
return std::string(1, DefaultDelimiter);
|
||||||
|
}
|
||||||
|
if (leftEnd == 0) {
|
||||||
|
// right is okay and not prefixed with delims, left is empty
|
||||||
|
if (left.size() == 0 && rightStart == 0)
|
||||||
|
return right.substr(rightStart);
|
||||||
|
// (right is okay and prefixed with delims) OR left is full of delims
|
||||||
|
return DefaultDelimiter + right.substr(rightStart);
|
||||||
|
}
|
||||||
|
// concatenation using both left and right
|
||||||
|
return left.substr(0, leftEnd) + DefaultDelimiter + right.substr(rightStart);
|
||||||
|
}
|
||||||
31
src/lib/common/PathUtilities.h
Normal file
31
src/lib/common/PathUtilities.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* barrier -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2018 Debauchee Open Source Group
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class PathUtilities
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::string basename(const std::string& path);
|
||||||
|
static std::string concat(const std::string& left, const std::string& right);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// static class
|
||||||
|
PathUtilities() {}
|
||||||
|
};
|
||||||
114
src/lib/common/unix/DataDirectories.cpp
Normal file
114
src/lib/common/unix/DataDirectories.cpp
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* barrier -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2018 Debauchee Open Source Group
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../DataDirectories.h"
|
||||||
|
|
||||||
|
#include <unistd.h> // sysconf
|
||||||
|
#include <stdlib.h> // getenv
|
||||||
|
#include <sys/types.h> // getpwuid(_r)
|
||||||
|
#include <pwd.h> // getpwuid(_r)
|
||||||
|
|
||||||
|
const std::string ProfileSubdir = "/barrier";
|
||||||
|
|
||||||
|
static std::string pw_dir(struct passwd* pwentp)
|
||||||
|
{
|
||||||
|
if (pwentp != NULL && pwentp->pw_dir != NULL)
|
||||||
|
return pwentp->pw_dir;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_GETPWUID_R
|
||||||
|
|
||||||
|
static std::string unix_home()
|
||||||
|
{
|
||||||
|
long size = -1;
|
||||||
|
#if defined(_SC_GETPW_R_SIZE_MAX)
|
||||||
|
size = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||||
|
#endif
|
||||||
|
if (size == -1)
|
||||||
|
size = BUFSIZ;
|
||||||
|
|
||||||
|
struct passwd pwent;
|
||||||
|
struct passwd* pwentp;
|
||||||
|
std::string buffer(size, 0);
|
||||||
|
getpwuid_r(getuid(), &pwent, &buffer[0], size, &pwentp);
|
||||||
|
return pw_dir(pwentp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // not HAVE_GETPWUID_R
|
||||||
|
|
||||||
|
static std::string unix_home()
|
||||||
|
{
|
||||||
|
return pw_dir(getpwuid(getuid()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAVE_GETPWUID_R
|
||||||
|
|
||||||
|
static std::string profile_basedir()
|
||||||
|
{
|
||||||
|
#ifdef WINAPI_XWINDOWS
|
||||||
|
// linux/bsd adheres to freedesktop standards
|
||||||
|
// https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
||||||
|
const char* dir = getenv("XDG_DATA_HOME");
|
||||||
|
if (dir != NULL)
|
||||||
|
return dir;
|
||||||
|
return unix_home() + "/.local/share";
|
||||||
|
#else
|
||||||
|
// macos has its own standards
|
||||||
|
// https://developer.apple.com/library/content/documentation/General/Conceptual/MOSXAppProgrammingGuide/AppRuntime/AppRuntime.html
|
||||||
|
return unix_home() + "/Library/Application Support";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& DataDirectories::profile()
|
||||||
|
{
|
||||||
|
if (_profile.empty())
|
||||||
|
_profile = profile_basedir() + ProfileSubdir;
|
||||||
|
return _profile;
|
||||||
|
}
|
||||||
|
const std::string& DataDirectories::profile(const std::string& path)
|
||||||
|
{
|
||||||
|
_profile = path;
|
||||||
|
return _profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& DataDirectories::global()
|
||||||
|
{
|
||||||
|
if (_global.empty())
|
||||||
|
// TODO: where on a unix system should public/global shared data go?
|
||||||
|
// as of march 2018 global() is not used for unix
|
||||||
|
_global = "/tmp";
|
||||||
|
return _global;
|
||||||
|
}
|
||||||
|
const std::string& DataDirectories::global(const std::string& path)
|
||||||
|
{
|
||||||
|
_global = path;
|
||||||
|
return _global;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& DataDirectories::systemconfig()
|
||||||
|
{
|
||||||
|
if (_systemconfig.empty())
|
||||||
|
_systemconfig = "/etc";
|
||||||
|
return _systemconfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& DataDirectories::systemconfig(const std::string& path)
|
||||||
|
{
|
||||||
|
_systemconfig = path;
|
||||||
|
return _systemconfig;
|
||||||
|
}
|
||||||
81
src/lib/common/win32/DataDirectories.cpp
Normal file
81
src/lib/common/win32/DataDirectories.cpp
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* barrier -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2018 Debauchee Open Source Group
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../DataDirectories.h"
|
||||||
|
|
||||||
|
#include <Shlobj.h>
|
||||||
|
|
||||||
|
std::string unicode_to_mb(const WCHAR* utfStr)
|
||||||
|
{
|
||||||
|
int utfLength = lstrlenW(utfStr);
|
||||||
|
int mbLength = WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, NULL, 0, NULL, NULL);
|
||||||
|
std::string mbStr(mbLength, 0);
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, &mbStr[0], mbLength, NULL, NULL);
|
||||||
|
return mbStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string known_folder_path(const KNOWNFOLDERID& id)
|
||||||
|
{
|
||||||
|
std::string path;
|
||||||
|
WCHAR* buffer;
|
||||||
|
HRESULT result = SHGetKnownFolderPath(id, 0, NULL, &buffer);
|
||||||
|
if (result == S_OK) {
|
||||||
|
path = unicode_to_mb(buffer);
|
||||||
|
CoTaskMemFree(buffer);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& DataDirectories::profile()
|
||||||
|
{
|
||||||
|
if (_profile.empty())
|
||||||
|
_profile = known_folder_path(FOLDERID_LocalAppData) + "\\Barrier";
|
||||||
|
return _profile;
|
||||||
|
}
|
||||||
|
const std::string& DataDirectories::profile(const std::string& path)
|
||||||
|
{
|
||||||
|
_profile = path;
|
||||||
|
return _profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& DataDirectories::global()
|
||||||
|
{
|
||||||
|
if (_global.empty())
|
||||||
|
_global = known_folder_path(FOLDERID_ProgramData) + "\\Barrier";
|
||||||
|
return _global;
|
||||||
|
}
|
||||||
|
const std::string& DataDirectories::global(const std::string& path)
|
||||||
|
{
|
||||||
|
_global = path;
|
||||||
|
return _global;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& DataDirectories::systemconfig()
|
||||||
|
{
|
||||||
|
// systemconfig() is a special case in that it will track the current value
|
||||||
|
// of global() unless and until it is explictly set otherwise
|
||||||
|
// previously it would default to the windows folder which was horrible!
|
||||||
|
if (_systemconfig.empty())
|
||||||
|
return global();
|
||||||
|
return _systemconfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& DataDirectories::systemconfig(const std::string& path)
|
||||||
|
{
|
||||||
|
_systemconfig = path;
|
||||||
|
return _systemconfig;
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
IpcClient::IpcClient(IEventQueue* events, SocketMultiplexer* socketMultiplexer) :
|
IpcClient::IpcClient(IEventQueue* events, SocketMultiplexer* socketMultiplexer) :
|
||||||
m_serverAddress(NetworkAddress(IPC_HOST, IPC_PORT)),
|
m_serverAddress(NetworkAddress(IPC_HOST, IPC_PORT)),
|
||||||
m_socket(events, socketMultiplexer),
|
m_socket(events, socketMultiplexer, IArchNetwork::kINET),
|
||||||
m_server(nullptr),
|
m_server(nullptr),
|
||||||
m_events(events)
|
m_events(events)
|
||||||
{
|
{
|
||||||
@@ -37,7 +37,7 @@ IpcClient::IpcClient(IEventQueue* events, SocketMultiplexer* socketMultiplexer)
|
|||||||
|
|
||||||
IpcClient::IpcClient(IEventQueue* events, SocketMultiplexer* socketMultiplexer, int port) :
|
IpcClient::IpcClient(IEventQueue* events, SocketMultiplexer* socketMultiplexer, int port) :
|
||||||
m_serverAddress(NetworkAddress(IPC_HOST, port)),
|
m_serverAddress(NetworkAddress(IPC_HOST, port)),
|
||||||
m_socket(events, socketMultiplexer),
|
m_socket(events, socketMultiplexer, IArchNetwork::kINET),
|
||||||
m_server(nullptr),
|
m_server(nullptr),
|
||||||
m_events(events)
|
m_events(events)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ IpcServer::IpcServer(IEventQueue* events, SocketMultiplexer* socketMultiplexer,
|
|||||||
void
|
void
|
||||||
IpcServer::init()
|
IpcServer::init()
|
||||||
{
|
{
|
||||||
m_socket = new TCPListenSocket(m_events, m_socketMultiplexer);
|
m_socket = new TCPListenSocket(m_events, m_socketMultiplexer, IArchNetwork::kINET);
|
||||||
|
|
||||||
m_clientsMutex = ARCH->newMutex();
|
m_clientsMutex = ARCH->newMutex();
|
||||||
m_address.resolve();
|
m_address.resolve();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/IInterface.h"
|
#include "common/IInterface.h"
|
||||||
|
#include "arch/IArchNetwork.h"
|
||||||
|
|
||||||
class IDataSocket;
|
class IDataSocket;
|
||||||
class IListenSocket;
|
class IListenSocket;
|
||||||
@@ -34,10 +35,14 @@ public:
|
|||||||
//@{
|
//@{
|
||||||
|
|
||||||
//! Create data socket
|
//! Create data socket
|
||||||
virtual IDataSocket* create(bool secure) const = 0;
|
virtual IDataSocket* create(
|
||||||
|
IArchNetwork::EAddressFamily family,
|
||||||
|
bool secure) const = 0;
|
||||||
|
|
||||||
//! Create listen socket
|
//! Create listen socket
|
||||||
virtual IListenSocket* createListen(bool secure) const = 0;
|
virtual IListenSocket* createListen(
|
||||||
|
IArchNetwork::EAddressFamily family,
|
||||||
|
bool secure) const = 0;
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,6 +28,45 @@
|
|||||||
// NetworkAddress
|
// NetworkAddress
|
||||||
//
|
//
|
||||||
|
|
||||||
|
static bool parse_address(const std::string& address, std::string& host, int& port)
|
||||||
|
{
|
||||||
|
/* Three cases ---
|
||||||
|
* brackets: parse inside for host, check end for port as :INTEGER. DONE
|
||||||
|
* one colon: ipv4 address with port. DONE
|
||||||
|
* otherwise: all host, no port. DONE
|
||||||
|
*
|
||||||
|
* very, very little error checking. depends on address being trimmed before call.
|
||||||
|
*
|
||||||
|
* does not override port with a default value if no port was found in address.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (address[0] == '[') {
|
||||||
|
// bracketed host possibly followed by port as :INTEGER
|
||||||
|
auto endBracket = address.find(']', 1);
|
||||||
|
if (endBracket == std::string::npos)
|
||||||
|
return false;
|
||||||
|
host = address.substr(1, endBracket - 1);
|
||||||
|
if (endBracket + 1 < address.length()) {
|
||||||
|
// port follows (or garbage)
|
||||||
|
if (address[endBracket + 1] != ':')
|
||||||
|
return false;
|
||||||
|
port = std::strtol(&address[endBracket + 2], nullptr, 10);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto colon = address.find(':');
|
||||||
|
if (colon != std::string::npos && address.find(':', colon + 1) == std::string::npos) {
|
||||||
|
// one single colon, must be ipv4 with port
|
||||||
|
host = address.substr(0, colon);
|
||||||
|
port = std::strtol(&address[colon + 1], nullptr, 10);
|
||||||
|
} else {
|
||||||
|
// no colons (ipv4) or more than one colon (ipv6), both without port
|
||||||
|
host = address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// name re-resolution adapted from a patch by Brent Priddy.
|
// name re-resolution adapted from a patch by Brent Priddy.
|
||||||
|
|
||||||
NetworkAddress::NetworkAddress() :
|
NetworkAddress::NetworkAddress() :
|
||||||
@@ -62,50 +101,9 @@ NetworkAddress::NetworkAddress(const String& hostname, int port) :
|
|||||||
m_hostname(hostname),
|
m_hostname(hostname),
|
||||||
m_port(port)
|
m_port(port)
|
||||||
{
|
{
|
||||||
// check for port suffix
|
if (!parse_address(hostname, m_hostname, m_port))
|
||||||
String::size_type i = m_hostname.rfind(':');
|
throw XSocketAddress(XSocketAddress::kUnknown,
|
||||||
if (i != String::npos && i + 1 < m_hostname.size()) {
|
m_hostname, m_port);
|
||||||
// found a colon. see if it looks like an IPv6 address.
|
|
||||||
bool colonNotation = false;
|
|
||||||
bool dotNotation = false;
|
|
||||||
bool doubleColon = false;
|
|
||||||
for (String::size_type j = 0; j < i; ++j) {
|
|
||||||
if (m_hostname[j] == ':') {
|
|
||||||
colonNotation = true;
|
|
||||||
dotNotation = false;
|
|
||||||
if (m_hostname[j + 1] == ':') {
|
|
||||||
doubleColon = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (m_hostname[j] == '.' && colonNotation) {
|
|
||||||
dotNotation = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// port suffix is ambiguous with IPv6 notation if there's
|
|
||||||
// a double colon and the end of the address is not in dot
|
|
||||||
// notation. in that case we assume it's not a port suffix.
|
|
||||||
// the user can replace the double colon with zeros to
|
|
||||||
// disambiguate.
|
|
||||||
if ((!doubleColon || dotNotation) || !colonNotation) {
|
|
||||||
// parse port from hostname
|
|
||||||
char* end;
|
|
||||||
const char* chostname = m_hostname.c_str();
|
|
||||||
long suffixPort = strtol(chostname + i + 1, &end, 10);
|
|
||||||
if (end == chostname + i + 1 || *end != '\0') {
|
|
||||||
throw XSocketAddress(XSocketAddress::kBadPort,
|
|
||||||
m_hostname, m_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
// trim port from hostname
|
|
||||||
m_hostname.erase(i);
|
|
||||||
|
|
||||||
// save port
|
|
||||||
m_port = static_cast<int>(suffixPort);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check port number
|
|
||||||
checkPort();
|
checkPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +143,7 @@ NetworkAddress::resolve()
|
|||||||
// if hostname is empty then use wildcard address otherwise look
|
// if hostname is empty then use wildcard address otherwise look
|
||||||
// up the name.
|
// up the name.
|
||||||
if (m_hostname.empty()) {
|
if (m_hostname.empty()) {
|
||||||
m_address = ARCH->newAnyAddr(IArchNetwork::kINET);
|
m_address = ARCH->newAnyAddr(IArchNetwork::kINET6);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_address = ARCH->nameToAddr(m_hostname);
|
m_address = ARCH->nameToAddr(m_hostname);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "net/SocketMultiplexer.h"
|
#include "net/SocketMultiplexer.h"
|
||||||
#include "net/TSocketMultiplexerMethodJob.h"
|
#include "net/TSocketMultiplexerMethodJob.h"
|
||||||
#include "arch/XArch.h"
|
#include "arch/XArch.h"
|
||||||
|
#include "common/DataDirectories.h"
|
||||||
|
|
||||||
static const char s_certificateDir[] = { "SSL" };
|
static const char s_certificateDir[] = { "SSL" };
|
||||||
static const char s_certificateFilename[] = { "Barrier.pem" };
|
static const char s_certificateFilename[] = { "Barrier.pem" };
|
||||||
@@ -32,8 +33,9 @@ static const char s_certificateFilename[] = { "Barrier.pem" };
|
|||||||
|
|
||||||
SecureListenSocket::SecureListenSocket(
|
SecureListenSocket::SecureListenSocket(
|
||||||
IEventQueue* events,
|
IEventQueue* events,
|
||||||
SocketMultiplexer* socketMultiplexer) :
|
SocketMultiplexer* socketMultiplexer,
|
||||||
TCPListenSocket(events, socketMultiplexer)
|
IArchNetwork::EAddressFamily family) :
|
||||||
|
TCPListenSocket(events, socketMultiplexer, family)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +55,7 @@ SecureListenSocket::accept()
|
|||||||
}
|
}
|
||||||
|
|
||||||
String certificateFilename = barrier::string::sprintf("%s/%s/%s",
|
String certificateFilename = barrier::string::sprintf("%s/%s/%s",
|
||||||
ARCH->getProfileDirectory().c_str(),
|
DataDirectories::profile().c_str(),
|
||||||
s_certificateDir,
|
s_certificateDir,
|
||||||
s_certificateFilename);
|
s_certificateFilename);
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ class IDataSocket;
|
|||||||
class SecureListenSocket : public TCPListenSocket{
|
class SecureListenSocket : public TCPListenSocket{
|
||||||
public:
|
public:
|
||||||
SecureListenSocket(IEventQueue* events,
|
SecureListenSocket(IEventQueue* events,
|
||||||
SocketMultiplexer* socketMultiplexer);
|
SocketMultiplexer* socketMultiplexer,
|
||||||
|
IArchNetwork::EAddressFamily family);
|
||||||
|
|
||||||
// IListenSocket overrides
|
// IListenSocket overrides
|
||||||
virtual IDataSocket*
|
virtual IDataSocket*
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "mt/Lock.h"
|
#include "mt/Lock.h"
|
||||||
#include "arch/XArch.h"
|
#include "arch/XArch.h"
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
|
#include "common/DataDirectories.h"
|
||||||
|
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
@@ -56,8 +57,9 @@ struct Ssl {
|
|||||||
|
|
||||||
SecureSocket::SecureSocket(
|
SecureSocket::SecureSocket(
|
||||||
IEventQueue* events,
|
IEventQueue* events,
|
||||||
SocketMultiplexer* socketMultiplexer) :
|
SocketMultiplexer* socketMultiplexer,
|
||||||
TCPSocket(events, socketMultiplexer),
|
IArchNetwork::EAddressFamily family) :
|
||||||
|
TCPSocket(events, socketMultiplexer, family),
|
||||||
m_ssl(nullptr),
|
m_ssl(nullptr),
|
||||||
m_secureReady(false),
|
m_secureReady(false),
|
||||||
m_fatal(false)
|
m_fatal(false)
|
||||||
@@ -698,7 +700,7 @@ SecureSocket::verifyCertFingerprint()
|
|||||||
String trustedServersFilename;
|
String trustedServersFilename;
|
||||||
trustedServersFilename = barrier::string::sprintf(
|
trustedServersFilename = barrier::string::sprintf(
|
||||||
"%s/%s/%s",
|
"%s/%s/%s",
|
||||||
ARCH->getProfileDirectory().c_str(),
|
DataDirectories::profile().c_str(),
|
||||||
kFingerprintDirName,
|
kFingerprintDirName,
|
||||||
kFingerprintTrustedServersFilename);
|
kFingerprintTrustedServersFilename);
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ A secure socket using SSL.
|
|||||||
*/
|
*/
|
||||||
class SecureSocket : public TCPSocket {
|
class SecureSocket : public TCPSocket {
|
||||||
public:
|
public:
|
||||||
SecureSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer);
|
SecureSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family);
|
||||||
SecureSocket(IEventQueue* events,
|
SecureSocket(IEventQueue* events,
|
||||||
SocketMultiplexer* socketMultiplexer,
|
SocketMultiplexer* socketMultiplexer,
|
||||||
ArchSocket socket);
|
ArchSocket socket);
|
||||||
|
|||||||
@@ -34,13 +34,13 @@
|
|||||||
// TCPListenSocket
|
// TCPListenSocket
|
||||||
//
|
//
|
||||||
|
|
||||||
TCPListenSocket::TCPListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer) :
|
TCPListenSocket::TCPListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family) :
|
||||||
m_events(events),
|
m_events(events),
|
||||||
m_socketMultiplexer(socketMultiplexer)
|
m_socketMultiplexer(socketMultiplexer)
|
||||||
{
|
{
|
||||||
m_mutex = new Mutex;
|
m_mutex = new Mutex;
|
||||||
try {
|
try {
|
||||||
m_socket = ARCH->newSocket(IArchNetwork::kINET, IArchNetwork::kSTREAM);
|
m_socket = ARCH->newSocket(family, IArchNetwork::kSTREAM);
|
||||||
}
|
}
|
||||||
catch (XArchNetwork& e) {
|
catch (XArchNetwork& e) {
|
||||||
throw XSocketCreate(e.what());
|
throw XSocketCreate(e.what());
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ A listen socket using TCP.
|
|||||||
*/
|
*/
|
||||||
class TCPListenSocket : public IListenSocket {
|
class TCPListenSocket : public IListenSocket {
|
||||||
public:
|
public:
|
||||||
TCPListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer);
|
TCPListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family);
|
||||||
virtual ~TCPListenSocket();
|
virtual ~TCPListenSocket();
|
||||||
|
|
||||||
// ISocket overrides
|
// ISocket overrides
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
// TCPSocket
|
// TCPSocket
|
||||||
//
|
//
|
||||||
|
|
||||||
TCPSocket::TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer) :
|
TCPSocket::TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family) :
|
||||||
IDataSocket(events),
|
IDataSocket(events),
|
||||||
m_events(events),
|
m_events(events),
|
||||||
m_mutex(),
|
m_mutex(),
|
||||||
@@ -45,7 +45,7 @@ TCPSocket::TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer)
|
|||||||
m_socketMultiplexer(socketMultiplexer)
|
m_socketMultiplexer(socketMultiplexer)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
m_socket = ARCH->newSocket(IArchNetwork::kINET, IArchNetwork::kSTREAM);
|
m_socket = ARCH->newSocket(family, IArchNetwork::kSTREAM);
|
||||||
}
|
}
|
||||||
catch (XArchNetwork& e) {
|
catch (XArchNetwork& e) {
|
||||||
throw XSocketCreate(e.what());
|
throw XSocketCreate(e.what());
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ A data socket using TCP.
|
|||||||
*/
|
*/
|
||||||
class TCPSocket : public IDataSocket {
|
class TCPSocket : public IDataSocket {
|
||||||
public:
|
public:
|
||||||
TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer);
|
TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family);
|
||||||
TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, ArchSocket socket);
|
TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, ArchSocket socket);
|
||||||
virtual ~TCPSocket();
|
virtual ~TCPSocket();
|
||||||
|
|
||||||
|
|||||||
@@ -41,27 +41,27 @@ TCPSocketFactory::~TCPSocketFactory()
|
|||||||
}
|
}
|
||||||
|
|
||||||
IDataSocket*
|
IDataSocket*
|
||||||
TCPSocketFactory::create(bool secure) const
|
TCPSocketFactory::create(IArchNetwork::EAddressFamily family, bool secure) const
|
||||||
{
|
{
|
||||||
if (secure) {
|
if (secure) {
|
||||||
SecureSocket* secureSocket = new SecureSocket(m_events, m_socketMultiplexer);
|
SecureSocket* secureSocket = new SecureSocket(m_events, m_socketMultiplexer, family);
|
||||||
secureSocket->initSsl (false);
|
secureSocket->initSsl (false);
|
||||||
return secureSocket;
|
return secureSocket;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return new TCPSocket(m_events, m_socketMultiplexer);
|
return new TCPSocket(m_events, m_socketMultiplexer, family);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IListenSocket*
|
IListenSocket*
|
||||||
TCPSocketFactory::createListen(bool secure) const
|
TCPSocketFactory::createListen(IArchNetwork::EAddressFamily family, bool secure) const
|
||||||
{
|
{
|
||||||
IListenSocket* socket = NULL;
|
IListenSocket* socket = NULL;
|
||||||
if (secure) {
|
if (secure) {
|
||||||
socket = new SecureListenSocket(m_events, m_socketMultiplexer);
|
socket = new SecureListenSocket(m_events, m_socketMultiplexer, family);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
socket = new TCPListenSocket(m_events, m_socketMultiplexer);
|
socket = new TCPListenSocket(m_events, m_socketMultiplexer, family);
|
||||||
}
|
}
|
||||||
|
|
||||||
return socket;
|
return socket;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "net/ISocketFactory.h"
|
#include "net/ISocketFactory.h"
|
||||||
|
#include "arch/IArchNetwork.h"
|
||||||
|
|
||||||
class IEventQueue;
|
class IEventQueue;
|
||||||
class SocketMultiplexer;
|
class SocketMultiplexer;
|
||||||
@@ -30,10 +31,12 @@ public:
|
|||||||
virtual ~TCPSocketFactory();
|
virtual ~TCPSocketFactory();
|
||||||
|
|
||||||
// ISocketFactory overrides
|
// ISocketFactory overrides
|
||||||
virtual IDataSocket*
|
virtual IDataSocket* create(
|
||||||
create(bool secure) const;
|
IArchNetwork::EAddressFamily family,
|
||||||
virtual IListenSocket*
|
bool secure) const;
|
||||||
createListen(bool secure) const;
|
virtual IListenSocket* createListen(
|
||||||
|
IArchNetwork::EAddressFamily family,
|
||||||
|
bool secure) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IEventQueue* m_events;
|
IEventQueue* m_events;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "platform/ImmuneKeysReader.h"
|
#include "platform/ImmuneKeysReader.h"
|
||||||
#include "barrier/protocol_types.h"
|
#include "barrier/protocol_types.h"
|
||||||
#include "barrier/XScreen.h"
|
#include "barrier/XScreen.h"
|
||||||
|
#include "common/DataDirectories.h"
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -52,7 +53,7 @@ static BYTE g_keyState[256] = { 0 };
|
|||||||
static bool g_fakeServerInput = false;
|
static bool g_fakeServerInput = false;
|
||||||
static std::vector<DWORD> g_immuneKeys;
|
static std::vector<DWORD> g_immuneKeys;
|
||||||
|
|
||||||
static const std::string ImmuneKeysPath = ArchFileWindows().getProfileDirectory() + "\\ImmuneKeys.txt";
|
static const std::string ImmuneKeysPath = DataDirectories::profile() + "\\ImmuneKeys.txt";
|
||||||
|
|
||||||
static std::vector<DWORD> immune_keys_list()
|
static std::vector<DWORD> immune_keys_list()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -62,3 +62,23 @@ MSWindowsUtil::getErrorString(HINSTANCE hinstance, DWORD error, DWORD id)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
This is a quick and dirty iterative CreateDirectory() wrapper that does zero
|
||||||
|
error checking. A much better cross-platform option exists in C++17 via
|
||||||
|
std::filesystem. If/when the project is updated to use 17 this function should
|
||||||
|
absolutley be replaced!
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
MSWindowsUtil::createDirectory(const std::string& path, bool stripLast)
|
||||||
|
{
|
||||||
|
// create parent directories
|
||||||
|
for (auto pos = path.find_first_of('\\'); pos != std::string::npos; pos = path.find_first_of('\\', pos + 1))
|
||||||
|
CreateDirectory(path.substr(0, pos).c_str(), NULL);
|
||||||
|
if (!stripLast)
|
||||||
|
// create innermost directory
|
||||||
|
CreateDirectory(path.c_str(), NULL);
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,4 +37,11 @@ public:
|
|||||||
found return the string for \p id, replacing ${1} with \p error.
|
found return the string for \p id, replacing ${1} with \p error.
|
||||||
*/
|
*/
|
||||||
static String getErrorString(HINSTANCE, DWORD error, DWORD id);
|
static String getErrorString(HINSTANCE, DWORD error, DWORD id);
|
||||||
|
|
||||||
|
//! Create directory
|
||||||
|
/*!
|
||||||
|
Create directory \p recursively optionally stripping the last component
|
||||||
|
(presumably the filename) if \p is set.
|
||||||
|
*/
|
||||||
|
static void createDirectory(const std::string& path, bool stripLast = false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,7 +44,20 @@ enum {
|
|||||||
|
|
||||||
typedef VOID (WINAPI *SendSas)(BOOL asUser);
|
typedef VOID (WINAPI *SendSas)(BOOL asUser);
|
||||||
|
|
||||||
const char g_activeDesktop[] = {"activeDesktop:"};
|
std::string activeDesktopName()
|
||||||
|
{
|
||||||
|
const std::size_t BufferLength = 1024;
|
||||||
|
std::string name;
|
||||||
|
HDESK desk = OpenInputDesktop(0, FALSE, GENERIC_READ);
|
||||||
|
if (desk != NULL) {
|
||||||
|
TCHAR buffer[BufferLength];
|
||||||
|
if (GetUserObjectInformation(desk, UOI_NAME, buffer, BufferLength - 1, NULL) == TRUE)
|
||||||
|
name = buffer;
|
||||||
|
CloseDesktop(desk);
|
||||||
|
}
|
||||||
|
LOG((CLOG_DEBUG "found desktop name: %.64s", name.c_str()));
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
MSWindowsWatchdog::MSWindowsWatchdog(
|
MSWindowsWatchdog::MSWindowsWatchdog(
|
||||||
bool daemonized,
|
bool daemonized,
|
||||||
@@ -64,22 +77,8 @@ MSWindowsWatchdog::MSWindowsWatchdog(
|
|||||||
m_processRunning(false),
|
m_processRunning(false),
|
||||||
m_fileLogOutputter(NULL),
|
m_fileLogOutputter(NULL),
|
||||||
m_autoElevated(false),
|
m_autoElevated(false),
|
||||||
m_ready(false),
|
|
||||||
m_daemonized(daemonized)
|
m_daemonized(daemonized)
|
||||||
{
|
{
|
||||||
m_mutex = ARCH->newMutex();
|
|
||||||
m_condVar = ARCH->newCondVar();
|
|
||||||
}
|
|
||||||
|
|
||||||
MSWindowsWatchdog::~MSWindowsWatchdog()
|
|
||||||
{
|
|
||||||
if (m_condVar != NULL) {
|
|
||||||
ARCH->closeCondVar(m_condVar);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_mutex != NULL) {
|
|
||||||
ARCH->closeMutex(m_mutex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -288,12 +287,9 @@ MSWindowsWatchdog::startProcess()
|
|||||||
if (!m_daemonized) {
|
if (!m_daemonized) {
|
||||||
createRet = doStartProcessAsSelf(m_command);
|
createRet = doStartProcessAsSelf(m_command);
|
||||||
} else {
|
} else {
|
||||||
SECURITY_ATTRIBUTES sa;
|
m_autoElevated = activeDesktopName() != "Default";
|
||||||
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
|
|
||||||
|
|
||||||
getActiveDesktop(&sa);
|
SECURITY_ATTRIBUTES sa{ 0 };
|
||||||
|
|
||||||
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
|
|
||||||
HANDLE userToken = getUserToken(&sa);
|
HANDLE userToken = getUserToken(&sa);
|
||||||
m_elevateProcess = m_autoElevated ? m_autoElevated : m_elevateProcess;
|
m_elevateProcess = m_autoElevated ? m_autoElevated : m_elevateProcess;
|
||||||
m_autoElevated = false;
|
m_autoElevated = false;
|
||||||
@@ -408,7 +404,7 @@ MSWindowsWatchdog::getCommand() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// seems like a fairly convoluted way to get the process name
|
// seems like a fairly convoluted way to get the process name
|
||||||
const char* launchName = App::instance().argsBase().m_pname;
|
const char* launchName = App::instance().argsBase().m_exename.c_str();
|
||||||
std::string args = ARCH->commandLine();
|
std::string args = ARCH->commandLine();
|
||||||
|
|
||||||
// build up a full command line
|
// build up a full command line
|
||||||
@@ -444,11 +440,7 @@ MSWindowsWatchdog::outputLoop(void*)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
buffer[bytesRead] = '\0';
|
buffer[bytesRead] = '\0';
|
||||||
|
|
||||||
testOutput(buffer);
|
|
||||||
|
|
||||||
m_ipcLogOutputter.write(kINFO, buffer);
|
m_ipcLogOutputter.write(kINFO, buffer);
|
||||||
|
|
||||||
if (m_fileLogOutputter != NULL) {
|
if (m_fileLogOutputter != NULL) {
|
||||||
m_fileLogOutputter->write(kINFO, buffer);
|
m_fileLogOutputter->write(kINFO, buffer);
|
||||||
}
|
}
|
||||||
@@ -549,63 +541,3 @@ MSWindowsWatchdog::shutdownExistingProcesses()
|
|||||||
CloseHandle(snapshot);
|
CloseHandle(snapshot);
|
||||||
m_processRunning = false;
|
m_processRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
MSWindowsWatchdog::getActiveDesktop(LPSECURITY_ATTRIBUTES security)
|
|
||||||
{
|
|
||||||
String installedDir = ARCH->getInstalledDirectory();
|
|
||||||
if (!installedDir.empty()) {
|
|
||||||
String syntoolCommand;
|
|
||||||
syntoolCommand.append("\"").append(installedDir).append("\\").append("syntool").append("\"");
|
|
||||||
syntoolCommand.append(" --get-active-desktop");
|
|
||||||
|
|
||||||
m_session.updateActiveSession();
|
|
||||||
bool elevateProcess = m_elevateProcess;
|
|
||||||
m_elevateProcess = true;
|
|
||||||
HANDLE userToken = getUserToken(security);
|
|
||||||
m_elevateProcess = elevateProcess;
|
|
||||||
|
|
||||||
BOOL createRet = doStartProcessAsUser(syntoolCommand, userToken, security);
|
|
||||||
|
|
||||||
if (!createRet) {
|
|
||||||
DWORD rc = GetLastError();
|
|
||||||
RevertToSelf();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG((CLOG_DEBUG "launched syntool to check active desktop"));
|
|
||||||
}
|
|
||||||
|
|
||||||
ARCH->lockMutex(m_mutex);
|
|
||||||
int waitTime = 0;
|
|
||||||
while (!m_ready) {
|
|
||||||
if (waitTime >= MAXIMUM_WAIT_TIME) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ARCH->waitCondVar(m_condVar, m_mutex, 1.0);
|
|
||||||
waitTime++;
|
|
||||||
}
|
|
||||||
m_ready = false;
|
|
||||||
ARCH->unlockMutex(m_mutex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
MSWindowsWatchdog::testOutput(String buffer)
|
|
||||||
{
|
|
||||||
// HACK: check standard output seems hacky.
|
|
||||||
size_t i = buffer.find(g_activeDesktop);
|
|
||||||
if (i != String::npos) {
|
|
||||||
size_t s = sizeof(g_activeDesktop);
|
|
||||||
String defaultDesktop("Default");
|
|
||||||
String sub = buffer.substr(i + s - 1, defaultDesktop.size());
|
|
||||||
if (sub != defaultDesktop) {
|
|
||||||
m_autoElevated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ARCH->lockMutex(m_mutex);
|
|
||||||
m_ready = true;
|
|
||||||
ARCH->broadcastCondVar(m_condVar);
|
|
||||||
ARCH->unlockMutex(m_mutex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ public:
|
|||||||
bool autoDetectCommand,
|
bool autoDetectCommand,
|
||||||
IpcServer& ipcServer,
|
IpcServer& ipcServer,
|
||||||
IpcLogOutputter& ipcLogOutputter);
|
IpcLogOutputter& ipcLogOutputter);
|
||||||
virtual ~MSWindowsWatchdog();
|
|
||||||
|
|
||||||
void startAsync();
|
void startAsync();
|
||||||
std::string getCommand() const;
|
std::string getCommand() const;
|
||||||
@@ -58,9 +57,6 @@ private:
|
|||||||
void startProcess();
|
void startProcess();
|
||||||
BOOL doStartProcessAsUser(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa);
|
BOOL doStartProcessAsUser(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa);
|
||||||
BOOL doStartProcessAsSelf(String& command);
|
BOOL doStartProcessAsSelf(String& command);
|
||||||
void sendSas();
|
|
||||||
void getActiveDesktop(LPSECURITY_ATTRIBUTES security);
|
|
||||||
void testOutput(String buffer);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread* m_thread;
|
Thread* m_thread;
|
||||||
@@ -80,9 +76,6 @@ private:
|
|||||||
bool m_processRunning;
|
bool m_processRunning;
|
||||||
FileLogOutputter* m_fileLogOutputter;
|
FileLogOutputter* m_fileLogOutputter;
|
||||||
bool m_autoElevated;
|
bool m_autoElevated;
|
||||||
ArchMutex m_mutex;
|
|
||||||
ArchCond m_condVar;
|
|
||||||
bool m_ready;
|
|
||||||
bool m_daemonized;
|
bool m_daemonized;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ ClientListener::ClientListener(const NetworkAddress& address,
|
|||||||
assert(m_socketFactory != NULL);
|
assert(m_socketFactory != NULL);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
m_listen = m_socketFactory->createListen(m_useSecureNetwork);
|
m_listen = m_socketFactory->createListen(
|
||||||
|
ARCH->getAddrFamily(address.getAddress()),
|
||||||
|
m_useSecureNetwork);
|
||||||
|
|
||||||
// setup event handler
|
// setup event handler
|
||||||
m_events->adoptHandler(m_events->forIListenSocket().connecting(),
|
m_events->adoptHandler(m_events->forIListenSocket().connecting(),
|
||||||
|
|||||||
Reference in New Issue
Block a user