From a883f8a80bab8d9c2c1eb881956a8a5d6c5bfecf Mon Sep 17 00:00:00 2001 From: Apex Liu Date: Sun, 11 Nov 2018 06:10:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8macOS=E4=B8=8A=E7=9A=84SSH=E8=BF=9C?= =?UTF-8?q?=E7=A8=8B=E6=97=B6=EF=BC=8C=E4=BD=BF=E7=94=A8Terminal=E6=88=96i?= =?UTF-8?q?Term2=E5=81=9A=E5=AE=A2=E6=88=B7=E7=AB=AF=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E8=87=AA=E5=8A=A8=E5=9B=9E=E8=BD=A6=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E7=99=BB=E5=BD=95=E4=BA=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/cfg/cacert.cer | 23 + client/cfg/localhost.key | 28 ++ client/cfg/localhost.pem | 24 + client/cfg/tp-assist.macos.json | 106 +++++ client/cfg/tp-assist.windows.json | 82 ++++ .../tp_assist_macos/apple-scripts/compile.sh | 8 +- .../scripts/Terminal.applescript | 44 -- ...{iTerm2.applescript => iterm2.applescript} | 0 .../scripts/terminal.applescript | 77 +++ client/tp_assist_macos/site/css/style.css | 2 +- client/tp_assist_macos/site/css/style.css.map | 1 - client/tp_assist_macos/site/index.html | 443 +++++++++--------- client/tp_assist_macos/site/js/config.js | 330 ++++++++++--- client/tp_assist_macos/site/less/style.less | 16 +- .../src/AboutWindowController.m | 27 +- client/tp_assist_macos/src/AppDelegate.mm | 27 +- .../src/Base.lproj/AboutWindowController.xib | 12 +- .../src/Base.lproj/Localizable.strings | 10 + .../src/Base.lproj/MainMenu.xib | 5 +- .../src/apple-scpt/Terminal.scpt | Bin 2394 -> 0 bytes .../apple-scpt/{iTerm2.scpt => iterm2.scpt} | Bin 2094 -> 2058 bytes .../src/apple-scpt/terminal.scpt | Bin 0 -> 2566 bytes client/tp_assist_macos/src/csrc/ts_cfg.cpp | 96 +++- client/tp_assist_macos/src/csrc/ts_cfg.h | 33 +- client/tp_assist_macos/src/csrc/ts_env.cpp | 9 +- .../tp_assist_macos/src/csrc/ts_http_rpc.cpp | 48 +- client/tp_assist_macos/src/csrc/ts_http_rpc.h | 46 +- client/tp_assist_macos/src/csrc/ts_ver.h | 2 +- .../en.lproj/AboutWindowController.strings | 15 +- .../src/en.lproj/MainMenu.strings | 11 +- .../tp_assist_macos/{ => src}/teleport.icns | Bin .../src/tp-assist.default.json | 30 -- .../tp_assist_macos/src/tp_assist-Info.plist | 4 +- client/tp_assist_macos/src/tpassist.png | Bin 0 -> 8341 bytes .../AboutWindowController.strings | 15 +- .../src/zh-Hans.lproj/Localizable.strings | 14 +- .../src/zh-Hans.lproj/MainMenu.strings | 11 +- .../tp_assist.xcodeproj/project.pbxproj | 92 ++-- common/libex/include/ex/ex_ini.h | 2 +- common/libex/src/ex_path.cpp | 4 +- common/libex/src/ex_util.cpp | 314 +++++++------ 41 files changed, 1299 insertions(+), 712 deletions(-) create mode 100644 client/cfg/cacert.cer create mode 100644 client/cfg/localhost.key create mode 100644 client/cfg/localhost.pem create mode 100644 client/cfg/tp-assist.macos.json create mode 100755 client/cfg/tp-assist.windows.json delete mode 100644 client/tp_assist_macos/apple-scripts/scripts/Terminal.applescript rename client/tp_assist_macos/apple-scripts/scripts/{iTerm2.applescript => iterm2.applescript} (100%) create mode 100644 client/tp_assist_macos/apple-scripts/scripts/terminal.applescript delete mode 100644 client/tp_assist_macos/site/css/style.css.map delete mode 100644 client/tp_assist_macos/src/apple-scpt/Terminal.scpt rename client/tp_assist_macos/src/apple-scpt/{iTerm2.scpt => iterm2.scpt} (80%) create mode 100644 client/tp_assist_macos/src/apple-scpt/terminal.scpt rename client/tp_assist_macos/{ => src}/teleport.icns (100%) delete mode 100644 client/tp_assist_macos/src/tp-assist.default.json create mode 100755 client/tp_assist_macos/src/tpassist.png diff --git a/client/cfg/cacert.cer b/client/cfg/cacert.cer new file mode 100644 index 0000000..d8f5d0c --- /dev/null +++ b/client/cfg/cacert.cer @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID4TCCAsmgAwIBAgIBADANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJDTjEN +MAsGA1UECgwEVFA0QTEZMBcGA1UECwwQVFA0QSBUZWxlcG9ydCBDQTEZMBcGA1UE +AwwQVFA0QSBUZWxlcG9ydCBDQTAgFw0xODExMDgxNzMyMjJaGA8yMTE4MTAxNTE3 +MzIyMlowUjELMAkGA1UEBhMCQ04xDTALBgNVBAoMBFRQNEExGTAXBgNVBAsMEFRQ +NEEgVGVsZXBvcnQgQ0ExGTAXBgNVBAMMEFRQNEEgVGVsZXBvcnQgQ0EwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCml/ERetMxXh17Uf4IlLjDfgGwnpQZ +L0UoCO2vAHk0h4eRx5x4fMB/Ml1YHYghVKJ9rxWeb+v5wWz9a8CFtNu+s46nG9cw +XdneQ2UT4L5+7a+mOyNGAcascfLWfUYoMnF0ugIf3OfsUeAwinMnvKi2I2b8XdXH +cXRqToEYmcovPLKaXByXFLjcMHMRwR5Es0zIRx+4uuIvCICndLRX5IGy/HGEPZyV +Vtrrrvkngz54UHB3C3sKuHuHBOxvJ1grJV9fLFptsbPhMonXfYKJpf+ODwmkEDFS ++4vV61ctYvUiElCPeQte23v6lIujqoLoHzYoi8J5BxEwBggeCgAZ/YYFAgMBAAGj +gb8wgbwwHQYDVR0OBBYEFKHqO88fYp8ard6SKPi8X4Gpr+uiMHoGA1UdIwRzMHGA +FKHqO88fYp8ard6SKPi8X4Gpr+uioVakVDBSMQswCQYDVQQGEwJDTjENMAsGA1UE +CgwEVFA0QTEZMBcGA1UECwwQVFA0QSBUZWxlcG9ydCBDQTEZMBcGA1UEAwwQVFA0 +QSBUZWxlcG9ydCBDQYIBADAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjANBgkqhkiG9w0BAQsFAAOCAQEAQWYR/WBsaWEwTE9IuoULsGs0G5CWwfIvezil +HUmtQQb2G3P0kxv43xU3PT3czfbd22h9diSHyyYXOShHIfNx7ZD4SUMGyukcfPst +oyLcnlMK2hxtu3s5hTc76D+m7ylLQgV52jwHOXXS9toRhIo76HY6Q5Qbz9koP/x+ +MOwmNJ+dLQj/qI1WZZI7FS7Idi2dB5KMp11a2kxgeBIxwkCreBm/MLfdLRyaMdGX +1L05AI0d7lCu+N+Fu2QX9wToBZ4rRQFrdakgCXqXCdM1O4Akf1KvCDXHUJKgMQUE +Hav+XOE7nrtxIwfH4VjmCZYRE+8ZTYbG8xSHDwIRMxhsLnb63w== +-----END CERTIFICATE----- diff --git a/client/cfg/localhost.key b/client/cfg/localhost.key new file mode 100644 index 0000000..852ff91 --- /dev/null +++ b/client/cfg/localhost.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDxI1ZDRvuNnkVB +JgTZmnwF97d7Ace+R0gSSkWi2l2oezakLSdUUkiysr1wx45u2Du36FNqMGg7LiCZ +SX1e2Zba96PI6vwNGnlprCfXTe2eV3W8kMPKA6c9X8BTktMZINNHO3K591jGx+uM +fyrl6/CFVPHNkl73Ium9u91JXIX9BOata4RTlphmHADc+hPXuC6oeN8qayZvV2rV +Jfx1wMlWCMiGJM36JJO5pywteBCKQkVJuJ7y29XF2wT690o+i6ugk+yI2/2OpiET +2E5SYdvyhlbcU+iBERsnY3X7IvFY8/m00YIjIc3reGSEwt9M5WTPRCjgonnpQGAx +9xWXwqkzAgMBAAECggEAT9b2YdInye0EWxy+cFoBBGzPeE/PlcW+LCghRFlutzEM +l3FH21hfL6OUq7m3BCZeJ3cp3zfl2upb6sT1WKlMlHV36jc7ew8v8fgJPPVVXp7w +oZ2A5estvVltsX4knOZMbgJV6xLldvOMnvkf9/6VpV/Jq9nxzXvmzmZcT0TuLCaF +uPk/g/yD5qQ8LkWXDVJeBiDrrOZYo5F+T8bveYKKIEZV0ZAlXwJqVOUFnhffIaDF +fZVDOv4K3+q0aRDLTY2hxptHZiKzpLXgU634nBN3fiy0Fj88upNIus22gjaz+Jfx +2pYv22iGNXAMFQwGaeuT7d4+qhgxze8C7YlLJsJWCQKBgQD8kkXbgYG+8NoKmovz +ki9nuK1R6On5pNjZ344SJm6t/s4FaxQhE/4oHvODwgolqKyT2Sq1K8/5NInRGA29 +xPqqkkhwWk3Zf9VTXgmuXsOikPhbCOuiehO+6/ZthmHYy1jBMqkAIWYaL9Ytn2qb +dKMHwzNdnppQNdQnwmXI2ZdRBQKBgQD0aVTSOmKfKdIxH9qFLdbi2CoyJMzjAjm9 +Ss5M0OhI9wZnCXyjPBx4hOs+M/BKx4lQ296u2Dh+gSK3L8K3x8lVqqx8gd614qaC +EWzXZpAbd1S835o2vVYEWXU0iI9s0jkj+VnILEWBMRPYManRUATB2phwRPulimdu +o+BWN0GG1wKBgCYBxO1hMasQB1+tHf5LM0MCcWJwEDV27wLqNzDYA7O/MjVyhZbs +sURMVAyxuGEuXrno5hpZO3SeyVZjrj2uVKIyXSA7FpfyOqHO9tn8fKgL9LOORhcv +E6WZUH3uyO6cuwBnpTLV082BAVPgN2SpSpcycppV8Za8Yu6QvExbIgAZAoGBALcq +ANETxDj3hHggIQlRkwqpaOXvQkSVtGOxne1fWdTkmz24lFlYgRWotwsErX29D6Ez +RSzPCXd0m2mhN1G3PaEfqOgeA6NXWeV73Y+HY1PSGAT7pXyEY+QajoVyGdo5qWzW +P3yOAQCSoQaSIWulhgspILhyWgxzLpRx53t1KXw9AoGBAOxsrIrx/S6onTz58ncZ +m99OWwJX4WmY5KKhc5dWrfgHrNfldSbhjRhjALy6hSPzkaVy01wXKeeIZl64rUbd +S/r58yALQ5wuIHAi53BLStxgqEdHQHLg16GqL3b/+Waaf+Fy9y5eoUQ976HPr33G +uDJ1AAnWjX3KvcyZeWLFTU2/ +-----END PRIVATE KEY----- diff --git a/client/cfg/localhost.pem b/client/cfg/localhost.pem new file mode 100644 index 0000000..b91d7e1 --- /dev/null +++ b/client/cfg/localhost.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEGTCCAwGgAwIBAgIEASUKPDANBgkqhkiG9w0BAQsFADBSMQswCQYDVQQGEwJD +TjENMAsGA1UECgwEVFA0QTEZMBcGA1UECwwQVFA0QSBUZWxlcG9ydCBDQTEZMBcG +A1UEAwwQVFA0QSBUZWxlcG9ydCBDQTAgFw0xODExMDgxNzMyMjdaGA8yMTE4MTAx +NTE3MzIyN1owXzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkJKMQswCQYDVQQHDAJ0 +cDERMA8GA1UECgwIVGVsZXBvcnQxDzANBgNVBAsMBkFzc2lzdDESMBAGA1UEAwwJ +bG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8SNWQ0b7 +jZ5FQSYE2Zp8Bfe3ewHHvkdIEkpFotpdqHs2pC0nVFJIsrK9cMeObtg7t+hTajBo +Oy4gmUl9XtmW2vejyOr8DRp5aawn103tnld1vJDDygOnPV/AU5LTGSDTRztyufdY +xsfrjH8q5evwhVTxzZJe9yLpvbvdSVyF/QTmrWuEU5aYZhwA3PoT17guqHjfKmsm +b1dq1SX8dcDJVgjIhiTN+iSTuacsLXgQikJFSbie8tvVxdsE+vdKPouroJPsiNv9 +jqYhE9hOUmHb8oZW3FPogREbJ2N1+yLxWPP5tNGCIyHN63hkhMLfTOVkz0Qo4KJ5 +6UBgMfcVl8KpMwIDAQABo4HnMIHkMB0GA1UdDgQWBBRc5d0h39QISTM55kCqPyy1 +dohEHTB6BgNVHSMEczBxgBSh6jvPH2KfGq3ekij4vF+Bqa/roqFWpFQwUjELMAkG +A1UEBhMCQ04xDTALBgNVBAoMBFRQNEExGTAXBgNVBAsMEFRQNEEgVGVsZXBvcnQg +Q0ExGTAXBgNVBAMMEFRQNEEgVGVsZXBvcnQgQ0GCAQAwDAYDVR0TAQH/BAIwADAO +BgNVHQ8BAf8EBAMCA4gwEwYDVR0lBAwwCgYIKwYBBQUHAwEwFAYDVR0RBA0wC4IJ +bG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQAfj/CpFDhv5CrnN2kxhtRAmesJ +q6/KxxkBaimjbS/BpfvqfC9RxGH7MIqGUkbC4/ADkEt2OmVU4+f2R3+rCl+x+r1t +9+3r/JSYYVBxFnF1GbDhiY9sKahgb4HoFjE2Fj8eVODcEzdApLr198p5IIIyfBys +WHV4CYFMvq5qCKbSR/JMfrm9GArAh1J+B+JMIfm8xwerFi0tfK2YT+N4QkvbidjG +sd+RKlR51GHo9m4iEQ7mDd9H8joVrVs2MVLGf2EoVU5y/Ahee4g7k3SKrn3GI/Ec +6BRCht+INCLI3bnC3MtJHJRzv5Vmu4pSh3cwnVHfe+VWLGvGlp2+KeC02xZ2 +-----END CERTIFICATE----- diff --git a/client/cfg/tp-assist.macos.json b/client/cfg/tp-assist.macos.json new file mode 100644 index 0000000..ceafa76 --- /dev/null +++ b/client/cfg/tp-assist.macos.json @@ -0,0 +1,106 @@ +{ + "file_version": 3, + "ssh": { + "selected": "terminal", + "available": [ + { + "name":"terminal", + "display": "终端(系统自带)", + "app": "Terminal.app", + "cmdline": "Basic", + "desc": [] + }, + { + "name": "iterm2", + "display": "iTerm2", + "app": "iTerm2.app", + "cmdline": "Default", + "desc": [] + }, + { + "name": "securecrt", + "display": "SecureCRT", + "app": "SecureCRT.app", + "cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /P {host_port} /PASSWORD **** {user_name}@{host_ip}", + "desc": [] + }, + { + "name": "other", + "display": "自定义", + "app": "", + "cmdline": "", + "desc": [] + } + ] + }, + + "sftp": { + "selected": "securefx", + "available": [ + { + "name": "securefx", + "display": "SecureFX", + "app": "SecureCRT.app", + "cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /P {host_port} /PASSWORD **** {user_name}@{host_ip}", + "desc": [] + }, + { + "name": "other", + "display": "自定义", + "app": "", + "cmdline": "", + "desc": [] + } + ] + }, + + "telnet": { + "selected": "terminal", + "available": [ + { + "name":"terminal", + "display": "终端(系统自带)", + "app": "Terminal.app", + "cmdline": "Basic", + "desc": [] + }, + { + "name": "iterm2", + "display": "iTerm2", + "app": "iTerm2.app", + "cmdline": "Default", + "desc": [] + }, + { + "name": "securecrt", + "display": "SecureCRT", + "app": "SecureCRT.app", + "cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /P {host_port} /PASSWORD **** {user_name}@{host_ip}", + "desc": [] + }, + { + "name": "other", + "display": "自定义", + "app": "", + "cmdline": "", + "desc": [] + } + ] + }, + + "rdp": { + "selected": "freerdp", + "available": [ + { + "name": "FreeRDP", + "display": "FreeRDP", + "app": "", + "cmdline": "", + "desc": [ + "建议使用homebrew安装freerdp,安装后freerdp默认路径在:/usr/local/Cellar/freerdp/x.y.z/bin/xfreerdp", + "首次安装freerdp后需要重新启动计算机" + ] + } + ] + } +} diff --git a/client/cfg/tp-assist.windows.json b/client/cfg/tp-assist.windows.json new file mode 100755 index 0000000..f4fc876 --- /dev/null +++ b/client/cfg/tp-assist.windows.json @@ -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" + } +} diff --git a/client/tp_assist_macos/apple-scripts/compile.sh b/client/tp_assist_macos/apple-scripts/compile.sh index 97b2bc1..7503566 100755 --- a/client/tp_assist_macos/apple-scripts/compile.sh +++ b/client/tp_assist_macos/apple-scripts/compile.sh @@ -4,8 +4,8 @@ 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 +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 +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 diff --git a/client/tp_assist_macos/apple-scripts/scripts/Terminal.applescript b/client/tp_assist_macos/apple-scripts/scripts/Terminal.applescript deleted file mode 100644 index 3b78a92..0000000 --- a/client/tp_assist_macos/apple-scripts/scripts/Terminal.applescript +++ /dev/null @@ -1,44 +0,0 @@ -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 diff --git a/client/tp_assist_macos/apple-scripts/scripts/iTerm2.applescript b/client/tp_assist_macos/apple-scripts/scripts/iterm2.applescript similarity index 100% rename from client/tp_assist_macos/apple-scripts/scripts/iTerm2.applescript rename to client/tp_assist_macos/apple-scripts/scripts/iterm2.applescript diff --git a/client/tp_assist_macos/apple-scripts/scripts/terminal.applescript b/client/tp_assist_macos/apple-scripts/scripts/terminal.applescript new file mode 100644 index 0000000..3357a40 --- /dev/null +++ b/client/tp_assist_macos/apple-scripts/scripts/terminal.applescript @@ -0,0 +1,77 @@ +on scriptRun(argsCmd, argsProfile, argsTitle) + set theCmd to (argsCmd) + set theProfile to (argsProfile) + set theTitle to (argsTitle) + set useless to "useless" + 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 + delay 1.0 + 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 + + delay 1.0 + reopen + activate + tell application "System Events" to key code 36 + 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 + + 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 + + delay 1.0 + reopen + activate + tell application "System Events" to key code 36 + + 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.5 + keystroke "t" using {command down} + end tell + end tell + + reopen + activate + do script theCmd in front window + + 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 + + delay 1.0 + reopen + activate + tell application "System Events" to key code 36 + + 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 diff --git a/client/tp_assist_macos/site/css/style.css b/client/tp_assist_macos/site/css/style.css index 82956e3..36da044 100644 --- a/client/tp_assist_macos/site/css/style.css +++ b/client/tp_assist_macos/site/css/style.css @@ -1 +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 */ \ No newline at end of file +@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;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;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{padding-left:3px;padding-right:3px}.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:164px}#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 */ \ No newline at end of file diff --git a/client/tp_assist_macos/site/css/style.css.map b/client/tp_assist_macos/site/css/style.css.map deleted file mode 100644 index f0bfed4..0000000 --- a/client/tp_assist_macos/site/css/style.css.map +++ /dev/null @@ -1 +0,0 @@ -{"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"} \ No newline at end of file diff --git a/client/tp_assist_macos/site/index.html b/client/tp_assist_macos/site/index.html index 13850f3..e942ef6 100644 --- a/client/tp_assist_macos/site/index.html +++ b/client/tp_assist_macos/site/index.html @@ -1,220 +1,225 @@ - - - - - - - TELEPORT助手配置 - - - - - - - - - - - - -
-
- Teleport助手本地配置 - - 此处配置保存到本地计算机上,如果更换计算机,需要重新配置! -
-
- - - - -
- -
-
-

