merge v3 to dev.

pull/129/head
Apex Liu 2018-05-11 17:03:46 +08:00
commit 5b1f639cfa
807 changed files with 152608 additions and 74654 deletions

30
.gitignore vendored
View File

@ -15,6 +15,7 @@ cmake_install.cmake
Makefile
cmake-build
cmake-build-debug
client/tp_assist_macos/build
# for Python
__pycache__
@ -31,10 +32,13 @@ __pycache__
**/.idea/inspectionProfiles
**/.idea/vcs.xml
*.css.map
# for tmp folder or files.
/out
/external/_download_
/external/linux
/external/macos
/external/jsoncpp
/external/mongoose
/external/openssl
@ -47,7 +51,7 @@ __pycache__
/external/libuv
/client/tools/putty
/client/tools/winscp
/client/tp_assist_macos/DerivedData
# for dist folder
**/_tmp_
@ -60,6 +64,7 @@ __pycache__
/server/share/db
/server/share/log
/server/share/replay
/server/testssh
# for generated files.
@ -71,3 +76,26 @@ __pycache__
/client/tp_rdp
/server/tp_core/protocol/rdp
/client/tools/tprdp
/server/tp_core/testssh
/client/tp_assist_win_it_doctor
/dist/client/windows/assist-it-doctor
# for MacOS.
.DS_Store
# Xcode
build/*
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
*.xcworkspace
!default.xcworkspace
xcuserdata
profile
*.moved-aside
/server/share/tmp

View File

@ -1,7 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$/builder" />
<content url="file://$MODULE_DIR$/builder">
<sourceFolder url="file://$MODULE_DIR$/builder" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="py34" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>

View File

@ -113,6 +113,7 @@ def clean_everything():
utils.remove(os.path.join(env.root_path, 'external', 'linux', 'release', 'lib', 'libmbedx509.a'))
utils.remove(os.path.join(env.root_path, 'external', 'linux', 'release', 'lib', 'libsqlite3.a'))
utils.remove(os.path.join(env.root_path, 'external', 'linux', 'release', 'lib', 'libssh.a'))
utils.remove(os.path.join(env.root_path, 'external', 'linux', 'release', 'lib', 'libssh_threads.a'))
utils.remove(os.path.join(env.root_path, 'external', 'linux', 'release', 'lib', 'libuv.a'))
@ -199,7 +200,7 @@ def make_options():
# options = list()
# options_idx = 0
if ctx.host_os == 'windows':
if ctx.host_os in ['windows', 'macos']:
add_option('x86', 'ver', 'Update version setting')
add_option('x86', 'pysrt', 'Make Python-Runtime for python%s-x86' % env.py_ver_str)
add_option('x64', 'external', 'Build external dependency')

View File

@ -2,8 +2,8 @@
from core import colorconsole as cc
from core import utils
from core.context import *
from core.ver import *
from core.context import *
from core.env import env
ctx = BuildContext()
@ -29,7 +29,7 @@ class BuilderWin(BuilderBase):
def build_exe(self):
cc.i('build tp_assist...')
sln_file = os.path.join(env.root_path, 'client', 'tp_assist', 'tp_assist.vs2015.sln')
sln_file = os.path.join(env.root_path, 'client', 'tp_assist_win', 'tp_assist.vs2015.sln')
out_file = os.path.join(env.root_path, 'out', 'client', ctx.bits_path, ctx.target_path, 'tp_assist.exe')
if os.path.exists(out_file):
utils.remove(out_file)
@ -46,9 +46,9 @@ class BuilderWin(BuilderBase):
# utils.ensure_file_exists(out_file)
def build_installer(self):
cc.i('build assist package for website...')
cc.i('build assist installer...')
name = 'teleport-assist-{}'.format(VER_TELEPORT_ASSIST)
name = 'teleport-assist-{}-{}'.format(ctx.dist, VER_TP_ASSIST)
out_path = os.path.join(env.root_path, 'out', 'installer')
utils.makedirs(out_path)
@ -69,21 +69,14 @@ class BuilderWin(BuilderBase):
if os.path.exists(tmp_app_path):
utils.remove(tmp_app_path)
# if os.path.exists(tmp_cfg_path):
# utils.remove(tmp_cfg_path)
utils.makedirs(tmp_app_path)
utils.makedirs(tmp_cfg_path)
utils.copy_file(os.path.join(env.root_path, 'out', 'client', ctx.bits_path, ctx.target_path), tmp_app_path, 'tp_assist.exe')
# utils.copy_file(os.path.join(env.root_path, 'client', 'tp_assist', 'cfg'), tmp_cfg_path, 'ssh.ini')
# utils.copy_file(os.path.join(env.root_path, 'client', 'tp_assist', 'cfg'), tmp_cfg_path, 'scp.ini')
# utils.copy_file(os.path.join(env.root_path, 'client', 'tp_assist', 'cfg'), tmp_cfg_path, 'telnet.ini')
utils.copy_file(os.path.join(env.root_path, 'client', 'tp_assist', 'cfg'), tmp_cfg_path, 'ssh.ini')
utils.copy_file(os.path.join(env.root_path, 'client', 'tp_assist', 'cfg'), tmp_cfg_path, 'scp.ini')
utils.copy_file(os.path.join(env.root_path, 'client', 'tp_assist', 'cfg'), tmp_cfg_path, 'telnet.ini')
utils.copy_file(os.path.join(env.root_path, 'client', 'tp_assist_win', 'cfg'), tmp_cfg_path, ('tp-assist.default.json', 'tp-assist.json'))
utils.copy_ex(os.path.join(env.root_path, 'client', 'tp_assist'), tmp_app_path, 'site')
utils.copy_ex(os.path.join(env.root_path, 'client', 'tp_assist_win'), tmp_app_path, 'site')
utils.makedirs(os.path.join(tmp_app_path, 'tools', 'putty'))
utils.copy_file(os.path.join(env.root_path, 'client', 'tools', 'putty'), os.path.join(tmp_app_path, 'tools', 'putty'), 'putty.exe')
@ -104,6 +97,75 @@ class BuilderWin(BuilderBase):
utils.nsis_build(os.path.join(env.root_path, 'dist', 'client', 'windows', 'assist', 'installer.nsi'))
class BuilderMacOS(BuilderBase):
def __init__(self):
super().__init__()
def build_exe(self):
cc.i('build tp_assist...')
configuration = ctx.target_path.capitalize()
proj_file = os.path.join(env.root_path, 'client', 'tp_assist_macos', 'tp_assist.xcodeproj')
out_file = os.path.join(env.root_path, 'client', 'tp_assist_macos', 'build', ctx.target_path, 'tp_assist.app')
if os.path.exists(out_file):
utils.remove(out_file)
utils.xcode_build(proj_file, 'tp_assist', configuration, False)
utils.ensure_file_exists(os.path.join(out_file, 'Contents', 'Info.plist'))
def build_installer(self):
cc.e('assist for macOS does not need an installer, you should make an .DMG file for release...')
# name = 'teleport-assist-{}-{}'.format(ctx.dist, VER_TP_ASSIST)
#
# out_path = os.path.join(env.root_path, 'out', 'installer')
# utils.makedirs(out_path)
#
# out_file = os.path.join(out_path, '{}.exe'.format(name))
# utils.remove(out_file)
#
# self._build_installer()
#
# utils.ensure_file_exists(out_file)
@staticmethod
def _build_installer():
return
# tmp_path = os.path.join(env.root_path, 'dist', 'client', 'windows', 'assist')
# tmp_app_path = os.path.join(tmp_path, 'apps')
# tmp_cfg_path = os.path.join(tmp_app_path, 'cfg')
#
# if os.path.exists(tmp_app_path):
# utils.remove(tmp_app_path)
#
# utils.makedirs(tmp_app_path)
# utils.makedirs(tmp_cfg_path)
#
# utils.copy_file(os.path.join(env.root_path, 'out', 'client', ctx.bits_path, ctx.target_path), tmp_app_path, 'tp_assist.exe')
# utils.copy_file(os.path.join(env.root_path, 'client', 'tp_assist_win', 'cfg'), tmp_cfg_path, ('tp-assist.default.json', 'tp-assist.json'))
#
# utils.copy_ex(os.path.join(env.root_path, 'client', 'tp_assist_win'), tmp_app_path, 'site')
#
# utils.makedirs(os.path.join(tmp_app_path, 'tools', 'putty'))
# utils.copy_file(os.path.join(env.root_path, 'client', 'tools', 'putty'), os.path.join(tmp_app_path, 'tools', 'putty'), 'putty.exe')
#
# utils.makedirs(os.path.join(tmp_app_path, 'tools', 'winscp'))
# utils.copy_file(os.path.join(env.root_path, 'client', 'tools', 'winscp'), os.path.join(tmp_app_path, 'tools', 'winscp'), 'WinSCP.exe')
# utils.copy_file(os.path.join(env.root_path, 'client', 'tools', 'winscp'), os.path.join(tmp_app_path, 'tools', 'winscp'), 'license.txt')
#
# utils.makedirs(os.path.join(tmp_app_path, 'tools', 'tprdp'))
# utils.copy_file(os.path.join(env.root_path, 'client', 'tools', 'tprdp'), os.path.join(tmp_app_path, 'tools', 'tprdp'), 'tprdp-client.exe')
# utils.copy_file(os.path.join(env.root_path, 'client', 'tools', 'tprdp'), os.path.join(tmp_app_path, 'tools', 'tprdp'), 'tprdp-replay.exe')
# utils.copy_file(os.path.join(env.root_path, 'client', 'tools', 'tprdp'), os.path.join(tmp_app_path, 'tools', 'tprdp'), 'libeay32.dll')
# utils.copy_file(os.path.join(env.root_path, 'client', 'tools', 'tprdp'), os.path.join(tmp_app_path, 'tools', 'tprdp'), 'ssleay32.dll')
# utils.copy_file(os.path.join(env.root_path, 'client', 'tools', 'tprdp'), os.path.join(tmp_app_path, 'tools', 'tprdp'), 'msvcr120.dll')
#
# utils.copy_file(os.path.join(env.root_path, 'client', 'tools'), os.path.join(tmp_app_path, 'tools'), 'securecrt-telnet.vbs')
#
# utils.nsis_build(os.path.join(env.root_path, 'dist', 'client', 'windows', 'assist', 'installer.nsi'))
class BuilderLinux(BuilderBase):
def __init__(self):
super().__init__()
@ -121,6 +183,8 @@ class BuilderLinux(BuilderBase):
def gen_builder(dist):
if dist == 'windows':
builder = BuilderWin()
elif dist == 'macos':
builder = BuilderMacOS()
elif dist == 'linux':
builder = BuilderLinux()
else:

View File

@ -293,22 +293,6 @@ class BuilderLinux(BuilderBase):
def _build_openssl(self, file_name):
pass # we do not need build openssl anymore, because first time run build.sh we built Python, it include openssl.
# if not os.path.exists(self.OPENSSL_PATH_SRC):
# os.system('tar -zxvf "{}/{}" -C "{}"'.format(PATH_DOWNLOAD, file_name, self.PATH_TMP))
#
# cc.n('build openssl static...')
# if os.path.exists(os.path.join(self.PATH_RELEASE, 'lib', 'libssl.a')):
# cc.w('already exists, skip.')
# return
#
# old_p = os.getcwd()
# os.chdir(self.OPENSSL_PATH_SRC)
# #os.system('./config --prefix={} --openssldir={}/openssl no-zlib no-shared'.format(self.PATH_RELEASE, self.PATH_RELEASE))
# os.system('./config --prefix={} --openssldir={}/openssl -fPIC no-zlib no-shared'.format(self.PATH_RELEASE, self.PATH_RELEASE))
# os.system('make')
# os.system('make install')
# os.chdir(old_p)
def _build_libuv(self, file_name):
if not os.path.exists(self.LIBUV_PATH_SRC):
# os.system('tar -zxvf "{}/{}" -C "{}"'.format(PATH_DOWNLOAD, file_name, PATH_TMP))
@ -463,9 +447,12 @@ class BuilderLinux(BuilderBase):
' -D_OPENSSL_VERSION={}' \
' -DOPENSSL_INCLUDE_DIR={}/include' \
' -DOPENSSL_LIBRARIES={}/lib' \
' -DWITH_SSH1=ON' \
' -DWITH_SFTP=ON' \
' -DWITH_SERVER=ON' \
' -DWITH_STATIC_LIB=ON' \
' -DWITH_GSSAPI=OFF' \
' -DWITH_ZLIB=OFF' \
' -DWITH_STATIC_LIB=ON' \
' -DWITH_PCAP=OFF' \
' -DWITH_TESTING=OFF' \
' -DWITH_CLIENT_TESTING=OFF' \
@ -521,7 +508,7 @@ class BuilderMacOS(BuilderBase):
def _init_path(self):
self.PATH_TMP = os.path.join(PATH_EXTERNAL, 'macos', 'tmp')
self.PATH_RELEASE = os.path.join(PATH_EXTERNAL, 'macos', 'release')
self.OPENSSL_PATH_SRC = os.path.join(self.PATH_TMP, 'openssl-{}'.format(env.ver_openssl))
self.OPENSSL_PATH_SRC = os.path.join(self.PATH_TMP, 'openssl-OpenSSL_{}'.format(env.ver_openssl.replace('.', '_')))
self.LIBUV_PATH_SRC = os.path.join(self.PATH_TMP, 'libuv-{}'.format(env.ver_libuv))
self.MBEDTLS_PATH_SRC = os.path.join(self.PATH_TMP, 'mbedtls-mbedtls-{}'.format(env.ver_mbedtls))
self.LIBSSH_PATH_SRC = os.path.join(self.PATH_TMP, 'libssh-{}'.format(env.ver_libssh))
@ -552,27 +539,28 @@ class BuilderMacOS(BuilderBase):
cc.w('already exists, skip.')
def _build_openssl(self, file_name):
pass # we do not need build openssl anymore, because first time run build.sh we built Python, it include openssl.
# we do not need build openssl anymore, because first time run build.sh we built Python, it include openssl.
# if not os.path.exists(self.OPENSSL_PATH_SRC):
# os.system('tar -zxvf "{}/{}" -C "{}"'.format(PATH_DOWNLOAD, file_name, self.PATH_TMP))
#
# cc.n('build openssl static...')
# if os.path.exists(os.path.join(self.PATH_RELEASE, 'lib', 'libssl.a')):
# cc.w('already exists, skip.')
# return
#
# old_p = os.getcwd()
# os.chdir(self.OPENSSL_PATH_SRC)
# #os.system('./config --prefix={} --openssldir={}/openssl no-zlib no-shared'.format(self.PATH_RELEASE, self.PATH_RELEASE))
# os.system('./config --prefix={} --openssldir={}/openssl -fPIC no-zlib no-shared'.format(self.PATH_RELEASE, self.PATH_RELEASE))
# os.system('make')
# os.system('make install')
# os.chdir(old_p)
if not os.path.exists(self.OPENSSL_PATH_SRC):
os.system('tar -zxvf "{}/{}" -C "{}"'.format(PATH_DOWNLOAD, file_name, self.PATH_TMP))
cc.n('build openssl static...', end='')
if os.path.exists(os.path.join(self.PATH_RELEASE, 'lib', 'libssl.a')):
cc.w('already exists, skip.')
return
old_p = os.getcwd()
os.chdir(self.OPENSSL_PATH_SRC)
#os.system('./config --prefix={} --openssldir={}/openssl no-zlib no-shared'.format(self.PATH_RELEASE, self.PATH_RELEASE))
# os.system('./Configure darwin64-x86_64-cc')
os.system('./Configure darwin64-x86_64-cc --prefix={} --openssldir={}/openssl -fPIC no-zlib no-shared'.format(self.PATH_RELEASE, self.PATH_RELEASE))
os.system('make')
os.system('make install')
os.chdir(old_p)
def _build_libuv(self, file_name):
cc.w('build libuv...skip')
return
cc.n('prepare libuv source code...', end='')
# return
if not os.path.exists(self.LIBUV_PATH_SRC):
# os.system('tar -zxvf "{}/{}" -C "{}"'.format(PATH_DOWNLOAD, file_name, PATH_TMP))
os.system('unzip "{}/{}" -d "{}"'.format(PATH_DOWNLOAD, file_name, self.PATH_TMP))
@ -584,7 +572,7 @@ class BuilderMacOS(BuilderBase):
cc.v('')
# we need following...
# apt-get install autoconf aptitude libtool gcc-c++
# brew install automake libtool
old_p = os.getcwd()
os.chdir(self.LIBUV_PATH_SRC)
@ -627,45 +615,6 @@ class BuilderMacOS(BuilderBase):
f.writelines(fl)
f.close()
# # fix config.h
# mkfile = os.path.join(self.MBEDTLS_PATH_SRC, 'include', 'mbedtls', 'config.h')
# f = open(mkfile)
# fl = f.readlines()
# f.close()
#
# for i in range(len(fl)):
# if fl[i].find('#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED') >= 0:
# fl[i] = '//#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED\n'
# elif fl[i].find('#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED') >= 0:
# fl[i] = '//#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED\n'
# elif fl[i].find('#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED') >= 0:
# fl[i] = '//#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED\n'
# elif fl[i].find('#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED') >= 0:
# fl[i] = '//#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED\n'
# elif fl[i].find('#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED') >= 0:
# fl[i] = '//#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED\n'
# elif fl[i].find('#define MBEDTLS_SELF_TEST') >= 0:
# fl[i] = '//#define MBEDTLS_SELF_TEST\n'
# elif fl[i].find('#define MBEDTLS_SSL_RENEGOTIATION') >= 0:
# fl[i] = '//#define MBEDTLS_SSL_RENEGOTIATION\n'
# elif fl[i].find('#define MBEDTLS_ECDH_C') >= 0:
# fl[i] = '//#define MBEDTLS_ECDH_C\n'
# elif fl[i].find('#define MBEDTLS_ECDSA_C') >= 0:
# fl[i] = '//#define MBEDTLS_ECDSA_C\n'
# elif fl[i].find('#define MBEDTLS_ECP_C') >= 0:
# fl[i] = '//#define MBEDTLS_ECP_C\n'
# elif fl[i].find('#define MBEDTLS_NET_C') >= 0:
# fl[i] = '//#define MBEDTLS_NET_C\n'
#
# elif fl[i].find('#define MBEDTLS_RSA_NO_CRT') >= 0:
# fl[i] = '#define MBEDTLS_RSA_NO_CRT\n'
# elif fl[i].find('#define MBEDTLS_SSL_PROTO_SSL3') >= 0:
# fl[i] = '#define MBEDTLS_SSL_PROTO_SSL3\n'
#
# f = open(mkfile, 'w')
# f.writelines(fl)
# f.close()
# fix source file
utils.ensure_file_exists(os.path.join(PATH_EXTERNAL, 'fix-external', 'mbedtls', 'include', 'mbedtls', 'config.h'))
utils.copy_file(os.path.join(PATH_EXTERNAL, 'fix-external', 'mbedtls', 'include', 'mbedtls'), os.path.join(self.MBEDTLS_PATH_SRC, 'include', 'mbedtls'), 'config.h')
@ -735,7 +684,7 @@ class BuilderMacOS(BuilderBase):
' -DWITH_EXAMPLES=OFF' \
' -DWITH_BENCHMARKS=OFF' \
' -DWITH_NACL=OFF' \
' ..'.format(self.PATH_RELEASE, env.ver_openssl_number, self.PATH_RELEASE, self.PATH_RELEASE)
''.format(self.PATH_RELEASE, env.ver_openssl_number, self.PATH_RELEASE, self.PATH_RELEASE)
try:
utils.cmake(build_path, 'Release', False, cmake_define)

View File

@ -10,9 +10,8 @@ from core.context import *
from core.ver import *
ctx = BuildContext()
# COMMON_MODULES = ['paste', 'pyasn1', 'pymemcache', 'pymysql', 'rsa', 'tornado', 'six.py']
with_rdp = os.path.exists(os.path.join(env.root_path, 'server', 'tp_core', 'protocol', 'rdp'))
with_telnet = os.path.exists(os.path.join(env.root_path, 'server', 'tp_core', 'protocol', 'telnet'))
class BuilderBase:
@ -47,7 +46,7 @@ class BuilderBase:
class BuilderWin(BuilderBase):
def __init__(self):
super().__init__()
self.name = 'teleport-server-windows-{}-{}'.format(ctx.bits_path, VER_TELEPORT_SERVER)
self.name = 'teleport-server-windows-{}-{}'.format(ctx.bits_path, VER_TP_SERVER)
self._final_file = os.path.join(env.root_path, 'out', 'installer', '{}.zip'.format(self.name))
self.dist_path = os.path.join(env.root_path, 'dist', 'server')
@ -73,7 +72,9 @@ class BuilderWin(BuilderBase):
utils.copy_ex(out_path, bin_path, 'tp_web.exe')
utils.copy_ex(out_path, bin_path, 'tp_core.exe')
utils.copy_ex(out_path, bin_path, 'tpssh.dll')
utils.copy_ex(out_path, bin_path, 'tprdp.dll')
utils.copy_ex(out_path, bin_path, 'tptelnet.dll')
if with_rdp:
utils.copy_ex(out_path, bin_path, 'tprdp.dll')
utils.copy_ex(os.path.join(env.root_path, 'out', 'pysrt'), bin_path, (ctx.dist_path, 'pysrt'))
@ -92,7 +93,7 @@ class BuilderWin(BuilderBase):
class BuilderLinux(BuilderBase):
def __init__(self):
super().__init__()
self.name = 'teleport-server-linux-{}-{}'.format(ctx.bits_path, VER_TELEPORT_SERVER)
self.name = 'teleport-server-linux-{}-{}'.format(ctx.bits_path, VER_TP_SERVER)
self._final_file = os.path.join(env.root_path, 'out', 'installer', '{}.tar.gz'.format(self.name))
self.dist_path = os.path.join(env.root_path, 'dist', 'server')
@ -102,11 +103,6 @@ class BuilderLinux(BuilderBase):
self.path_tmp = os.path.join(self.base_tmp, self.name)
self.path_tmp_data = os.path.join(self.path_tmp, 'data')
# self.server_path = os.path.join(env.root_path, 'dist', 'installer', ctx.dist, 'server')
# self.script_path = self.tmp_path = os.path.join(self.server_path, 'script')
# self.src_path = os.path.join(env.root_path, 'source')
# self.out_tmp_path = os.path.join(self.tmp_path, self.name, 'server')
def build_installer(self):
cc.n('make teleport installer package...')
@ -119,49 +115,22 @@ class BuilderLinux(BuilderBase):
utils.copy_file(os.path.join(env.root_path, 'server', 'share', 'etc'), os.path.join(self.path_tmp_data, 'tmp', 'etc'), ('core.ini.in', 'core.ini'))
utils.copy_file(os.path.join(env.root_path, 'server', 'share', 'etc'), os.path.join(self.path_tmp_data, 'tmp', 'etc'), 'tp_ssh_server.key')
# out_path = os.path.join(env.root_path, 'out', 'eom_ts', ctx.target_path, ctx.dist_path)
# out_path = os.path.join(env.root_path, 'out', 'eom_ts', ctx.bits_path, 'bin')
# bin_path = os.path.join(self.tmp_path, 'bin')
# utils.copy_file(out_path, bin_path, 'eom_ts')
# fix new line flag
utils.fix_new_line_flag(os.path.join(self.path_tmp_data, 'tmp', 'etc', 'web.ini'))
utils.fix_new_line_flag(os.path.join(self.path_tmp_data, 'tmp', 'etc', 'core.ini'))
out_path = os.path.join(env.root_path, 'out', 'server', ctx.bits_path, 'bin')
bin_path = os.path.join(self.path_tmp_data, 'bin')
utils.copy_ex(out_path, bin_path, 'tp_web')
utils.copy_ex(out_path, bin_path, 'tp_core')
utils.copy_ex(out_path, bin_path, 'libtpssh.so')
utils.copy_ex(out_path, bin_path, 'libtprdp.so')
utils.copy_ex(out_path, bin_path, 'libtptelnet.so')
if with_rdp:
utils.copy_ex(out_path, bin_path, 'libtprdp.so')
utils.copy_ex(os.path.join(env.root_path, 'out', 'pysrt'), bin_path, (ctx.dist_path, 'pysrt'))
# utils.copy_file(os.path.join(env.root_path, 'share', 'etc'), os.path.join(self.tmp_path, 'tmp', 'etc'), 'eom_ts.ini')
# utils.copy_file(os.path.join(env.root_path, 'share', 'etc'), os.path.join(self.tmp_path, 'tmp', 'etc'), 'license.key')
# utils.copy_ex(os.path.join(env.root_path, 'share', 'etc'), os.path.join(self.tmp_path, 'tmp', 'etc'), 'ssl')
# utils.copy_ex(os.path.join(env.root_path, 'share', 'data'), os.path.join(self.tmp_path, 'tmp', 'data'), ('ts_db_release.db', 'ts_db.db'))
# utils.copy_ex(os.path.join(env.root_path, 'server', 'share', 'data'), os.path.join(self.tmp_path, 'tmp', 'data'), 'main.sql')
# utils.make_zip(self.tmp_path, os.path.join(self.tmp_path, '..', 'eom_ts.zip'))
# utils.make_targz(os.path.join(self.tmp_path, '..'), 'teleport', 'teleport.tar.gz')
# utils.remove(self.tmp_path)
# make final installer.
# cc.n('pack final server installer...')
# out_file = os.path.join(env.root_path, 'dist', '{}.zip'.format(self.name))
# out_file = os.path.join(env.root_path, 'out', 'installer', '{}.tar.gz'.format(self.name))
# if os.path.exists(out_file):
# utils.remove(out_file)
# # copy installer scripts.
# for i in ['daemon', 'start.sh', 'stop.sh', 'status.sh']:
# # for i in ['daemon_web', 'daemon_core', 'teleport.sh']:
# shutil.copy(os.path.join(self.dist_path, 'script', i), os.path.abspath(os.path.join(self.tmp_path, '..', i)))
# for i in ['install.sh', 'uninst.sh']:
# shutil.copy(os.path.join(self.dist_path, 'script', i), os.path.abspath(os.path.join(self.tmp_path, '..', '..', i)))
# 复制安装所需的脚本
# utils.copy_ex(os.path.join(self.dist_path, 'script'), self.path_tmp, 'install.sh')
# utils.copy_ex(os.path.join(self.dist_path, 'script'), self.path_tmp, 'uninst.sh')
utils.copy_ex(os.path.join(self.dist_path), self.path_tmp, 'setup.sh')
utils.copy_ex(os.path.join(self.dist_path), self.path_tmp, 'script')
utils.copy_ex(os.path.join(self.dist_path), self.path_tmp, 'daemon')

View File

@ -1,14 +1,12 @@
# -*- coding: utf-8 -*-
# import codecs
# import shutil
# import time
from core import colorconsole as cc
from core import utils
from core.context import *
from core.env import env
ctx = BuildContext()
with_rdp = os.path.exists(os.path.join(env.root_path, 'server', 'tp_core', 'protocol', 'rdp'))
class BuilderBase:
@ -52,7 +50,15 @@ class BuilderWin(BuilderBase):
utils.msvc_build(sln_file, 'tpssh', ctx.target_path, ctx.bits_path, False)
utils.ensure_file_exists(out_file)
if os.path.exists(os.path.join(env.root_path, 'server', 'tp_core', 'protocol', 'ssh', 'tpssh.vs2015.sln')):
cc.n('build TELNET protocol ...')
sln_file = os.path.join(env.root_path, 'server', 'tp_core', 'protocol', 'telnet', 'tptelnet.vs2015.sln')
out_file = os.path.join(env.root_path, 'out', 'server', ctx.bits_path, ctx.target_path, 'tptelnet.dll')
if os.path.exists(out_file):
utils.remove(out_file)
utils.msvc_build(sln_file, 'tptelnet', ctx.target_path, ctx.bits_path, False)
utils.ensure_file_exists(out_file)
if with_rdp:
cc.n('build RDP protocol ...')
sln_file = os.path.join(env.root_path, 'server', 'tp_core', 'protocol', 'rdp', 'tprdp.vs2015.sln')
out_file = os.path.join(env.root_path, 'out', 'server', ctx.bits_path, ctx.target_path, 'tprdp.dll')
@ -67,11 +73,46 @@ class BuilderLinux(BuilderBase):
super().__init__()
def build_server(self):
cc.n('build server app (tp_core/libtpssh/tp_web)...')
cc.n('build server app (tp_core/libtpssh/libtelnet/librdp/tp_web)...')
out_path = os.path.join(env.root_path, 'out', 'server', ctx.bits_path, 'bin')
out_files = [os.path.join(out_path, 'tp_core'), os.path.join(out_path, 'libtpssh.so'),
os.path.join(out_path, 'tp_web')]
out_files = list()
out_files.append(os.path.join(out_path, 'tp_core'))
out_files.append(os.path.join(out_path, 'tp_web'))
out_files.append(os.path.join(out_path, 'libtpssh.so'))
out_files.append(os.path.join(out_path, 'libtptelnet.so'))
if with_rdp:
out_files.append(os.path.join(out_path, 'libtprdp.so'))
for f in out_files:
if os.path.exists(f):
utils.remove(f)
utils.makedirs(out_path)
utils.cmake(os.path.join(env.root_path, 'server', 'cmake-build'), ctx.target_path, False)
# utils.strip(out_file)
for f in out_files:
if os.path.exists(f):
utils.ensure_file_exists(f)
class BuilderMacOS(BuilderBase):
def __init__(self):
super().__init__()
def build_server(self):
cc.n('build server app (tp_core/libtpssh/libtelnet/librdp/tp_web)...')
out_path = os.path.join(env.root_path, 'out', 'server', ctx.bits_path, 'bin')
out_files = list()
out_files.append(os.path.join(out_path, 'tp_core'))
out_files.append(os.path.join(out_path, 'tp_web'))
out_files.append(os.path.join(out_path, 'libtpssh.so'))
out_files.append(os.path.join(out_path, 'libtptelnet.so'))
if with_rdp:
out_files.append(os.path.join(out_path, 'libtprdp.so'))
for f in out_files:
if os.path.exists(f):
@ -92,6 +133,8 @@ def gen_builder(dist):
builder = BuilderWin()
elif dist == 'linux':
builder = BuilderLinux()
elif dist == 'macos':
builder = BuilderMacOS()
else:
raise RuntimeError('unsupported platform.')
@ -123,15 +166,6 @@ def main():
if 'server' in argv:
builder.build_server()
# if 'app' in argv:
# builder.build_app()
# if 'installer' in argv:
# builder.build_installer()
# if 'runtime' in argv:
# builder.build_runtime()
if __name__ == '__main__':
try:

View File

@ -4,24 +4,20 @@
import codecs
from core import colorconsole as cc
from core import utils
from core.env import env
from core.context import *
from core.env import env
ctx = BuildContext()
# ROOT_PATH = utils.cfg.ROOT_PATH
class Builder:
def __init__(self):
self.ver_in = os.path.join(env.root_path, 'version.in')
self.VER_TELEPORT_SERVER = ''
self.VER_TELEPORT_ASSIST = ''
self.VER_TELEPORT_ASSIST_REQUIRE = ''
# self.VER_TELEPORT_MAKECERT = ''
self.VER_TP_SERVER = ''
self.VER_TP_TPCORE = ''
self.VER_TP_TPWEB = ''
self.VER_TP_ASSIST = ''
def build(self):
cc.n('update version...')
@ -31,43 +27,41 @@ class Builder:
with codecs.open(self.ver_in, 'r', 'utf-8') as f:
lines = f.readlines()
for l in lines:
if l.startswith('TELEPORT_SERVER '):
if l.startswith('TP_SERVER '):
x = l.split(' ')
self.VER_TELEPORT_SERVER = x[1].strip()
elif l.startswith('TELEPORT_ASSIST '):
self.VER_TP_SERVER = x[1].strip()
elif l.startswith('TP_TPCORE '):
x = l.split(' ')
self.VER_TELEPORT_ASSIST = x[1].strip()
elif l.startswith('TELEPORT_ASSIST_REQUIRE '):
self.VER_TP_TPCORE = x[1].strip()
elif l.startswith('TP_TPWEB '):
x = l.split(' ')
self.VER_TELEPORT_ASSIST_REQUIRE = x[1].strip()
# elif l.startswith('TELEPORT_MAKECERT '):
# x = l.split(' ')
# self.VER_TELEPORT_MAKECERT = x[1].strip()
self.VER_TP_TPWEB = x[1].strip()
elif l.startswith('TP_ASSIST '):
x = l.split(' ')
self.VER_TP_ASSIST = x[1].strip()
#
cc.v('new version:')
cc.v(' TELEPORT-Server : ', self.VER_TELEPORT_SERVER)
cc.v(' TELEPORT-Assist : ', self.VER_TELEPORT_ASSIST)
cc.v(' TELEPORT-Assist-require : ', self.VER_TELEPORT_ASSIST_REQUIRE)
# cc.v(' TELEPORT-MakeCert : ', self.VER_TELEPORT_MAKECERT)
cc.v(' Server : ', self.VER_TP_SERVER)
cc.v(' - tp_core : ', self.VER_TP_TPCORE)
cc.v(' - tp_web : ', self.VER_TP_TPWEB)
cc.v(' Assist : ', self.VER_TP_ASSIST)
cc.v('')
self.make_build_ver()
self.make_assist_ver()
self.make_tp_core_ver()
self.make_tp_web_ver()
self.make_web_ver()
self.make_builder_ver()
self.make_server_ver()
self.make_tpcore_ver()
self.make_tpweb_ver()
self.make_assist_win_ver()
self.make_assist_macos_ver()
def make_build_ver(self):
def make_builder_ver(self):
ver_file = os.path.join(env.root_path, 'build', 'builder', 'core', 'ver.py')
# ver_content = '# -*- coding: utf8 -*-\nVER_TELEPORT_SERVER = "{}"\nVER_TELEPORT_ASSIST = "{}"\nVER_TELEPORT_MAKECERT = "{}"\n'.format(self.VER_TELEPORT_SERVER, self.VER_TELEPORT_ASSIST, self.VER_TELEPORT_MAKECERT)
ver_content = '# -*- coding: utf8 -*-\nVER_TELEPORT_SERVER = "{}"\nVER_TELEPORT_ASSIST = "{}"\n'.format(self.VER_TELEPORT_SERVER, self.VER_TELEPORT_ASSIST)
ver_content = '# -*- coding: utf8 -*-\nVER_TP_SERVER = "{}"\nVER_TP_ASSIST = "{}"\n'.format(self.VER_TP_SERVER, self.VER_TP_ASSIST)
rewrite = False
if not os.path.exists(ver_file):
rewrite = True
else:
old_content = ''
with open(ver_file, 'r') as f:
old_content = f.read()
if old_content != ver_content:
@ -78,60 +72,14 @@ class Builder:
with open(ver_file, 'w') as f:
f.write(ver_content)
def make_web_ver(self):
ver_file = os.path.join(env.root_path, 'server', 'www', 'teleport', 'app', 'eom_ver.py')
# ver_content = '# -*- coding: utf8 -*-\n\nTS_VER = "{}"\n'.format(self.VER_TELEPORT_SERVER)
ver_content = '# -*- coding: utf8 -*-\nTS_VER = "{}"\nTP_ASSIST_LAST_VER = "{}"\nTP_ASSIST_REQUIRE = "{}"\n'.format(self.VER_TELEPORT_SERVER, self.VER_TELEPORT_ASSIST, self.VER_TELEPORT_ASSIST_REQUIRE)
rewrite = False
if not os.path.exists(ver_file):
rewrite = True
else:
old_content = ''
with open(ver_file, 'r') as f:
old_content = f.read()
if old_content != ver_content:
rewrite = True
if rewrite:
cc.v(' update {}...'.format(ver_file))
with open(ver_file, 'w') as f:
f.write(ver_content)
def make_assist_ver(self):
ver_file = os.path.join(env.root_path, 'client', 'tp_assist', 'ts_ver.h')
ver_content = '#ifndef __TS_ASSIST_VER_H__\n#define __TS_ASSIST_VER_H__\n\n#define TP_ASSIST_VER\tL"{}"\n\n#endif // __TS_ASSIST_VER_H__\n'.format(self.VER_TELEPORT_ASSIST)
rewrite = False
if not os.path.exists(ver_file):
rewrite = True
else:
old_content = ''
with open(ver_file, 'r') as f:
old_content = f.read()
if old_content != ver_content:
rewrite = True
if rewrite:
cc.v(' update {}...'.format(ver_file))
with open(ver_file, 'w') as f:
f.write(ver_content)
rc_file = os.path.join(env.root_path, 'client', 'tp_assist', 'tp_assist.rc')
self._update_vs_rc(rc_file, self.VER_TELEPORT_ASSIST)
nsi_file = os.path.join(env.root_path, 'dist', 'client', 'windows', 'assist', 'installer.nsi')
self._update_nsi_rc(nsi_file, self.VER_TELEPORT_ASSIST)
def make_tp_core_ver(self):
def make_tpcore_ver(self):
ver_file = os.path.join(env.root_path, 'server', 'tp_core', 'core', 'ts_ver.h')
ver_content = '#ifndef __TS_SERVER_VER_H__\n#define __TS_SERVER_VER_H__\n\n#define TP_SERVER_VER\tL"{}"\n\n#endif // __TS_SERVER_VER_H__\n'.format(self.VER_TELEPORT_SERVER)
ver_content = '#ifndef __TS_SERVER_VER_H__\n#define __TS_SERVER_VER_H__\n\n#define TP_SERVER_VER\tL"{}"\n\n#endif // __TS_SERVER_VER_H__\n'.format(self.VER_TP_TPCORE)
rewrite = False
if not os.path.exists(ver_file):
rewrite = True
else:
old_content = ''
with open(ver_file, 'r') as f:
old_content = f.read()
if old_content != ver_content:
@ -143,17 +91,80 @@ class Builder:
f.write(ver_content)
rc_file = os.path.join(env.root_path, 'server', 'tp_core', 'core', 'tp_core.rc')
self._update_vs_rc(rc_file, self.VER_TELEPORT_SERVER)
self._update_ver_rc(rc_file, self.VER_TP_TPCORE)
def make_tp_web_ver(self):
ver_file = os.path.join(env.root_path, 'server', 'tp_web', 'src', 'ts_ver.h')
ver_content = '#ifndef __TS_SERVER_VER_H__\n#define __TS_SERVER_VER_H__\n\n#define TP_SERVER_VER\tL"{}"\n\n#endif // __TS_SERVER_VER_H__\n'.format(self.VER_TELEPORT_SERVER)
def make_server_ver(self):
ver_file = os.path.join(env.root_path, 'server', 'www', 'teleport', 'webroot', 'app', 'app_ver.py')
# ver_content = '# -*- coding: utf8 -*-\n\nTS_VER = "{}"\n'.format(self.VER_TELEPORT_SERVER)
ver_content = '# -*- coding: utf8 -*-\nTP_SERVER_VER = "{}"\n'.format(self.VER_TP_SERVER)
rewrite = False
if not os.path.exists(ver_file):
rewrite = True
else:
with open(ver_file, 'r') as f:
old_content = f.read()
if old_content != ver_content:
rewrite = True
if rewrite:
cc.v(' update {}...'.format(ver_file))
with open(ver_file, 'w') as f:
f.write(ver_content)
def make_assist_win_ver(self):
ver_file = os.path.join(env.root_path, 'client', 'tp_assist_win', 'ts_ver.h')
ver_content = '#ifndef __TS_ASSIST_VER_H__\n#define __TS_ASSIST_VER_H__\n\n#define TP_ASSIST_VER\tL"{}"\n\n#endif // __TS_ASSIST_VER_H__\n'.format(self.VER_TP_ASSIST)
rewrite = False
if not os.path.exists(ver_file):
rewrite = True
else:
with open(ver_file, 'r') as f:
old_content = f.read()
if old_content != ver_content:
rewrite = True
if rewrite:
cc.v(' update {}...'.format(ver_file))
with open(ver_file, 'w') as f:
f.write(ver_content)
rc_file = os.path.join(env.root_path, 'client', 'tp_assist_win', 'tp_assist.rc')
self._update_ver_rc(rc_file, self.VER_TP_ASSIST)
nsi_file = os.path.join(env.root_path, 'dist', 'client', 'windows', 'assist', 'installer.nsi')
self._update_ver_nsi(nsi_file, self.VER_TP_ASSIST)
def make_assist_macos_ver(self):
plist_file = os.path.join(env.root_path, 'client', 'tp_assist_macos', 'src', 'tp_assist-Info.plist')
self._update_ver_plist(plist_file, self.VER_TP_ASSIST)
ver_file = os.path.join(env.root_path, 'client', 'tp_assist_macos', 'src', 'csrc', 'ts_ver.h')
ver_content = '#ifndef __TS_ASSIST_VER_H__\n#define __TS_ASSIST_VER_H__\n\n#define TP_ASSIST_VER\tL"{}"\n\n#endif // __TS_ASSIST_VER_H__\n'.format(self.VER_TP_ASSIST)
rewrite = False
if not os.path.exists(ver_file):
rewrite = True
else:
with open(ver_file, 'r') as f:
old_content = f.read()
if old_content != ver_content:
rewrite = True
if rewrite:
cc.v(' update {}...'.format(ver_file))
with open(ver_file, 'w') as f:
f.write(ver_content)
def make_tpweb_ver(self):
ver_file = os.path.join(env.root_path, 'server', 'tp_web', 'src', 'ts_ver.h')
ver_content = '#ifndef __TS_SERVER_VER_H__\n#define __TS_SERVER_VER_H__\n\n#define TP_SERVER_VER\tL"{}"\n\n#endif // __TS_SERVER_VER_H__\n'.format(self.VER_TP_TPWEB)
rewrite = False
if not os.path.exists(ver_file):
rewrite = True
else:
old_content = ''
with open(ver_file, 'r') as f:
old_content = f.read()
if old_content != ver_content:
@ -165,14 +176,14 @@ class Builder:
f.write(ver_content)
rc_file = os.path.join(env.root_path, 'server', 'tp_web', 'src', 'tp_web.rc')
self._update_vs_rc(rc_file, self.VER_TELEPORT_SERVER)
self._update_ver_rc(rc_file, self.VER_TP_TPWEB)
def _update_vs_rc(self, rcFilePath, ver):
def _update_ver_rc(self, rcFilePath, ver):
""" update rc file version info """
t_ver = ver.split('.')
if len(t_ver) != 4:
raise RuntimeError('Invalid version for assist.')
raise RuntimeError('Invalid version for .rc file.')
bOK = False
try:
@ -276,14 +287,13 @@ class Builder:
wrcFile.close()
except IOError:
raise RuntimeError('can not open rc file.')
raise RuntimeError('can not process rc file.')
def _update_nsi_rc(self, nsiFilePath, ver):
def _update_ver_nsi(self, nsiFilePath, ver):
""" update nsis file version info """
# nver = ver.split('.')
t_ver = ver.split('.')
if len(t_ver) != 4:
raise RuntimeError('Invalid version for assist.')
raise RuntimeError('Invalid version for nsis file.')
bOK = False
try:
@ -350,7 +360,77 @@ class Builder:
return bOK
except IOError:
raise RuntimeError('can not open nsi file.')
raise RuntimeError('can not process nsi file.')
def _update_ver_plist(self, plist_file, ver):
""" update plist file version info for MacOS app."""
t_ver = ver.split('.')
if len(t_ver) != 4:
raise RuntimeError('Invalid version for plist file.')
bOK = False
try:
# open rc file
f = codecs.open(plist_file, 'r', 'utf8')
# read out all lines of rc file
lines = f.readlines()
f.close()
is_ver = False
for x in range(len(lines)):
l = lines[x]
if l.find('<key>CFBundleShortVersionString</key>') != -1:
is_ver = True
continue
if l.find('<key>CFBundleVersion</key>') != -1:
is_ver = True
continue
# pos1 = rcline.find(' FILEVERSION ')
# pos2 = rcline.rfind('\\0"')
# _ver = rcline[pos1 + 13: pos2].strip()
#
# rcSplitList = _ver.split(",")
# if (len(rcSplitList) < 4):
# rcSplitList = _ver.split(".")
# if (len(rcSplitList) < 4):
# raise RuntimeError('Invalid .rc file.')
# if '.'.join(rcSplitList) == ver:
# continue
#
# rcline = '%s%s,%s,%s,%s\n' % (rcline[0:pos1 + 13], t_ver[0], t_ver[1], t_ver[2], t_ver[3])
#
# rcLines[x] = ""
# rcLines[x] = rcline
# # cc.v('[ver] new ver: %s' % rcLines[x])
# bOK = True
if is_ver:
is_ver = False
pos1 = l.find('<string>')
pos2 = l.rfind('</string>')
if pos1 == -1 or pos2 == -2:
continue
_ver = l[pos1 + 8: pos2].strip()
v = _ver.split(".")
if len(v) < 4:
raise RuntimeError('Invalid .plist file.')
old_ver = '.'.join(v)
if old_ver == ver:
continue
lines[x] = '\t<string>{ver}</string>\n'.format(ver=ver)
bOK = True
if bOK:
cc.v(' update {}...'.format(plist_file))
wrcFile = codecs.open(plist_file, 'w', 'utf8')
wrcFile.writelines(lines)
wrcFile.close()
except IOError:
raise RuntimeError('can not process plist file.')
def main():

View File

@ -32,7 +32,7 @@ CR_LIGHT_MAGENTA = 15 # 亮紫色 - 警告
CR_LIGHT_CYAN = 16 # 亮青色
CR_VERBOSE = CR_LIGHT_GRAY
CR_NORMAL = CR_WHITE
CR_NORMAL = CR_RESTORE
CR_INFO = CR_GREEN
CR_WARN = CR_LIGHT_YELLOW
CR_ERROR = CR_LIGHT_RED

View File

@ -143,7 +143,7 @@ class Env(object):
if warn_miss_tool:
cc.w(' - can not locate `nsis`, so I can not make installer.')
elif self.is_linux:
elif self.is_linux or self.is_macos:
if 'cmake' in _tmp:
self.cmake = _tmp['cmake']
else:

View File

@ -9,6 +9,7 @@ import time
import platform
from . import colorconsole as cc
from . import utils
rm_file_every_level = ['.pyc', '.pyo']
@ -47,7 +48,8 @@ def remove_cache(path):
for d in dir_list:
d = d.lower()
if d == '__pycache__':
shutil.rmtree(os.path.join(parent, d))
# shutil.rmtree(os.path.join(parent, d))
utils.remove(os.path.join(parent, d))
continue
remove_cache(os.path.join(parent, d))

View File

@ -63,9 +63,10 @@ def download_file(desc, url, target_path, file_name):
if env.is_win:
cmd = '""{}" --no-check-certificate {} -O "{}""'.format(env.wget, url, local_file_name)
os.system(cmd)
elif env.is_linux:
elif env.is_linux or env.is_macos:
os.system('wget --no-check-certificate {} -O "{}"'.format(url, local_file_name))
else:
cc.e('can not download, no download tool.')
return False
if not os.path.exists(local_file_name) or not _check_download_file(local_file_name):
@ -106,7 +107,7 @@ def extension_suffixes():
def remove(*args):
path = os.path.join(*args)
path = os.path.abspath(os.path.join(*args))
cc.v('remove [%s] ...' % path, end='')
if not os.path.exists(path):
@ -117,6 +118,8 @@ def remove(*args):
cc.v('.', end='')
try:
if os.path.isdir(path):
if path == '/':
raise RuntimeError('### What are you doing?!! ###')
shutil.rmtree(path, ignore_errors=True)
time.sleep(0.5)
else:
@ -278,7 +281,7 @@ def sys_exec(cmd, direct_output=False, output_codec=None):
line = line.rstrip('\r\n')
if direct_output:
cc.o((cc.CR_GRAY, line), end='\n')
cc.o((cc.CR_CYAN, line), end='\n')
output.append(line)
@ -304,6 +307,21 @@ def msvc_build(sln_file, proj_name, target, platform, force_rebuild):
raise RuntimeError('build MSVC project `{}` failed.'.format(proj_name))
def xcode_build(proj_file, proj_name, target, force_rebuild):
# if env.msbuild is None:
# raise RuntimeError('where is `msbuild`?')
if force_rebuild:
cmd = 'xcodebuild -project "{}" -target {} -configuration {} clean'.format(proj_file, proj_name, target)
ret, _ = sys_exec(cmd, direct_output=True)
cc.v('ret:', ret)
cmd = 'xcodebuild -project "{}" -target {} -configuration {}'.format(proj_file, proj_name, target)
ret, _ = sys_exec(cmd, direct_output=True)
if ret != 0:
raise RuntimeError('build XCode project `{}` failed.'.format(proj_name))
def nsis_build(nsi_file, _define=''):
if env.nsis is None:
raise RuntimeError('where is `nsis`?')
@ -334,6 +352,7 @@ def cmake(work_path, target, force_rebuild, cmake_define=''):
else:
target = 'Release'
cmd = '"{}" -DCMAKE_BUILD_TYPE={} {} ..;make'.format(env.cmake, target, cmake_define)
cc.o(cmd)
ret, _ = sys_exec(cmd, direct_output=True)
os.chdir(old_p)
if ret != 0:
@ -351,6 +370,17 @@ def strip(filename):
return True
def fix_new_line_flag(filename):
cc.n('fix new line flag to CR for text file', filename)
if not os.path.exists(filename):
return False
cmd = 'dos2unix {}'.format(filename)
ret, _ = sys_exec(cmd, direct_output=True)
if ret != 0:
raise RuntimeError('failed to dos2unix file [{}], ret={}.'.format(filename, ret))
return True
def make_zip(src_path, to_file, from_parent=True):
cc.v('compress folder into .zip...')

View File

@ -1,3 +1,3 @@
# -*- coding: utf8 -*-
VER_TELEPORT_SERVER = "2.2.10.1"
VER_TELEPORT_ASSIST = "2.2.6.1"
VER_TP_SERVER = "3.0.1.6"
VER_TP_ASSIST = "3.0.1.6"

View File

@ -1 +0,0 @@
@charset "utf-8";body{font-family:"Microsoft YaHei","微软雅黑",Helvetica,Arial,sans-serif;font-size:13px;background-color:#fff;color:#333}html,body{height:100%}.header{width:100%;height:48px;position:fixed;top:0;line-height:48px;font-size:80%;background-color:#3b3b3b;color:#fff;z-index:999}.header .title{font-size:16px}.header .sub-title{margin-left:30px;color:#acacac}.header-fix{height:48px}.footer{width:100%;height:24px;position:fixed;bottom:0;text-align:center;line-height:24px;background-color:#d5d5d5;border-top:1px solid #a2a2a2;font-size:80%;z-index:999}.content{margin:20px 0 50px 0}.content .cfg-title{font-size:16px;font-weight:bold}.content .form-group{margin-bottom:5px}.content .col-sm-1,.content .col-sm-2,.content .col-sm-3,.content .col-sm-4,.content .col-sm-5,.content .col-sm-6,.content .col-sm-7{padding-left:3px;padding-right:3px}.content .arg-detail{font-size:11px}.content .arg-detail ol,.content .arg-detail ul{margin-bottom:0}.content .arg-detail-common{background-color:#dbffbe;border-radius:5px;padding:15px}.content .input-args{font-family:Consolas,Lucida Console,Monaco,Courier,'Courier New',monospace}.arg-varb{color:#0a6aa1;font-weight:bold;font-family:Consolas,Lucida Console,Monaco,Courier,'Courier New',monospace;display:inline-block;width:128px}

View File

@ -1,190 +0,0 @@
<!DOCTYPE html>
<!--[if IE 8]>
<html lang="en" class="ie8"><![endif]-->
<!--[if !IE]><!-->
<html lang="zh_CN">
<!--<![endif]-->
<head>
<meta charset="utf-8"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>TELEPORT助手配置</title>
<link rel="shortcut icon" href="favicon.png">
<link href="plugins/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
<link href="plugins/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<link href="plugins/gritter/css/jquery.gritter.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div class="header">
<div class="container">
<span class="title"><i class="fa fa-cog fa-fw"></i> Teleport助手本地配置</span>
<span class="sub-title">此处配置保存到本地计算机上,如果更换计算机,需要重新配置!</span>
</div>
</div>
<div class="header-fix"></div>
<div class="footer">
<div class="container">
<p>触维软件旗下产品 | TELEPORT | &copy;2015 - 2017 <a href="http://teleport.eomsoft.net/" target="_blank">触维软件</a>,保留所有权利。</p>
</div>
</div>
<div class="container">
<div class="content">
<div class="arg-detail arg-detail-common">
<span><strong>注意:</strong>命令参数设置中,如需传递主机信息和登录信息,可以用以下变量替换(注意大小写!):</span>
<ul>
<li><span class="arg-varb">{host_ip}</span> 替换主机IP地址</li>
<li><span class="arg-varb">{host_port}</span> 替换主机端口号</li>
<li><span class="arg-varb">{user_name}</span> 替换用户名</li>
<li><span class="arg-varb">{real_ip}</span> 替换为远程主机真实IP仅用于显示例如客户端的窗口标题或标签页标题等</li>
<li><span class="arg-varb">{assist_tools_path}</span> 替换为助手工具所在的tools目录的绝对路径</li>
</ul>
</div>
<hr/>
<p class="cfg-title">本地 SSH 客户端配置</p>
<div class="form-horizontal">
<div class="form-group form-group-sm">
<label for="ssh-client-type" class="col-sm-1 control-label"><strong>客户端:</strong></label>
<div class="col-sm-2">
<select id="ssh-client-type" class="form-control"></select>
</div>
</div>
<div class="form-group form-group-sm">
<label for="ssh-exec-path" class="col-sm-1 control-label"><strong>程序路径:</strong></label>
<div class="col-sm-6">
<div class="input-group">
<input id="ssh-exec-path" type="text" class="form-control" placeholder="客户端可执行程序文件路径" readonly="readonly">
<span class="input-group-btn"><button class="btn btn-sm btn-primary" type="button" id="ssh-select-path">选择...</button></span>
</div>
</div>
</div>
<div class="form-group form-group-sm">
<label for="ssh-exec-args" class="col-sm-1 control-label"><strong>命令参数:</strong></label>
<div class="col-sm-6">
<input id="ssh-exec-args" type="text" class="form-control input-args" placeholder="客户端启动所需命令行参数"/>
</div>
</div>
<div class="form-group form-group-sm">
<div class="col-sm-1"></div>
<div class="col-sm-6">
<a id="ssh-btn-save" class="btn btn-primary" href="javascript:;"><i class="fa fa-check fa-fw"></i> 保存设置!</a>
</div>
</div>
</div>
<hr/>
<p class="cfg-title">本地 SFTP 客户端配置</p>
<div class="form-horizontal">
<div class="form-group form-group-sm">
<label for="sftp-client-type" class="col-sm-1 control-label"><strong>客户端:</strong></label>
<div class="col-sm-2">
<select id="sftp-client-type" class="form-control"></select>
</div>
</div>
<div class="form-group form-group-sm">
<label for="sftp-exec-path" class="col-sm-1 control-label"><strong>程序路径:</strong></label>
<div class="col-sm-6">
<div class="input-group">
<input id="sftp-exec-path" type="text" class="form-control" placeholder="客户端可执行程序文件路径" readonly="readonly">
<span class="input-group-btn"><button class="btn btn-sm btn-primary" type="button" id="sftp-select-path">选择...</button></span>
</div>
</div>
</div>
<div class="form-group form-group-sm">
<label for="sftp-exec-args" class="col-sm-1 control-label"><strong>命令参数:</strong></label>
<div class="col-sm-6">
<input id="sftp-exec-args" type="text" class="form-control input-args" placeholder="客户端启动所需命令行参数"/>
</div>
</div>
<div class="form-group form-group-sm">
<div class="col-sm-1"></div>
<div class="col-sm-6">
<a id="sftp-btn-save" class="btn btn-primary" href="javascript:;"><i class="fa fa-check fa-fw"></i> 保存设置!</a>
</div>
</div>
</div>
<hr/>
<p class="cfg-title">本地 TELNET 客户端配置</p>
<div class="form-horizontal">
<div class="form-group form-group-sm">
<label for="telnet-client-type" class="col-sm-1 control-label"><strong>客户端:</strong></label>
<div class="col-sm-2">
<select id="telnet-client-type" class="form-control"></select>
</div>
</div>
<div class="form-group form-group-sm">
<label for="telnet-exec-path" class="col-sm-1 control-label"><strong>程序路径:</strong></label>
<div class="col-sm-6">
<div class="input-group">
<input id="telnet-exec-path" type="text" class="form-control" placeholder="客户端可执行程序文件路径" readonly="readonly">
<span class="input-group-btn"><button class="btn btn-sm btn-primary" type="button" id="telnet-select-path">选择...</button></span>
</div>
</div>
</div>
<div class="form-group form-group-sm">
<label for="telnet-exec-args" class="col-sm-1 control-label"><strong>命令参数:</strong></label>
<div class="col-sm-6">
<input id="telnet-exec-args" type="text" class="form-control input-args" placeholder="客户端启动所需命令行参数"/>
</div>
</div>
<div class="form-group form-group-sm">
<div class="col-sm-1"></div>
<div class="col-sm-6">
<a id="telnet-btn-save" class="btn btn-primary" href="javascript:;"><i class="fa fa-check fa-fw"></i> 保存设置!</a>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="plugins/underscore/underscore-min.js"></script>
<script type="text/javascript" src="plugins/jquery/jquery.min.js"></script>
<script type="text/javascript" src="plugins/bootstrap/js/bootstrap.min.js"></script>
<!--[if lt IE 9]>
<script src="plugins/html5shiv/html5shiv.min.js"></script>
<![endif]-->
<!--<script type="text/javascript" src="js/json2.js"></script>-->
<script type="text/javascript" src="plugins/gritter/js/jquery.gritter.js"></script>
<script type="text/javascript" src="plugins/keypress/keypress.min.js"></script>
<script type="text/javascript" src="js/ui/config.js"></script>
<script type="text/javascript">
</script>
</body>
</html>

View File

@ -1,269 +0,0 @@
"use strict";
var g_ssh_config_dict = [];
var g_current_ssh = "";
var g_sftp_config_dict = [];
var g_current_sftp = "";
var g_telnet_config_dict = [];
var g_current_telnet = "";
var get_client_config_list = function (type) {
var type = type;
var data = {
type: type
};
var args_ = encodeURIComponent(JSON.stringify(data));
$.ajax({
type: 'GET',
timeout: 5000,
url: 'http://127.0.0.1:50022/ts_get_config/' + args_,
jsonp: 'callback',
dataType: 'json',
success: function (ret) {
if (ret.code == 0) {
init_config_list(type, ret.config_list);
} else {
alert("获取配置信息失败!");
}
},
error: function (jqXhr, _error, _e) {
console.log('state:', jqXhr.state());
alert("获取配置信息失败!");
}
});
}
var set_current_client_config = function (tpye, name, path, commandline, desc) {
var data = {
type: tpye,
name: name,
path: path,
commandline: commandline
};
var args_ = encodeURIComponent(JSON.stringify(data));
$.ajax({
type: 'GET',
timeout: 5000,
url: 'http://127.0.0.1:50022/ts_set_config/' + args_,
jsonp: 'callback',
dataType: 'json',
success: function (ret) {
if (ret.code == 0) {
alert("保存成功");
} else {
alert("保存成功" + ret.code);
}
},
error: function (jqXhr, _error, _e) {
console.log('state:', jqXhr.state());
alert("保存失败");
}
});
}
var open_exist_file = function (callback) {
var data = {
action: 1
};
var args_ = encodeURIComponent(JSON.stringify(data));
$.ajax({
type: 'GET',
timeout: -1,
url: 'http://127.0.0.1:50022/ts_file_action/' + args_,
jsonp: 'callback',
dataType: 'json',
success: function (ret) {
callback(0, ret.path);
},
error: function (jqXhr, _error, _e) {
console.log('state:', jqXhr.state());
callback(-1, "");
}
});
}
var init_config_list = function (type, config_list) {
var html = "";
if (type == 1) {
$("#ssh-client-type").html(html);
for (var i = 0; i < config_list.length; i++) {
var item = config_list[i];
html = '<option id="ssh-' + item.name + '" value="' + item.name + '">' + item.alias_name + '</option>';
$('#ssh-client-type').append(html);
if (item.current == 1) {
$('#ssh-' + item.name).attr('selected', true);
init_config_param(type, item.build_in, item.path, item.commandline);
g_current_ssh = item.name;
}
g_ssh_config_dict[item.name] = item;
}
} else if(type == 2) {
$('#sftp-client-type').html(html);
for (var i = 0; i < config_list.length; i++) {
var item = config_list[i];
html = '<option id="sftp-' + item.name + '" value="' + item.name + '">' + item.alias_name + '</option>';
$('#sftp-client-type').append(html);
if (item.current == 1) {
$('#sftp-' + item.name).attr('selected', true);
init_config_param(type, item.build_in, item.path, item.commandline);
g_current_sftp = item.name;
}
g_sftp_config_dict[item.name] = item;
}
} else if(type == 3) {
$('#telnet-client-type').html(html);
for (var i = 0; i < config_list.length; i++) {
var item = config_list[i];
html = '<option id="telnet-' + item.name + '" value="' + item.name + '">' + item.alias_name + '</option>';
$("#telnet-client-type").append(html);
if (item.current == 1) {
$('#telnet-' + item.name).attr('selected', true);
init_config_param(type, item.build_in, item.path, item.commandline);
g_current_telnet = item.name;
}
g_telnet_config_dict[item.name] = item;
}
}
}
var init_config_param = function (type, build_in, path, command_line) {
if (type == 1) {
if (build_in == 1) {
$("#ssh-exec-args").attr("readonly", "readonly");
$("#ssh-select-path").attr("disabled", "disabled");
} else {
$("#ssh-exec-args").removeAttr("readonly");
$("#ssh-select-path").removeAttr("disabled");
}
$("#ssh-exec-path").val(path);
$("#ssh-exec-args").val(command_line);
} else if (type == 2) {
if (build_in == 1) {
$("#sftp-exec-args").attr("readonly", "readonly");
$("#sftp-select-path").attr("disabled", "disabled");
} else {
$("#sftp-exec-args").removeAttr("readonly");
$("#sftp-select-path").removeAttr("disabled");
}
$("#sftp-exec-path").val(path);
$("#sftp-exec-args").val(command_line);
} else if(type == 3) {
if (build_in == 1) {
$("#telnet-exec-args").attr("readonly", "readonly");
$("#telnet-select-path").attr("disabled", "disabled");
} else {
$("#telnet-exec-args").removeAttr("readonly");
$("#telnet-select-path").removeAttr("disabled");
}
$("#telnet-exec-path").val(path);
$("#telnet-exec-args").val(command_line);
}
}
$(document).ready(function () {
get_client_config_list(1);
get_client_config_list(2);
get_client_config_list(3);
$("#ssh-client-type").change(function () {
var i = 0;
var name = $("#ssh-client-type").val();
var item = g_ssh_config_dict[name];
init_config_param(1, item.build_in, item.path, item.commandline);
g_current_ssh = item.name;
});
$("#ssh-select-path").click(function () {
open_exist_file(function (code, path) {
if (code == 0) {
$("#ssh-exec-path").val(path);
} else {
console.log("can not select file.");
}
});
});
$("#ssh-btn-save").click(function () {
var name = $("#ssh-client-type").val();
var path = $("#ssh-exec-path").val();
if (path == "") {
alert("请选择路径");
return;
}
var command_line = $("#ssh-exec-args").val();
if (command_line == "") {
alert("请输入命令行");
return;
}
set_current_client_config(1, name, path, command_line);
});
$("#sftp-client-type").change(function () {
var i = 0;
var name = $("#sftp-client-type").val();
var item = g_sftp_config_dict[name];
init_config_param(2, item.build_in, item.path, item.commandline);
g_current_sftp = item.name;
});
$("#sftp-select-path").click(function () {
open_exist_file(function (code, path) {
if (code == 0) {
$("#sftp-exec-path").val(path);
} else {
console.log("can not select file.");
}
});
});
$("#sftp-btn-save").click(function () {
var name = $("#sftp-client-type").val();
var path = $("#sftp-exec-path").val();
if (path == "") {
alert("请选择路径");
return;
}
var command_line = $("#sftp-exec-args").val();
if (command_line == "") {
alert("请输入命令行");
return;
}
set_current_client_config(2, name, path, command_line);
});
$("#telnet-client-type").change(function () {
var i = 0;
var name = $("#telnet-client-type").val();
var item = g_telnet_config_dict[name];
init_config_param(3, item.build_in, item.path, item.commandline);
g_current_telnet = item.name;
});
$("#telnet-select-path").click(function () {
open_exist_file(function (code, path) {
if (code == 0) {
$("#telnet-exec-path").val(path);
} else {
console.log("can not select file.");
}
});
});
$("#telnet-btn-save").click(function () {
var name = $("#telnet-client-type").val();
var path = $("#telnet-exec-path").val();
if (path == "") {
alert("请选择路径");
return;
}
var command_line = $("#telnet-exec-args").val();
if (command_line == "") {
alert("请输入命令行");
return;
}
set_current_client_config(3, name, path, command_line);
});
});

View File

@ -1,110 +0,0 @@
@charset "utf-8";
@page-bg: #fff;
@page-color: #333;
@toolbar-bg: #d5d5d5;
@header-height: 48px;
@footer-height: 24px;
//@font-family-normal: "Open Sans", "Helvetica Neue", "Microsoft YaHei", "微软雅黑", Helvetica, Arial, sans-serif;
@font-family-normal: "Microsoft YaHei", "微软雅黑", Helvetica, Arial, sans-serif;
@font-family-mono: Consolas, Lucida Console, Monaco, Courier, 'Courier New', monospace;
body {
font-family: @font-family-normal;
font-size: 13px;
background-color: @page-bg;
color: @page-color;
}
html, body {
height: 100%;
}
.header {
width: 100%;
height: @header-height;
position: fixed;
top: 0;
//text-align: center;
line-height: @header-height;
//border-bottom: 1px solid darken(@toolbar-bg, 20%);
font-size: 80%;
background-color: #3b3b3b;
color: #fff;
z-index: 999;
.title {
font-size: 16px;
}
.sub-title {
margin-left:30px;
color: #acacac;
}
}
.header-fix {
height: @header-height;
}
.footer {
width: 100%;
height: @footer-height;
position: fixed;
bottom: 0;
text-align: center;
line-height: @footer-height;
background-color: @toolbar-bg;
border-top: 1px solid darken(@toolbar-bg, 20%);
font-size: 80%;
z-index: 999;
}
.content {
margin: 20px 0 50px 0;
.cfg-title {
font-size: 16px;
font-weight: bold;
}
.form-group {
margin-bottom:5px;
}
.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7 {
padding-left:3px;
padding-right:3px;
}
.arg-detail {
font-size:11px;
ol, ul {
margin-bottom:0;
}
}
.arg-detail-common {
//border:1px solid #f33;
background-color: #dbffbe;
//color:#fff;
border-radius: 5px;
padding:15px;
//margin-bottom:10px;
}
.input-args {
font-family: @font-family-mono;
}
}
.arg-varb {
color:#0a6aa1;
font-weight:bold;
font-family: @font-family-mono;
display:inline-block;
width:128px;
//margin-right:20px;
}

View File

@ -1,244 +0,0 @@
#include "stdafx.h"
//#include "ts_ini.h"
#include "ts_cfg.h"
#include "ts_env.h"
TsCfgSSH g_cfgSSH;
TsCfgScp g_cfgScp;
TsCfgTelnet g_cfgTelnet;
void split_by_char(ex_wstr s, char ch, std::vector<ex_wstr>& ret)
{
int pos;
while (s.length() != 0)
{
pos = s.find_first_of(ch, 0);
if (-1 == pos)
{
ret.push_back(s);
s = s.erase(0, s.length());
}
else if (0 == pos)
{
s = s.erase(0, pos + 1);
}
else
{
ex_wstr temp;
temp.append(s, 0, pos);
ret.push_back(temp);
s = s.erase(0, pos + 1);
}
}
}
//=====================================================================
// Base Configuration Class
//=====================================================================
TsClientCfgBase::TsClientCfgBase()
{
m_clientsetmap.clear();
m_client_list.clear();
}
TsClientCfgBase::~TsClientCfgBase()
{}
bool TsClientCfgBase::_init(void)
{
client_set temp;
ExIniSection* cfg = NULL;
cfg = m_ini.GetSection(_T("common"));
if (NULL == cfg)
{
EXLOGE("[ERROR] Invalid configuration, [common] section not found.\n");
return false;
}
ex_wstr _wstr;
if (!cfg->GetStr(_T("current_client"), _wstr)) {
return false;
}
m_current_client = _wstr;
if (!cfg->GetStr(_T("client_list"), _wstr)) {
return false;
}
std::vector<ex_wstr> c_list;
split_by_char(_wstr, ',', c_list);
std::vector<ex_wstr>::iterator it;
for (it = c_list.begin(); it != c_list.end(); it++)
{
ex_wstr sec_name = it->c_str();
cfg = m_ini.GetSection(sec_name);
if (NULL == cfg)
{
EXLOGE("[ERROR] Invalid configuration, [common] section not found.\n");
return false;
}
if (!cfg->GetStr(_T("name"), _wstr)) {
continue;
}
temp.name = _wstr;
if (!cfg->GetStr(_T("path"), _wstr)) {
continue;
}
temp.path = _wstr;
if (!cfg->GetStr(_T("alias_name"), _wstr)) {
continue;
}
temp.alias_name = _wstr;
if (!cfg->GetStr(_T("command_line"), _wstr)) {
continue;
}
temp.commandline = _wstr;
if (!cfg->GetStr(_T("desc"), _wstr)) {
continue;
}
temp.desc = _wstr;
temp.is_default = false;
m_clientsetmap[temp.name] = temp;
m_client_list.push_back(temp.name);
}
return true;
}
void TsClientCfgBase::set(ex_wstr sec_name, ex_wstr key, ex_wstr value)
{
if (sec_name != _T("common"))
{
clientsetmap::iterator it = m_clientsetmap.find(sec_name);
if (it == m_clientsetmap.end())
return;
}
ExIniSection* cfg = NULL;
cfg = m_ini.GetSection(sec_name);
if (NULL == cfg)
{
EXLOGE("[ERROR] Invalid configuration, [common] section not found.\n");
return;
}
cfg->SetValue(key, value);
return;
}
void TsClientCfgBase::save()
{
m_ini.Save(EX_CODEPAGE_UTF8);
}
//=====================================================
TsCfgSSH::TsCfgSSH()
{}
TsCfgSSH::~TsCfgSSH()
{}
bool TsCfgSSH::init(void)
{
m_current_client = _T("putty");
client_set temp;
temp.name = _T("putty");
temp.alias_name = _T("PuTTY (内置)");
temp.path = g_env.m_tools_path;
temp.path += _T("\\putty\\putty.exe");
temp.commandline = _T("-ssh -pw **** -P {host_port} -l {user_name} {host_ip}");
temp.desc = _T("PuTTY为开放源代码软件主要由Simon Tatham维护使用MIT licence授权。");
temp.is_default = true;
m_clientsetmap[temp.name] = temp;
m_client_list.push_back(temp.name);
if (!m_ini.LoadFromFile(g_env.m_ssh_client_conf_file))
{
EXLOGE("can not load ssh config file.\n");
return false;
}
return _init();
}
//=====================================================
TsCfgScp::TsCfgScp()
{}
TsCfgScp::~TsCfgScp()
{}
bool TsCfgScp::init(void)
{
m_current_client = _T("winscp");
client_set temp;
temp.name = _T("winscp");
temp.alias_name = _T("WinSCP (内置)");
temp.path = g_env.m_tools_path;
temp.path += _T("\\winscp\\winscp.exe");
temp.commandline = _T("/sessionname=\"TP#{real_ip}\" {user_name}:****@{host_ip}:{host_port}");
temp.desc = _T("WinSCP是一个Windows环境下使用SSH的开源图形化SFTP客户端。同时支持SCP协议。它的主要功能就是在本地与远程计算机间安全的复制文件。");
temp.is_default = true;
m_clientsetmap[temp.name] = temp;
m_client_list.push_back(temp.name);
if (!m_ini.LoadFromFile(g_env.m_scp_client_conf_file))
{
EXLOGE("can not load scp config file.\n");
return false;
}
return _init();
}
//=====================================================
TsCfgTelnet::TsCfgTelnet()
{}
TsCfgTelnet::~TsCfgTelnet()
{}
bool TsCfgTelnet::init(void)
{
m_current_client = _T("putty");
client_set temp;
temp.name = _T("putty");
temp.alias_name = _T("PuTTY (内置)");
temp.path = g_env.m_tools_path;
temp.path += _T("\\putty\\putty.exe");
//temp.commandline = _T("-telnet -P {host_port} -l {user_name} {host_ip}");
temp.commandline = _T("telnet://{user_name}@{host_ip}:{host_port}");
temp.desc = _T("PuTTY为开放源代码软件主要由Simon Tatham维护使用MIT licence授权。");
temp.is_default = true;
m_clientsetmap[temp.name] = temp;
m_client_list.push_back(temp.name);
if (!m_ini.LoadFromFile(g_env.m_telnet_client_conf_file))
{
EXLOGE("can not load telnet config file.\n");
return false;
}
return _init();
}

View File

@ -1,71 +0,0 @@
#ifndef __TS_CFG_H__
#define __TS_CFG_H__
#include <ex.h>
#include <vector>
#include <map>
typedef std::vector<ex_wstr> client_list;
struct client_set
{
ex_wstr name;
ex_wstr alias_name;
ex_wstr path;
ex_wstr commandline;
ex_wstr desc;
bool is_default;
};
typedef std::map<ex_wstr, client_set> clientsetmap;
class TsClientCfgBase
{
public:
TsClientCfgBase();
virtual ~TsClientCfgBase();
virtual bool init(void) = 0;
void set(ex_wstr sec_name, ex_wstr key, ex_wstr value);
void save();
client_list m_client_list;
clientsetmap m_clientsetmap;
ex_wstr m_current_client;
protected:
bool _init(void);
protected:
ExIniFile m_ini;
};
class TsCfgSSH : public TsClientCfgBase
{
public:
TsCfgSSH();
~TsCfgSSH();
bool init(void);
};
extern TsCfgSSH g_cfgSSH;
class TsCfgScp : public TsClientCfgBase
{
public:
TsCfgScp();
~TsCfgScp();
bool init(void);
};
extern TsCfgScp g_cfgScp;
class TsCfgTelnet : public TsClientCfgBase
{
public:
TsCfgTelnet();
~TsCfgTelnet();
bool init(void);
};
extern TsCfgTelnet g_cfgTelnet;
#endif // __TS_CFG_H__

View File

@ -1,86 +0,0 @@
#include "stdafx.h"
#include "ts_env.h"
#include <time.h>
#ifdef EX_OS_WIN32
# include <direct.h>
//# include <ShlObj.h>
#endif
TsEnv g_env;
//=======================================================
//
//=======================================================
TsEnv::TsEnv()
{}
TsEnv::~TsEnv()
{}
bool TsEnv::init(void)
{
if (!ex_exec_file(m_exec_file))
return false;
m_exec_path = m_exec_file;
if (!ex_dirname(m_exec_path))
return false;
m_ssh_client_conf_file = m_exec_path;
ex_path_join(m_ssh_client_conf_file, false, L"cfg", L"ssh.ini", NULL);
m_scp_client_conf_file = m_exec_path;
ex_path_join(m_scp_client_conf_file, false, L"cfg", L"scp.ini", NULL);
m_telnet_client_conf_file = m_exec_path;
ex_path_join(m_telnet_client_conf_file, false, L"cfg", L"telnet.ini", NULL);
m_log_path = m_exec_path;
ex_path_join(m_log_path, false, L"log", NULL);
#ifdef _DEBUG
// m_ssh_client_conf_file = m_exec_path;
// ex_path_join(m_ssh_client_conf_file, false, L"ssh.ini", NULL);
//
// m_scp_client_conf_file = m_exec_path;
// ex_path_join(m_scp_client_conf_file, false, L"scp.ini", NULL);
//
// m_telnet_client_conf_file = m_exec_path;
// ex_path_join(m_telnet_client_conf_file, false, L"telnet.ini", NULL);
//
// m_log_path = m_exec_path;
// ex_path_join(m_log_path, false, L"log", NULL);
m_site_path = m_exec_path;
ex_path_join(m_site_path, true, L"..", L"..", L"..", L"..", L"client", L"tp_assist", L"site", NULL);
m_tools_path = m_exec_path;
ex_path_join(m_tools_path, true, L"..", L"..", L"..", L"..", L"client", L"tools", NULL);
#else
// TCHAR szBuf[PATH_MAX] = { 0 };
// SHGetSpecialFolderPathW(NULL, szBuf, CSIDL_APPDATA, FALSE);
//
// m_ssh_client_conf_file = szBuf;// m_exec_path;
// ex_path_join(m_ssh_client_conf_file, false, L"eomsoft", L"teleport", L"assist", L"cfg", L"ssh.ini", NULL);
//
// m_scp_client_conf_file = szBuf;// m_exec_path;
// ex_path_join(m_scp_client_conf_file, false, L"eomsoft", L"teleport", L"assist", L"cfg", L"scp.ini", NULL);
//
// m_telnet_client_conf_file = szBuf;// m_exec_path;
// ex_path_join(m_telnet_client_conf_file, false, L"eomsoft", L"teleport", L"assist", L"cfg", L"telnet.ini", NULL);
//
// m_log_path = szBuf;// m_exec_path;
// ex_path_join(m_log_path, false, L"eomsoft", L"teleport", L"assist", L"log", NULL);
m_site_path = m_exec_path;
ex_path_join(m_site_path, false, L"site", NULL);
m_tools_path = m_exec_path;
ex_path_join(m_tools_path, false, L"tools", NULL);
#endif
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
#!/bin/bash
PATH_ROOT=$(cd "$(dirname "$0")/.."; pwd)
echo "compiling applescripts for OS X terminal..."
rm ${PATH_ROOT}/src/apple-scpt/Terminal.scpt
rm ${PATH_ROOT}/src/apple-scpt/iTerm2.scpt
osacompile -o ${PATH_ROOT}/src/apple-scpt/Terminal.scpt -x ${PATH_ROOT}/apple-scripts/scripts/Terminal.applescript
osacompile -o ${PATH_ROOT}/src/apple-scpt/iTerm2.scpt -x ${PATH_ROOT}/apple-scripts/scripts/iTerm2.applescript

View File

@ -0,0 +1,44 @@
on scriptRun(argsCmd, argsProfile, argsTitle)
set theCmd to (argsCmd)
set theProfile to (argsProfile)
set theTitle to (argsTitle)
CommandRun(theCmd, theProfile, theTitle)
end scriptRun
on CommandRun(theCmd, theProfile, theTitle)
tell application "Terminal"
if it is not running then
--if this is the first time Terminal is running you have specify window 1
--if you dont do this you will get two windows and the title wont be set
activate
set newTerm to do script theCmd in window 1
set newTerm's current settings to settings set theProfile
set custom title of front window to theTitle
else
--Terminal is running get the window count
set windowCount to (count every window)
if windowCount = 0 then
--Terminal is running but no windows are open
--run our script in a new window
reopen
activate
do script theCmd in window 1
else
--Terminal is running and we have a window run in a new tab
reopen
activate
tell application "System Events"
tell process "Terminal"
delay 0.2
keystroke "t" using {command down}
end tell
end tell
activate
do script theCmd in front window
end if
set current settings of selected tab of front window to settings set theProfile
set title displays custom title of front window to true
set custom title of selected tab of front window to theTitle
end if
end tell
end CommandRun

View File

@ -0,0 +1,70 @@
on scriptRun(argsCmd, argsProfile, argsTitle)
set theCmd to (argsCmd)
set theProfile to (argsProfile)
set theTitle to (argsTitle)
CommandRun(theCmd, theProfile, theTitle)
end scriptRun
on CommandRun(theCmd, theProfile, theTitle)
tell application "iTerm"
if it is not running then
tell application "iTerm"
activate
delay 0.2
try
close first window
end try
end tell
tell application "iTerm"
try
create window with profile theProfile
on error msg
create window with profile "Default"
end try
tell the current window
tell the current session
set name to theTitle
set profile to theProfile
write text theCmd
end tell
end tell
end tell
else
--assume that iTerm is open and open a new tab
try
tell application "iTerm"
activate
tell the current window
try
create tab with profile theProfile
on error msg
create tab with profile "Default"
end try
tell the current tab
tell the current session
set name to theTitle
write text theCmd
end tell
end tell
end tell
end tell
on error msg
--if all iTerm windows are closed the app stays open. In this scenario iTerm has no "current window" and will give an error when trying to create the new tab.
tell application "iTerm"
try
create window with profile theProfile
on error msg
create window with profile "Default"
end try
tell the current window
tell the current session
set name to theTitle
write text theCmd
end tell
end tell
end tell
end try
end if
end tell
end CommandRun

View File

@ -0,0 +1 @@
@charset "utf-8";body{font-family:"Microsoft YaHei","微软雅黑",Helvetica,Arial,sans-serif;font-size:13px;background-color:#fff;color:#333}html,body{height:100%}.header{width:100%;height:48px;position:fixed;top:0;line-height:48px;font-size:80%;background-color:#3b3b3b;color:#fff;z-index:999}.header .title{font-size:16px}.header .sub-title{margin-left:30px;color:#acacac}.header-fix{height:48px}.footer{width:100%;height:24px;position:fixed;bottom:0;text-align:center;line-height:24px;background-color:#d5d5d5;border-top:1px solid #a2a2a2;font-size:80%;z-index:999}.content{margin:20px 0 50px 0}.content .cfg-title{font-size:16px;font-weight:bold}.content .form-group{margin-bottom:5px}.content .col-sm-1,.content .col-sm-2,.content .col-sm-3,.content .col-sm-4,.content .col-sm-5,.content .col-sm-6,.content .col-sm-7,.content .col-sm-8,.content .col-sm-9,.content .col-sm-10,.content .col-sm-11,.content .col-sm-12{padding-left:3px;padding-right:3px}.content .arg-detail{font-size:11px}.content .arg-detail ol,.content .arg-detail ul{margin-bottom:0}.content .desc{display:inline-block;margin-top:5px;color:#6b6b6b}.content .arg-detail-common{background-color:#dbffbe;border-radius:5px;padding:15px}.content .input-args{font-family:Consolas,Lucida Console,Monaco,Courier,'Courier New',monospace}.arg-varb{color:#0a6aa1;font-weight:bold;font-family:Consolas,Lucida Console,Monaco,Courier,'Courier New',monospace;display:inline-block;width:128px}#gritter-notice-wrapper{z-index:9999}.gritter-bottom,.gritter-item,.gritter-top{background:rgba(0,0,0,0.8) !important}.gritter-top{border-top-left-radius:3px;border-top-right-radius:3px}.gritter-bottom{border-bottom-left-radius:3px;border-bottom-right-radius:3px}.gritter-close,.gritter-light .gritter-close{left:auto !important;right:5px !important;top:5px !important;width:16px !important;height:16px !important;line-height:16px !important;display:block !important;border-radius:50%}.gritter-close:before,.gritter-light .gritter-close:before{content:'\f00d' !important;font-family:FontAwesome !important;font-size:9px !important;width:16px !important;height:16px !important;line-height:16px !important;color:#fff !important;text-indent:0 !important;position:absolute !important;text-align:center !important;right:0 !important;top:0 !important}.gritter-title{font-size:13px !important;line-height:16px !important;padding-bottom:5px !important;font-weight:400 !important;color:#fff !important;text-shadow:none !important}.gritter-item{color:#aaa !important;font-size:13px !important;padding:2px 15px 5px !important}.gritter-error .gritter-bottom,.gritter-error .gritter-item,.gritter-error .gritter-top{background:rgba(123,32,32,0.9) !important}.gritter-error .gritter-title{color:#fff !important}.gritter-error .gritter-item{color:#ddd !important}.gritter-error .gritter-close{left:auto !important;right:5px !important;top:5px !important;width:16px !important;height:16px !important;line-height:16px !important;display:block !important;border-radius:50%;background:#e33b3b !important}.gritter-success .gritter-bottom,.gritter-success .gritter-item,.gritter-success .gritter-top{background:rgba(1,65,16,0.9) !important}.gritter-success .gritter-title{color:#ddd !important}.gritter-success .gritter-item{color:#ccc !important}.gritter-success .gritter-close{background:#0eb320 !important}#gritter-notice-wrapper{width:320px;max-width:480px}/*# sourceMappingURL=style.css.map */

View File

@ -0,0 +1 @@
{"version":3,"sources":["style.less"],"names":[],"mappings":"AAAA,SAAS,QAaT,KACE,YAJmB,kBAAmB,iCAItC,CACA,cAAA,CACA,qBAAA,CACA,WAGF,KAAM,KACJ,YAGF,QACE,UAAA,CACA,WAAA,CACA,cAAA,CACA,KAAA,CAEA,gBAAA,CAEA,aAAA,CAEA,wBAAA,CACA,UAAA,CACA,YAZF,OAcE,QACE,eAfJ,OAiBE,YACE,gBAAA,CACA,cAIJ,YACE,YAGF,QACE,UAAA,CACA,WAAA,CACA,cAAA,CACA,QAAA,CACA,iBAAA,CACA,gBAAA,CACA,wBAAA,CACA,4BAAA,CACA,aAAA,CACA,YAGF,SACE,qBADF,QAGE,YACE,cAAA,CACA,iBALJ,QAQE,aACE,kBATJ,QAYE,WAZF,QAYa,WAZb,QAYwB,WAZxB,QAYmC,WAZnC,QAY8C,WAZ9C,QAYyD,WAZzD,QAYoE,WAZpE,QAY+E,WAZ/E,QAY0F,WAZ1F,QAYqG,YAZrG,QAYiH,YAZjH,QAY6H,YACzH,gBAAA,CACA,kBAdJ,QAiBE,aACE,eAlBJ,QAiBE,YAEE,IAnBJ,QAiBE,YAEM,IACF,gBApBN,QAwBE,OACE,oBAAA,CACA,cAAA,CACA,cA3BJ,QA8BE,oBAEE,wBAAA,CAEA,iBAAA,CACA,aAnCJ,QAuCE,aACE,mDA7F0D,wBAiG9D,UACE,aAAA,CACA,gBAAA,CACA,mDApG4D,uBAoG5D,CACA,oBAAA,CACA,YAiBF,wBAKE,aAGF,gBAAiB,cAAe,aAE9B,0BAAA,YAGF,aACE,0BAAA,CACA,4BAGF,gBACE,6BAAA,CACA,+BAGF,eAAgB,cAAe,gBAU7B,SAAA,YACA,SAAA,YACA,OAAA,YACA,UAAA,YACA,WAAA,YACA,gBAAA,YACA,aAAA,YACA,kBAGF,cAAc,QAAS,cAAe,eAAc,QAClD,QAAS,OAAT,YACA,uBAAA,YACA,aAAA,YACA,UAAA,YACA,WAAA,YACA,gBAAA,YACA,UAAA,YACA,aAAA,YACA,iBAAA,YACA,iBAAA,YACA,OAAA,YACA,KAAA,YAcF,eACE,cAAA,YACA,gBAAA,YACA,kBAAA,YACA,eAAA,YACA,UAAA,YACA,gBAAA,YAQF,cAEE,UAAA,YACA,cAAA,YACA,oBAAA,YAGF,cACE,iBADF,cACmB,eADnB,cACkC,cAC9B,8BAAA,YAFJ,cAKE,gBACE,UAAA,YANJ,cASE,eACE,UAAA,YAVJ,cAaE,gBACE,SAAA,YACA,SAAA,YACA,OAAA,YACA,UAAA,YACA,WAAA,YACA,gBAAA,YACA,aAAA,YACA,iBAAA,CACA,kBAAA,YAIJ,gBACE,iBADF,gBACmB,eADnB,gBACkC,cAE9B,4BAAA,YAHJ,gBAME,gBAEE,UAAA,YARJ,gBAWE,eAEE,UAAA,YAbJ,gBAgBE,gBACE,kBAAA,YAKJ,wBACE,WAAA,CAEA","file":"style.css","sourceRoot":"../less"}

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,105 @@
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="utf-8"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>TELEPORT助手配置</title>
<link rel="shortcut icon" href="favicon.png">
<link href="plugins/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
<link href="plugins/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<link href="plugins/gritter/css/jquery.gritter.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div class="header">
<div class="container">
<span class="title"><i class="fa fa-cog fa-fw"></i> Teleport助手本地配置</span>
<span class="sub-title">此处配置保存到本地计算机上,如果更换计算机,需要重新配置!</span>
</div>
</div>
<div class="header-fix"></div>
<div class="footer">
<div class="container">
<p><a href="http://www.tp4a.com/" target="_blank">TELEPORT</a> | &copy;2015 - 2018保留所有权利。</p>
</div>
</div>
<div class="container">
<div class="content">
<hr/>
<p class="cfg-title">本地终端配置用于SSH</p>
<div class="form-horizontal">
<div class="form-group form-group-sm">
<label for="term-type" class="col-sm-1 control-label"><strong>终端:</strong></label>
<div class="col-sm-3">
<select id="term-type" class="form-control"></select>
</div>
</div>
<div class="form-group form-group-sm">
<label for="term-profile" class="col-sm-1 control-label"><strong>使用配置:</strong></label>
<div class="col-sm-3">
<input id="term-profile" type="text" class="form-control input-args"/>
</div>
</div>
</div>
<hr/>
<p class="cfg-title">本地RDP配置</p>
<div class="form-horizontal">
<div class="form-group form-group-sm">
<label for="rdp-type" class="col-sm-1 control-label"><strong>RDP客户端</strong></label>
<div class="col-sm-3">
<select id="rdp-type" class="form-control"></select>
</div>
</div>
<div class="form-group form-group-sm">
<label for="rdp-app" class="col-sm-1 control-label"><strong>程序路径:</strong></label>
<div class="col-sm-8">
<input id="rdp-app" type="text" class="form-control input-args"/>
<span class="desc"><i class="fa fa-info-circle"></i> 建议使用homebrew安装freerdp安装后freerdp默认路径在/usr/local/Cellar/freerdp/x.y.z/bin/xfreerdp</span>
</div>
</div>
</div>
<hr/>
<div class="form-horizontal">
<div class="form-group form-group-sm">
<div class="col-sm-1"></div>
<div class="col-sm-3">
<a id="btn-save" class="btn btn-primary" href="javascript:;"><i class="fa fa-check fa-fw"></i> 保存设置</a>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="plugins/underscore/underscore-min.js"></script>
<script type="text/javascript" src="plugins/jquery/jquery.min.js"></script>
<script type="text/javascript" src="plugins/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="plugins/gritter/js/jquery.gritter.js"></script>
<script type="text/javascript" src="plugins/keypress/keypress.min.js"></script>
<script type="text/javascript" src="js/config.js"></script>
<script type="text/javascript">
</script>
</body>
</html>