此处配置保存到本地计算机上,如果更换计算机,需要重新配置!

- 注意:命令行参数设置中,可以用以下变量替换(注意大小写!): -
    -
  • {host_ip} 替换主机IP地址
  • -
  • {host_port} 替换主机端口号
  • -
  • {user_name} 替换用户名
  • -
  • {real_ip} 替换为远程主机真实IP(仅用于显示,例如客户端的窗口标题或标签页标题等)
  • -
-
- -
-

本地 SSH 客户端配置

- -
-
- -
- -
-
- -
- -
-
- - -
-
-
- -
- -
- -
-
- -
- -
-

本地 SFTP 客户端配置

- - -
-
- -
- -
-
- -
- -
-
- - -
-
-
- -
- -
- -
-
- -
- -
-

本地 TELNET 客户端配置

- -
-
- -
- -
-
- -
- -
-
- - -
-
-
- -
- -
- -
-
- -
- -
-

本地RDP配置

- -
-
- -
- -
-
- -
- -
-
- - -
-
-
- -
- -
- -
-
- -
- -
-

本地RDP配置

- -
-
- -
- -
-
-
- -
- - 建议使用homebrew安装freerdp,安装后freerdp默认路径在:/usr/local/Cellar/freerdp/x.y.z/bin/xfreerdp - 首次安装freerdp后需要重新启动计算机 -
-
-
- - -
-
-
-
- -
-
- - -
- -
- - - - - - - - - - - - - - + + + + + + + + + + + TELEPORT助手配置 + + + + + + + + + + + + +
+
+ Teleport 助手本地配置 + +
+
+
+ + + + +
+ +
+ +
+