View File

@ -0,0 +1,205 @@
"use strict";
var g_url_base = 'http://127.0.0.1:50022';
var g_cfg = null;
var dom = {
term_type: $('#term-type'),
term_profile: $('#term-profile'),
rdp_type: $('#rdp-type'),
rdp_app: $('#rdp-app'),
btn_save: $('#btn-save')
};
var get_config = function () {
$.ajax({
type: 'GET',
timeout: 5000,
url: g_url_base + '/api/get_config',
jsonp: 'callback',
dataType: 'json',
success: function (ret) {
if (ret.code == 0) {
g_cfg = ret.data;
update_dom();
} else {
notify_error("获取配置信息失败!");
}
},
error: function (jqXhr, _error, _e) {
console.log('state:', jqXhr.state());
notify_error("获取配置信息失败!");
}
});
}
function update_dom() {
console.log('---', g_cfg);
dom.term_type.html('');
if (!_.isUndefined(g_cfg.term)) {
if (_.isUndefined(g_cfg.term.selected)) {
g_cfg.term.selected = '';
}
if (!_.isUndefined(g_cfg.term.available) && g_cfg.term.available.length > 0) {
var selected = '';
var profile = '';
var html = [];
for (var i = 0; i < g_cfg.term.available.length; i++) {
var item = g_cfg.term.available[i];
if (selected === '' || item.name === g_cfg.term.selected) {
selected = item.name;
profile = item.profile;
}
html.push('<option id="term-' + item.name + '" value="' + item.name + '">' + item.display + '</option>');
}
dom.term_type.html(html.join(''));
dom.term_type.val(selected);
dom.term_profile.val(profile);
}
}
if (!_.isUndefined(g_cfg.rdp)) {
if (_.isUndefined(g_cfg.rdp.selected)) {
g_cfg.rdp.selected = '';
}
if (!_.isUndefined(g_cfg.rdp.available) && g_cfg.rdp.available.length > 0) {
var selected = '';
var app = '';
var html = [];
for (var i = 0; i < g_cfg.rdp.available.length; i++) {
var item = g_cfg.rdp.available[i];
if (selected === '' || item.name === g_cfg.rdp.selected) {
selected = item.name;
app = item.app;
}
html.push('<option id="rdp-' + item.name + '" value="' + item.name + '">' + item.display + '</option>');
}
dom.rdp_type.html(html.join(''));
dom.rdp_type.val(selected);
dom.rdp_app.val(app);
}
}
}
function on_term_change() {
g_cfg.term.selected = dom.term_type.val();
for (var i = 0; i < g_cfg.term.available.length; i++) {
var item = g_cfg.term.available[i];
if (item.name === g_cfg.term.selected) {
dom.term_profile.val(item.profile);
return;
}
}
notify_error('所选的终端配置项并不存在!');
}
function on_rdp_change() {
g_cfg.rdp.selected = dom.rdp_type.val();
for (var i = 0; i < g_cfg.rdp.available.length; i++) {
var item = g_cfg.rdp.available[i];
if (item.name === g_cfg.rdp.selected) {
dom.rdp_app.val(item.app);
return;
}
}
notify_error('所选的RDP配置项并不存在');
}
function on_save() {
if (g_cfg === null)
return;
for (var i = 0; i < g_cfg.term.available.length; i++) {
var item = g_cfg.term.available[i];
if (item.name === g_cfg.term.selected) {
item.profile = dom.term_profile.val();
break;
}
}
for (var i = 0; i < g_cfg.rdp.available.length; i++) {
var item = g_cfg.rdp.available[i];
if (item.name === g_cfg.rdp.selected) {
item.app = dom.rdp_app.val();
break;
}
}
var args_ = encodeURIComponent(JSON.stringify(g_cfg));
$.ajax({
type: 'GET',
timeout: 5000,
url: g_url_base + '/api/set_config/' + args_,
jsonp: 'callback',
dataType: 'json',
success: function (ret) {
if (ret.code == 0) {
notify_success('设置保存成功!');
} else {
notify_error('设置保存失败!' + ret.code);
}
},
error: function () {
notify_error('网络故障,设置保存失败');
}
});
}
function notify_error(message_, title_) {
var _title = title_ || '';
$.gritter.add({
class_name: 'gritter-error',
time: 10000,
title: '<i class="fa fa-warning fa-fw"></i> 错误:' + _title,
text: message_
});
console.error('错误', _title, message_);
};
function notify_success(message_, title_) {
var _title = title_ || null;
if (_title !== null)
_title = '<i class="fa fa-check-square fa-fw"></i> ' + _title;
$.gritter.add({
class_name: 'gritter-success',
time: 5000,
title: _title,
text: message_
});
};
$(document).ready(function () {
get_config();
dom.term_type.change(function () {
on_term_change();
});
dom.rdp_type.change(function () {
on_rdp_change();
});
dom.btn_save.click(function () {
on_save();
});
});

View File

@ -0,0 +1,273 @@
@charset "utf-8";
@page-bg: #fff;
@page-color: #333;
@toolbar-bg: #d5d5d5;
@header-height: 48px;
@footer-height: 24px;
//@font-family-normal: "Open Sans", "Helvetica Neue", "Microsoft YaHei", "微软雅黑", Helvetica, Arial, sans-serif;
@font-family-normal: "Microsoft YaHei", "微软雅黑", Helvetica, Arial, sans-serif;
@font-family-mono: Consolas, Lucida Console, Monaco, Courier, 'Courier New', monospace;
body {
font-family: @font-family-normal;
font-size: 13px;
background-color: @page-bg;
color: @page-color;
}
html, body {
height: 100%;
}
.header {
width: 100%;
height: @header-height;
position: fixed;
top: 0;
//text-align: center;
line-height: @header-height;
//border-bottom: 1px solid darken(@toolbar-bg, 20%);
font-size: 80%;
background-color: #3b3b3b;
color: #fff;
z-index: 999;
.title {
font-size: 16px;
}
.sub-title {
margin-left: 30px;
color: #acacac;
}
}
.header-fix {
height: @header-height;
}
.footer {
width: 100%;
height: @footer-height;
position: fixed;
bottom: 0;
text-align: center;
line-height: @footer-height;
background-color: @toolbar-bg;
border-top: 1px solid darken(@toolbar-bg, 20%);
font-size: 80%;
z-index: 999;
}
.content {
margin: 20px 0 50px 0;
.cfg-title {
font-size: 16px;
font-weight: bold;
}
.form-group {
margin-bottom: 5px;
}
.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
padding-left: 3px;
padding-right: 3px;
}
.arg-detail {
font-size: 11px;
ol, ul {
margin-bottom: 0;
}
}
.desc {
display:inline-block;
margin-top:5px;
color:rgb(107, 107, 107);
}
.arg-detail-common {
//border:1px solid #f33;
background-color: #dbffbe;
//color:#fff;
border-radius: 5px;
padding: 15px;
//margin-bottom:10px;
}
.input-args {
font-family: @font-family-mono;
}
}
.arg-varb {
color: #0a6aa1;
font-weight: bold;
font-family: @font-family-mono;
display: inline-block;
width: 128px;
//margin-right:20px;
}
// gritter
//========================================================
// 浮动式提示框(页面右上角浮动显示,可自动消失)
//========================================================
// .gritter-item-wrapper {
// background:0 0!important;
// // -webkit-border-radius:3px!important;
// // -moz-border-radius:3px!important;
// border-radius:3px;
// }
#gritter-notice-wrapper {
//position: fixed;
//top: 20px;
//right: 20px;
//width: 420px;
z-index: 9999;
}
.gritter-bottom, .gritter-item, .gritter-top {
// background:url(../img/transparent/black-0.8.png)!important;
background: rgba(0, 0, 0, .8) !important;
}
.gritter-top {
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
.gritter-bottom {
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
}
.gritter-close, .gritter-light .gritter-close {
//left: auto !important;
//right: 15px !important;
//top: 0 !important;
//background: #ff7370 !important;
//width: 16px !important;
//height: 16px !important;
//line-height: 16px !important;
//display: block !important;
left: auto !important;
right: 5px !important;
top: 5px !important;
width: 16px !important;
height: 16px !important;
line-height: 16px !important;
display: block !important;
border-radius: 50%;
}
.gritter-close:before, .gritter-light .gritter-close:before {
content: '\f00d' !important;
font-family: FontAwesome !important;
font-size: 9px !important;
width: 16px !important;
height: 16px !important;
line-height: 16px !important;
color: #fff !important;
text-indent: 0 !important;
position: absolute !important;
text-align: center !important;
right: 0 !important;
top: 0 !important;
}
//.gritter-with-image {
// width: 210px !important;
//}
//
//.gritter-image {
// margin: 2px 10px 0 0 !important;
// -webkit-border-radius: 2px;
// -moz-border-radius: 2px;
// border-radius: 2px;
//}
.gritter-title {
font-size: 13px !important;
line-height: 16px !important;
padding-bottom: 5px !important;
font-weight: 400 !important;
color: #fff !important;
text-shadow: none !important;
}
// .gritter-light .gritter-title {
// color:#333!important;
// font-weight:600!important;
// }
.gritter-item {
// font-family:'Open Sans'!important;
color: #aaa !important;
font-size: 13px !important;
padding: 2px 15px 5px !important;
}
.gritter-error {
.gritter-bottom, .gritter-item, .gritter-top {
background: rgba(123, 32, 32, .9) !important;
}
.gritter-title {
color: #fff !important;
}
.gritter-item {
color: #ddd !important;
}
.gritter-close {
left: auto !important;
right: 5px !important;
top: 5px !important;
width: 16px !important;
height: 16px !important;
line-height: 16px !important;
display: block !important;
border-radius: 50%;
background: #e33b3b !important;
}
}
.gritter-success {
.gritter-bottom, .gritter-item, .gritter-top {
//background: rgba(32, 123, 32, .9) !important;
background: rgba(1, 65, 16, 0.9) !important;
}
.gritter-title {
//color: #fff !important;
color: #ddd !important;
}
.gritter-item {
//color: #ddd !important;
color: #ccc !important;
}
.gritter-close {
background: #0eb320 !important;
}
}
#gritter-notice-wrapper {
width: 320px;
//width:auto;
max-width: 480px;
}