此处配置保存到本地计算机上,如果更换计算机,需要重新配置!

+ 注意:命令行参数设置中,可以用以下变量替换(注意大小写!): +
    +
  • {host_ip} 替换主机IP地址
  • +
  • {host_port} 替换主机端口号
  • +
  • {user_name} 替换用户名
  • +
  • {real_ip} 替换为远程主机真实IP(仅用于显示,例如客户端的窗口标题或标签页标题等)
  • +
  • {assist_tools_path} 替换为助手工具所在的tools目录的绝对路径
  • +
+
+ + +
+

本地 SSH 客户端配置

+ +
+
+ +
+ +
+
+ +
+ +
+
+ + +
+
+
+ +
+ +
+ +
+
+
+ + +
+

本地 SFTP 客户端配置

+ +
+
+ +
+ +
+
+ +
+ +
+
+ + +
+
+
+ +
+ +
+ +
+
+ +
+ + +
+

本地 TELNET 客户端配置

+ +
+
+ +
+ +
+
+ +
+ +
+
+ + +
+
+
+ +
+ +
+ +
+
+ +
+ + +
+

本地 RDP 客户端配置

+ + + + + + + + + + + + + +
+
+ +
+ +
+
+ +
+ +
+
+ + +
+
+
+ +
+ +
+ +
+
+
+ + +
+
+
+
+ +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/tp_assist_macos/site/js/config.js b/client/tp_assist_macos/site/js/config.js index 66900e9..4722b3f 100644 --- a/client/tp_assist_macos/site/js/config.js +++ b/client/tp_assist_macos/site/js/config.js @@ -5,16 +5,53 @@ var g_url_base = 'http://127.0.0.1:50022'; var g_cfg = null; var dom = { - term_type: $('#term-type'), - term_profile: $('#term-profile'), + version: $('#version'), + + ssh_type: $('#ssh-type'), + ssh_app: $('#ssh-app'), + ssh_cmdline: $('#ssh-cmdline'), + ssh_select_app: $('#ssh-select-app'), + + sftp_type: $('#sftp-type'), + sftp_app: $('#sftp-app'), + sftp_cmdline: $('#sftp-cmdline'), + sftp_select_app: $('#sftp-select-app'), + + telnet_type: $('#telnet-type'), + telnet_app: $('#telnet-app'), + telnet_cmdline: $('#telnet-cmdline'), + telnet_select_app: $('#telnet-select-app'), + rdp_type: $('#rdp-type'), rdp_app: $('#rdp-app'), + rdp_cmdline: $('#rdp-cmdline'), + rdp_select_app: $('#rdp-select-app'), btn_save: $('#btn-save') }; +function get_version() { + $.ajax({ + type: 'GET', + timeout: 5000, + url: g_url_base + '/api/get_version', + jsonp: 'callback', + dataType: 'json', + success: function (ret) { + if (ret.code == 0) { + dom.version.text('v' + ret.version); + } else { + alert("获取助手版本信息失败!"); + } + }, + error: function (jqXhr, _error, _e) { + console.log('state:', jqXhr.state()); + alert("获取助手版本信息失败!"); + } + }); +} -var get_config = function () { +function get_config() { $.ajax({ type: 'GET', timeout: 5000, @@ -24,51 +61,122 @@ var get_config = function () { success: function (ret) { if (ret.code == 0) { g_cfg = ret.data; + console.log(g_cfg); update_dom(); } else { - notify_error("获取配置信息失败!"); + alert("获取配置信息失败!"); } }, error: function (jqXhr, _error, _e) { console.log('state:', jqXhr.state()); - notify_error("获取配置信息失败!"); + alert("获取配置信息失败!"); } }); } function update_dom() { - console.log('---', g_cfg); + if (_.isNull(g_cfg)) + return; - dom.term_type.html(''); - - if (!_.isUndefined(g_cfg.term)) { - if (_.isUndefined(g_cfg.term.selected)) { - g_cfg.term.selected = ''; + dom.ssh_type.html(''); + if (!_.isUndefined(g_cfg.ssh)) { + if (_.isUndefined(g_cfg.ssh.selected)) { + g_cfg.ssh.selected = ''; } - if (!_.isUndefined(g_cfg.term.available) && g_cfg.term.available.length > 0) { + if (!_.isUndefined(g_cfg.ssh.available) && g_cfg.ssh.available.length > 0) { var selected = ''; - var profile = ''; + var app = ''; + var cmdline = ''; var html = []; - for (var i = 0; i < g_cfg.term.available.length; i++) { - var item = g_cfg.term.available[i]; + for (var i = 0; i < g_cfg.ssh.available.length; i++) { + var item = g_cfg.ssh.available[i]; - if (selected === '' || item.name === g_cfg.term.selected) { + if (selected === '' || item.name === g_cfg.ssh.selected) { selected = item.name; - profile = item.profile; + app = item.app; + cmdline = item.cmdline; } - html.push(''); + html.push(''); } - dom.term_type.html(html.join('')); + dom.ssh_type.html(html.join('')); - dom.term_type.val(selected); - dom.term_profile.val(profile); + dom.ssh_type.val(selected); + dom.ssh_app.val(app); + dom.ssh_cmdline.val(cmdline); } } + dom.sftp_type.html(''); + if (!_.isUndefined(g_cfg.sftp)) { + if (_.isUndefined(g_cfg.sftp.selected)) { + g_cfg.sftp.selected = ''; + } + + if (!_.isUndefined(g_cfg.sftp.available) && g_cfg.sftp.available.length > 0) { + var selected = ''; + var app = ''; + var cmdline = ''; + + var html = []; + for (var i = 0; i < g_cfg.sftp.available.length; i++) { + var item = g_cfg.sftp.available[i]; + + if (selected === '' || item.name === g_cfg.sftp.selected) { + selected = item.name; + app = item.app; + cmdline = item.cmdline; + } + + html.push(''); + } + + dom.sftp_type.html(html.join('')); + + dom.sftp_type.val(selected); + dom.sftp_app.val(app); + dom.sftp_cmdline.val(cmdline); + } + } + + + dom.telnet_type.html(''); + if (!_.isUndefined(g_cfg.telnet)) { + if (_.isUndefined(g_cfg.telnet.selected)) { + g_cfg.telnet.selected = ''; + } + + if (!_.isUndefined(g_cfg.telnet.available) && g_cfg.telnet.available.length > 0) { + var selected = ''; + var app = ''; + var cmdline = ''; + + var html = []; + for (var i = 0; i < g_cfg.telnet.available.length; i++) { + var item = g_cfg.telnet.available[i]; + + if (selected === '' || item.name === g_cfg.telnet.selected) { + selected = item.name; + app = item.app; + cmdline = item.cmdline; + } + + html.push(''); + } + + dom.telnet_type.html(html.join('')); + + dom.telnet_type.val(selected); + dom.telnet_app.val(app); + dom.telnet_cmdline.val(cmdline); + } + } + + + dom.rdp_type.html(''); if (!_.isUndefined(g_cfg.rdp)) { if (_.isUndefined(g_cfg.rdp.selected)) { g_cfg.rdp.selected = ''; @@ -77,6 +185,7 @@ function update_dom() { if (!_.isUndefined(g_cfg.rdp.available) && g_cfg.rdp.available.length > 0) { var selected = ''; var app = ''; + var cmdline = ''; var html = []; for (var i = 0; i < g_cfg.rdp.available.length; i++) { @@ -85,60 +194,55 @@ function update_dom() { if (selected === '' || item.name === g_cfg.rdp.selected) { selected = item.name; app = item.app; + cmdline = item.cmdline; } - html.push(''); + html.push(''); } dom.rdp_type.html(html.join('')); dom.rdp_type.val(selected); dom.rdp_app.val(app); + dom.rdp_cmdline.val(cmdline); } } } -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(); + var i = 0; + for (i = 0; i < g_cfg.ssh.available.length; i++) { + var item = g_cfg.ssh.available[i]; + if (item.name === g_cfg.ssh.selected) { + item.app = dom.ssh_app.val(); + item.cmdline = dom.ssh_cmdline.val(); break; } } - for (var i = 0; i < g_cfg.rdp.available.length; i++) { + for (i = 0; i < g_cfg.sftp.available.length; i++) { + var item = g_cfg.sftp.available[i]; + if (item.name === g_cfg.sftp.selected) { + item.app = dom.sftp_app.val(); + item.cmdline = dom.sftp_cmdline.val(); + break; + } + } + for (i = 0; i < g_cfg.telnet.available.length; i++) { + var item = g_cfg.telnet.available[i]; + if (item.name === g_cfg.telnet.selected) { + item.app = dom.telnet_app.val(); + item.cmdline = dom.telnet_cmdline.val(); + break; + } + } + for (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(); + item.cmdline = dom.rdp_cmdline.val(); break; } } @@ -165,6 +269,30 @@ function on_save() { }); } +var select_local_file = function (callback) { + var data = { + action: 1 + }; + var args_ = encodeURIComponent(JSON.stringify(data)); + + $.ajax({ + type: 'GET', + timeout: -1, + url: g_url_base + '/api/file_action/' + args_, + jsonp: 'callback', + dataType: 'json', + success: function (ret) { + if(ret.code === 0) + callback(0, ret.path); + }, + error: function (jqXhr, _error, _e) { + console.log('state:', jqXhr.state()); + callback(-1, ""); + } + }); +} + + function notify_error(message_, title_) { var _title = title_ || ''; $.gritter.add({ @@ -188,18 +316,104 @@ function notify_success(message_, title_) { }); }; - $(document).ready(function () { + get_version(); + get_config(); - dom.term_type.change(function () { - on_term_change(); + dom.ssh_type.change(function () { + g_cfg.ssh.selected = dom.ssh_type.val(); + for (var i = 0; i < g_cfg.ssh.available.length; i++) { + var item = g_cfg.ssh.available[i]; + if (item.name === g_cfg.ssh.selected) { + dom.ssh_app.val(item.app); + dom.ssh_cmdline.val(item.cmdline); + return; + } + } + notify_error('所选的配置项不存在!'); }); + dom.ssh_select_app.click(function () { + select_local_file(function (code, path) { + if (code == 0) { + dom.ssh_app.val(path); + } else { + console.log("can not select file."); + } + }); + }); + + + dom.sftp_type.change(function () { + g_cfg.sftp.selected = dom.sftp_type.val(); + for (var i = 0; i < g_cfg.sftp.available.length; i++) { + var item = g_cfg.sftp.available[i]; + if (item.name === g_cfg.sftp.selected) { + dom.sftp_app.val(item.app); + dom.sftp_cmdline.val(item.cmdline); + return; + } + } + notify_error('所选的配置项不存在!'); + }); + dom.sftp_select_app.click(function () { + select_local_file(function (code, path) { + if (code == 0) { + dom.sftp_app.val(path); + } else { + console.log("can not select file."); + } + }); + }); + + + dom.telnet_type.change(function () { + g_cfg.telnet.selected = dom.telnet_type.val(); + for (var i = 0; i < g_cfg.telnet.available.length; i++) { + var item = g_cfg.telnet.available[i]; + if (item.name === g_cfg.telnet.selected) { + dom.telnet_app.val(item.app); + dom.telnet_cmdline.val(item.cmdline); + return; + } + } + notify_error('所选的配置项不存在!'); + }); + dom.telnet_select_app.click(function () { + select_local_file(function (code, path) { + if (code == 0) { + dom.telnet_app.val(path); + } else { + console.log("can not select file."); + } + }); + }); + + dom.rdp_type.change(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); + dom.rdp_cmdline.val(item.cmdline); + return; + } + } + notify_error('所选的配置项不存在!'); }); + dom.rdp_select_app.click(function () { + select_local_file(function (code, path) { + if (code == 0) { + dom.rdp_app.val(path); + } else { + console.log("can not select file."); + } + }); + }); + dom.btn_save.click(function () { on_save(); }); -}); +}); \ No newline at end of file diff --git a/client/tp_assist_macos/site/less/style.less b/client/tp_assist_macos/site/less/style.less index 964264a..6560fe8 100644 --- a/client/tp_assist_macos/site/less/style.less +++ b/client/tp_assist_macos/site/less/style.less @@ -30,7 +30,7 @@ html, body { //text-align: center; line-height: @header-height; //border-bottom: 1px solid darken(@toolbar-bg, 20%); - font-size: 80%; + //font-size: 80%; background-color: #3b3b3b; color: #fff; @@ -58,7 +58,7 @@ html, body { line-height: @footer-height; background-color: @toolbar-bg; border-top: 1px solid darken(@toolbar-bg, 20%); - font-size: 80%; + //font-size: 80%; z-index: 999; } @@ -74,24 +74,18 @@ html, body { 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 { + .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 { padding-left: 3px; padding-right: 3px; } .arg-detail { - font-size: 11px; + //font-size: 13px; 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; @@ -111,7 +105,7 @@ html, body { font-weight: bold; font-family: @font-family-mono; display: inline-block; - width: 128px; + width: 164px; //margin-right:20px; } diff --git a/client/tp_assist_macos/src/AboutWindowController.m b/client/tp_assist_macos/src/AboutWindowController.m index d7d2d98..32d17b6 100644 --- a/client/tp_assist_macos/src/AboutWindowController.m +++ b/client/tp_assist_macos/src/AboutWindowController.m @@ -38,28 +38,29 @@ NSDictionary *plistDict; plistDict = [[NSBundle mainBundle] infoDictionary]; //Get the application name. - id applicationName = [plistDict objectForKey:@"CFBundleName"]; +// id applicationName = [plistDict objectForKey:@"CFBundleName"]; //Get the build version. id applicationVersion = [plistDict objectForKey:@"CFBundleVersion"]; //Get the copyright. - id applicationCopyright = [plistDict objectForKey:@"NSHumanReadableCopyright"]; +// id applicationCopyright = [plistDict objectForKey:@"NSHumanReadableCopyright"]; //Build the string for the windows title. - NSString *aboutTitle = [NSString stringWithFormat:@"%@%@", NSLocalizedString(@"About ",nil), applicationName]; - [aboutWindow.window setTitle:aboutTitle]; + // NSString *aboutTitle = [NSString stringWithFormat:@"%@%@", NSLocalizedString(@"About ",nil), applicationName]; + NSString *strTitle = [NSString stringWithFormat:@"%@%@", + NSLocalizedString(@"about ",nil), + NSLocalizedString(@"app_name",nil)]; + [aboutWindow.window setTitle:strTitle]; //Build the string for the application name. appName - tagline - NSString *progName = [NSString stringWithFormat:@"%@", NSLocalizedString(@"Teleport Assist",nil)]; - [appName setStringValue:progName]; + NSString *strProgName = [NSString stringWithFormat:@"%@", NSLocalizedString(@"app_full_name", nil)]; + [appName setStringValue:strProgName]; //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]; - + NSString *strVersion = [NSString stringWithFormat:@"%@%@", NSLocalizedString(@"version", nil), applicationVersion]; + [appVersion setStringValue:strVersion]; + + NSString *strCopyright = [NSString stringWithFormat:@"%@", NSLocalizedString(@"copyright", nil)]; + [appCopyright setStringValue:strCopyright]; } - (IBAction)btnHomepage:(id)sender { diff --git a/client/tp_assist_macos/src/AppDelegate.mm b/client/tp_assist_macos/src/AppDelegate.mm index 1791214..c9ed446 100644 --- a/client/tp_assist_macos/src/AppDelegate.mm +++ b/client/tp_assist_macos/src/AppDelegate.mm @@ -44,7 +44,7 @@ int AppDelegate_start_ssh_client (void *_self, const char* cmd_line, const char* // 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"]; + NSString *cfgFileInResource = [[NSBundle mainBundle] pathForResource:@"tp-assist.macos" ofType:@"json"]; [[NSFileManager defaultManager] copyItemAtPath:cfgFileInResource toPath:cfgFile error:nil]; } @@ -67,9 +67,6 @@ int AppDelegate_start_ssh_client (void *_self, const char* cmd_line, const char* // 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]; @@ -87,11 +84,20 @@ int AppDelegate_start_ssh_client (void *_self, const char* cmd_line, const char* else msg = @"发生未知错误!"; - NSAlert *alert = [NSAlert alertWithMessageText:@"无法启动Teleport助手" - defaultButton:@"确定" - alternateButton:Nil - otherButton:Nil - informativeTextWithFormat:msg]; + NSAlert *alert = [[NSAlert alloc] init]; + alert.icon = [NSImage imageNamed:@"tpassist"]; + + [alert addButtonWithTitle:@"确定"]; + [alert setMessageText:@"无法启动Teleport助手"]; + [alert setInformativeText:msg]; + + [alert runModal]; + +// NSAlert *alert = [NSAlert alertWithMessageText:@"无法启动Teleport助手" +// defaultButton:@"确定" +// alternateButton:Nil +// otherButton:Nil +// informativeTextWithFormat:@"%@", msg]; [alert runModal]; http_rpc_stop(); @@ -134,7 +140,8 @@ int AppDelegate_start_ssh_client (void *_self, const char* cmd_line, const char* //Create the container event - //We need these constants from the Carbon OpenScripting framework, but we don't actually need Carbon.framework... + // 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' diff --git a/client/tp_assist_macos/src/Base.lproj/AboutWindowController.xib b/client/tp_assist_macos/src/Base.lproj/AboutWindowController.xib index c2bd698..f9946ed 100644 --- a/client/tp_assist_macos/src/Base.lproj/AboutWindowController.xib +++ b/client/tp_assist_macos/src/Base.lproj/AboutWindowController.xib @@ -1,8 +1,8 @@ - + - + @@ -16,11 +16,11 @@ - + - + @@ -53,7 +53,7 @@ - + @@ -73,7 +73,7 @@ - + diff --git a/client/tp_assist_macos/src/Base.lproj/Localizable.strings b/client/tp_assist_macos/src/Base.lproj/Localizable.strings index fc24123..e10f545 100644 --- a/client/tp_assist_macos/src/Base.lproj/Localizable.strings +++ b/client/tp_assist_macos/src/Base.lproj/Localizable.strings @@ -2,3 +2,13 @@ Localizable.strings TPAssist */ + +"app_name" = "Teleport助手"; + +//============================================= +// for About Window +//============================================= +"version" = "Version: "; +"app_full_name" = "Teleport Assist for macOS"; +"copyright" = "Copyright © 2017~2018 TP4A. All rights reserved."; +"visit_tp4a_website" = "Visit Teleport Website" diff --git a/client/tp_assist_macos/src/Base.lproj/MainMenu.xib b/client/tp_assist_macos/src/Base.lproj/MainMenu.xib index a93d3c7..d0fe852 100644 --- a/client/tp_assist_macos/src/Base.lproj/MainMenu.xib +++ b/client/tp_assist_macos/src/Base.lproj/MainMenu.xib @@ -1,8 +1,9 @@ - + - + + diff --git a/client/tp_assist_macos/src/apple-scpt/Terminal.scpt b/client/tp_assist_macos/src/apple-scpt/Terminal.scpt deleted file mode 100644 index 12b084cf91c8ce0cae9026b196149612ff5af379..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2394 zcmcImS#KLv6#mB9?3vVC7ot`bk?0Ff4L`Wqv!U<}{({wx`)7WEcX5tXR zLw*1ch&SjLS)AjqK`{Uy42T&OxqD4sXNJN0d7=AVp2*QI(`U@4PM3uwN>3De ziXCzIY|SzXj@4zB;rm^tLQhZ^hpgpuIn~UFPC4mf?)9^?njkIEV|qk?q8c^yP@#nl zy-D<#`OqVHD(Me+EBIC6hnI=a1G-Q56ncPg95t%-k*(!2E=cAw3f;%fI26%du=4Fj zR(Fl}TtlIIrI@1MF&yso3D_#2hlz2n)u^Vsbcb%!Jk8OpLU%Wabms+;Zf_V#p?L)3 zsCGJZL0Q(x!ya=rbi5~aCCH))z~zz3P86uPyEFNto7;!KO;T!&J@FD{NEiZe+Q zbWNejb<>;JG`(vZq~~E$ToxayXq?9ADvi<=g~r#7Ft%xgs~bd6XtY#fQ}1?kD~B2e ztqc^pQYvw`VP^8(TE5G4ptwd-7(vL`fm*sumuQ48(l8CtAPvw3`W;*7JnyFf{e~d* zQy-n9vvekaTIokG@4o-xdCMa~%^J3FEgj@NELF8MCR6G4Lk;zvKK%|?A2_;LD{?hV zH5*k6h4qKOptXN`u=v5j@*qA~_(bv5m+hrrUz=lO4ad-#Vvx5ohWb7{zKJ*`PGH$f0?+dHV<&3S3LO@5FknJO7Eyi|_`^%j zI&VQEl1L$qFkV^hH@56H_N>>fkYW(|$aEQ%a)Hk^nJ%F&nlo%o)tsW)mCX|M@|e#d zuuLO7u9Ht5nJzNYSTHgT^9(I->6yH(t<30!=6vkPG{obag4Hh5pg@|yIca;B8~8h{@0JK7j3>cR`mAiKh~S)jn_iy z9^27#^-V?HbnJg2I?r&=z~X0bm$TYHZ?#EY@3d|e4UHwYMsWj+yMAU566=CFLF(w> zZ#(Dlx~n>uWCHIRhb`6WNno|R1lH!@#~#*l8a=S#unKdiM-z&SOt$S!l(^4z7F!Ax zTOBF3HV{^6@;s}gU}?5rT;AUz6k-a&=Qn|u)$e`t*DuBMmCQ#{UDWQe^BFy>t|+D# zX6~@%=h^Hh9O4b)0n4zT1GK9u%dih#MQ_R22l&d8=^Q%|fjbM9U3MZ0;tKj~NyaA6 zKO;~^b3!zQU&g}tDKg%mOS|!EexhNvNM+Dy~$ToWa@bAa_afXhtRmXVgjKPvL2%GrV|$s7XlF`o0hRy#2-z%*j(+nu#Y?uz diff --git a/client/tp_assist_macos/src/apple-scpt/iTerm2.scpt b/client/tp_assist_macos/src/apple-scpt/iterm2.scpt similarity index 80% rename from client/tp_assist_macos/src/apple-scpt/iTerm2.scpt rename to client/tp_assist_macos/src/apple-scpt/iterm2.scpt index 2ff77de487265a8a2e31f8cbcdcfee11632c1539..85f01b998cacd8a913ebe8755f9331dde9ba2314 100644 GIT binary patch delta 148 zcmZ1{&?T^;l9?%wV{#+2&*TZrY?IG23vvrEFflN)<|Zcl2Lr{WIGkJ<82uXi4+e^h@mxQD`m~2O0}wD) zPv&NEsApjJG`)WQfdEJd1pWg70|Tc5n1djA9199^GLsWaGV}9_83Y(O7#OafkM;&C z5QMPvCji-u3@jjnfp*G*t+YbcWyO#gl3J9jmsn81z`(~K!obOp$uM~tix{gfgCm3U J=7TJr%m8%bFjoKo diff --git a/client/tp_assist_macos/src/apple-scpt/terminal.scpt b/client/tp_assist_macos/src/apple-scpt/terminal.scpt new file mode 100644 index 0000000000000000000000000000000000000000..bd6e757f8e45b0f2190df2a799dc7364e6fcb96b GIT binary patch literal 2566 zcmcImOK%fb6#m9>uruTMm4qfpNRdjraD#2O-cXvFO=%~plLcK=nv5sy5PNLRjGbo3 z59p$c{s3OxwF}h8f8Y(}T_7Z+2}wvGJW3(Zo}TN86RV0tk;+&ef9F2V`R+O2z1Mp+ zCqJ|&*SjmZD=ofZ0R9LO{S65|i3pGwBg`fuQTX7ezt93dS|tXEGWO9+dZExuY)zxh z(QUKr+7+t~Kdo2_y+C&wvR*0{H7hSV<$e!yZ<=??^3_|+0dkcrR}dQ6WLdV+Ww0nPrx(TjNx^cV9AJ;t^)6wzL`OCx5%@QeY^ zQ0P%Drs#J~mwVd;92C&U#CWZO+e2EW2Xvp7Xp!zI^sq^+lHS8h+3}JIU80NhE24CP&eJ(MOK0dbVu+)IPSHs^5kXk`I>`I>4LtAr zBxnVbWy9w{l651s7ByYXH4pW{hkRi06A~*nEv=B$%H`(6oAwAFjh&t?_v)3#RkjH!jfrA_> zxO>@KkWANks59=A@36MOI;RO5xvNw%E)5d*+ghNy-2CmNU6q1sSTFDCb<^6fE_ZO=c1Nv-5J$O`Fc@> zyb}D#bZ%8Hy5$<8#S>n1wfAgIBo>S0j6ivv(P>7)Uzpd!cSUCmoqTrwYvTlYhXi*| zdfvif8yrVh3|*W%c5#YbjA$Aw?j(YW@p0byh_5x7PSmNEZKsi{&~A)oq|Ybg(r1aO zK114$eTf4h_|$2B`_)4;iP_OqA%p;5L5aD;siX6Kd(|VNae;w1NK8;vZ`xuUfhD%X zL;IyIiP@bDBYblmJAmyNZXCGox#m}R)DZ0x?hVg~)gy`aS4C3?_T$?||4ihagoe0= yj#L~y8aitW($J-0tA@8mtGuf2p`jY@I{W{flscde3`L;vKQ;bS*S<0_@xwoq#pp8t literal 0 HcmV?d00001 diff --git a/client/tp_assist_macos/src/csrc/ts_cfg.cpp b/client/tp_assist_macos/src/csrc/ts_cfg.cpp index afa1f03..341036d 100644 --- a/client/tp_assist_macos/src/csrc/ts_cfg.cpp +++ b/client/tp_assist_macos/src/csrc/ts_cfg.cpp @@ -19,6 +19,20 @@ bool TsCfg::init(void) { if(!_load(file_content)) return false; + if(!m_root.isObject()) { + EXLOGE("invalid config file, not in json format?\n"); + return false; + } + + if(m_root["file_version"].isNull()) { + EXLOGE("invalid config file, maybe need create new one?\n"); + return false; + } + + if(!m_root["file_version"].isInt()) { + + } + return true; } @@ -38,6 +52,78 @@ bool TsCfg::save(const ex_astr& new_value) return true; } +bool TsCfg::_parse_app(const Json::Value& m_root, const ex_astr& str_app, APP_CONFIG& cfg) { + const Json::Value& jApp = m_root[str_app.c_str()]; + if(!jApp.isObject()) + return false; + + if (!jApp["selected"].isString()) { + EXLOGE("invalid config, error 2.\n"); + return false; + } + ex_astr _selected = jApp["selected"].asCString();; + + if (!jApp["available"].isArray() || jApp["available"].size() == 0) { + EXLOGE("invalid config, error 3.\n"); + return false; + } + const Json::Value& jAppList = jApp["available"]; + + int i = 0; + for (i = 0; i < jAppList.size(); ++i) { + if ( + !jAppList[i]["name"].isString() + || !jAppList[i]["app"].isString() + || !jAppList[i]["cmdline"].isString() + || !jAppList[i]["desc"].isArray() + ) { + EXLOGE("invalid config, error 4.\n"); + return false; + } + + if(jAppList[i]["name"].asString().empty()) { + EXLOGE("invalid config, need name.\n"); + return false; + } + + if (jAppList[i]["display"].isNull() || jAppList[i]["display"].asString().empty()) { + cfg.display = jAppList[i]["name"].asCString(); + } else + cfg.display = jAppList[i]["display"].asCString(); + + if (jAppList[i]["name"].asCString() != _selected) + continue; + + cfg.name = jAppList[i]["name"].asCString(); + cfg.display = jAppList[i]["display"].asCString(); + cfg.application = jAppList[i]["app"].asCString(); + cfg.cmdline = jAppList[i]["cmdline"].asCString(); + + if(jAppList[i]["desc"].size() > 0) { +// cfg.description = jApp["available"][i]["app"].asCString(); + + const Json::Value& jAppDescList = jAppList[i]["desc"]; + + int j = 0; + for(j = 0; j < jAppDescList.size(); ++j) { + if(!jAppDescList[i].isString()) + return false; + cfg.description.push_back(jAppDescList[i].asCString()); + } + } + + break; + } + + if (cfg.application.empty() || cfg.cmdline.empty()) { + EXLOGE("invalid config, error 6.\n"); + return false; + } + + return true; +} + + bool TsCfg::_load(const ex_astr& str_json) { Json::Reader jreader; @@ -46,14 +132,13 @@ bool TsCfg::_load(const ex_astr& str_json) { return false; } - ex_astr sel_name; - int i = 0; - ex_astr tmp; - //=================================== // check ssh config //=================================== - + if(!_parse_app(m_root, "ssh", ssh)) + return false; + +#if 0 if (!m_root["ssh"].isObject()) { EXLOGE("invalid config, error 1.\n"); return false; @@ -265,6 +350,7 @@ bool TsCfg::_load(const ex_astr& str_json) { EXLOGE("invalid config, error 6.\n"); return false; } +#endif #if 0 // ------------ term --------------------- diff --git a/client/tp_assist_macos/src/csrc/ts_cfg.h b/client/tp_assist_macos/src/csrc/ts_cfg.h index 1e7b6ec..741b5d9 100644 --- a/client/tp_assist_macos/src/csrc/ts_cfg.h +++ b/client/tp_assist_macos/src/csrc/ts_cfg.h @@ -6,6 +6,14 @@ #include +typedef struct APP_CONFIG { + ex_astr name; + ex_astr display; + ex_astr application; + ex_astr cmdline; + ex_astrs description; +}APP_CONFIG; + class TsCfg { public: @@ -17,29 +25,14 @@ public: 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 ssh_app; - ex_astr ssh_cmdline; - ex_astr scp_app; - ex_astr scp_cmdline; - ex_astr telnet_app; - ex_astr telnet_cmdline; - ex_astr rdp_name; - ex_astr rdp_app; - ex_astr rdp_cmdline; + APP_CONFIG ssh; + APP_CONFIG sftp; + APP_CONFIG telnet; + APP_CONFIG rdp; - -// ex_astr rdp_name; -// ex_astr rdp_display; -// ex_astr rdp_app; - //ex_astr rdp_cmdline; - protected: bool _load(const ex_astr& str_json); + bool _parse_app(const Json::Value& m_root, const ex_astr& str_app, APP_CONFIG& cfg); protected: Json::Value m_root; diff --git a/client/tp_assist_macos/src/csrc/ts_env.cpp b/client/tp_assist_macos/src/csrc/ts_env.cpp index fb7fc8d..fc196d9 100644 --- a/client/tp_assist_macos/src/csrc/ts_env.cpp +++ b/client/tp_assist_macos/src/csrc/ts_env.cpp @@ -1,4 +1,3 @@ -//#include "stdafx.h" #include "ts_env.h" #include @@ -24,12 +23,12 @@ 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/tp4a/teleport/client/tp_assist_macos/site"; -//#else +#ifdef EX_DEBUG + m_site_path = L"/Users/apex/work/tp4a/teleport/client/tp_assist_macos/site"; +#else m_site_path = m_res_path; ex_path_join(m_site_path, false, L"site", NULL); -//#endif +#endif return true; } diff --git a/client/tp_assist_macos/src/csrc/ts_http_rpc.cpp b/client/tp_assist_macos/src/csrc/ts_http_rpc.cpp index d697b93..dc76798 100644 --- a/client/tp_assist_macos/src/csrc/ts_http_rpc.cpp +++ b/client/tp_assist_macos/src/csrc/ts_http_rpc.cpp @@ -1,9 +1,3 @@ -//#include "stdafx.h" - -//#pragma warning(disable:4091) - -//#include -//#include #include #include @@ -15,7 +9,6 @@ #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" @@ -140,7 +133,7 @@ bool TsHttpRpc::init(const char* ip, int port) void TsHttpRpc::_thread_loop(void) { - while (!m_stop_flag) + while (!m_need_stop) { mg_mgr_poll(&m_mg_mgr, 500); } @@ -148,10 +141,10 @@ void TsHttpRpc::_thread_loop(void) EXLOGV("[core] rpc main loop end.\n"); } -void TsHttpRpc::_set_stop_flag(void) -{ - m_stop_flag = true; -} +//void TsHttpRpc::_set_stop_flag(void) +//{ +// m_stop_flag = true; +//} void TsHttpRpc::_mg_event_handler(struct mg_connection *nc, int ev, void *ev_data) { @@ -478,7 +471,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) // RDP //============================================== - if(g_cfg.rdp_app.length() == 0) { + if(g_cfg.rdp.application.length() == 0) { _create_json_ret(buf, TPE_NOT_EXISTS); return; } @@ -546,7 +539,7 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) //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_exec = g_cfg.rdp.application; s_argv.push_back(s_exec.c_str()); { @@ -594,18 +587,21 @@ void TsHttpRpc::_rpc_func_run_client(const ex_astr& func_args, ex_astr& buf) 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; + if(g_cfg.ssh.name == "terminal" || g_cfg.ssh.name == "iterm2") { + 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.ssh.name.c_str(), g_cfg.ssh.cmdline.c_str(), szTitle); + if(ret == 0) + _create_json_ret(buf, TPE_OK); + else + _create_json_ret(buf, TPE_FAILED); + return; + } + } else { diff --git a/client/tp_assist_macos/src/csrc/ts_http_rpc.h b/client/tp_assist_macos/src/csrc/ts_http_rpc.h index 9f5786b..ff31ec3 100644 --- a/client/tp_assist_macos/src/csrc/ts_http_rpc.h +++ b/client/tp_assist_macos/src/csrc/ts_http_rpc.h @@ -14,29 +14,38 @@ /* //================================================================= -ӿʹ˵ -󣬼 127.0.0.1:50022httpʽҪ£ + # HTTP-RPC-INTERFACE: + + listen on http://localhost:50022 and https://localhost:50023. + + ---------------- + GET method: + http://127.0.0.1:50022/method/json_param + + here `json_param` is string in json format and encoded by url_encode(). -GET ʽ -http://127.0.0.1:50022/method/json_param -json_paramʹurl_encodeбjsonʽַ + ---------------- + POST method + http://127.0.0.1:50022/method -POST ʽ -http://127.0.0.1:50022/method -postjson_param + here the data field of POST should be json_param. + + + ## URI detail: + + - method the method to request to execute. + - json_param param of the method and it is optional. -УURIΪ֣ -method ִе񷽷 -json_param 񷽷ĸӲûиӲⲿֿʡԡ + ## RESULT -ظʽִн󣬷һjsonʽַߣʽ£ - -{"code":0,"data":varb} - -УcodeDZеģֵһ룬0ʾɹʧܣûdata򡣲ɹʱdata -ķݣʽݾִе񷽷ͬͬ + A string in json format should returned with following format: + + {"code":0,"data":varb} + `code` field always exists and 0 means success. + `data` field is optional. + */ int http_rpc_start(void* app); @@ -67,7 +76,8 @@ public: protected: void _thread_loop(void); - void _set_stop_flag(void); +// void _set_stop_flag(void); +// void _on_stop(); private: int _parse_request(struct http_message* req, ex_astr& func_cmd, ex_astr& func_args); diff --git a/client/tp_assist_macos/src/csrc/ts_ver.h b/client/tp_assist_macos/src/csrc/ts_ver.h index b2b4e76..a296cc3 100644 --- a/client/tp_assist_macos/src/csrc/ts_ver.h +++ b/client/tp_assist_macos/src/csrc/ts_ver.h @@ -1,6 +1,6 @@ #ifndef __TS_ASSIST_VER_H__ #define __TS_ASSIST_VER_H__ -#define TP_ASSIST_VER L"3.1.0" +#define TP_ASSIST_VER L"3.2.0" #endif // __TS_ASSIST_VER_H__ diff --git a/client/tp_assist_macos/src/en.lproj/AboutWindowController.strings b/client/tp_assist_macos/src/en.lproj/AboutWindowController.strings index 5aa3681..f4d60d1 100644 --- a/client/tp_assist_macos/src/en.lproj/AboutWindowController.strings +++ b/client/tp_assist_macos/src/en.lproj/AboutWindowController.strings @@ -1,15 +1,2 @@ - -/* 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"; +"uUM-88-32s.title" = "Visit Teleport Website"; diff --git a/client/tp_assist_macos/src/en.lproj/MainMenu.strings b/client/tp_assist_macos/src/en.lproj/MainMenu.strings index 136cf79..cb217cb 100644 --- a/client/tp_assist_macos/src/en.lproj/MainMenu.strings +++ b/client/tp_assist_macos/src/en.lproj/MainMenu.strings @@ -15,7 +15,7 @@ "136.title" = "Quit TPAssist"; /* Class = "NSMenuItem"; title = "About"; ObjectID = "638"; */ -"638.title" = "About"; +"638.title" = "About Teleport Assist"; /* Class = "NSMenuItem"; title = "Quit"; ObjectID = "644"; */ "644.title" = "Quit"; @@ -23,11 +23,4 @@ /* 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"; +"pkv-BD-W9b.title" = "Visit Teleport Website"; diff --git a/client/tp_assist_macos/teleport.icns b/client/tp_assist_macos/src/teleport.icns similarity index 100% rename from client/tp_assist_macos/teleport.icns rename to client/tp_assist_macos/src/teleport.icns diff --git a/client/tp_assist_macos/src/tp-assist.default.json b/client/tp_assist_macos/src/tp-assist.default.json deleted file mode 100644 index 7428afb..0000000 --- a/client/tp_assist_macos/src/tp-assist.default.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "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": "" - } - ] - } -} diff --git a/client/tp_assist_macos/src/tp_assist-Info.plist b/client/tp_assist_macos/src/tp_assist-Info.plist index bb67df1..63fffbc 100644 --- a/client/tp_assist_macos/src/tp_assist-Info.plist +++ b/client/tp_assist_macos/src/tp_assist-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 3.1.0 + 3.2.0 CFBundleSignature ???? CFBundleVersion - 3.1.0 + 3.2.0 LSApplicationCategoryType public.app-category.productivity LSMinimumSystemVersion diff --git a/client/tp_assist_macos/src/tpassist.png b/client/tp_assist_macos/src/tpassist.png new file mode 100755 index 0000000000000000000000000000000000000000..ac7d3aca01a789d692d593576868d077a997effa GIT binary patch literal 8341 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

BpBX zTw^l@@b6%F@Zcn_rHz1ot*~rADFvW#WZH+K%ajIV#l zhc>-Q12MljLOue}Y4AG#=1Fj(bdDeZ^; zl0y?D5e}^8+XoXtzn^Ke^{*XoNKk$m%o@H&p>kvW%y0rl#IkY{%X1WHklARO)dSG3 znGdJvWZyX-#WZ=M@jXYh=7z*RyYmp7 zo}@a&jg{VlUocB5k9g>Dolak0pIN(-Y!GWF`e!p%ly^U%G|S@@?R6%&_e$r-*{G|K z`Na|D>24c~8Awk(v|Uma-NM2obGhhkCoL>v1mZz;U-tDRP$5GsmS%cxTr>$NBr5P&wNfs4E?J9Vc)2{=?@$ye1lnc znL@0t7i9o{Z`B^s`pfb9)BtpJLP}uHe>yZ+vZtk&|7Pa_6m!!F&BbA3T}ez7n{Qs= zp5T(wN!4Ivv<@P*{nqn)KdJG01zI^#s>$E4e`>Cdvk3apae-er@w7ooj#7>~jS>@( zBfrg0CZM;vrTY-KQS&gm;4_tV&<*^_L6oky|5H;w?9z#NIa)!dnAxN7$w&dXoI@>S zs^(ZaXQE!d5zt%AgWO{ZhJIi$TA5qz%6wdYq^nuK@AB6L{G6ze?U9RuJ_3RQ*2y(I zw^)cmZ;S@D=M-A6vtZVhTJJzV=T)slf^pb;^8^fC$!{C22y96o_BW}MsV24&Lnn(2 zVDR@KDX)eC_}0Fm&D+16apuJ!ZEo4+!dc1ARwSvb73xxN?@vzWeg}6GwOusCv459{ zstzLT^g%xKbrM_YI7Yqv^|O33l97JccMC*mrwwPa+9N%d*HYbpd%{6=K-u^Rb&L1# zZe=`<3|;iCo(#j{!G2OTMk{X4klF>G44!#i3Z(-Fv^>ytDF+GMvv73oOqis^Sch@O zzYV0SY)ZmXI8!dgt~G?Jd0)zqsye+ttc~Rra;wBa7*B?uy-rBC=R(ueFB?Z4!Ip;gmE*Vkw}vQn9O&O%IVZ9Q+&BUY3^*kF%t< zx|n(MmWER^knfCcmE~*m#6yHOz9;3^VwYm0Qs(dCycqSngi> zo+EtmN0&_)&(Ru-=!b^(dG$bRk-;GlB~ z7#@uI8|&rt6ky|A6z@pw0l9^Zp6~PyCTh<>$=f}{$}&q8Vr_$ZmHeNVwXmYLiOU~0 z3OLg^yle;H2+ovr&wOE9r%hZwJhPlC%Q4`NFEdg%2miVXZA^eLtD~ohfAt;IidfCM za_WfV>CKVF(V3)(^A9fA`;P!$yNltR|1$412GtdTA@{4&YtdDKf`a6f%SJiuEPa#PWBCFXdOXBh@Pn)3R!?3ScDrU zxoht@`sEXY%BuL{XQ_!Nd sK8vwtsjHrxcr8IS=}CQK5rhRuPH?SNmaVn?`=fxmvX0UR1sin_addr), dst, size); // } // -static const char * _inet_ntop_v4(const void *src, char *dst, size_t size) -{ - const char digits[] = "0123456789"; - int i; - struct in_addr *addr = (struct in_addr *)src; - u_long a = ntohl(addr->s_addr); - const char *orig_dst = dst; - - if (size < EX_IPV4_NAME_LEN) { - //errno = ENOSPC; - return NULL; - } - for (i = 0; i < 4; ++i) { - int n = (a >> (24 - i * 8)) & 0xFF; - int non_zerop = 0; - - if (non_zerop || n / 100 > 0) { - *dst++ = digits[n / 100]; - n %= 100; - non_zerop = 1; - } - if (non_zerop || n / 10 > 0) { - *dst++ = digits[n / 10]; - n %= 10; - non_zerop = 1; - } - *dst++ = digits[n]; - if (i != 3) - *dst++ = '.'; - } - *dst++ = '\0'; - return orig_dst; +static const char * _inet_ntop_v4(const void *src, char *dst, size_t size) +{ + const char digits[] = "0123456789"; + int i; + struct in_addr *addr = (struct in_addr *)src; + u_long a = ntohl(addr->s_addr); + const char *orig_dst = dst; + + if (size < EX_IPV4_NAME_LEN) { + //errno = ENOSPC; + return NULL; + } + for (i = 0; i < 4; ++i) { + int n = (a >> (24 - i * 8)) & 0xFF; + int non_zerop = 0; + + if (non_zerop || n / 100 > 0) { + *dst++ = digits[n / 100]; + n %= 100; + non_zerop = 1; + } + if (non_zerop || n / 10 > 0) { + *dst++ = digits[n / 10]; + n %= 10; + non_zerop = 1; + } + *dst++ = digits[n]; + if (i != 3) + *dst++ = '.'; + } + *dst++ = '\0'; + return orig_dst; } -#define IN6ADDRSZ 16 +#define IN6ADDRSZ 16 #define INT16SZ 2 -static const char * _inet_ntop_v6(const ex_u8 *src, char *dst, size_t size) -{ - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[EX_IPV6_NAME_LEN]; - char *tp; - struct { - long base; - long len; - } best, cur; - u_long words[IN6ADDRSZ / INT16SZ]; - int i; - - /* Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, 0, sizeof(words)); - for (i = 0; i < IN6ADDRSZ; i++) - words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); - - best.base = -1; - cur.base = -1; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) - { - if (words[i] == 0) - { - if (cur.base == -1) - cur.base = i, cur.len = 1; - else cur.len++; - } - else if (cur.base != -1) - { - if (best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - if ((cur.base != -1) && (best.base == -1 || cur.len > best.len)) - best = cur; - if (best.base != -1 && best.len < 2) - best.base = -1; - - /* Format the result. - */ - tp = tmp; - size_t tmp_size = 0; - size_t offset = 0; - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) - { - /* Are we inside the best run of 0x00's? - */ - if (best.base != -1 && i >= best.base && i < (best.base + best.len)) - { - if (i == best.base) { - *tp++ = ':'; - offset += 1; - } - continue; - } - - /* Are we following an initial run of 0x00s or any real hex? - */ - if (i != 0) { - *tp++ = ':'; - offset += 1; - } - - /* Is this address an encapsulated IPv4? - */ - if (i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) - { - if (!_inet_ntop_v4(src + 12, tp, sizeof(tmp) - (tp - tmp))) - { - //errno = ENOSPC; - return (NULL); - } - tmp_size = strlen(tp); - tp += tmp_size; - offset += tmp_size; - break; - } - //tp += ex_strformat(tp, "%lX", words[i]); - tmp_size = ex_strformat(tp, EX_IPV6_NAME_LEN-offset, "%lX", words[i]); - tp += tmp_size; - offset += tmp_size; - } - - /* Was it a trailing run of 0x00's? - */ - if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) - *tp++ = ':'; - *tp++ = '\0'; - - /* Check for overflow, copy, and we're done. - */ - if ((size_t)(tp - tmp) > size) - { - //errno = ENOSPC; - return (NULL); - } - //return strcpy(dst, tmp); - return ex_strcpy(dst, size, tmp); - //return (NULL); +static const char * _inet_ntop_v6(const ex_u8 *src, char *dst, size_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[EX_IPV6_NAME_LEN]; + char *tp; + struct { + long base; + long len; + } best, cur; + u_long words[IN6ADDRSZ / INT16SZ]; + int i; + + /* Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, 0, sizeof(words)); + for (i = 0; i < IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + + best.base = -1; + cur.base = -1; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) + { + if (words[i] == 0) + { + if (cur.base == -1) { + cur.base = i; + cur.len = 1; + } + else{ + cur.len++; + } + } + else if (cur.base != -1) + { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + if ((cur.base != -1) && (best.base == -1 || cur.len > best.len)) + best = cur; + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* Format the result. + */ + tp = tmp; + size_t tmp_size = 0; + size_t offset = 0; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) + { + /* Are we inside the best run of 0x00's? + */ + if (best.base != -1 && i >= best.base && i < (best.base + best.len)) + { + if (i == best.base) { + *tp++ = ':'; + offset += 1; + } + continue; + } + + /* Are we following an initial run of 0x00s or any real hex? + */ + if (i != 0) { + *tp++ = ':'; + offset += 1; + } + + /* Is this address an encapsulated IPv4? + */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) + { + if (!_inet_ntop_v4(src + 12, tp, sizeof(tmp) - (tp - tmp))) + { + //errno = ENOSPC; + return (NULL); + } + tmp_size = strlen(tp); + tp += tmp_size; + offset += tmp_size; + break; + } + //tp += ex_strformat(tp, "%lX", words[i]); + tmp_size = ex_strformat(tp, EX_IPV6_NAME_LEN-offset, "%lX", words[i]); + tp += tmp_size; + offset += tmp_size; + } + + /* Was it a trailing run of 0x00's? + */ + if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* Check for overflow, copy, and we're done. + */ + if ((size_t)(tp - tmp) > size) + { + //errno = ENOSPC; + return (NULL); + } + //return strcpy(dst, tmp); + return ex_strcpy(dst, size, tmp); + //return (NULL); +} + +const char* ex_inet_ntop(int af, const void *src, char *dst, size_t size) { + switch (af) { + case AF_INET: + return _inet_ntop_v4(src, dst, size); + case AF_INET6: + return _inet_ntop_v6((const ex_u8*)src, dst, size); + default: + errno = EAFNOSUPPORT; + return NULL; + } } -const char* ex_inet_ntop(int af, const void *src, char *dst, size_t size) { - switch (af) { - case AF_INET: - return _inet_ntop_v4(src, dst, size); - case AF_INET6: - return _inet_ntop_v6((const ex_u8*)src, dst, size); - default: - errno = EAFNOSUPPORT; - return NULL; - } -} - int ex_ip4_name(const struct sockaddr_in *src, char *dst, size_t size) { if (NULL == _inet_ntop_v4((const unsigned char *)&(src->sin_addr), dst, size)) return -1;