View File

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -0,0 +1,20 @@
//
// AboutWindowController.h
// TPAssist
//
// Created by ApexLiu at 2017-09-13.
//
#import <Cocoa/Cocoa.h>
@interface AboutWindowController : NSWindowController
@property (strong) NSWindowController *aboutWindow;
@property (strong) IBOutlet NSTextField *appName;
@property (strong) IBOutlet NSTextField *appVersion;
@property (strong) IBOutlet NSTextField *appCopyright;
- (IBAction)btnHomepage:(id)sender;
@end

View File

@ -0,0 +1,78 @@
//
// AboutWindowController.m
// TPAssist
//
// Created by ApexLiu at 2017-09-13.
//
#import "AboutWindowController.h"
@interface AboutWindowController ()
@end
@implementation AboutWindowController
@synthesize aboutWindow;
@synthesize appName;
@synthesize appVersion;
@synthesize appCopyright;
NSDictionary *plistDict;
- (id)initWithWindow:(NSWindow *)window
{
aboutWindow = [super initWithWindow:window];
if (self) {
// Initialization code here.
}
return self;
}
- (void)windowDidLoad
{
[super windowDidLoad];
//Prevent the window from changing positions after multiple opens.
[aboutWindow setShouldCascadeWindows:NO];
//Load the plist so we can get current info for the about box.
plistDict = [[NSBundle mainBundle] infoDictionary];
//Get the application name.
id applicationName = [plistDict objectForKey:@"CFBundleName"];
//Get the build version.
id applicationVersion = [plistDict objectForKey:@"CFBundleVersion"];
//Get the copyright.
id applicationCopyright = [plistDict objectForKey:@"NSHumanReadableCopyright"];
//Build the string for the windows title.
NSString *aboutTitle = [NSString stringWithFormat:@"%@%@", NSLocalizedString(@"About ",nil), applicationName];
[aboutWindow.window setTitle:aboutTitle];
//Build the string for the application name. appName - tagline
NSString *progName = [NSString stringWithFormat:@"%@", NSLocalizedString(@"Teleport Assist",nil)];
[appName setStringValue:progName];
//Build the string for the version. Version: $build
NSString *progVersion = [NSString stringWithFormat:@"%@", applicationVersion];
[appVersion setStringValue:progVersion];
//Make the copyright font smaller.
// [appCopyright setFont:[NSFont systemFontOfSize:10]];
[appCopyright setStringValue:applicationCopyright];
}
- (IBAction)btnHomepage:(id)sender {
//Get the homepage from the plist
id applicationHomepage = [plistDict objectForKey:@"Product Homepage"];
//Build the homepage's URL.
NSURL *homeURL = [NSURL URLWithString:applicationHomepage];
//Go to the website.
[[NSWorkspace sharedWorkspace] openURL:homeURL];
//Close the about box.
[aboutWindow close];
}
@end

View File

@ -0,0 +1,24 @@
//
// AppDelegate-C-Interface.cpp
// tp_assist
//
// Created by ApexLiu on 2017/9/29.
// Copyright © 2017年 eomsoft. All rights reserved.
//
#include "AppDelegate-C-Interface.h"
#include "csrc/ts_env.h"
#include "csrc/ts_cfg.h"
#include "csrc/ts_http_rpc.h"
int cpp_main(void* _self, const char* cfg_file, const char* res_path) {
if(!g_env.init(cfg_file, res_path))
return -1;
if(!g_cfg.init())
return -2;
if(0 != http_rpc_start(_self))
return -3;
return 0;
}

View File

@ -0,0 +1,17 @@
//
// wrap_c_objc.h
// tp_assist
//
// Created by ApexLiu on 2017/9/27.
// Copyright © 2017年 eomsoft. All rights reserved.
//
#ifndef wrap_c_objc_h
#define wrap_c_objc_h
int AppDelegate_start_ssh_client (void *_self, const char* cmd_line, const char* term_type, const char* term_theme, const char* term_title);
// for cpp global object initialize.
int cpp_main(void* _self, const char* cfg_file, const char* res_path);
#endif /* wrap_c_objc_h */

View File

@ -0,0 +1,20 @@
//
// AppDelegate.h
// TPAssist
//
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate, NSMenuDelegate>{
IBOutlet NSMenu *menu;
IBOutlet NSArrayController *arrayController;
NSImage *regularIcon;
NSImage *altIcon;
NSStatusItem *statusItem;
}
- (int) start_ssh_client:(NSString*)cmd_line termType:(NSString*)term_type termTheme:(NSString*)term_theme termTitle:(NSString*)term_title;
@end

View File

@ -0,0 +1,199 @@
//
// AppDelegate.m
// TPAssist
//
// Object-C与标准C/C++混合编程
// http://www.cppblog.com/zhangyuntaoshe/articles/123138.html
/*
//stringWithUTF8String:
//Returns a string created by copying the data from a given C array of UTF8-encoded bytes.
cout<<"从string转成NSString:";
NSLog( [NSString stringWithUTF8String:str.c_str()] );
//cocoa Foundational NSString使用:
NSString *istr=[NSString stringWithString:@"english and 中文"];
str=[istr cStringUsingEncoding: NSUTF8StringEncoding];
cout<<"从NSString转成string: "<<str<<endl;
*/
#import "AppDelegate.h"
#import "AboutWindowController.h"
#include "AppDelegate-C-Interface.h"
#include "csrc/ts_http_rpc.h"
@implementation AppDelegate
int AppDelegate_start_ssh_client (void *_self, const char* cmd_line, const char* term_type, const char* term_theme, const char* term_title) {
NSString* cmdLine = [NSString stringWithUTF8String:cmd_line];
NSString* termType = [NSString stringWithUTF8String:term_type];
NSString* termTheme = [NSString stringWithUTF8String:term_theme];
NSString* termTitle = [NSString stringWithUTF8String:term_title];
return [(__bridge id)_self start_ssh_client:cmdLine termType:termType termTheme:termTheme termTitle:termTitle];
}
- (void) awakeFromNib {
// The path for the configuration file (by default: ~/.tp_assist.ini)
NSString *cfgFile = [NSHomeDirectory() stringByAppendingPathComponent:@".tp-assist.json"];
// if the config file does not exist, create a default one
if ( ![[NSFileManager defaultManager] fileExistsAtPath:cfgFile] ) {
NSString *cfgFileInResource = [[NSBundle mainBundle] pathForResource:@"tp-assist.default" ofType:@"json"];
[[NSFileManager defaultManager] copyItemAtPath:cfgFileInResource toPath:cfgFile error:nil];
}
// Define Icons
//only regular icon is needed for 10.10 and higher. OS X changes the icon for us.
regularIcon = [NSImage imageNamed:@"StatusIcon"];
altIcon = [NSImage imageNamed:@"StatusIconAlt"];
// TODO: 现在statusIcon有两个问题
// 1. 不会响应系统设置“暗色菜单栏和Dock”的事件
// 2. 即使是设置为暗色系,启动本程序也会使用黑色图标,导致在菜单栏中看不到图标。
// 因此,应该响应系统的设置菜单栏颜色的事件,同时启动前先获取菜单栏的色系。
// Create the status bar item
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
[statusItem setMenu:menu];
[statusItem setImage: regularIcon];
[statusItem setHighlightMode:YES];
[statusItem setAlternateImage: altIcon];
// Needed to trigger the menuWillOpen event
[menu setDelegate:self];
//http_rpc_start((__bridge void*)self);
NSString *resPath = [[NSBundle mainBundle] resourcePath];
std::string cpp_res_path = [resPath cStringUsingEncoding:NSUTF8StringEncoding];
std::string cpp_cfg_file = [cfgFile cStringUsingEncoding:NSUTF8StringEncoding];
int ret = cpp_main((__bridge void*)self, cpp_cfg_file.c_str(), cpp_res_path.c_str());
if(ret != 0) {
// TODO: show error message and exit.
NSString *msg = Nil;
if(ret == -1)
msg = @"初始化运行环境失败!";
else if(ret == -2)
msg = @"加载配置文件失败!";
else if(ret == -3)
msg = @"启动本地通讯端口失败请检查本地50022端口是否被占用";
NSAlert *alert = [NSAlert alertWithMessageText:@"无法启动Teleport助手"
defaultButton:@"确定"
alternateButton:Nil
otherButton:Nil
informativeTextWithFormat:msg];
[alert runModal];
http_rpc_stop();
[[NSStatusBar systemStatusBar] removeStatusItem:statusItem];
[NSApp terminate:NSApp]; }
}
- (int) start_ssh_client:(NSString*)cmd_line termType:(NSString*)term_type termTheme:(NSString*)term_theme termTitle:(NSString*)term_title {
NSString *term = [[NSBundle mainBundle] pathForResource:term_type ofType:@"scpt"];
if(!term)
return 1;
NSString *handlerName = @"scriptRun";
NSArray *passParameters = @[cmd_line, term_theme, term_title];
[self runScript:term handler:handlerName parameters:passParameters];
return 0;
}
- (void) runScript:(NSString *)scriptPath handler:(NSString*)handlerName parameters:(NSArray*)parametersInArray {
NSAppleScript * appleScript;
NSAppleEventDescriptor * thisApplication, *containerEvent;
NSURL * pathURL = [NSURL fileURLWithPath:scriptPath];
NSDictionary * appleScriptCreationError = nil;
appleScript = [[NSAppleScript alloc] initWithContentsOfURL:pathURL error:&appleScriptCreationError];
if (handlerName && [handlerName length])
{
/* If we have a handlerName (and potentially parameters), we build
* an NSAppleEvent to execute the script. */
//Get a descriptor
int pid = [[NSProcessInfo processInfo] processIdentifier];
thisApplication = [NSAppleEventDescriptor descriptorWithDescriptorType:typeKernelProcessID
bytes:&pid
length:sizeof(pid)];
//Create the container event
//We need these constants from the Carbon OpenScripting framework, but we don't actually need Carbon.framework...
#define kASAppleScriptSuite 'ascr'
#define kASSubroutineEvent 'psbr'
#define keyASSubroutineName 'snam'
containerEvent = [NSAppleEventDescriptor appleEventWithEventClass:kASAppleScriptSuite
eventID:kASSubroutineEvent
targetDescriptor:thisApplication
returnID:kAutoGenerateReturnID
transactionID:kAnyTransactionID];
//Set the target handler
[containerEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithString:handlerName]
forKeyword:keyASSubroutineName];
//Pass parameters - parameters is expecting an NSArray with only NSString objects
if ([parametersInArray count])
{
NSAppleEventDescriptor *arguments = [[NSAppleEventDescriptor alloc] initListDescriptor];
NSString *object;
for (object in parametersInArray) {
[arguments insertDescriptor:[NSAppleEventDescriptor descriptorWithString:object]
atIndex:([arguments numberOfItems] +1)];
}
[containerEvent setParamDescriptor:arguments forKeyword:keyDirectObject];
}
//Execute the event
[appleScript executeAppleEvent:containerEvent error:nil];
}
}
- (IBAction)visitWebsite:(id)sender {
NSURL *url = [NSURL URLWithString:@"http://www.tp4a.com/"];
[[NSWorkspace sharedWorkspace] openURL:url];
}
- (IBAction)configure:(id)sender {
NSURL *configURL = [NSURL URLWithString:@"http://127.0.0.1:50022/config"];
[[NSWorkspace sharedWorkspace] openURL:configURL];
}
- (IBAction)showAbout:(id)sender {
//Call the windows controller
AboutWindowController *aboutWindow = [[AboutWindowController alloc] initWithWindowNibName:@"AboutWindowController"];
//Set the window to stay on top
[aboutWindow.window makeKeyAndOrderFront:nil];
[aboutWindow.window setLevel:NSFloatingWindowLevel];
//Show the window
[aboutWindow showWindow:self];
}
- (IBAction)quit:(id)sender {
http_rpc_stop();
[[NSStatusBar systemStatusBar] removeStatusItem:statusItem];
[NSApp terminate:NSApp];
}
@end

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13196" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13196"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="AboutWindowController">
<connections>
<outlet property="appCopyright" destination="rfT-bT-B7g" id="9uI-a1-vwK"/>
<outlet property="appName" destination="APf-vF-1w0" id="N4r-kg-BHK"/>
<outlet property="appVersion" destination="LTk-GB-fgJ" id="41k-wk-DtW"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="About Teleport Assist" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="750" y="574" width="315" height="204"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="315" height="204"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6kW-hd-spe">
<rect key="frame" x="125" y="126" width="64" height="64"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageAlignment="top" imageScaling="proportionallyDown" image="teleport" id="VBv-EA-L5r"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="APf-vF-1w0">
<rect key="frame" x="18" y="99" width="279" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Program Name and Tag Line" id="tb3-eK-HAT">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LTk-GB-fgJ">
<rect key="frame" x="18" y="73" width="279" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Version" id="6fl-Xm-UPS">
<font key="font" metaFont="system" size="10"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="soF-wq-5hG">
<rect key="frame" x="14" y="13" width="287" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Homepage" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="uUM-88-32s">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system" size="11"/>
</buttonCell>
<connections>
<action selector="btnHomepage:" target="-2" id="ZGb-bg-pCR"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rfT-bT-B7g">
<rect key="frame" x="18" y="51" width="279" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Copyright" id="Cmu-CQ-3V9">
<font key="font" metaFont="system" size="10"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="51" y="233"/>
</window>
</objects>
<resources>
<image name="teleport" width="512" height="512"/>
</resources>
</document>

View File

@ -0,0 +1,4 @@
/*
Localizable.strings
TPAssist
*/

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13196" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13196"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="494" id="495"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<menu title="AMainMenu" systemMenu="main" id="29">
<items>
<menuItem title="TPAssist" id="56">
<menu key="submenu" title="TPAssist" systemMenu="apple" id="57">
<items>
<menuItem title="About TPAssist" id="58">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="showAbout:" target="494" id="3cL-aP-7Oh"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="143">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Quit TPAssist" keyEquivalent="q" id="136">
<connections>
<action selector="quit:" target="494" id="eU6-ZU-57n"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<customObject id="494" customClass="AppDelegate">
<connections>
<outlet property="arrayController" destination="620" id="621"/>
<outlet property="menu" destination="542" id="558"/>
</connections>
</customObject>
<customObject id="420" customClass="NSFontManager"/>
<menu autoenablesItems="NO" id="542">
<items>
<menuItem title="About" id="638">
<attributedString key="attributedTitle"/>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="showAbout:" target="494" id="lj3-p9-1cy"/>
</connections>
</menuItem>
<menuItem title="Settings" id="646">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="configure:" target="494" id="DVo-fI-7Ae"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="Lga-cg-zB5">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Visit TELEPORT Website" id="pkv-BD-W9b">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="visitWebsite:" target="494" id="BBn-Sm-LOn"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="8Pg-XX-l39">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Quit" id="644">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="quit:" target="494" id="645"/>
</connections>
</menuItem>
</items>
<point key="canvasLocation" x="121" y="-20"/>
</menu>
<arrayController id="620"/>
</objects>
</document>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,159 @@
#include "ts_cfg.h"
#include "ts_env.h"
TsCfg g_cfg;
TsCfg::TsCfg()
{}
TsCfg::~TsCfg()
{}
bool TsCfg::init(void) {
ex_astr file_content;
if(!ex_read_text_file(g_env.m_cfg_file, file_content)) {
EXLOGE("can not load config file.\n");
return false;
}
if(!_load(file_content))
return false;
return true;
}
bool TsCfg::save(const ex_astr& new_value)
{
if(!_load(new_value))
return false;
Json::StyledWriter jwriter;
ex_astr val = jwriter.write(m_root);
if(!ex_write_text_file(g_env.m_cfg_file, val)) {
EXLOGE("can not save config file.\n");
return false;
}
return true;
}
bool TsCfg::_load(const ex_astr& str_json) {
Json::Reader jreader;
if (!jreader.parse(str_json.c_str(), m_root)) {
EXLOGE("can not parse new config data, not in json format?\n");
return false;
}
// ------------ term ---------------------
if (!m_root["term"].isObject()) {
EXLOGE("invalid config, error 1.\n");
return false;
}
if( !m_root["term"]["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
return false;
}
term_name = m_root["term"]["selected"].asCString();
if(!m_root["term"]["available"].isArray() || m_root["term"]["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
return false;
}
int i = 0;
for (i = 0; i < m_root["term"]["available"].size(); ++i) {
if(
!m_root["term"]["available"][i]["name"].isString()
|| !m_root["term"]["available"][i]["app"].isString()
|| !m_root["term"]["available"][i]["profile"].isString()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if(m_root["term"]["available"][i]["name"].asCString() != term_name)
continue;
if(m_root["term"]["available"][i]["disp"].isString()) {
term_display = m_root["term"]["available"][i]["display"].asCString();
} else if(m_root["term"]["available"][i]["disp"].isNull()) {
m_root["term"]["available"][i]["disp"] = term_name;
term_display = term_name;
} else {
EXLOGE("invalid config, error 5.\n");
return false;
}
term_app = m_root["term"]["available"][i]["app"].asCString();
term_profile = m_root["term"]["available"][i]["profile"].asCString();
break;
}
if(term_name.length() == 0 || term_app.length() == 0 || term_profile.length() == 0) {
EXLOGE("invalid config, error 6.\n");
return false;
}
// ------------ RDP ---------------------
if (!m_root["rdp"].isObject()) {
EXLOGE("invalid config, error 1.\n");
return false;
}
if( !m_root["rdp"]["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
return false;
}
rdp_name = m_root["rdp"]["selected"].asCString();
if(!m_root["rdp"]["available"].isArray() || m_root["rdp"]["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
return false;
}
for (i = 0; i < m_root["rdp"]["available"].size(); ++i) {
if(
!m_root["rdp"]["available"][i]["name"].isString()
|| !m_root["rdp"]["available"][i]["app"].isString()
//|| !m_root["rdp"]["available"][i]["profile"].isString()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if(m_root["rdp"]["available"][i]["name"].asCString() != rdp_name)
continue;
if(m_root["rdp"]["available"][i]["disp"].isString()) {
rdp_display = m_root["term"]["available"][i]["display"].asCString();
} else if(m_root["rdp"]["available"][i]["disp"].isNull()) {
m_root["rdp"]["available"][i]["disp"] = rdp_name;
rdp_display = rdp_name;
} else {
EXLOGE("invalid config, error 5.\n");
return false;
}
rdp_app = m_root["rdp"]["available"][i]["app"].asCString();
//rdp_profile = m_root["rdp"]["available"][i]["profile"].asCString();
break;
}
if(rdp_name.length() == 0) {
EXLOGE("invalid config, error 6.\n");
return false;
}
return true;
}

View File

@ -0,0 +1,39 @@
#ifndef __TS_CFG_H__
#define __TS_CFG_H__
#include <ex.h>
#include <vector>
#include <json/json.h>
class TsCfg
{
public:
TsCfg();
virtual ~TsCfg();
bool init(void);
bool save(const ex_astr& new_value);
Json::Value& get_root() {return m_root;}
ex_astr term_name;
ex_astr term_display;
ex_astr term_app;
ex_astr term_profile;
ex_astr rdp_name;
ex_astr rdp_display;
ex_astr rdp_app;
//ex_astr rdp_cmdline;
protected:
bool _load(const ex_astr& str_json);
protected:
Json::Value m_root;
};
extern TsCfg g_cfg;
#endif // __TS_CFG_H__

View File

@ -0,0 +1,12 @@
#ifndef __TS_CONST_H__
#define __TS_CONST_H__
//#define TS_WEB_URL L"http://teleport.eomsoft.net/"
//#define TS_BBS_URL L"http://bbs.eomsoft.net/"
//#define TS_TRAY_MSG L"Teleport助手正常工作中"
#define TS_HTTP_RPC_PORT 50022
//#define TS_HTTP_RPC_HOST "127.0.0.1"
#define TS_HTTP_RPC_HOST "localhost"
#endif // __TS_CONST_H__

View File

@ -0,0 +1,35 @@
//#include "stdafx.h"
#include "ts_env.h"
#include <time.h>
#ifdef EX_OS_WIN32
# include <direct.h>
//# include <ShlObj.h>
#endif
TsEnv g_env;
//=======================================================
//
//=======================================================
TsEnv::TsEnv()
{}
TsEnv::~TsEnv()
{}
bool TsEnv::init(const char* cfg_file, const char* res_path)
{
ex_astr2wstr(cfg_file, m_cfg_file);
ex_astr2wstr(res_path, m_res_path);
//#ifdef EX_DEBUG
// m_site_path = L"/Users/apex/work/eomsoft/teleport-dev/client/tp_assist_macos/site";
//#else
m_site_path = m_res_path;
ex_path_join(m_site_path, false, L"site", NULL);
//#endif
return true;
}

View File

@ -0,0 +1,31 @@
#ifndef __TS_ENV_H__
#define __TS_ENV_H__
#include <ex.h>
class TsEnv
{
public:
TsEnv();
~TsEnv();
bool init(const char* cfg_file, const char* res_path);
public:
ex_wstr m_cfg_file;
ex_wstr m_res_path;
// ex_wstr m_exec_file;
// ex_wstr m_exec_path;
//
// ex_wstr m_ssh_client_conf_file;
// ex_wstr m_scp_client_conf_file;
// ex_wstr m_telnet_client_conf_file;
// ex_wstr m_log_path;
ex_wstr m_site_path;
// ex_wstr m_tools_path;
};
extern TsEnv g_env;
#endif // __TS_ENV_H__

View File

@ -0,0 +1,773 @@
//#include "stdafx.h"
//#pragma warning(disable:4091)
//#include <commdlg.h>
//#include <ShlObj.h>
#include <unistd.h>
#include <teleport_const.h>
#ifndef MAX_PATH
# define MAX_PATH 1024
#endif
#include "../AppDelegate-C-Interface.h"
#include "ts_http_rpc.h"
//#include "dlg_main.h"
#include "ts_ver.h"
#include "ts_env.h"
#include "ts_cfg.h"
// #define RDP_CLIENT_SYSTEM_BUILTIN
// #define RDP_CLIENT_SYSTEM_ACTIVE_CONTROL
#define RDP_CLIENT_FREERDP
TsHttpRpc g_http_interface;
void* g_app = NULL;
int http_rpc_start(void* app) {
g_app = app;
// if(!g_env.init())
// return;
if (!g_http_interface.init(TS_HTTP_RPC_HOST, TS_HTTP_RPC_PORT))
{
EXLOGE("[ERROR] can not start HTTP-RPC listener, maybe port %d is already in use.\n", TS_HTTP_RPC_PORT);
return -1;
}
EXLOGW("======================================================\n");
EXLOGW("[rpc] TeleportAssist-HTTP-RPC ready on %s:%d\n", TS_HTTP_RPC_HOST, TS_HTTP_RPC_PORT);
if(!g_http_interface.start())
return -2;
return 0;
}
void http_rpc_stop(void)
{
g_http_interface.stop();
}
#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
int ts_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded)
{
int i, j, a, b;
for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++)
{
if (src[i] == '%')
{
if (i < src_len - 2 && isxdigit(*(const unsigned char *)(src + i + 1)) &&
isxdigit(*(const unsigned char *)(src + i + 2))) {
a = tolower(*(const unsigned char *)(src + i + 1));
b = tolower(*(const unsigned char *)(src + i + 2));
dst[j] = (char)((HEXTOI(a) << 4) | HEXTOI(b));
i += 2;
}
else
{
return -1;
}
}
else if (is_form_url_encoded && src[i] == '+')
{
dst[j] = ' ';
}
else
{
dst[j] = src[i];
}
}
dst[j] = '\0'; /* Null-terminate the destination */
return i >= src_len ? j : -1;
}
TsHttpRpc::TsHttpRpc() :
ExThreadBase("http-rpc-thread")
{
mg_mgr_init(&m_mg_mgr, NULL);
}
TsHttpRpc::~TsHttpRpc()
{
mg_mgr_free(&m_mg_mgr);
}
bool TsHttpRpc::init(const char* ip, int port)
{
struct mg_connection* nc = NULL;
char addr[128] = { 0 };
if (0 == strcmp(ip, "127.0.0.1") || 0 == strcmp(ip, "localhost"))
ex_strformat(addr, 128, "tcp://127.0.0.1:%d", port);
else
ex_strformat(addr, 128, "tcp://%s:%d", ip, port);
nc = mg_bind(&m_mg_mgr, addr, _mg_event_handler);
if (nc == NULL)
{
EXLOGE("[rpc] TsHttpRpc::init %s:%d\n", ip, port);
return false;
}
nc->user_data = this;
mg_set_protocol_http_websocket(nc);
m_content_type_map[".js"] = "application/javascript";
m_content_type_map[".png"] = "image/png";
m_content_type_map[".jpeg"] = "image/jpeg";
m_content_type_map[".jpg"] = "image/jpeg";
m_content_type_map[".gif"] = "image/gif";
m_content_type_map[".ico"] = "image/x-icon";
m_content_type_map[".json"] = "image/json";
m_content_type_map[".html"] = "text/html";
m_content_type_map[".css"] = "text/css";
m_content_type_map[".tif"] = "image/tiff";
m_content_type_map[".tiff"] = "image/tiff";
m_content_type_map[".svg"] = "text/html";
return true;
}
void TsHttpRpc::_thread_loop(void)
{
while (!m_stop_flag)
{
mg_mgr_poll(&m_mg_mgr, 500);
}
EXLOGV("[core] rpc main loop end.\n");
}
void TsHttpRpc::_set_stop_flag(void)
{
m_stop_flag = true;
}
void TsHttpRpc::_mg_event_handler(struct mg_connection *nc, int ev, void *ev_data)
{
struct http_message *hm = (struct http_message*)ev_data;
TsHttpRpc* _this = (TsHttpRpc*)nc->user_data;
if (NULL == _this)
{
EXLOGE("[ERROR] invalid http request.\n");
return;
}
switch (ev)
{
case MG_EV_HTTP_REQUEST:
{
ex_astr uri;
ex_chars _uri;
_uri.resize(hm->uri.len + 1);
memset(&_uri[0], 0, hm->uri.len + 1);
memcpy(&_uri[0], hm->uri.p, hm->uri.len);
uri = &_uri[0];
#ifdef EX_DEBUG
const char* dbg_method = NULL;
if (hm->method.len == 3 && 0 == memcmp(hm->method.p, "GET", hm->method.len))
dbg_method = "GET";
else if (hm->method.len == 4 && 0 == memcmp(hm->method.p, "POST", hm->method.len))
dbg_method = "POST";
else
dbg_method = "UNSUPPORTED-HTTP-METHOD";
EXLOGV("[rpc] got %s request: %s\n", dbg_method, uri.c_str());
#endif
ex_astr ret_buf;
bool b_is_index = false;
if (uri == "/")
{
ex_wstr page = L"<html lang=\"zh_CN\"><head><meta charset=\"utf-8\"/><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><title>Teleport Assistor</title>\n<style type=\"text/css\">\n.box{padding:20px;margin:40px;border:1px solid #78b17c;background-color:#e4ffe5;}\n</style>\n</head><body><div class=\"box\">Teleport Assistor works fine.</div></body></html>";
ex_wstr2astr(page, ret_buf, EX_CODEPAGE_UTF8);
mg_printf(nc, "HTTP/1.0 200 OK\r\nAccess-Control-Allow-Origin: *\r\nContent-Length: %ld\r\nContent-Type: text/html\r\n\r\n%s", ret_buf.size() - 1, &ret_buf[0]);
nc->flags |= MG_F_SEND_AND_CLOSE;
return;
}
if (uri == "/config")
{
uri = "/index.html";
b_is_index = true;
}
ex_astr temp;
size_t offset = uri.find("/", 1);
if (offset > 0)
{
temp = uri.substr(1, offset-1);
if(temp == "api") {
ex_astr method;
ex_astr json_param;
int rv = _this->_parse_request(hm, method, json_param);
if (0 != rv)
{
EXLOGE("[ERROR] http-rpc got invalid request.\n");
_this->_create_json_ret(ret_buf, rv);
}
else
{
_this->_process_js_request(method, json_param, ret_buf);
}
mg_printf(nc, "HTTP/1.0 200 OK\r\nAccess-Control-Allow-Origin: *\r\nContent-Length: %ld\r\nContent-Type: application/json\r\n\r\n%s", ret_buf.size() - 1, &ret_buf[0]);
nc->flags |= MG_F_SEND_AND_CLOSE;
return;
}
}
ex_astr file_suffix;
offset = uri.rfind(".");
if (offset > 0)
{
file_suffix = uri.substr(offset, uri.length());
}
ex_wstr2astr(g_env.m_site_path, temp);
ex_astr index_path = temp + uri;
FILE* file = ex_fopen(index_path.c_str(), "rb");
if (file)
{
unsigned long file_size = 0;
char* buf = 0;
size_t ret = 0;
fseek(file, 0, SEEK_END);
file_size = ftell(file);
buf = new char[file_size];
memset(buf, 0, file_size);
fseek(file, 0, SEEK_SET);
ret = fread(buf, 1, file_size, file);
fclose(file);
ex_astr content_type = _this->get_content_type(file_suffix);
mg_printf(nc, "HTTP/1.0 200 OK\r\nAccess-Control-Allow-Origin: *\r\nContent-Length: %ld\r\nContent-Type: %s\r\n\r\n", file_size, content_type.c_str());
mg_send(nc, buf, (int)file_size);
delete []buf;
nc->flags |= MG_F_SEND_AND_CLOSE;
return;
}
else if (b_is_index)
{
ex_wstr page = L"<html lang=\"zh_CN\"><html><head><title>404 Not Found</title></head><body bgcolor=\"white\"><center><h1>404 Not Found</h1></center><hr><center><p>Teleport Assistor configuration page not found.</p></center></body></html>";
ex_wstr2astr(page, ret_buf, EX_CODEPAGE_UTF8);
mg_printf(nc, "HTTP/1.0 404 File Not Found\r\nAccess-Control-Allow-Origin: *\r\nContent-Length: %ld\r\nContent-Type: text/html\r\n\r\n%s", ret_buf.size() - 1, &ret_buf[0]);
nc->flags |= MG_F_SEND_AND_CLOSE;
return;
}
}
break;
default:
break;
}
}
int TsHttpRpc::_parse_request(struct http_message* req, ex_astr& func_cmd, ex_astr& func_args)
{
if (NULL == req)
return TPE_FAILED;
bool is_get = true;
if (req->method.len == 3 && 0 == memcmp(req->method.p, "GET", req->method.len))
is_get = true;
else if (req->method.len == 4 && 0 == memcmp(req->method.p, "POST", req->method.len))
is_get = false;
else
return TPE_HTTP_METHOD;
ex_astrs strs;
size_t pos_start = 1; // 跳过第一个字节,一定是 '/'
size_t i = 0;
for (i = pos_start; i < req->uri.len; ++i)
{
if (req->uri.p[i] == '/')
{
if (i - pos_start > 0)
{
ex_astr tmp_uri;
tmp_uri.assign(req->uri.p + pos_start, i - pos_start);
strs.push_back(tmp_uri);
}
pos_start = i + 1; // 跳过当前找到的分隔符
}
}
if (pos_start < req->uri.len)
{
ex_astr tmp_uri;
tmp_uri.assign(req->uri.p + pos_start, req->uri.len - pos_start);
strs.push_back(tmp_uri);
}
if (0 == strs.size() || strs[0] != "api")
return TPE_PARAM;
if (is_get)
{
if (2 == strs.size())
{
func_cmd = strs[1];
}
else if (3 == strs.size())
{
func_cmd = strs[1];
func_args = strs[2];
}
else
{
return TPE_PARAM;
}
}
else
{
if (2 == strs.size())
{
func_cmd = strs[1];
}
else
{
return TPE_PARAM;
}
if (req->body.len > 0)
{
func_args.assign(req->body.p, req->body.len);
}
}
if (func_args.length() > 0)
{
// 将参数进行 url-decode 解码
size_t len = func_args.length() * 2;
ex_chars sztmp;
sztmp.resize(len);
memset(&sztmp[0], 0, len);
if (-1 == ts_url_decode(func_args.c_str(), (int)func_args.length(), &sztmp[0], (int)len, 0))
return TPE_HTTP_URL_ENCODE;
func_args = &sztmp[0];
}
EXLOGV("[rpc] method=%s, json_param=%s\n", func_cmd.c_str(), func_args.c_str());
return TPE_OK;
}
void TsHttpRpc::_process_js_request(const ex_astr& func_cmd, const ex_astr& func_args, ex_astr& buf)
{
if (func_cmd == "get_version")
{
_rpc_func_get_version(func_args, buf);
}
else if (func_cmd == "run")
{
_rpc_func_run_client(func_args, buf);
}
else if (func_cmd == "rdp_play")
{
_rpc_func_rdp_play(func_args, buf);
}
else if (func_cmd == "get_config")
{
_rpc_func_get_config(func_args, buf);
}
else if (func_cmd == "set_config")
{
_rpc_func_set_config(func_args, buf);
}
else if (func_cmd == "file_action")
{
_rpc_func_file_action(func_args, buf);
}
else
{
EXLOGE("[rpc] got unknown command: %s\n", func_cmd.c_str());
_create_json_ret(buf, TPE_UNKNOWN_CMD);
}
}
void TsHttpRpc::_create_json_ret(ex_astr& buf, int errcode)
{
// 返回: {"code":123}
Json::FastWriter jr_writer;
Json::Value jr_root;
jr_root["code"] = errcode;
buf = jr_writer.write(jr_root);
}
void TsHttpRpc::_create_json_ret(ex_astr& buf, Json::Value& jr_root)
{
Json::FastWriter jr_writer;
buf = jr_writer.write(jr_root);
}
void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf)
{
// 入参:{"ip":"192.168.5.11","port":22,"uname":"root","uauth":"abcdefg","authmode":1,"protocol":2}
// authmode: 1=password, 2=private-key
// protocol: 1=rdp, 2=ssh
// SSH返回 {"code":0, "data":{"sid":"0123abcde"}}
// RDP返回 {"code":0, "data":{"sid":"0123abcde0A"}}
Json::Reader jreader;
Json::Value jsRoot;
if (!jreader.parse(func_args.c_str(), jsRoot))
{
_create_json_ret(buf, TPE_JSON_FORMAT);
return;
}
if (!jsRoot.isObject())
{
_create_json_ret(buf, TPE_PARAM);
return;
}
// 判断参数是否正确
if (!jsRoot["teleport_ip"].isString()
|| !jsRoot["teleport_port"].isNumeric() || !jsRoot["remote_host_ip"].isString()
|| !jsRoot["session_id"].isString() || !jsRoot["protocol_type"].isNumeric() || !jsRoot["protocol_sub_type"].isNumeric()
|| !jsRoot["protocol_flag"].isNumeric()
)
{
_create_json_ret(buf, TPE_PARAM);
return;
}
int pro_type = jsRoot["protocol_type"].asUInt();
int pro_sub = jsRoot["protocol_sub_type"].asInt();
ex_u32 protocol_flag = jsRoot["protocol_flag"].asUInt();
ex_astr teleport_ip = jsRoot["teleport_ip"].asCString();
int teleport_port = jsRoot["teleport_port"].asUInt();
ex_astr real_host_ip = jsRoot["remote_host_ip"].asCString();
ex_astr sid = jsRoot["session_id"].asCString();
ex_astr s_exec;
ex_astrs s_argv;
if (pro_type == TP_PROTOCOL_TYPE_RDP)
{
//==============================================
// RDP
//==============================================
if(g_cfg.rdp_app.length() == 0) {
_create_json_ret(buf, TPE_NOT_EXISTS);
return;
}
bool flag_clipboard = (protocol_flag & TP_FLAG_RDP_CLIPBOARD);
bool flag_disk = (protocol_flag & TP_FLAG_RDP_DISK);
bool flag_console = (protocol_flag & TP_FLAG_RDP_CONSOLE);
int rdp_w = 800;
int rdp_h = 640;
bool rdp_console = false;
if (!jsRoot["rdp_width"].isNull()) {
if (jsRoot["rdp_width"].isNumeric()) {
rdp_w = jsRoot["rdp_width"].asUInt();
}
else {
_create_json_ret(buf, TPE_PARAM);
return;
}
}
if (!jsRoot["rdp_height"].isNull()) {
if (jsRoot["rdp_height"].isNumeric()) {
rdp_h = jsRoot["rdp_height"].asUInt();
}
else {
_create_json_ret(buf, TPE_PARAM);
return;
}
}
if (!jsRoot["rdp_console"].isNull()) {
if (jsRoot["rdp_console"].isBool()) {
rdp_console = jsRoot["rdp_console"].asBool();
}
else {
_create_json_ret(buf, TPE_PARAM);
return;
}
}
if (!flag_console)
rdp_console = false;
size_t split_pos = sid.length() - 2;
ex_astr real_sid = sid.substr(0, split_pos);
ex_astr str_pwd_len = sid.substr(split_pos, sid.length());
size_t n_pwd_len = strtol(str_pwd_len.c_str(), NULL, 16);
n_pwd_len -= real_sid.length();
n_pwd_len -= 2;
char szPwd[256] = { 0 };
for (int i = 0; i < n_pwd_len; i++)
{
szPwd[i] = '*';
}
//ex_astr2wstr(real_sid, w_sid);
//w_exe_path = _T("\"");
//w_exe_path += g_cfg.rdp_app + _T("\" ");
//w_exe_path += g_cfg.rdp_cmdline;
//w_exe_path = _T("xfreerdp -u {user_name} {size} {console} {clipboard} {drives} ");
//w_exe_path = _T("/usr/local/Cellar/freerdp/1.0.2_1/bin/xfreerdp -u {user_name} {size} {console} ");
//w_exe_path = _T("xfreerdp -u {user_name} {size} {console} ");
//s_exec = "/usr/local/Cellar/freerdp/1.0.2_1/bin/xfreerdp";
s_exec = g_cfg.rdp_app;
s_argv.push_back(s_exec.c_str());
{
ex_astr username = "02" + real_sid;
s_argv.push_back("-u");
s_argv.push_back(username.c_str());
if (rdp_w == 0 || rdp_h == 0) {
s_argv.push_back("-f");
}
else {
char sz_size[64] = {0};
ex_strformat(sz_size, 63, "%dx%d", rdp_w, rdp_h);
s_argv.push_back("-g");
s_argv.push_back(sz_size);
}
if (flag_console && rdp_console)
s_argv.push_back("/admin");
// if(flag_clipboard)
// s_argv.push_back("+clipboard");
// else
// s_argv.push_back("-clipboard");
// if(flag_disk)
// s_argv.push_back("+drives");
// else
// s_argv.push_back("-drives");
{
char sz_temp[128] = {0};
ex_strformat(sz_temp, 127, "%s:%d", teleport_ip.c_str(), teleport_port);
s_argv.push_back(sz_temp);
}
}
}
else if (pro_type == TP_PROTOCOL_TYPE_SSH)
{
//==============================================
// SSH
//==============================================
if (pro_sub == TP_PROTOCOL_TYPE_SSH_SHELL)
{
char szCmd[1024] = {0};
ex_strformat(szCmd, 1023, "ssh %s@%s -p %d", sid.c_str(), teleport_ip.c_str(), teleport_port);
char szTitle[128] = {0};
ex_strformat(szTitle, 127, "TP#%s", real_host_ip.c_str());
int ret = AppDelegate_start_ssh_client(g_app, szCmd, g_cfg.term_name.c_str(), g_cfg.term_profile.c_str(), szTitle);
if(ret == 0)
_create_json_ret(buf, TPE_OK);
else
_create_json_ret(buf, TPE_FAILED);
return;
}
else
{
// sorry, SFTP not supported yet for macOS.
_create_json_ret(buf, TPE_NOT_IMPLEMENT);
return;
}
}
else if (pro_type == TP_PROTOCOL_TYPE_TELNET)
{
//==============================================
// TELNET
//==============================================
// sorry, TELNET not supported yet for macOS.
_create_json_ret(buf, TPE_NOT_IMPLEMENT);
return;
}
// ex_replace_all(w_exe_path, _T("{host_port}"), w_port);
// ex_replace_all(w_exe_path, _T("{host_ip}"), w_teleport_ip.c_str());
// ex_replace_all(w_exe_path, _T("{user_name}"), w_sid.c_str());
// ex_replace_all(w_exe_path, _T("{real_ip}"), w_real_host_ip.c_str());
//ex_replace_all(w_exe_path, _T("{assist_tools_path}"), g_env.m_tools_path.c_str());
Json::Value root_ret;
ex_astr utf8_path = s_exec;
//ex_wstr2astr(w_exe_path, utf8_path, EX_CODEPAGE_UTF8);
ex_astrs::iterator it = s_argv.begin();
for(; it != s_argv.end(); ++it) {
utf8_path += " ";
utf8_path += (*it);
}
root_ret["path"] = utf8_path;
// if (!CreateProcess(NULL, (wchar_t *)w_exe_path.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
// {
// EXLOGE(_T("CreateProcess() failed. Error=0x%08X.\n %s\n"), GetLastError(), w_exe_path.c_str());
// root_ret["code"] = TPE_START_CLIENT;
// _create_json_ret(buf, root_ret);
// return;
// }
//system(utf8_path.c_str());
//ex_astr __sid;
//ex_wstr2astr(w_sid, __sid);
//execlp("xfreerdp", "-u", __sid.c_str(), "-g", "800x600", "127.0.0.1:52089", NULL);
// FILE *f = popen(utf8_path.c_str(), "r");
// if(f == NULL) {
// root_ret["code"] = TPE_FAILED;
// } else {
// root_ret["code"] = TPE_OK;
// pclose(f);
// }
// {
// int i = 0;
// char** _argv = (char**)calloc(s_argv.size()+1, sizeof(char*));
// if (!_argv)
// return;
//
// for (i = 0; i < s_argv.size(); ++i)
// {
// _argv[i] = ex_strdup(s_argv[i].c_str());
// }
// _argv[i] = NULL;
//
// execv(s_exec.c_str(), _argv);
//
// for(i = 0; i < s_argv.size(); ++i) {
// if(_argv[i] != NULL) {
// free(_argv[i]);
// }
// }
// free(_argv);
//
// }
// for macOS, Create Process should be fork()/exec()...
pid_t processId;
if ((processId = fork()) == 0) {
int i = 0;
char** _argv = (char**)calloc(s_argv.size()+1, sizeof(char*));
if (!_argv)
return;
for (i = 0; i < s_argv.size(); ++i)
{
_argv[i] = ex_strdup(s_argv[i].c_str());
}
_argv[i] = NULL;
execv(s_exec.c_str(), _argv);
for(i = 0; i < s_argv.size(); ++i) {
if(_argv[i] != NULL) {
free(_argv[i]);
}
}
free(_argv);
} else if (processId < 0) {
root_ret["code"] = TPE_FAILED;
} else {
root_ret["code"] = TPE_OK;
}
// root_ret["code"] = TPE_OK;
_create_json_ret(buf, root_ret);
}
void TsHttpRpc::_rpc_func_rdp_play(const ex_astr& func_args, ex_astr& buf)
{
_create_json_ret(buf, TPE_NOT_IMPLEMENT);
}
void TsHttpRpc::_rpc_func_get_config(const ex_astr& func_args, ex_astr& buf)
{
Json::Value jr_root;
jr_root["code"] = 0;
jr_root["data"] = g_cfg.get_root();
_create_json_ret(buf, jr_root);
}
void TsHttpRpc::_rpc_func_set_config(const ex_astr& func_args, ex_astr& buf)
{
Json::Reader jreader;
Json::Value jsRoot;
if (!jreader.parse(func_args.c_str(), jsRoot))
{
_create_json_ret(buf, TPE_JSON_FORMAT);
return;
}
if(!g_cfg.save(func_args))
_create_json_ret(buf, TPE_FAILED);
else
_create_json_ret(buf, TPE_OK);
}
void TsHttpRpc::_rpc_func_file_action(const ex_astr& func_args, ex_astr& buf) {
_create_json_ret(buf, TPE_NOT_IMPLEMENT);
}
void TsHttpRpc::_rpc_func_get_version(const ex_astr& func_args, ex_astr& buf)
{
Json::Value root_ret;
ex_wstr w_version = TP_ASSIST_VER;
ex_astr version;
ex_wstr2astr(w_version, version, EX_CODEPAGE_UTF8);
root_ret["version"] = version;
root_ret["code"] = TPE_OK;
_create_json_ret(buf, root_ret);
return;
}

View File

@ -0,0 +1,93 @@
#ifndef __TS_HTTP_RPC_H__
#define __TS_HTTP_RPC_H__
#include "ts_const.h"
#include <vector>
#include <string>
#include <map>
#include <ex.h>
#include <json/json.h>
#include "../../external/mongoose/mongoose.h"
/*
//=================================================================
使
127.0.0.1:50022http
GET
http://127.0.0.1:50022/method/json_param
json_param使url_encodejson
POST
http://127.0.0.1:50022/method
postjson_param
URI
method
json_param
json
{"code":0,"data":varb}
code0datadata
*/
int http_rpc_start(void* app);
void http_rpc_stop(void);
typedef std::map<ex_astr, ex_astr> content_type_map;
class TsHttpRpc : public ExThreadBase
{
public:
TsHttpRpc();
~TsHttpRpc();
bool init(const char* ip, int port);
ex_astr get_content_type(ex_astr file_suffix)
{
content_type_map::iterator it = m_content_type_map.find(file_suffix);
if (it != m_content_type_map.end())
{
return it->second;
}
else
{
return "application/octet-stream";
}
};
protected:
void _thread_loop(void);
void _set_stop_flag(void);
private:
int _parse_request(struct http_message* req, ex_astr& func_cmd, ex_astr& func_args);
void _process_js_request(const ex_astr& func_cmd, const ex_astr& func_args, ex_astr& buf);
void _create_json_ret(ex_astr& buf, int errcode);
void _create_json_ret(ex_astr& buf, Json::Value& jr_root);
void _rpc_func_run_client(const ex_astr& func_args, ex_astr& buf);
void _rpc_func_check(const ex_astr& func_args, ex_astr& buf);
void _rpc_func_rdp_play(const ex_astr& func_args, ex_astr& buf);
void _rpc_func_get_config(const ex_astr& func_args, ex_astr& buf);
void _rpc_func_set_config(const ex_astr& func_args, ex_astr& buf);
void _rpc_func_file_action(const ex_astr& func_args, ex_astr& buf);
void _rpc_func_get_version(const ex_astr& func_args, ex_astr& buf);
static void _mg_event_handler(struct mg_connection *nc, int ev, void *ev_data);
private:
content_type_map m_content_type_map;
struct mg_mgr m_mg_mgr;
};
#endif // __TS_HTTP_RPC_H__

View File

@ -1,6 +1,6 @@
#ifndef __TS_ASSIST_VER_H__
#define __TS_ASSIST_VER_H__
#define TP_ASSIST_VER L"2.2.6.1"
#define TP_ASSIST_VER L"3.0.1.6"
#endif // __TS_ASSIST_VER_H__

View File

@ -0,0 +1,15 @@
/* Class = "NSTextFieldCell"; title = "Version"; ObjectID = "6fl-Xm-UPS"; */
"6fl-Xm-UPS.title" = "Version";
/* Class = "NSTextFieldCell"; title = "Copyright"; ObjectID = "Cmu-CQ-3V9"; */
"Cmu-CQ-3V9.title" = "Copyright";
/* Class = "NSWindow"; title = "Window"; ObjectID = "F0z-JX-Cv5"; */
"F0z-JX-Cv5.title" = "Window";
/* Class = "NSTextFieldCell"; title = "Program Name and Tag Line"; ObjectID = "tb3-eK-HAT"; */
"tb3-eK-HAT.title" = "Teleport Assistor for MacOS";
/* Class = "NSButtonCell"; title = "Homepage"; ObjectID = "uUM-88-32s"; */
"uUM-88-32s.title" = "Visit TELEPORT Website";

View File

@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */

View File

@ -0,0 +1,4 @@
/*
Localizable.strings
TPAssist
*/

View File

@ -0,0 +1,33 @@
/* Class = "NSMenu"; title = "AMainMenu"; ObjectID = "29"; */
"29.title" = "AMainMenu";
/* Class = "NSMenuItem"; title = "TPAssist"; ObjectID = "56"; */
"56.title" = "TPAssist";
/* Class = "NSMenu"; title = "TPAssist"; ObjectID = "57"; */
"57.title" = "TPAssist";
/* Class = "NSMenuItem"; title = "About TPAssist"; ObjectID = "58"; */
"58.title" = "About TPAssist";
/* Class = "NSMenuItem"; title = "Quit TPAssist"; ObjectID = "136"; */
"136.title" = "Quit TPAssist";
/* Class = "NSMenuItem"; title = "About"; ObjectID = "638"; */
"638.title" = "About";
/* Class = "NSMenuItem"; title = "Quit"; ObjectID = "644"; */
"644.title" = "Quit";
/* Class = "NSMenuItem"; title = "Settings"; ObjectID = "646"; */
"646.title" = "Settings";
/* Class = "NSMenu"; title = "Settings"; ObjectID = "647"; */
"647.title" = "Settings";
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "648"; */
"648.title" = "Edit";
/* Class = "NSMenuItem"; title = "Quit"; ObjectID = "649"; */
"649.title" = "Quit";

View File

@ -0,0 +1,11 @@
//
// main.m
// TPAssist
//
#import <Cocoa/Cocoa.h>
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **)argv);
}

View File

@ -0,0 +1,30 @@
{
"term": {
"selected": "Terminal",
"available": [
{
"name":"Terminal",
"display": "终端(系统自带)",
"app": "Terminal.app",
"profile": "Basic"
},
{
"name": "iTerm2",
"display": "iTerm2",
"app": "iTerm2.app",
"profile": "Default"
}
]
},
"rdp": {
"selected": "FreeRDP",
"available": [
{
"name": "FreeRDP",
"display": "FreeRDP",
"app": ""
}
]
}
}

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>zh_CN</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>teleport</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>3.0.1.6</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>3.0.1.6</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.productivity</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>LSUIElement</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2017~2018 EOMSOFT. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>Product Homepage</key>
<string>http://teleport.eomsoft.net/</string>
</dict>
</plist>

View File

@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'TPAssist' target in the 'TPAssist' project
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif

View File

@ -0,0 +1,15 @@
/* Class = "NSTextFieldCell"; title = "Version"; ObjectID = "6fl-Xm-UPS"; */
"6fl-Xm-UPS.title" = "Version";
/* Class = "NSTextFieldCell"; title = "Copyright"; ObjectID = "Cmu-CQ-3V9"; */
"Cmu-CQ-3V9.title" = "Copyright";
/* Class = "NSWindow"; title = "Window"; ObjectID = "F0z-JX-Cv5"; */
"F0z-JX-Cv5.title" = "Window";
/* Class = "NSTextFieldCell"; title = "Program Name and Tag Line"; ObjectID = "tb3-eK-HAT"; */
"tb3-eK-HAT.title" = "Teleport助手 for MacOS";
/* Class = "NSButtonCell"; title = "官方网站"; ObjectID = "uUM-88-32s"; */
"uUM-88-32s.title" = "访问TELEPORT官方网站";

View File

@ -0,0 +1,15 @@
/*
Localizable.strings
TPAssist
Created by ApexLiu at 2017-09-13.
*/
/* NSLocalizedString(@"",nil)*/
"About " = "关于 ";
//"Version: " = "版本:";
"Teleport Assist" = "Teleport 助手 - macOS";
"Quit" = "退出";
//"Continue" = "继续";

View File

@ -0,0 +1,33 @@
/* Class = "NSMenu"; title = "AMainMenu"; ObjectID = "29"; */
"29.title" = "AMainMenu";
/* Class = "NSMenuItem"; title = "TPAssist"; ObjectID = "56"; */
"56.title" = "TPAssist";
/* Class = "NSMenu"; title = "TPAssist"; ObjectID = "57"; */
"57.title" = "TPAssist";
/* Class = "NSMenuItem"; title = "关于 TPAssist"; ObjectID = "58"; */
"58.title" = "关于 TPAssist";
/* Class = "NSMenuItem"; title = "退出 TPAssist"; ObjectID = "136"; */
"136.title" = "退出 TPAssist";
/* Class = "NSMenuItem"; title = "关于"; ObjectID = "638"; */
"638.title" = "关于";
/* Class = "NSMenuItem"; title = "退出"; ObjectID = "644"; */
"644.title" = "退出";
/* Class = "NSMenuItem"; title = "设置"; ObjectID = "646"; */
"646.title" = "设置";
/* Class = "NSMenu"; title = "设置"; ObjectID = "647"; */
"647.title" = "设置";
/* Class = "NSMenuItem"; title = "编辑"; ObjectID = "648"; */
"648.title" = "编辑";
/* Class = "NSMenuItem"; title = "Quit"; ObjectID = "649"; */
"649.title" = "Quit";

Binary file not shown.

View File

@ -0,0 +1,552 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
0ADB3B0C178EF8DB004E9BB9 /* StatusIconAlt.png in Resources */ = {isa = PBXBuildFile; fileRef = 0ADB3B08178EF8DB004E9BB9 /* StatusIconAlt.png */; };
0ADB3B0D178EF8DB004E9BB9 /* StatusIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 0ADB3B09178EF8DB004E9BB9 /* StatusIcon.png */; };
0ADB3B0E178EF8DB004E9BB9 /* StatusIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0ADB3B0A178EF8DB004E9BB9 /* StatusIcon@2x.png */; };
0ADB3B0F178EF8DB004E9BB9 /* StatusIconAlt@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 0ADB3B0B178EF8DB004E9BB9 /* StatusIconAlt@2x.png */; };
7A0C94AA1F68BD2900E04C3E /* AboutWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6FC541A51D45CF7F00A896E3 /* AboutWindowController.xib */; };
7A18188F1F7D5D7F00F3C882 /* AppDelegate-C-Interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A18188E1F7D5D7F00F3C882 /* AppDelegate-C-Interface.cpp */; };
7A1818911F7FBBC200F3C882 /* tp-assist.default.json in Resources */ = {isa = PBXBuildFile; fileRef = 7A1818901F7FBBC200F3C882 /* tp-assist.default.json */; };
7A1818931F815B8A00F3C882 /* Terminal.scpt in Resources */ = {isa = PBXBuildFile; fileRef = 7A1818921F815B8A00F3C882 /* Terminal.scpt */; };
7A27E4A91F6A8EEC004FDE5D /* ts_env.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A27E4A71F6A8EEC004FDE5D /* ts_env.cpp */; };
7AA2CD381F6A92620074C92B /* ts_http_rpc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA2CD371F6A92620074C92B /* ts_http_rpc.cpp */; };
7AA2CD3B1F6A955A0074C92B /* ts_cfg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA2CD391F6A955A0074C92B /* ts_cfg.cpp */; };
7AA2CD441F6AB9750074C92B /* ex_ini.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA2CD3D1F6AB9750074C92B /* ex_ini.cpp */; };
7AA2CD451F6AB9750074C92B /* ex_log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA2CD3E1F6AB9750074C92B /* ex_log.cpp */; };
7AA2CD461F6AB9750074C92B /* ex_path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA2CD3F1F6AB9750074C92B /* ex_path.cpp */; };
7AA2CD471F6AB9750074C92B /* ex_str.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA2CD401F6AB9750074C92B /* ex_str.cpp */; };
7AA2CD481F6AB9750074C92B /* ex_thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA2CD411F6AB9750074C92B /* ex_thread.cpp */; };
7AA2CD491F6AB9750074C92B /* ex_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA2CD421F6AB9750074C92B /* ex_util.cpp */; };
7AA2CD4A1F6AB9750074C92B /* ex_winsrv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA2CD431F6AB9750074C92B /* ex_winsrv.cpp */; };
7AA2CD511F6AB9F10074C92B /* json_reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA2CD4C1F6AB9F10074C92B /* json_reader.cpp */; };
7AA2CD521F6AB9F10074C92B /* json_value.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA2CD4E1F6AB9F10074C92B /* json_value.cpp */; };
7AA2CD541F6AB9F10074C92B /* json_writer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA2CD501F6AB9F10074C92B /* json_writer.cpp */; };
7AA2CD571F6ABA2E0074C92B /* mongoose.c in Sources */ = {isa = PBXBuildFile; fileRef = 7AA2CD561F6ABA2E0074C92B /* mongoose.c */; };
7AA2CD591F6AC0DA0074C92B /* site in Resources */ = {isa = PBXBuildFile; fileRef = 7AA2CD581F6AC0DA0074C92B /* site */; };
7AD1F1D31F7A55EA0048A496 /* iTerm2.scpt in Resources */ = {isa = PBXBuildFile; fileRef = 7AD1F1D11F7A55EA0048A496 /* iTerm2.scpt */; };
A1B7B9DD1DB53ED200809327 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = A1B7B9DF1DB53ED200809327 /* Localizable.strings */; };
A1D700071A5DCE8D003563E4 /* AboutWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = A1D700061A5DCE8D003563E4 /* AboutWindowController.m */; };
C149EBFE15D5214600B1F558 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C149EBFD15D5214600B1F558 /* Cocoa.framework */; };
C149EC0815D5214600B1F558 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C149EC0615D5214600B1F558 /* InfoPlist.strings */; };
C149EC0A15D5214600B1F558 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C149EC0915D5214600B1F558 /* main.m */; };
C149EC1115D5214600B1F558 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = C149EC1015D5214600B1F558 /* AppDelegate.mm */; };
C149EC1415D5214600B1F558 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = C149EC1215D5214600B1F558 /* MainMenu.xib */; };
C159DC2815D5DE8000F5DE24 /* teleport.icns in Resources */ = {isa = PBXBuildFile; fileRef = C159DC2715D5DE7F00F5DE24 /* teleport.icns */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
0ADB3B08178EF8DB004E9BB9 /* StatusIconAlt.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = StatusIconAlt.png; sourceTree = "<group>"; };
0ADB3B09178EF8DB004E9BB9 /* StatusIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = StatusIcon.png; sourceTree = "<group>"; };
0ADB3B0A178EF8DB004E9BB9 /* StatusIcon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "StatusIcon@2x.png"; sourceTree = "<group>"; };
0ADB3B0B178EF8DB004E9BB9 /* StatusIconAlt@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "StatusIconAlt@2x.png"; sourceTree = "<group>"; };
7A18188E1F7D5D7F00F3C882 /* AppDelegate-C-Interface.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = "AppDelegate-C-Interface.cpp"; sourceTree = "<group>"; };
7A1818901F7FBBC200F3C882 /* tp-assist.default.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "tp-assist.default.json"; sourceTree = "<group>"; };
7A1818921F815B8A00F3C882 /* Terminal.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; path = Terminal.scpt; sourceTree = "<group>"; };
7A1818951F8242E900F3C882 /* apple-scripts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "apple-scripts"; sourceTree = "<group>"; };
7A27E4A61F6A899B004FDE5D /* ts_const.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ts_const.h; sourceTree = "<group>"; };
7A27E4A71F6A8EEC004FDE5D /* ts_env.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ts_env.cpp; sourceTree = "<group>"; };
7A27E4A81F6A8EEC004FDE5D /* ts_env.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ts_env.h; sourceTree = "<group>"; };
7A40FFE21F7B2A4500F11697 /* AppDelegate-C-Interface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AppDelegate-C-Interface.h"; sourceTree = "<group>"; };
7AA2CD361F6A92380074C92B /* ts_http_rpc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ts_http_rpc.h; sourceTree = "<group>"; };
7AA2CD371F6A92620074C92B /* ts_http_rpc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ts_http_rpc.cpp; sourceTree = "<group>"; };
7AA2CD391F6A955A0074C92B /* ts_cfg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ts_cfg.cpp; sourceTree = "<group>"; };
7AA2CD3A1F6A955A0074C92B /* ts_cfg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ts_cfg.h; sourceTree = "<group>"; };
7AA2CD3D1F6AB9750074C92B /* ex_ini.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ex_ini.cpp; path = ../../../../common/libex/src/ex_ini.cpp; sourceTree = "<group>"; };
7AA2CD3E1F6AB9750074C92B /* ex_log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ex_log.cpp; path = ../../../../common/libex/src/ex_log.cpp; sourceTree = "<group>"; };
7AA2CD3F1F6AB9750074C92B /* ex_path.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ex_path.cpp; path = ../../../../common/libex/src/ex_path.cpp; sourceTree = "<group>"; };
7AA2CD401F6AB9750074C92B /* ex_str.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ex_str.cpp; path = ../../../../common/libex/src/ex_str.cpp; sourceTree = "<group>"; };
7AA2CD411F6AB9750074C92B /* ex_thread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ex_thread.cpp; path = ../../../../common/libex/src/ex_thread.cpp; sourceTree = "<group>"; };
7AA2CD421F6AB9750074C92B /* ex_util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ex_util.cpp; path = ../../../../common/libex/src/ex_util.cpp; sourceTree = "<group>"; };
7AA2CD431F6AB9750074C92B /* ex_winsrv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ex_winsrv.cpp; path = ../../../../common/libex/src/ex_winsrv.cpp; sourceTree = "<group>"; };
7AA2CD4C1F6AB9F10074C92B /* json_reader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = json_reader.cpp; path = ../../../../external/jsoncpp/src/lib_json/json_reader.cpp; sourceTree = "<group>"; };
7AA2CD4D1F6AB9F10074C92B /* json_tool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = json_tool.h; path = ../../../../external/jsoncpp/src/lib_json/json_tool.h; sourceTree = "<group>"; };
7AA2CD4E1F6AB9F10074C92B /* json_value.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = json_value.cpp; path = ../../../../external/jsoncpp/src/lib_json/json_value.cpp; sourceTree = "<group>"; };
7AA2CD4F1F6AB9F10074C92B /* json_valueiterator.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = json_valueiterator.inl; path = ../../../../external/jsoncpp/src/lib_json/json_valueiterator.inl; sourceTree = "<group>"; };
7AA2CD501F6AB9F10074C92B /* json_writer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = json_writer.cpp; path = ../../../../external/jsoncpp/src/lib_json/json_writer.cpp; sourceTree = "<group>"; };
7AA2CD561F6ABA2E0074C92B /* mongoose.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mongoose.c; path = ../../../../external/mongoose/mongoose.c; sourceTree = "<group>"; };
7AA2CD581F6AC0DA0074C92B /* site */ = {isa = PBXFileReference; lastKnownFileType = folder; path = site; sourceTree = "<group>"; };
7AD1F1D11F7A55EA0048A496 /* iTerm2.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; path = iTerm2.scpt; sourceTree = "<group>"; };
A1B7B9D31DB5361700809327 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
A1B7B9DE1DB53ED200809327 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
A1B7B9E01DB53ED700809327 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; };
A1B7B9E11DB53EDA00809327 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
A1B7B9ED1DB54D6700809327 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AboutWindowController.xib; sourceTree = "<group>"; };
A1B7B9EE1DB54D7B00809327 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/MainMenu.strings"; sourceTree = "<group>"; };
A1B7B9EF1DB54D7F00809327 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/MainMenu.strings; sourceTree = "<group>"; };
A1B7B9F01DB54D8900809327 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/AboutWindowController.strings; sourceTree = "<group>"; };
A1B7B9F11DB54D8C00809327 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/AboutWindowController.strings"; sourceTree = "<group>"; };
A1D700051A5DCDF4003563E4 /* AboutWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutWindowController.h; sourceTree = "<group>"; };
A1D700061A5DCE8D003563E4 /* AboutWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AboutWindowController.m; sourceTree = "<group>"; };
C149EBF915D5214600B1F558 /* tp_assist.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = tp_assist.app; sourceTree = BUILT_PRODUCTS_DIR; };
C149EBFD15D5214600B1F558 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
C149EC0015D5214600B1F558 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
C149EC0115D5214600B1F558 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
C149EC0215D5214600B1F558 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
C149EC0515D5214600B1F558 /* tp_assist-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "tp_assist-Info.plist"; sourceTree = "<group>"; };
C149EC0715D5214600B1F558 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C149EC0915D5214600B1F558 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
C149EC0B15D5214600B1F558 /* tp_assist-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "tp_assist-Prefix.pch"; sourceTree = "<group>"; };
C149EC0F15D5214600B1F558 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
C149EC1015D5214600B1F558 /* AppDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AppDelegate.mm; sourceTree = "<group>"; };
C159DC2715D5DE7F00F5DE24 /* teleport.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = teleport.icns; path = ../teleport.icns; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
C149EBF615D5214600B1F558 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C149EBFE15D5214600B1F558 /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0ADB3B10178EF8E2004E9BB9 /* Images */ = {
isa = PBXGroup;
children = (
0ADB3B09178EF8DB004E9BB9 /* StatusIcon.png */,
0ADB3B0A178EF8DB004E9BB9 /* StatusIcon@2x.png */,
0ADB3B08178EF8DB004E9BB9 /* StatusIconAlt.png */,
0ADB3B0B178EF8DB004E9BB9 /* StatusIconAlt@2x.png */,
);
name = Images;
sourceTree = "<group>";
};
7AA2CD3C1F6AB9560074C92B /* libex */ = {
isa = PBXGroup;
children = (
7AA2CD3D1F6AB9750074C92B /* ex_ini.cpp */,
7AA2CD3E1F6AB9750074C92B /* ex_log.cpp */,
7AA2CD3F1F6AB9750074C92B /* ex_path.cpp */,
7AA2CD401F6AB9750074C92B /* ex_str.cpp */,
7AA2CD411F6AB9750074C92B /* ex_thread.cpp */,
7AA2CD421F6AB9750074C92B /* ex_util.cpp */,
7AA2CD431F6AB9750074C92B /* ex_winsrv.cpp */,
);
name = libex;
sourceTree = "<group>";
};
7AA2CD4B1F6AB9880074C92B /* jsoncpp */ = {
isa = PBXGroup;
children = (
7AA2CD4C1F6AB9F10074C92B /* json_reader.cpp */,
7AA2CD4D1F6AB9F10074C92B /* json_tool.h */,
7AA2CD4E1F6AB9F10074C92B /* json_value.cpp */,
7AA2CD4F1F6AB9F10074C92B /* json_valueiterator.inl */,
7AA2CD501F6AB9F10074C92B /* json_writer.cpp */,
);
name = jsoncpp;
sourceTree = "<group>";
};
7AA2CD551F6ABA000074C92B /* mongoose */ = {
isa = PBXGroup;
children = (
7AA2CD561F6ABA2E0074C92B /* mongoose.c */,
);
name = mongoose;
sourceTree = "<group>";
};
7AD3E8741F6A7CC600D2EB48 /* csrc */ = {
isa = PBXGroup;
children = (
7AA2CD551F6ABA000074C92B /* mongoose */,
7AA2CD4B1F6AB9880074C92B /* jsoncpp */,
7AA2CD3C1F6AB9560074C92B /* libex */,
7AA2CD391F6A955A0074C92B /* ts_cfg.cpp */,
7AA2CD3A1F6A955A0074C92B /* ts_cfg.h */,
7AA2CD371F6A92620074C92B /* ts_http_rpc.cpp */,
7AA2CD361F6A92380074C92B /* ts_http_rpc.h */,
7A27E4A71F6A8EEC004FDE5D /* ts_env.cpp */,
7A27E4A81F6A8EEC004FDE5D /* ts_env.h */,
7A27E4A61F6A899B004FDE5D /* ts_const.h */,
);
path = csrc;
sourceTree = "<group>";
};
A12D9BE61BCF2C72004F52A6 /* apple-scpt */ = {
isa = PBXGroup;
children = (
7A1818921F815B8A00F3C882 /* Terminal.scpt */,
7AD1F1D11F7A55EA0048A496 /* iTerm2.scpt */,
);
path = "apple-scpt";
sourceTree = "<group>";
};
C149EBEE15D5214600B1F558 = {
isa = PBXGroup;
children = (
7A1818951F8242E900F3C882 /* apple-scripts */,
7AA2CD581F6AC0DA0074C92B /* site */,
C149EC0315D5214600B1F558 /* src */,
C149EBFC15D5214600B1F558 /* Frameworks */,
C149EBFA15D5214600B1F558 /* Products */,
);
sourceTree = "<group>";
};
C149EBFA15D5214600B1F558 /* Products */ = {
isa = PBXGroup;
children = (
C149EBF915D5214600B1F558 /* tp_assist.app */,
);
name = Products;
sourceTree = "<group>";
};
C149EBFC15D5214600B1F558 /* Frameworks */ = {
isa = PBXGroup;
children = (
C149EBFD15D5214600B1F558 /* Cocoa.framework */,
C149EBFF15D5214600B1F558 /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "<group>";
};
C149EBFF15D5214600B1F558 /* Other Frameworks */ = {
isa = PBXGroup;
children = (
C149EC0015D5214600B1F558 /* AppKit.framework */,
C149EC0115D5214600B1F558 /* CoreData.framework */,
C149EC0215D5214600B1F558 /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
};
C149EC0315D5214600B1F558 /* src */ = {
isa = PBXGroup;
children = (
7A1818901F7FBBC200F3C882 /* tp-assist.default.json */,
7AD3E8741F6A7CC600D2EB48 /* csrc */,
A12D9BE61BCF2C72004F52A6 /* apple-scpt */,
C159DC2715D5DE7F00F5DE24 /* teleport.icns */,
C149EC0F15D5214600B1F558 /* AppDelegate.h */,
C149EC1015D5214600B1F558 /* AppDelegate.mm */,
C149EC1215D5214600B1F558 /* MainMenu.xib */,
0ADB3B10178EF8E2004E9BB9 /* Images */,
C149EC0415D5214600B1F558 /* Supporting Files */,
A1D700051A5DCDF4003563E4 /* AboutWindowController.h */,
A1D700061A5DCE8D003563E4 /* AboutWindowController.m */,
6FC541A51D45CF7F00A896E3 /* AboutWindowController.xib */,
7A40FFE21F7B2A4500F11697 /* AppDelegate-C-Interface.h */,
7A18188E1F7D5D7F00F3C882 /* AppDelegate-C-Interface.cpp */,
);
path = src;
sourceTree = "<group>";
};
C149EC0415D5214600B1F558 /* Supporting Files */ = {
isa = PBXGroup;
children = (
C149EC0515D5214600B1F558 /* tp_assist-Info.plist */,
C149EC0615D5214600B1F558 /* InfoPlist.strings */,
C149EC0915D5214600B1F558 /* main.m */,
C149EC0B15D5214600B1F558 /* tp_assist-Prefix.pch */,
A1B7B9DF1DB53ED200809327 /* Localizable.strings */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
C149EBF815D5214600B1F558 /* tp_assist */ = {
isa = PBXNativeTarget;
buildConfigurationList = C149EC1715D5214600B1F558 /* Build configuration list for PBXNativeTarget "tp_assist" */;
buildPhases = (
C149EBF515D5214600B1F558 /* Sources */,
C149EBF615D5214600B1F558 /* Frameworks */,
C149EBF715D5214600B1F558 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = tp_assist;
productName = Shuttle;
productReference = C149EBF915D5214600B1F558 /* tp_assist.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
C149EBF015D5214600B1F558 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0930;
ORGANIZATIONNAME = eomsoft;
};
buildConfigurationList = C149EBF315D5214600B1F558 /* Build configuration list for PBXProject "tp_assist" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
"zh-Hans",
Base,
);
mainGroup = C149EBEE15D5214600B1F558;
productRefGroup = C149EBFA15D5214600B1F558 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
C149EBF815D5214600B1F558 /* tp_assist */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
C149EBF715D5214600B1F558 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7AA2CD591F6AC0DA0074C92B /* site in Resources */,
A1B7B9DD1DB53ED200809327 /* Localizable.strings in Resources */,
0ADB3B0D178EF8DB004E9BB9 /* StatusIcon.png in Resources */,
0ADB3B0C178EF8DB004E9BB9 /* StatusIconAlt.png in Resources */,
C149EC0815D5214600B1F558 /* InfoPlist.strings in Resources */,
0ADB3B0F178EF8DB004E9BB9 /* StatusIconAlt@2x.png in Resources */,
7AD1F1D31F7A55EA0048A496 /* iTerm2.scpt in Resources */,
0ADB3B0E178EF8DB004E9BB9 /* StatusIcon@2x.png in Resources */,
C149EC1415D5214600B1F558 /* MainMenu.xib in Resources */,
C159DC2815D5DE8000F5DE24 /* teleport.icns in Resources */,
7A0C94AA1F68BD2900E04C3E /* AboutWindowController.xib in Resources */,
7A1818911F7FBBC200F3C882 /* tp-assist.default.json in Resources */,
7A1818931F815B8A00F3C882 /* Terminal.scpt in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
C149EBF515D5214600B1F558 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7A27E4A91F6A8EEC004FDE5D /* ts_env.cpp in Sources */,
7AA2CD4A1F6AB9750074C92B /* ex_winsrv.cpp in Sources */,
7AA2CD3B1F6A955A0074C92B /* ts_cfg.cpp in Sources */,
A1D700071A5DCE8D003563E4 /* AboutWindowController.m in Sources */,
7AA2CD521F6AB9F10074C92B /* json_value.cpp in Sources */,
C149EC0A15D5214600B1F558 /* main.m in Sources */,
7AA2CD381F6A92620074C92B /* ts_http_rpc.cpp in Sources */,
7AA2CD481F6AB9750074C92B /* ex_thread.cpp in Sources */,
7AA2CD471F6AB9750074C92B /* ex_str.cpp in Sources */,
7AA2CD571F6ABA2E0074C92B /* mongoose.c in Sources */,
7AA2CD541F6AB9F10074C92B /* json_writer.cpp in Sources */,
C149EC1115D5214600B1F558 /* AppDelegate.mm in Sources */,
7A18188F1F7D5D7F00F3C882 /* AppDelegate-C-Interface.cpp in Sources */,
7AA2CD511F6AB9F10074C92B /* json_reader.cpp in Sources */,
7AA2CD461F6AB9750074C92B /* ex_path.cpp in Sources */,
7AA2CD441F6AB9750074C92B /* ex_ini.cpp in Sources */,
7AA2CD451F6AB9750074C92B /* ex_log.cpp in Sources */,
7AA2CD491F6AB9750074C92B /* ex_util.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
6FC541A51D45CF7F00A896E3 /* AboutWindowController.xib */ = {
isa = PBXVariantGroup;
children = (
A1B7B9ED1DB54D6700809327 /* Base */,
A1B7B9F01DB54D8900809327 /* en */,
A1B7B9F11DB54D8C00809327 /* zh-Hans */,
);
name = AboutWindowController.xib;
sourceTree = "<group>";
};
A1B7B9DF1DB53ED200809327 /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
A1B7B9DE1DB53ED200809327 /* en */,
A1B7B9E01DB53ED700809327 /* Base */,
A1B7B9E11DB53EDA00809327 /* zh-Hans */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
C149EC0615D5214600B1F558 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
C149EC0715D5214600B1F558 /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
C149EC1215D5214600B1F558 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
A1B7B9D31DB5361700809327 /* Base */,
A1B7B9EE1DB54D7B00809327 /* zh-Hans */,
A1B7B9EF1DB54D7F00809327 /* en */,
);
name = MainMenu.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
C149EC1515D5214600B1F558 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
../../common/teleport,
../../common/libex/include,
../../external/mongoose,
../../external/jsoncpp/include,
);
MACOSX_DEPLOYMENT_TARGET = 10.9;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
C149EC1615D5214600B1F558 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
../../common/teleport,
../../common/libex/include,
../../external/mongoose,
../../external/jsoncpp/include,
);
MACOSX_DEPLOYMENT_TARGET = 10.9;
SDKROOT = macosx;
};
name = Release;
};
C149EC1815D5214600B1F558 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "src/tp_assist-Prefix.pch";
INFOPLIST_FILE = "src/tp_assist-Info.plist";
MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_BUNDLE_IDENTIFIER = "teleport.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Debug;
};
C149EC1915D5214600B1F558 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "src/tp_assist-Prefix.pch";
INFOPLIST_FILE = "src/tp_assist-Info.plist";
MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_BUNDLE_IDENTIFIER = "teleport.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
C149EBF315D5214600B1F558 /* Build configuration list for PBXProject "tp_assist" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C149EC1515D5214600B1F558 /* Debug */,
C149EC1615D5214600B1F558 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C149EC1715D5214600B1F558 /* Build configuration list for PBXNativeTarget "tp_assist" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C149EC1815D5214600B1F558 /* Debug */,
C149EC1915D5214600B1F558 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = C149EBF015D5214600B1F558 /* Project object */;
}

View File

@ -0,0 +1,82 @@
{
"ssh": {
"selected": "putty",
"available": [
{
"name":"putty",
"display": "PuTTY内置",
"app": "{assist_tools_path}\\putty\\putty.exe",
"cmdline": "-ssh -pw **** -P {host_port} -l {user_name} {host_ip}"
},
{
"name": "crt",
"display": "SecureCRT",
"app": "",
"cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /P {host_port} /PASSWORD **** {user_name}@{host_ip}"
},
{
"name": "xshell",
"display": "Xshell",
"app": "",
"cmdline": "-newtab \"TP#ssh://{real_ip}\" -url ssh://{user_name}:****@{host_ip}:{host_port}"
},
{
"name": "other",
"display": "自定义",
"app": "",
"cmdline": ""
}
]
},
"scp": {
"selected": "winscp",
"available": [
{
"name":"winscp",
"display": "WinSCP内置",
"app": "{assist_tools_path}\\winscp\\winscp.exe",
"cmdline": "/sessionname=\"TP#{real_ip}\" {user_name}:****@{host_ip}:{host_port}"
},
{
"name": "other",
"display": "自定义",
"app": "",
"cmdline": ""
}
]
},
"telnet": {
"selected": "putty",
"available": [
{
"name":"putty",
"display": "PuTTY内置",
"app": "{assist_tools_path}\\putty\\putty.exe",
"cmdline": "telnet://{user_name}@{host_ip}:{host_port}"
},
{
"name": "crt",
"display": "SecureCRT",
"app": "",
"cmdline": "/T /N \"TP#telnet://{real_ip}\" /ARG {user_name} /SCRIPT \"{assist_tools_path}\\securecrt-telnet.vbs\" /TELNET {host_ip} {host_port}"
},
{
"name": "other",
"display": "自定义",
"app": "",
"cmdline": ""
}
]
},
"rdp" : {
"available" : [
{
"app" : "{assist_tools_path}\\tprdp\\tprdp-client.exe",
"cmdline" : "/v:{host_ip}:{host_port} /u:{user_name} /t:\"TP#{real_ip}\"",
"display" : "FreeRDP内置",
"name" : "freerdp"
}
],
"selected" : "freerdp"
}
}

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Some files were not shown because too many files have changed in this diff Show More