feat: 完成 M2 mosh(LAN + tsnet 端到端验证)
- mosh(blinksh/ios C++)+protobuf-lite 交叉编译为 MoshCore.xcframework (CommonCrypto 后端、含 arm64 模拟器 slice;绕 autotools 用 CMake 直编 + 手写 config.h) - tsnet 桥新增 UDP relay(StartMoshRelay:loopback↔tsnet.Dial 逐包搬运) - MoshSession(pipe↔FILE*/pthread/SIGWINCH)+ MoshConnectScanner(TXCore,+4 单测=39) - SSHTerminalModel 编排:SSH 引导 mosh-server→解析 MOSH CONNECT→relay→mosh 接管 - LAN 直连 + mosh-over-tsnet 均端到端验证通过,R1(tsnet UDP 数据报语义) 证伪 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -11,8 +11,13 @@ DerivedData/
|
||||
# XcodeGen 生成的工程(由 project.yml 重生)
|
||||
apps/**/*.xcodeproj
|
||||
|
||||
# CMake 构建中间产物(由 vendor/build/build-cssh.sh 重建;build-cssh.sh 本身保留)
|
||||
# CMake 构建中间产物(由 vendor/build/build-*.sh 重建;脚本与手写 config.h/CMakeLists 保留)
|
||||
vendor/build/cssh/
|
||||
vendor/build/mosh-out/
|
||||
# protobuf 的 host protoc / iOS slice 构建目录(由 build-mosh.sh 重建;源码与生成的 *.pb.* 保留提交)
|
||||
vendor/protobuf/build-host/
|
||||
vendor/protobuf/build-iossim/
|
||||
vendor/protobuf/build-*/
|
||||
|
||||
# 说明:vendored 第三方源/预编译 xcframework(vendor/*、artifacts/*)**有意提交**,
|
||||
# 以在受限网络环境下保持仓库自包含、克隆即可构建运行。
|
||||
|
||||
24
CLAUDE.md
24
CLAUDE.md
@@ -23,6 +23,13 @@ swift test --package-path packages/TXCore # 35 tests
|
||||
# 重建 SSH 库 xcframework(libssh2+mbedTLS,改 vendor/libssh2|mbedtls 后)
|
||||
bash vendor/build/build-cssh.sh all # 产出 artifacts/CSSHCore.xcframework (library-only!)
|
||||
|
||||
# 重建 mosh 库 xcframework(mosh C++ + protobuf-lite,改 vendor/mosh|protobuf 或 build/mosh/* 后)
|
||||
bash vendor/build/build-mosh.sh all # 产出 artifacts/MoshCore.xcframework (library-only!)
|
||||
# 注:首次需 host protoc 生成 .pb.cc(已 checkin,无需重跑):
|
||||
# cmake -S vendor/protobuf -B vendor/protobuf/build-host -G Ninja -Dprotobuf_BUILD_TESTS=OFF && \
|
||||
# cmake --build vendor/protobuf/build-host --target protoc && \
|
||||
# vendor/protobuf/build-host/protoc --proto_path=vendor/mosh/src/protobufs --cpp_out=vendor/mosh/src/protobufs *.proto
|
||||
|
||||
# 重建 tsnet 桥(改 vendor/tsnet-bridge/tsnetbridge/bridge.go 后)
|
||||
export GOROOT=$HOME/.local/go; export PATH=$GOROOT/bin:$HOME/go/bin:$PATH
|
||||
cd vendor/tsnet-bridge && gomobile bind -target=ios,iossimulator \
|
||||
@@ -48,17 +55,24 @@ sleep N; xcrun simctl io $UDID screenshot /tmp/x.png # 然后用 Read 工具
|
||||
- 直连 SSH:`-txHost H -txPort 22 -txUser U -txPass PW -txAutoCommand "echo hi"`
|
||||
- tsnet SSH:额外加 `-txTsnetKey <authkey>`(-txHost 填 tailnet IP)
|
||||
- 纯 tsnet 自检(加入+对端枚举):只给 `-txTsnetKey <authkey>`(不给 -txHost)
|
||||
- **mosh 直连(LAN)**:`-txHost H -txPort 22 -txUser U -txPass PW -txMosh 1`(登录后跑 mosh-server→解析 MOSH CONNECT→mosh_main 直连 UDP)
|
||||
- **mosh over tsnet**:额外加 `-txTsnetKey <authkey>`(-txHost 填 tailnet IP;relay=loopback↔tsnet UDP)
|
||||
- 自定义 mosh-server 命令:`-txMoshServerCmd "…"`(默认 `mosh-server new -s -c 256 -l LANG=en_US.UTF-8 -l LC_ALL=en_US.UTF-8`)
|
||||
|
||||
## 仓库结构
|
||||
- `packages/TXCore` — 零依赖纯逻辑:tmux 解析器/layout/`SessionMachine`(会话状态机+退避重连)/`TmuxControlSequence`(DCS 检测)。
|
||||
- `packages/TXTransport` — `SSHSession`(libssh2, 支持外部 fd)/`Transport` 协议;`CSSH`(C shim: 头+modulemap)/`CSSHCore`(binaryTarget)。
|
||||
- `apps/TerminalX/iOS` — `SSHTerminalModel`(连接编排+tsnet+tmux 路由)/`ContentView`/`TmuxController`(tmux 网关)/`TsnetProbe`(M1 自检)。
|
||||
- `vendor/` — 所有非 Swift 依赖本地化:`libghostty-spm`(GhosttyKit)/`MSDisplayLink`/`libssh2`/`mbedtls`/`tsnet-bridge`(Go)。
|
||||
- `artifacts/` — 预编译 xcframework(gitignore):`CSSHCore`/`TsnetBridge`。
|
||||
- `packages/TXTransport` — `SSHSession`(libssh2, 支持外部 fd)/`MoshSession`(mosh_main 桥)/`Transport` 协议;C shim: `CSSH`+`CSSHCore`(libssh2)、`CMosh`+`MoshCore`(mosh)。
|
||||
- `apps/TerminalX/iOS` — `SSHTerminalModel`(连接编排+tsnet+tmux 路由+mosh 编排)/`ContentView`/`TmuxController`(tmux 网关)/`TsnetProbe`(M1 自检)。
|
||||
- `vendor/` — 所有非 Swift 依赖本地化:`libghostty-spm`(GhosttyKit)/`MSDisplayLink`/`libssh2`/`mbedtls`/`tsnet-bridge`(Go)/`mosh`(blinksh/ios 分支)/`protobuf`(3.21.12);`build/mosh/`(手写 config.h+CMakeLists)。
|
||||
- `artifacts/` — 预编译 xcframework(**有意提交**,非 gitignore):`CSSHCore`/`TsnetBridge`/`MoshCore`。
|
||||
|
||||
## 约定 & 坑
|
||||
- **CSSHCore 必须 library-only**(无 Headers/modulemap);libssh2 的 Swift module 由包内 `CSSH` C target 提供。否则与 GhosttyKit 撞 `include/module.modulemap`。
|
||||
- **CSSHCore/MoshCore 必须 library-only**(无 Headers/modulemap);Swift module 由包内 `CSSH`/`CMosh` C target 提供。否则与 GhosttyKit 撞 `include/module.modulemap`。
|
||||
- **mosh 构建**:绕过 autotools 用 CMake 直编 `src/*.cc`(手写 `build/mosh/config.h`);crypto 用 CommonCrypto(`USE_APPLE_COMMON_CRYPTO_AES=1`);用 `terminaldisplayinit_ios.cc`(无 terminfo);已 patch 3 处 vendored 源(`::bind` 消歧义 / curses include 包 `#if !IOS_CONTROLLER` / 去 iOS 禁用 `system()`);protobuf 只需 lite runtime,`.pb.cc` 已 checkin。
|
||||
- **protoc 装不了不是问题**:用源码 CMake 编一个 host protoc 生成 `.pb.cc` 即可(一次性,产物 checkin)。
|
||||
- **一进程一个 Go runtime、只一次 gomobile bind**(全在 `tsnetbridge` 包)。
|
||||
- **Swift `\r\n` 是单个 Character(扩展字形簇)**:判行尾用 `Character.isNewline`,不能 `c != "\r"`(`MoshConnectScanner` 曾踩)。
|
||||
- **Swift6 `SendNonSendable` pass 可能崩溃**(`pthread_create`+`Unmanaged` 上下文+C 入口的组合):改用 `Foundation.Thread`+线程内 `pthread_self()` 规避(见 `MoshSession`)。
|
||||
- GhosttyKit 的 `InMemoryTerminalSession.receive` 在 surface 未 attach 时**丢弃**写入 → 用 `OutputGate` 缓冲到 `surfaceSize != nil` 再 flush。
|
||||
- tmux `-CC attach` **不推 %window-add** → 必须主动 `list-windows` 枚举。
|
||||
- SourceKit "No such module" 是索引噪声,**以 `swift build`/`xcodebuild` 为准**。
|
||||
|
||||
@@ -47,6 +47,14 @@ final class TsnetManager: @unchecked Sendable {
|
||||
}
|
||||
throw lastError ?? TsnetError.notUp
|
||||
}
|
||||
|
||||
/// 为 mosh 建立 UDP relay:loopback ↔ tsnet(host:moshPort)。返回句柄(含 localPort)。
|
||||
/// 阻塞(tsnet UDP Dial),需后台线程调用。
|
||||
func startMoshRelay(host: String, moshPort: Int, timeoutMs: Int) throws -> TsnetbridgeMoshRelay {
|
||||
lock.lock(); let n = node; lock.unlock()
|
||||
guard let n else { throw TsnetError.notUp }
|
||||
return try n.startMoshRelay(host, moshPort: moshPort, timeoutMs: timeoutMs)
|
||||
}
|
||||
}
|
||||
|
||||
/// 线程安全地持有 transport 引用,供 libghostty 的输入/resize 回调(非主线程)安全取用。
|
||||
@@ -59,6 +67,16 @@ final class TransportHolder: @unchecked Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
/// 线程安全地持有 mosh 会话引用;非 nil 时终端输入/resize 路由到 mosh 而非 SSH transport。
|
||||
final class MoshHolder: @unchecked Sendable {
|
||||
private let lock = NSLock()
|
||||
private var value: MoshSession?
|
||||
var session: MoshSession? {
|
||||
get { lock.lock(); defer { lock.unlock() }; return value }
|
||||
set { lock.lock(); value = newValue; lock.unlock() }
|
||||
}
|
||||
}
|
||||
|
||||
/// 输出闸门:surface 未 attach 时 receive 会丢弃写入,故未就绪先缓冲、就绪后按序 flush(修白屏)。
|
||||
final class OutputGate: @unchecked Sendable {
|
||||
private let lock = NSLock()
|
||||
@@ -109,15 +127,33 @@ final class SSHTerminalModel: ObservableObject {
|
||||
private var tsnetAuthKey: String?
|
||||
private let tsnetMgr = TsnetManager()
|
||||
|
||||
/// M2 mosh 模式:SSH 登录后跑 mosh-server,解析 MOSH CONNECT,改由 mosh(UDP over tsnet relay) 承载会话。
|
||||
private var moshMode = false
|
||||
private var moshServerCmd = "mosh-server new -s -c 256 -l LANG=en_US.UTF-8 -l LC_ALL=en_US.UTF-8"
|
||||
private let moshHolder: MoshHolder
|
||||
private var moshSession: MoshSession?
|
||||
private var moshRelay: TsnetbridgeMoshRelay?
|
||||
private let moshScanner = MoshConnectScanner()
|
||||
private var moshBootstrapSent = false
|
||||
|
||||
init() {
|
||||
let holder = TransportHolder()
|
||||
let moshHolder = MoshHolder()
|
||||
let session = InMemoryTerminalSession(
|
||||
write: { data in holder.transport?.send(data) },
|
||||
resize: { vp in holder.transport?.resize(cols: vp.columns, rows: vp.rows) }
|
||||
// 输入/resize:mosh 激活时路由到 mosh,否则走 SSH transport。
|
||||
write: { data in
|
||||
if let m = moshHolder.session { m.send([UInt8](data)) }
|
||||
else { holder.transport?.send(data) }
|
||||
},
|
||||
resize: { vp in
|
||||
if let m = moshHolder.session { m.resize(cols: Int(vp.columns), rows: Int(vp.rows)) }
|
||||
else { holder.transport?.resize(cols: vp.columns, rows: vp.rows) }
|
||||
}
|
||||
)
|
||||
let state = TerminalViewState()
|
||||
state.configuration = TerminalSurfaceOptions(backend: .inMemory(session))
|
||||
self.holder = holder
|
||||
self.moshHolder = moshHolder
|
||||
self.session = session
|
||||
self.state = state
|
||||
self.gate = OutputGate(session: session)
|
||||
@@ -158,6 +194,11 @@ final class SSHTerminalModel: ObservableObject {
|
||||
let port = d.integer(forKey: "txPort")
|
||||
autoCommand = d.string(forKey: "txAutoCommand")
|
||||
if let key = d.string(forKey: "txTsnetKey"), !key.isEmpty { tsnetAuthKey = key }
|
||||
if d.bool(forKey: "txMosh") {
|
||||
moshMode = true
|
||||
if let cmd = d.string(forKey: "txMoshServerCmd"), !cmd.isEmpty { moshServerCmd = cmd }
|
||||
autoCommand = nil // mosh 模式用自己的引导流程,不用 txAutoCommand
|
||||
}
|
||||
connect(host: host, port: port == 0 ? 22 : port,
|
||||
username: user, password: d.string(forKey: "txPass") ?? "")
|
||||
}
|
||||
@@ -201,7 +242,14 @@ final class SSHTerminalModel: ObservableObject {
|
||||
private func wireAndStart(_ ssh: SSHSession) {
|
||||
exitTmux() // 新会话回原始模式(tmux 会话在服务端,重连后需重新 -CC attach)
|
||||
let router = tmuxRouter
|
||||
ssh.onBytes = { data in router.feed(data) } // 经路由器分流 raw / tmux 网关
|
||||
if moshMode {
|
||||
// mosh 模式:SSH 字节喂给引导流程(既显示进度、又扫描 MOSH CONNECT)。
|
||||
ssh.onBytes = { [weak self] data in
|
||||
Task { @MainActor in self?.moshBootstrapFeed(data) }
|
||||
}
|
||||
} else {
|
||||
ssh.onBytes = { data in router.feed(data) } // 经路由器分流 raw / tmux 网关
|
||||
}
|
||||
ssh.onState = { [weak self] newState in
|
||||
Task { @MainActor in self?.handleTransportState(newState) }
|
||||
}
|
||||
@@ -232,10 +280,85 @@ final class SSHTerminalModel: ObservableObject {
|
||||
tmuxRouter.reset()
|
||||
}
|
||||
|
||||
// MARK: - M2 mosh 编排
|
||||
|
||||
/// SSH 已连接后引导 mosh-server(延迟等 shell 提示符,只发一次)。
|
||||
private func scheduleMoshBootstrap() {
|
||||
guard moshMode, !moshBootstrapSent, moshSession == nil else { return }
|
||||
moshBootstrapSent = true
|
||||
let holder = self.holder
|
||||
let cmd = moshServerCmd
|
||||
banner = "启动 mosh-server…"
|
||||
Task {
|
||||
try? await Task.sleep(nanoseconds: 2_500_000_000) // 等 shell 提示符就绪
|
||||
holder.transport?.send(Data("\n".utf8))
|
||||
try? await Task.sleep(nanoseconds: 800_000_000)
|
||||
NSLog("MOSHDBG sent mosh-server cmd: \(cmd)")
|
||||
holder.transport?.send(Data((cmd + "\n").utf8))
|
||||
}
|
||||
}
|
||||
|
||||
/// mosh 引导期消费 SSH 字节:显示进度 + 扫描 MOSH CONNECT,命中即切换到 mosh。
|
||||
/// mosh 接管后忽略 SSH 残余字节,避免污染 mosh 的屏幕状态。
|
||||
private func moshBootstrapFeed(_ data: Data) {
|
||||
guard moshSession == nil else { return }
|
||||
gate.deliver(data) // 让用户看到 mosh-server 引导输出
|
||||
let text = String(decoding: data, as: UTF8.self)
|
||||
if let info = moshScanner.feed(text) {
|
||||
NSLog("MOSHDBG parsed MOSH CONNECT port=\(info.port) keyLen=\(info.key.count)")
|
||||
launchMosh(info)
|
||||
}
|
||||
}
|
||||
|
||||
/// 拿到 MOSH CONNECT 后:tsnet 起 UDP relay(loopback:port) → 建 MoshSession → 接管会话。
|
||||
private func launchMosh(_ info: MoshConnectInfo) {
|
||||
guard moshSession == nil, let config else { return }
|
||||
banner = "mosh 连接中(server port \(info.port))…"
|
||||
if tsnetAuthKey != nil {
|
||||
let mgr = tsnetMgr
|
||||
let host = config.host
|
||||
Task.detached {
|
||||
do {
|
||||
NSLog("MOSHDBG startMoshRelay host=\(host) moshPort=\(info.port)")
|
||||
let relay = try mgr.startMoshRelay(host: host, moshPort: info.port, timeoutMs: 15000)
|
||||
let localPort = relay.localPort()
|
||||
NSLog("MOSHDBG relay up localPort=\(localPort)")
|
||||
await MainActor.run { self.activateMosh(ip: "127.0.0.1", port: localPort, key: info.key, relay: relay) }
|
||||
} catch {
|
||||
NSLog("MOSHDBG relay FAILED: \(error.localizedDescription)")
|
||||
await MainActor.run { self.banner = "mosh relay 失败:\(error.localizedDescription)" }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 直连模式:iOS 允许出站 UDP,直接连 host:port。
|
||||
activateMosh(ip: config.host, port: info.port, key: info.key, relay: nil)
|
||||
}
|
||||
}
|
||||
|
||||
private func activateMosh(ip: String, port: Int, key: String, relay: TsnetbridgeMoshRelay?) {
|
||||
guard moshSession == nil else { return }
|
||||
let mosh = MoshSession(ip: ip, port: port, key: key, cols: 80, rows: 24)
|
||||
mosh.onBytes = { [weak self] bytes in
|
||||
guard let self else { return }
|
||||
self.gate.deliver(Data(bytes))
|
||||
}
|
||||
mosh.onClosed = { [weak self] rc in
|
||||
Task { @MainActor in self?.banner = "mosh 已结束(rc=\(rc))" }
|
||||
}
|
||||
moshRelay = relay
|
||||
moshSession = mosh
|
||||
moshHolder.session = mosh // 输入/resize 从此路由到 mosh
|
||||
mosh.start()
|
||||
NSLog("MOSHDBG activateMosh ip=\(ip) port=\(port) started")
|
||||
banner = "mosh 已连接"
|
||||
}
|
||||
|
||||
private func handleTransportState(_ st: TransportState) {
|
||||
switch st {
|
||||
case .authenticating: run(machine.reduce(.authenticating))
|
||||
case .connected: run(machine.reduce(.established))
|
||||
case .connected:
|
||||
run(machine.reduce(.established))
|
||||
if moshMode { scheduleMoshBootstrap() }
|
||||
case .disconnected(let reason): run(machine.reduce(.transportClosed(reason: reason)))
|
||||
case .failed(let message): run(machine.reduce(.authFailed(reason: message)))
|
||||
case .idle, .connecting: break
|
||||
|
||||
58
artifacts/MoshCore.xcframework/Info.plist
Normal file
58
artifacts/MoshCore.xcframework/Info.plist
Normal file
@@ -0,0 +1,58 @@
|
||||
<?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>AvailableLibraries</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>BinaryPath</key>
|
||||
<string>libMoshCore.a</string>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64_x86_64-simulator</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>libMoshCore.a</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
<string>x86_64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
<key>SupportedPlatformVariant</key>
|
||||
<string>simulator</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>BinaryPath</key>
|
||||
<string>libMoshCore.a</string>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>libMoshCore.a</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>BinaryPath</key>
|
||||
<string>libMoshCore.a</string>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>macos-arm64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>libMoshCore.a</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>macos</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XFWK</string>
|
||||
<key>XCFrameworkFormatVersion</key>
|
||||
<string>1.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
artifacts/MoshCore.xcframework/ios-arm64/libMoshCore.a
Normal file
BIN
artifacts/MoshCore.xcframework/ios-arm64/libMoshCore.a
Normal file
Binary file not shown.
Binary file not shown.
BIN
artifacts/MoshCore.xcframework/macos-arm64/libMoshCore.a
Normal file
BIN
artifacts/MoshCore.xcframework/macos-arm64/libMoshCore.a
Normal file
Binary file not shown.
@@ -4,20 +4,6 @@
|
||||
<dict>
|
||||
<key>AvailableLibraries</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>BinaryPath</key>
|
||||
<string>TsnetBridge.framework/TsnetBridge</string>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>TsnetBridge.framework</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>BinaryPath</key>
|
||||
<string>TsnetBridge.framework/TsnetBridge</string>
|
||||
@@ -35,6 +21,20 @@
|
||||
<key>SupportedPlatformVariant</key>
|
||||
<string>simulator</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>BinaryPath</key>
|
||||
<string>TsnetBridge.framework/TsnetBridge</string>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>TsnetBridge.framework</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XFWK</string>
|
||||
|
||||
@@ -11,8 +11,31 @@
|
||||
#include "Universe.objc.h"
|
||||
|
||||
|
||||
@class TsnetbridgeMoshRelay;
|
||||
@class TsnetbridgeNode;
|
||||
|
||||
/**
|
||||
* MoshRelay 是一条 mosh-over-tsnet 的 UDP 中继:
|
||||
mosh-client 在本地把 UDP 包发到 127.0.0.1:<LocalPort>,本中继逐包经 tsnet 转发到
|
||||
tailnet 内 host:moshPort,回包再转回"最近一次上行的 client 源地址"(吸收 mosh 的 roaming/端口跳变)。
|
||||
与 DialTCPFD 的差异:mosh 内部自建 UDP socket 并 connect(),无法注入外部 fd,故用 loopback relay。
|
||||
*/
|
||||
@interface TsnetbridgeMoshRelay : NSObject <goSeqRefInterface> {
|
||||
}
|
||||
@property(strong, readonly) _Nonnull id _ref;
|
||||
|
||||
- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
|
||||
- (nonnull instancetype)init;
|
||||
/**
|
||||
* Close 关闭中继(两条泵 goroutine 随即因 conn 关闭而退出)。
|
||||
*/
|
||||
- (BOOL)close:(NSError* _Nullable* _Nullable)error;
|
||||
/**
|
||||
* LocalPort 返回 loopback relay 监听的端口(mosh_main 的 port 参数)。
|
||||
*/
|
||||
- (long)localPort;
|
||||
@end
|
||||
|
||||
/**
|
||||
* Node 包装一个嵌入式 tsnet 节点。gomobile 导出为引用型对象。
|
||||
*/
|
||||
@@ -44,6 +67,11 @@ Swift 侧 close(fd) 会触发泵结束并关闭 tsConn。返回 -1 + error 表
|
||||
* SelfIP 返回本节点的 Tailscale IPv4(经 LocalClient().Status() 取;未就绪返回空串)。
|
||||
*/
|
||||
- (NSString* _Nonnull)selfIP;
|
||||
/**
|
||||
* StartMoshRelay 建立中继并启动双向泵,返回句柄。Swift 用 LocalPort() 作为 mosh_main 的 port
|
||||
参数、ip 传 "127.0.0.1"。失败返回 nil + error。timeoutMs 限制 tsnet UDP Dial 的建连等待。
|
||||
*/
|
||||
- (TsnetbridgeMoshRelay* _Nullable)startMoshRelay:(NSString* _Nullable)host moshPort:(long)moshPort timeoutMs:(long)timeoutMs error:(NSError* _Nullable* _Nullable)error;
|
||||
/**
|
||||
* UpWithAuthKey 用 auth key 启动并等待 Running(timeoutMs 到则返回 error)。
|
||||
gomobile 友好签名:基本类型入参、error 出参。
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>100.0</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.0.1784856790</string>
|
||||
<string>0.0.1784861278</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.1784856790</string>
|
||||
<string>0.0.1784861278</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
</dict>
|
||||
|
||||
Binary file not shown.
@@ -11,8 +11,31 @@
|
||||
#include "Universe.objc.h"
|
||||
|
||||
|
||||
@class TsnetbridgeMoshRelay;
|
||||
@class TsnetbridgeNode;
|
||||
|
||||
/**
|
||||
* MoshRelay 是一条 mosh-over-tsnet 的 UDP 中继:
|
||||
mosh-client 在本地把 UDP 包发到 127.0.0.1:<LocalPort>,本中继逐包经 tsnet 转发到
|
||||
tailnet 内 host:moshPort,回包再转回"最近一次上行的 client 源地址"(吸收 mosh 的 roaming/端口跳变)。
|
||||
与 DialTCPFD 的差异:mosh 内部自建 UDP socket 并 connect(),无法注入外部 fd,故用 loopback relay。
|
||||
*/
|
||||
@interface TsnetbridgeMoshRelay : NSObject <goSeqRefInterface> {
|
||||
}
|
||||
@property(strong, readonly) _Nonnull id _ref;
|
||||
|
||||
- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
|
||||
- (nonnull instancetype)init;
|
||||
/**
|
||||
* Close 关闭中继(两条泵 goroutine 随即因 conn 关闭而退出)。
|
||||
*/
|
||||
- (BOOL)close:(NSError* _Nullable* _Nullable)error;
|
||||
/**
|
||||
* LocalPort 返回 loopback relay 监听的端口(mosh_main 的 port 参数)。
|
||||
*/
|
||||
- (long)localPort;
|
||||
@end
|
||||
|
||||
/**
|
||||
* Node 包装一个嵌入式 tsnet 节点。gomobile 导出为引用型对象。
|
||||
*/
|
||||
@@ -44,6 +67,11 @@ Swift 侧 close(fd) 会触发泵结束并关闭 tsConn。返回 -1 + error 表
|
||||
* SelfIP 返回本节点的 Tailscale IPv4(经 LocalClient().Status() 取;未就绪返回空串)。
|
||||
*/
|
||||
- (NSString* _Nonnull)selfIP;
|
||||
/**
|
||||
* StartMoshRelay 建立中继并启动双向泵,返回句柄。Swift 用 LocalPort() 作为 mosh_main 的 port
|
||||
参数、ip 传 "127.0.0.1"。失败返回 nil + error。timeoutMs 限制 tsnet UDP Dial 的建连等待。
|
||||
*/
|
||||
- (TsnetbridgeMoshRelay* _Nullable)startMoshRelay:(NSString* _Nullable)host moshPort:(long)moshPort timeoutMs:(long)timeoutMs error:(NSError* _Nullable* _Nullable)error;
|
||||
/**
|
||||
* UpWithAuthKey 用 auth key 启动并等待 Running(timeoutMs 到则返回 error)。
|
||||
gomobile 友好签名:基本类型入参、error 出参。
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>100.0</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.0.1784856790</string>
|
||||
<string>0.0.1784861278</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.1784856790</string>
|
||||
<string>0.0.1784861278</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
</dict>
|
||||
|
||||
Binary file not shown.
@@ -6,7 +6,11 @@
|
||||
---
|
||||
|
||||
## 0. 一句话现状
|
||||
一个**原生 iPad SSH 终端**已可用并真机验证:libghostty 渲染 + 键盘输入 + SSH 直连 + **SSH-over-tsnet(Tailscale 用户态)** + **tmux -CC 原生 tab** + 断线自动重连。四大核心需求(libghostty/tailscale/tmux 已验证,**mosh 未做**)。仅在 iOS 模拟器验证(未上真机/未签名/未提交 git)。
|
||||
一个**原生 iPad SSH 终端**已可用并真机验证:libghostty 渲染 + 键盘输入 + SSH 直连 + **SSH-over-tsnet(Tailscale 用户态)** + **tmux -CC 原生 tab** + **mosh(LAN 直连已端到端验证)** + 断线自动重连。四大核心需求(libghostty/tailscale/tmux/**mosh 均已验证**)。仅在 iOS 模拟器验证(未上真机/未签名/未提交 git)。
|
||||
> **mosh 状态(2026-07-24 全部验证通过)**:mosh(C++,blinksh/ios)+protobuf-lite 交叉编译成 `MoshCore.xcframework`(CommonCrypto 后端,含 arm64 模拟器 slice);tsnet 桥加 UDP relay(`StartMoshRelay`);`MoshSession`(pipe↔FILE*/pthread/SIGWINCH)+`MoshConnectScanner`(TXCore,39 单测)+`SSHTerminalModel` 编排(SSH 引导 mosh-server→解析 MOSH CONNECT→接管)。
|
||||
> - **LAN 直连端到端验证**(192.168.9.199):mosh-server 存活 104s≫60s 无客户端超时+子 shell+心跳=真连。
|
||||
> - **mosh over tsnet 端到端验证**(vohive-vm 100.69.201.101):app 日志 `parsed MOSH CONNECT port=60002`→`relay up localPort=63542`→`activateMosh started`;屏幕渲染远端 shell 且无 mosh 断连 overlay=relay UDP 双向流通。**R1(tsnet UDP 数据报语义) 证伪**。
|
||||
> - 复现 tsnet:模拟器已持久化 tsnet 节点状态(`~/Library/.../tsnet-main`),`-txTsnetKey` 传任意非空串即可凭存量身份重连(节点未被 tailnet 清理时);节点被清理则需新 ephemeral key。
|
||||
|
||||
## 1. 项目愿景与硬约束
|
||||
- 目标:iPad/iPhone 远程轻量运维 macOS/Linux + vibe coding。平台优先级 **iPadOS > iOS > macOS(Apple Silicon)**。
|
||||
@@ -36,7 +40,7 @@
|
||||
| **M1.5** tmux -CC 原生 tab | ✅ MVP | 直连跑 `tmux -CC attach` → 渲染 fish/tmux 两原生 tab + 活动窗口内容 |
|
||||
| dial 重试打磨 | ✅ | `TsnetManager.dialFD` 6 次退避重试,解决 tsnet 首连路径预热超时 |
|
||||
| **R5** Go+gvisor+C+++Swift 同进程 | ✅ retire | 全程真机无崩溃 |
|
||||
| **M2** mosh | ◻️ 未开始 | libmoshios(C++) + 本地 UDP relay over tsnet |
|
||||
| **M2** mosh | ✅ 完成(LAN + tsnet 均验证) | libmoshios(C++)+protobuf-lite→`MoshCore.xcframework`;UDP relay over tsnet;**LAN 直连 + mosh-over-tsnet 均端到端验证通过**(R1 证伪) |
|
||||
| **M3** 生命周期深化 | ◻️ 部分 | 前后台 FSM 已做;mosh 快速恢复 + tmux 兜底 待做 |
|
||||
| **M4** 安全 | ◻️ 未做 | **当前 SSH 接受任意 host key**(见 SSHSession TODO);known_hosts 固定 + Secure Enclave 密钥 待做 |
|
||||
| **M5** 合规提审 | ⏸️ 暂缓 | 用户指示暂缓 |
|
||||
@@ -47,7 +51,10 @@
|
||||
- `Session/SessionMachine.swift` —— `reduce(event)->[Effect]` 会话状态机(指数退避重连/后台冻结/前台恢复)。
|
||||
- `packages/TXTransport/Sources/`
|
||||
- `TXTransport/Transport.swift`(协议+SSHConfig+SSHError)、`SSHSession.swift`(libssh2;`preconnectedFD` 支持外部 fd;事件循环 poll+非阻塞)。
|
||||
- `CSSH/`(C target:libssh2 头 + `include/module.modulemap`,供 `import CSSH`)、`CSSHCore`(binaryTarget,library-only)。
|
||||
- `TXTransport/MoshSession.swift`(M2):驱动 `mosh_main`;pipe↔FILE* 桥(in/out)、Foundation.Thread 跑阻塞主循环+`pthread_self()` 供 `pthread_kill(SIGWINCH)` resize、忽略 SIGPIPE、setenv UTF-8 locale。
|
||||
- `CSSH/`(C target:libssh2 头 + modulemap,供 `import CSSH`)、`CSSHCore`(binaryTarget,library-only)。
|
||||
- `CMosh/`(C target:`moshiosbridge.h`(mosh_main)+modulemap+占位 shim.c,供 `import CMosh`)、`MoshCore`(binaryTarget,library-only);TXTransport 链 `libc++`/`libz`(mosh 是 C++ 且 compressor 用 zlib;CommonCrypto 属 libSystem 自动解析)。
|
||||
- `TXCore/Mosh/MoshConnect.swift`:`MoshConnectScanner` 流式扫描 `MOSH CONNECT <port> <key>`(注意 Swift 视 `\r\n` 为单 Character,行尾判定须用 `isNewline`)。
|
||||
- `apps/TerminalX/iOS/`
|
||||
- `SSHTerminalModel.swift` —— 核心编排:`OutputGate`(surface-ready 缓冲)、`TransportHolder`、`TsnetManager`(tsnet 节点 up/dial+重试)、`TsnetError`、`TmuxRouter`(raw/gateway 字节分流)、状态机驱动 startSession(直连/tsnet 分支)、`autoConnectIfConfigured`(启动参数)。
|
||||
- `ContentView.swift` —— 分支:`tmuxController != nil`→`TmuxTabbedView`(tab 条+活动窗口);否则 `RawTerminalView`;`TsnetProbeView`(纯自检);`ConnectionForm`。
|
||||
@@ -66,13 +73,13 @@
|
||||
- **多平台**:iOS target 已跑;macOS target(本地 PTY, `TXPTY`)未建。
|
||||
|
||||
## 7. 下一步建议(按价值)
|
||||
1. **M2 mosh over tsnet**:接 `blinksh/mosh`(libmoshios C++,依赖 protobuf) 交叉编译成 xcframework(参考 `build-cssh.sh` 模式) → 本地 UDP relay(mosh 连 127.0.0.1:N,Go 侧 `tsnet` UDP `ListenPacket`/`Dial` 转发;bridge 加 UDP relay 方法,类比 `DialTCPFD`)。SSH 先起 `mosh-server` 拿 key+port。**需用户提供装了 mosh-server 的 tailnet 主机**做端到端。
|
||||
2. **tmux 多 pane 分屏**:`TmuxLayout` 已能解析布局树 → 把 window 内多 pane 渲染成 SwiftUI 分屏(每 pane 一 surface)。
|
||||
3. **M4 安全**:known_hosts 固定 + SE 密钥。
|
||||
4. **产品化**:主机列表持久化(Keychain)、多标签(非 tmux)、软键盘运维工具栏(GhosttyKit 内建,接线即可)。
|
||||
1. **M2 mosh 打磨**(功能已通,打磨项):`activateMosh` 写死 80x24 初值(靠首次 resize 纠正);SSH 会话在 mosh 接管后保持 idle 未关(占一条连接);`MoshSession.close()` 后 mosh 线程可能滞留(阻塞主循环,见 TODO);moshiosbridge.cc 顶部 `fwrite("Hello from the Bridge!")` 调试行可清理;`SSHTerminalModel` 里 `NSLog("MOSHDBG …")` 诊断日志可按需保留/删除;mosh-server 引导后远端会累积 detached 会话(`mosh-server new` 每次新建),可考虑复用或清理。**挂起→恢复<3s 门(M3)待专门测**。
|
||||
3. **tmux 多 pane 分屏**:`TmuxLayout` 已能解析布局树 → 把 window 内多 pane 渲染成 SwiftUI 分屏(每 pane 一 surface)。
|
||||
4. **M4 安全**:known_hosts 固定 + SE 密钥。
|
||||
5. **产品化**:主机列表持久化(Keychain)、多标签(非 tmux)、软键盘运维工具栏(GhosttyKit 内建,接线即可)。
|
||||
|
||||
## 8. 测试资源(用户提供,**凭据勿写入仓库/勿硬编码**,每次向用户索取)
|
||||
- 一台局域网 macOS(有 tmux)、一台 tailnet 内 online 的 Ubuntu VM(vohive-vm)、一个 tailnet auth key(ephemeral,可能过期,用户会给新的)。用于直连 SSH / SSH-over-tsnet / tmux / M2 mosh 端到端验证。
|
||||
- 一台局域网 macOS(有 tmux + **mosh-server**,如 MacBook-Air-M1;fish 为默认 shell,`mosh-server` 在 `/opt/homebrew/bin` 且交互 shell PATH 可见)、一台 tailnet 内 online 的 Ubuntu VM(vohive-vm)、一个 tailnet auth key(ephemeral,可能过期,用户会给新的)。用于直连 SSH / SSH-over-tsnet / tmux / M2 mosh 端到端验证。凭据每次向用户即时索取。
|
||||
- tailnet 是 `tail3b5057.ts.net`,已见节点:vohive-vm(linux)、iphone-air、ipad-pro、macbook-air-m1、macbook-air。
|
||||
|
||||
## 9. 工作纪律(务必遵守)
|
||||
|
||||
50
packages/TXCore/Sources/TXCore/Mosh/MoshConnect.swift
Normal file
50
packages/TXCore/Sources/TXCore/Mosh/MoshConnect.swift
Normal file
@@ -0,0 +1,50 @@
|
||||
import Foundation
|
||||
|
||||
/// 解析 `mosh-server new` 打印的握手行 `MOSH CONNECT <port> <key>`。
|
||||
///
|
||||
/// 引导流程:经 SSH 跑 `mosh-server new …` → 服务端 detach 并在 stdout 打印这一行 →
|
||||
/// 客户端据此用 UDP + key 连到 host:port。因 SSH 流里混有提示符/回显,采用流式扫描:
|
||||
/// 逐段 `feed` 追加缓冲并尝试匹配,命中即返回(幂等,多次命中以首次为准)。
|
||||
public struct MoshConnectInfo: Equatable, Sendable {
|
||||
public let port: Int
|
||||
public let key: String
|
||||
public init(port: Int, key: String) { self.port = port; self.key = key }
|
||||
}
|
||||
|
||||
public final class MoshConnectScanner {
|
||||
private var buffer = ""
|
||||
private var found: MoshConnectInfo?
|
||||
|
||||
public init() {}
|
||||
|
||||
/// 追加一段输出并尝试匹配;返回本次(或此前)解析到的握手信息(若有)。
|
||||
@discardableResult
|
||||
public func feed(_ text: String) -> MoshConnectInfo? {
|
||||
if let found { return found }
|
||||
buffer += text
|
||||
// 只保留尾部,避免无限增长(握手行很短,8KB 足够跨 feed 边界)。
|
||||
if buffer.count > 8192 { buffer = String(buffer.suffix(8192)) }
|
||||
if let info = Self.parse(buffer) { found = info; return info }
|
||||
return nil
|
||||
}
|
||||
|
||||
public var result: MoshConnectInfo? { found }
|
||||
|
||||
/// 从任意文本中提取第一处 `MOSH CONNECT <port> <key>`。key 为 base64(AES-128 会话密钥)。
|
||||
public static func parse(_ text: String) -> MoshConnectInfo? {
|
||||
guard let range = text.range(of: "MOSH CONNECT ") else { return nil }
|
||||
let rest = text[range.upperBound...]
|
||||
// 取该 token 起至行尾,按空白切分:port key。
|
||||
// 注意:Swift 把 "\r\n" 视为单个 Character(扩展字形簇),不能用 $0 != "\r" 判行尾,
|
||||
// 必须用 isNewline(对 \n / \r / \r\n 均为真)。
|
||||
let line = rest.split(whereSeparator: { $0.isNewline }).first ?? ""
|
||||
let parts = line.split(whereSeparator: { $0 == " " || $0 == "\t" })
|
||||
guard parts.count >= 2, let port = Int(parts[0]) else { return nil }
|
||||
let key = String(parts[1])
|
||||
// key 须为纯 base64 字符集且非空,避免把提示符碎片误当 key。
|
||||
guard !key.isEmpty, key.allSatisfy({ $0.isLetter || $0.isNumber || $0 == "+" || $0 == "/" || $0 == "=" }) else {
|
||||
return nil
|
||||
}
|
||||
return MoshConnectInfo(port: port, key: key)
|
||||
}
|
||||
}
|
||||
37
packages/TXCore/Tests/TXCoreTests/MoshConnectTests.swift
Normal file
37
packages/TXCore/Tests/TXCoreTests/MoshConnectTests.swift
Normal file
@@ -0,0 +1,37 @@
|
||||
import XCTest
|
||||
@testable import TXCore
|
||||
|
||||
final class MoshConnectTests: XCTestCase {
|
||||
func testParseBasic() {
|
||||
let info = MoshConnectScanner.parse("MOSH CONNECT 60001 gPFm3s8bkfMGrun5QI0Xdw")
|
||||
XCTAssertEqual(info, MoshConnectInfo(port: 60001, key: "gPFm3s8bkfMGrun5QI0Xdw"))
|
||||
}
|
||||
|
||||
func testParseAmidNoise() {
|
||||
let out = """
|
||||
user@host:~$ mosh-server new -s -c 256\r
|
||||
\r
|
||||
MOSH CONNECT 60022 AbCd1234+/xyzKEY0000==\r
|
||||
\r
|
||||
mosh-server (mosh 1.4.0)\r
|
||||
"""
|
||||
let info = MoshConnectScanner.parse(out)
|
||||
XCTAssertEqual(info?.port, 60022)
|
||||
XCTAssertEqual(info?.key, "AbCd1234+/xyzKEY0000==")
|
||||
}
|
||||
|
||||
func testNoMatch() {
|
||||
XCTAssertNil(MoshConnectScanner.parse("bash: mosh-server: command not found"))
|
||||
XCTAssertNil(MoshConnectScanner.parse("MOSH CONNECT notaport keyhere"))
|
||||
}
|
||||
|
||||
func testStreamingAcrossFeeds() {
|
||||
let s = MoshConnectScanner()
|
||||
XCTAssertNil(s.feed("prompt$ mosh-server new\r\nMOSH CON"))
|
||||
XCTAssertNil(s.result)
|
||||
let info = s.feed("NECT 60007 KeyAcrossBoundary123\r\n")
|
||||
XCTAssertEqual(info, MoshConnectInfo(port: 60007, key: "KeyAcrossBoundary123"))
|
||||
// 幂等:后续 feed 不改变结果。
|
||||
XCTAssertEqual(s.feed("MOSH CONNECT 61000 other"), MoshConnectInfo(port: 60007, key: "KeyAcrossBoundary123"))
|
||||
}
|
||||
}
|
||||
@@ -18,14 +18,26 @@ let package = Package(
|
||||
.binaryTarget(name: "CSSHCore", path: "../../artifacts/CSSHCore.xcframework"),
|
||||
// 头文件 + modulemap 载体(供 `import CSSH`);库符号来自 CSSHCore。
|
||||
.target(name: "CSSH", publicHeadersPath: "include"),
|
||||
// mosh(C++) + protobuf-lite 静态库切片(vendor/build/build-mosh.sh,library-only)。
|
||||
.binaryTarget(name: "MoshCore", path: "../../artifacts/MoshCore.xcframework"),
|
||||
// 头文件 + modulemap 载体(供 `import CMosh` 调 mosh_main);库符号来自 MoshCore。
|
||||
.target(name: "CMosh", publicHeadersPath: "include"),
|
||||
.target(
|
||||
name: "TXTransport",
|
||||
dependencies: [
|
||||
"CSSH",
|
||||
"CSSHCore",
|
||||
"CMosh",
|
||||
"MoshCore",
|
||||
.product(name: "TXCore", package: "TXCore"),
|
||||
],
|
||||
swiftSettings: [.swiftLanguageMode(.v6)]
|
||||
swiftSettings: [.swiftLanguageMode(.v6)],
|
||||
// mosh 是 C++(需 libc++)且 compressor.cc 用 zlib(需 libz);
|
||||
// CommonCrypto 属 libSystem 伞库,Apple 平台自动解析无需显式链接。
|
||||
linkerSettings: [
|
||||
.linkedLibrary("c++"),
|
||||
.linkedLibrary("z"),
|
||||
]
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
module CMosh {
|
||||
header "moshiosbridge.h"
|
||||
export *
|
||||
}
|
||||
17
packages/TXTransport/Sources/CMosh/include/moshiosbridge.h
Normal file
17
packages/TXTransport/Sources/CMosh/include/moshiosbridge.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* CMosh — Swift 可 import 的 mosh 客户端入口头(库符号来自 MoshCore.xcframework)。
|
||||
* 对应 vendor/mosh/src/frontend/moshiosbridge.h,保持签名一致。
|
||||
* mosh_main 是阻塞式主循环:读 f_in(用户输入字节)、写 f_out(终端输出字节),
|
||||
* 经 UDP 连 ip:port(mosh SSP,AES-128-OCB),window_size 供 SIGWINCH resize。 */
|
||||
#ifndef CMOSH_MOSHIOSBRIDGE_H
|
||||
#define CMOSH_MOSHIOSBRIDGE_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#if __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
int mosh_main(FILE *f_in, FILE *f_out, struct winsize *window_size,
|
||||
const char *ip, const char *port, const char *key, const char *predict_mode);
|
||||
|
||||
#endif /* CMOSH_MOSHIOSBRIDGE_H */
|
||||
3
packages/TXTransport/Sources/CMosh/shim.c
Normal file
3
packages/TXTransport/Sources/CMosh/shim.c
Normal file
@@ -0,0 +1,3 @@
|
||||
// CMosh 是 mosh_main 头文件 + modulemap 的载体 target(供 `import CMosh`);
|
||||
// 实际库符号来自 MoshCore.xcframework(静态库)。此处仅需一个非空翻译单元。
|
||||
typedef int cmosh_shim_placeholder;
|
||||
162
packages/TXTransport/Sources/TXTransport/MoshSession.swift
Normal file
162
packages/TXTransport/Sources/TXTransport/MoshSession.swift
Normal file
@@ -0,0 +1,162 @@
|
||||
import Foundation
|
||||
import CMosh
|
||||
|
||||
/// MoshSession — 驱动 vendored mosh 客户端(MoshCore.xcframework 的 `mosh_main`)。
|
||||
///
|
||||
/// 桥接模型:`mosh_main` 是阻塞式主循环,用 `FILE*` 读用户输入、写终端输出。
|
||||
/// - 输入:Swift `send(_:)` 写入 inPipe[1] → mosh 从 `fileno(f_in)=inPipe[0]` 读。
|
||||
/// - 输出:mosh 写 `f_out=outPipe[1]` → 后台读线程从 outPipe[0] 读 → `onBytes`。
|
||||
/// - resize:更新共享 `winsize` 结构后 `pthread_kill(SIGWINCH)`,mosh 的 select 循环据此重绘。
|
||||
///
|
||||
/// 连接目标由调用方给定 ip:port —— mosh-over-tsnet 时传 `127.0.0.1:<relay 本地端口>`
|
||||
/// (见 TsnetBridge 的 MoshRelay),mosh 感知不到 tailnet 的存在。
|
||||
public final class MoshSession: @unchecked Sendable {
|
||||
/// mosh 输出的终端字节(送入 libghostty)。
|
||||
public var onBytes: (@Sendable ([UInt8]) -> Void)?
|
||||
/// mosh_main 返回(会话结束)时回调,携带返回码(0=成功退出)。
|
||||
public var onClosed: (@Sendable (Int32) -> Void)?
|
||||
|
||||
private let ip: String
|
||||
private let port: String
|
||||
private let key: String
|
||||
private let predictMode: String
|
||||
|
||||
private let winPtr = UnsafeMutablePointer<winsize>.allocate(capacity: 1)
|
||||
private let lock = NSLock()
|
||||
private var inWriteFD: Int32 = -1 // Swift 写用户输入
|
||||
private var outReadFD: Int32 = -1 // Swift 读终端输出
|
||||
private var moshThread: pthread_t?
|
||||
private var started = false
|
||||
private var closed = false
|
||||
|
||||
/// - Parameters:
|
||||
/// - ip/port: mosh-server 的可达地址(tsnet 场景为 loopback relay 地址)。
|
||||
/// - key: `mosh-server new` 打印的 MOSH_KEY(base64 会话密钥)。
|
||||
/// - predictMode: always | never | adaptive | experimental(默认 adaptive)。
|
||||
public init(ip: String, port: Int, key: String, cols: Int, rows: Int, predictMode: String = "adaptive") {
|
||||
self.ip = ip
|
||||
self.port = String(port)
|
||||
self.key = key
|
||||
self.predictMode = predictMode
|
||||
winPtr.pointee = winsize(ws_row: UInt16(rows), ws_col: UInt16(cols), ws_xpixel: 0, ws_ypixel: 0)
|
||||
}
|
||||
|
||||
deinit {
|
||||
winPtr.deallocate()
|
||||
}
|
||||
|
||||
/// 建立 pipe、启动读线程与 mosh 主循环线程。可多次调用无副作用(仅首次生效)。
|
||||
public func start() {
|
||||
lock.lock()
|
||||
if started { lock.unlock(); return }
|
||||
started = true
|
||||
lock.unlock()
|
||||
|
||||
// 写关闭的 pipe 会触发 SIGPIPE(默认杀进程);改为返回 EPIPE。
|
||||
signal(SIGPIPE, SIG_IGN)
|
||||
// mosh 要求 UTF-8 native locale,否则 is_utf8_locale() 失败 → exit(1)。
|
||||
setenv("LANG", "en_US.UTF-8", 1)
|
||||
setenv("LC_ALL", "en_US.UTF-8", 1)
|
||||
|
||||
var inPipe: [Int32] = [-1, -1]
|
||||
var outPipe: [Int32] = [-1, -1]
|
||||
_ = inPipe.withUnsafeMutableBufferPointer { pipe($0.baseAddress) }
|
||||
_ = outPipe.withUnsafeMutableBufferPointer { pipe($0.baseAddress) }
|
||||
|
||||
lock.lock()
|
||||
inWriteFD = inPipe[1]
|
||||
outReadFD = outPipe[0]
|
||||
lock.unlock()
|
||||
|
||||
startReader(fd: outPipe[0])
|
||||
startMosh(inReadFD: inPipe[0], outWriteFD: outPipe[1])
|
||||
}
|
||||
|
||||
/// 写入用户输入字节(键盘)。
|
||||
public func send(_ bytes: [UInt8]) {
|
||||
lock.lock(); let fd = inWriteFD; lock.unlock()
|
||||
guard fd >= 0, !bytes.isEmpty else { return }
|
||||
var off = 0
|
||||
bytes.withUnsafeBytes { buf in
|
||||
while off < buf.count {
|
||||
let n = write(fd, buf.baseAddress!.advanced(by: off), buf.count - off)
|
||||
if n <= 0 { break }
|
||||
off += n
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 更新终端尺寸并通知 mosh(SIGWINCH → process_resize)。
|
||||
public func resize(cols: Int, rows: Int) {
|
||||
winPtr.pointee.ws_col = UInt16(cols)
|
||||
winPtr.pointee.ws_row = UInt16(rows)
|
||||
lock.lock(); let tid = moshThread; lock.unlock()
|
||||
if let tid { pthread_kill(tid, SIGWINCH) }
|
||||
}
|
||||
|
||||
/// 关闭会话:关掉 pipe(mosh 侧 select 遇 EOF/EPIPE),读线程随即结束。
|
||||
public func close() {
|
||||
lock.lock()
|
||||
if closed { lock.unlock(); return }
|
||||
closed = true
|
||||
let w = inWriteFD, r = outReadFD
|
||||
inWriteFD = -1; outReadFD = -1
|
||||
lock.unlock()
|
||||
if w >= 0 { Foundation.close(w) }
|
||||
if r >= 0 { Foundation.close(r) }
|
||||
}
|
||||
|
||||
// MARK: - 私有
|
||||
|
||||
private func setMoshThread(_ tid: pthread_t) { lock.lock(); moshThread = tid; lock.unlock() }
|
||||
|
||||
private func handleExit(_ rc: Int32) {
|
||||
lock.lock(); moshThread = nil; lock.unlock()
|
||||
onClosed?(rc)
|
||||
}
|
||||
|
||||
/// mosh 主循环线程:fdopen 两端 FILE*,调用阻塞的 mosh_main。用 Foundation.Thread
|
||||
/// (而非 pthread_create + Unmanaged 上下文)以规避 Swift6 SendNonSendable pass 的编译器崩溃;
|
||||
/// 线程内 pthread_self() 取得 tid 供 SIGWINCH。
|
||||
private func startMosh(inReadFD: Int32, outWriteFD: Int32) {
|
||||
let ip = self.ip, port = self.port, key = self.key, predict = self.predictMode
|
||||
let winPtr = self.winPtr
|
||||
let t = Thread { [weak self] in
|
||||
self?.setMoshThread(pthread_self())
|
||||
guard let fin = fdopen(inReadFD, "r"), let fout = fdopen(outWriteFD, "w") else {
|
||||
self?.handleExit(-1); return
|
||||
}
|
||||
setvbuf(fout, nil, _IONBF, 0) // mosh 用 fwrite 写 out_fd,须无缓冲才能实时流出
|
||||
let rc = ip.withCString { ipC in
|
||||
port.withCString { portC in
|
||||
key.withCString { keyC in
|
||||
predict.withCString { prC in
|
||||
mosh_main(fin, fout, winPtr, ipC, portC, keyC, prC)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fflush(fout)
|
||||
self?.handleExit(rc)
|
||||
}
|
||||
t.name = "mosh-main"
|
||||
t.stackSize = 2 * 1024 * 1024
|
||||
t.start()
|
||||
}
|
||||
|
||||
/// 后台读线程:把 mosh 输出字节泵给 onBytes。
|
||||
private func startReader(fd: Int32) {
|
||||
let t = Thread { [weak self] in
|
||||
var buf = [UInt8](repeating: 0, count: 16384)
|
||||
while true {
|
||||
let n = buf.withUnsafeMutableBytes { read(fd, $0.baseAddress, $0.count) }
|
||||
if n <= 0 { break }
|
||||
let chunk = Array(buf[0..<n])
|
||||
self?.onBytes?(chunk)
|
||||
}
|
||||
}
|
||||
t.name = "mosh-reader"
|
||||
t.stackSize = 512 * 1024
|
||||
t.start()
|
||||
}
|
||||
}
|
||||
76
vendor/build/build-mosh.sh
vendored
Executable file
76
vendor/build/build-mosh.sh
vendored
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
# 交叉编译 mosh(blinksh/ios 分支) + protobuf-lite → MoshCore.xcframework(iOS device/simulator/macOS)。
|
||||
# crypto 后端 = Apple CommonCrypto(系统内建);特性宏由 build/mosh/config.h 手写提供(绕过 autotools)。
|
||||
# 产出 library-only xcframework(头文件与 modulemap 由包内 C target 提供,避免 modulemap 撞车,同 CSSHCore 教训)。
|
||||
set -euo pipefail
|
||||
|
||||
BUILD="$(cd "$(dirname "$0")" && pwd)" # vendor/build
|
||||
VENDOR="$(cd "$BUILD/.." && pwd)" # vendor
|
||||
MOSH_SRC="$VENDOR/mosh/src"
|
||||
PROTOBUF="$VENDOR/protobuf"
|
||||
PROTOBUF_SRC="$PROTOBUF/src"
|
||||
MOSH_CMAKE="$BUILD/mosh"
|
||||
OUT="$BUILD/mosh-out"
|
||||
ARTIFACTS="$VENDOR/../artifacts"
|
||||
IOS_DEPLOY=17.0
|
||||
MAC_DEPLOY=14.0
|
||||
|
||||
build_slice() {
|
||||
local name="$1" sysname="$2" sysroot="$3" archs="$4" deploy="$5"
|
||||
echo "==================== slice: $name ($archs @ $sysroot) ===================="
|
||||
rm -rf "$OUT/$name"; mkdir -p "$OUT/$name"
|
||||
|
||||
local common=(
|
||||
-G Ninja
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_SYSTEM_NAME="$sysname"
|
||||
-DCMAKE_OSX_SYSROOT="$sysroot"
|
||||
-DCMAKE_OSX_ARCHITECTURES="$archs"
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET="$deploy"
|
||||
)
|
||||
|
||||
# --- protobuf-lite(仅 lite runtime;mosh 的 .proto 是 proto2 + LITE_RUNTIME) ---
|
||||
cmake -S "$PROTOBUF" -B "$OUT/$name/protobuf" "${common[@]}" \
|
||||
-Dprotobuf_BUILD_TESTS=OFF \
|
||||
-Dprotobuf_BUILD_PROTOC_BINARIES=OFF \
|
||||
-Dprotobuf_BUILD_LIBPROTOC=OFF \
|
||||
-Dprotobuf_BUILD_SHARED_LIBS=OFF \
|
||||
-DCMAKE_CXX_STANDARD=14
|
||||
cmake --build "$OUT/$name/protobuf" --target libprotobuf-lite -j8
|
||||
|
||||
# --- moshios(我们的 CMakeLists,编 src/*.cc) ---
|
||||
cmake -S "$MOSH_CMAKE" -B "$OUT/$name/mosh" "${common[@]}" \
|
||||
-DMOSH_SRC="$MOSH_SRC" \
|
||||
-DPROTOBUF_SRC="$PROTOBUF_SRC"
|
||||
cmake --build "$OUT/$name/mosh" -j8
|
||||
|
||||
# --- 合并静态库 → 单一 libMoshCore.a ---
|
||||
libtool -static -o "$OUT/$name/libMoshCore.a" \
|
||||
"$OUT/$name/mosh/libmoshios.a" \
|
||||
"$OUT/$name/protobuf/libprotobuf-lite.a"
|
||||
echo "[+] $name → $(lipo -archs "$OUT/$name/libMoshCore.a")"
|
||||
}
|
||||
|
||||
pack_xcframework() {
|
||||
echo "==================== packing MoshCore.xcframework (library-only) ===================="
|
||||
rm -rf "$ARTIFACTS/MoshCore.xcframework"; mkdir -p "$ARTIFACTS"
|
||||
local args=()
|
||||
for s in "$@"; do
|
||||
args+=(-library "$OUT/$s/libMoshCore.a")
|
||||
done
|
||||
xcodebuild -create-xcframework "${args[@]}" -output "$ARTIFACTS/MoshCore.xcframework"
|
||||
echo "[+] MoshCore.xcframework:"; ls "$ARTIFACTS/MoshCore.xcframework"
|
||||
}
|
||||
|
||||
case "${1:-all}" in
|
||||
iossim) build_slice iossim iOS iphonesimulator "arm64;x86_64" "$IOS_DEPLOY" ;;
|
||||
device) build_slice ios-arm64 iOS iphoneos "arm64" "$IOS_DEPLOY" ;;
|
||||
macos) build_slice macos Darwin macosx "arm64" "$MAC_DEPLOY" ;;
|
||||
all)
|
||||
build_slice iossim iOS iphonesimulator "arm64;x86_64" "$IOS_DEPLOY"
|
||||
build_slice ios-arm64 iOS iphoneos "arm64" "$IOS_DEPLOY"
|
||||
build_slice macos Darwin macosx "arm64" "$MAC_DEPLOY"
|
||||
pack_xcframework iossim ios-arm64 macos
|
||||
;;
|
||||
pack) shift; pack_xcframework "$@" ;;
|
||||
esac
|
||||
83
vendor/build/mosh/CMakeLists.txt
vendored
Normal file
83
vendor/build/mosh/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(moshios CXX)
|
||||
|
||||
# 直接编译 blinksh/mosh(ios 分支) 的 src/*.cc 为静态库,绕过 autotools。
|
||||
# 特性宏由同目录手写 config.h 提供(-I 本目录,且优先于 src 树内任何 config.h)。
|
||||
# 变量入参:
|
||||
# MOSH_SRC —— vendor/mosh/src 绝对路径
|
||||
# PROTOBUF_SRC —— vendor/protobuf/src 绝对路径(提供 protobuf-lite 头)
|
||||
if(NOT DEFINED MOSH_SRC)
|
||||
message(FATAL_ERROR "MOSH_SRC 未设置")
|
||||
endif()
|
||||
if(NOT DEFINED PROTOBUF_SRC)
|
||||
message(FATAL_ERROR "PROTOBUF_SRC 未设置")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS ON) # gnu++14(mosh 用到 GNU 扩展)
|
||||
|
||||
# 依据 src/*/Makefile.am 的 BUILD_IOS_CONTROLLER 分支精确选取源文件。
|
||||
# 关键:terminal 用 terminaldisplayinit_ios.cc(非 terminaldisplayinit.cc,后者需 ncurses);
|
||||
# frontend 仅取 moshiosbridge/iosclient/terminaloverlay(排除 mosh-client/server/mosh/stmclient)。
|
||||
set(MOSH_SOURCES
|
||||
${MOSH_SRC}/crypto/base64.cc
|
||||
${MOSH_SRC}/crypto/crypto.cc
|
||||
${MOSH_SRC}/crypto/ocb.cc
|
||||
${MOSH_SRC}/network/compressor.cc
|
||||
${MOSH_SRC}/network/network.cc
|
||||
${MOSH_SRC}/network/networktransport.cc
|
||||
${MOSH_SRC}/network/transportfragment.cc
|
||||
${MOSH_SRC}/network/transportsender.cc
|
||||
${MOSH_SRC}/statesync/completeterminal.cc
|
||||
${MOSH_SRC}/statesync/user.cc
|
||||
${MOSH_SRC}/terminal/parseraction.cc
|
||||
${MOSH_SRC}/terminal/parser.cc
|
||||
${MOSH_SRC}/terminal/parserstate.cc
|
||||
${MOSH_SRC}/terminal/terminal.cc
|
||||
${MOSH_SRC}/terminal/terminaldispatcher.cc
|
||||
${MOSH_SRC}/terminal/terminaldisplay.cc
|
||||
${MOSH_SRC}/terminal/terminaldisplayinit_ios.cc
|
||||
${MOSH_SRC}/terminal/terminalframebuffer.cc
|
||||
${MOSH_SRC}/terminal/terminalfunctions.cc
|
||||
${MOSH_SRC}/terminal/terminaluserinput.cc
|
||||
${MOSH_SRC}/util/locale_utils.cc
|
||||
${MOSH_SRC}/util/pty_compat.cc
|
||||
${MOSH_SRC}/util/select.cc
|
||||
${MOSH_SRC}/util/swrite.cc
|
||||
${MOSH_SRC}/util/timestamp.cc
|
||||
${MOSH_SRC}/protobufs/hostinput.pb.cc
|
||||
${MOSH_SRC}/protobufs/transportinstruction.pb.cc
|
||||
${MOSH_SRC}/protobufs/userinput.pb.cc
|
||||
${MOSH_SRC}/frontend/moshiosbridge.cc
|
||||
${MOSH_SRC}/frontend/iosclient.cc
|
||||
${MOSH_SRC}/frontend/terminaloverlay.cc
|
||||
)
|
||||
|
||||
add_library(moshios STATIC ${MOSH_SOURCES})
|
||||
|
||||
target_include_directories(moshios PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR} # 手写 config.h(必须最先)
|
||||
${MOSH_SRC}
|
||||
${MOSH_SRC}/crypto
|
||||
${MOSH_SRC}/network
|
||||
${MOSH_SRC}/statesync
|
||||
${MOSH_SRC}/terminal
|
||||
${MOSH_SRC}/util
|
||||
${MOSH_SRC}/protobufs
|
||||
${MOSH_SRC}/frontend
|
||||
${PROTOBUF_SRC}
|
||||
)
|
||||
|
||||
# 1.3.2 老代码在 Xcode 26/新 clang 下告警多;关掉噪声,绝不开 -Werror。
|
||||
# 强制前置 <cstdint>:protobuf 3.21.12 的 stubs/port.h 用了 int8_t 却未自带 stdint 包含,
|
||||
# iOS SDK 头链比 host macOS 严格,会报 "unknown type name 'int8_t'"。全 TU 注入即修复。
|
||||
target_compile_options(moshios PRIVATE
|
||||
"SHELL:-include cstdint"
|
||||
-Wno-deprecated-declarations
|
||||
-Wno-deprecated-register
|
||||
-Wno-register
|
||||
-Wno-unused-parameter
|
||||
-Wno-writable-strings
|
||||
-fno-strict-aliasing
|
||||
)
|
||||
56
vendor/build/mosh/config.h
vendored
Normal file
56
vendor/build/mosh/config.h
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/* config.h — 手写替代 mosh autotools 的 configure 产物(iOS/macOS/Apple Silicon)。
|
||||
* 本环境缺 autoconf/automake,故不跑 ./autogen.sh;改由 CMake 直接编 src/*.cc,
|
||||
* 用本文件提供全部特性宏。仅面向 Darwin(iOS device/simulator, macOS arm64)。
|
||||
* 依据:configure.ac 的 AC_CHECK 系列 + 各 .cc 里实际引用的 HAVE / USE 宏收敛而来。 */
|
||||
#ifndef MOSH_TX_CONFIG_H
|
||||
#define MOSH_TX_CONFIG_H
|
||||
|
||||
/* --- 包标识(仅用于版本串打印) --- */
|
||||
#define PACKAGE_NAME "mosh"
|
||||
#define PACKAGE_STRING "mosh 1.3.2"
|
||||
#define PACKAGE_VERSION "1.3.2"
|
||||
#define VERSION "1.3.2"
|
||||
|
||||
/* --- iOS controller 模式:只编 client 库(对应 --enable-ios-controller) --- */
|
||||
#define IOS_CONTROLLER 1
|
||||
|
||||
/* --- crypto 后端:Apple CommonCrypto(iOS/macOS 系统内建,无需 OpenSSL/mbedTLS) ---
|
||||
* ocb.cc 用 `#elif USE_APPLE_COMMON_CRYPTO_AES` 选择 <CommonCrypto/CommonCryptor.h>。 */
|
||||
#define USE_APPLE_COMMON_CRYPTO_AES 1
|
||||
#define USE_OPENSSL_AES 0
|
||||
#define USE_NETTLE_AES 0
|
||||
#define USE_REFERENCE_AES 0
|
||||
#define USE_AES_NI 0
|
||||
|
||||
/* --- 时间源:iOS/macOS 均有 clock_gettime(CLOCK_MONOTONIC) --- */
|
||||
#define HAVE_CLOCK_GETTIME 1
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
#define HAVE_MACH_ABSOLUTE_TIME 1
|
||||
|
||||
/* --- 字节序:Darwin 用 <libkern/OSByteOrder.h>(byteorder.h 的 HAVE_OSX_SWAP 分支) --- */
|
||||
#define HAVE_OSX_SWAP 1
|
||||
#define HAVE_DECL_BE64TOH 0
|
||||
#define HAVE_DECL_BETOH64 0
|
||||
|
||||
/* --- 编译器内建(clang 全支持) --- */
|
||||
#define HAVE_DECL___BUILTIN_CTZ 1
|
||||
#define HAVE_DECL___BUILTIN_BSWAP64 1
|
||||
|
||||
/* --- Darwin/iOS 存在的头文件 --- */
|
||||
#define HAVE_LANGINFO_H 1
|
||||
#define HAVE_SYS_UIO_H 1
|
||||
#define HAVE_PATHS_H 1
|
||||
#define HAVE_UTIL_H 1
|
||||
#define HAVE_UTMPX_H 1
|
||||
|
||||
/* --- Darwin/iOS 存在的函数 --- */
|
||||
#define HAVE_POSIX_MEMALIGN 1
|
||||
#define HAVE_PSELECT 1
|
||||
#define HAVE_CFMAKERAW 1
|
||||
#define HAVE_FORKPTY 1
|
||||
|
||||
/* 说明:IP_MTU_DISCOVER / IP_RECVTOS(Linux only) 与 HAVE_IUTF8 均以 #ifdef 判定,
|
||||
* 此处不定义即自动跳过(network.cc 相关分支只在 Linux 生效;HAVE_IUTF8 仅被
|
||||
* 已排除的 mosh-server.cc/stmclient.cc 使用)。 */
|
||||
|
||||
#endif /* MOSH_TX_CONFIG_H */
|
||||
30
vendor/mosh/.gitignore
vendored
Normal file
30
vendor/mosh/.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
*.a
|
||||
*.o
|
||||
*.pb.cc
|
||||
*.pb.h
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
.cproject
|
||||
.project
|
||||
|
||||
/INSTALL
|
||||
/aclocal.m4
|
||||
/ar-lib
|
||||
/autom4te.cache
|
||||
/compile
|
||||
/config.h
|
||||
/config.h.in
|
||||
/config.h.in~
|
||||
/config.log
|
||||
/config.status
|
||||
/configure
|
||||
/depcomp
|
||||
/install-sh
|
||||
/missing
|
||||
/mosh-*.tar.gz
|
||||
/stamp-h1
|
||||
/test-driver
|
||||
/VERSION
|
||||
/scripts/mosh
|
||||
/version.h
|
||||
33
vendor/mosh/.travis.yml
vendored
Normal file
33
vendor/mosh/.travis.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
cache:
|
||||
- apt
|
||||
|
||||
language: cpp
|
||||
sudo: required
|
||||
dist: trusty
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- protobuf-compiler
|
||||
- libprotobuf-dev
|
||||
- libutempter-dev
|
||||
- tmux # test suite
|
||||
- perl # test suite
|
||||
|
||||
before_install:
|
||||
- if test "$TRAVIS_OS_NAME" = osx; then brew update; fi
|
||||
- if test "$TRAVIS_OS_NAME" = osx; then brew install protobuf tmux; fi
|
||||
- if test "$TRAVIS_OS_NAME" = osx; then brew outdated protobuf tmux || brew upgrade protobuf tmux; fi
|
||||
- git fetch --tags --unshallow
|
||||
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- ./configure --enable-compile-warnings=error --enable-examples
|
||||
- AM_TESTS_REDIRECT='9>&2' make distcheck 9>&2
|
||||
|
||||
notifications:
|
||||
irc: "chat.freenode.net#mosh"
|
||||
6
vendor/mosh/AUTHORS
vendored
Normal file
6
vendor/mosh/AUTHORS
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
Keith Winstein <mosh-devel@mit.edu>
|
||||
Anders Kaseorg
|
||||
Quentin Smith
|
||||
Richard Tibbetts
|
||||
Keegan McAllister
|
||||
John Hood
|
||||
674
vendor/mosh/COPYING
vendored
Normal file
674
vendor/mosh/COPYING
vendored
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
11
vendor/mosh/COPYING.iOS
vendored
Normal file
11
vendor/mosh/COPYING.iOS
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
The Mosh developers are aware that the terms of service that apply to
|
||||
apps distributed via Apple's App Store services may conflict with
|
||||
rights granted under Mosh's license, the GNU General Public License,
|
||||
version 3. The Mosh copyright holders do not wish this conflict to
|
||||
prevent the otherwise-compliant distribution of Mosh-derived apps via
|
||||
the App Store. Therefore, we have committed not to pursue any license
|
||||
violation that results solely from the conflict between the GPLv3 and
|
||||
the Apple App Store terms of service. In other words, as long as you
|
||||
comply with the GPL in all other respects, including its requirements
|
||||
to provide users with source code and the text of the license, we will
|
||||
not object to your distribution of Mosh through the App Store.
|
||||
351
vendor/mosh/ChangeLog
vendored
Normal file
351
vendor/mosh/ChangeLog
vendored
Normal file
@@ -0,0 +1,351 @@
|
||||
2015-07-12 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 1.2.5 released.
|
||||
|
||||
* New features:
|
||||
* Bind to a specific IP address with --bind-server. (Philipp
|
||||
Haselwarter)
|
||||
* MOSH_ESCAPE_KEY configures escape character. (Timo
|
||||
J. Rinne)
|
||||
* Support non-roaming IPv6. (Anders Kaseorg)
|
||||
* Implement XTerm mouse mode. (Barosl LEE, Andrew Chin,
|
||||
Louis Kruger)
|
||||
* Report Git revision along with version if available.
|
||||
(John Hood)
|
||||
|
||||
* Platform support:
|
||||
* Add pselect() emulation. (Jérémie Courrèges-Anglas)
|
||||
* OpenBSD, OS X: Fix be64toh-related issues. (Jérémie
|
||||
Courrèges-Anglas)
|
||||
* ARM Neon: fix gcc4.8 compiling problem(Pasi Sjöholm)
|
||||
* NaCl: Conditionally rename main to mosh_main. (Richard
|
||||
Woodbury)
|
||||
* FreeBSD: Token pasting, forkpty(), ARM fixes. (John Hood)
|
||||
* AIX: Implement CTTY grabbing when TIOCSCTTY is missing
|
||||
(Anton Lundin)
|
||||
* OS X: Broaden build support to cover OS X 10.5 through
|
||||
10.10. (John Hood)
|
||||
* Debian: Improve bash-completion install and
|
||||
functionality. (Suggested by Gabriel Filion, John Hood)
|
||||
|
||||
* Bug fixes:
|
||||
* Automake/autoconf workarounds. (Anders Kaseorg)
|
||||
* mosh-server: Allow startup without PTY. (Keith Winstein)
|
||||
* network.cc: Properly close old fd on Socket assignment
|
||||
operator. (Thanks to Igor Bukanov)
|
||||
* mosh-server: Allow startup with zero-window-size PTY.
|
||||
(Igor Bukanov)
|
||||
* AddrInfo: Fix error message generation when node == NULL
|
||||
(Anders Kaseorg)
|
||||
* Timestamp: Prevent integer overflow on Darwin PPC 32-bit
|
||||
(Anders Kaseorg)
|
||||
* scripts/mosh: Fix hang when remote closes the connection
|
||||
(Anders Kaseorg)
|
||||
* Fix issues with parsing of 256-color SGR sequences.
|
||||
(John Hood)
|
||||
* Numerous code hygiene, Coverity, and Clang static analyzer
|
||||
fixes. (Anders Kaseorg, Geoffrey Thomas, John Hood)
|
||||
|
||||
2013-03-27 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 1.2.4 released.
|
||||
|
||||
* New features:
|
||||
* Support port ranges with -p LOWPORT:HIGHPORT (Luke Mewburn)
|
||||
* Ctrl-^ Ctrl-Z suspends mosh client (Nikolai Zeldovich)
|
||||
* mm:ss display of lost-contact times (Kevin Ballard)
|
||||
* Show infobar with control chars when Ctrl-^ is typed
|
||||
* Put terminal in altscreen mode (Anders Kaseorg)
|
||||
* Tell automake/Debian pkg about our checks (Anders Kaseorg)
|
||||
|
||||
* Platform support:
|
||||
* OS X: Script to build a universal package (Peter Iannucci)
|
||||
* FreeBSD: Fix build problems (Jimmy Olgeni)
|
||||
* AIX: port by Anton Lundin
|
||||
* Solaris with system curses (Anton Lundin)
|
||||
* Cygwin and others: eliminate use of IO::Pty (Anton Lundin)
|
||||
|
||||
* Bug fixes:
|
||||
* Fix bug (introduced in 1.2.3) where server stays around
|
||||
if process quits while client is detached
|
||||
* Clean up spurious entries from detached sessions warning
|
||||
* Fix freeze when connectivity is one-directional for hours
|
||||
(reported by Axel Beckert)
|
||||
* Don't wipe title until a new one is set (sqweek)
|
||||
* Eliminate memory leaks and cppcheck warnings (Anders Kaseorg)
|
||||
|
||||
2012-10-19 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 1.2.3 released.
|
||||
|
||||
* Security improvements:
|
||||
* Use OpenSSL AES implementation
|
||||
* Update AES-OCB implementation (Keegan McAllister)
|
||||
* Don't let bad server dictate IP (Felix Groebert)
|
||||
|
||||
* New features:
|
||||
* Client hops ports to survive challenging client-side firewall
|
||||
* Server stops sending to save client power (Daniel Drown)
|
||||
* Set DiffServ code point and ECN-capable (Dave Täht)
|
||||
* Slow down if explicit congestion notification received
|
||||
* Warn about unattached Mosh sessions on login
|
||||
* Compatible with KDE konsole (uses BEL to terminate OSC)
|
||||
* Improved heuristic about color of predicted characters
|
||||
|
||||
* Bug fixes:
|
||||
* Improved performance on systems with expensive time
|
||||
* No longer choke on "ffff::" address for hosts with IPv6
|
||||
* More conservative MTU and datagram sizing
|
||||
|
||||
* Platform support:
|
||||
* Build on Solaris and IllumOS (Timo Sirainen, Ira Cooper)
|
||||
* Build on ARM with gcc 4.7 (Alexander Chernyakhovsky)
|
||||
|
||||
* Licensing changes:
|
||||
* Allow distribution on Apple App Stores
|
||||
* Allow linking with OpenSSL
|
||||
|
||||
2012-06-12 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 1.2.2 released.
|
||||
|
||||
* Remove warning on out-of-order/duplicated datagrams
|
||||
|
||||
* Add "experimental" prediction mode
|
||||
|
||||
2012-05-25 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 1.2.1 released.
|
||||
|
||||
* Improve performance on lossy links.
|
||||
|
||||
* New diagnostic message when link is dead in only one direction.
|
||||
|
||||
* Use less CPU when link is down. (Keegan McAllister)
|
||||
|
||||
* Use much less CPU when application or mosh-server sends
|
||||
large repeat counts (resolves CVE-2012-2385, reported by
|
||||
Timo Juhani Lindfors).
|
||||
|
||||
* Use less memory when mosh-server is malicious.
|
||||
|
||||
* Fix vttest regression re: wrapping and tabs.
|
||||
|
||||
* Enable roundtrip verifier of terminal emulator correctness
|
||||
when verbose.
|
||||
|
||||
* Remove skalibs as a dependency. (Keegan McAllister)
|
||||
|
||||
* Remove use of poll() and OS X poll workaround. (Keegan McAllister)
|
||||
|
||||
* Include bash_completion file. (ejeffrey)
|
||||
|
||||
* Include UFW firewall profile. (Fumihito YOSHIDA)
|
||||
|
||||
* Warning on out-of-order/duplicated datagrams
|
||||
(or failed nonce increment).
|
||||
|
||||
* Clearer error message on invalid port number.
|
||||
|
||||
* Cleanups to quit scenario when firewalled.
|
||||
|
||||
2012-04-26 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 1.2 released.
|
||||
|
||||
* Remove Boost as a dependency (Keegan McAllister)
|
||||
|
||||
* Add support for FreeBSD, Cygwin, RHEL/CentOS 5, OS X 10.5 on PPC.
|
||||
|
||||
* More verbose and helpful diagnostics. Server now has -v flag.
|
||||
|
||||
* Client now has --ssh= flag to set SSH options (like port)
|
||||
|
||||
* Remove skalibs as a dependency on Debian/Ubuntu (Keegan McAllister)
|
||||
|
||||
* Now passes locale-related env vars over the connection
|
||||
|
||||
* Fix startup script to no longer hang on some Macs (Jay Freeman)
|
||||
|
||||
* Fix terminal emulation and argument parsing on FreeBSD
|
||||
|
||||
* Fix alignment problems on ARM
|
||||
|
||||
* Now prints message of the day
|
||||
|
||||
* Use binary hardening flags where available (Keegan McAllister)
|
||||
|
||||
* Responsiveness and CPU-usage improvements
|
||||
|
||||
* Several terminal-emulation improvements and bug fixes
|
||||
|
||||
2012-04-03 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 1.1.3 released.
|
||||
|
||||
* Builds on armel, armhf, and kFreeBSD.
|
||||
|
||||
* Fixes bug causing occasional missing/extra wraparound copy-and-paste.
|
||||
|
||||
* Eliminates valgrind complaint over unused winsize fields.
|
||||
|
||||
* Close connection after four petabytes (per OCB recommendation).
|
||||
|
||||
2012-03-28 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 1.1.2 released.
|
||||
|
||||
* Fixes to build on OS X 10.5 with older gcc and -lpoll (Quentin Smith)
|
||||
|
||||
* Add --with-utempter and --without-utempter per gentoo request
|
||||
(Michael Weber)
|
||||
|
||||
* configure now requires ncurses headers (and others) to be installed
|
||||
|
||||
* Consolidate locale routines to help Android port (Keegan McAllister)
|
||||
|
||||
2012-03-27 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 1.1.1 released.
|
||||
|
||||
* Fix spec file and build failure on Fedora.
|
||||
|
||||
* Print out error message properly on fatal_assert().
|
||||
|
||||
* Support for machines without posix_memalign().
|
||||
|
||||
2012-03-22 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 1.1 released (stable release).
|
||||
|
||||
* Allows user to specify remote command to execute.
|
||||
|
||||
* Only advertises 256 colors when user's terminal has 256 colors.
|
||||
|
||||
* Add chaff to datagrams to frustrate statistical analysis of length
|
||||
|
||||
* Cosmetic fixes to terminal handling
|
||||
|
||||
* Improved startup script (Anders Kaseorg)
|
||||
|
||||
2012-03-16 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 1.0.2 released.
|
||||
|
||||
* Uses xterm-256color and supports 256-color escape sequences.
|
||||
|
||||
* Posterizes to 8 colors unless the user has a 256-color terminal.
|
||||
|
||||
* Handles terminals without BCE.
|
||||
|
||||
* Starts login shell.
|
||||
|
||||
2012-03-14 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 1.0.1 released.
|
||||
|
||||
* Roughly 40% less CPU usage.
|
||||
|
||||
2012-03-12 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 1.0 released.
|
||||
|
||||
* mosh now supports --version option and prints no-warranty message.
|
||||
|
||||
2012-03-10 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 0.98 released.
|
||||
|
||||
* Add option to select server-side UDP port.
|
||||
|
||||
* Restrict default UDP port range to 60000..61000.
|
||||
|
||||
* Use TERM / terminfo to decide when to send ECH sequence.
|
||||
|
||||
* Now works properly inside tmux.
|
||||
|
||||
2012-03-07 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 0.97 released.
|
||||
|
||||
* Merged Mac OS X port (thanks to Quentin Smith and Anders Kaseorg)
|
||||
|
||||
* Server will quit if no connection within first 60 seconds
|
||||
|
||||
* Startup script no longer requires threaded Perl
|
||||
|
||||
* Add --enable-compile-warnings=error to ./configure
|
||||
|
||||
* Fix some flicker issues with adaptive prediction mode
|
||||
|
||||
2012-02-26 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 0.96 released.
|
||||
|
||||
* Compress all instructions with zlib
|
||||
|
||||
2012-02-25 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 0.95 released.
|
||||
|
||||
* Make echo acknowledgment reliable to reduce spurious mispredict detections.
|
||||
|
||||
* Require two dropped heartbeats before showing blue bar of lost contact
|
||||
|
||||
* Print newline before MOSH CONNECT string to make more robust if intermediate keys hit
|
||||
|
||||
* Disable ControlMaster in initial SSH connection so proxy is always used
|
||||
|
||||
* Make retransmissions occur at frame rate (vs. every 3 seconds) for limited time after loss
|
||||
|
||||
2012-02-15 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 0.94 released.
|
||||
|
||||
* Make man pages
|
||||
|
||||
* Replace C++11 features (lambda and auto) with boost equivalents
|
||||
(Anders Kaseorg)
|
||||
|
||||
* Now builds with g++ or clang (with libstdc++)
|
||||
|
||||
2012-02-13 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 0.93 released.
|
||||
|
||||
* Make utmp entries
|
||||
|
||||
2012-02-13 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 0.92 released.
|
||||
|
||||
* Allows user to select prediction mode (always/never/adaptive)
|
||||
|
||||
* Fix bug in server startup on slow hosts
|
||||
|
||||
* Better prediction when deleting at line ending
|
||||
|
||||
2012-02-09 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 0.91 released.
|
||||
|
||||
* Startup script support SSH options and aliases (Anders Kaseorg)
|
||||
|
||||
* End use of Path MTU discovery and allow IP fragmentation because,
|
||||
e.g., Cisco VPN has MTU of 1200 and does not pass ICMP too-big.
|
||||
|
||||
* Better exception and error handling.
|
||||
|
||||
* Restrict predictive local echo display to long-delay links
|
||||
(>60 ms RTT) or for temporarily after a "glitch." Otherwise simply
|
||||
show server echos, while maintaining prediction overlay in the
|
||||
background in case it is needed.
|
||||
|
||||
2012-02-07 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 0.9b released.
|
||||
* Improvements to build system (Anders Kaseorg)
|
||||
|
||||
2012-02-06 Keith Winstein <mosh-devel@mit.edu>
|
||||
|
||||
* Version 0.9 released.
|
||||
45
vendor/mosh/Makefile.am
vendored
Normal file
45
vendor/mosh/Makefile.am
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
SUBDIRS = scripts src man conf
|
||||
EXTRA_DIST = autogen.sh ocb-license.html README.md COPYING.iOS
|
||||
BUILT_SOURCES = version.h
|
||||
CLANG_SCAN_BUILD = scan-build
|
||||
AM_DISTCHECK_CONFIGURE_FLAGS = --enable-compile-warnings=distcheck --enable-examples
|
||||
|
||||
.PHONY: VERSION
|
||||
|
||||
VERSION:
|
||||
@echo @PACKAGE_STRING@ > VERSION.dist
|
||||
@set -e; if git describe --dirty --always > VERSION.git 2>&1 && \
|
||||
[ -z `git rev-parse --show-prefix` ]; then \
|
||||
if ! diff -q VERSION.git VERSION > /dev/null 2>&1; then \
|
||||
mv -f VERSION.git VERSION; \
|
||||
fi; \
|
||||
elif ! diff -q VERSION.dist VERSION > /dev/null 2>&1; then \
|
||||
mv -f VERSION.dist VERSION; \
|
||||
fi
|
||||
@rm -f VERSION.dist VERSION.git
|
||||
|
||||
version.h: VERSION
|
||||
@printf '#define BUILD_VERSION "%s"\n' "$$(cat VERSION)" > version.h.new
|
||||
@set -e; if ! diff -q version.h version.h.new > /dev/null 2>&1; then \
|
||||
mv -f version.h.new version.h; \
|
||||
fi
|
||||
@rm -f version.h.new
|
||||
|
||||
clean-local:
|
||||
@rm -rf version.h VERSION cov-int mosh-coverity.txz
|
||||
|
||||
cppcheck: $(BUILT_SOURCES) config.h
|
||||
cppcheck --enable=all --template=gcc -include config.h -I . \
|
||||
-I src/crypto -I src/frontend -I src/network -I src/protobufs \
|
||||
-I src/statesync -I src/terminal -I src/util \
|
||||
-I /usr/include -I /usr/include/google/protobuf -I/usr/include/openssl \
|
||||
.
|
||||
|
||||
cov-build: $(BUILT_SOURCES) config.h
|
||||
$(MAKE) clean && rm -rf cov-int && \
|
||||
cov-build --dir cov-int $(MAKE) check && \
|
||||
tar -caf mosh-coverity.txz cov-int
|
||||
|
||||
scan-build: $(BUILT_SOURCES) config.h
|
||||
$(MAKE) clean && $(CLANG_SCAN_BUILD) $(MAKE) check
|
||||
26
vendor/mosh/NEWS
vendored
Normal file
26
vendor/mosh/NEWS
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
2012-04-26
|
||||
----------
|
||||
|
||||
* Version 1.2 released
|
||||
|
||||
2012-03-22
|
||||
----------
|
||||
|
||||
* Version 1.1 released
|
||||
|
||||
2012-03-12
|
||||
----------
|
||||
|
||||
* Version 1.0 released
|
||||
|
||||
2012-03-07 Release candidate (0.97):
|
||||
------------------------------------
|
||||
|
||||
* Now builds on Mac OS X as well as GNU/Linux
|
||||
|
||||
2012-02-06 Initial release (0.9):
|
||||
---------------------------------
|
||||
|
||||
* Supports intermittent connectivity
|
||||
* Supports client and server IP roaming
|
||||
* Local echo supports typing and the left and right arrow keys
|
||||
15
vendor/mosh/README.md
vendored
Normal file
15
vendor/mosh/README.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
#iOSClient for Mosh
|
||||
These are a set of small changes to make Mosh compile for iOS as
|
||||
a separate library that can be linked into applications. Please do
|
||||
not use to compile mosh-client or mosh-server. You can use a separate
|
||||
script [Build Mosh](https://github.com/blinksh/build-mosh) and it is
|
||||
currently being used in [Blink](https://github.com/blinksh/blink).
|
||||
|
||||
There are four main changes to the original Mosh code, that we hope to
|
||||
integrate at some point with the main branch:
|
||||
- iOSClient as a new main loop for the library.
|
||||
- Multithread code suppport.
|
||||
- Makefiles support for the iOS version.
|
||||
- Bug fixes (sockets, etc...)
|
||||
|
||||
Original Mosh can be found on [Mosh](https://github.com/mobile-shell/mosh)
|
||||
88
vendor/mosh/THANKS
vendored
Normal file
88
vendor/mosh/THANKS
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
* Hari Balakrishnan, who advised this work and came up with the name.
|
||||
|
||||
* Paul Williams (www.vt100.net), whose reverse-engineered vt500 state
|
||||
diagram is the basis for the Mosh parser.
|
||||
|
||||
* The anonymous users who contributed session logs for tuning and
|
||||
measuring Mosh's predictive echo.
|
||||
|
||||
* Nickolai Zeldovich for helpful comments on the Mosh research paper.
|
||||
|
||||
* Richard Stallman for helpful discussion about the capabilities of
|
||||
the SUPDUP Local Editing Protocol.
|
||||
|
||||
* Nelson Elhage
|
||||
|
||||
* Christine Spang
|
||||
|
||||
* Stefie Tellex
|
||||
|
||||
* Joseph Sokol-Margolis
|
||||
|
||||
* Waseem Daher
|
||||
|
||||
* Bill McCloskey
|
||||
|
||||
* Austin Roach
|
||||
|
||||
* Greg Hudson
|
||||
|
||||
* Karl Ramm
|
||||
|
||||
* Alexander Chernyakhovsky
|
||||
|
||||
* Peter Iannucci
|
||||
|
||||
* Evan Broder
|
||||
|
||||
* Neha Narula
|
||||
|
||||
* Katrina LaCurts
|
||||
|
||||
* Ramesh Chandra
|
||||
|
||||
* Peter Jeremy
|
||||
|
||||
* Ed Schouten
|
||||
|
||||
* Ryan Steinmetz
|
||||
|
||||
* Jay Freeman
|
||||
|
||||
* Dave Täht
|
||||
|
||||
* Larry Doolittle
|
||||
|
||||
* Daniel Drown
|
||||
|
||||
* Timo Juhani Lindfors
|
||||
|
||||
* Timo Sirainen
|
||||
|
||||
* Ira Cooper
|
||||
|
||||
* Felix Gröbert
|
||||
|
||||
* Luke Mewburn
|
||||
|
||||
* Anton Lundin
|
||||
|
||||
* Philipp Haselwarter
|
||||
|
||||
* Timo J. Rinne
|
||||
|
||||
* Barosl Lee
|
||||
|
||||
* Andrew Chin
|
||||
|
||||
* Louis Kruger
|
||||
|
||||
* Jérémie Courrèges-Anglas
|
||||
|
||||
* Pasi Sjöholm
|
||||
|
||||
* Richard Woodbury
|
||||
|
||||
* Igor Bukanov
|
||||
|
||||
* Geoffrey Thomas
|
||||
3
vendor/mosh/autogen.sh
vendored
Executable file
3
vendor/mosh/autogen.sh
vendored
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec autoreconf -fi
|
||||
3
vendor/mosh/build-package.sh
vendored
Executable file
3
vendor/mosh/build-package.sh
vendored
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
git-buildpackage --git-upstream-branch=master --git-upstream-tree=branch
|
||||
11
vendor/mosh/conf/Makefile.am
vendored
Normal file
11
vendor/mosh/conf/Makefile.am
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
completionsdir = @completions@
|
||||
dist_completions_DATA =
|
||||
nobase_dist_sysconf_DATA =
|
||||
|
||||
if INSTALL_UFW
|
||||
nobase_dist_sysconf_DATA += ufw/applications.d/mosh
|
||||
endif
|
||||
|
||||
if INSTALL_COMPLETION
|
||||
dist_completions_DATA += bash-completion/completions/mosh
|
||||
endif
|
||||
9
vendor/mosh/conf/bash-completion/completions/mosh
vendored
Normal file
9
vendor/mosh/conf/bash-completion/completions/mosh
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
_mosh () {
|
||||
local cur prev
|
||||
|
||||
_init_completion || return
|
||||
|
||||
_known_hosts_real -a "$cur"
|
||||
}
|
||||
|
||||
complete -F _mosh mosh
|
||||
4
vendor/mosh/conf/ufw/applications.d/mosh
vendored
Normal file
4
vendor/mosh/conf/ufw/applications.d/mosh
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[mosh]
|
||||
title=Mosh (mobile shell)
|
||||
description=Mobile shell that supports roaming and intelligent local echo
|
||||
ports=60000:61000/udp
|
||||
512
vendor/mosh/configure.ac
vendored
Normal file
512
vendor/mosh/configure.ac
vendored
Normal file
@@ -0,0 +1,512 @@
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.61])
|
||||
AC_INIT([mosh], [1.2.5], [mosh-devel@mit.edu])
|
||||
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
AC_CONFIG_SRCDIR([src/frontend/mosh-client.cc])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_RANLIB
|
||||
AC_PATH_PROG([PROTOC], [protoc], [])
|
||||
AS_IF([test x"$PROTOC" = x],
|
||||
[AC_MSG_ERROR([cannot find protoc, the Protocol Buffers compiler])])
|
||||
|
||||
# automake 1.12 seems to require this, but automake 1.11 doesn't recognize it
|
||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||
|
||||
WARNING_CXXFLAGS=""
|
||||
PICKY_CXXFLAGS=""
|
||||
AC_ARG_ENABLE([compile-warnings],
|
||||
[AS_HELP_STRING([--enable-compile-warnings@<:@=no/yes/maximum/error/distcheck@:>@],
|
||||
[Turn on compiler warnings])],
|
||||
[case "$enableval" in
|
||||
no)
|
||||
;;
|
||||
'' | yes)
|
||||
WARNING_CXXFLAGS="-Wall"
|
||||
;;
|
||||
maximum)
|
||||
WARNING_CXXFLAGS="-Wall"
|
||||
PICKY_CXXFLAGS="-Wextra -pedantic -Wno-long-long -Weffc++ -Wmissing-declarations"
|
||||
;;
|
||||
error)
|
||||
WARNING_CXXFLAGS="-Wall -Werror"
|
||||
PICKY_CXXFLAGS="-Wextra -pedantic -Wno-long-long -Weffc++ -Wmissing-declarations"
|
||||
;;
|
||||
distcheck)
|
||||
if test "$(uname -s)" = Linux; then
|
||||
WARNING_CXXFLAGS="-Wall -Werror"
|
||||
else
|
||||
WARNING_CXXFLAGS="-Wall"
|
||||
fi
|
||||
PICKY_CXXFLAGS="-Wextra -pedantic -Wno-long-long -Weffc++ -Wmissing-declarations"
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Unknown argument '$enableval' to --enable-compile-warnings])
|
||||
;;
|
||||
esac],
|
||||
[WARNING_CXXFLAGS="-Wall"])
|
||||
AC_SUBST([WARNING_CXXFLAGS])
|
||||
AC_SUBST([PICKY_CXXFLAGS])
|
||||
|
||||
# We want to check for compiler flag support, but there is no way to make
|
||||
# clang's "argument unused" warning fatal. So we invoke the compiler through a
|
||||
# wrapper script that greps for this message.
|
||||
|
||||
saved_CC="$CC"
|
||||
saved_CXX="$CXX"
|
||||
saved_LD="$LD"
|
||||
flag_wrap="$srcdir/scripts/wrap-compiler-for-flag-check"
|
||||
CC="$flag_wrap $CC"
|
||||
CXX="$flag_wrap $CXX"
|
||||
LD="$flag_wrap $LD"
|
||||
|
||||
# We use the same hardening flags for C and C++. We must check that each flag
|
||||
# is supported by both compilers.
|
||||
AC_DEFUN([check_cc_cxx_flag],
|
||||
[AC_LANG_PUSH(C)
|
||||
AX_CHECK_COMPILE_FLAG([$1],
|
||||
[AC_LANG_PUSH(C++)
|
||||
AX_CHECK_COMPILE_FLAG([$1], [$2], [$3], [-Werror $4])
|
||||
AC_LANG_POP(C++)],
|
||||
[$3], [-Werror $4])
|
||||
AC_LANG_POP(C)])
|
||||
AC_DEFUN([check_link_flag],
|
||||
[AX_CHECK_LINK_FLAG([$1], [$2], [$3], [-Werror $4])])
|
||||
|
||||
AC_ARG_ENABLE([hardening],
|
||||
[AS_HELP_STRING([--enable-hardening],
|
||||
[Enable compiler and linker options to frustrate memory corruption exploits @<:@yes@:>@])],
|
||||
[hardening="$enableval"],
|
||||
[hardening="yes"])
|
||||
|
||||
HARDEN_CFLAGS=""
|
||||
HARDEN_LDFLAGS=""
|
||||
AS_IF([test x"$hardening" != x"no"], [
|
||||
check_cc_cxx_flag([-fno-strict-overflow], [HARDEN_CFLAGS="$HARDEN_CFLAGS -fno-strict-overflow"])
|
||||
|
||||
# This one will likely succeed, even on platforms where it does nothing.
|
||||
check_cc_cxx_flag([-D_FORTIFY_SOURCE=2], [HARDEN_CFLAGS="$HARDEN_CFLAGS -D_FORTIFY_SOURCE=2"])
|
||||
|
||||
check_cc_cxx_flag([-fstack-protector-all],
|
||||
[HARDEN_CFLAGS="$HARDEN_CFLAGS -fstack-protector-all"
|
||||
check_cc_cxx_flag([-Wstack-protector], [HARDEN_CFLAGS="$HARDEN_CFLAGS -Wstack-protector"],
|
||||
[], [-fstack-protector-all])
|
||||
check_cc_cxx_flag([--param ssp-buffer-size=1], [HARDEN_CFLAGS="$HARDEN_CFLAGS --param ssp-buffer-size=1"],
|
||||
[], [-fstack-protector-all])])
|
||||
|
||||
check_cc_cxx_flag([-fPIE],
|
||||
[check_link_flag([-fPIE -pie],
|
||||
[HARDEN_CFLAGS="$HARDEN_CFLAGS -fPIE"
|
||||
HARDEN_LDFLAGS="$HARDEN_LDFLAGS -pie"],
|
||||
[check_link_flag([-fPIE -Wl,-pie],
|
||||
[HARDEN_CFLAGS="$HARDEN_CFLAGS -fPIE"
|
||||
HARDEN_LDFLAGS="$HARDEN_LDFLAGS -Wl,-pie"])])])
|
||||
|
||||
check_link_flag([-Wl,-z,relro],
|
||||
[HARDEN_LDFLAGS="$HARDEN_LDFLAGS -Wl,-z,relro"
|
||||
check_link_flag([-Wl,-z,now], [HARDEN_LDFLAGS="$HARDEN_LDFLAGS -Wl,-z,now"])])])
|
||||
AC_SUBST([HARDEN_CFLAGS])
|
||||
AC_SUBST([HARDEN_LDFLAGS])
|
||||
|
||||
# Also check for a few non-hardening-related flags.
|
||||
MISC_CXXFLAGS=""
|
||||
AC_LANG_PUSH(C++)
|
||||
AX_CHECK_COMPILE_FLAG([-fno-default-inline],
|
||||
[MISC_CXXFLAGS="$MISC_CXXFLAGS -fno-default-inline"], [], [-Werror])
|
||||
AX_CHECK_COMPILE_FLAG([-pipe],
|
||||
[MISC_CXXFLAGS="$MISC_CXXFLAGS -pipe"], [], [-Werror])
|
||||
AC_LANG_POP(C++)
|
||||
AC_SUBST([MISC_CXXFLAGS])
|
||||
|
||||
# End of flag tests.
|
||||
CC="$saved_CC"
|
||||
CXX="$saved_CXX"
|
||||
LD="$saved_LD"
|
||||
|
||||
AC_ARG_ENABLE([client],
|
||||
[AS_HELP_STRING([--enable-client], [Build the mosh-client program @<:@yes@:>@])],
|
||||
[build_client="$enableval"],
|
||||
[build_client="yes"])
|
||||
AM_CONDITIONAL([BUILD_CLIENT], [test x"$build_client" != xno])
|
||||
|
||||
AC_ARG_ENABLE([server],
|
||||
[AS_HELP_STRING([--enable-server], [Build the mosh-server program @<:@yes@:>@])],
|
||||
[build_server="$enableval"],
|
||||
[build_server="yes"])
|
||||
AM_CONDITIONAL([BUILD_SERVER], [test x"$build_server" != xno])
|
||||
|
||||
AC_ARG_ENABLE([ios-controller],
|
||||
[AS_HELP_STRING([--enable-ios-controller], [Build the mosh iOS controller library @<:@no@:>@])],
|
||||
[build_ios_controller="$enableval"],
|
||||
[build_ios_controller="no"])
|
||||
AM_CONDITIONAL([BUILD_IOS_CONTROLLER], [test x"$build_ios_controller" != xno])
|
||||
AS_IF([test x"$build_ios_controller" != xno], [AC_DEFINE([IOS_CONTROLLER], [1], [Define if compiling iOS controller])])
|
||||
|
||||
AC_ARG_ENABLE([examples],
|
||||
[AS_HELP_STRING([--enable-examples], [Build the miscellaneous programs in src/examples @<:@no@:>@])],
|
||||
[build_examples="$enableval"],
|
||||
[build_examples="no"])
|
||||
AM_CONDITIONAL([BUILD_EXAMPLES], [test x"$build_examples" != xno])
|
||||
|
||||
AC_ARG_ENABLE([ufw],
|
||||
[AS_HELP_STRING([--enable-ufw], [Install firewall profile for ufw (Uncomplicated Firewall) @<:@no@:>@])],
|
||||
[install_ufw="$enableval"],
|
||||
[install_ufw="no"])
|
||||
AM_CONDITIONAL([INSTALL_UFW], [test x"$install_ufw" != xno])
|
||||
|
||||
AC_ARG_ENABLE([completion],
|
||||
[AS_HELP_STRING([--enable-completion], [Install bash_completion rule @<:@no@:>@])],
|
||||
[install_completion="$enableval"],
|
||||
[install_completion="no"])
|
||||
AM_CONDITIONAL([INSTALL_COMPLETION], [test x"$install_completion" != xno])
|
||||
|
||||
# Checks for libraries.
|
||||
AC_ARG_WITH([utempter],
|
||||
[AS_HELP_STRING([--with-utempter], [write utmp entries using libutempter @<:@check@:>@])],
|
||||
[with_utempter="$withval"],
|
||||
[with_utempter="check"])
|
||||
AS_IF([test x"$with_utempter" != xno],
|
||||
[AC_SEARCH_LIBS([utempter_remove_record], [utempter],
|
||||
[AC_DEFINE([HAVE_UTEMPTER], [1], [Define if libutempter is available.])],
|
||||
[AS_IF([test x"$with_utempter" = xcheck],
|
||||
[AC_MSG_WARN([Unable to find libutempter; utmp entries will not be made.])],
|
||||
[AC_MSG_ERROR([--with-utempter was given but libutempter was not found.])])])])
|
||||
|
||||
AC_SEARCH_LIBS([compress], [z], , [AC_MSG_ERROR([Unable to find zlib.])])
|
||||
|
||||
AC_SEARCH_LIBS([socket], [socket])
|
||||
AC_SEARCH_LIBS([inet_addr], [nsl])
|
||||
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS(m4_normalize([
|
||||
fcntl.h
|
||||
langinfo.h
|
||||
limits.h
|
||||
locale.h
|
||||
netdb.h
|
||||
netinet/in.h
|
||||
stddef.h
|
||||
stdint.h
|
||||
inttypes.h
|
||||
stdlib.h
|
||||
string.h
|
||||
sys/ioctl.h
|
||||
sys/resource.h
|
||||
sys/socket.h
|
||||
sys/stat.h
|
||||
sys/time.h
|
||||
termios.h
|
||||
unistd.h
|
||||
wchar.h
|
||||
wctype.h
|
||||
]), [], [AC_MSG_ERROR([Missing required header file.])])
|
||||
|
||||
AC_CHECK_HEADERS([pty.h util.h libutil.h paths.h])
|
||||
AC_CHECK_HEADERS([endian.h sys/endian.h])
|
||||
AC_CHECK_HEADERS([utmpx.h])
|
||||
AC_CHECK_HEADERS([termio.h])
|
||||
AC_CHECK_HEADERS([sys/uio.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_HEADER_STDBOOL
|
||||
AC_C_INLINE
|
||||
AC_TYPE_INT64_T
|
||||
AC_TYPE_PID_T
|
||||
AC_C_RESTRICT
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_SSIZE_T
|
||||
AC_TYPE_UINT16_T
|
||||
AC_TYPE_UINT32_T
|
||||
AC_TYPE_UINT64_T
|
||||
AC_TYPE_UINT8_T
|
||||
AC_TYPE_UINTPTR_T
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_FORK
|
||||
AC_FUNC_MBRTOWC
|
||||
AC_CHECK_FUNCS(m4_normalize([
|
||||
gettimeofday
|
||||
setrlimit
|
||||
iswprint
|
||||
memchr
|
||||
memset
|
||||
nl_langinfo
|
||||
posix_memalign
|
||||
setenv
|
||||
setlocale
|
||||
sigaction
|
||||
socket
|
||||
strchr
|
||||
strdup
|
||||
strncasecmp
|
||||
strtok
|
||||
strerror
|
||||
strtol
|
||||
wcwidth
|
||||
cfmakeraw
|
||||
pselect
|
||||
getaddrinfo
|
||||
getnameinfo
|
||||
]))
|
||||
|
||||
# AC_SEARCH_LIBS([clock_gettime], [rt], [AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Define if clock_gettime is available.])])
|
||||
|
||||
# Start by trying to find the needed tinfo parts by pkg-config
|
||||
PKG_CHECK_MODULES([TINFO], [tinfo],
|
||||
[AC_DEFINE([HAVE_CURSES_H], [1], [Define to 1 if <curses.h> is present])],
|
||||
[PKG_CHECK_MODULES([TINFO], [ncurses],
|
||||
[AC_DEFINE([HAVE_CURSES_H], [1], [Define to 1 if <curses.h> is present])],
|
||||
[AX_CHECK_LIBRARY([TINFO], [curses.h], [tinfo],
|
||||
[AC_DEFINE([HAVE_CURSES_H], [1], [Define to 1 if <curses.h> is present])
|
||||
AC_SUBST([TINFO_CFLAGS], ["$TINFO_CPPFLAGS"])
|
||||
AC_SUBST([TINFO_LIBS], ["$TINFO_LDFLAGS -ltinfo"])],)])])
|
||||
|
||||
# Then try to find it in a specific install dir
|
||||
AC_ARG_WITH(curses, AC_HELP_STRING([--with-curses=DIR], [Where curses is installed]),
|
||||
[if test $withval != yes; then
|
||||
cv_curses=$withval
|
||||
fi
|
||||
if test x$cv_curses != x/usr; then
|
||||
CURSES_LDFLAGS="-L${cv_curses}/lib"
|
||||
CURSES_CPPFLAGS="-I${cv_curses}/include"
|
||||
fi])
|
||||
|
||||
if test "x$ax_cv_have_TINFO" = xno ; then
|
||||
# save away old LDFLAGS/CPPFLAGS and check for curses with cv_curses
|
||||
old_LDFLAGS="$LDFLAGS"
|
||||
old_CPPFLAGS="$CPPFLAGS"
|
||||
LDFLAGS="$LDFLAGS $CURSES_LDFLAGS"
|
||||
CPPFLAGS="$LDFLAGS $CURSES_CPPFLAGS"
|
||||
|
||||
AX_WITH_CURSES
|
||||
# restore old LDFLAGS/CPPFLAGS
|
||||
LDFLAGS="$old_LDFLAGS"
|
||||
CPPFLAGS="$old_CPPFLAGS"
|
||||
|
||||
if test "x$ax_cv_curses_which" = xno ; then
|
||||
AC_MSG_ERROR([requires either tinfo, NcursesW or Ncurses library])
|
||||
else
|
||||
AC_SUBST([TINFO_LIBS], ["$CURSES_LDFLAGS $CURSES_LIB"])
|
||||
AC_SUBST([TINFO_CFLAGS], ["$CURSES_CPPFLAGS"])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Default to OpenSSL, or OS X crypto library if found
|
||||
AC_CHECK_HEADERS([CommonCrypto/CommonCrypto.h],
|
||||
[default_crypto_library="apple-common-crypto"],
|
||||
[default_crypto_library="openssl"]
|
||||
)
|
||||
|
||||
dnl Allow user to select over the default.
|
||||
AC_ARG_WITH(
|
||||
[crypto-library],
|
||||
[AS_HELP_STRING([--with-crypto-library=library], [build with the given crypto library, TYPE=openssl|nettle|apple-common-crypto @<:@default=openssl@:>@])],
|
||||
[
|
||||
case "${withval}" in
|
||||
openssl|nettle|apple-common-crypto) ;;
|
||||
*) AC_MSG_ERROR([bad value ${withval} for --with-crypto-library]) ;;
|
||||
esac
|
||||
],
|
||||
[with_crypto_library="$default_crypto_library"]
|
||||
)
|
||||
|
||||
dnl Checks for chosen crypto library
|
||||
case "${with_crypto_library}" in
|
||||
openssl)
|
||||
PKG_CHECK_MODULES([CRYPTO], [openssl],
|
||||
[],
|
||||
[AC_MSG_ERROR([OpenSSL crypto library not found])])
|
||||
AC_DEFINE([USE_OPENSSL_AES], [1], [Use OpenSSL library])
|
||||
;;
|
||||
nettle)
|
||||
PKG_CHECK_MODULES([CRYPTO], [nettle],
|
||||
[],
|
||||
[AC_MSG_ERROR([Nettle crypto library not found])])
|
||||
AC_DEFINE([USE_NETTLE_AES], [1], [Use Nettle library])
|
||||
;;
|
||||
apple-common-crypto)
|
||||
dnl Common Crypto is in Apple's standard paths and base libraries.
|
||||
dnl So just check for presence of the header.
|
||||
AC_CHECK_HEADERS([CommonCrypto/CommonCrypto.h],
|
||||
[],
|
||||
[AC_MSG_ERROR([Apple Common Crypto header not found])])
|
||||
AC_DEFINE([USE_APPLE_COMMON_CRYPTO_AES], [1], [Use Apple Common Crypto library])
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_CHECK_DECL([forkpty],
|
||||
[AC_DEFINE([FORKPTY_IN_LIBUTIL], [1],
|
||||
[Define if libutil.h necessary for forkpty().])],
|
||||
, [[#include <sys/types.h>
|
||||
#include <libutil.h>]])
|
||||
|
||||
AC_CHECK_LIB([util], [forkpty], [
|
||||
AC_DEFINE([HAVE_FORKPTY],, [Define if you have forkpty().])
|
||||
LIBUTIL="-lutil"
|
||||
AC_SUBST([LIBUTIL])
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([whether pipe2(..., O_CLOEXEC) is supported])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define _GNU_SOURCE
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
int pipefd[2];
|
||||
]], [[(void) pipe2(pipefd, O_CLOEXEC);]])],
|
||||
[AC_DEFINE([HAVE_PIPE2_CLOEXEC], [1],
|
||||
[Define if pipe2(..., O_CLOEXEC) is available.])
|
||||
AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
|
||||
AC_MSG_CHECKING([whether FD_ISSET() argument is const])
|
||||
AC_LANG_PUSH(C++)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/select.h>
|
||||
class T {
|
||||
public:
|
||||
fd_set fds;
|
||||
bool Fun( void ) const { return FD_ISSET( 0, &fds ); } };]],
|
||||
[[T x; return x.Fun();]])],
|
||||
[AC_DEFINE([FD_ISSET_IS_CONST], [1],
|
||||
[Define if FD_ISSET() fd_set argument is const.])
|
||||
AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
AC_LANG_POP(C++)
|
||||
|
||||
AC_CHECK_DECLS([__builtin_bswap64, __builtin_ctz])
|
||||
|
||||
AC_MSG_CHECKING([whether clock_gettime() is supported])
|
||||
AS_IF([test x"$build_ios_controller" != xno],
|
||||
[AC_DEFINE([HAVE_CLOCK_GETTIME], [0]) AC_MSG_RESULT([no])],
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <time.h>
|
||||
struct timespec ts;
|
||||
]], [[return clock_gettime(CLOCK_MONOTONIC, &ts);]])],
|
||||
[AC_DEFINE([HAVE_CLOCK_GETTIME], [1],
|
||||
[Define if clock_gettime() is available.])
|
||||
AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
)
|
||||
|
||||
AC_CHECK_DECL([mach_absolute_time],
|
||||
[AC_DEFINE([HAVE_MACH_ABSOLUTE_TIME], [1],
|
||||
[Define if mach_absolute_time is available.])],
|
||||
, [[#include <mach/mach_time.h>]])
|
||||
|
||||
AC_CHECK_DECL([pipe2],
|
||||
[AC_DEFINE([HAVE_PIPE2], [1],
|
||||
[Define if pipe2 is available.])],
|
||||
, [[#define _GNU_SOURCE
|
||||
#include <unistd.h>]])
|
||||
|
||||
AC_CHECK_DECL([signalfd],
|
||||
[AC_DEFINE([HAVE_SIGNALFD], [1],
|
||||
[Define if signalfd is available.])],
|
||||
, [[#include <sys/signalfd.h>]])
|
||||
|
||||
AC_CHECK_DECL([forkpty],
|
||||
[AC_DEFINE([FORKPTY_IN_LIBUTIL], [1],
|
||||
[Define if libutil.h necessary for forkpty().])],
|
||||
, [[#include <libutil.h>]])
|
||||
|
||||
AC_CHECK_DECL([openpty],
|
||||
[AC_DEFINE([OPENPTY_IN_LIBUTIL], [1],
|
||||
[Define if libutil.h necessary for openpty().])],
|
||||
, [[#include <libutil.h>]])
|
||||
|
||||
dnl AC_CHECK_DECL([htobe64],
|
||||
dnl [AC_DEFINE([HAVE_HTOBE64], [1],
|
||||
dnl [Define if htobe64 and friends exist.])],
|
||||
dnl [AC_CHECK_DECL([OSSwapHostToBigInt64],
|
||||
dnl [AC_DEFINE([HAVE_OSX_SWAP], [1],
|
||||
dnl [Define if OSSwapHostToBigInt64 and friends exist.])],
|
||||
dnl [AC_MSG_WARN([Unable to find byte swapping functions; using built-in routines.])],
|
||||
dnl [[#include <libkern/OSByteOrder.h>]])],
|
||||
|
||||
AC_CHECK_DECLS([be64toh, betoh64], [], [],
|
||||
[[#if defined(HAVE_ENDIAN_H)
|
||||
#include <endian.h>
|
||||
#elif defined(HAVE_SYS_ENDIAN_H)
|
||||
#include <sys/types.h>
|
||||
#include <sys/endian.h>
|
||||
#endif]])
|
||||
|
||||
AC_CHECK_DECL([getline],
|
||||
[AC_DEFINE([HAVE_GETLINE], [1],
|
||||
[Define if getline exists.])],
|
||||
, [[#include <stdio.h>]])
|
||||
|
||||
AS_IF([test x"$ac_cv_have_decl_be64toh" != xyes &&
|
||||
test x"$ac_cv_have_decl_betoh64" != xyes],
|
||||
[AC_CHECK_DECL([OSSwapHostToBigInt64],
|
||||
[AC_DEFINE([HAVE_OSX_SWAP], [1],
|
||||
[Define if OSSwapHostToBigInt64 and friends exist.])],
|
||||
[AC_MSG_WARN([Unable to find byte swapping functions; using built-in routines.])],
|
||||
[[#include <libkern/OSByteOrder.h>]])])
|
||||
|
||||
AC_CHECK_DECL([IP_MTU_DISCOVER],
|
||||
[AC_DEFINE([HAVE_IP_MTU_DISCOVER], [1],
|
||||
[Define if IP_MTU_DISCOVER is a valid sockopt.])],
|
||||
, [[#include <netinet/in.h>]])
|
||||
|
||||
AC_CHECK_DECL([IP_RECVTOS],
|
||||
[AC_DEFINE([HAVE_IP_RECVTOS], [1],
|
||||
[Define if IP_RECVTOS is a valid sockopt.])],
|
||||
, [[#include <netinet/in.h>]])
|
||||
|
||||
AC_CHECK_DECL([__STDC_ISO_10646__],
|
||||
[],
|
||||
[AC_MSG_WARN([C library doesn't advertise wchar_t is Unicode (OS X works anyway with workaround).])],
|
||||
[[#include <wchar.h>]])
|
||||
|
||||
AC_CHECK_DECL([IUTF8],
|
||||
[AC_DEFINE([HAVE_IUTF8], [1],
|
||||
[Define if IUTF8 is a defined termios mode.])],
|
||||
[AC_MSG_WARN([No IUTF8 termios mode; character-erase of multibyte character sequence probably does not work properly in canonical mode on this platform.])],
|
||||
[[#include <termios.h>]])
|
||||
|
||||
# Checks for protobuf
|
||||
PKG_CHECK_MODULES([protobuf], [protobuf])
|
||||
|
||||
# Bash completion needs to ask where it goes if >= 2.0 is installed.
|
||||
AS_IF([test "$install_completion" != no],
|
||||
[PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0],
|
||||
[if test "$prefix" = "NONE"; then
|
||||
completions="`pkg-config --variable=completionsdir bash-completion`"
|
||||
else
|
||||
completions="`pkg-config --define-variable=prefix=$prefix --variable=completionsdir bash-completion`"
|
||||
fi],
|
||||
[completions="${sysconfdir}/bash_completion.d"])
|
||||
AC_SUBST([completions])])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
src/Makefile
|
||||
src/crypto/Makefile
|
||||
src/frontend/Makefile
|
||||
src/network/Makefile
|
||||
src/protobufs/Makefile
|
||||
src/statesync/Makefile
|
||||
src/terminal/Makefile
|
||||
src/util/Makefile
|
||||
scripts/Makefile
|
||||
src/examples/Makefile
|
||||
src/tests/Makefile
|
||||
man/Makefile
|
||||
conf/Makefile
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
AC_MSG_NOTICE([ === Configuration results ===])
|
||||
AC_MSG_NOTICE([Version: $PACKAGE_VERSION])
|
||||
AC_MSG_NOTICE([c++ compiler: $CXX])
|
||||
AC_MSG_NOTICE([Warning CXXFLAGS: $WARNING_CXXFLAGS])
|
||||
AC_MSG_NOTICE([Picky CXXFLAGS: $PICKY_CXXFLAGS])
|
||||
AC_MSG_NOTICE([Harden CFLAGS: $HARDEN_CFLAGS])
|
||||
AC_MSG_NOTICE([ =============================])
|
||||
675
vendor/mosh/debian/changelog
vendored
Normal file
675
vendor/mosh/debian/changelog
vendored
Normal file
@@ -0,0 +1,675 @@
|
||||
mosh (1.2.5-1) unstable; urgency=low
|
||||
|
||||
* Version 1.2.5 released.
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sun, 12 Jul 2015 12:42:00 -0400
|
||||
|
||||
mosh (1.2.4.95rc2-1) unstable; urgency=low
|
||||
|
||||
* Version 1.2.5 release candidate.
|
||||
|
||||
* New features:
|
||||
* Bind to a specific IP address with --bind-server. (Philipp
|
||||
Haselwarter)
|
||||
* MOSH_ESCAPE_KEY configures escape character. (Timo
|
||||
J. Rinne)
|
||||
* Support non-roaming IPv6. (Anders Kaseorg)
|
||||
* Implement XTerm mouse mode. (Barosl LEE, Andrew Chin,
|
||||
Louis Kruger)
|
||||
* Report Git revision along with version if available.
|
||||
(John Hood)
|
||||
|
||||
* Platform support:
|
||||
* Add pselect() emulation. (Jérémie Courrèges-Anglas)
|
||||
* OpenBSD, OS X: Fix be64toh-related issues. (Jérémie
|
||||
Courrèges-Anglas)
|
||||
* ARM Neon: fix gcc4.8 compiling problem(Pasi Sjöholm)
|
||||
* NaCl: Conditionally rename main to mosh_main. (Richard
|
||||
Woodbury)
|
||||
* FreeBSD: Token pasting, forkpty(), ARM fixes. (John Hood)
|
||||
* AIX: Implement CTTY grabbing when TIOCSCTTY is missing
|
||||
(Anton Lundin)
|
||||
* OS X: Broaden build support to cover OS X 10.5 through
|
||||
10.10. (John Hood)
|
||||
* Debian: Improve bash-completion install and
|
||||
functionality. (Suggested by Gabriel Filion, John Hood)
|
||||
|
||||
* Bug fixes:
|
||||
* Automake/autoconf workarounds. (Anders Kaseorg)
|
||||
* mosh-server: Allow startup without PTY. (Keith Winstein)
|
||||
* network.cc: Properly close old fd on Socket assignment
|
||||
operator. (Thanks to Igor Bukanov)
|
||||
* mosh-server: Allow startup with zero-window-size PTY.
|
||||
(Igor Bukanov)
|
||||
* AddrInfo: Fix error message generation when node == NULL
|
||||
(Anders Kaseorg)
|
||||
* Timestamp: Prevent integer overflow on Darwin PPC 32-bit
|
||||
(Anders Kaseorg)
|
||||
* scripts/mosh: Fix hang when remote closes the connection
|
||||
(Anders Kaseorg)
|
||||
* Fix issues with parsing of 256-color SGR sequences.
|
||||
(John Hood)
|
||||
* Numerous code hygiene, Coverity, and Clang static analyzer
|
||||
fixes. (Anders Kaseorg, Geoffrey Thomas, John Hood)
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Mon, 08 Jun 2015 22:45:00 -0400
|
||||
|
||||
mosh (1.2.4a-1) unstable; urgency=low
|
||||
|
||||
* Eliminate redundant ocb.cc test (fixes build warning on ARM/MIPS/s390)
|
||||
* Add explicit cast to int (fixes build warning on older gcc)
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 27 Mar 2013 18:32:33 -0400
|
||||
|
||||
mosh (1.2.4-1) unstable; urgency=low
|
||||
|
||||
* Version 1.2.4 released.
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 27 Mar 2013 00:17:39 -0400
|
||||
|
||||
mosh (1.2.3.95rc1-1) unstable; urgency=low
|
||||
|
||||
* Version 1.2.4 release candidate
|
||||
|
||||
* New features:
|
||||
* Support port ranges with -p LOWPORT:HIGHPORT (Luke Mewburn)
|
||||
* Ctrl-^ Ctrl-Z suspends mosh client (Nikolai Zeldovich)
|
||||
* mm:ss display of lost-contact times (Kevin Ballard)
|
||||
* Show infobar with control chars when Ctrl-^ is typed
|
||||
* Put terminal in altscreen mode (Anders Kaseorg)
|
||||
* Tell automake/Debian pkg about our checks (Anders Kaseorg)
|
||||
|
||||
* Platform support:
|
||||
* OS X: Script to build a universal package (Peter Iannucci)
|
||||
* FreeBSD: Fix build problems (Jimmy Olgeni)
|
||||
* AIX: port by Anton Lundin
|
||||
* Solaris with system curses (Anton Lundin)
|
||||
* Cygwin and others: eliminate use of IO::Pty (Anton Lundin)
|
||||
|
||||
* Bug fixes:
|
||||
* Fix bug (introduced in 1.2.3) where server stays around
|
||||
if process quits while client is detached
|
||||
* Clean up spurious entries from detached sessions warning
|
||||
* Fix freeze when connectivity is one-directional for hours
|
||||
(reported by Axel Beckert)
|
||||
* Don't wipe title until a new one is set (sqweek)
|
||||
* Eliminate memory leaks and cppcheck warnings (Anders Kaseorg)
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sun, 10 Mar 2013 17:46:37 -0400
|
||||
|
||||
mosh (1.2.3-1) unstable; urgency=low
|
||||
|
||||
* Version 1.2.3 released.
|
||||
|
||||
* Update AES-OCB implementation (Keegan McAllister)
|
||||
|
||||
* More conservative MTU and datagram sizing
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Fri, 19 Oct 2012 15:21:54 -0400
|
||||
|
||||
mosh (1.2.2.95rc1-1) unstable; urgency=low
|
||||
|
||||
* Security improvements:
|
||||
* Use OpenSSL AES implementation
|
||||
* Don't let bad server dictate IP (Felix Groebert)
|
||||
|
||||
* New features:
|
||||
* Client hops ports to survive challenging client-side firewall
|
||||
* Server stops sending to save client power (Daniel Drown)
|
||||
* Set DiffServ code point and ECN-capable (Dave Täht)
|
||||
* Slow down if explicit congestion notification received
|
||||
* Warn about unattached Mosh sessions on login
|
||||
* Compatible with KDE konsole (uses BEL to terminate OSC)
|
||||
* Improved heuristic about color of predicted characters
|
||||
|
||||
* Bug fixes:
|
||||
* Improved performance on systems with expensive time
|
||||
* No longer choke on "ffff::" address for hosts with IPv6
|
||||
|
||||
* Platform support:
|
||||
* Build on Solaris and IllumOS (Timo Sirainen, Ira Cooper)
|
||||
* Build on ARM with gcc 4.7 (Alexander Chernyakhovsky)
|
||||
|
||||
* Licensing changes:
|
||||
* Allow distribution on Apple App Stores
|
||||
* Allow linking with OpenSSL
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Fri, 05 Oct 2012 19:45:51 -0400
|
||||
|
||||
mosh (1.2.2-1) unstable; urgency=low
|
||||
|
||||
* Version 1.2.2 released.
|
||||
|
||||
* Remove warning on out-of-order/duplicated datagrams
|
||||
|
||||
* Add "experimental" prediction mode
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Tue, 12 Jun 2012 14:52:17 -0400
|
||||
|
||||
mosh (1.2.1-1) unstable; urgency=low
|
||||
|
||||
* Version 1.2.1 released.
|
||||
|
||||
* Warning on out-of-order/duplicated datagrams (or failed nonce increment)
|
||||
|
||||
* Clearer error message on invalid port number
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Fri, 25 May 2012 18:03:31 -0400
|
||||
|
||||
mosh (1.2.0.97-1) unstable; urgency=low
|
||||
|
||||
* Cosmetic cleanups to quit sequence when server is firewalled
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 23 May 2012 12:16:47 -0400
|
||||
|
||||
mosh (1.2.0.96-1) unstable; urgency=low
|
||||
|
||||
* Include bash_completion file (ejeffrey)
|
||||
|
||||
* Include UFW firewall profile (Fumihito YOSHIDA)
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 23 May 2012 07:05:54 -0400
|
||||
|
||||
mosh (1.2.0.95-1) unstable; urgency=low
|
||||
|
||||
* Improve performance on lossy links.
|
||||
|
||||
* New diagnostic message when link is dead in only one direction.
|
||||
|
||||
* Use less CPU when link is down. (Keegan McAllister)
|
||||
|
||||
* Use much less CPU when application or mosh-server sends
|
||||
large repeat counts (resolves CVE-2012-2385, reported by
|
||||
Timo Juhani Lindfors).
|
||||
|
||||
* Use less memory when mosh-server is malicious.
|
||||
|
||||
* Fix vttest regression re: wrapping and tabs.
|
||||
|
||||
* Enable roundtrip verifier of terminal emulator correctness
|
||||
when verbose.
|
||||
|
||||
* Remove skalibs as a dependency. (Keegan McAllister)
|
||||
|
||||
* Remove use of poll() and OS X poll workaround. (Keegan McAllister)
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 23 May 2012 03:36:13 -0400
|
||||
|
||||
mosh (1.2-1) unstable; urgency=low
|
||||
|
||||
* Version 1.2 released.
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Thu, 26 Apr 2012 01:35:59 -0400
|
||||
|
||||
mosh (1.1.99b-1) unstable; urgency=low
|
||||
|
||||
* Update THANKS and copyright information
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 25 Apr 2012 02:53:21 -0400
|
||||
|
||||
mosh (1.1.99a-1) unstable; urgency=low
|
||||
|
||||
* Fix using broken system poll on OS X 10.6
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 25 Apr 2012 02:30:44 -0400
|
||||
|
||||
mosh (1.1.99-1) unstable; urgency=low
|
||||
|
||||
* Fix build problems on FreeBSD 7 and 8
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Tue, 24 Apr 2012 23:52:22 -0400
|
||||
|
||||
mosh (1.1.98-1) unstable; urgency=low
|
||||
|
||||
* Fix build problems on Cygwin
|
||||
|
||||
* Fix build problems on Debian armel/armhf
|
||||
|
||||
* Fix alignment problems on ARM
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Tue, 24 Apr 2012 19:00:03 -0400
|
||||
|
||||
mosh (1.1.97-1) unstable; urgency=low
|
||||
|
||||
* Revert use of protobufs' zero-copy gzip stream
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Mon, 23 Apr 2012 22:53:44 -0400
|
||||
|
||||
mosh (1.1.96-1) unstable; urgency=low
|
||||
|
||||
* Include binary hardening check script in GNU-style tar.gz
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Mon, 23 Apr 2012 20:21:14 -0400
|
||||
|
||||
mosh (1.1.95-1) unstable; urgency=low
|
||||
|
||||
* Eliminate PPC32 dependence on posix_memalign()
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sun, 22 Apr 2012 23:18:13 -0400
|
||||
|
||||
mosh (1.1.94e-1) unstable; urgency=low
|
||||
|
||||
* Improve responsiveness on fast links
|
||||
|
||||
* Include poll implementation for Mac OS X
|
||||
|
||||
* Use protobufs' zero-copy gzip stream
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sun, 22 Apr 2012 16:59:25 -0400
|
||||
|
||||
mosh (1.1.94d-1) unstable; urgency=low
|
||||
|
||||
* More helpful locale-related error messages
|
||||
|
||||
* Improve prediction transparency
|
||||
|
||||
* Honor .hushlogin
|
||||
|
||||
* Set PWD to deal with home directories that are symlinks
|
||||
|
||||
* Back off overlay frame rate when all timing tests have fired (saves CPU)
|
||||
|
||||
* -v flag now makes server more verbose
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Thu, 19 Apr 2012 02:44:48 -0400
|
||||
|
||||
mosh (1.1.94c-1) unstable; urgency=low
|
||||
|
||||
* Further improved Debian rule to disable conflicting stack protector flags
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Tue, 17 Apr 2012 04:17:08 -0400
|
||||
|
||||
mosh (1.1.94b-1) unstable; urgency=low
|
||||
|
||||
* Improved Debian rule to disable conflicting stack protector flags
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Tue, 17 Apr 2012 03:24:23 -0400
|
||||
|
||||
mosh (1.1.94a-1) unstable; urgency=low
|
||||
|
||||
* Bump base version
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Tue, 17 Apr 2012 02:36:30 -0400
|
||||
|
||||
mosh (1.1.94-2) unstable; urgency=low
|
||||
|
||||
* Disable conflicting Debian/Ubuntu stack protector flags
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Tue, 17 Apr 2012 02:15:41 -0400
|
||||
|
||||
mosh (1.1.94-1) unstable; urgency=low
|
||||
|
||||
* Release pre-candidate for mosh 1.2
|
||||
|
||||
* Remove Boost as a dependency (Keegan McAllister)
|
||||
|
||||
* More friendly error messages in some common cases
|
||||
|
||||
* Now passes locale-related env vars over the connection
|
||||
|
||||
* Remove skalibs as a depenency on Debian/Ubuntu (Keegan McAllister)
|
||||
|
||||
* Fix startup script to no longer hang on some Macs (Jay Freeman)
|
||||
|
||||
* Fix argument parsing on FreeBSD (Daniel O'Connor)
|
||||
|
||||
* Use binary hardening flags where available (Keegan McAllister)
|
||||
|
||||
* Several improvements to terminal emulation correctness
|
||||
|
||||
* Now prints message of the day (motd)
|
||||
|
||||
* Allows core dumps of subsidiary applications if desired
|
||||
|
||||
* Cleaner execution of subsidiary shell (Jay Freeman)
|
||||
|
||||
* Fix leaking utmp entries (Ed Schouten)
|
||||
|
||||
* Add support for Cygwin (Joshua Pollack)
|
||||
|
||||
* Add support for RHEL/CentOS 5 (Reini Urban)
|
||||
|
||||
* Use less CPU when server's network is down
|
||||
|
||||
* Disable posterization of 256colors to 8 ANSI colors
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Mon, 16 Apr 2012 21:16:28 -0400
|
||||
|
||||
mosh (1.1.3a-1) unstable; urgency=low
|
||||
|
||||
* Support 16-color escape sequences (Anders Kaseorg)
|
||||
|
||||
* Fix some wraparound glitches
|
||||
|
||||
* Fix escape sequences when server run on BSD and OS X (Peter Jeremy)
|
||||
|
||||
* FreeBSD support (Ben Kaduk)
|
||||
|
||||
* Fixes to build on iOS (Peter Iannucci)
|
||||
|
||||
* Add some tests (Keegan McAllister)
|
||||
|
||||
* Support OS X iTerm with lowercase "utf-8"
|
||||
|
||||
* Avoid unnecessary link with -lncurses when possible (Anders Kaseorg)
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 11 Apr 2012 03:36:49 -0400
|
||||
|
||||
mosh (1.1.3-1) unstable; urgency=low
|
||||
|
||||
* Version 1.1.3 released.
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Tue, 03 Apr 2012 12:33:46 -0400
|
||||
|
||||
mosh (1.1.2c-1) unstable; urgency=low
|
||||
|
||||
* Fix bug causing occasional missing (or spurious) wraparound copy-and-paste
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Mon, 02 Apr 2012 19:08:19 -0400
|
||||
|
||||
mosh (1.1.2b-1) unstable; urgency=low
|
||||
|
||||
* Close connection after four petabytes (per OCB recommendation)
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sat, 31 Mar 2012 17:25:10 -0400
|
||||
|
||||
mosh (1.1.2a-1) unstable; urgency=low
|
||||
|
||||
* Fixes to build on armel and armhf (Keegan McAllister)
|
||||
|
||||
* Fix to build on FreeBSD, with warning about broken tty multibyte delete (reported by Christoph Egger)
|
||||
|
||||
* Keep sane values in unused wx_xpixel/wx_ypixel values of struct winsize.
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sat, 31 Mar 2012 15:51:31 -0400
|
||||
|
||||
mosh (1.1.2-1) unstable; urgency=low
|
||||
|
||||
* Version 1.1.2 released.
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 28 Mar 2012 18:02:28 +0200
|
||||
|
||||
mosh (1.1.1a-1) unstable; urgency=low
|
||||
|
||||
* Fixes to build on OS X 10.5 with older gcc and -lpoll (Quentin Smith)
|
||||
|
||||
* Add --with-utempter and --without-utempter per gentoo req (Michael Weber)
|
||||
|
||||
* configure now requires ncurses headers (and others) to be installed
|
||||
|
||||
* Consolidate locale routines to help Android port (Keegan McAllister)
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 28 Mar 2012 15:16:51 +0200
|
||||
|
||||
mosh (1.1.1-1) unstable; urgency=low
|
||||
|
||||
* Version 1.1.1 released.
|
||||
|
||||
* Fix spec file and build failure on Fedora.
|
||||
|
||||
* Print out error message properly on fatal_assert().
|
||||
|
||||
* Support for machines without posix_memalign().
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Tue, 27 Mar 2012 01:18:26 +0200
|
||||
|
||||
mosh (1.1-1) unstable; urgency=low
|
||||
|
||||
* Version 1.1 released
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Thu, 22 Mar 2012 18:40:59 -0400
|
||||
|
||||
mosh (1.0.9d-1) unstable; urgency=low
|
||||
|
||||
* Fix bug preventing -p argument from working
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 21 Mar 2012 22:46:51 -0400
|
||||
|
||||
mosh (1.0.9c-1) unstable; urgency=low
|
||||
|
||||
* Improved building on Mac OS X (Anders Kaseorg)
|
||||
|
||||
* PRNG (for chaff) now reads from /dev/urandom (Keegan McAllister)
|
||||
|
||||
* Startup script cleanups and fix shell quoting (Anders Kaseorg)
|
||||
|
||||
* Disables core dumps (containing session key) (Keegan McAllister)
|
||||
|
||||
* Improved terminal shutdown and other cosmetic fixes
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 21 Mar 2012 19:23:41 -0400
|
||||
|
||||
mosh (1.0.9b-1) unstable; urgency=low
|
||||
|
||||
* More efficient repaint when scrolling top part of window
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sun, 18 Mar 2012 16:37:30 -0400
|
||||
|
||||
mosh (1.0.9a-1) unstable; urgency=low
|
||||
|
||||
* Add chaff to datagrams to frustrate statistical analysis of length
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sun, 18 Mar 2012 14:00:11 -0400
|
||||
|
||||
mosh (1.0.9-1) unstable; urgency=low
|
||||
|
||||
* Release candidate for version 1.1.
|
||||
|
||||
* Allows user to specify remote command to execute.
|
||||
|
||||
* Only advertises 256 colors when user's terminal has 256 colors.
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sun, 18 Mar 2012 06:06:43 -0400
|
||||
|
||||
mosh (1.0.2-1) unstable; urgency=low
|
||||
|
||||
* Version 1.02 released.
|
||||
|
||||
* Uses xterm-256color and supports 256-color escape sequences.
|
||||
|
||||
* Posterizes to 8 colors unless the user has a 256-color terminal.
|
||||
|
||||
* Handles terminals without BCE.
|
||||
|
||||
* Starts login shell.
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Fri, 16 Mar 2012 17:57:45 -0400
|
||||
|
||||
mosh (1.0.1-1) unstable; urgency=low
|
||||
|
||||
* Version 1.01 released.
|
||||
|
||||
* Roughly 40% less CPU usage.
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 14 Mar 2012 04:55:11 -0400
|
||||
|
||||
mosh (1.0-1) unstable; urgency=low
|
||||
|
||||
* Version 1.0 released.
|
||||
|
||||
* mosh now supports --version option and prints no-warranty message.
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Mon, 12 Mar 2012 04:51:43 -0400
|
||||
|
||||
mosh (0.98c-1) unstable; urgency=low
|
||||
|
||||
* Fix pointer comparison (Anders Kaseorg)
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sat, 10 Mar 2012 16:50:35 -0500
|
||||
|
||||
mosh (0.98b-1) unstable; urgency=low
|
||||
|
||||
* Update README.md
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sat, 10 Mar 2012 14:05:12 -0500
|
||||
|
||||
mosh (0.98a-1) unstable; urgency=low
|
||||
|
||||
* Small cleanup to generated terminal output when predictions active
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sat, 10 Mar 2012 06:40:24 -0500
|
||||
|
||||
mosh (0.98-1) unstable; urgency=low
|
||||
|
||||
* Version 0.98 released.
|
||||
|
||||
* Add option to select server-side UDP port.
|
||||
|
||||
* Restrict default UDP port range to 60000..61000.
|
||||
|
||||
* Use TERM / terminfo to decide when to send ECH sequence.
|
||||
|
||||
* Now works properly inside tmux.
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sat, 10 Mar 2012 05:45:34 -0500
|
||||
|
||||
mosh (0.97-1) unstable; urgency=low
|
||||
|
||||
* Merged Mac OS X port (thanks to Quentin Smith and Anders Kaseorg)
|
||||
|
||||
* Server will quit if no connection within first 60 seconds
|
||||
|
||||
* Startup script no longer requires threaded Perl
|
||||
|
||||
* Add --enable-compile-warnings=error to ./configure
|
||||
|
||||
* Fix some flicker issues with adaptive prediction mode
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 07 Mar 2012 04:17:19 -0500
|
||||
|
||||
mosh (0.96a-3) unstable; urgency=low
|
||||
|
||||
* Update copyright file to correct pkg.m4 is GPL-2+ not GPL-2
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sat, 03 Mar 2012 19:06:43 -0500
|
||||
|
||||
mosh (0.96a-2) unstable; urgency=low
|
||||
|
||||
* Update copyright file to include public domain files and other licenses
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sat, 03 Mar 2012 14:05:15 -0500
|
||||
|
||||
mosh (0.96a-1) unstable; urgency=low
|
||||
|
||||
* Version 0.96a released.
|
||||
|
||||
* Fix build problem on i386
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sun, 26 Feb 2012 13:49:44 -0500
|
||||
|
||||
mosh (0.96-1) unstable; urgency=low
|
||||
|
||||
* Version 0.96 released.
|
||||
|
||||
* Compress all instructions with zlib
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sun, 26 Feb 2012 04:40:46 -0500
|
||||
|
||||
mosh (0.95-1) unstable; urgency=low
|
||||
|
||||
* Version 0.95 released.
|
||||
|
||||
* Make echo acknowledgment reliable to reduce spurious mispredict detections.
|
||||
|
||||
* Require two dropped heartbeats before showing blue bar of lost contact
|
||||
|
||||
* Print newline before MOSH CONNECT string to make more robust
|
||||
|
||||
* Disable ControlMaster in initial SSH connection so proxy is always used
|
||||
|
||||
* Make retransmissions occur at frame rate for limited time after loss
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sat, 25 Feb 2012 15:15:59 -0500
|
||||
|
||||
mosh (0.94c-1) unstable; urgency=low
|
||||
|
||||
* Move to protobuf (from protobuf-lite) to make build on Ubuntu 10.04
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Mon, 20 Feb 2012 00:39:12 -0500
|
||||
|
||||
mosh (0.94b-1) unstable; urgency=low
|
||||
|
||||
* Relax autoconf dependency
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sun, 19 Feb 2012 22:55:53 -0500
|
||||
|
||||
mosh (0.94a-1) unstable; urgency=low
|
||||
|
||||
* Relax debhelper dependency to make build on Ubuntu 10.04 LTS lucid
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sun, 19 Feb 2012 22:03:03 -0500
|
||||
|
||||
mosh (0.94-1) unstable; urgency=low
|
||||
|
||||
* Version 0.94 released.
|
||||
|
||||
* Make man pages.
|
||||
|
||||
* Replace C++11 features (lambda and auto) with boost equivalents
|
||||
(Anders Kaseorg)
|
||||
|
||||
* Now builds with g++ or clang (with libstdc++)
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Wed, 15 Feb 2012 13:56:11 -0500
|
||||
|
||||
mosh (0.93-1) unstable; urgency=low
|
||||
|
||||
* Version 0.93 released.
|
||||
|
||||
* Make utmp entries.
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Mon, 13 Feb 2012 05:44:35 -0500
|
||||
|
||||
mosh (0.92-1) unstable; urgency=low
|
||||
|
||||
* Version 0.92 released.
|
||||
|
||||
* Allows user to select prediction mode (always/never/adaptive)
|
||||
|
||||
* Fix bug in server startup on slow hosts
|
||||
|
||||
* Better prediction when deleting at line ending
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Mon, 13 Feb 2012 03:53:31 -0500
|
||||
|
||||
mosh (0.91a-0ubuntu1) oneiric; urgency=low
|
||||
|
||||
* Add missing dependencies to debian/control
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Thu, 09 Feb 2012 09:34:18 -0500
|
||||
|
||||
mosh (0.91-0ubuntu1) oneiric; urgency=low
|
||||
|
||||
* Version 0.91 released.
|
||||
|
||||
* Startup script support SSH options and aliases (Anders Kaseorg)
|
||||
|
||||
* End use of Path MTU discovery and allow IP fragmentation because,
|
||||
e.g., Cisco VPN has MTU of 1200 and does not pass ICMP too-big.
|
||||
|
||||
* Better exception and error handling.
|
||||
|
||||
* Restrict predictive local echo display to long-delay links
|
||||
(>60 ms RTT) or for temporarily after a "glitch." Otherwise simply
|
||||
show server echos, while maintaining prediction overlay in the
|
||||
background in case it is needed.
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Thu, 09 Feb 2012 03:05:45 -0500
|
||||
|
||||
mosh (0.9b-0ubuntu1) oneiric; urgency=low
|
||||
|
||||
* Merged Anders Kaseorg fixes to build system
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Tue, 07 Feb 2012 17:27:42 -0500
|
||||
|
||||
mosh (0.9a-0ubuntu1) oneiric; urgency=low
|
||||
|
||||
* Edit README
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sun, 05 Feb 2012 03:50:53 -0500
|
||||
|
||||
mosh (0.9-0ubuntu1) oneiric; urgency=low
|
||||
|
||||
* Initial release
|
||||
|
||||
-- Keith Winstein <keithw@mit.edu> Sun, 05 Feb 2012 03:50:53 -0500
|
||||
1
vendor/mosh/debian/compat
vendored
Normal file
1
vendor/mosh/debian/compat
vendored
Normal file
@@ -0,0 +1 @@
|
||||
7
|
||||
21
vendor/mosh/debian/control
vendored
Normal file
21
vendor/mosh/debian/control
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
Source: mosh
|
||||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: Keith Winstein <keithw@mit.edu>
|
||||
Build-Depends: debhelper (>= 7.0.50), autotools-dev, protobuf-compiler, libprotobuf-dev, dh-autoreconf, pkg-config, libutempter-dev, zlib1g-dev, libncurses5-dev, libssl-dev, bash-completion
|
||||
Standards-Version: 3.9.6.1
|
||||
Homepage: http://mosh.mit.edu
|
||||
Vcs-Git: git://github.com/keithw/mosh.git
|
||||
Vcs-Browser: https://github.com/keithw/mosh
|
||||
|
||||
Package: mosh
|
||||
Architecture: any
|
||||
Pre-Depends: dpkg (>= 1.15.7.2)
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, openssh-client
|
||||
Recommends: libio-socket-ip-perl
|
||||
Description: Mobile shell that supports roaming and intelligent local echo
|
||||
Mosh is a remote terminal application that supports:
|
||||
- intermittent network connectivity,
|
||||
- roaming to different IP address without dropping the connection, and
|
||||
- intelligent local echo and line editing to reduce the effects
|
||||
of "network lag" on high-latency connections.
|
||||
149
vendor/mosh/debian/copyright
vendored
Normal file
149
vendor/mosh/debian/copyright
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: mosh
|
||||
Source: http://github.com/keithw/mosh
|
||||
|
||||
Files: *
|
||||
Copyright: 2012 Keith Winstein <mosh-devel@mit.edu>
|
||||
License: GPL-3+ with OpenSSL exception
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
.
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
|
||||
Files: m4/pkg.m4
|
||||
Copyright: 2004 Scott James Remnant <scott@netsplit.com>
|
||||
License: GPL-2+
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
As a special exception to the GNU General Public License, if you
|
||||
distribute this file as part of a program that contains a
|
||||
configuration script generated by Autoconf, you may include it under
|
||||
the same distribution terms that you use for the rest of that program.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2"
|
||||
|
||||
Files: m4/ax_check_library.m4
|
||||
Copyright: 2010 Diego Elio Petteno` <flameeyes@gmail.com>
|
||||
License: GPL-3+
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
As a special exception, the respective Autoconf Macro's copyright owner
|
||||
gives unlimited permission to copy, distribute and modify the configure
|
||||
scripts that are the output of Autoconf when processing the Macro. You
|
||||
need not follow the terms of the GNU General Public License when using
|
||||
or distributing such scripts, even though portions of the text of the
|
||||
Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
all other use of the material that constitutes the Autoconf Macro.
|
||||
.
|
||||
This special exception to the GPL applies to versions of the Autoconf
|
||||
Macro released by the Autoconf Archive. When you make and distribute a
|
||||
modified version of the Autoconf Macro, you may extend this special
|
||||
exception to the GPL to apply to your modified version as well.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
|
||||
Files: m4/ax_check_compile_flag.m4 m4/ax_check_link_flag.m4
|
||||
Copyright: 2008 Guido U. Draheim <guidod@gmx.de>
|
||||
2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||
License: GPL-3+
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
As a special exception, the respective Autoconf Macro's copyright owner
|
||||
gives unlimited permission to copy, distribute and modify the configure
|
||||
scripts that are the output of Autoconf when processing the Macro. You
|
||||
need not follow the terms of the GNU General Public License when using
|
||||
or distributing such scripts, even though portions of the text of the
|
||||
Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
all other use of the material that constitutes the Autoconf Macro.
|
||||
.
|
||||
This special exception to the GPL applies to versions of the Autoconf
|
||||
Macro released by the Autoconf Archive. When you make and distribute a
|
||||
modified version of the Autoconf Macro, you may extend this special
|
||||
exception to the GPL to apply to your modified version as well.
|
||||
|
||||
Files: src/crypto/ocb.cc
|
||||
Copyright: 2011 Ted Krovetz
|
||||
License: ISC
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.
|
||||
Phillip Rogaway holds patents relevant to OCB. See the following for
|
||||
his patent grant: http://www.cs.ucdavis.edu/~rogaway/ocb/grant.htm
|
||||
(also found in ocb-license.html in the Mosh source distribution).
|
||||
|
||||
Files: src/crypto/ae.h
|
||||
Copyright: none
|
||||
License: public-domain
|
||||
This file is in the public domain. It is provided "as is", without
|
||||
warranty of any kind. Use at your own risk.
|
||||
.
|
||||
Comments are welcome: Ted Krovetz <ted@krovetz>.
|
||||
1
vendor/mosh/debian/docs
vendored
Normal file
1
vendor/mosh/debian/docs
vendored
Normal file
@@ -0,0 +1 @@
|
||||
README.md
|
||||
1
vendor/mosh/debian/mosh.maintscript
vendored
Normal file
1
vendor/mosh/debian/mosh.maintscript
vendored
Normal file
@@ -0,0 +1 @@
|
||||
rm_conffile /etc/bash_completion.d/mosh 1.2.5~ -- "$@"
|
||||
25
vendor/mosh/debian/rules
vendored
Executable file
25
vendor/mosh/debian/rules
vendored
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Sample debian/rules that uses debhelper.
|
||||
# This file was originally written by Joey Hess and Craig Small.
|
||||
# As a special exception, when this file is copied by dh-make into a
|
||||
# dh-make output file, you may use that output file without restriction.
|
||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
# Through Autoconf we set hardening flags that are actually more aggressive
|
||||
# than the Ubuntu defaults, but they conflict with same.
|
||||
export DEB_BUILD_MAINT_OPTIONS = hardening=-stackprotector
|
||||
-include /usr/share/dpkg/buildflags.mk
|
||||
|
||||
%:
|
||||
dh $@ --with autoreconf
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure -- \
|
||||
--disable-silent-rules \
|
||||
--enable-ufw \
|
||||
--enable-completion \
|
||||
--enable-compile-warnings=error
|
||||
1
vendor/mosh/debian/source/format
vendored
Normal file
1
vendor/mosh/debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
||||
2
vendor/mosh/debian/watch
vendored
Normal file
2
vendor/mosh/debian/watch
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
version=3
|
||||
https://github.com/keithw/mosh/tags .*/mosh-(\d[\d\.]+)\.tar\.gz
|
||||
92
vendor/mosh/fedora/mosh.spec
vendored
Normal file
92
vendor/mosh/fedora/mosh.spec
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
Name: mosh
|
||||
Version: 1.2.5
|
||||
Release: 1%{?dist}
|
||||
Summary: Mobile shell that supports roaming and intelligent local echo
|
||||
|
||||
License: GPLv3+
|
||||
Group: Applications/Internet
|
||||
URL: http://mosh.mit.edu/
|
||||
Source0: https://github.com/downloads/keithw/mosh/mosh-%{version}.tar.gz
|
||||
|
||||
BuildRequires: protobuf-compiler
|
||||
BuildRequires: protobuf-devel
|
||||
BuildRequires: libutempter-devel
|
||||
BuildRequires: zlib-devel
|
||||
BuildRequires: ncurses-devel
|
||||
BuildRequires: openssl-devel
|
||||
Requires: openssh-clients
|
||||
Requires: openssl
|
||||
Requires: perl-IO-Socket-IP
|
||||
|
||||
%description
|
||||
Mosh is a remote terminal application that supports:
|
||||
- intermittent network connectivity,
|
||||
- roaming to different IP address without dropping the connection, and
|
||||
- intelligent local echo and line editing to reduce the effects
|
||||
of "network lag" on high-latency connections.
|
||||
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
|
||||
%build
|
||||
# Use upstream's more aggressive hardening instead of Fedora's defaults
|
||||
export CFLAGS="-g -O2" CXXFLAGS="-g -O2"
|
||||
%configure --enable-compile-warnings=error
|
||||
make %{?_smp_mflags}
|
||||
|
||||
|
||||
%install
|
||||
make install DESTDIR=$RPM_BUILD_ROOT
|
||||
|
||||
|
||||
%files
|
||||
%doc README.md COPYING ChangeLog
|
||||
%{_bindir}/mosh
|
||||
%{_bindir}/mosh-client
|
||||
%{_bindir}/mosh-server
|
||||
%{_mandir}/man1/mosh.1.gz
|
||||
%{_mandir}/man1/mosh-client.1.gz
|
||||
%{_mandir}/man1/mosh-server.1.gz
|
||||
|
||||
|
||||
%changelog
|
||||
* Sun Jul 12 2015 John Hood <cgull@glup.org> - 1.2.5-1
|
||||
- Update to mosh 1.2.5
|
||||
|
||||
* Fri Jun 26 2015 John Hood <cgull@glup.org> - 1.2.4.95rc2-1
|
||||
- Update to mosh 1.2.4.95rc2
|
||||
|
||||
* Mon Jun 08 2015 John Hood <cgull@glup.org> - 1.2.4.95rc1-1
|
||||
- Update to mosh 1.2.4.95rc1
|
||||
|
||||
* Wed Mar 27 2013 Alexander Chernyakhovsky <achernya@mit.edu> - 1.2.4-1
|
||||
- Update to mosh 1.2.4
|
||||
|
||||
* Sun Mar 10 2013 Alexander Chernyakhovsky <achernya@mit.edu> - 1.2.3-3
|
||||
- Rebuilt for Protobuf API change from 2.4.1 to 2.5.0
|
||||
|
||||
* Thu Feb 14 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.2.3-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
|
||||
|
||||
* Fri Oct 19 2012 Alexander Chernyakhovsky <achernya@mit.edu> - 1.2.3-1
|
||||
- Update to mosh 1.2.3
|
||||
|
||||
* Fri Jul 20 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.2.2-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
|
||||
|
||||
* Wed Jun 13 2012 Alexander Chernyakhovsky <achernya@mit.edu> - 1.2.2-1
|
||||
- Update to mosh 1.2.2
|
||||
|
||||
* Sat Apr 28 2012 Alexander Chernyakhovsky <achernya@mit.edu> - 1.2-2
|
||||
- Add -g and -O2 CFLAGS
|
||||
|
||||
* Fri Apr 27 2012 Alexander Chernyakhovsky <achernya@mit.edu> - 1.2-1
|
||||
- Update to mosh 1.2.
|
||||
|
||||
* Mon Mar 26 2012 Alexander Chernyakhovsky <achernya@mit.edu> - 1.1.1-1
|
||||
- Update to mosh 1.1.1.
|
||||
|
||||
* Wed Mar 21 2012 Alexander Chernyakhovsky <achernya@mit.edu> - 1.1-1
|
||||
- Initial packaging for mosh.
|
||||
72
vendor/mosh/m4/ax_check_compile_flag.m4
vendored
Normal file
72
vendor/mosh/m4/ax_check_compile_flag.m4
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check whether the given FLAG works with the current language's compiler
|
||||
# or gives an error. (Warnings, however, are ignored)
|
||||
#
|
||||
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
|
||||
# success/failure.
|
||||
#
|
||||
# If EXTRA-FLAGS is defined, it is added to the current language's default
|
||||
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
|
||||
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
|
||||
# force the compiler to issue an error when a bad flag is given.
|
||||
#
|
||||
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
|
||||
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 2
|
||||
|
||||
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
|
||||
[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
|
||||
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
|
||||
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
|
||||
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
|
||||
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
|
||||
[AS_VAR_SET(CACHEVAR,[yes])],
|
||||
[AS_VAR_SET(CACHEVAR,[no])])
|
||||
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
|
||||
AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
|
||||
[m4_default([$2], :)],
|
||||
[m4_default([$3], :)])
|
||||
AS_VAR_POPDEF([CACHEVAR])dnl
|
||||
])dnl AX_CHECK_COMPILE_FLAGS
|
||||
95
vendor/mosh/m4/ax_check_library.m4
vendored
Normal file
95
vendor/mosh/m4/ax_check_library.m4
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_check_library.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CHECK_LIBRARY(VARIABLE-PREFIX, HEADER-FILE, LIBRARY-FILE,
|
||||
# [ACTION-IF-FOUND], [ACTION-IF-NOT_FOUND])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Provides a generic test for a given library, similar in concept to the
|
||||
# PKG_CHECK_MODULES macro used by pkg-config.
|
||||
#
|
||||
# Most simplest libraries can be checked against simply through the
|
||||
# presence of a header file and a library to link to. This macro allows to
|
||||
# wrap around the test so that it doesn't have to be recreated each time.
|
||||
#
|
||||
# Rather than define --with-$LIBRARY arguments, it uses variables in the
|
||||
# same way that PKG_CHECK_MODULES does. It doesn't, though, use the same
|
||||
# names, since you shouldn't provide a value for LIBS or CFLAGS but rather
|
||||
# for LDFLAGS and CPPFLAGS, to tell the linker and compiler where to find
|
||||
# libraries and headers respectively.
|
||||
#
|
||||
# If the library is find, HAVE_PREFIX is defined, and in all cases
|
||||
# PREFIX_LDFLAGS and PREFIX_CPPFLAGS are substituted.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# AX_CHECK_LIBRARY([LIBEVENT], [event.h], [event], [],
|
||||
# [AC_MSG_ERROR([Unable to find libevent])])
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2010 Diego Elio Petteno` <flameeyes@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 4
|
||||
|
||||
AC_DEFUN([AX_CHECK_LIBRARY], [
|
||||
AC_ARG_VAR($1[_CPPFLAGS], [C preprocessor flags for ]$1[ headers])
|
||||
AC_ARG_VAR($1[_LDFLAGS], [linker flags for ]$1[ libraries])
|
||||
|
||||
AC_CACHE_VAL(AS_TR_SH([ax_cv_have_]$1),
|
||||
[save_CPPFLAGS="$CPPFLAGS"
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
save_LIBS="$LIBS"
|
||||
|
||||
AS_IF([test "x$]$1[_CPPFLAGS" != "x"],
|
||||
[CPPFLAGS="$CPPFLAGS $]$1[_CPPFLAGS"])
|
||||
|
||||
AS_IF([test "x$]$1[_LDFLAGS" != "x"],
|
||||
[LDFLAGS="$LDFLAGS $]$1[_LDFLAGS"])
|
||||
|
||||
AC_CHECK_HEADER($2, [
|
||||
AC_CHECK_LIB($3, [main],
|
||||
[AS_TR_SH([ax_cv_have_]$1)=yes],
|
||||
[AS_TR_SH([ax_cv_have_]$1)=no])
|
||||
], [AS_TR_SH([ax_cv_have_]$1)=no])
|
||||
|
||||
CPPFLAGS="$save_CPPFLAGS"
|
||||
LDFLAGS="$save_LDFLAGS"
|
||||
LIBS="$save_LIBS"
|
||||
])
|
||||
|
||||
AS_IF([test "$]AS_TR_SH([ax_cv_have_]$1)[" = "yes"],
|
||||
AC_DEFINE([HAVE_]$1, [1], [Define to 1 if ]$1[ is found])
|
||||
[$4],
|
||||
[$5])
|
||||
])
|
||||
71
vendor/mosh/m4/ax_check_link_flag.m4
vendored
Normal file
71
vendor/mosh/m4/ax_check_link_flag.m4
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check whether the given FLAG works with the linker or gives an error.
|
||||
# (Warnings, however, are ignored)
|
||||
#
|
||||
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
|
||||
# success/failure.
|
||||
#
|
||||
# If EXTRA-FLAGS is defined, it is added to the linker's default flags
|
||||
# when the check is done. The check is thus made with the flags: "LDFLAGS
|
||||
# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
|
||||
# issue an error when a bad flag is given.
|
||||
#
|
||||
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
|
||||
# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 2
|
||||
|
||||
AC_DEFUN([AX_CHECK_LINK_FLAG],
|
||||
[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
|
||||
AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
|
||||
ax_check_save_flags=$LDFLAGS
|
||||
LDFLAGS="$LDFLAGS $4 $1"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM()],
|
||||
[AS_VAR_SET(CACHEVAR,[yes])],
|
||||
[AS_VAR_SET(CACHEVAR,[no])])
|
||||
LDFLAGS=$ax_check_save_flags])
|
||||
AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
|
||||
[m4_default([$2], :)],
|
||||
[m4_default([$3], :)])
|
||||
AS_VAR_POPDEF([CACHEVAR])dnl
|
||||
])dnl AX_CHECK_LINK_FLAGS
|
||||
518
vendor/mosh/m4/ax_with_curses.m4
vendored
Normal file
518
vendor/mosh/m4/ax_with_curses.m4
vendored
Normal file
@@ -0,0 +1,518 @@
|
||||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_with_curses.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_WITH_CURSES
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro checks whether a SysV or X/Open-compatible Curses library is
|
||||
# present, along with the associated header file. The NcursesW
|
||||
# (wide-character) library is searched for first, followed by Ncurses,
|
||||
# then the system-default plain Curses. The first library found is the
|
||||
# one returned.
|
||||
#
|
||||
# The following options are understood: --with-ncursesw, --with-ncurses,
|
||||
# --without-ncursesw, --without-ncurses. The "--with" options force the
|
||||
# macro to use that particular library, terminating with an error if not
|
||||
# found. The "--without" options simply skip the check for that library.
|
||||
# The effect on the search pattern is:
|
||||
#
|
||||
# (no options) - NcursesW, Ncurses, Curses
|
||||
# --with-ncurses --with-ncursesw - NcursesW only [*]
|
||||
# --without-ncurses --with-ncursesw - NcursesW only [*]
|
||||
# --with-ncursesw - NcursesW only [*]
|
||||
# --with-ncurses --without-ncursesw - Ncurses only [*]
|
||||
# --with-ncurses - NcursesW, Ncurses [**]
|
||||
# --without-ncurses --without-ncursesw - Curses only
|
||||
# --without-ncursesw - Ncurses, Curses
|
||||
# --without-ncurses - NcursesW, Curses
|
||||
#
|
||||
# [*] If the library is not found, abort the configure script.
|
||||
#
|
||||
# [**] If the second library (Ncurses) is not found, abort configure.
|
||||
#
|
||||
# The following preprocessor symbols may be defined by this macro if the
|
||||
# appropriate conditions are met:
|
||||
#
|
||||
# HAVE_CURSES - if any SysV or X/Open Curses library found
|
||||
# HAVE_CURSES_ENHANCED - if library supports X/Open Enhanced functions
|
||||
# HAVE_CURSES_COLOR - if library supports color (enhanced functions)
|
||||
# HAVE_CURSES_OBSOLETE - if library supports certain obsolete features
|
||||
# HAVE_NCURSESW - if NcursesW (wide char) library is to be used
|
||||
# HAVE_NCURSES - if the Ncurses library is to be used
|
||||
#
|
||||
# HAVE_CURSES_H - if <curses.h> is present and should be used
|
||||
# HAVE_NCURSESW_H - if <ncursesw.h> should be used
|
||||
# HAVE_NCURSES_H - if <ncurses.h> should be used
|
||||
# HAVE_NCURSESW_CURSES_H - if <ncursesw/curses.h> should be used
|
||||
# HAVE_NCURSES_CURSES_H - if <ncurses/curses.h> should be used
|
||||
#
|
||||
# (These preprocessor symbols are discussed later in this document.)
|
||||
#
|
||||
# The following output variable is defined by this macro; it is precious
|
||||
# and may be overridden on the ./configure command line:
|
||||
#
|
||||
# CURSES_LIB - library to add to xxx_LDADD
|
||||
#
|
||||
# The library listed in CURSES_LIB is NOT added to LIBS by default. You
|
||||
# need to add CURSES_LIB to the appropriate xxx_LDADD line in your
|
||||
# Makefile.am. For example:
|
||||
#
|
||||
# prog_LDADD = @CURSES_LIB@
|
||||
#
|
||||
# If CURSES_LIB is set on the configure command line (such as by running
|
||||
# "./configure CURSES_LIB=-lmycurses"), then the only header searched for
|
||||
# is <curses.h>. The user may use the CPPFLAGS precious variable to
|
||||
# override the standard #include search path. If the user needs to
|
||||
# specify an alternative path for a library (such as for a non-standard
|
||||
# NcurseW), the user should use the LDFLAGS variable.
|
||||
#
|
||||
# The following shell variables may be defined by this macro:
|
||||
#
|
||||
# ax_cv_curses - set to "yes" if any Curses library found
|
||||
# ax_cv_curses_enhanced - set to "yes" if Enhanced functions present
|
||||
# ax_cv_curses_color - set to "yes" if color functions present
|
||||
# ax_cv_curses_obsolete - set to "yes" if obsolete features present
|
||||
#
|
||||
# ax_cv_ncursesw - set to "yes" if NcursesW library found
|
||||
# ax_cv_ncurses - set to "yes" if Ncurses library found
|
||||
# ax_cv_plaincurses - set to "yes" if plain Curses library found
|
||||
# ax_cv_curses_which - set to "ncursesw", "ncurses", "plaincurses" or "no"
|
||||
#
|
||||
# These variables can be used in your configure.ac to determine the level
|
||||
# of support you need from the Curses library. For example, if you must
|
||||
# have either Ncurses or NcursesW, you could include:
|
||||
#
|
||||
# AX_WITH_CURSES
|
||||
# if test "x$ax_cv_ncursesw" != xyes && test "x$ax_cv_ncurses" != xyes; then
|
||||
# AX_MSG_ERROR([requires either NcursesW or Ncurses library])
|
||||
# fi
|
||||
#
|
||||
# If any Curses library will do (but one must be present and must support
|
||||
# color), you could use:
|
||||
#
|
||||
# AX_WITH_CURSES
|
||||
# if test "x$ax_cv_curses" != xyes || test "x$ax_cv_curses_color" != xyes; then
|
||||
# AC_MSG_ERROR([requires an X/Open-compatible Curses library with color])
|
||||
# fi
|
||||
#
|
||||
# Certain preprocessor symbols and shell variables defined by this macro
|
||||
# can be used to determine various features of the Curses library. In
|
||||
# particular, HAVE_CURSES and ax_cv_curses are defined if the Curses
|
||||
# library found conforms to the traditional SysV and/or X/Open Base Curses
|
||||
# definition. Any working Curses library conforms to this level.
|
||||
#
|
||||
# HAVE_CURSES_ENHANCED and ax_cv_curses_enhanced are defined if the
|
||||
# library supports the X/Open Enhanced Curses definition. In particular,
|
||||
# the wide-character types attr_t, cchar_t and wint_t, the functions
|
||||
# wattr_set() and wget_wch() and the macros WA_NORMAL and _XOPEN_CURSES
|
||||
# are checked. The Ncurses library does NOT conform to this definition,
|
||||
# although NcursesW does.
|
||||
#
|
||||
# HAVE_CURSES_COLOR and ax_cv_curses_color are defined if the library
|
||||
# supports color functions and macros such as COLOR_PAIR, A_COLOR,
|
||||
# COLOR_WHITE, COLOR_RED and init_pair(). These are NOT part of the
|
||||
# X/Open Base Curses definition, but are part of the Enhanced set of
|
||||
# functions. The Ncurses library DOES support these functions, as does
|
||||
# NcursesW.
|
||||
#
|
||||
# HAVE_CURSES_OBSOLETE and ax_cv_curses_obsolete are defined if the
|
||||
# library supports certain features present in SysV and BSD Curses but not
|
||||
# defined in the X/Open definition. In particular, the functions
|
||||
# getattrs(), getcurx() and getmaxx() are checked.
|
||||
#
|
||||
# To use the HAVE_xxx_H preprocessor symbols, insert the following into
|
||||
# your system.h (or equivalent) header file:
|
||||
#
|
||||
# #if defined HAVE_NCURSESW_CURSES_H
|
||||
# # include <ncursesw/curses.h>
|
||||
# #elif defined HAVE_NCURSESW_H
|
||||
# # include <ncursesw.h>
|
||||
# #elif defined HAVE_NCURSES_CURSES_H
|
||||
# # include <ncurses/curses.h>
|
||||
# #elif defined HAVE_NCURSES_H
|
||||
# # include <ncurses.h>
|
||||
# #elif defined HAVE_CURSES_H
|
||||
# # include <curses.h>
|
||||
# #else
|
||||
# # error "SysV or X/Open-compatible Curses header file required"
|
||||
# #endif
|
||||
#
|
||||
# For previous users of this macro: you should not need to change anything
|
||||
# in your configure.ac or Makefile.am, as the previous (serial 10)
|
||||
# semantics are still valid. However, you should update your system.h (or
|
||||
# equivalent) header file to the fragment shown above. You are encouraged
|
||||
# also to make use of the extended functionality provided by this version
|
||||
# of AX_WITH_CURSES, as well as in the additional macros
|
||||
# AX_WITH_CURSES_PANEL, AX_WITH_CURSES_MENU and AX_WITH_CURSES_FORM.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2009 Mark Pulford <mark@kyne.com.au>
|
||||
# Copyright (c) 2009 Damian Pietras <daper@daper.net>
|
||||
# Copyright (c) 2012 Reuben Thomas <rrt@sc3d.org>
|
||||
# Copyright (c) 2011 John Zaitseff <J.Zaitseff@zap.org.au>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 13
|
||||
|
||||
AU_ALIAS([MP_WITH_CURSES], [AX_WITH_CURSES])
|
||||
AC_DEFUN([AX_WITH_CURSES], [
|
||||
AC_ARG_VAR([CURSES_LIB], [linker library for Curses, e.g. -lcurses])
|
||||
AC_ARG_WITH([ncurses], [AS_HELP_STRING([--with-ncurses],
|
||||
[force the use of Ncurses or NcursesW])],
|
||||
[], [with_ncurses=check])
|
||||
AC_ARG_WITH([ncursesw], [AS_HELP_STRING([--without-ncursesw],
|
||||
[do not use NcursesW (wide character support)])],
|
||||
[], [with_ncursesw=check])
|
||||
|
||||
ax_saved_LIBS=$LIBS
|
||||
AS_IF([test "x$with_ncurses" = xyes || test "x$with_ncursesw" = xyes],
|
||||
[ax_with_plaincurses=no], [ax_with_plaincurses=check])
|
||||
|
||||
ax_cv_curses_which=no
|
||||
|
||||
# Test for NcursesW
|
||||
|
||||
AS_IF([test "x$CURSES_LIB" = x && test "x$with_ncursesw" != xno], [
|
||||
LIBS="$ax_saved_LIBS -lncursesw"
|
||||
|
||||
AC_CACHE_CHECK([for NcursesW wide-character library], [ax_cv_ncursesw], [
|
||||
AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])],
|
||||
[ax_cv_ncursesw=yes], [ax_cv_ncursesw=no])
|
||||
])
|
||||
AS_IF([test "x$ax_cv_ncursesw" = xno && test "x$with_ncursesw" = xyes], [
|
||||
AC_MSG_ERROR([--with-ncursesw specified but could not find NcursesW library])
|
||||
])
|
||||
|
||||
AS_IF([test "x$ax_cv_ncursesw" = xyes], [
|
||||
ax_cv_curses=yes
|
||||
ax_cv_curses_which=ncursesw
|
||||
CURSES_LIB="-lncursesw"
|
||||
AC_DEFINE([HAVE_NCURSESW], [1], [Define to 1 if the NcursesW library is present])
|
||||
AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present])
|
||||
|
||||
AC_CACHE_CHECK([for working ncursesw/curses.h], [ax_cv_header_ncursesw_curses_h], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@define _XOPEN_SOURCE_EXTENDED 1
|
||||
@%:@include <ncursesw/curses.h>
|
||||
]], [[
|
||||
chtype a = A_BOLD;
|
||||
int b = KEY_LEFT;
|
||||
chtype c = COLOR_PAIR(1) & A_COLOR;
|
||||
attr_t d = WA_NORMAL;
|
||||
cchar_t e;
|
||||
wint_t f;
|
||||
int g = getattrs(stdscr);
|
||||
int h = getcurx(stdscr) + getmaxx(stdscr);
|
||||
initscr();
|
||||
init_pair(1, COLOR_WHITE, COLOR_RED);
|
||||
wattr_set(stdscr, d, 0, NULL);
|
||||
wget_wch(stdscr, &f);
|
||||
]])],
|
||||
[ax_cv_header_ncursesw_curses_h=yes],
|
||||
[ax_cv_header_ncursesw_curses_h=no])
|
||||
])
|
||||
AS_IF([test "x$ax_cv_header_ncursesw_curses_h" = xyes], [
|
||||
ax_cv_curses_enhanced=yes
|
||||
ax_cv_curses_color=yes
|
||||
ax_cv_curses_obsolete=yes
|
||||
AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions])
|
||||
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
|
||||
AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features])
|
||||
AC_DEFINE([HAVE_NCURSESW_CURSES_H], [1], [Define to 1 if <ncursesw/curses.h> is present])
|
||||
])
|
||||
|
||||
AC_CACHE_CHECK([for working ncursesw.h], [ax_cv_header_ncursesw_h], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@define _XOPEN_SOURCE_EXTENDED 1
|
||||
@%:@include <ncursesw.h>
|
||||
]], [[
|
||||
chtype a = A_BOLD;
|
||||
int b = KEY_LEFT;
|
||||
chtype c = COLOR_PAIR(1) & A_COLOR;
|
||||
attr_t d = WA_NORMAL;
|
||||
cchar_t e;
|
||||
wint_t f;
|
||||
int g = getattrs(stdscr);
|
||||
int h = getcurx(stdscr) + getmaxx(stdscr);
|
||||
initscr();
|
||||
init_pair(1, COLOR_WHITE, COLOR_RED);
|
||||
wattr_set(stdscr, d, 0, NULL);
|
||||
wget_wch(stdscr, &f);
|
||||
]])],
|
||||
[ax_cv_header_ncursesw_h=yes],
|
||||
[ax_cv_header_ncursesw_h=no])
|
||||
])
|
||||
AS_IF([test "x$ax_cv_header_ncursesw_h" = xyes], [
|
||||
ax_cv_curses_enhanced=yes
|
||||
ax_cv_curses_color=yes
|
||||
ax_cv_curses_obsolete=yes
|
||||
AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions])
|
||||
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
|
||||
AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features])
|
||||
AC_DEFINE([HAVE_NCURSESW_H], [1], [Define to 1 if <ncursesw.h> is present])
|
||||
])
|
||||
|
||||
AC_CACHE_CHECK([for working ncurses.h], [ax_cv_header_ncurses_h_with_ncursesw], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@define _XOPEN_SOURCE_EXTENDED 1
|
||||
@%:@include <ncurses.h>
|
||||
]], [[
|
||||
chtype a = A_BOLD;
|
||||
int b = KEY_LEFT;
|
||||
chtype c = COLOR_PAIR(1) & A_COLOR;
|
||||
attr_t d = WA_NORMAL;
|
||||
cchar_t e;
|
||||
wint_t f;
|
||||
int g = getattrs(stdscr);
|
||||
int h = getcurx(stdscr) + getmaxx(stdscr);
|
||||
initscr();
|
||||
init_pair(1, COLOR_WHITE, COLOR_RED);
|
||||
wattr_set(stdscr, d, 0, NULL);
|
||||
wget_wch(stdscr, &f);
|
||||
]])],
|
||||
[ax_cv_header_ncurses_h_with_ncursesw=yes],
|
||||
[ax_cv_header_ncurses_h_with_ncursesw=no])
|
||||
])
|
||||
AS_IF([test "x$ax_cv_header_ncurses_h_with_ncursesw" = xyes], [
|
||||
ax_cv_curses_enhanced=yes
|
||||
ax_cv_curses_color=yes
|
||||
ax_cv_curses_obsolete=yes
|
||||
AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions])
|
||||
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
|
||||
AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features])
|
||||
AC_DEFINE([HAVE_NCURSES_H], [1], [Define to 1 if <ncurses.h> is present])
|
||||
])
|
||||
|
||||
AS_IF([test "x$ax_cv_header_ncursesw_curses_h" = xno && test "x$ax_cv_header_ncursesw_h" = xno && test "x$ax_cv_header_ncurses_h_with_ncursesw" = xno], [
|
||||
AC_MSG_WARN([could not find a working ncursesw/curses.h, ncursesw.h or ncurses.h])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
# Test for Ncurses
|
||||
|
||||
AS_IF([test "x$CURSES_LIB" = x && test "x$with_ncurses" != xno && test "x$ax_cv_curses_which" = xno], [
|
||||
LIBS="$ax_saved_LIBS -lncurses"
|
||||
|
||||
AC_CACHE_CHECK([for Ncurses library], [ax_cv_ncurses], [
|
||||
AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])],
|
||||
[ax_cv_ncurses=yes], [ax_cv_ncurses=no])
|
||||
])
|
||||
AS_IF([test "x$ax_cv_ncurses" = xno && test "x$with_ncurses" = xyes], [
|
||||
AC_MSG_ERROR([--with-ncurses specified but could not find Ncurses library])
|
||||
])
|
||||
|
||||
AS_IF([test "x$ax_cv_ncurses" = xyes], [
|
||||
ax_cv_curses=yes
|
||||
ax_cv_curses_which=ncurses
|
||||
CURSES_LIB="-lncurses"
|
||||
AC_DEFINE([HAVE_NCURSES], [1], [Define to 1 if the Ncurses library is present])
|
||||
AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present])
|
||||
|
||||
AC_CACHE_CHECK([for working ncurses/curses.h], [ax_cv_header_ncurses_curses_h], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@include <ncurses/curses.h>
|
||||
]], [[
|
||||
chtype a = A_BOLD;
|
||||
int b = KEY_LEFT;
|
||||
chtype c = COLOR_PAIR(1) & A_COLOR;
|
||||
int g = getattrs(stdscr);
|
||||
int h = getcurx(stdscr) + getmaxx(stdscr);
|
||||
initscr();
|
||||
init_pair(1, COLOR_WHITE, COLOR_RED);
|
||||
]])],
|
||||
[ax_cv_header_ncurses_curses_h=yes],
|
||||
[ax_cv_header_ncurses_curses_h=no])
|
||||
])
|
||||
AS_IF([test "x$ax_cv_header_ncurses_curses_h" = xyes], [
|
||||
ax_cv_curses_color=yes
|
||||
ax_cv_curses_obsolete=yes
|
||||
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
|
||||
AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features])
|
||||
AC_DEFINE([HAVE_NCURSES_CURSES_H], [1], [Define to 1 if <ncurses/curses.h> is present])
|
||||
])
|
||||
|
||||
AC_CACHE_CHECK([for working ncurses.h], [ax_cv_header_ncurses_h], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@include <ncurses.h>
|
||||
]], [[
|
||||
chtype a = A_BOLD;
|
||||
int b = KEY_LEFT;
|
||||
chtype c = COLOR_PAIR(1) & A_COLOR;
|
||||
int g = getattrs(stdscr);
|
||||
int h = getcurx(stdscr) + getmaxx(stdscr);
|
||||
initscr();
|
||||
init_pair(1, COLOR_WHITE, COLOR_RED);
|
||||
]])],
|
||||
[ax_cv_header_ncurses_h=yes],
|
||||
[ax_cv_header_ncurses_h=no])
|
||||
])
|
||||
AS_IF([test "x$ax_cv_header_ncurses_h" = xyes], [
|
||||
ax_cv_curses_color=yes
|
||||
ax_cv_curses_obsolete=yes
|
||||
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
|
||||
AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features])
|
||||
AC_DEFINE([HAVE_NCURSES_H], [1], [Define to 1 if <ncurses.h> is present])
|
||||
])
|
||||
|
||||
AS_IF([test "x$ax_cv_header_ncurses_curses_h" = xno && test "x$ax_cv_header_ncurses_h" = xno], [
|
||||
AC_MSG_WARN([could not find a working ncurses/curses.h or ncurses.h])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
# Test for plain Curses (or if CURSES_LIB was set by user)
|
||||
|
||||
AS_IF([test "x$with_plaincurses" != xno && test "x$ax_cv_curses_which" = xno], [
|
||||
AS_IF([test "x$CURSES_LIB" != x], [
|
||||
LIBS="$ax_saved_LIBS $CURSES_LIB"
|
||||
], [
|
||||
LIBS="$ax_saved_LIBS -lcurses"
|
||||
])
|
||||
|
||||
AC_CACHE_CHECK([for Curses library], [ax_cv_plaincurses], [
|
||||
AC_LINK_IFELSE([AC_LANG_CALL([], [initscr])],
|
||||
[ax_cv_plaincurses=yes], [ax_cv_plaincurses=no])
|
||||
])
|
||||
|
||||
AS_IF([test "x$ax_cv_plaincurses" = xyes], [
|
||||
ax_cv_curses=yes
|
||||
ax_cv_curses_which=plaincurses
|
||||
AS_IF([test "x$CURSES_LIB" = x], [
|
||||
CURSES_LIB="-lcurses"
|
||||
])
|
||||
AC_DEFINE([HAVE_CURSES], [1], [Define to 1 if a SysV or X/Open compatible Curses library is present])
|
||||
|
||||
# Check for base conformance (and header file)
|
||||
|
||||
AC_CACHE_CHECK([for working curses.h], [ax_cv_header_curses_h], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@include <curses.h>
|
||||
]], [[
|
||||
chtype a = A_BOLD;
|
||||
int b = KEY_LEFT;
|
||||
initscr();
|
||||
]])],
|
||||
[ax_cv_header_curses_h=yes],
|
||||
[ax_cv_header_curses_h=no])
|
||||
])
|
||||
AS_IF([test "x$ax_cv_header_curses_h" = xyes], [
|
||||
AC_DEFINE([HAVE_CURSES_H], [1], [Define to 1 if <curses.h> is present])
|
||||
|
||||
# Check for X/Open Enhanced conformance
|
||||
|
||||
AC_CACHE_CHECK([for X/Open Enhanced Curses conformance], [ax_cv_plaincurses_enhanced], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@define _XOPEN_SOURCE_EXTENDED 1
|
||||
@%:@include <curses.h>
|
||||
@%:@ifndef _XOPEN_CURSES
|
||||
@%:@error "this Curses library is not enhanced"
|
||||
"this Curses library is not enhanced"
|
||||
@%:@endif
|
||||
]], [[
|
||||
chtype a = A_BOLD;
|
||||
int b = KEY_LEFT;
|
||||
chtype c = COLOR_PAIR(1) & A_COLOR;
|
||||
attr_t d = WA_NORMAL;
|
||||
cchar_t e;
|
||||
wint_t f;
|
||||
initscr();
|
||||
init_pair(1, COLOR_WHITE, COLOR_RED);
|
||||
wattr_set(stdscr, d, 0, NULL);
|
||||
wget_wch(stdscr, &f);
|
||||
]])],
|
||||
[ax_cv_plaincurses_enhanced=yes],
|
||||
[ax_cv_plaincurses_enhanced=no])
|
||||
])
|
||||
AS_IF([test "x$ax_cv_plaincurses_enhanced" = xyes], [
|
||||
ax_cv_curses_enhanced=yes
|
||||
ax_cv_curses_color=yes
|
||||
AC_DEFINE([HAVE_CURSES_ENHANCED], [1], [Define to 1 if library supports X/Open Enhanced functions])
|
||||
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
|
||||
])
|
||||
|
||||
# Check for color functions
|
||||
|
||||
AC_CACHE_CHECK([for Curses color functions], [ax_cv_plaincurses_color], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@define _XOPEN_SOURCE_EXTENDED 1
|
||||
@%:@include <curses.h>
|
||||
]], [[
|
||||
chtype a = A_BOLD;
|
||||
int b = KEY_LEFT;
|
||||
chtype c = COLOR_PAIR(1) & A_COLOR;
|
||||
initscr();
|
||||
init_pair(1, COLOR_WHITE, COLOR_RED);
|
||||
]])],
|
||||
[ax_cv_plaincurses_color=yes],
|
||||
[ax_cv_plaincurses_color=no])
|
||||
])
|
||||
AS_IF([test "x$ax_cv_plaincurses_color" = xyes], [
|
||||
ax_cv_curses_color=yes
|
||||
AC_DEFINE([HAVE_CURSES_COLOR], [1], [Define to 1 if library supports color (enhanced functions)])
|
||||
])
|
||||
|
||||
# Check for obsolete functions
|
||||
|
||||
AC_CACHE_CHECK([for obsolete Curses functions], [ax_cv_plaincurses_obsolete], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@include <curses.h>
|
||||
]], [[
|
||||
chtype a = A_BOLD;
|
||||
int b = KEY_LEFT;
|
||||
int g = getattrs(stdscr);
|
||||
int h = getcurx(stdscr) + getmaxx(stdscr);
|
||||
initscr();
|
||||
]])],
|
||||
[ax_cv_plaincurses_obsolete=yes],
|
||||
[ax_cv_plaincurses_obsolete=no])
|
||||
])
|
||||
AS_IF([test "x$ax_cv_plaincurses_obsolete" = xyes], [
|
||||
ax_cv_curses_obsolete=yes
|
||||
AC_DEFINE([HAVE_CURSES_OBSOLETE], [1], [Define to 1 if library supports certain obsolete features])
|
||||
])
|
||||
])
|
||||
|
||||
AS_IF([test "x$ax_cv_header_curses_h" = xno], [
|
||||
AC_MSG_WARN([could not find a working curses.h])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
AS_IF([test "x$ax_cv_curses" != xyes], [ax_cv_curses=no])
|
||||
AS_IF([test "x$ax_cv_curses_enhanced" != xyes], [ax_cv_curses_enhanced=no])
|
||||
AS_IF([test "x$ax_cv_curses_color" != xyes], [ax_cv_curses_color=no])
|
||||
AS_IF([test "x$ax_cv_curses_obsolete" != xyes], [ax_cv_curses_obsolete=no])
|
||||
|
||||
LIBS=$ax_saved_LIBS
|
||||
])dnl
|
||||
159
vendor/mosh/m4/pkg.m4
vendored
Normal file
159
vendor/mosh/m4/pkg.m4
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
# serial 1 (pkg-config-0.24)
|
||||
#
|
||||
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# PKG_PROG_PKG_CONFIG([MIN-VERSION])
|
||||
# ----------------------------------
|
||||
AC_DEFUN([PKG_PROG_PKG_CONFIG],
|
||||
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
|
||||
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
|
||||
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
|
||||
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
|
||||
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
|
||||
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
|
||||
|
||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
||||
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
|
||||
fi
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
_pkg_min_version=m4_default([$1], [0.9.0])
|
||||
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
PKG_CONFIG=""
|
||||
fi
|
||||
fi[]dnl
|
||||
])# PKG_PROG_PKG_CONFIG
|
||||
|
||||
# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
#
|
||||
# Check to see whether a particular set of modules exists. Similar
|
||||
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
|
||||
#
|
||||
# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
# only at the first occurence in configure.ac, so if the first place
|
||||
# it's called might be skipped (such as if it is within an "if", you
|
||||
# have to call PKG_CHECK_EXISTS manually
|
||||
# --------------------------------------------------------------
|
||||
AC_DEFUN([PKG_CHECK_EXISTS],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
|
||||
m4_default([$2], [:])
|
||||
m4_ifvaln([$3], [else
|
||||
$3])dnl
|
||||
fi])
|
||||
|
||||
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
|
||||
# ---------------------------------------------
|
||||
m4_define([_PKG_CONFIG],
|
||||
[if test -n "$$1"; then
|
||||
pkg_cv_[]$1="$$1"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
PKG_CHECK_EXISTS([$3],
|
||||
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes ],
|
||||
[pkg_failed=yes])
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi[]dnl
|
||||
])# _PKG_CONFIG
|
||||
|
||||
# _PKG_SHORT_ERRORS_SUPPORTED
|
||||
# -----------------------------
|
||||
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||
_pkg_short_errors_supported=yes
|
||||
else
|
||||
_pkg_short_errors_supported=no
|
||||
fi[]dnl
|
||||
])# _PKG_SHORT_ERRORS_SUPPORTED
|
||||
|
||||
|
||||
# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
|
||||
# [ACTION-IF-NOT-FOUND])
|
||||
#
|
||||
#
|
||||
# Note that if there is a possibility the first call to
|
||||
# PKG_CHECK_MODULES might not happen, you should be sure to include an
|
||||
# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
|
||||
#
|
||||
#
|
||||
# --------------------------------------------------------------
|
||||
AC_DEFUN([PKG_CHECK_MODULES],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
|
||||
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
|
||||
|
||||
pkg_failed=no
|
||||
AC_MSG_CHECKING([for $1])
|
||||
|
||||
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
|
||||
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
|
||||
|
||||
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
|
||||
and $1[]_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details.])
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
AC_MSG_RESULT([no])
|
||||
_PKG_SHORT_ERRORS_SUPPORTED
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
||||
else
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
|
||||
|
||||
m4_default([$4], [AC_MSG_ERROR(
|
||||
[Package requirements ($2) were not met:
|
||||
|
||||
$$1_PKG_ERRORS
|
||||
|
||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||
installed software in a non-standard prefix.
|
||||
|
||||
_PKG_TEXT])[]dnl
|
||||
])
|
||||
elif test $pkg_failed = untried; then
|
||||
AC_MSG_RESULT([no])
|
||||
m4_default([$4], [AC_MSG_FAILURE(
|
||||
[The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
|
||||
_PKG_TEXT
|
||||
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
|
||||
])
|
||||
else
|
||||
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
|
||||
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
|
||||
AC_MSG_RESULT([yes])
|
||||
$3
|
||||
fi[]dnl
|
||||
])# PKG_CHECK_MODULES
|
||||
3
vendor/mosh/macosx/.gitignore
vendored
Normal file
3
vendor/mosh/macosx/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/mosh-package.pmdoc
|
||||
/Mosh*.pkg
|
||||
/prefix
|
||||
15
vendor/mosh/macosx/Distribution.in
vendored
Normal file
15
vendor/mosh/macosx/Distribution.in
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<installer-script minSpecVersion="1.000000" authoringTool="com.apple.PackageMaker" authoringToolVersion="3.0.6" authoringToolBuild="201">
|
||||
<title>@PACKAGE_VERSION@</title>
|
||||
<options customize="never" allow-external-scripts="no"/>
|
||||
<domains enable_anywhere="true"/>
|
||||
<readme file="ReadMe"/>
|
||||
<license file="License"/>
|
||||
<choices-outline>
|
||||
<line choice="choice0"/>
|
||||
</choices-outline>
|
||||
<choice id="choice0" title="Default" customLocation="/usr">
|
||||
<pkg-ref id="edu.mit.mosh.mosh.pkg"/>
|
||||
</choice>
|
||||
<pkg-ref id="edu.mit.mosh.mosh.pkg" installKBytes="2204" version="@PACKAGE_VERSION@" auth="Root">#edu.mit.mosh.mosh.pkg</pkg-ref>
|
||||
</installer-script>
|
||||
153
vendor/mosh/macosx/build.sh
vendored
Executable file
153
vendor/mosh/macosx/build.sh
vendored
Executable file
@@ -0,0 +1,153 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# This script is known to work on:
|
||||
# OS X 10.5.8, Xcode 3.1.2, SDK 10.5, MacPorts 2.3.3
|
||||
# OS X 10.9.5, Xcode 5.1.1, SDK 10.9, MacPorts 2.3.2
|
||||
# OS X 10.10.3, XCode 6.3.2, SDK 10.10, Homebrew 0.9.5/8da6986
|
||||
#
|
||||
# You may need to set PATH to include the location of your
|
||||
# PackageMaker binary, if your system is old enough to need that.
|
||||
# Setting MACOSX_DEPLOYMENT_TARGET will select an SDK as usual.
|
||||
#
|
||||
# If you are using Homebrew, you should install protobuf (and any
|
||||
# other future Homebrew dependencies) with
|
||||
# `--universal --build-bottle`.
|
||||
# The first option should be fairly obvious; the second has the side
|
||||
# effect of disabling Homebrew's overzealous processor optimization
|
||||
# with (effectively) `-march=native`.
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
protobuf_LIBS=$(l=libprotobuf.a; for i in /opt/local/lib /usr/local/lib; do if [ -f $i/$l ]; then echo $i/$l; fi; done)
|
||||
if [ -z "$protobuf_LIBS" ]; then echo "Can't find libprotobuf.a"; exit 1; fi
|
||||
export protobuf_LIBS
|
||||
if ! pkg-config --cflags protobuf > /dev/null 2>&1; then
|
||||
protobuf_CFLAGS=-I$(for i in /opt /usr; do d=$i/local/include; if [ -d $d/google/protobuf ]; then echo $d; fi; done)
|
||||
if [ "$protobuf_CFLAGS" = "-I" ]; then echo "Can't find protobuf includes"; exit 1; fi
|
||||
export protobuf_CFLAGS
|
||||
fi
|
||||
|
||||
echo "Building into prefix..."
|
||||
|
||||
|
||||
#
|
||||
# XXX This script abuses Configure's --prefix argument badly. It uses
|
||||
# it as a $DESTDIR, but --prefix can also affect paths in generated
|
||||
# objects. That is not *currently* a problem in mosh.
|
||||
#
|
||||
PREFIX="$(pwd)/prefix"
|
||||
|
||||
ARCHS=" ppc ppc64 i386 x86_64"
|
||||
|
||||
pushd .. > /dev/null
|
||||
|
||||
if [ ! -f configure ];
|
||||
then
|
||||
echo "Running autogen."
|
||||
PATH=/opt/local/bin:$PATH ./autogen.sh
|
||||
fi
|
||||
|
||||
#
|
||||
# Build archs one by one.
|
||||
#
|
||||
for arch in $ARCHS; do
|
||||
echo "Building for ${arch}..."
|
||||
prefix="${PREFIX}_${arch}"
|
||||
rm -rf "${prefix}"
|
||||
mkdir "${prefix}"
|
||||
if ./configure --prefix="${prefix}/local" \
|
||||
CC="cc -arch ${arch}" CPP="cc -arch ${arch} -E" CXX="c++ -arch ${arch}" \
|
||||
TINFO_LIBS=-lncurses &&
|
||||
make clean &&
|
||||
make install -j8 &&
|
||||
rm -f "${prefix}/etc"
|
||||
then
|
||||
# mosh-client built with Xcode 3.1.2 bus-errors if the binary is stripped.
|
||||
# strip "${prefix}/local/bin/mosh-client" "${prefix}/local/bin/mosh-server"
|
||||
BUILT_ARCHS="$BUILT_ARCHS $arch"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$BUILT_ARCHS" ]; then
|
||||
echo "No architectures built successfully"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building universal binaries for archs ${BUILT_ARCHS}..."
|
||||
|
||||
|
||||
rm -rf "$PREFIX"
|
||||
# Copy one architecture to get all files into place.
|
||||
for arch in $BUILT_ARCHS; do
|
||||
cp -Rp "${PREFIX}_${arch}" "${PREFIX}"
|
||||
break
|
||||
done
|
||||
|
||||
# Build fat binaries
|
||||
# XXX will break with spaces in pathname
|
||||
for prog in local/bin/mosh-client local/bin/mosh-server; do
|
||||
archprogs=
|
||||
for arch in $BUILT_ARCHS; do
|
||||
archprogs="$archprogs ${PREFIX}_${arch}/$prog"
|
||||
done
|
||||
lipo -create $archprogs -output "${PREFIX}/$prog"
|
||||
done
|
||||
|
||||
perl -wlpi -e 's{#!/usr/bin/env perl}{#!/usr/bin/perl}' "$PREFIX/local/bin/mosh"
|
||||
|
||||
popd > /dev/null
|
||||
|
||||
PACKAGE_VERSION=$(cat ../VERSION)
|
||||
|
||||
OUTFILE="$PACKAGE_VERSION.pkg"
|
||||
|
||||
rm -f "$OUTFILE"
|
||||
|
||||
if which -s pkgbuild; then
|
||||
# To replace PackageMaker, you:
|
||||
# * make a bare package with the build products
|
||||
# * essentially take the Distribution file that PackageMaker generated and
|
||||
# use it as the --distribution input file for productbuild
|
||||
echo "Preprocessing package description..."
|
||||
PKGID=edu.mit.mosh.mosh.pkg
|
||||
for file in Distribution; do
|
||||
sed -e "s/@PACKAGE_VERSION@/${PACKAGE_VERSION}/g" ${file}.in > ${file}
|
||||
done
|
||||
echo "Running pkgbuild/productbuild..."
|
||||
mkdir -p Resources/en.lproj
|
||||
cp -p copying.rtf Resources/en.lproj/License
|
||||
cp -p readme.rtf Resources/en.lproj/Readme
|
||||
pkgbuild --root "$PREFIX" --identifier $PKGID $PKGID
|
||||
productbuild --distribution Distribution \
|
||||
--resources Resources \
|
||||
--package-path . \
|
||||
"$OUTFILE"
|
||||
echo "Cleaning up..."
|
||||
rm -rf $PKGID
|
||||
else
|
||||
echo "Preprocessing package description..."
|
||||
INDIR=mosh-package.pmdoc.in
|
||||
OUTDIR=mosh-package.pmdoc
|
||||
mkdir -p "$OUTDIR"
|
||||
pushd "$INDIR" > /dev/null
|
||||
for file in *
|
||||
do
|
||||
sed -e 's/$PACKAGE_VERSION/'"$PACKAGE_VERSION"'/g' "$file" > "../$OUTDIR/$file"
|
||||
done
|
||||
popd > /dev/null
|
||||
echo "Running PackageMaker..."
|
||||
env PATH="/Applications/PackageMaker.app/Contents/MacOS:/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS:$PATH" PackageMaker -d mosh-package.pmdoc -o "$OUTFILE" -i edu.mit.mosh.mosh.pkg
|
||||
echo "Cleaning up..."
|
||||
rm -rf "$OUTDIR"
|
||||
fi
|
||||
|
||||
|
||||
if [ -f "$OUTFILE" ];
|
||||
then
|
||||
echo "Successfully built $OUTFILE with archs ${BUILT_ARCHS}."
|
||||
else
|
||||
echo "There was an error building $OUTFILE."
|
||||
false
|
||||
fi
|
||||
252
vendor/mosh/macosx/copying.rtf
vendored
Normal file
252
vendor/mosh/macosx/copying.rtf
vendored
Normal file
@@ -0,0 +1,252 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf320
|
||||
{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural
|
||||
|
||||
\f0\fs26 \cf0 GNU GENERAL PUBLIC LICENSE\
|
||||
Version 3, 29 June 2007\
|
||||
\
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\
|
||||
Everyone is permitted to copy and distribute verbatim copies\
|
||||
of this license document, but changing it is not allowed.\
|
||||
\
|
||||
Preamble\
|
||||
\
|
||||
The GNU General Public License is a free, copyleft license for software and other kinds of works.\
|
||||
\
|
||||
The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.\
|
||||
\
|
||||
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.\
|
||||
\
|
||||
To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.\
|
||||
\
|
||||
For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.\
|
||||
\
|
||||
Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.\
|
||||
\
|
||||
For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.\
|
||||
\
|
||||
Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.\
|
||||
\
|
||||
Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.\
|
||||
\
|
||||
The precise terms and conditions for copying, distribution and modification follow.\
|
||||
\
|
||||
TERMS AND CONDITIONS\
|
||||
\
|
||||
0. Definitions.\
|
||||
\
|
||||
"This License" refers to version 3 of the GNU General Public License.\
|
||||
\
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.\
|
||||
\
|
||||
"The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations.\
|
||||
\
|
||||
To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work.\
|
||||
\
|
||||
A "covered work" means either the unmodified Program or a work based on the Program.\
|
||||
\
|
||||
To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.\
|
||||
\
|
||||
To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.\
|
||||
\
|
||||
An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.\
|
||||
\
|
||||
1. Source Code.\
|
||||
\
|
||||
The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work.\
|
||||
\
|
||||
A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.\
|
||||
\
|
||||
The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.\
|
||||
\
|
||||
The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.\
|
||||
\
|
||||
The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.\
|
||||
\
|
||||
The Corresponding Source for a work in source code form is that same work.\
|
||||
\
|
||||
2. Basic Permissions.\
|
||||
\
|
||||
All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.\
|
||||
\
|
||||
You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.\
|
||||
\
|
||||
Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.\
|
||||
\
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.\
|
||||
\
|
||||
No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.\
|
||||
\
|
||||
When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.\
|
||||
\
|
||||
4. Conveying Verbatim Copies.\
|
||||
\
|
||||
You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.\
|
||||
\
|
||||
You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.\
|
||||
\
|
||||
5. Conveying Modified Source Versions.\
|
||||
\
|
||||
You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:\
|
||||
\
|
||||
a) The work must carry prominent notices stating that you modified it, and giving a relevant date.\
|
||||
\
|
||||
b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices".\
|
||||
\
|
||||
c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.\
|
||||
\
|
||||
d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.\
|
||||
\
|
||||
A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.\
|
||||
\
|
||||
6. Conveying Non-Source Forms.\
|
||||
\
|
||||
You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:\
|
||||
\
|
||||
a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.\
|
||||
\
|
||||
b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.\
|
||||
\
|
||||
c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.\
|
||||
\
|
||||
d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.\
|
||||
\
|
||||
e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.\
|
||||
\
|
||||
A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.\
|
||||
\
|
||||
A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.\
|
||||
\
|
||||
"Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.\
|
||||
\
|
||||
If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).\
|
||||
\
|
||||
The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.\
|
||||
\
|
||||
Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.\
|
||||
\
|
||||
7. Additional Terms.\
|
||||
\
|
||||
"Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.\
|
||||
\
|
||||
When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.\
|
||||
\
|
||||
Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:\
|
||||
\
|
||||
a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or\
|
||||
\
|
||||
b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or\
|
||||
\
|
||||
c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or\
|
||||
\
|
||||
d) Limiting the use for publicity purposes of names of licensors or authors of the material; or\
|
||||
\
|
||||
e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or\
|
||||
\
|
||||
f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.\
|
||||
\
|
||||
All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.\
|
||||
\
|
||||
If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.\
|
||||
\
|
||||
Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.\
|
||||
\
|
||||
8. Termination.\
|
||||
\
|
||||
You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).\
|
||||
\
|
||||
However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.\
|
||||
\
|
||||
Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.\
|
||||
\
|
||||
Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.\
|
||||
\
|
||||
9. Acceptance Not Required for Having Copies.\
|
||||
\
|
||||
You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.\
|
||||
\
|
||||
10. Automatic Licensing of Downstream Recipients.\
|
||||
\
|
||||
Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.\
|
||||
\
|
||||
An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.\
|
||||
\
|
||||
You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.\
|
||||
\
|
||||
11. Patents.\
|
||||
\
|
||||
A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version".\
|
||||
\
|
||||
A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.\
|
||||
\
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.\
|
||||
\
|
||||
In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.\
|
||||
\
|
||||
If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.\
|
||||
\
|
||||
If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.\
|
||||
\
|
||||
A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.\
|
||||
\
|
||||
Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.\
|
||||
\
|
||||
12. No Surrender of Others' Freedom.\
|
||||
\
|
||||
If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.\
|
||||
\
|
||||
13. Use with the GNU Affero General Public License.\
|
||||
\
|
||||
Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.\
|
||||
\
|
||||
14. Revised Versions of this License.\
|
||||
\
|
||||
The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.\
|
||||
\
|
||||
Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.\
|
||||
\
|
||||
If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.\
|
||||
\
|
||||
Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.\
|
||||
\
|
||||
15. Disclaimer of Warranty.\
|
||||
\
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\
|
||||
\
|
||||
16. Limitation of Liability.\
|
||||
\
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\
|
||||
\
|
||||
17. Interpretation of Sections 15 and 16.\
|
||||
\
|
||||
If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.\
|
||||
\
|
||||
END OF TERMS AND CONDITIONS\
|
||||
\
|
||||
How to Apply These Terms to Your New Programs\
|
||||
\
|
||||
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.\
|
||||
\
|
||||
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.\
|
||||
\
|
||||
<one line to give the program's name and a brief idea of what it does.>\
|
||||
Copyright (C) <year> <name of author>\
|
||||
\
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\
|
||||
\
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\
|
||||
\
|
||||
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.\
|
||||
\
|
||||
Also add information on how to contact you by electronic and paper mail.\
|
||||
\
|
||||
If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:\
|
||||
\
|
||||
<program> Copyright (C) <year> <name of author> This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.\
|
||||
\
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box".\
|
||||
\
|
||||
You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <http://www.gnu.org/licenses/>.\
|
||||
\
|
||||
The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.}
|
||||
50
vendor/mosh/macosx/mosh-package.pmdoc.in/01prefix-contents.xml
vendored
Normal file
50
vendor/mosh/macosx/mosh-package.pmdoc.in/01prefix-contents.xml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<pkg-contents spec="1.12">
|
||||
<f n="prefix" o="root" g="wheel" p="16877" pt="prefix" m="false" t="file">
|
||||
<f n="local" o="root" g="wheel" p="16877">
|
||||
<f n="bin" o="root" g="wheel" p="16877">
|
||||
<f n="mosh" o="root" g="wheel" p="33261">
|
||||
<mod>group</mod>
|
||||
<mod>owner</mod>
|
||||
</f>
|
||||
<f n="mosh-client" o="root" g="wheel" p="33261">
|
||||
<mod>group</mod>
|
||||
<mod>owner</mod>
|
||||
</f>
|
||||
<f n="mosh-server" o="root" g="wheel" p="33261">
|
||||
<mod>group</mod>
|
||||
<mod>owner</mod>
|
||||
</f>
|
||||
<mod>group</mod>
|
||||
<mod>owner</mod>
|
||||
</f>
|
||||
<f n="share" o="root" g="wheel" p="16877">
|
||||
<f n="man" o="root" g="wheel" p="16877">
|
||||
<f n="man1" o="root" g="wheel" p="16877">
|
||||
<f n="mosh-client.1" o="root" g="wheel" p="33188">
|
||||
<mod>group</mod>
|
||||
<mod>owner</mod>
|
||||
</f>
|
||||
<f n="mosh-server.1" o="root" g="wheel" p="33188">
|
||||
<mod>group</mod>
|
||||
<mod>owner</mod>
|
||||
</f>
|
||||
<f n="mosh.1" o="root" g="wheel" p="33188">
|
||||
<mod>group</mod>
|
||||
<mod>owner</mod>
|
||||
</f>
|
||||
<mod>group</mod>
|
||||
<mod>owner</mod>
|
||||
</f>
|
||||
<mod>group</mod>
|
||||
<mod>owner</mod>
|
||||
</f>
|
||||
<mod>group</mod>
|
||||
<mod>owner</mod>
|
||||
</f>
|
||||
<mod>group</mod>
|
||||
<mod>owner</mod>
|
||||
</f>
|
||||
<mod>group</mod>
|
||||
<mod>owner</mod>
|
||||
</f>
|
||||
</pkg-contents>
|
||||
30
vendor/mosh/macosx/mosh-package.pmdoc.in/01prefix.xml
vendored
Normal file
30
vendor/mosh/macosx/mosh-package.pmdoc.in/01prefix.xml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<pkgref spec="1.12" uuid="38E2F0D0-8573-4E7B-8A50-A86056DD0EE8">
|
||||
<config>
|
||||
<identifier>edu.mit.mosh.mosh.pkg</identifier>
|
||||
<version>$PACKAGE_VERSION</version>
|
||||
<description></description>
|
||||
<post-install type="none"/>
|
||||
<requireAuthorization/>
|
||||
<installFrom relative="true" mod="true">prefix</installFrom>
|
||||
<installTo mod="true">/usr</installTo>
|
||||
<flags>
|
||||
<followSymbolicLinks/>
|
||||
</flags>
|
||||
<packageStore type="internal">
|
||||
</packageStore>
|
||||
<mod>installTo</mod>
|
||||
<mod>relocatable</mod>
|
||||
<mod>installFrom.path</mod>
|
||||
<mod>identifier</mod>
|
||||
<mod>parent</mod>
|
||||
<mod>includeRoot</mod>
|
||||
<mod>installTo.path</mod>
|
||||
<mod>installFrom.isRelativeType</mod>
|
||||
<mod>version</mod>
|
||||
</config>
|
||||
<contents>
|
||||
<file-list>01prefix-contents.xml</file-list>
|
||||
<filter>/\.gitignore$</filter>
|
||||
<filter>/\.DS_Store$</filter>
|
||||
</contents>
|
||||
</pkgref>
|
||||
32
vendor/mosh/macosx/mosh-package.pmdoc.in/index.xml
vendored
Normal file
32
vendor/mosh/macosx/mosh-package.pmdoc.in/index.xml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<pkmkdoc spec="1.12">
|
||||
<properties>
|
||||
<title>Mosh $PACKAGE_VERSION</title>
|
||||
<build>Mosh.pkg</build>
|
||||
<organization>edu.mit.mosh</organization>
|
||||
<userSees ui="easy"/>
|
||||
<min-target os="3"/>
|
||||
<domain anywhere="true"/>
|
||||
</properties>
|
||||
<distribution>
|
||||
<versions min-spec="1.000000"/>
|
||||
<scripts></scripts>
|
||||
</distribution>
|
||||
<description>Mosh is a remote terminal application that supports intermittent connectivity, allows roaming, and provides speculative local echo and line editing of user keystrokes.</description>
|
||||
<contents>
|
||||
<choice title="Default" id="choice0" starts_selected="true" starts_enabled="true" starts_hidden="false">
|
||||
<customLoc>/</customLoc>
|
||||
<pkgref id="edu.mit.mosh.mosh.pkg"/>
|
||||
</choice>
|
||||
</contents>
|
||||
<resources bg-scale="none" bg-align="topleft">
|
||||
<locale lang="en">
|
||||
<resource relative="true" mod="true" type="license">copying.rtf</resource>
|
||||
<resource relative="true" mod="true" type="readme">readme.rtf</resource>
|
||||
</locale>
|
||||
</resources>
|
||||
<flags/>
|
||||
<item type="file">01prefix.xml</item>
|
||||
<mod>properties.title</mod>
|
||||
<mod>properties.userDomain</mod>
|
||||
<mod>description</mod>
|
||||
</pkmkdoc>
|
||||
108
vendor/mosh/macosx/readme.rtf
vendored
Normal file
108
vendor/mosh/macosx/readme.rtf
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf320
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fmodern\fcharset0 Courier;}
|
||||
{\colortbl;\red255\green255\blue255;\red38\green38\blue38;\red246\green246\blue246;\red51\green108\blue190;
|
||||
}
|
||||
{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1}
|
||||
{\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid101\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2}
|
||||
{\list\listtemplateid3\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid201\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid3}}
|
||||
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}}
|
||||
\deftab720
|
||||
\pard\pardeftab720\sa200
|
||||
|
||||
\f0\b\fs56 \cf0 Mosh: the mobile shell\
|
||||
\pard\pardeftab720\sa300
|
||||
|
||||
\b0\fs28 \cf2 Mosh is a remote terminal application that supports intermittent connectivity, allows roaming, and provides speculative local echo and line editing of user keystrokes.\
|
||||
It aims to support the typical interactive uses of SSH, plus:\
|
||||
\pard\tx220\tx720\pardeftab720\li720\fi-720
|
||||
\ls1\ilvl0\cf2 {\listtext \'95 }Mosh keeps the session alive if the client goes to sleep and wakes up later, or temporarily loses its Internet connection.\
|
||||
{\listtext \'95 }Mosh allows the client and server to "roam" and change IP addresses, while keeping the connection alive. Unlike SSH, Mosh can be used while switching between Wi-Fi networks or from Wi-Fi to cellular data to wired Ethernet.\
|
||||
\pard\tx220\tx720\pardeftab720\li720\fi-720\sa300
|
||||
\ls1\ilvl0\cf2 {\listtext \'95 }The Mosh client runs a predictive model of the server's behavior in the background and tries to guess intelligently how each keystroke will affect the screen state. When it is confident in its predictions, it will show them to the user while waiting for confirmation from the server. Most typing and uses of the left- and right-arrow keys can be echoed immediately.\uc0\u8232 As a result, Mosh is usable on high-latency links, e.g. on a cellular data connection or spotty Wi-Fi. In distinction from previous attempts at local echo modes in other protocols, Mosh works properly with full-screen applications such as emacs, vi, alpine, and irssi, and automatically recovers from occasional prediction errors within an RTT. On high-latency links, Mosh underlines its predictions while they are outstanding and removes the underline when they are confirmed by the server.\
|
||||
\pard\pardeftab720\sa300
|
||||
\cf2 Mosh does not support X forwarding or the non-interactive uses of SSH, including port forwarding.\
|
||||
\pard\pardeftab720\sa200
|
||||
|
||||
\b\fs48 \cf0 Other features\
|
||||
\pard\tx220\tx720\pardeftab720\li720\fi-720
|
||||
\ls2\ilvl0
|
||||
\b0\fs28 \cf2 {\listtext \'95 }Mosh adjusts its frame rate so as not to fill up network queues on slow links, so "Control-C" always works within an RTT to halt a runaway process.\
|
||||
{\listtext \'95 }Mosh warns the user when it has not heard from the server in a while.\
|
||||
{\listtext \'95 }Mosh supports lossy links that lose a significant fraction of their packets.\
|
||||
{\listtext \'95 }Mosh handles some Unicode edge cases better than SSH and existing terminal emulators by themselves, but requires a UTF-8 environment to run.\
|
||||
{\listtext \'95 }Mosh leverages SSH to set up the connection and authenticate users. Mosh does not contain any privileged (root) code.\
|
||||
\
|
||||
\pard\pardeftab720\sa200
|
||||
|
||||
\b\fs48 \cf0 Usage\
|
||||
\pard\pardeftab720\sa300
|
||||
|
||||
\b0\fs28 \cf2 The
|
||||
\f1\fs24 \cb3 mosh-client
|
||||
\f0\fs28 \cb1 binary must be installed on the user's machine, and the
|
||||
\f1\fs24 \cb3 mosh-server
|
||||
\f0\fs28 \cb1 binary on the remote host.\
|
||||
The user runs:\
|
||||
\pard\pardeftab720
|
||||
|
||||
\f1\fs24 \cf2 \cb3 $ mosh [user@]host\
|
||||
\pard\pardeftab720\sa300
|
||||
|
||||
\f0\fs28 \cf2 \cb1 A command may also be specified, for example:\
|
||||
\pard\pardeftab720
|
||||
|
||||
\f1\fs24 \cf2 \cb3 $ mosh host -- screen -r\
|
||||
\pard\pardeftab720\sa300
|
||||
|
||||
\f0\fs28 \cf2 \cb1 If the
|
||||
\f1\fs24 \cb3 mosh-client
|
||||
\f0\fs28 \cb1 or
|
||||
\f1\fs24 \cb3 mosh-server
|
||||
\f0\fs28 \cb1 binaries are installed outside the user's PATH,
|
||||
\f1\fs24 \cb3 mosh
|
||||
\f0\fs28 \cb1 accepts the arguments
|
||||
\f1\fs24 \cb3 --client=PATH
|
||||
\f0\fs28 \cb1 and
|
||||
\f1\fs24 \cb3 --server=PATH
|
||||
\f0\fs28 \cb1 to select alternate locations. More options are documented in the mosh(1) manual page.\
|
||||
Mosh supports 256-color mode as long as the user's own terminal does. Generally this means the
|
||||
\f1\fs24 \cb3 TERM
|
||||
\f0\fs28 \cb1 environment variable must be set to
|
||||
\f1\fs24 \cb3 xterm-256color
|
||||
\f0\fs28 \cb1 or
|
||||
\f1\fs24 \cb3 screen-256color-bce
|
||||
\f0\fs28 \cb1 before running
|
||||
\f1\fs24 \cb3 mosh
|
||||
\f0\fs28 \cb1 .\
|
||||
\pard\pardeftab720\sa200
|
||||
|
||||
\b\fs48 \cf0 How it works\
|
||||
\pard\pardeftab720\sa300
|
||||
|
||||
\b0\fs28 \cf2 The
|
||||
\f1\fs24 \cb3 mosh
|
||||
\f0\fs28 \cb1 program will SSH to
|
||||
\f1\fs24 \cb3 user@host
|
||||
\f0\fs28 \cb1 to establish the connection. SSH may prompt the user for a password or use public-key authentication to log in.\
|
||||
From this point,
|
||||
\f1\fs24 \cb3 mosh
|
||||
\f0\fs28 \cb1 runs the
|
||||
\f1\fs24 \cb3 mosh-server
|
||||
\f0\fs28 \cb1 process (as the user) on the server machine. The server process listens on a high UDP port and sends its port number and an AES-128 secret key back to the client over SSH. The SSH connection is then shut down and the terminal session begins over UDP.\
|
||||
If the client changes IP addresses, the server will begin sending to the client on the new IP address within a few seconds.\
|
||||
To function, Mosh requires UDP datagrams to be passed between client and server. By default,
|
||||
\f1\fs24 \cb3 mosh
|
||||
\f0\fs28 \cb1 uses a port number between 60000 and 61000, but the user can select a particular port with the -p option.\
|
||||
\pard\pardeftab720\sa200
|
||||
|
||||
\b\fs48 \cf0 More info\
|
||||
\pard\tx220\tx720\pardeftab720\li720\fi-720\sa300
|
||||
\ls3\ilvl0
|
||||
\b0\fs28 \cf2 {\listtext \'95 }Mosh Web site:\uc0\u8232 {\field{\*\fldinst{HYPERLINK "http://mosh.mit.edu/"}}{\fldrslt \cf4 http://mosh.mit.edu}}\
|
||||
\pard\tx220\tx720\pardeftab720\li720\fi-720\sa300
|
||||
\ls3\ilvl0
|
||||
\f1\fs24 \cf2 \cb3 {\listtext \'95 }mosh-devel@mit.edu
|
||||
\f0\fs28 \cb1 mailing list:\uc0\u8232 {\field{\*\fldinst{HYPERLINK "http://mailman.mit.edu/mailman/listinfo/mosh-devel"}}{\fldrslt \cf4 http://mailman.mit.edu/mailman/listinfo/mosh-devel}}\
|
||||
\ls3\ilvl0
|
||||
\f1\fs24 \cb3 {\listtext \'95 }mosh-users@mit.edu
|
||||
\f0\fs28 \cb1 mailing list:\uc0\u8232 {\field{\*\fldinst{HYPERLINK "http://mailman.mit.edu/mailman/listinfo/mosh-users"}}{\fldrslt \cf4 http://mailman.mit.edu/mailman/listinfo/mosh-users}}}
|
||||
9
vendor/mosh/man/Makefile.am
vendored
Normal file
9
vendor/mosh/man/Makefile.am
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
dist_man_MANS =
|
||||
|
||||
if BUILD_CLIENT
|
||||
dist_man_MANS += mosh.1 mosh-client.1
|
||||
endif
|
||||
|
||||
if BUILD_SERVER
|
||||
dist_man_MANS += mosh-server.1
|
||||
endif
|
||||
96
vendor/mosh/man/mosh-client.1
vendored
Normal file
96
vendor/mosh/man/mosh-client.1
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH MOSH 1 "February 2012"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.SH NAME
|
||||
mosh-client \- client-side helper for mosh
|
||||
.SH SYNOPSIS
|
||||
MOSH_KEY=KEY
|
||||
.B mosh-client
|
||||
IP PORT
|
||||
.br
|
||||
.B mosh-client
|
||||
\-c
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
\fBmosh-client\fP is a helper program for the
|
||||
.BR mosh (1)
|
||||
remote terminal application.
|
||||
|
||||
\fBmosh\fP itself is a setup script that establishes an SSH
|
||||
connection, runs the server-side helper \fBmosh-server\fP,
|
||||
and collects the server's port number and session key.
|
||||
|
||||
\fBmosh\fP then executes \fBmosh-client\fP with the server's IP
|
||||
address, port, and session key. \fBmosh-client\fP runs for
|
||||
the lifetime of the connection.
|
||||
|
||||
The 22-byte base64 session key given by \fBmosh-server\fP is supplied
|
||||
in the MOSH_KEY environment variable. This represents a 128-bit AES
|
||||
key that protects the integrity and confidentiality of the session.
|
||||
|
||||
For constructing new setup wrappers for remote execution facilities
|
||||
other than SSH, it may be necessary to invoke \fBmosh-client\fP
|
||||
directly.
|
||||
|
||||
With the \-c option, \fBmosh-client\fP instead prints the number of colors
|
||||
of the terminal given by the TERM environment variable.
|
||||
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
|
||||
.TP
|
||||
.B MOSH_KEY
|
||||
This variable must be set, and must contain a Base64-encoded cryptographic key from
|
||||
.BR mosh-server (1).
|
||||
|
||||
.TP
|
||||
.B MOSH_ESCAPE_KEY
|
||||
See
|
||||
.BR mosh (1).
|
||||
|
||||
.TP
|
||||
.B MOSH_PREDICTION_DISPLAY
|
||||
Controls local echo as described in
|
||||
.BR mosh (1).
|
||||
|
||||
.TP
|
||||
.B MOSH_TITLE_NOPREFIX
|
||||
See
|
||||
.BR mosh (1).
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR mosh (1),
|
||||
.BR mosh-server (1).
|
||||
|
||||
Project home page:
|
||||
.I http://mosh.mit.edu
|
||||
|
||||
.br
|
||||
.SH AUTHOR
|
||||
mosh was written by Keith Winstein <mosh-devel@mit.edu>.
|
||||
.SH BUGS
|
||||
Please report bugs to \fImosh-devel@mit.edu\fP. Users may also subscribe
|
||||
to the
|
||||
.nh
|
||||
.I mosh-users@mit.edu
|
||||
.hy
|
||||
mailing list, at
|
||||
.br
|
||||
.nh
|
||||
.I http://mailman.mit.edu/mailman/listinfo/mosh-users
|
||||
.hy
|
||||
.
|
||||
156
vendor/mosh/man/mosh-server.1
vendored
Normal file
156
vendor/mosh/man/mosh-server.1
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH MOSH 1 "October 2012"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.SH NAME
|
||||
mosh-server \- server-side helper for mosh
|
||||
.SH SYNOPSIS
|
||||
.B mosh-server
|
||||
new
|
||||
[\-s]
|
||||
[\-v]
|
||||
[\-i \fIIP\fP]
|
||||
[\-p \fIPORT\fP[:\fIPORT2\fP]]
|
||||
[\-c \fICOLORS\fP]
|
||||
[\-\- command...]
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
\fBmosh-server\fP is a helper program for the
|
||||
.BR mosh(1)
|
||||
remote terminal application.
|
||||
|
||||
\fBmosh-server\fP binds to a high UDP port and chooses an encryption
|
||||
key to protect the session. It prints both on standard output,
|
||||
detaches from the terminal, and waits for the \fBmosh-client\fP to
|
||||
establish a connection. It will exit if no client has contacted
|
||||
it within 60 seconds.
|
||||
|
||||
By default, \fBmosh-server\fP binds to a port between 60000 and
|
||||
61000 and executes the user's login shell.
|
||||
|
||||
On platforms with \fButempter\fP, \fBmosh-server\fP maintains an entry
|
||||
in the
|
||||
.BR utmp(5)
|
||||
file to indicate its process ID, whether the session is connected,
|
||||
and the client's current IP address.
|
||||
|
||||
\fBmosh-server\fP exits when the client terminates the connection.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
The argument "new" must be first on the command line to use
|
||||
command-line options.
|
||||
|
||||
.TP
|
||||
.B \-s
|
||||
bind to the local interface used for an incoming SSH connection, given
|
||||
in the \fBSSH_CONNECTION\fP environment variable (for multihomed
|
||||
hosts)
|
||||
|
||||
.TP
|
||||
.B \-v
|
||||
Print some debugging information even after detaching.
|
||||
|
||||
.TP
|
||||
.B \-i \fIIP\fP
|
||||
IP address of the local interface to bind (for multihomed hosts)
|
||||
|
||||
.TP
|
||||
.B \-p \fIPORT\fP[:\fIPORT2\fP]
|
||||
UDP port number or port-range to bind
|
||||
|
||||
.TP
|
||||
.B \-c \fICOLORS\fP
|
||||
Number of colors to advertise to applications through TERM (e.g. 8, 256)
|
||||
|
||||
.TP
|
||||
.B \-l \fINAME=VALUE\fP
|
||||
Locale-related environment variable to try as part of a fallback
|
||||
environment, if the startup environment does not specify a character
|
||||
set of UTF-8.
|
||||
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
These variables allow server-side configuration of Mosh's behavior.
|
||||
They may be set by administrators in system login/rc files,
|
||||
/etc/login.conf, or similar mechanisms, or users in their shell's
|
||||
login/rc files. \fBmosh-server\fP passes these variables to the login
|
||||
session and shell that it starts, but changing them there will have no
|
||||
effect.
|
||||
|
||||
.TP
|
||||
.B MOSH_SERVER_NETWORK_TMOUT
|
||||
If this variable is set to a positive integer number, it specifies how
|
||||
long (in seconds) \fBmosh-server\fP will wait to receive an update from the
|
||||
client before exiting. Since \fPmosh\fP is very useful for mobile
|
||||
clients with intermittent operation and connectivity, we suggest
|
||||
setting this variable to a high value, such as 604800 (one week) or
|
||||
2592000 (30 days). Otherwise, \fBmosh-server\fP will wait
|
||||
indefinitely for a client to reappear. This variable is somewhat
|
||||
similar to the \fBTMOUT\fP variable found in many Bourne shells.
|
||||
However, it is not a login-session inactivity timeout; it only applies
|
||||
to network connectivity.
|
||||
|
||||
.TP
|
||||
.B MOSH_SERVER_SIGNAL_TMOUT
|
||||
If this variable is set to a positive integer number, it specifies how
|
||||
long (in seconds) \fBmosh-server\fP will ignore SIGUSR1 while waiting
|
||||
to receive an update from the client. Otherwise, \fBSIGUSR1\fP will
|
||||
always terminate \fBmosh-server\fP. Users and administrators may
|
||||
implement scripts to clean up disconnected Mosh sessions. With this
|
||||
variable set, a user or administrator can issue
|
||||
|
||||
.nf
|
||||
$ pkill -SIGUSR1 mosh-server
|
||||
.fi
|
||||
|
||||
to kill disconnected sessions without killing connected login
|
||||
sessions.
|
||||
|
||||
.SH EXAMPLE
|
||||
|
||||
.nf
|
||||
$ mosh-server
|
||||
|
||||
MOSH CONNECT 60001 UAkFedSsVJs2LfMeKyQB5g
|
||||
|
||||
mosh-server (mosh 1.1)
|
||||
[...] (copyright notice omitted)
|
||||
|
||||
[mosh-server detached, pid = 20443]
|
||||
.fi
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR mosh (1),
|
||||
.BR mosh-client (1).
|
||||
|
||||
Project home page:
|
||||
.I http://mosh.mit.edu
|
||||
|
||||
.br
|
||||
.SH AUTHOR
|
||||
mosh was written by Keith Winstein <mosh-devel@mit.edu>.
|
||||
.SH BUGS
|
||||
Please report bugs to \fImosh-devel@mit.edu\fP. Users may also subscribe
|
||||
to the
|
||||
.nh
|
||||
.I mosh-users@mit.edu
|
||||
.hy
|
||||
mailing list, at
|
||||
.br
|
||||
.nh
|
||||
.I http://mailman.mit.edu/mailman/listinfo/mosh-users
|
||||
.hy
|
||||
.
|
||||
254
vendor/mosh/man/mosh.1
vendored
Normal file
254
vendor/mosh/man/mosh.1
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH MOSH 1 "April 2013"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.SH NAME
|
||||
mosh \- mobile shell with roaming and intelligent local echo
|
||||
.SH SYNOPSIS
|
||||
.B mosh
|
||||
.RI [ options ]
|
||||
[--]
|
||||
[user@]host
|
||||
[command...]
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
\fBmosh\fP (mobile shell) is a remote terminal application that
|
||||
supports intermittent connectivity, allows roaming, and provides
|
||||
speculative local echo and line editing of user keystrokes.
|
||||
|
||||
Compared with \fBssh\fP, \fBmosh\fP is more robust \(em its
|
||||
connections stay up across sleeps and changes in the client's IP
|
||||
address \(em and more responsive, because the protocol is tolerant of
|
||||
packet loss and the client can echo most keystrokes immediately,
|
||||
without waiting for a network round-trip.
|
||||
|
||||
\fBmosh\fP uses \fBssh\fP to establish a connection to the remote host
|
||||
and authenticate with existing means (e.g., public-key authentication
|
||||
or a password). \fBmosh\fP executes the unprivileged \fBmosh-server\fP
|
||||
helper program on the server, then closes the SSH connection and
|
||||
starts the \fBmosh-client\fP, which establishes a long-lived datagram
|
||||
connection over UDP.
|
||||
|
||||
To improve responsiveness, \fBmosh\fP runs a predictive model of the
|
||||
server's behavior in the background, trying to guess the effect of
|
||||
each keystroke on the screen. It makes predictions for normal typing,
|
||||
backspace, and the left- and right-arrow keys. When it is confident,
|
||||
\fBmosh\fP displays the predictions without waiting for the
|
||||
server. The predictive model must prove itself anew on each row of the
|
||||
terminal and after each control character, so \fBmosh\fP avoids
|
||||
echoing passwords or non-echoing editor commands.
|
||||
|
||||
By default, \fBmosh\fP shows its predictions only on high-latency
|
||||
connections and to smooth out network glitches. (On longer-latency
|
||||
links, the predicted cells are underlined until confirmed by the
|
||||
server.) Occasional echo mistakes are corrected within a network
|
||||
round-trip and do not cause lasting effect.
|
||||
|
||||
\fBmosh\fP does not support X forwarding or the non-interactive uses
|
||||
of SSH, including port forwarding or sshfs. \fBmosh\fP works through
|
||||
typical client-side network address translators but requires UDP to
|
||||
pass between client and server. By default, \fBmosh\fP uses the ports
|
||||
between 60000 and 61000, but allows the user to request a particular
|
||||
UDP port instead.
|
||||
|
||||
\fBmosh\fP will do its best to arrange a UTF-8 character set locale on
|
||||
the client and server. The client must have locale-related environment
|
||||
variables that specify UTF-8. \fBmosh\fP will pass these client
|
||||
variables to the \fBmosh-server\fP on its command line, but in most
|
||||
cases they will not need to be used. \fBmosh-server\fP first attempts
|
||||
to use its own locale-related environment variables, which come from
|
||||
the system default configuration (sometimes /etc/default/locale) or
|
||||
from having been passed over the SSH connection. But if these
|
||||
variables don't call for the use of UTF-8, \fBmosh-server\fP will
|
||||
apply the locale-related environment variables from the client and try
|
||||
again.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \fIcommand\fP
|
||||
Command to run on remote host. By default, \fBmosh\fP executes a login shell.
|
||||
|
||||
.TP
|
||||
.B \-\-client=\fIPATH\fP
|
||||
path to client helper on local machine (default: "mosh-client")
|
||||
|
||||
.TP
|
||||
.B \-\-server=\fICOMMAND\fP
|
||||
command to run server helper on remote machine (default: "mosh-server")
|
||||
|
||||
The server helper is unprivileged and can be installed in the user's
|
||||
home directory.
|
||||
|
||||
This option can be used to set environment variables for the server by
|
||||
using the
|
||||
.BR env (1)
|
||||
command to wrap the actual server command. See
|
||||
.BR mosh-server (1)
|
||||
for available environment variables.
|
||||
|
||||
.TP
|
||||
.B \-\-ssh=\fICOMMAND\fP
|
||||
OpenSSH command to remotely execute mosh-server on remote machine (default: "ssh")
|
||||
|
||||
An alternate ssh port can be specified with, \fIe.g.\fP, \-\-ssh="ssh \-p 2222".
|
||||
|
||||
.TP
|
||||
.B \-\-predict=\fIWHEN\fP
|
||||
Controls use of speculative local echo. WHEN defaults to `adaptive'
|
||||
(show predictions on slower links and to smooth out network glitches)
|
||||
and can also be `always` or `never'.
|
||||
|
||||
The MOSH_PREDICTION_DISPLAY environment variable controls this setting
|
||||
permanently and can adopt the same three values.
|
||||
|
||||
Even on `always', \fBmosh\fP will only show predictions when it is
|
||||
confident. This generally means a previous prediction on the same row
|
||||
of the terminal has been confirmed by the server, without any
|
||||
intervening control character keystrokes.
|
||||
|
||||
.TP
|
||||
.B \-a
|
||||
Synonym for \-\-predict=always
|
||||
|
||||
.TP
|
||||
.B \-n
|
||||
Synonym for \-\-predict=never
|
||||
|
||||
.TP
|
||||
.B --family=\fIFAMILY\fP
|
||||
Force the use of a particular address family, which defaults to `inet'
|
||||
(IPv4), and can also be `inet6' (IPv6; requires IO::Socket::IP or
|
||||
IO::Socket::INET6).
|
||||
|
||||
.TP
|
||||
.B -4
|
||||
Synonym for \-\-family=inet
|
||||
|
||||
.TP
|
||||
.B -6
|
||||
Synonym for \-\-family=inet6
|
||||
|
||||
.TP
|
||||
.B \-p \fIPORT\fP[:\fIPORT2\fP], \-\-port=\fIPORT\fP[:\fIPORT2\fP]
|
||||
Use a particular server-side UDP port or port range,
|
||||
for example, if this is the
|
||||
only port that is forwarded through a firewall to the
|
||||
server. Otherwise, \fBmosh\fP will choose a port between 60000 and
|
||||
61000.
|
||||
|
||||
.TP
|
||||
.B \-\-bind\-server={ssh|any|\fIIP\fP}
|
||||
Control the IP address that the \fBmosh-server\fP binds to.
|
||||
|
||||
The default is `ssh', in which case the server will reply from the IP
|
||||
address that the SSH connection came from (as found in the
|
||||
\fBSSH_CONNECTION\fP environment variable). This is useful for
|
||||
multihomed servers.
|
||||
|
||||
With \-\-bind\-server=any, the server will reply on the default interface
|
||||
and will not bind to a particular IP address. This can be useful if
|
||||
the connection is made through \fBsslh\fP or another tool that makes
|
||||
the SSH connection appear to come from localhost.
|
||||
|
||||
With \-\-bind\-server=\fIIP\fP, the server will attempt to bind to the
|
||||
specified IP address.
|
||||
|
||||
.TP
|
||||
.B \-\-no\-init
|
||||
Do not send the \fBsmcup\fP initialization string and \fBrmcup\fP
|
||||
deinitialization string to the client's terminal. On many terminals
|
||||
this disables alternate screen mode.
|
||||
|
||||
.TP
|
||||
.B \-\-local
|
||||
Invoke \fBmosh-server\fP locally, without using \fBssh\fP. This
|
||||
option requires the \fBhost\fP argument to be a local, numeric
|
||||
IPv4/IPv6 address. This option is useful for testing.
|
||||
|
||||
.SH ESCAPE SEQUENCES
|
||||
|
||||
The default escape character used by Mosh is ASCII RS (decimal 30).
|
||||
This is typically typed as \fBCtrl-^\fP or \fBCtrl-Shift-6\fP, on US
|
||||
English keyboards. Users of non-English keyboards may find it
|
||||
difficult or impossible to type the default escape character, and may
|
||||
need to change the escape character. See the description of
|
||||
MOSH_ESCAPE_KEY, below. In this description, the configured escape
|
||||
character is represented as \fBEsc\fP.
|
||||
|
||||
There are two slightly different modes for escape sequences, depending
|
||||
whether the escape character is printable or not.
|
||||
|
||||
If the escape character is a printable character, it must be prefixed
|
||||
with a newline, similar to \fBOpenSSH\fP. To send the escape character
|
||||
itself, type it twice. If the escape character is set to \fB~\fP,
|
||||
\fBmosh\fP will behave much like \fBOpenSSH\fP.
|
||||
|
||||
If the escape character is a non-printable control character, no
|
||||
prefix is used and the escape character is recognized at any time. To
|
||||
send the escape character itself, type the escape character, then its
|
||||
corresponding ASCII character (for \fBCtrl-^\fP you would type \fB^\fP,
|
||||
for \fBCtrl-B\fP you would type \fBB\fP).
|
||||
|
||||
The escape sequence to shut down the connection is
|
||||
\fBEsc .\fP. The sequence \fBEsc Ctrl-Z\fP suspends the client.
|
||||
Any other sequence passes both characters through to the server.
|
||||
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
These variables are not actually interpreted by
|
||||
.BR mosh (1)
|
||||
itself, but are passed through to
|
||||
.BR mosh-server (1).
|
||||
They are described here for ease of use.
|
||||
|
||||
.TP
|
||||
.B MOSH_ESCAPE_KEY
|
||||
When set, this configures the escape character used for local
|
||||
commands. The escape character may be set to any ASCII character in
|
||||
the range 1-127. The variable must be set with a single literal ASCII
|
||||
character. Control characters are set with the actual ASCII
|
||||
control character, not with a printable representation such as "^B".
|
||||
|
||||
.TP
|
||||
.B MOSH_PREDICTION_DISPLAY
|
||||
Controls local echo as described above. The command-line flag
|
||||
overrides this variable.
|
||||
|
||||
.TP
|
||||
.B MOSH_TITLE_NOPREFIX
|
||||
When set, inhibits prepending "[mosh]" to window title.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR mosh-client (1),
|
||||
.BR mosh-server (1).
|
||||
|
||||
Project home page:
|
||||
.I http://mosh.mit.edu
|
||||
|
||||
.br
|
||||
.SH AUTHOR
|
||||
mosh was written by Keith Winstein <mosh-devel@mit.edu>.
|
||||
.SH BUGS
|
||||
Please report bugs to \fImosh-devel@mit.edu\fP. Users may also subscribe
|
||||
to the
|
||||
.nh
|
||||
.I mosh-users@mit.edu
|
||||
.hy
|
||||
mailing list, at
|
||||
.br
|
||||
.nh
|
||||
.I http://mailman.mit.edu/mailman/listinfo/mosh-users
|
||||
.hy
|
||||
.
|
||||
47
vendor/mosh/ocb-license.html
vendored
Normal file
47
vendor/mosh/ocb-license.html
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<TITLE>OCB - An Authenticated-Encryption Scheme - GPL Patent Grant - Rogaway</TITLE>
|
||||
|
||||
<body bgcolor="#FFFFFF">
|
||||
<H2><a name="ocb-grant"> <font face="Arial, Helvetica, sans-serif" size="6" color="#FF0000">OCB:
|
||||
Patent Grant for GNU GPL</font> </a> </H2>
|
||||
|
||||
Whereas I, Phillip Rogaway (hereinafter "Inventor") have sought
|
||||
patent protection for certain technology
|
||||
(hereinafter "Patented Technology"),
|
||||
and Inventor wishes to aid the Free Software Foundation in achieving its goals,
|
||||
and Inventor wishes to increase public awareness of Patented Technology,
|
||||
Inventor hereby grants a fully paid-up, nonexclusive,
|
||||
royalty-free license to
|
||||
practice any patents claiming priority to the
|
||||
patent applications below ("the Patents")
|
||||
if practiced by
|
||||
software distributed
|
||||
under the terms of any version of
|
||||
the GNU General Public License as published by the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111.
|
||||
Inventor reserves all other rights, including without limitation
|
||||
licensing for software not distributed under the GNU General Public License.
|
||||
|
||||
<h4>The patents:</h4>
|
||||
|
||||
|
||||
<ul>
|
||||
<li> <a href="http://appft1.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&Sect2=HITOFF&p=1&u=%2Fnetahtml%2FPTO%2Fsearch-bool.html&r=2&f=G&l=50&co1=AND&d=PG01&s1=rogaway.IN.&OS=IN/rogaway&RS=IN/rogaway">
|
||||
09/918,615</a> -
|
||||
Method and Apparatus for Facilitating Efficient Authenticated Encryption.
|
||||
|
||||
<li> <a href="http://appft1.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&Sect2=HITOFF&p=1&u=%2Fnetahtml%2FPTO%2Fsearch-bool.html&r=3&f=G&l=50&co1=AND&d=PG01&s1=rogaway.IN.&OS=IN/rogaway&RS=IN/rogaway">
|
||||
09/948,084</a> -
|
||||
Method and Apparatus for Realizing a Parallelizable Variable-Input-Length
|
||||
Pseudorandom Function.
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<p><b>June 12, 2012</b>: Phillip Rogaway licensed the distribution of OCB
|
||||
in Mosh under the GPL with the OpenSSL linking exception and iOS
|
||||
waiver contained in the <code>COPYING.iOS</code> file.</p>
|
||||
|
||||
<blockquote>
|
||||
"Mosh with the two GPL exemptions you specify in the attached note
|
||||
is freely licensed to use for any OCB-related IP that I own."
|
||||
</blockquote>
|
||||
9
vendor/mosh/scripts/Makefile.am
vendored
Normal file
9
vendor/mosh/scripts/Makefile.am
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
EXTRA_DIST = wrap-compiler-for-flag-check mosh.pl
|
||||
if BUILD_CLIENT
|
||||
bin_SCRIPTS = mosh
|
||||
endif
|
||||
CLEANFILES = $(bin_SCRIPTS)
|
||||
|
||||
mosh: mosh.pl ../VERSION Makefile
|
||||
@sed -e "s/\@VERSION\@/`cat ../VERSION`/" -e "s/\@PACKAGE_STRING\@/@PACKAGE_STRING@/" $(srcdir)/mosh.pl > mosh
|
||||
@chmod a+x mosh
|
||||
362
vendor/mosh/scripts/mosh.pl
vendored
Executable file
362
vendor/mosh/scripts/mosh.pl
vendored
Executable file
@@ -0,0 +1,362 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# Mosh: the mobile shell
|
||||
# Copyright 2012 Keith Winstein
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# In addition, as a special exception, the copyright holders give
|
||||
# permission to link the code of portions of this program with the
|
||||
# OpenSSL library under certain conditions as described in each
|
||||
# individual source file, and distribute linked combinations including
|
||||
# the two.
|
||||
#
|
||||
# You must obey the GNU General Public License in all respects for all
|
||||
# of the code used other than OpenSSL. If you modify file(s) with this
|
||||
# exception, you may extend this exception to your version of the
|
||||
# file(s), but you are not obligated to do so. If you do not wish to do
|
||||
# so, delete this exception statement from your version. If you delete
|
||||
# this exception statement from all source files in the program, then
|
||||
# also delete it here.
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use IO::Socket;
|
||||
use Text::ParseWords;
|
||||
|
||||
$|=1;
|
||||
|
||||
my $client = 'mosh-client';
|
||||
my $server = 'mosh-server';
|
||||
|
||||
my $predict = undef;
|
||||
|
||||
my $bind_ip = undef;
|
||||
|
||||
my $family = 'inet';
|
||||
my $port_request = undef;
|
||||
|
||||
my @ssh = ('ssh');
|
||||
|
||||
my $term_init = 1;
|
||||
|
||||
my $localhost = undef;
|
||||
|
||||
my $help = undef;
|
||||
my $version = undef;
|
||||
|
||||
my @cmdline = @ARGV;
|
||||
|
||||
my $usage =
|
||||
qq{Usage: $0 [options] [--] [user@]host [command...]
|
||||
--client=PATH mosh client on local machine
|
||||
(default: "mosh-client")
|
||||
--server=COMMAND mosh server on remote machine
|
||||
(default: "mosh-server")
|
||||
|
||||
--predict=adaptive local echo for slower links [default]
|
||||
-a --predict=always use local echo even on fast links
|
||||
-n --predict=never never use local echo
|
||||
--predict=experimental aggressively echo even when incorrect
|
||||
|
||||
-4 --family=inet use IPv4 only [default]
|
||||
-6 --family=inet6 use IPv6 only
|
||||
-p PORT[:PORT2]
|
||||
--port=PORT[:PORT2] server-side UDP port or range
|
||||
--bind-server={ssh|any|IP} ask the server to reply from an IP address
|
||||
(default: "ssh")
|
||||
|
||||
--ssh=COMMAND ssh command to run when setting up session
|
||||
(example: "ssh -p 2222")
|
||||
(default: "ssh")
|
||||
|
||||
--no-init do not send terminal initialization string
|
||||
|
||||
--local run mosh-server locally without using ssh
|
||||
|
||||
--help this message
|
||||
--version version and copyright information
|
||||
|
||||
Please report bugs to mosh-devel\@mit.edu.
|
||||
Mosh home page: http://mosh.mit.edu\n};
|
||||
|
||||
my $version_message = '@PACKAGE_STRING@ [build @VERSION@]' . qq{
|
||||
Copyright 2012 Keith Winstein <mosh-devel\@mit.edu>
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.\n};
|
||||
|
||||
sub predict_check {
|
||||
my ( $predict, $env_set ) = @_;
|
||||
|
||||
if ( not exists { adaptive => 0, always => 0,
|
||||
never => 0, experimental => 0 }->{ $predict } ) {
|
||||
my $explanation = $env_set ? " (MOSH_PREDICTION_DISPLAY in environment)" : "";
|
||||
print STDERR qq{$0: Unknown mode \"$predict\"$explanation.\n\n};
|
||||
|
||||
die $usage;
|
||||
}
|
||||
}
|
||||
|
||||
GetOptions( 'client=s' => \$client,
|
||||
'server=s' => \$server,
|
||||
'predict=s' => \$predict,
|
||||
'port=s' => \$port_request,
|
||||
'a' => sub { $predict = 'always' },
|
||||
'n' => sub { $predict = 'never' },
|
||||
'family=s' => \$family,
|
||||
'4' => sub { $family = 'inet' },
|
||||
'6' => sub { $family = 'inet6' },
|
||||
'p=s' => \$port_request,
|
||||
'ssh=s' => sub { @ssh = shellwords($_[1]); },
|
||||
'init!' => \$term_init,
|
||||
'local' => \$localhost,
|
||||
'help' => \$help,
|
||||
'version' => \$version,
|
||||
'fake-proxy!' => \my $fake_proxy,
|
||||
'bind-server=s' => \$bind_ip) or die $usage;
|
||||
|
||||
die $usage if ( defined $help );
|
||||
die $version_message if ( defined $version );
|
||||
|
||||
if ( defined $predict ) {
|
||||
predict_check( $predict, 0 );
|
||||
} elsif ( defined $ENV{ 'MOSH_PREDICTION_DISPLAY' } ) {
|
||||
$predict = $ENV{ 'MOSH_PREDICTION_DISPLAY' };
|
||||
predict_check( $predict, 1 );
|
||||
} else {
|
||||
$predict = 'adaptive';
|
||||
predict_check( $predict, 0 );
|
||||
}
|
||||
|
||||
if ( defined $port_request ) {
|
||||
if ( $port_request =~ m{^(\d+)(:(\d+))?$} ) {
|
||||
my ( $low, $clause, $high ) = ( $1, $2, $3 );
|
||||
# good port or port-range
|
||||
if ( $low <= 0 or $low > 65535 ) {
|
||||
die "$0: Server-side (low) port ($low) must be within valid range [1..65535].\n";
|
||||
}
|
||||
if ( defined $high ) {
|
||||
if ( $high <= 0 or $high > 65535 ) {
|
||||
die "$0: Server-side high port ($high) must be within valid range [1..65535].\n";
|
||||
}
|
||||
if ( $low > $high ) {
|
||||
die "$0: Server-side port range ($port_request): low port greater than high port.\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
die "$0: Server-side port or range ($port_request) is not valid.\n";
|
||||
}
|
||||
}
|
||||
|
||||
delete $ENV{ 'MOSH_PREDICTION_DISPLAY' };
|
||||
|
||||
my $userhost;
|
||||
my @command;
|
||||
my @bind_arguments;
|
||||
|
||||
if ( ! defined $fake_proxy ) {
|
||||
if ( scalar @ARGV < 1 ) {
|
||||
die $usage;
|
||||
}
|
||||
$userhost = shift;
|
||||
@command = @ARGV;
|
||||
if ( not defined $bind_ip or $bind_ip =~ m{^ssh$}i ) {
|
||||
if ( not defined $localhost ) {
|
||||
push @bind_arguments, '-s';
|
||||
} else {
|
||||
push @bind_arguments, ('-i', "$userhost");
|
||||
}
|
||||
} elsif ( $bind_ip =~ m{^any$}i ) {
|
||||
# do nothing
|
||||
} elsif ( $bind_ip =~ m{^[0-9\.]+$} ) {
|
||||
push @bind_arguments, ('-i', "$bind_ip");
|
||||
} else {
|
||||
print STDERR qq{$0: Unknown server binding option: $bind_ip\n};
|
||||
|
||||
die $usage;
|
||||
}
|
||||
} else {
|
||||
my ( $host, $port ) = @ARGV;
|
||||
|
||||
use Errno qw(EINTR);
|
||||
my $have_ipv6 = eval {
|
||||
require IO::Socket::IP;
|
||||
IO::Socket::IP->import('-register');
|
||||
1;
|
||||
} || eval {
|
||||
require IO::Socket::INET6;
|
||||
1;
|
||||
};
|
||||
use POSIX qw(_exit);
|
||||
|
||||
# Report failure if IPv6 needed and not available.
|
||||
if (lc($family) eq "inet6") {
|
||||
if (!$have_ipv6) {
|
||||
die "$0: IPv6 sockets not available in this Perl install\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Resolve hostname and connect
|
||||
my $afstr = 'AF_' . uc( $family );
|
||||
my $af = eval { IO::Socket->$afstr } or die "$0: Invalid family $family\n";
|
||||
my $sock = IO::Socket->new( Domain => $af,
|
||||
Family => $af,
|
||||
PeerHost => $host,
|
||||
PeerPort => $port,
|
||||
Proto => "tcp" )
|
||||
or die "$0: Could not connect to $host: $@\n";
|
||||
|
||||
print STDERR "MOSH IP ", $sock->peerhost, "\n";
|
||||
|
||||
# Act like netcat
|
||||
binmode($sock);
|
||||
binmode(STDIN);
|
||||
binmode(STDOUT);
|
||||
|
||||
sub cat {
|
||||
my ( $from, $to ) = @_;
|
||||
while ( my $n = $from->sysread( my $buf, 4096 ) ) {
|
||||
next if ( $n == -1 && $! == EINTR );
|
||||
$n >= 0 or last;
|
||||
$to->write( $buf ) or last;
|
||||
}
|
||||
}
|
||||
|
||||
defined( my $pid = fork ) or die "$0: fork: $!\n";
|
||||
if ( $pid == 0 ) {
|
||||
close STDIN;
|
||||
cat $sock, \*STDOUT; $sock->shutdown( 0 );
|
||||
_exit 0;
|
||||
}
|
||||
$SIG{ 'HUP' } = 'IGNORE';
|
||||
close STDOUT;
|
||||
cat \*STDIN, $sock; $sock->shutdown( 1 );
|
||||
close STDIN;
|
||||
waitpid $pid, 0;
|
||||
exit;
|
||||
}
|
||||
|
||||
# Count colors
|
||||
open COLORCOUNT, '-|', $client, ('-c') or die "Can't count colors: $!\n";
|
||||
my $colors = "";
|
||||
{
|
||||
local $/ = undef;
|
||||
$colors = <COLORCOUNT>;
|
||||
}
|
||||
close COLORCOUNT or die;
|
||||
|
||||
chomp $colors;
|
||||
|
||||
if ( (not defined $colors)
|
||||
or $colors !~ m{^[0-9]+$}
|
||||
or $colors < 0 ) {
|
||||
$colors = 0;
|
||||
}
|
||||
|
||||
$ENV{ 'MOSH_CLIENT_PID' } = $$; # We don't support this, but it's useful for test and debug.
|
||||
|
||||
my $pid = open(my $pipe, "-|");
|
||||
die "$0: fork: $!\n" unless ( defined $pid );
|
||||
if ( $pid == 0 ) { # child
|
||||
open(STDERR, ">&STDOUT") or die;
|
||||
|
||||
my @server = ( 'new' );
|
||||
|
||||
push @server, ( '-c', $colors );
|
||||
|
||||
push @server, @bind_arguments;
|
||||
|
||||
if ( defined $port_request ) {
|
||||
push @server, ( '-p', $port_request );
|
||||
}
|
||||
|
||||
for ( &locale_vars ) {
|
||||
push @server, ( '-l', $_ );
|
||||
}
|
||||
|
||||
if ( scalar @command > 0 ) {
|
||||
push @server, '--', @command;
|
||||
}
|
||||
|
||||
if ( defined( $localhost )) {
|
||||
delete $ENV{ 'SSH_CONNECTION' };
|
||||
chdir; # $HOME
|
||||
print "MOSH IP ${userhost}\n";
|
||||
exec( $server, @server );
|
||||
die "Cannot exec $server: $!\n";
|
||||
}
|
||||
my $quoted_self = shell_quote( $0, "--family=$family" );
|
||||
exec @ssh, '-S', 'none', '-o', "ProxyCommand=$quoted_self --fake-proxy -- %h %p", '-n', '-tt', $userhost, '--', "$server " . shell_quote( @server );
|
||||
die "Cannot exec ssh: $!\n";
|
||||
} else { # parent
|
||||
my ( $ip, $port, $key );
|
||||
my $bad_udp_port_warning = 0;
|
||||
LINE: while ( <$pipe> ) {
|
||||
chomp;
|
||||
if ( m{^MOSH IP } ) {
|
||||
if ( defined $ip ) {
|
||||
die "$0 error: detected attempt to redefine MOSH IP.\n";
|
||||
}
|
||||
( $ip ) = m{^MOSH IP (\S+)\s*$} or die "Bad MOSH IP string: $_\n";
|
||||
} elsif ( m{^MOSH CONNECT } ) {
|
||||
if ( ( $port, $key ) = m{^MOSH CONNECT (\d+?) ([A-Za-z0-9/+]{22})\s*$} ) {
|
||||
last LINE;
|
||||
} else {
|
||||
die "Bad MOSH CONNECT string: $_\n";
|
||||
}
|
||||
} else {
|
||||
if ( defined $port_request and $port_request =~ m{:} and m{Bad UDP port} ) {
|
||||
$bad_udp_port_warning = 1;
|
||||
}
|
||||
print "$_\n";
|
||||
}
|
||||
}
|
||||
waitpid $pid, 0;
|
||||
close $pipe;
|
||||
|
||||
if ( not defined $ip ) {
|
||||
die "$0: Did not find remote IP address (is SSH ProxyCommand disabled?).\n";
|
||||
}
|
||||
|
||||
if ( not defined $key or not defined $port ) {
|
||||
if ( $bad_udp_port_warning ) {
|
||||
die "$0: Server does not support UDP port range option.\n";
|
||||
}
|
||||
die "$0: Did not find mosh server startup message.\n";
|
||||
}
|
||||
|
||||
# Now start real mosh client
|
||||
$ENV{ 'MOSH_KEY' } = $key;
|
||||
$ENV{ 'MOSH_PREDICTION_DISPLAY' } = $predict;
|
||||
$ENV{ 'MOSH_NO_TERM_INIT' } = '1' if !$term_init;
|
||||
exec {$client} ("$client @cmdline |", $ip, $port);
|
||||
}
|
||||
|
||||
sub shell_quote { join ' ', map {(my $a = $_) =~ s/'/'\\''/g; "'$a'"} @_ }
|
||||
|
||||
sub locale_vars {
|
||||
my @names = qw[LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION LC_ALL];
|
||||
|
||||
my @assignments;
|
||||
|
||||
for ( @names ) {
|
||||
if ( defined $ENV{ $_ } ) {
|
||||
push @assignments, $_ . q{=} . $ENV{ $_ };
|
||||
}
|
||||
}
|
||||
|
||||
return @assignments;
|
||||
}
|
||||
22
vendor/mosh/scripts/wrap-compiler-for-flag-check
vendored
Executable file
22
vendor/mosh/scripts/wrap-compiler-for-flag-check
vendored
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
|
||||
# There is no way to make clang's "argument unused" warning fatal. So when
|
||||
# configure checks for supported flags, it runs $CC, $CXX, $LD via this
|
||||
# wrapper.
|
||||
#
|
||||
# Ideally the search string would also include 'clang: ' but this output might
|
||||
# depend on clang's argv[0].
|
||||
|
||||
if out=`"$@" 2>&1`; then
|
||||
echo "$out"
|
||||
if echo "$out" | grep 'warning: argument unused' >/dev/null; then
|
||||
echo "$0: found clang warning"
|
||||
exit 1
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
code=$?
|
||||
echo "$out"
|
||||
exit $code
|
||||
fi
|
||||
1
vendor/mosh/src/Makefile.am
vendored
Normal file
1
vendor/mosh/src/Makefile.am
vendored
Normal file
@@ -0,0 +1 @@
|
||||
SUBDIRS = protobufs util crypto terminal network statesync frontend examples tests
|
||||
17
vendor/mosh/src/crypto/Makefile.am
vendored
Normal file
17
vendor/mosh/src/crypto/Makefile.am
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
AM_CPPFLAGS = -I$(srcdir)/../util $(CRYPTO_CFLAGS)
|
||||
AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS)
|
||||
|
||||
noinst_LIBRARIES = libmoshcrypto.a
|
||||
|
||||
OCB_SRCS = \
|
||||
ae.h \
|
||||
ocb.cc
|
||||
|
||||
libmoshcrypto_a_SOURCES = \
|
||||
$(OCB_SRCS) \
|
||||
base64.cc \
|
||||
base64.h \
|
||||
byteorder.h \
|
||||
crypto.cc \
|
||||
crypto.h \
|
||||
prng.h
|
||||
182
vendor/mosh/src/crypto/ae.h
vendored
Normal file
182
vendor/mosh/src/crypto/ae.h
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
/* ---------------------------------------------------------------------------
|
||||
*
|
||||
* AEAD API 0.12 - 13 July 2011
|
||||
*
|
||||
* This file gives an interface appropriate for many authenticated
|
||||
* encryption with associated data (AEAD) implementations. It does not try
|
||||
* to accommodate all possible options or limitations that an implementation
|
||||
* might have -- you should consult the documentation of your chosen
|
||||
* implementation to find things like RFC 5116 constants, alignment
|
||||
* requirements, whether the incremental interface is supported, etc.
|
||||
*
|
||||
* This file is in the public domain. It is provided "as is", without
|
||||
* warranty of any kind. Use at your own risk.
|
||||
*
|
||||
* Comments are welcome: Ted Krovetz <ted@krovetz>.
|
||||
*
|
||||
* ------------------------------------------------------------------------ */
|
||||
|
||||
#ifndef _AE_H_
|
||||
#define _AE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
*
|
||||
* Constants
|
||||
*
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
/* Return status codes: Negative return values indicate an error occurred.
|
||||
* For full explanations of error values, consult the implementation's
|
||||
* documentation. */
|
||||
#define AE_SUCCESS ( 0) /* Indicates successful completion of call */
|
||||
#define AE_INVALID (-1) /* Indicates bad tag during decryption */
|
||||
#define AE_NOT_SUPPORTED (-2) /* Indicates unsupported option requested */
|
||||
|
||||
/* Flags: When data can be processed "incrementally", these flags are used
|
||||
* to indicate whether the submitted data is the last or not. */
|
||||
#define AE_FINALIZE (1) /* This is the last of data */
|
||||
#define AE_PENDING (0) /* More data of is coming */
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
*
|
||||
* AEAD opaque structure definition
|
||||
*
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
typedef struct _ae_ctx ae_ctx;
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
*
|
||||
* Data Structure Routines
|
||||
*
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
ae_ctx* ae_allocate (void *misc); /* Allocate ae_ctx, set optional ptr */
|
||||
void ae_free (ae_ctx *ctx); /* Deallocate ae_ctx struct */
|
||||
int ae_clear (ae_ctx *ctx); /* Undo initialization */
|
||||
int ae_ctx_sizeof(void); /* Return sizeof(ae_ctx) */
|
||||
/* ae_allocate() allocates an ae_ctx structure, but does not initialize it.
|
||||
* ae_free() deallocates an ae_ctx structure, but does not zeroize it.
|
||||
* ae_clear() zeroes sensitive values associated with an ae_ctx structure
|
||||
* and deallocates any auxiliary structures allocated during ae_init().
|
||||
* ae_ctx_sizeof() returns sizeof(ae_ctx), to aid in any static allocations.
|
||||
*/
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
*
|
||||
* AEAD Routines
|
||||
*
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
int ae_init(ae_ctx *ctx,
|
||||
const void *key,
|
||||
int key_len,
|
||||
int nonce_len,
|
||||
int tag_len);
|
||||
/* --------------------------------------------------------------------------
|
||||
*
|
||||
* Initialize an ae_ctx context structure.
|
||||
*
|
||||
* Parameters:
|
||||
* ctx - Pointer to an ae_ctx structure to be initialized
|
||||
* key - Pointer to user-supplied key
|
||||
* key_len - Length of key supplied, in bytes
|
||||
* nonce_len - Length of nonces to be used for this key, in bytes
|
||||
* tag_len - Length of tags to be produced for this key, in bytes
|
||||
*
|
||||
* Returns:
|
||||
* AE_SUCCESS - Success. Ctx ready for use.
|
||||
* AE_NOT_SUPPORTED - An unsupported length was supplied. Ctx is untouched.
|
||||
* Otherwise - Error. Check implementation documentation for codes.
|
||||
*
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
int ae_encrypt(ae_ctx *ctx,
|
||||
const void *nonce,
|
||||
const void *pt,
|
||||
int pt_len,
|
||||
const void *ad,
|
||||
int ad_len,
|
||||
void *ct,
|
||||
void *tag,
|
||||
int final);
|
||||
/* --------------------------------------------------------------------------
|
||||
*
|
||||
* Encrypt plaintext; provide for authentication of ciphertext/associated data.
|
||||
*
|
||||
* Parameters:
|
||||
* ctx - Pointer to an ae_ctx structure initialized by ae_init.
|
||||
* nonce - Pointer to a nonce_len (defined in ae_init) byte nonce.
|
||||
* pt - Pointer to plaintext bytes to be encrypted.
|
||||
* pt_len - number of bytes pointed to by pt.
|
||||
* ad - Pointer to associated data.
|
||||
* ad_len - number of bytes pointed to by ad.
|
||||
* ct - Pointer to buffer to receive ciphertext encryption.
|
||||
* tag - Pointer to receive authentication tag; or NULL
|
||||
* if tag is to be bundled into the ciphertext.
|
||||
* final - Non-zero if this call completes the plaintext being encrypted.
|
||||
*
|
||||
* If nonce!=NULL then a message is being initiated. If final!=0
|
||||
* then a message is being finalized. If final==0 or nonce==NULL
|
||||
* then the incremental interface is being used. If nonce!=NULL and
|
||||
* ad_len<0, then use same ad as last message.
|
||||
*
|
||||
* Returns:
|
||||
* non-negative - Number of bytes written to ct.
|
||||
* AE_NOT_SUPPORTED - Usage mode unsupported (eg, incremental and/or sticky).
|
||||
* Otherwise - Error. Check implementation documentation for codes.
|
||||
*
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
int ae_decrypt(ae_ctx *ctx,
|
||||
const void *nonce,
|
||||
const void *ct,
|
||||
int ct_len,
|
||||
const void *ad,
|
||||
int ad_len,
|
||||
void *pt,
|
||||
const void *tag,
|
||||
int final);
|
||||
/* --------------------------------------------------------------------------
|
||||
*
|
||||
* Decrypt ciphertext; provide authenticity of plaintext and associated data.
|
||||
*
|
||||
* Parameters:
|
||||
* ctx - Pointer to an ae_ctx structure initialized by ae_init.
|
||||
* nonce - Pointer to a nonce_len (defined in ae_init) byte nonce.
|
||||
* ct - Pointer to ciphertext bytes to be decrypted.
|
||||
* ct_len - number of bytes pointed to by ct.
|
||||
* ad - Pointer to associated data.
|
||||
* ad_len - number of bytes pointed to by ad.
|
||||
* pt - Pointer to buffer to receive plaintext decryption.
|
||||
* tag - Pointer to tag_len (defined in ae_init) bytes; or NULL
|
||||
* if tag is bundled into the ciphertext. Non-NULL tag is only
|
||||
* read when final is non-zero.
|
||||
* final - Non-zero if this call completes the ciphertext being decrypted.
|
||||
*
|
||||
* If nonce!=NULL then "ct" points to the start of a ciphertext. If final!=0
|
||||
* then "in" points to the final piece of ciphertext. If final==0 or nonce==
|
||||
* NULL then the incremental interface is being used. If nonce!=NULL and
|
||||
* ad_len<0, then use same ad as last message.
|
||||
*
|
||||
* Returns:
|
||||
* non-negative - Number of bytes written to pt.
|
||||
* AE_INVALID - Authentication failure.
|
||||
* AE_NOT_SUPPORTED - Usage mode unsupported (eg, incremental and/or sticky).
|
||||
* Otherwise - Error. Check implementation documentation for codes.
|
||||
*
|
||||
* NOTE !!! NOTE !!! -- The ciphertext should be assumed possibly inauthentic
|
||||
* until it has been completely written and it is
|
||||
* verified that this routine did not return AE_INVALID.
|
||||
*
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* closing brace for extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* _AE_H_ */
|
||||
113
vendor/mosh/src/crypto/base64.cc
vendored
Normal file
113
vendor/mosh/src/crypto/base64.cc
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fatal_assert.h"
|
||||
#include "base64.h"
|
||||
|
||||
static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/* Reverse maps from an ASCII char to a base64 sixbit value. Returns > 0x3f on failure. */
|
||||
static unsigned char base64_char_to_sixbit(char c)
|
||||
{
|
||||
/*
|
||||
* Yes, this is slow. But it's also very simple, and easy to verify.
|
||||
* We don't need performance here.
|
||||
*/
|
||||
const char *match = NULL;
|
||||
for ( const char *search = table; *search; search++ ) {
|
||||
if ( *search == c ) {
|
||||
match = search;
|
||||
}
|
||||
}
|
||||
if ( !match ) {
|
||||
return 0xff;
|
||||
}
|
||||
return match - table;
|
||||
}
|
||||
|
||||
bool base64_decode( const char *b64, const size_t b64_len,
|
||||
uint8_t *raw, size_t *raw_len )
|
||||
{
|
||||
fatal_assert( b64_len == 24 ); /* only useful for Mosh keys */
|
||||
fatal_assert( *raw_len == 16 );
|
||||
|
||||
uint32_t bytes = 0;
|
||||
for (int i = 0; i < 22; i++) {
|
||||
unsigned char sixbit = base64_char_to_sixbit(*(b64++));
|
||||
if (sixbit > 0x3f) {
|
||||
return false;
|
||||
}
|
||||
bytes <<= 6;
|
||||
bytes |= sixbit;
|
||||
/* write groups of 3 */
|
||||
if (i % 4 == 3) {
|
||||
raw[0] = bytes >> 16;
|
||||
raw[1] = bytes >> 8;
|
||||
raw[2] = bytes;
|
||||
raw += 3;
|
||||
bytes = 0;
|
||||
}
|
||||
}
|
||||
/* last byte of output */
|
||||
*raw = bytes >> 4;
|
||||
if (b64[0] != '=' || b64[1] != '=') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void base64_encode( const uint8_t *raw, const size_t raw_len,
|
||||
char *b64, const size_t b64_len )
|
||||
{
|
||||
fatal_assert( b64_len == 24 ); /* only useful for Mosh keys */
|
||||
fatal_assert( raw_len == 16 );
|
||||
|
||||
/* first 15 bytes of input */
|
||||
for (int i = 0; i < 5; i++) {
|
||||
uint32_t bytes = (raw[0] << 16) | (raw[1] << 8) | raw[2];
|
||||
b64[0] = table[(bytes >> 18) & 0x3f];
|
||||
b64[1] = table[(bytes >> 12) & 0x3f];
|
||||
b64[2] = table[(bytes >> 6) & 0x3f];
|
||||
b64[3] = table[(bytes) & 0x3f];
|
||||
raw += 3;
|
||||
b64 += 4;
|
||||
}
|
||||
|
||||
/* last byte of input, last 4 of output */
|
||||
b64[0] = table[*raw >> 2];
|
||||
b64[1] = table[(*raw << 4) & 0x3f];
|
||||
b64[2] = '=';
|
||||
b64[3] = '=';
|
||||
}
|
||||
39
vendor/mosh/src/crypto/base64.h
vendored
Normal file
39
vendor/mosh/src/crypto/base64.h
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
bool base64_decode( const char *b64, const size_t b64_len,
|
||||
uint8_t *raw, size_t *raw_len );
|
||||
|
||||
void base64_encode( const uint8_t *raw, const size_t raw_len,
|
||||
char *b64, const size_t b64_len );
|
||||
131
vendor/mosh/src/crypto/byteorder.h
vendored
Normal file
131
vendor/mosh/src/crypto/byteorder.h
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#ifndef BYTEORDER_HPP
|
||||
#define BYTEORDER_HPP
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_DECL_BE64TOH || HAVE_DECL_BETOH64
|
||||
|
||||
# if defined(HAVE_ENDIAN_H)
|
||||
# include <endian.h>
|
||||
# elif defined(HAVE_SYS_ENDIAN_H)
|
||||
# include <sys/types.h>
|
||||
# include <sys/endian.h>
|
||||
# endif
|
||||
|
||||
#if !HAVE_DECL_BE64TOH && HAVE_DECL_BETOH64
|
||||
#define be64toh betoh64
|
||||
#define be16toh betoh16
|
||||
#endif
|
||||
|
||||
#elif HAVE_OSX_SWAP
|
||||
# include <libkern/OSByteOrder.h>
|
||||
# define htobe64 OSSwapHostToBigInt64
|
||||
# define be64toh OSSwapBigToHostInt64
|
||||
# define htobe16 OSSwapHostToBigInt16
|
||||
# define be16toh OSSwapBigToHostInt16
|
||||
|
||||
#else
|
||||
|
||||
/* Use our fallback implementation, which is correct for any endianness. */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Make sure they aren't macros */
|
||||
#undef htobe64
|
||||
#undef be64toh
|
||||
#undef htobe16
|
||||
#undef be16toh
|
||||
|
||||
/* Use unions rather than casts, to comply with strict aliasing rules. */
|
||||
|
||||
inline uint64_t htobe64( uint64_t x ) {
|
||||
uint8_t xs[ 8 ] = {
|
||||
( x >> 56 ) & 0xFF,
|
||||
( x >> 48 ) & 0xFF,
|
||||
( x >> 40 ) & 0xFF,
|
||||
( x >> 32 ) & 0xFF,
|
||||
( x >> 24 ) & 0xFF,
|
||||
( x >> 16 ) & 0xFF,
|
||||
( x >> 8 ) & 0xFF,
|
||||
x & 0xFF };
|
||||
union {
|
||||
const uint8_t *p8;
|
||||
const uint64_t *p64;
|
||||
} u;
|
||||
u.p8 = xs;
|
||||
return *u.p64;
|
||||
}
|
||||
|
||||
inline uint64_t be64toh( uint64_t x ) {
|
||||
union {
|
||||
const uint8_t *p8;
|
||||
const uint64_t *p64;
|
||||
} u;
|
||||
u.p64 = &x;
|
||||
return ( uint64_t( u.p8[ 0 ] ) << 56 )
|
||||
| ( uint64_t( u.p8[ 1 ] ) << 48 )
|
||||
| ( uint64_t( u.p8[ 2 ] ) << 40 )
|
||||
| ( uint64_t( u.p8[ 3 ] ) << 32 )
|
||||
| ( uint64_t( u.p8[ 4 ] ) << 24 )
|
||||
| ( uint64_t( u.p8[ 5 ] ) << 16 )
|
||||
| ( uint64_t( u.p8[ 6 ] ) << 8 )
|
||||
| ( uint64_t( u.p8[ 7 ] ) );
|
||||
}
|
||||
|
||||
inline uint16_t htobe16( uint16_t x ) {
|
||||
uint8_t xs[ 2 ] = {
|
||||
( x >> 8 ) & 0xFF,
|
||||
x & 0xFF };
|
||||
union {
|
||||
const uint8_t *p8;
|
||||
const uint16_t *p16;
|
||||
} u;
|
||||
u.p8 = xs;
|
||||
return *u.p16;
|
||||
}
|
||||
|
||||
inline uint16_t be16toh( uint16_t x ) {
|
||||
union {
|
||||
const uint8_t *p8;
|
||||
const uint16_t *p16;
|
||||
} u;
|
||||
u.p16 = &x;
|
||||
return ( uint16_t( u.p8[ 0 ] ) << 8 )
|
||||
| ( uint16_t( u.p8[ 1 ] ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
320
vendor/mosh/src/crypto/crypto.cc
vendored
Normal file
320
vendor/mosh/src/crypto/crypto.cc
vendored
Normal file
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <sys/resource.h>
|
||||
#include <fstream>
|
||||
|
||||
#include "byteorder.h"
|
||||
#include "crypto.h"
|
||||
#include "base64.h"
|
||||
#include "prng.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Crypto;
|
||||
|
||||
long int myatoi( const char *str )
|
||||
{
|
||||
char *end;
|
||||
|
||||
errno = 0;
|
||||
long int ret = strtol( str, &end, 10 );
|
||||
|
||||
if ( ( errno != 0 )
|
||||
|| ( end != str + strlen( str ) ) ) {
|
||||
throw CryptoException( "Bad integer." );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AlignedBuffer::AlignedBuffer( size_t len, const char *data )
|
||||
: m_len( len ), m_allocated( NULL ), m_data( NULL )
|
||||
{
|
||||
#if defined(HAVE_POSIX_MEMALIGN)
|
||||
if ( ( 0 != posix_memalign( &m_allocated, 16, len ) )
|
||||
|| ( m_allocated == NULL ) ) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
m_data = (char *) m_allocated;
|
||||
|
||||
#else
|
||||
/* malloc() a region 15 bytes larger than we need, and find
|
||||
the aligned offset within. */
|
||||
m_allocated = malloc( 15 + len );
|
||||
if ( m_allocated == NULL ) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
uintptr_t iptr = (uintptr_t) m_allocated;
|
||||
if ( iptr & 0xF ) {
|
||||
iptr += 16 - ( iptr & 0xF );
|
||||
}
|
||||
assert( !( iptr & 0xF ) );
|
||||
assert( iptr >= (uintptr_t) m_allocated );
|
||||
assert( iptr <= ( 15 + (uintptr_t) m_allocated ) );
|
||||
|
||||
m_data = (char *) iptr;
|
||||
|
||||
#endif /* !defined(HAVE_POSIX_MEMALIGN) */
|
||||
|
||||
if ( data ) {
|
||||
memcpy( m_data, data, len );
|
||||
}
|
||||
}
|
||||
|
||||
Base64Key::Base64Key( string printable_key )
|
||||
{
|
||||
if ( printable_key.length() != 22 ) {
|
||||
throw CryptoException( "Key must be 22 letters long." );
|
||||
}
|
||||
|
||||
string base64 = printable_key + "==";
|
||||
|
||||
size_t len = 16;
|
||||
if ( !base64_decode( base64.data(), 24, key, &len ) ) {
|
||||
throw CryptoException( "Key must be well-formed base64." );
|
||||
}
|
||||
|
||||
if ( len != 16 ) {
|
||||
throw CryptoException( "Key must represent 16 octets." );
|
||||
}
|
||||
|
||||
/* to catch changes after the first 128 bits */
|
||||
if ( printable_key != this->printable_key() ) {
|
||||
throw CryptoException( "Base64 key was not encoded 128-bit key." );
|
||||
}
|
||||
}
|
||||
|
||||
Base64Key::Base64Key()
|
||||
{
|
||||
PRNG().fill( key, sizeof( key ) );
|
||||
}
|
||||
|
||||
Base64Key::Base64Key(PRNG &prng)
|
||||
{
|
||||
prng.fill( key, sizeof( key ) );
|
||||
}
|
||||
|
||||
string Base64Key::printable_key( void ) const
|
||||
{
|
||||
char base64[ 24 ];
|
||||
|
||||
base64_encode( key, 16, base64, 24 );
|
||||
|
||||
if ( (base64[ 23 ] != '=')
|
||||
|| (base64[ 22 ] != '=') ) {
|
||||
throw CryptoException( string( "Unexpected output from base64_encode: " ) + string( base64, 24 ) );
|
||||
}
|
||||
|
||||
base64[ 22 ] = 0;
|
||||
return string( base64 );
|
||||
}
|
||||
|
||||
Session::Session( Base64Key s_key )
|
||||
: key( s_key ), ctx_buf( ae_ctx_sizeof() ),
|
||||
ctx( (ae_ctx *)ctx_buf.data() ), blocks_encrypted( 0 ),
|
||||
plaintext_buffer( RECEIVE_MTU ),
|
||||
ciphertext_buffer( RECEIVE_MTU ),
|
||||
nonce_buffer( Nonce::NONCE_LEN )
|
||||
{
|
||||
if ( AE_SUCCESS != ae_init( ctx, key.data(), 16, 12, 16 ) ) {
|
||||
throw CryptoException( "Could not initialize AES-OCB context." );
|
||||
}
|
||||
}
|
||||
|
||||
Session::~Session()
|
||||
{
|
||||
if ( ae_clear( ctx ) != AE_SUCCESS ) {
|
||||
throw CryptoException( "Could not clear AES-OCB context." );
|
||||
}
|
||||
}
|
||||
|
||||
Nonce::Nonce( uint64_t val )
|
||||
{
|
||||
uint64_t val_net = htobe64( val );
|
||||
|
||||
memset( bytes, 0, 4 );
|
||||
memcpy( bytes + 4, &val_net, 8 );
|
||||
}
|
||||
|
||||
uint64_t Nonce::val( void )
|
||||
{
|
||||
uint64_t ret;
|
||||
memcpy( &ret, bytes + 4, 8 );
|
||||
return be64toh( ret );
|
||||
}
|
||||
|
||||
Nonce::Nonce( char *s_bytes, size_t len )
|
||||
{
|
||||
if ( len != 8 ) {
|
||||
throw CryptoException( "Nonce representation must be 8 octets long." );
|
||||
}
|
||||
|
||||
memset( bytes, 0, 4 );
|
||||
memcpy( bytes + 4, s_bytes, 8 );
|
||||
}
|
||||
|
||||
Message::Message( char *nonce_bytes, size_t nonce_len,
|
||||
char *text_bytes, size_t text_len )
|
||||
: nonce( nonce_bytes, nonce_len ),
|
||||
text( (char *)text_bytes, text_len )
|
||||
{}
|
||||
|
||||
Message::Message( Nonce s_nonce, string s_text )
|
||||
: nonce( s_nonce ),
|
||||
text( s_text )
|
||||
{}
|
||||
|
||||
string Session::encrypt( Message plaintext )
|
||||
{
|
||||
const size_t pt_len = plaintext.text.size();
|
||||
const int ciphertext_len = pt_len + 16;
|
||||
|
||||
assert( (size_t)ciphertext_len <= ciphertext_buffer.len() );
|
||||
assert( pt_len <= plaintext_buffer.len() );
|
||||
|
||||
memcpy( plaintext_buffer.data(), plaintext.text.data(), pt_len );
|
||||
memcpy( nonce_buffer.data(), plaintext.nonce.data(), Nonce::NONCE_LEN );
|
||||
|
||||
if ( ciphertext_len != ae_encrypt( ctx, /* ctx */
|
||||
nonce_buffer.data(), /* nonce */
|
||||
plaintext_buffer.data(), /* pt */
|
||||
pt_len, /* pt_len */
|
||||
NULL, /* ad */
|
||||
0, /* ad_len */
|
||||
ciphertext_buffer.data(), /* ct */
|
||||
NULL, /* tag */
|
||||
AE_FINALIZE ) ) { /* final */
|
||||
throw CryptoException( "ae_encrypt() returned error." );
|
||||
}
|
||||
|
||||
blocks_encrypted += pt_len >> 4;
|
||||
if ( pt_len & 0xF ) {
|
||||
/* partial block */
|
||||
blocks_encrypted++;
|
||||
}
|
||||
|
||||
/* "Both the privacy and the authenticity properties of OCB degrade as
|
||||
per s^2 / 2^128, where s is the total number of blocks that the
|
||||
adversary acquires.... In order to ensure that s^2 / 2^128 remains
|
||||
small, a given key should be used to encrypt at most 2^48 blocks (2^55
|
||||
bits or 4 petabytes)"
|
||||
|
||||
-- http://tools.ietf.org/html/draft-krovetz-ocb-03
|
||||
|
||||
We deem it unlikely that a legitimate user will send 4 PB through a Mosh
|
||||
session. If it happens, we simply kill the session. The server and
|
||||
client use the same key, so we actually need to die after 2^47 blocks.
|
||||
*/
|
||||
if ( blocks_encrypted >> 47 ) {
|
||||
throw CryptoException( "Encrypted 2^47 blocks.", true );
|
||||
}
|
||||
|
||||
string text( ciphertext_buffer.data(), ciphertext_len );
|
||||
|
||||
return plaintext.nonce.cc_str() + text;
|
||||
}
|
||||
|
||||
Message Session::decrypt( string ciphertext )
|
||||
{
|
||||
if ( ciphertext.size() < 24 ) {
|
||||
throw CryptoException( "Ciphertext must contain nonce and tag." );
|
||||
}
|
||||
|
||||
char *str = (char *)ciphertext.data();
|
||||
|
||||
int body_len = ciphertext.size() - 8;
|
||||
int pt_len = body_len - 16;
|
||||
|
||||
if ( pt_len < 0 ) { /* super-assertion that pt_len does not equal AE_INVALID */
|
||||
fprintf( stderr, "BUG.\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
assert( (size_t)body_len <= ciphertext_buffer.len() );
|
||||
assert( (size_t)pt_len <= plaintext_buffer.len() );
|
||||
|
||||
Nonce nonce( str, 8 );
|
||||
memcpy( ciphertext_buffer.data(), str + 8, body_len );
|
||||
memcpy( nonce_buffer.data(), nonce.data(), Nonce::NONCE_LEN );
|
||||
|
||||
if ( pt_len != ae_decrypt( ctx, /* ctx */
|
||||
nonce_buffer.data(), /* nonce */
|
||||
ciphertext_buffer.data(), /* ct */
|
||||
body_len, /* ct_len */
|
||||
NULL, /* ad */
|
||||
0, /* ad_len */
|
||||
plaintext_buffer.data(), /* pt */
|
||||
NULL, /* tag */
|
||||
AE_FINALIZE ) ) { /* final */
|
||||
throw CryptoException( "Packet failed integrity check." );
|
||||
}
|
||||
|
||||
Message ret( nonce, string( plaintext_buffer.data(), pt_len ) );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static rlim_t saved_core_rlimit;
|
||||
|
||||
/* Disable dumping core, as a precaution to avoid saving sensitive data
|
||||
to disk. */
|
||||
void Crypto::disable_dumping_core( void ) {
|
||||
struct rlimit limit;
|
||||
if ( 0 != getrlimit( RLIMIT_CORE, &limit ) ) {
|
||||
/* We don't throw CryptoException because this is called very early
|
||||
in main(), outside of 'try'. */
|
||||
perror( "getrlimit(RLIMIT_CORE)" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
saved_core_rlimit = limit.rlim_cur;
|
||||
limit.rlim_cur = 0;
|
||||
if ( 0 != setrlimit( RLIMIT_CORE, &limit ) ) {
|
||||
perror( "setrlimit(RLIMIT_CORE)" );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
void Crypto::reenable_dumping_core( void ) {
|
||||
/* Silent failure is safe. */
|
||||
struct rlimit limit;
|
||||
if ( 0 == getrlimit( RLIMIT_CORE, &limit ) ) {
|
||||
limit.rlim_cur = saved_core_rlimit;
|
||||
setrlimit( RLIMIT_CORE, &limit );
|
||||
}
|
||||
}
|
||||
150
vendor/mosh/src/crypto/crypto.h
vendored
Normal file
150
vendor/mosh/src/crypto/crypto.h
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_HPP
|
||||
#define CRYPTO_HPP
|
||||
|
||||
#include "ae.h"
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <exception>
|
||||
|
||||
using std::string;
|
||||
|
||||
long int myatoi( const char *str );
|
||||
|
||||
class PRNG;
|
||||
|
||||
namespace Crypto {
|
||||
|
||||
class CryptoException : public std::exception {
|
||||
public:
|
||||
string text;
|
||||
bool fatal;
|
||||
CryptoException( string s_text, bool s_fatal = false )
|
||||
: text( s_text ), fatal( s_fatal ) {};
|
||||
const char *what() const throw () { return text.c_str(); }
|
||||
~CryptoException() throw () {}
|
||||
};
|
||||
|
||||
/* 16-byte-aligned buffer, with length. */
|
||||
class AlignedBuffer {
|
||||
private:
|
||||
size_t m_len;
|
||||
void *m_allocated;
|
||||
char *m_data;
|
||||
|
||||
public:
|
||||
AlignedBuffer( size_t len, const char *data = NULL );
|
||||
|
||||
~AlignedBuffer() {
|
||||
free( m_allocated );
|
||||
}
|
||||
|
||||
char * data( void ) const { return m_data; }
|
||||
size_t len( void ) const { return m_len; }
|
||||
|
||||
private:
|
||||
/* Not implemented */
|
||||
AlignedBuffer( const AlignedBuffer & );
|
||||
AlignedBuffer & operator=( const AlignedBuffer & );
|
||||
};
|
||||
|
||||
class Base64Key {
|
||||
private:
|
||||
unsigned char key[ 16 ];
|
||||
|
||||
public:
|
||||
Base64Key(); /* random key */
|
||||
Base64Key(PRNG &prng);
|
||||
Base64Key( string printable_key );
|
||||
string printable_key( void ) const;
|
||||
unsigned char *data( void ) { return key; }
|
||||
};
|
||||
|
||||
class Nonce {
|
||||
public:
|
||||
static const int NONCE_LEN = 12;
|
||||
|
||||
private:
|
||||
char bytes[ NONCE_LEN ];
|
||||
|
||||
public:
|
||||
Nonce( uint64_t val );
|
||||
Nonce( char *s_bytes, size_t len );
|
||||
|
||||
string cc_str( void ) const { return string( bytes + 4, 8 ); }
|
||||
const char *data( void ) const { return bytes; }
|
||||
uint64_t val( void );
|
||||
};
|
||||
|
||||
class Message {
|
||||
public:
|
||||
Nonce nonce;
|
||||
string text;
|
||||
|
||||
Message( char *nonce_bytes, size_t nonce_len,
|
||||
char *text_bytes, size_t text_len );
|
||||
Message( Nonce s_nonce, string s_text );
|
||||
};
|
||||
|
||||
class Session {
|
||||
private:
|
||||
Base64Key key;
|
||||
AlignedBuffer ctx_buf;
|
||||
ae_ctx *ctx;
|
||||
uint64_t blocks_encrypted;
|
||||
|
||||
AlignedBuffer plaintext_buffer;
|
||||
AlignedBuffer ciphertext_buffer;
|
||||
AlignedBuffer nonce_buffer;
|
||||
|
||||
public:
|
||||
static const int RECEIVE_MTU = 2048;
|
||||
|
||||
Session( Base64Key s_key );
|
||||
~Session();
|
||||
|
||||
string encrypt( Message plaintext );
|
||||
Message decrypt( string ciphertext );
|
||||
|
||||
Session( const Session & );
|
||||
Session & operator=( const Session & );
|
||||
};
|
||||
|
||||
void disable_dumping_core( void );
|
||||
void reenable_dumping_core( void );
|
||||
}
|
||||
|
||||
#endif
|
||||
1533
vendor/mosh/src/crypto/ocb.cc
vendored
Normal file
1533
vendor/mosh/src/crypto/ocb.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
91
vendor/mosh/src/crypto/prng.h
vendored
Normal file
91
vendor/mosh/src/crypto/prng.h
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#ifndef PRNG_HPP
|
||||
#define PRNG_HPP
|
||||
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include <fstream>
|
||||
|
||||
#include "crypto.h"
|
||||
|
||||
/* Read random bytes from /dev/urandom.
|
||||
|
||||
We rely on stdio buffering for efficiency. */
|
||||
|
||||
static const char rdev[] = "/dev/urandom";
|
||||
|
||||
using namespace Crypto;
|
||||
|
||||
class PRNG {
|
||||
private:
|
||||
std::ifstream randfile;
|
||||
|
||||
/* unimplemented to satisfy -Weffc++ */
|
||||
PRNG( const PRNG & );
|
||||
PRNG & operator=( const PRNG & );
|
||||
|
||||
public:
|
||||
PRNG() : randfile( rdev, std::ifstream::in | std::ifstream::binary ) {}
|
||||
|
||||
void fill( void *dest, size_t size ) {
|
||||
if ( 0 == size ) {
|
||||
return;
|
||||
}
|
||||
|
||||
randfile.read( static_cast<char *>( dest ), size );
|
||||
if ( !randfile ) {
|
||||
throw CryptoException( "Could not read from " + std::string( rdev ) );
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t uint8() {
|
||||
uint8_t x;
|
||||
fill( &x, 1 );
|
||||
return x;
|
||||
}
|
||||
|
||||
uint32_t uint32() {
|
||||
uint32_t x;
|
||||
fill( &x, 4 );
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t uint64() {
|
||||
uint64_t x;
|
||||
fill( &x, 8 );
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
6
vendor/mosh/src/examples/.gitignore
vendored
Normal file
6
vendor/mosh/src/examples/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/decrypt
|
||||
/encrypt
|
||||
/ntester
|
||||
/parse
|
||||
/termemu
|
||||
/benchmark
|
||||
30
vendor/mosh/src/examples/Makefile.am
vendored
Normal file
30
vendor/mosh/src/examples/Makefile.am
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS)
|
||||
AM_LDFLAGS = $(HARDEN_LDFLAGS)
|
||||
|
||||
if BUILD_EXAMPLES
|
||||
noinst_PROGRAMS = encrypt decrypt ntester parse termemu benchmark
|
||||
endif
|
||||
|
||||
encrypt_SOURCES = encrypt.cc
|
||||
encrypt_CPPFLAGS = -I$(srcdir)/../crypto
|
||||
encrypt_LDADD = ../crypto/libmoshcrypto.a $(CRYPTO_LIBS)
|
||||
|
||||
decrypt_SOURCES = decrypt.cc
|
||||
decrypt_CPPFLAGS = -I$(srcdir)/../crypto
|
||||
decrypt_LDADD = ../crypto/libmoshcrypto.a $(CRYPTO_LIBS)
|
||||
|
||||
parse_SOURCES = parse.cc
|
||||
parse_CPPFLAGS = -I$(srcdir)/../terminal -I$(srcdir)/../util
|
||||
parse_LDADD = ../terminal/libmoshterminal.a ../util/libmoshutil.a $(LIBUTIL)
|
||||
|
||||
termemu_SOURCES = termemu.cc
|
||||
termemu_CPPFLAGS = -I$(srcdir)/../terminal -I$(srcdir)/../util -I$(srcdir)/../statesync -I../protobufs
|
||||
termemu_LDADD = ../terminal/libmoshterminal.a ../util/libmoshutil.a ../statesync/libmoshstatesync.a ../protobufs/libmoshprotos.a $(LIBUTIL) $(TINFO_LIBS) $(protobuf_LIBS)
|
||||
|
||||
ntester_SOURCES = ntester.cc
|
||||
ntester_CPPFLAGS = -I$(srcdir)/../util -I$(srcdir)/../statesync -I$(srcdir)/../terminal -I$(srcdir)/../network -I$(srcdir)/../crypto -I../protobufs $(protobuf_CFLAGS)
|
||||
ntester_LDADD = ../statesync/libmoshstatesync.a ../terminal/libmoshterminal.a ../network/libmoshnetwork.a ../crypto/libmoshcrypto.a ../protobufs/libmoshprotos.a ../util/libmoshutil.a $(LIBUTIL) -lm $(protobuf_LIBS) $(CRYPTO_LIBS)
|
||||
|
||||
benchmark_SOURCES = benchmark.cc
|
||||
benchmark_CPPFLAGS = -I$(srcdir)/../util -I$(srcdir)/../statesync -I$(srcdir)/../terminal -I../protobufs -I$(srcdir)/../frontend -I$(srcdir)/../crypto -I$(srcdir)/../network $(protobuf_CFLAGS)
|
||||
benchmark_LDADD = ../frontend/terminaloverlay.o ../statesync/libmoshstatesync.a ../terminal/libmoshterminal.a ../protobufs/libmoshprotos.a ../network/libmoshnetwork.a ../crypto/libmoshcrypto.a ../util/libmoshutil.a $(STDDJB_LDFLAGS) $(LIBUTIL) -lm $(TINFO_LIBS) $(protobuf_LIBS) $(CRYPTO_LIBS)
|
||||
127
vendor/mosh/src/examples/benchmark.cc
vendored
Normal file
127
vendor/mosh/src/examples/benchmark.cc
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
#include <exception>
|
||||
|
||||
#if HAVE_PTY_H
|
||||
#include <pty.h>
|
||||
#elif HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
|
||||
#include "swrite.h"
|
||||
#include "completeterminal.h"
|
||||
#include "user.h"
|
||||
#include "terminaloverlay.h"
|
||||
#include "locale_utils.h"
|
||||
#include "fatal_assert.h"
|
||||
|
||||
const int ITERATIONS = 100000;
|
||||
|
||||
using namespace Terminal;
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
try {
|
||||
int fbmod = 0;
|
||||
int width = 80, height = 24;
|
||||
int iterations = ITERATIONS;
|
||||
if (argc > 1) {
|
||||
iterations = atoi(argv[1]);
|
||||
if (iterations < 1 || iterations > 1000000000) {
|
||||
fprintf(stderr, "bogus iteration count\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (argc > 3) {
|
||||
width = atoi(argv[2]);
|
||||
height = atoi(argv[3]);
|
||||
if (width < 1 || width > 1000 || height < 1 || height > 1000) {
|
||||
fprintf(stderr, "bogus window size\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
Framebuffer local_framebuffers[ 2 ] = { Framebuffer(width,height), Framebuffer(width,height) };
|
||||
Framebuffer *local_framebuffer = &(local_framebuffers[ fbmod ]);
|
||||
Framebuffer *new_state = &(local_framebuffers[ !fbmod ]);
|
||||
Overlay::OverlayManager overlays;
|
||||
Display display( true );
|
||||
Complete local_terminal( width, height );
|
||||
|
||||
/* Adopt native locale */
|
||||
set_native_locale();
|
||||
fatal_assert( is_utf8_locale() );
|
||||
|
||||
for ( int i = 0; i < iterations; i++ ) {
|
||||
/* type a character */
|
||||
overlays.get_prediction_engine().new_user_byte( i + 'x', *local_framebuffer );
|
||||
|
||||
/* fetch target state */
|
||||
*new_state = local_terminal.get_fb();
|
||||
|
||||
/* apply local overlays */
|
||||
overlays.apply( *new_state );
|
||||
|
||||
/* calculate minimal difference from where we are */
|
||||
const string diff( display.new_frame( false,
|
||||
*local_framebuffer,
|
||||
*new_state ) );
|
||||
|
||||
/* make sure to use diff */
|
||||
if ( diff.size() > INT_MAX ) {
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
fbmod = !fbmod;
|
||||
local_framebuffer = &(local_framebuffers[ fbmod ]);
|
||||
new_state = &(local_framebuffers[ !fbmod ]);
|
||||
}
|
||||
} catch ( const std::exception &e ) {
|
||||
fprintf( stderr, "Exception caught: %s\n", e.what() );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
70
vendor/mosh/src/examples/decrypt.cc
vendored
Normal file
70
vendor/mosh/src/examples/decrypt.cc
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "crypto.h"
|
||||
|
||||
using namespace Crypto;
|
||||
using namespace std;
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
if ( argc != 2 ) {
|
||||
fprintf( stderr, "Usage: %s KEY\n", argv[ 0 ] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
Base64Key key( argv[ 1 ] );
|
||||
Session session( key );
|
||||
|
||||
/* Read input */
|
||||
ostringstream input;
|
||||
input << cin.rdbuf();
|
||||
|
||||
/* Decrypt message */
|
||||
|
||||
Message message = session.decrypt( input.str() );
|
||||
|
||||
fprintf( stderr, "Nonce = %ld\n",
|
||||
(long)message.nonce.val() );
|
||||
cout << message.text;
|
||||
} catch ( const CryptoException &e ) {
|
||||
cerr << e.what() << endl;
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
71
vendor/mosh/src/examples/encrypt.cc
vendored
Normal file
71
vendor/mosh/src/examples/encrypt.cc
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "crypto.h"
|
||||
|
||||
using namespace Crypto;
|
||||
using namespace std;
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
if ( argc != 2 ) {
|
||||
fprintf( stderr, "Usage: %s NONCE\n", argv[ 0 ] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
Base64Key key;
|
||||
Session session( key );
|
||||
Nonce nonce( myatoi( argv[ 1 ] ) );
|
||||
|
||||
/* Read input */
|
||||
ostringstream input;
|
||||
input << cin.rdbuf();
|
||||
|
||||
/* Encrypt message */
|
||||
|
||||
string ciphertext = session.encrypt( Message( nonce, input.str() ) );
|
||||
|
||||
cerr << "Key: " << key.printable_key() << endl;
|
||||
|
||||
cout << ciphertext;
|
||||
} catch ( const CryptoException &e ) {
|
||||
cerr << e.what() << endl;
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
177
vendor/mosh/src/examples/ntester.cc
vendored
Normal file
177
vendor/mosh/src/examples/ntester.cc
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "user.h"
|
||||
#include "fatal_assert.h"
|
||||
#include "pty_compat.h"
|
||||
#include "networktransport.cc"
|
||||
#include "select.h"
|
||||
|
||||
using namespace Network;
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
bool server = true;
|
||||
char *key;
|
||||
char *ip;
|
||||
char *port;
|
||||
|
||||
UserStream me, remote;
|
||||
|
||||
Transport<UserStream, UserStream> *n;
|
||||
|
||||
try {
|
||||
if ( argc > 1 ) {
|
||||
server = false;
|
||||
/* client */
|
||||
|
||||
key = argv[ 1 ];
|
||||
ip = argv[ 2 ];
|
||||
port = argv[ 3 ];
|
||||
|
||||
n = new Transport<UserStream, UserStream>( me, remote, key, ip, port );
|
||||
} else {
|
||||
n = new Transport<UserStream, UserStream>( me, remote, NULL, NULL );
|
||||
}
|
||||
fprintf( stderr, "Port bound is %s, key is %s\n", n->port().c_str(), n->get_key().c_str() );
|
||||
} catch ( const std::exception &e ) {
|
||||
fprintf( stderr, "Fatal startup error: %s\n", e.what() );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( server ) {
|
||||
Select &sel = Select::get_instance();
|
||||
uint64_t last_num = n->get_remote_state_num();
|
||||
while ( true ) {
|
||||
try {
|
||||
sel.clear_fds();
|
||||
std::vector< int > fd_list( n->fds() );
|
||||
assert( fd_list.size() == 1 ); /* servers don't hop */
|
||||
int network_fd = fd_list.back();
|
||||
sel.add_fd( network_fd );
|
||||
if ( sel.select( n->wait_time() ) < 0 ) {
|
||||
perror( "select" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
n->tick();
|
||||
|
||||
if ( sel.read( network_fd ) ) {
|
||||
n->recv();
|
||||
|
||||
if ( n->get_remote_state_num() != last_num ) {
|
||||
fprintf( stderr, "[%d=>%d %s]", (int)last_num, (int)n->get_remote_state_num(), n->get_remote_diff().c_str() );
|
||||
last_num = n->get_remote_state_num();
|
||||
}
|
||||
}
|
||||
} catch ( const std::exception &e ) {
|
||||
fprintf( stderr, "Server error: %s\n", e.what() );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
struct termios saved_termios;
|
||||
struct termios the_termios;
|
||||
|
||||
if ( tcgetattr( STDIN_FILENO, &the_termios ) < 0 ) {
|
||||
perror( "tcgetattr" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
saved_termios = the_termios;
|
||||
|
||||
cfmakeraw( &the_termios );
|
||||
|
||||
if ( tcsetattr( STDIN_FILENO, TCSANOW, &the_termios ) < 0 ) {
|
||||
perror( "tcsetattr" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
Select &sel = Select::get_instance();
|
||||
|
||||
while( true ) {
|
||||
sel.clear_fds();
|
||||
sel.add_fd( STDIN_FILENO );
|
||||
|
||||
std::vector< int > fd_list( n->fds() );
|
||||
for ( std::vector< int >::const_iterator it = fd_list.begin();
|
||||
it != fd_list.end();
|
||||
it++ ) {
|
||||
sel.add_fd( *it );
|
||||
}
|
||||
|
||||
try {
|
||||
if ( sel.select( n->wait_time() ) < 0 ) {
|
||||
perror( "select" );
|
||||
}
|
||||
|
||||
n->tick();
|
||||
|
||||
if ( sel.read( STDIN_FILENO ) ) {
|
||||
char x;
|
||||
fatal_assert( read( STDIN_FILENO, &x, 1 ) == 1 );
|
||||
n->get_current_state().push_back( Parser::UserByte( x ) );
|
||||
}
|
||||
|
||||
bool network_ready_to_read = false;
|
||||
for ( std::vector< int >::const_iterator it = fd_list.begin();
|
||||
it != fd_list.end();
|
||||
it++ ) {
|
||||
if ( sel.read( *it ) ) {
|
||||
/* packet received from the network */
|
||||
/* we only read one socket each run */
|
||||
network_ready_to_read = true;
|
||||
}
|
||||
|
||||
if ( sel.error( *it ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( network_ready_to_read ) {
|
||||
n->recv();
|
||||
}
|
||||
} catch ( const std::exception &e ) {
|
||||
fprintf( stderr, "Client error: %s\n", e.what() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( tcsetattr( STDIN_FILENO, TCSANOW, &saved_termios ) < 0 ) {
|
||||
perror( "tcsetattr" );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
delete n;
|
||||
}
|
||||
224
vendor/mosh/src/examples/parse.cc
vendored
Normal file
224
vendor/mosh/src/examples/parse.cc
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <wchar.h>
|
||||
#include <assert.h>
|
||||
#include <wctype.h>
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
#include <termios.h>
|
||||
|
||||
#if HAVE_PTY_H
|
||||
#include <pty.h>
|
||||
#elif HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#elif HAVE_LIBUTIL_H
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
|
||||
#include "parser.h"
|
||||
#include "swrite.h"
|
||||
#include "locale_utils.h"
|
||||
#include "fatal_assert.h"
|
||||
#include "pty_compat.h"
|
||||
#include "select.h"
|
||||
|
||||
const size_t buf_size = 1024;
|
||||
|
||||
static void emulate_terminal( int fd );
|
||||
static int copy( int src, int dest );
|
||||
static int vt_parser( int fd, Parser::UTF8Parser *parser );
|
||||
|
||||
int main( int argc __attribute__((unused)),
|
||||
char *argv[] __attribute__((unused)),
|
||||
char *envp[] )
|
||||
{
|
||||
int master;
|
||||
struct termios saved_termios, raw_termios, child_termios;
|
||||
|
||||
set_native_locale();
|
||||
fatal_assert( is_utf8_locale() );
|
||||
|
||||
if ( tcgetattr( STDIN_FILENO, &saved_termios ) < 0 ) {
|
||||
perror( "tcgetattr" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
child_termios = saved_termios;
|
||||
|
||||
#ifdef HAVE_IUTF8
|
||||
if ( !(child_termios.c_iflag & IUTF8) ) {
|
||||
fprintf( stderr, "Warning: Locale is UTF-8 but termios IUTF8 flag not set. Setting IUTF8 flag.\n" );
|
||||
child_termios.c_iflag |= IUTF8;
|
||||
}
|
||||
#else
|
||||
fprintf( stderr, "Warning: termios IUTF8 flag not defined. Character-erase of multibyte character sequence probably does not work properly on this platform.\n" );
|
||||
#endif /* HAVE_IUTF8 */
|
||||
|
||||
pid_t child = forkpty( &master, NULL, &child_termios, NULL );
|
||||
|
||||
if ( child == -1 ) {
|
||||
perror( "forkpty" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( child == 0 ) {
|
||||
/* child */
|
||||
char *my_argv[ 2 ];
|
||||
my_argv[ 0 ] = strdup( "/bin/bash" );
|
||||
assert( my_argv[ 0 ] );
|
||||
|
||||
my_argv[ 1 ] = NULL;
|
||||
|
||||
if ( execve( "/bin/bash", my_argv, envp ) < 0 ) {
|
||||
perror( "execve" );
|
||||
exit( 1 );
|
||||
}
|
||||
exit( 0 );
|
||||
} else {
|
||||
/* parent */
|
||||
raw_termios = saved_termios;
|
||||
|
||||
cfmakeraw( &raw_termios );
|
||||
|
||||
if ( tcsetattr( STDIN_FILENO, TCSANOW, &raw_termios ) < 0 ) {
|
||||
perror( "tcsetattr" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
emulate_terminal( master );
|
||||
|
||||
if ( tcsetattr( STDIN_FILENO, TCSANOW, &saved_termios ) < 0 ) {
|
||||
perror( "tcsetattr" );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void emulate_terminal( int fd )
|
||||
{
|
||||
Parser::UTF8Parser parser;
|
||||
|
||||
Select &sel = Select::get_instance();
|
||||
sel.add_fd( STDIN_FILENO );
|
||||
sel.add_fd( fd );
|
||||
|
||||
while ( 1 ) {
|
||||
int active_fds = sel.select( -1 );
|
||||
if ( active_fds <= 0 ) {
|
||||
perror( "select" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( sel.read( STDIN_FILENO ) ) {
|
||||
if ( copy( STDIN_FILENO, fd ) < 0 ) {
|
||||
return;
|
||||
}
|
||||
} else if ( sel.read( fd ) ) {
|
||||
if ( vt_parser( fd, &parser ) < 0 ) {
|
||||
return;
|
||||
}
|
||||
} else if ( sel.error( STDIN_FILENO ) || sel.error( fd ) ) {
|
||||
return;
|
||||
} else {
|
||||
fprintf( stderr, "select mysteriously woken up\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int copy( int src, int dest )
|
||||
{
|
||||
char buf[ buf_size ];
|
||||
|
||||
ssize_t bytes_read = read( src, buf, buf_size );
|
||||
if ( bytes_read == 0 ) { /* EOF */
|
||||
return -1;
|
||||
} else if ( bytes_read < 0 ) {
|
||||
perror( "read" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return swrite( dest, buf, bytes_read );
|
||||
}
|
||||
|
||||
static int vt_parser( int fd, Parser::UTF8Parser *parser )
|
||||
{
|
||||
char buf[ buf_size ];
|
||||
|
||||
/* fill buffer if possible */
|
||||
ssize_t bytes_read = read( fd, buf, buf_size );
|
||||
if ( bytes_read == 0 ) { /* EOF */
|
||||
return -1;
|
||||
} else if ( bytes_read < 0 ) {
|
||||
perror( "read" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* feed to parser */
|
||||
for ( int i = 0; i < bytes_read; i++ ) {
|
||||
std::list<Parser::Action *> actions = parser->input( buf[ i ] );
|
||||
for ( std::list<Parser::Action *>::iterator j = actions.begin();
|
||||
j != actions.end();
|
||||
j++ ) {
|
||||
|
||||
Parser::Action *act = *j;
|
||||
assert( act );
|
||||
|
||||
if ( act->char_present ) {
|
||||
if ( iswprint( act->ch ) ) {
|
||||
printf( "%s(0x%02x=%lc) ", act->name().c_str(), (unsigned int)act->ch, (wint_t)act->ch );
|
||||
} else {
|
||||
printf( "%s(0x%02x) ", act->name().c_str(), (unsigned int)act->ch );
|
||||
}
|
||||
} else {
|
||||
printf( "[%s] ", act->name().c_str() );
|
||||
}
|
||||
|
||||
delete act;
|
||||
|
||||
fflush( stdout );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
333
vendor/mosh/src/examples/termemu.cc
vendored
Normal file
333
vendor/mosh/src/examples/termemu.cc
vendored
Normal file
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <wchar.h>
|
||||
#include <assert.h>
|
||||
#include <wctype.h>
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/time.h>
|
||||
#include <exception>
|
||||
|
||||
#if HAVE_PTY_H
|
||||
#include <pty.h>
|
||||
#elif HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#elif HAVE_LIBUTIL_H
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
|
||||
#include "parser.h"
|
||||
#include "completeterminal.h"
|
||||
#include "swrite.h"
|
||||
#include "fatal_assert.h"
|
||||
#include "pty_compat.h"
|
||||
#include "locale_utils.h"
|
||||
#include "select.h"
|
||||
|
||||
const size_t buf_size = 16384;
|
||||
|
||||
static void emulate_terminal( int fd );
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
int master;
|
||||
struct termios saved_termios, raw_termios, child_termios;
|
||||
|
||||
set_native_locale();
|
||||
fatal_assert( is_utf8_locale() );
|
||||
|
||||
if ( tcgetattr( STDIN_FILENO, &saved_termios ) < 0 ) {
|
||||
perror( "tcgetattr" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
child_termios = saved_termios;
|
||||
|
||||
#ifdef HAVE_IUTF8
|
||||
if ( !(child_termios.c_iflag & IUTF8) ) {
|
||||
fprintf( stderr, "Warning: Locale is UTF-8 but termios IUTF8 flag not set. Setting IUTF8 flag.\n" );
|
||||
child_termios.c_iflag |= IUTF8;
|
||||
}
|
||||
#else
|
||||
fprintf( stderr, "Warning: termios IUTF8 flag not defined. Character-erase of multibyte character sequence probably does not work properly on this platform.\n" );
|
||||
#endif /* HAVE_IUTF8 */
|
||||
|
||||
pid_t child = forkpty( &master, NULL, &child_termios, NULL );
|
||||
|
||||
if ( child == -1 ) {
|
||||
perror( "forkpty" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( child == 0 ) {
|
||||
/* child */
|
||||
if ( setenv( "TERM", "xterm-256color", true ) < 0 ) {
|
||||
perror( "setenv" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* ask ncurses to send UTF-8 instead of ISO 2022 for line-drawing chars */
|
||||
if ( setenv( "NCURSES_NO_UTF8_ACS", "1", true ) < 0 ) {
|
||||
perror( "setenv" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
char *my_argv[ 2 ];
|
||||
|
||||
if ( argc > 1 ) {
|
||||
argv++;
|
||||
} else {
|
||||
/* get shell name */
|
||||
my_argv[ 0 ] = getenv( "SHELL" );
|
||||
if ( my_argv[ 0 ] == NULL || *my_argv[ 0 ] == '\0' ) {
|
||||
struct passwd *pw = getpwuid( geteuid() );
|
||||
if ( pw == NULL ) {
|
||||
perror( "getpwuid" );
|
||||
exit( 1 );
|
||||
}
|
||||
my_argv[ 0 ] = strdup( pw->pw_shell );
|
||||
}
|
||||
assert( my_argv[ 0 ] );
|
||||
my_argv[ 1 ] = NULL;
|
||||
argv = my_argv;
|
||||
}
|
||||
if ( execvp( argv[ 0 ], argv ) < 0 ) {
|
||||
perror( "execve" );
|
||||
exit( 1 );
|
||||
}
|
||||
exit( 0 );
|
||||
} else {
|
||||
/* parent */
|
||||
raw_termios = saved_termios;
|
||||
|
||||
cfmakeraw( &raw_termios );
|
||||
|
||||
if ( tcsetattr( STDIN_FILENO, TCSANOW, &raw_termios ) < 0 ) {
|
||||
perror( "tcsetattr" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
try {
|
||||
emulate_terminal( master );
|
||||
} catch ( const std::exception &e ) {
|
||||
fprintf( stderr, "\r\nException caught: %s\r\n", e.what() );
|
||||
}
|
||||
|
||||
if ( tcsetattr( STDIN_FILENO, TCSANOW, &saved_termios ) < 0 ) {
|
||||
perror( "tcsetattr" );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
printf( "[stm is exiting.]\n" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Print a frame if the last frame was more than 1/50 seconds ago */
|
||||
static bool tick( Terminal::Framebuffer &state, Terminal::Framebuffer &new_frame,
|
||||
const Terminal::Display &display )
|
||||
{
|
||||
static bool initialized = false;
|
||||
static struct timeval last_time;
|
||||
|
||||
struct timeval this_time;
|
||||
|
||||
if ( gettimeofday( &this_time, NULL ) < 0 ) {
|
||||
perror( "gettimeofday" );
|
||||
}
|
||||
|
||||
double diff = (this_time.tv_sec - last_time.tv_sec)
|
||||
+ .000001 * (this_time.tv_usec - last_time.tv_usec);
|
||||
|
||||
if ( (!initialized)
|
||||
|| (diff >= 0.02) ) {
|
||||
display.downgrade( new_frame );
|
||||
|
||||
std::string update = display.new_frame( initialized, state, new_frame );
|
||||
swrite( STDOUT_FILENO, update.c_str() );
|
||||
state = new_frame;
|
||||
|
||||
initialized = true;
|
||||
last_time = this_time;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* This is the main loop.
|
||||
|
||||
1. New bytes from the user get applied to the terminal emulator
|
||||
as "UserByte" actions.
|
||||
|
||||
2. New bytes from the host get sent to the Parser, and then
|
||||
those actions are applied to the terminal.
|
||||
|
||||
3. Resize events (from a SIGWINCH signal) get turned into
|
||||
"Resize" actions and applied to the terminal.
|
||||
|
||||
At every event from select(), we run the tick() function to
|
||||
possibly print a new frame (if we haven't printed one in the
|
||||
last 1/50 second). The new frames are "differential" -- they
|
||||
assume the previous frame was sent to the real terminal.
|
||||
*/
|
||||
|
||||
static void emulate_terminal( int fd )
|
||||
{
|
||||
/* get current window size */
|
||||
struct winsize window_size;
|
||||
if ( ioctl( STDIN_FILENO, TIOCGWINSZ, &window_size ) < 0 ) {
|
||||
perror( "ioctl TIOCGWINSZ" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* tell child process */
|
||||
if ( ioctl( fd, TIOCSWINSZ, &window_size ) < 0 ) {
|
||||
perror( "ioctl TIOCSWINSZ" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* open parser and terminal */
|
||||
Terminal::Complete complete( window_size.ws_col, window_size.ws_row );
|
||||
Terminal::Framebuffer state( window_size.ws_col, window_size.ws_row );
|
||||
|
||||
/* open display */
|
||||
Terminal::Display display( true ); /* use TERM to initialize */
|
||||
|
||||
Select &sel = Select::get_instance();
|
||||
sel.add_fd( STDIN_FILENO );
|
||||
sel.add_fd( fd );
|
||||
sel.add_signal( SIGWINCH );
|
||||
|
||||
swrite( STDOUT_FILENO, display.open().c_str() );
|
||||
|
||||
int timeout = -1;
|
||||
|
||||
while ( 1 ) {
|
||||
int active_fds = sel.select( timeout );
|
||||
if ( active_fds < 0 ) {
|
||||
perror( "select" );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( sel.read( STDIN_FILENO ) ) {
|
||||
/* input from user */
|
||||
char buf[ buf_size ];
|
||||
|
||||
/* fill buffer if possible */
|
||||
ssize_t bytes_read = read( STDIN_FILENO, buf, buf_size );
|
||||
if ( bytes_read == 0 ) { /* EOF */
|
||||
return;
|
||||
} else if ( bytes_read < 0 ) {
|
||||
perror( "read" );
|
||||
return;
|
||||
}
|
||||
|
||||
std::string terminal_to_host;
|
||||
|
||||
for ( int i = 0; i < bytes_read; i++ ) {
|
||||
Parser::UserByte ub( buf[ i ] );
|
||||
terminal_to_host += complete.act( &ub );
|
||||
}
|
||||
|
||||
if ( swrite( fd, terminal_to_host.c_str(), terminal_to_host.length() ) < 0 ) {
|
||||
break;
|
||||
}
|
||||
} else if ( sel.read( fd ) ) {
|
||||
/* input from host */
|
||||
char buf[ buf_size ];
|
||||
|
||||
/* fill buffer if possible */
|
||||
ssize_t bytes_read = read( fd, buf, buf_size );
|
||||
if ( bytes_read == 0 ) { /* EOF */
|
||||
return;
|
||||
} else if ( bytes_read < 0 ) {
|
||||
perror( "read" );
|
||||
return;
|
||||
}
|
||||
|
||||
std::string terminal_to_host = complete.act( std::string( buf, bytes_read ) );
|
||||
if ( swrite( fd, terminal_to_host.c_str(), terminal_to_host.length() ) < 0 ) {
|
||||
break;
|
||||
}
|
||||
} else if ( sel.signal( SIGWINCH ) ) {
|
||||
/* get new size */
|
||||
if ( ioctl( STDIN_FILENO, TIOCGWINSZ, &window_size ) < 0 ) {
|
||||
perror( "ioctl TIOCGWINSZ" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* tell emulator */
|
||||
Parser::Resize r( window_size.ws_col, window_size.ws_row );
|
||||
complete.act( &r );
|
||||
|
||||
/* tell child process */
|
||||
if ( ioctl( fd, TIOCSWINSZ, &window_size ) < 0 ) {
|
||||
perror( "ioctl TIOCSWINSZ" );
|
||||
return;
|
||||
}
|
||||
} else if ( sel.error( STDIN_FILENO ) || sel.error( fd ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
Terminal::Framebuffer new_frame( complete.get_fb() );
|
||||
|
||||
if ( tick( state, new_frame, display ) ) { /* there was a frame */
|
||||
timeout = -1;
|
||||
} else {
|
||||
timeout = 20;
|
||||
}
|
||||
}
|
||||
|
||||
std::string update = display.new_frame( true, state, complete.get_fb() );
|
||||
swrite( STDOUT_FILENO, update.c_str() );
|
||||
|
||||
swrite( STDOUT_FILENO, display.close().c_str() );
|
||||
}
|
||||
3
vendor/mosh/src/frontend/.gitignore
vendored
Normal file
3
vendor/mosh/src/frontend/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/mosh-client
|
||||
/mosh-server
|
||||
/mosh
|
||||
27
vendor/mosh/src/frontend/Makefile.am
vendored
Normal file
27
vendor/mosh/src/frontend/Makefile.am
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
AM_CPPFLAGS = -I$(srcdir)/../statesync -I$(srcdir)/../terminal -I$(srcdir)/../network -I$(srcdir)/../crypto -I../protobufs -I$(srcdir)/../util $(TINFO_CFLAGS) $(protobuf_CFLAGS) $(CRYPTO_CFLAGS)
|
||||
AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXFLAGS)
|
||||
AM_LDFLAGS = $(HARDEN_LDFLAGS)
|
||||
LDADD = ../crypto/libmoshcrypto.a ../network/libmoshnetwork.a ../statesync/libmoshstatesync.a ../terminal/libmoshterminal.a ../util/libmoshutil.a ../protobufs/libmoshprotos.a -lm $(TINFO_LIBS) $(protobuf_LIBS) $(CRYPTO_LIBS)
|
||||
|
||||
mosh_server_LDADD = $(LDADD) $(LIBUTIL)
|
||||
mosh_client_LDADD = $(LDADD) $(LIBUTIL)
|
||||
|
||||
bin_PROGRAMS =
|
||||
|
||||
if BUILD_CLIENT
|
||||
bin_PROGRAMS += mosh-client
|
||||
endif
|
||||
|
||||
if BUILD_SERVER
|
||||
bin_PROGRAMS += mosh-server
|
||||
endif
|
||||
|
||||
if BUILD_IOS_CONTROLLER
|
||||
noinst_LIBRARIES = libmoshiosclient.a
|
||||
endif
|
||||
|
||||
|
||||
mosh_client_SOURCES = mosh-client.cc stmclient.cc stmclient.h terminaloverlay.cc terminaloverlay.h
|
||||
mosh_server_SOURCES = mosh-server.cc
|
||||
|
||||
libmoshiosclient_a_SOURCES = moshiosbridge.cc moshiosbridge.h iosclient.cc iosclient.h terminaloverlay.cc terminaloverlay.h
|
||||
573
vendor/mosh/src/frontend/iosclient.cc
vendored
Normal file
573
vendor/mosh/src/frontend/iosclient.cc
vendored
Normal file
@@ -0,0 +1,573 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#if HAVE_PTY_H
|
||||
#include <pty.h>
|
||||
#elif HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
|
||||
#include "iosclient.h"
|
||||
#include "swrite.h"
|
||||
#include "completeterminal.h"
|
||||
#include "user.h"
|
||||
#include "fatal_assert.h"
|
||||
#include "locale_utils.h"
|
||||
#include "pty_compat.h"
|
||||
#include "select.h"
|
||||
#include "timestamp.h"
|
||||
|
||||
#include "networktransport.cc"
|
||||
|
||||
void iOSClient::resume( void )
|
||||
{
|
||||
/* Restore termios state */
|
||||
// if ( tcsetattr( in_fd, TCSANOW, &raw_termios ) < 0 ) {
|
||||
// perror( "tcsetattr" );
|
||||
// exit( 1 );
|
||||
// }
|
||||
|
||||
// /* Put terminal in application-cursor-key mode */
|
||||
// swrite( out_fd, display.open().c_str() );
|
||||
|
||||
// /* Flag that outer terminal state is unknown */
|
||||
// repaint_requested = true;
|
||||
}
|
||||
|
||||
void iOSClient::init( void )
|
||||
{
|
||||
if ( !is_utf8_locale() ) {
|
||||
LocaleVar native_ctype = get_ctype();
|
||||
string native_charset( locale_charset() );
|
||||
|
||||
fprintf( out_fd, "mosh-client needs a UTF-8 native locale to run.\r\n" );
|
||||
fprintf( out_fd, "Unfortunately, the client's environment (%s) specifies\nthe character set \"%s\".\r\n", native_ctype.str().c_str(), native_charset.c_str() );
|
||||
/* system() 在 iOS 不可用;此处仅诊断打印(运行前已确保 UTF-8 locale,不会走到)。 */
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
// /* Verify terminal configuration */
|
||||
// if ( tcgetattr( in_fd, &saved_termios ) < 0 ) {
|
||||
// perror( "tcgetattr" );
|
||||
// exit( 1 );
|
||||
// }
|
||||
|
||||
// /* Put terminal driver in raw mode */
|
||||
// raw_termios = saved_termios;
|
||||
|
||||
// #ifdef HAVE_IUTF8
|
||||
// if ( !(raw_termios.c_iflag & IUTF8) ) {
|
||||
// // fprintf( stderr, "Warning: Locale is UTF-8 but termios IUTF8 flag not set. Setting IUTF8 flag.\n" );
|
||||
// /* Probably not really necessary since we are putting terminal driver into raw mode anyway. */
|
||||
// raw_termios.c_iflag |= IUTF8;
|
||||
// }
|
||||
// #endif /* HAVE_IUTF8 */
|
||||
|
||||
// cfmakeraw( &raw_termios );
|
||||
|
||||
// if ( tcsetattr( in_fd, TCSANOW, &raw_termios ) < 0 ) {
|
||||
// perror( "tcsetattr" );
|
||||
// exit( 1 );
|
||||
// }
|
||||
|
||||
// /* Put terminal in application-cursor-key mode */
|
||||
// swrite( out_fd, display.open().c_str() );
|
||||
|
||||
// TODO: Send signal to set window Title
|
||||
// /* Add our name to window title */
|
||||
// if ( !getenv( "MOSH_TITLE_NOPREFIX" ) ) {
|
||||
// overlays.set_title_prefix( wstring( L"[mosh] " ) );
|
||||
// }
|
||||
|
||||
/* Set terminal escape key. */
|
||||
const char *escape_key_env;
|
||||
if ( (escape_key_env = getenv( "MOSH_ESCAPE_KEY" )) != NULL ) {
|
||||
if ( strlen( escape_key_env ) == 1 ) {
|
||||
escape_key = (int)escape_key_env[0];
|
||||
if ( escape_key > 0 && escape_key < 128 ) {
|
||||
if ( escape_key < 32 ) {
|
||||
/* If escape is ctrl-something, pass it with repeating the key without ctrl. */
|
||||
escape_pass_key = escape_key + (int)'@';
|
||||
} else {
|
||||
/* If escape is something else, pass it with repeating the key itself. */
|
||||
escape_pass_key = escape_key;
|
||||
}
|
||||
if ( escape_pass_key >= 'A' && escape_pass_key <= 'Z' ) {
|
||||
/* If escape pass is an upper case character, define optional version
|
||||
as lower case of the same. */
|
||||
escape_pass_key2 = escape_pass_key + (int)'a' - (int)'A';
|
||||
} else {
|
||||
escape_pass_key2 = escape_pass_key;
|
||||
}
|
||||
} else {
|
||||
escape_key = 0x1E;
|
||||
escape_pass_key = '^';
|
||||
escape_pass_key2 = '^';
|
||||
}
|
||||
} else if ( strlen( escape_key_env ) == 0 ) {
|
||||
escape_key = -1;
|
||||
} else {
|
||||
escape_key = 0x1E;
|
||||
escape_pass_key = '^';
|
||||
escape_pass_key2 = '^';
|
||||
}
|
||||
} else {
|
||||
escape_key = 0x1E;
|
||||
escape_pass_key = '^';
|
||||
escape_pass_key2 = '^';
|
||||
}
|
||||
|
||||
/* There are so many better ways to shoot oneself into leg than
|
||||
setting escape key to Ctrl-C, Ctrl-D, NewLine, Ctrl-L or CarriageReturn
|
||||
that we just won't allow that. */
|
||||
if ( escape_key == 0x03 || escape_key == 0x04 || escape_key == 0x0A || escape_key == 0x0C || escape_key == 0x0D ) {
|
||||
escape_key = 0x1E;
|
||||
escape_pass_key = '^';
|
||||
escape_pass_key2 = '^';
|
||||
}
|
||||
|
||||
/* Adjust escape help differently if escape is a control character. */
|
||||
if ( escape_key > 0 ) {
|
||||
char escape_pass_name_buf[16];
|
||||
char escape_key_name_buf[16];
|
||||
snprintf(escape_pass_name_buf, sizeof escape_pass_name_buf, "\"%c\"", escape_pass_key);
|
||||
if (escape_key < 32) {
|
||||
snprintf(escape_key_name_buf, sizeof escape_key_name_buf, "Ctrl-%c", escape_pass_key);
|
||||
escape_requires_lf = false;
|
||||
} else {
|
||||
snprintf(escape_key_name_buf, sizeof escape_key_name_buf, "\"%c\"", escape_key);
|
||||
escape_requires_lf = true;
|
||||
}
|
||||
string tmp;
|
||||
tmp = string( escape_pass_name_buf );
|
||||
wstring escape_pass_name = std::wstring(tmp.begin(), tmp.end());
|
||||
tmp = string( escape_key_name_buf );
|
||||
wstring escape_key_name = std::wstring(tmp.begin(), tmp.end());
|
||||
escape_key_help = L"Commands: Ctrl-Z suspends, \".\" quits, " + escape_pass_name + L" gives literal " + escape_key_name;
|
||||
overlays.get_notification_engine().set_escape_key_string( tmp );
|
||||
}
|
||||
wchar_t tmp[ 128 ];
|
||||
swprintf( tmp, 128, L"Nothing received from server on UDP port %s.", port.c_str() );
|
||||
connecting_notification = wstring( tmp );
|
||||
}
|
||||
|
||||
void iOSClient::shutdown( void )
|
||||
{
|
||||
/* Restore screen state */
|
||||
overlays.get_notification_engine().set_notification_string( wstring( L"" ) );
|
||||
overlays.get_notification_engine().server_heard( timestamp() );
|
||||
overlays.set_title_prefix( wstring( L"" ) );
|
||||
output_new_frame();
|
||||
|
||||
/* Restore terminal and terminal-driver state */
|
||||
//swrite( out_fd, display.close().c_str() );
|
||||
|
||||
// if ( tcsetattr( in_fd, TCSANOW, &saved_termios ) < 0 ) {
|
||||
// perror( "tcsetattr" );
|
||||
// exit( 1 );
|
||||
// }
|
||||
|
||||
if ( still_connecting() ) {
|
||||
fprintf( out_fd, "\nmosh did not make a successful connection to %s:%s.\r\n", ip.c_str(), port.c_str() );
|
||||
fprintf( out_fd, "Please verify that UDP port %s is not firewalled and can reach the server.\r\n\n", port.c_str() );
|
||||
fprintf( out_fd, "(By default, mosh uses a UDP port between 60000 and 61000. The -p option\nselects a specific UDP port number.)\r\n" );
|
||||
} else if ( network ) {
|
||||
if ( !clean_shutdown ) {
|
||||
fprintf( out_fd, "\r\n\nmosh did not shut down cleanly. Please note that the\r\nmosh-server process may still be running on the server.\r\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void iOSClient::main_init( void )
|
||||
{
|
||||
Select &sel = Select::get_instance();
|
||||
sel.add_signal( SIGWINCH );
|
||||
sel.add_signal( SIGTERM );
|
||||
sel.add_signal( SIGINT );
|
||||
sel.add_signal( SIGHUP );
|
||||
sel.add_signal( SIGPIPE );
|
||||
sel.add_signal( SIGCONT );
|
||||
|
||||
/* local state */
|
||||
local_framebuffer = new Terminal::Framebuffer( window_size->ws_col, window_size->ws_row );
|
||||
new_state = new Terminal::Framebuffer( 1, 1 );
|
||||
|
||||
/* initialize screen */
|
||||
string init = display.new_frame( false, *local_framebuffer, *local_framebuffer );
|
||||
fwrite( init.data(), init.size(), 1, out_fd );
|
||||
|
||||
/* open network */
|
||||
Network::UserStream blank;
|
||||
Terminal::Complete local_terminal( window_size->ws_col, window_size->ws_row );
|
||||
network = new Network::Transport< Network::UserStream, Terminal::Complete >( blank, local_terminal,
|
||||
key.c_str(), ip.c_str(), port.c_str() );
|
||||
|
||||
network->set_send_delay( 1 ); /* minimal delay on outgoing keystrokes */
|
||||
|
||||
/* tell server the size of the terminal */
|
||||
network->get_current_state().push_back( Parser::Resize( window_size->ws_col, window_size->ws_row ) );
|
||||
}
|
||||
|
||||
void iOSClient::output_new_frame( void )
|
||||
{
|
||||
if ( !network ) { /* clean shutdown even when not initialized */
|
||||
return;
|
||||
}
|
||||
|
||||
/* fetch target state */
|
||||
*new_state = network->get_latest_remote_state().state.get_fb();
|
||||
|
||||
/* apply local overlays */
|
||||
overlays.apply( *new_state );
|
||||
|
||||
/* apply any mutations */
|
||||
display.downgrade( *new_state );
|
||||
|
||||
/* calculate minimal difference from where we are */
|
||||
const string diff( display.new_frame( !repaint_requested,
|
||||
*local_framebuffer,
|
||||
*new_state ) );
|
||||
fwrite( diff.data(), diff.size(), 1, out_fd);
|
||||
//swrite( out_fd, diff.data(), diff.size() );
|
||||
|
||||
repaint_requested = false;
|
||||
|
||||
/* switch pointers */
|
||||
Terminal::Framebuffer *tmp = new_state;
|
||||
new_state = local_framebuffer;
|
||||
local_framebuffer = tmp;
|
||||
}
|
||||
|
||||
void iOSClient::process_network_input( void )
|
||||
{
|
||||
network->recv();
|
||||
|
||||
/* Now give hints to the overlays */
|
||||
overlays.get_notification_engine().server_heard( network->get_latest_remote_state().timestamp );
|
||||
overlays.get_notification_engine().server_acked( network->get_sent_state_acked_timestamp() );
|
||||
|
||||
overlays.get_prediction_engine().set_local_frame_acked( network->get_sent_state_acked() );
|
||||
overlays.get_prediction_engine().set_send_interval( network->send_interval() );
|
||||
overlays.get_prediction_engine().set_local_frame_late_acked( network->get_latest_remote_state().state.get_echo_ack() );
|
||||
}
|
||||
|
||||
bool iOSClient::process_user_input( int fd )
|
||||
{
|
||||
const int buf_size = 16384;
|
||||
char buf[ buf_size ];
|
||||
|
||||
/* fill buffer if possible */
|
||||
ssize_t bytes_read = read( fd, buf, buf_size );
|
||||
if ( bytes_read == 0 ) { /* EOF */
|
||||
return false;
|
||||
} else if ( bytes_read < 0 ) {
|
||||
perror( "read" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !network->shutdown_in_progress() ) {
|
||||
overlays.get_prediction_engine().set_local_frame_sent( network->get_sent_state_last() );
|
||||
|
||||
for ( int i = 0; i < bytes_read; i++ ) {
|
||||
char the_byte = buf[ i ];
|
||||
|
||||
overlays.get_prediction_engine().new_user_byte( the_byte, *local_framebuffer );
|
||||
|
||||
if ( quit_sequence_started ) {
|
||||
if ( the_byte == '.' ) { /* Quit sequence is Ctrl-^ . */
|
||||
if ( network->has_remote_addr() && (!network->shutdown_in_progress()) ) {
|
||||
overlays.get_notification_engine().set_notification_string( wstring( L"Exiting on user request..." ), true );
|
||||
network->start_shutdown();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if ( the_byte == 0x1a ) { /* Suspend sequence is escape_key Ctrl-Z */
|
||||
/* Restore terminal and terminal-driver state */
|
||||
// swrite( out_fd, display.close().c_str() );
|
||||
|
||||
// if ( tcsetattr( in_fd, TCSANOW, &saved_termios ) < 0 ) {
|
||||
// perror( "tcsetattr" );
|
||||
// exit( 1 );
|
||||
// }
|
||||
|
||||
// printf( "\n\033[37;44m[mosh is suspended.]\033[m\n" );
|
||||
|
||||
// fflush( NULL );
|
||||
|
||||
// /* actually suspend */
|
||||
// kill( 0, SIGSTOP );
|
||||
|
||||
// resume();
|
||||
} else if ( (the_byte == escape_pass_key) || (the_byte == escape_pass_key2) ) {
|
||||
/* Emulation sequence to type escape_key is escape_key +
|
||||
escape_pass_key (that is escape key without Ctrl) */
|
||||
network->get_current_state().push_back( Parser::UserByte( escape_key ) );
|
||||
} else {
|
||||
/* Escape key followed by anything other than . and ^ gets sent literally */
|
||||
network->get_current_state().push_back( Parser::UserByte( escape_key ) );
|
||||
network->get_current_state().push_back( Parser::UserByte( the_byte ) );
|
||||
}
|
||||
|
||||
quit_sequence_started = false;
|
||||
|
||||
if ( overlays.get_notification_engine().get_notification_string() == escape_key_help ) {
|
||||
overlays.get_notification_engine().set_notification_string( L"" );
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
quit_sequence_started = (escape_key > 0) && (the_byte == escape_key) && (lf_entered || (! escape_requires_lf));
|
||||
if ( quit_sequence_started ) {
|
||||
lf_entered = false;
|
||||
overlays.get_notification_engine().set_notification_string( escape_key_help, true, false );
|
||||
continue;
|
||||
}
|
||||
|
||||
lf_entered = ( (the_byte == 0x0A) || (the_byte == 0x0D) ); /* LineFeed, Ctrl-J, '\n' or CarriageReturn, Ctrl-M, '\r' */
|
||||
|
||||
if ( the_byte == 0x0C ) { /* Ctrl-L */
|
||||
repaint_requested = true;
|
||||
}
|
||||
|
||||
network->get_current_state().push_back( Parser::UserByte( the_byte ) );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool iOSClient::process_resize( void )
|
||||
{
|
||||
/* get new size */
|
||||
// if ( ioctl( in_fd, TIOCGWINSZ, &window_size ) < 0 ) {
|
||||
// perror( "ioctl TIOCGWINSZ" );
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// /* tell remote emulator */
|
||||
Parser::Resize res( window_size->ws_col, window_size->ws_row );
|
||||
|
||||
if ( !network->shutdown_in_progress() ) {
|
||||
network->get_current_state().push_back( res );
|
||||
}
|
||||
|
||||
/* note remote emulator will probably reply with its own Resize to adjust our state */
|
||||
|
||||
/* tell prediction engine */
|
||||
overlays.get_prediction_engine().reset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool iOSClient::main( void )
|
||||
{
|
||||
/* initialize signal handling and structures */
|
||||
main_init();
|
||||
|
||||
/* prepare to poll for events */
|
||||
Select &sel = Select::get_instance();
|
||||
|
||||
while ( 1 ) {
|
||||
try {
|
||||
output_new_frame();
|
||||
|
||||
int wait_time = min( network->wait_time(), overlays.wait_time() );
|
||||
|
||||
/* Handle startup "Connecting..." message */
|
||||
if ( still_connecting() ) {
|
||||
wait_time = min( 250, wait_time );
|
||||
}
|
||||
|
||||
/* poll for events */
|
||||
/* network->fd() can in theory change over time */
|
||||
sel.clear_fds();
|
||||
std::vector< int > fd_list( network->fds() );
|
||||
for ( std::vector< int >::const_iterator it = fd_list.begin();
|
||||
it != fd_list.end();
|
||||
it++ ) {
|
||||
sel.add_fd( *it );
|
||||
}
|
||||
sel.add_fd( in_fd );
|
||||
|
||||
int active_fds = sel.select( wait_time );
|
||||
if ( active_fds < 0 ) {
|
||||
perror( "select" );
|
||||
break;
|
||||
}
|
||||
|
||||
bool network_ready_to_read = false;
|
||||
|
||||
for ( std::vector< int >::const_iterator it = fd_list.begin();
|
||||
it != fd_list.end();
|
||||
it++ ) {
|
||||
if ( sel.read( *it ) ) {
|
||||
/* packet received from the network */
|
||||
/* we only read one socket each run */
|
||||
network_ready_to_read = true;
|
||||
}
|
||||
|
||||
if ( sel.error( *it ) ) {
|
||||
/* network problem */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( network_ready_to_read ) {
|
||||
process_network_input();
|
||||
}
|
||||
|
||||
if ( sel.read( in_fd ) ) {
|
||||
/* input from the user needs to be fed to the network */
|
||||
if ( !process_user_input( in_fd ) ) {
|
||||
if ( !network->has_remote_addr() ) {
|
||||
break;
|
||||
} else if ( !network->shutdown_in_progress() ) {
|
||||
overlays.get_notification_engine().set_notification_string( wstring( L"Exiting..." ), true );
|
||||
network->start_shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( sel.signal( SIGWINCH ) ) {
|
||||
/* resize */
|
||||
if ( !process_resize() ) { return false; }
|
||||
}
|
||||
|
||||
if ( sel.signal( SIGCONT ) ) {
|
||||
resume();
|
||||
}
|
||||
|
||||
if ( sel.signal( SIGTERM )
|
||||
|| sel.signal( SIGINT )
|
||||
|| sel.signal( SIGHUP )
|
||||
|| sel.signal( SIGPIPE ) ) {
|
||||
/* shutdown signal */
|
||||
if ( !network->has_remote_addr() ) {
|
||||
break;
|
||||
} else if ( !network->shutdown_in_progress() ) {
|
||||
overlays.get_notification_engine().set_notification_string( wstring( L"Signal received, shutting down..." ), true );
|
||||
network->start_shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
if ( sel.error( in_fd ) ) {
|
||||
/* user problem */
|
||||
if ( !network->has_remote_addr() ) {
|
||||
break;
|
||||
} else if ( !network->shutdown_in_progress() ) {
|
||||
overlays.get_notification_engine().set_notification_string( wstring( L"Exiting..." ), true );
|
||||
network->start_shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/* quit if our shutdown has been acknowledged */
|
||||
if ( network->shutdown_in_progress() && network->shutdown_acknowledged() ) {
|
||||
clean_shutdown = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/* quit after shutdown acknowledgement timeout */
|
||||
if ( network->shutdown_in_progress() && network->shutdown_ack_timed_out() ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* quit if we received and acknowledged a shutdown request */
|
||||
if ( network->counterparty_shutdown_ack_sent() ) {
|
||||
clean_shutdown = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/* write diagnostic message if can't reach server */
|
||||
if ( still_connecting()
|
||||
&& (!network->shutdown_in_progress())
|
||||
&& (timestamp() - network->get_latest_remote_state().timestamp > 250) ) {
|
||||
if ( timestamp() - network->get_latest_remote_state().timestamp > 15000 ) {
|
||||
if ( !network->shutdown_in_progress() ) {
|
||||
overlays.get_notification_engine().set_notification_string( wstring( L"Timed out waiting for server..." ), true );
|
||||
network->start_shutdown();
|
||||
}
|
||||
} else {
|
||||
overlays.get_notification_engine().set_notification_string( connecting_notification );
|
||||
}
|
||||
} else if ( (network->get_remote_state_num() != 0)
|
||||
&& (overlays.get_notification_engine().get_notification_string()
|
||||
== connecting_notification) ) {
|
||||
overlays.get_notification_engine().set_notification_string( L"" );
|
||||
}
|
||||
|
||||
network->tick();
|
||||
|
||||
const Network::NetworkException *exn = network->get_send_exception();
|
||||
if ( exn ) {
|
||||
overlays.get_notification_engine().set_network_exception( *exn );
|
||||
} else {
|
||||
overlays.get_notification_engine().clear_network_exception();
|
||||
}
|
||||
} catch ( const Network::NetworkException &e ) {
|
||||
if ( !network->shutdown_in_progress() ) {
|
||||
overlays.get_notification_engine().set_network_exception( e );
|
||||
}
|
||||
|
||||
struct timespec req;
|
||||
req.tv_sec = 0;
|
||||
req.tv_nsec = 200000000; /* 0.2 sec */
|
||||
nanosleep( &req, NULL );
|
||||
freeze_timestamp();
|
||||
} catch ( const Crypto::CryptoException &e ) {
|
||||
if ( e.fatal ) {
|
||||
throw;
|
||||
} else {
|
||||
wchar_t tmp[ 128 ];
|
||||
swprintf( tmp, 128, L"Crypto exception: %s", e.what() );
|
||||
overlays.get_notification_engine().set_notification_string( wstring( tmp ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
return clean_shutdown;
|
||||
}
|
||||
|
||||
148
vendor/mosh/src/frontend/iosclient.h
vendored
Normal file
148
vendor/mosh/src/frontend/iosclient.h
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#ifndef IOS_CLIENT_HPP
|
||||
#define IOS_CLIENT_HPP
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include <string>
|
||||
|
||||
#include "completeterminal.h"
|
||||
#include "networktransport.h"
|
||||
#include "user.h"
|
||||
#include "terminaloverlay.h"
|
||||
|
||||
class iOSClient {
|
||||
private:
|
||||
int in_fd;
|
||||
FILE * out_fd;
|
||||
|
||||
std::string ip;
|
||||
std::string port;
|
||||
std::string key;
|
||||
|
||||
int escape_key;
|
||||
int escape_pass_key;
|
||||
int escape_pass_key2;
|
||||
bool escape_requires_lf;
|
||||
std::wstring escape_key_help;
|
||||
|
||||
struct termios saved_termios, raw_termios;
|
||||
|
||||
struct winsize *window_size;
|
||||
|
||||
Terminal::Framebuffer *local_framebuffer, *new_state;
|
||||
Overlay::OverlayManager overlays;
|
||||
Network::Transport< Network::UserStream, Terminal::Complete > *network;
|
||||
Terminal::Display display;
|
||||
|
||||
std::wstring connecting_notification;
|
||||
bool repaint_requested, lf_entered, quit_sequence_started;
|
||||
bool clean_shutdown;
|
||||
|
||||
void main_init( void );
|
||||
void process_network_input( void );
|
||||
bool process_user_input( int fd );
|
||||
bool process_resize( void );
|
||||
|
||||
void output_new_frame( void );
|
||||
|
||||
bool still_connecting( void ) const
|
||||
{
|
||||
/* Initially, network == NULL */
|
||||
return network && ( network->get_remote_state_num() == 0 );
|
||||
}
|
||||
|
||||
void resume( void ); /* restore state after SIGCONT */
|
||||
|
||||
public:
|
||||
iOSClient( int s_in_fd, FILE * s_out_fd, struct winsize *s_window_size,
|
||||
const char *s_ip, const char *s_port, const char *s_key, const char *predict_mode )
|
||||
: in_fd( s_in_fd ), out_fd( s_out_fd ),
|
||||
ip( s_ip ), port( s_port ), key( s_key ),
|
||||
escape_key( 0x1E ), escape_pass_key( '^' ), escape_pass_key2( '^' ),
|
||||
escape_requires_lf( false ), escape_key_help( L"?" ),
|
||||
saved_termios(), raw_termios(),
|
||||
window_size( s_window_size ),
|
||||
local_framebuffer( NULL ),
|
||||
new_state( NULL ),
|
||||
overlays(),
|
||||
network( NULL ),
|
||||
display( false ), /* use TERM environment var to initialize display */
|
||||
connecting_notification(),
|
||||
repaint_requested( false ),
|
||||
lf_entered( false ),
|
||||
quit_sequence_started( false ),
|
||||
clean_shutdown( false )
|
||||
{
|
||||
if ( predict_mode ) {
|
||||
if ( !strcmp( predict_mode, "always" ) ) {
|
||||
overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Always );
|
||||
} else if ( !strcmp( predict_mode, "never" ) ) {
|
||||
overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Never );
|
||||
} else if ( !strcmp( predict_mode, "adaptive" ) ) {
|
||||
overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Adaptive );
|
||||
} else if ( !strcmp( predict_mode, "experimental" ) ) {
|
||||
overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Experimental );
|
||||
} else {
|
||||
fprintf( stderr, "Unknown prediction mode %s.\n", predict_mode );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void init( void );
|
||||
void shutdown( void );
|
||||
bool main( void );
|
||||
|
||||
~iOSClient()
|
||||
{
|
||||
if ( local_framebuffer != NULL ) {
|
||||
delete local_framebuffer;
|
||||
}
|
||||
|
||||
if ( new_state != NULL ) {
|
||||
delete new_state;
|
||||
}
|
||||
|
||||
if ( network != NULL ) {
|
||||
delete network;
|
||||
}
|
||||
}
|
||||
|
||||
/* unused */
|
||||
iOSClient( const iOSClient & );
|
||||
iOSClient & operator=( const iOSClient & );
|
||||
};
|
||||
|
||||
#endif
|
||||
197
vendor/mosh/src/frontend/mosh-client.cc
vendored
Normal file
197
vendor/mosh/src/frontend/mosh-client.cc
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "stmclient.h"
|
||||
#include "crypto.h"
|
||||
#include "locale_utils.h"
|
||||
#include "fatal_assert.h"
|
||||
|
||||
/* These need to be included last because of conflicting defines. */
|
||||
/*
|
||||
* stmclient.h includes termios.h, and that will break termio/termios pull in on Solaris.
|
||||
* The solution is to include termio.h also.
|
||||
* But Mac OS X doesn't have termio.h, so this needs a guard.
|
||||
*/
|
||||
#ifdef HAVE_TERMIO_H
|
||||
#include <termio.h>
|
||||
#endif
|
||||
|
||||
#if defined HAVE_NCURSESW_CURSES_H
|
||||
# include <ncursesw/curses.h>
|
||||
# include <ncursesw/term.h>
|
||||
#elif defined HAVE_NCURSESW_H
|
||||
# include <ncursesw.h>
|
||||
# include <term.h>
|
||||
#elif defined HAVE_NCURSES_CURSES_H
|
||||
# include <ncurses/curses.h>
|
||||
# include <ncurses/term.h>
|
||||
#elif defined HAVE_NCURSES_H
|
||||
# include <ncurses.h>
|
||||
# include <term.h>
|
||||
#elif defined HAVE_CURSES_H
|
||||
# include <curses.h>
|
||||
# include <term.h>
|
||||
#else
|
||||
# error "SysV or X/Open-compatible Curses header file required"
|
||||
#endif
|
||||
|
||||
static void usage( const char *argv0 ) {
|
||||
fprintf( stderr, "mosh-client (%s) [build %s]\n", PACKAGE_STRING, BUILD_VERSION );
|
||||
fprintf( stderr, "Copyright 2012 Keith Winstein <mosh-devel@mit.edu>\n" );
|
||||
fprintf( stderr, "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law.\n\n" );
|
||||
|
||||
fprintf( stderr, "Usage: %s IP PORT\n %s -c\n", argv0, argv0 );
|
||||
}
|
||||
|
||||
static void print_colorcount( void )
|
||||
{
|
||||
/* check colors */
|
||||
setupterm((char *)0, 1, (int *)0);
|
||||
|
||||
char colors_name[] = "colors";
|
||||
int color_val = tigetnum( colors_name );
|
||||
if ( color_val == -2 ) {
|
||||
fprintf( stderr, "Invalid terminfo numeric capability: %s\n",
|
||||
colors_name );
|
||||
}
|
||||
|
||||
printf( "%d\n", color_val );
|
||||
}
|
||||
|
||||
#ifdef NACL
|
||||
int mosh_main( int argc, char *argv[] )
|
||||
#else
|
||||
int main( int argc, char *argv[] )
|
||||
#endif
|
||||
{
|
||||
/* For security, make sure we don't dump core */
|
||||
Crypto::disable_dumping_core();
|
||||
|
||||
/* Detect edge case */
|
||||
fatal_assert( argc > 0 );
|
||||
|
||||
/* Get arguments */
|
||||
int opt;
|
||||
while ( (opt = getopt( argc, argv, "c" )) != -1 ) {
|
||||
switch ( opt ) {
|
||||
case 'c':
|
||||
print_colorcount();
|
||||
exit( 0 );
|
||||
break;
|
||||
default:
|
||||
usage( argv[ 0 ] );
|
||||
exit( 1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *ip, *desired_port;
|
||||
|
||||
if ( argc - optind != 2 ) {
|
||||
usage( argv[ 0 ] );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
ip = argv[ optind ];
|
||||
desired_port = argv[ optind + 1 ];
|
||||
|
||||
/* Sanity-check arguments */
|
||||
if ( desired_port
|
||||
&& ( strspn( desired_port, "0123456789" ) != strlen( desired_port ) ) ) {
|
||||
fprintf( stderr, "%s: Bad UDP port (%s)\n\n", argv[ 0 ], desired_port );
|
||||
usage( argv[ 0 ] );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* Read key from environment */
|
||||
char *env_key = getenv( "MOSH_KEY" );
|
||||
if ( env_key == NULL ) {
|
||||
fprintf( stderr, "MOSH_KEY environment variable not found.\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* Read prediction preference */
|
||||
char *predict_mode = getenv( "MOSH_PREDICTION_DISPLAY" );
|
||||
/* can be NULL */
|
||||
|
||||
char *key = strdup( env_key );
|
||||
if ( key == NULL ) {
|
||||
perror( "strdup" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( unsetenv( "MOSH_KEY" ) < 0 ) {
|
||||
perror( "unsetenv" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* Adopt native locale */
|
||||
set_native_locale();
|
||||
|
||||
bool success = false;
|
||||
try {
|
||||
STMClient client( fileno(stdout), fileno(stdin), ip, desired_port, key, predict_mode );
|
||||
client.init();
|
||||
|
||||
try {
|
||||
success = client.main();
|
||||
} catch ( ... ) {
|
||||
client.shutdown();
|
||||
throw;
|
||||
}
|
||||
|
||||
client.shutdown();
|
||||
} catch ( const Network::NetworkException &e ) {
|
||||
fprintf( stderr, "Network exception: %s\r\n",
|
||||
e.what() );
|
||||
success = false;
|
||||
} catch ( const Crypto::CryptoException &e ) {
|
||||
fprintf( stderr, "Crypto exception: %s\r\n",
|
||||
e.what() );
|
||||
success = false;
|
||||
} catch ( const std::exception &e ) {
|
||||
fprintf( stderr, "Error: %s\r\n", e.what() );
|
||||
success = false;
|
||||
}
|
||||
|
||||
printf( "\n[mosh is exiting.]\n" );
|
||||
|
||||
free( key );
|
||||
|
||||
return !success;
|
||||
}
|
||||
11
vendor/mosh/src/frontend/mosh-ios-controller.cc
vendored
Normal file
11
vendor/mosh/src/frontend/mosh-ios-controller.cc
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int init()
|
||||
{
|
||||
// Initialize connection using libssh
|
||||
|
||||
// Initialize input/output loop
|
||||
// Thread/file descriptor? Polling? Callbacks?
|
||||
|
||||
return 0;
|
||||
}
|
||||
934
vendor/mosh/src/frontend/mosh-server.cc
vendored
Normal file
934
vendor/mosh/src/frontend/mosh-server.cc
vendored
Normal file
@@ -0,0 +1,934 @@
|
||||
/*
|
||||
Mosh: the mobile shell
|
||||
Copyright 2012 Keith Winstein
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations including
|
||||
the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all
|
||||
of the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the
|
||||
file(s), but you are not obligated to do so. If you do not wish to do
|
||||
so, delete this exception statement from your version. If you delete
|
||||
this exception statement from all source files in the program, then
|
||||
also delete it here.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <string.h>
|
||||
#include <sstream>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <typeinfo>
|
||||
#include <signal.h>
|
||||
#ifdef HAVE_UTEMPTER
|
||||
#include <utempter.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef HAVE_UTMPX_H
|
||||
#include <utmpx.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PATHS_H
|
||||
#include <paths.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_PTY_H
|
||||
#include <pty.h>
|
||||
#elif HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
|
||||
#if FORKPTY_IN_LIBUTIL
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
|
||||
#include "completeterminal.h"
|
||||
#include "swrite.h"
|
||||
#include "user.h"
|
||||
#include "fatal_assert.h"
|
||||
#include "locale_utils.h"
|
||||
#include "pty_compat.h"
|
||||
#include "select.h"
|
||||
#include "timestamp.h"
|
||||
#include "fatal_assert.h"
|
||||
|
||||
#ifndef _PATH_BSHELL
|
||||
#define _PATH_BSHELL "/bin/sh"
|
||||
#endif
|
||||
|
||||
#include "networktransport.cc"
|
||||
|
||||
typedef Network::Transport< Terminal::Complete, Network::UserStream > ServerConnection;
|
||||
|
||||
static void serve( int host_fd,
|
||||
Terminal::Complete &terminal,
|
||||
ServerConnection &network,
|
||||
long network_timeout,
|
||||
long network_signaled_timeout );
|
||||
|
||||
static int run_server( const char *desired_ip, const char *desired_port,
|
||||
const string &command_path, char *command_argv[],
|
||||
const int colors, bool verbose, bool with_motd );
|
||||
|
||||
using namespace std;
|
||||
|
||||
static void print_usage( FILE *stream, const char *argv0 )
|
||||
{
|
||||
fprintf( stream, "Usage: %s new [-s] [-v] [-i LOCALADDR] [-p PORT[:PORT2]] [-c COLORS] [-l NAME=VALUE] [-- COMMAND...]\n", argv0 );
|
||||
}
|
||||
|
||||
static void print_motd( void );
|
||||
static void chdir_homedir( void );
|
||||
static bool motd_hushed( void );
|
||||
static void warn_unattached( const string & ignore_entry );
|
||||
|
||||
/* Simple spinloop */
|
||||
static void spin( void )
|
||||
{
|
||||
static unsigned int spincount = 0;
|
||||
spincount++;
|
||||
|
||||
if ( spincount > 10 ) {
|
||||
struct timespec req;
|
||||
req.tv_sec = 0;
|
||||
req.tv_nsec = 100000000; /* 0.1 sec */
|
||||
nanosleep( &req, NULL );
|
||||
freeze_timestamp();
|
||||
}
|
||||
}
|
||||
|
||||
static string get_SSH_IP( void )
|
||||
{
|
||||
const char *SSH_CONNECTION = getenv( "SSH_CONNECTION" );
|
||||
if ( !SSH_CONNECTION ) { /* Older sshds don't set this */
|
||||
fprintf( stderr, "Warning: SSH_CONNECTION not found; binding to any interface.\n" );
|
||||
return string( "" );
|
||||
}
|
||||
istringstream ss( SSH_CONNECTION );
|
||||
string dummy, local_interface_IP;
|
||||
ss >> dummy >> dummy >> local_interface_IP;
|
||||
if ( !ss ) {
|
||||
fprintf( stderr, "Warning: Could not parse SSH_CONNECTION; binding to any interface.\n" );
|
||||
return string( "" );
|
||||
}
|
||||
|
||||
/* Strip IPv6 prefix. */
|
||||
const char IPv6_prefix[] = "::ffff:";
|
||||
|
||||
if ( ( local_interface_IP.length() > strlen( IPv6_prefix ) )
|
||||
&& ( 0 == strncasecmp( local_interface_IP.c_str(), IPv6_prefix, strlen( IPv6_prefix ) ) ) ) {
|
||||
return local_interface_IP.substr( strlen( IPv6_prefix ) );
|
||||
}
|
||||
|
||||
return local_interface_IP;
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
/* For security, make sure we don't dump core */
|
||||
Crypto::disable_dumping_core();
|
||||
|
||||
/* Detect edge case */
|
||||
fatal_assert( argc > 0 );
|
||||
|
||||
const char *desired_ip = NULL;
|
||||
string desired_ip_str;
|
||||
const char *desired_port = NULL;
|
||||
string command_path;
|
||||
char **command_argv = NULL;
|
||||
int colors = 0;
|
||||
bool verbose = false; /* don't close stdin/stdout/stderr */
|
||||
/* Will cause mosh-server not to correctly detach on old versions of sshd. */
|
||||
list<string> locale_vars;
|
||||
|
||||
/* strip off command */
|
||||
for ( int i = 0; i < argc; i++ ) {
|
||||
if ( 0 == strcmp( argv[ i ], "--help" ) || 0 == strcmp( argv[ i ], "-h" ) ) {
|
||||
print_usage( stdout, argv[ 0 ] );
|
||||
exit( 0 );
|
||||
}
|
||||
if ( 0 == strcmp( argv[ i ], "--" ) ) { /* -- is mandatory */
|
||||
if ( i != argc - 1 ) {
|
||||
command_argv = argv + i + 1;
|
||||
}
|
||||
argc = i; /* rest of options before -- */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse new command-line syntax */
|
||||
if ( (argc >= 2)
|
||||
&& (strcmp( argv[ 1 ], "new" ) == 0) ) {
|
||||
/* new option syntax */
|
||||
int opt;
|
||||
while ( (opt = getopt( argc - 1, argv + 1, "i:p:c:svl:" )) != -1 ) {
|
||||
switch ( opt ) {
|
||||
case 'i':
|
||||
desired_ip = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
desired_port = optarg;
|
||||
break;
|
||||
case 's':
|
||||
desired_ip_str = get_SSH_IP();
|
||||
if ( !desired_ip_str.empty() ) {
|
||||
desired_ip = desired_ip_str.c_str();
|
||||
fatal_assert( desired_ip );
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
try {
|
||||
colors = myatoi( optarg );
|
||||
} catch ( const CryptoException & ) {
|
||||
fprintf( stderr, "%s: Bad number of colors (%s)\n", argv[ 0 ], optarg );
|
||||
print_usage( stderr, argv[ 0 ] );
|
||||
exit( 1 );
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
break;
|
||||
case 'l':
|
||||
locale_vars.push_back( string( optarg ) );
|
||||
break;
|
||||
default:
|
||||
print_usage( stderr, argv[ 0 ] );
|
||||
/* don't die on unknown options */
|
||||
}
|
||||
}
|
||||
} else if ( argc == 1 ) {
|
||||
/* legacy argument parsing for older client wrapper script */
|
||||
/* do nothing */
|
||||
} else if ( argc == 2 ) {
|
||||
desired_ip = argv[ 1 ];
|
||||
} else if ( argc == 3 ) {
|
||||
desired_ip = argv[ 1 ];
|
||||
desired_port = argv[ 2 ];
|
||||
} else {
|
||||
print_usage( stderr, argv[ 0 ] );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* Sanity-check arguments */
|
||||
int dpl, dph;
|
||||
if ( desired_port && ! Connection::parse_portrange( desired_port, dpl, dph ) ) {
|
||||
fprintf( stderr, "%s: Bad UDP port range (%s)\n", argv[ 0 ], desired_port );
|
||||
print_usage( stderr, argv[ 0 ] );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
bool with_motd = false;
|
||||
|
||||
/* Get shell */
|
||||
char *my_argv[ 2 ];
|
||||
string shell_name;
|
||||
if ( !command_argv ) {
|
||||
/* get shell name */
|
||||
const char *shell = getenv( "SHELL" );
|
||||
if ( shell == NULL ) {
|
||||
struct passwd *pw = getpwuid( geteuid() );
|
||||
if ( pw == NULL ) {
|
||||
perror( "getpwuid" );
|
||||
exit( 1 );
|
||||
}
|
||||
shell = pw->pw_shell;
|
||||
}
|
||||
|
||||
string shell_path( shell );
|
||||
if ( shell_path.empty() ) { /* empty shell means Bourne shell */
|
||||
shell_path = _PATH_BSHELL;
|
||||
}
|
||||
|
||||
command_path = shell_path;
|
||||
|
||||
size_t shell_slash( shell_path.rfind('/') );
|
||||
if ( shell_slash == string::npos ) {
|
||||
shell_name = shell_path;
|
||||
} else {
|
||||
shell_name = shell_path.substr(shell_slash + 1);
|
||||
}
|
||||
|
||||
/* prepend '-' to make login shell */
|
||||
shell_name = '-' + shell_name;
|
||||
|
||||
my_argv[ 0 ] = const_cast<char *>( shell_name.c_str() );
|
||||
my_argv[ 1 ] = NULL;
|
||||
command_argv = my_argv;
|
||||
|
||||
with_motd = true;
|
||||
}
|
||||
|
||||
if ( command_path.empty() ) {
|
||||
command_path = command_argv[0];
|
||||
}
|
||||
|
||||
/* Adopt implementation locale */
|
||||
set_native_locale();
|
||||
if ( !is_utf8_locale() ) {
|
||||
/* save details for diagnostic */
|
||||
LocaleVar native_ctype = get_ctype();
|
||||
string native_charset( locale_charset() );
|
||||
|
||||
/* apply locale-related environment variables from client */
|
||||
clear_locale_variables();
|
||||
for ( list<string>::const_iterator i = locale_vars.begin();
|
||||
i != locale_vars.end();
|
||||
i++ ) {
|
||||
char *env_string = strdup( i->c_str() );
|
||||
fatal_assert( env_string );
|
||||
if ( 0 != putenv( env_string ) ) {
|
||||
perror( "putenv" );
|
||||
}
|
||||
}
|
||||
|
||||
/* check again */
|
||||
set_native_locale();
|
||||
if ( !is_utf8_locale() ) {
|
||||
LocaleVar client_ctype = get_ctype();
|
||||
string client_charset( locale_charset() );
|
||||
|
||||
fprintf( stderr, "mosh-server needs a UTF-8 native locale to run.\n\n" );
|
||||
fprintf( stderr, "Unfortunately, the local environment (%s) specifies\nthe character set \"%s\",\n\n", native_ctype.str().c_str(), native_charset.c_str() );
|
||||
fprintf( stderr, "The client-supplied environment (%s) specifies\nthe character set \"%s\".\n\n", client_ctype.str().c_str(), client_charset.c_str() );
|
||||
int unused __attribute((unused)) = system( "locale" );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return run_server( desired_ip, desired_port, command_path, command_argv, colors, verbose, with_motd );
|
||||
} catch ( const Network::NetworkException &e ) {
|
||||
fprintf( stderr, "Network exception: %s\n",
|
||||
e.what() );
|
||||
return 1;
|
||||
} catch ( const Crypto::CryptoException &e ) {
|
||||
fprintf( stderr, "Crypto exception: %s\n",
|
||||
e.what() );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int run_server( const char *desired_ip, const char *desired_port,
|
||||
const string &command_path, char *command_argv[],
|
||||
const int colors, bool verbose, bool with_motd ) {
|
||||
/* get network idle timeout */
|
||||
long network_timeout = 0;
|
||||
char *timeout_envar = getenv( "MOSH_SERVER_NETWORK_TMOUT" );
|
||||
if ( timeout_envar && *timeout_envar ) {
|
||||
errno = 0;
|
||||
char *endptr;
|
||||
network_timeout = strtol( timeout_envar, &endptr, 10 );
|
||||
if ( *endptr != '\0' || ( network_timeout == 0 && errno == EINVAL ) ) {
|
||||
fprintf( stderr, "MOSH_SERVER_NETWORK_TMOUT not a valid integer, ignoring\n" );
|
||||
} else if ( network_timeout < 0 ) {
|
||||
fprintf( stderr, "MOSH_SERVER_NETWORK_TMOUT is negative, ignoring\n" );
|
||||
network_timeout = 0;
|
||||
}
|
||||
}
|
||||
/* get network signaled idle timeout */
|
||||
long network_signaled_timeout = 0;
|
||||
char *signal_envar = getenv( "MOSH_SERVER_SIGNAL_TMOUT" );
|
||||
if ( signal_envar && *signal_envar ) {
|
||||
errno = 0;
|
||||
char *endptr;
|
||||
network_signaled_timeout = strtol( signal_envar, &endptr, 10 );
|
||||
if ( *endptr != '\0' || ( network_signaled_timeout == 0 && errno == EINVAL ) ) {
|
||||
fprintf( stderr, "MOSH_SERVER_SIGNAL_TMOUT not a valid integer, ignoring\n" );
|
||||
} else if ( network_signaled_timeout < 0 ) {
|
||||
fprintf( stderr, "MOSH_SERVER_SIGNAL_TMOUT is negative, ignoring\n" );
|
||||
network_signaled_timeout = 0;
|
||||
}
|
||||
}
|
||||
/* get initial window size */
|
||||
struct winsize window_size;
|
||||
if ( ioctl( STDIN_FILENO, TIOCGWINSZ, &window_size ) < 0 ||
|
||||
window_size.ws_col == 0 ||
|
||||
window_size.ws_row == 0 ) {
|
||||
fprintf( stderr, "Server started without pseudo-terminal. Opening 80x24 terminal.\n" );
|
||||
|
||||
/* Fill in sensible defaults. */
|
||||
/* They will be overwritten by client on first connection. */
|
||||
memset( &window_size, 0, sizeof( window_size ) );
|
||||
window_size.ws_col = 80;
|
||||
window_size.ws_row = 24;
|
||||
}
|
||||
|
||||
/* open parser and terminal */
|
||||
Terminal::Complete terminal( window_size.ws_col, window_size.ws_row );
|
||||
|
||||
/* open network */
|
||||
Network::UserStream blank;
|
||||
ServerConnection *network = new ServerConnection( terminal, blank, desired_ip, desired_port );
|
||||
|
||||
if ( verbose ) {
|
||||
network->set_verbose();
|
||||
}
|
||||
|
||||
printf( "\nMOSH CONNECT %s %s\n", network->port().c_str(), network->get_key().c_str() );
|
||||
fflush( stdout );
|
||||
|
||||
/* don't let signals kill us */
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sa.sa_flags = 0;
|
||||
fatal_assert( 0 == sigfillset( &sa.sa_mask ) );
|
||||
fatal_assert( 0 == sigaction( SIGHUP, &sa, NULL ) );
|
||||
fatal_assert( 0 == sigaction( SIGPIPE, &sa, NULL ) );
|
||||
|
||||
|
||||
/* detach from terminal */
|
||||
pid_t the_pid = fork();
|
||||
if ( the_pid < 0 ) {
|
||||
perror( "fork" );
|
||||
} else if ( the_pid > 0 ) {
|
||||
_exit( 0 );
|
||||
}
|
||||
|
||||
fprintf( stderr, "\nmosh-server (%s) [build %s]\n", PACKAGE_STRING, BUILD_VERSION );
|
||||
fprintf( stderr, "Copyright 2012 Keith Winstein <mosh-devel@mit.edu>\n" );
|
||||
fprintf( stderr, "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law.\n\n" );
|
||||
|
||||
fprintf( stderr, "[mosh-server detached, pid = %d]\n", (int)getpid() );
|
||||
|
||||
int master;
|
||||
|
||||
#ifndef HAVE_IUTF8
|
||||
fprintf( stderr, "\nWarning: termios IUTF8 flag not defined.\nCharacter-erase of multibyte character sequence\nprobably does not work properly on this platform.\n" );
|
||||
#endif /* HAVE_IUTF8 */
|
||||
|
||||
/* close file descriptors */
|
||||
if ( !verbose ) {
|
||||
/* Necessary to properly detach on old versions of sshd (e.g. RHEL/CentOS 5.0). */
|
||||
int nullfd;
|
||||
|
||||
nullfd = open( "/dev/null", O_RDWR );
|
||||
if ( nullfd == -1 ) {
|
||||
perror( "open" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( dup2 ( nullfd, STDIN_FILENO ) < 0 ||
|
||||
dup2 ( nullfd, STDOUT_FILENO ) < 0 ||
|
||||
dup2 ( nullfd, STDERR_FILENO ) < 0 ) {
|
||||
perror( "dup2" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( close( nullfd ) < 0 ) {
|
||||
perror( "close" );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
char utmp_entry[ 64 ] = { 0 };
|
||||
snprintf( utmp_entry, 64, "mosh [%d]", getpid() );
|
||||
|
||||
/* Fork child process */
|
||||
pid_t child = forkpty( &master, NULL, NULL, &window_size );
|
||||
|
||||
if ( child == -1 ) {
|
||||
perror( "forkpty" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
if ( child == 0 ) {
|
||||
/* child */
|
||||
|
||||
/* reenable signals */
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sa.sa_flags = 0;
|
||||
fatal_assert( 0 == sigfillset( &sa.sa_mask ) );
|
||||
fatal_assert( 0 == sigaction( SIGHUP, &sa, NULL ) );
|
||||
fatal_assert( 0 == sigaction( SIGPIPE, &sa, NULL ) );
|
||||
|
||||
/* close server-related file descriptors */
|
||||
delete network;
|
||||
|
||||
/* set IUTF8 if available */
|
||||
#ifdef HAVE_IUTF8
|
||||
struct termios child_termios;
|
||||
if ( tcgetattr( STDIN_FILENO, &child_termios ) < 0 ) {
|
||||
perror( "tcgetattr" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
child_termios.c_iflag |= IUTF8;
|
||||
|
||||
if ( tcsetattr( STDIN_FILENO, TCSANOW, &child_termios ) < 0 ) {
|
||||
perror( "tcsetattr" );
|
||||
exit( 1 );
|
||||
}
|
||||
#endif /* HAVE_IUTF8 */
|
||||
|
||||
/* set TERM */
|
||||
const char default_term[] = "xterm";
|
||||
const char color_term[] = "xterm-256color";
|
||||
|
||||
if ( setenv( "TERM", (colors == 256) ? color_term : default_term, true ) < 0 ) {
|
||||
perror( "setenv" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* ask ncurses to send UTF-8 instead of ISO 2022 for line-drawing chars */
|
||||
if ( setenv( "NCURSES_NO_UTF8_ACS", "1", true ) < 0 ) {
|
||||
perror( "setenv" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* clear STY environment variable so GNU screen regards us as top level */
|
||||
if ( unsetenv( "STY" ) < 0 ) {
|
||||
perror( "unsetenv" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
chdir_homedir();
|
||||
|
||||
if ( with_motd && (!motd_hushed()) ) {
|
||||
print_motd();
|
||||
warn_unattached( utmp_entry );
|
||||
}
|
||||
|
||||
Crypto::reenable_dumping_core();
|
||||
|
||||
if ( execvp( command_path.c_str(), command_argv ) < 0 ) {
|
||||
perror( "execvp" );
|
||||
_exit( 1 );
|
||||
}
|
||||
} else {
|
||||
/* parent */
|
||||
|
||||
#ifdef HAVE_UTEMPTER
|
||||
/* make utmp entry */
|
||||
utempter_add_record( master, utmp_entry );
|
||||
#endif
|
||||
|
||||
try {
|
||||
serve( master, terminal, *network, network_timeout, network_signaled_timeout );
|
||||
} catch ( const Network::NetworkException &e ) {
|
||||
fprintf( stderr, "Network exception: %s\n",
|
||||
e.what() );
|
||||
} catch ( const Crypto::CryptoException &e ) {
|
||||
fprintf( stderr, "Crypto exception: %s\n",
|
||||
e.what() );
|
||||
}
|
||||
|
||||
#ifdef HAVE_UTEMPTER
|
||||
utempter_remove_record( master );
|
||||
#endif
|
||||
|
||||
if ( close( master ) < 0 ) {
|
||||
perror( "close" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
delete network;
|
||||
}
|
||||
|
||||
printf( "\n[mosh-server is exiting.]\n" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network, long network_timeout, long network_signaled_timeout )
|
||||
{
|
||||
/* scale timeouts */
|
||||
const uint64_t network_timeout_ms = static_cast<uint64_t>( network_timeout ) * 1000;
|
||||
const uint64_t network_signaled_timeout_ms = static_cast<uint64_t>( network_signaled_timeout ) * 1000;
|
||||
/* prepare to poll for events */
|
||||
Select &sel = Select::get_instance();
|
||||
sel.add_signal( SIGTERM );
|
||||
sel.add_signal( SIGINT );
|
||||
sel.add_signal( SIGUSR1 );
|
||||
|
||||
uint64_t last_remote_num = network.get_remote_state_num();
|
||||
|
||||
#ifdef HAVE_UTEMPTER
|
||||
bool connected_utmp = false;
|
||||
|
||||
Addr saved_addr;
|
||||
socklen_t saved_addr_len = 0;
|
||||
#endif
|
||||
|
||||
while ( 1 ) {
|
||||
try {
|
||||
static const uint64_t timeout_if_no_client = 60000;
|
||||
int timeout = INT_MAX;
|
||||
uint64_t now = Network::timestamp();
|
||||
|
||||
timeout = min( timeout, network.wait_time() );
|
||||
timeout = min( timeout, terminal.wait_time( now ) );
|
||||
if ( (!network.get_remote_state_num())
|
||||
|| network.shutdown_in_progress() ) {
|
||||
timeout = min( timeout, 5000 );
|
||||
}
|
||||
/*
|
||||
* The server goes completely asleep if it has no remote peer.
|
||||
* We may want to wake up sooner.
|
||||
*/
|
||||
if ( network_timeout_ms ) {
|
||||
int64_t network_sleep = network_timeout_ms -
|
||||
( now - network.get_latest_remote_state().timestamp );
|
||||
if ( network_sleep < 0 ) {
|
||||
network_sleep = 0;
|
||||
} else if ( network_sleep > INT_MAX ) {
|
||||
/* 24 days might be too soon. That's OK. */
|
||||
network_sleep = INT_MAX;
|
||||
}
|
||||
timeout = min( timeout, static_cast<int>(network_sleep) );
|
||||
}
|
||||
|
||||
/* poll for events */
|
||||
sel.clear_fds();
|
||||
std::vector< int > fd_list( network.fds() );
|
||||
assert( fd_list.size() == 1 ); /* servers don't hop */
|
||||
int network_fd = fd_list.back();
|
||||
sel.add_fd( network_fd );
|
||||
if ( !network.shutdown_in_progress() ) {
|
||||
sel.add_fd( host_fd );
|
||||
}
|
||||
|
||||
int active_fds = sel.select( timeout );
|
||||
if ( active_fds < 0 ) {
|
||||
perror( "select" );
|
||||
break;
|
||||
}
|
||||
|
||||
now = Network::timestamp();
|
||||
uint64_t time_since_remote_state = now - network.get_latest_remote_state().timestamp;
|
||||
|
||||
if ( sel.read( network_fd ) ) {
|
||||
/* packet received from the network */
|
||||
network.recv();
|
||||
|
||||
/* is new user input available for the terminal? */
|
||||
if ( network.get_remote_state_num() != last_remote_num ) {
|
||||
last_remote_num = network.get_remote_state_num();
|
||||
|
||||
string terminal_to_host;
|
||||
|
||||
Network::UserStream us;
|
||||
us.apply_string( network.get_remote_diff() );
|
||||
/* apply userstream to terminal */
|
||||
for ( size_t i = 0; i < us.size(); i++ ) {
|
||||
const Parser::Action *action = us.get_action( i );
|
||||
terminal_to_host += terminal.act( action );
|
||||
if ( typeid( *action ) == typeid( Parser::Resize ) ) {
|
||||
/* tell child process of resize */
|
||||
const Parser::Resize *res = static_cast<const Parser::Resize *>( us.get_action( i ) );
|
||||
struct winsize window_size;
|
||||
if ( ioctl( host_fd, TIOCGWINSZ, &window_size ) < 0 ) {
|
||||
perror( "ioctl TIOCGWINSZ" );
|
||||
return;
|
||||
}
|
||||
window_size.ws_col = res->width;
|
||||
window_size.ws_row = res->height;
|
||||
if ( ioctl( host_fd, TIOCSWINSZ, &window_size ) < 0 ) {
|
||||
perror( "ioctl TIOCSWINSZ" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !us.empty() ) {
|
||||
/* register input frame number for future echo ack */
|
||||
terminal.register_input_frame( last_remote_num, now );
|
||||
}
|
||||
|
||||
/* update client with new state of terminal */
|
||||
if ( !network.shutdown_in_progress() ) {
|
||||
network.set_current_state( terminal );
|
||||
}
|
||||
|
||||
/* write any writeback octets back to the host */
|
||||
if ( swrite( host_fd, terminal_to_host.c_str(), terminal_to_host.length() ) < 0 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_UTEMPTER
|
||||
/* update utmp entry if we have become "connected" */
|
||||
if ( (!connected_utmp)
|
||||
|| saved_addr_len != network.get_remote_addr_len()
|
||||
|| memcmp( &saved_addr, &network.get_remote_addr(),
|
||||
saved_addr_len ) != 0 ) {
|
||||
utempter_remove_record( host_fd );
|
||||
|
||||
saved_addr = network.get_remote_addr();
|
||||
saved_addr_len = network.get_remote_addr_len();
|
||||
|
||||
char host[ NI_MAXHOST ];
|
||||
int errcode = getnameinfo( &saved_addr.sa, saved_addr_len,
|
||||
host, sizeof( host ), NULL, 0,
|
||||
NI_NUMERICHOST );
|
||||
if ( errcode != 0 ) {
|
||||
throw NetworkException( std::string( "serve: getnameinfo: " ) + gai_strerror( errcode ), 0 );
|
||||
}
|
||||
|
||||
char tmp[ 64 ];
|
||||
snprintf( tmp, 64, "%s via mosh [%d]", host, getpid() );
|
||||
utempter_add_record( host_fd, tmp );
|
||||
|
||||
connected_utmp = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if ( (!network.shutdown_in_progress()) && sel.read( host_fd ) ) {
|
||||
/* input from the host needs to be fed to the terminal */
|
||||
const int buf_size = 16384;
|
||||
char buf[ buf_size ];
|
||||
|
||||
/* fill buffer if possible */
|
||||
ssize_t bytes_read = read( host_fd, buf, buf_size );
|
||||
|
||||
/* If the pty slave is closed, reading from the master can fail with
|
||||
EIO (see #264). So we treat errors on read() like EOF. */
|
||||
if ( bytes_read <= 0 ) {
|
||||
network.start_shutdown();
|
||||
} else {
|
||||
string terminal_to_host = terminal.act( string( buf, bytes_read ) );
|
||||
|
||||
/* update client with new state of terminal */
|
||||
network.set_current_state( terminal );
|
||||
|
||||
/* write any writeback octets back to the host */
|
||||
if ( swrite( host_fd, terminal_to_host.c_str(), terminal_to_host.length() ) < 0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool idle_shutdown = false;
|
||||
if ( network_timeout_ms &&
|
||||
network_timeout_ms <= time_since_remote_state ) {
|
||||
idle_shutdown = true;
|
||||
fprintf( stderr, "Network idle for %" PRIu64 " seconds.\n", time_since_remote_state / 1000 );
|
||||
}
|
||||
if ( sel.signal( SIGUSR1 ) ) {
|
||||
if ( !network_signaled_timeout_ms || network_signaled_timeout_ms <= time_since_remote_state ) {
|
||||
idle_shutdown = true;
|
||||
fprintf( stderr, "Network idle for %"PRIu64" seconds when SIGUSR1 received\n", time_since_remote_state / 1000 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( sel.any_signal() || idle_shutdown ) {
|
||||
/* shutdown signal */
|
||||
if ( network.has_remote_addr() && (!network.shutdown_in_progress()) ) {
|
||||
network.start_shutdown();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( sel.error( network_fd ) ) {
|
||||
/* network problem */
|
||||
break;
|
||||
}
|
||||
|
||||
if ( (!network.shutdown_in_progress()) && sel.error( host_fd ) ) {
|
||||
/* host problem */
|
||||
network.start_shutdown();
|
||||
}
|
||||
|
||||
/* quit if our shutdown has been acknowledged */
|
||||
if ( network.shutdown_in_progress() && network.shutdown_acknowledged() ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* quit after shutdown acknowledgement timeout */
|
||||
if ( network.shutdown_in_progress() && network.shutdown_ack_timed_out() ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* quit if we received and acknowledged a shutdown request */
|
||||
if ( network.counterparty_shutdown_ack_sent() ) {
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_UTEMPTER
|
||||
/* update utmp if has been more than 30 seconds since heard from client */
|
||||
if ( connected_utmp ) {
|
||||
if ( time_since_remote_state > 30000 ) {
|
||||
utempter_remove_record( host_fd );
|
||||
|
||||
char tmp[ 64 ];
|
||||
snprintf( tmp, 64, "mosh [%d]", getpid() );
|
||||
utempter_add_record( host_fd, tmp );
|
||||
|
||||
connected_utmp = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( terminal.set_echo_ack( now ) ) {
|
||||
/* update client with new echo ack */
|
||||
if ( !network.shutdown_in_progress() ) {
|
||||
network.set_current_state( terminal );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !network.get_remote_state_num()
|
||||
&& time_since_remote_state >= timeout_if_no_client ) {
|
||||
fprintf( stderr, "No connection within %" PRIu64 " seconds.\n",
|
||||
timeout_if_no_client / 1000 );
|
||||
break;
|
||||
}
|
||||
|
||||
network.tick();
|
||||
} catch ( const Network::NetworkException &e ) {
|
||||
fprintf( stderr, "%s\n", e.what() );
|
||||
spin();
|
||||
} catch ( const Crypto::CryptoException &e ) {
|
||||
if ( e.fatal ) {
|
||||
throw;
|
||||
} else {
|
||||
fprintf( stderr, "Crypto exception: %s\n", e.what() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* OpenSSH prints the motd on startup, so we will too */
|
||||
static void print_motd( void )
|
||||
{
|
||||
FILE *motd = fopen( "/etc/motd", "r" );
|
||||
if ( !motd ) {
|
||||
return; /* don't report error on missing or forbidden motd */
|
||||
}
|
||||
|
||||
const int BUFSIZE = 256;
|
||||
|
||||
char buffer[ BUFSIZE ];
|
||||
while ( 1 ) {
|
||||
size_t bytes_read = fread( buffer, 1, BUFSIZE, motd );
|
||||
if ( bytes_read == 0 ) {
|
||||
break; /* don't report error */
|
||||
}
|
||||
size_t bytes_written = fwrite( buffer, 1, bytes_read, stdout );
|
||||
if ( bytes_written == 0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose( motd );
|
||||
}
|
||||
|
||||
static void chdir_homedir( void )
|
||||
{
|
||||
const char *home = getenv( "HOME" );
|
||||
if ( home == NULL ) {
|
||||
struct passwd *pw = getpwuid( geteuid() );
|
||||
if ( pw == NULL ) {
|
||||
perror( "getpwuid" );
|
||||
return; /* non-fatal */
|
||||
}
|
||||
home = pw->pw_dir;
|
||||
}
|
||||
|
||||
if ( chdir( home ) < 0 ) {
|
||||
perror( "chdir" );
|
||||
}
|
||||
|
||||
if ( setenv( "PWD", home, 1 ) < 0 ) {
|
||||
perror( "setenv" );
|
||||
}
|
||||
}
|
||||
|
||||
static bool motd_hushed( void )
|
||||
{
|
||||
/* must be in home directory already */
|
||||
struct stat buf;
|
||||
return (0 == lstat( ".hushlogin", &buf ));
|
||||
}
|
||||
|
||||
static bool device_exists( const char *ut_line )
|
||||
{
|
||||
string device_name = string( "/dev/" ) + string( ut_line );
|
||||
struct stat buf;
|
||||
return (0 == lstat( device_name.c_str(), &buf ));
|
||||
}
|
||||
|
||||
static void warn_unattached( const string & ignore_entry )
|
||||
{
|
||||
#ifdef HAVE_UTMPX_H
|
||||
/* get username */
|
||||
const struct passwd *pw = getpwuid( geteuid() );
|
||||
if ( pw == NULL ) {
|
||||
perror( "getpwuid" );
|
||||
/* non-fatal */
|
||||
return;
|
||||
}
|
||||
|
||||
const string username( pw->pw_name );
|
||||
|
||||
/* look for unattached sessions */
|
||||
vector< string > unattached_mosh_servers;
|
||||
|
||||
while ( struct utmpx *entry = getutxent() ) {
|
||||
if ( (entry->ut_type == USER_PROCESS)
|
||||
&& (username == string( entry->ut_user )) ) {
|
||||
/* does line show unattached mosh session */
|
||||
string text( entry->ut_host );
|
||||
if ( (text.size() >= 5)
|
||||
&& (text.substr( 0, 5 ) == "mosh ")
|
||||
&& (text[ text.size() - 1 ] == ']')
|
||||
&& (text != ignore_entry)
|
||||
&& device_exists( entry->ut_line ) ) {
|
||||
unattached_mosh_servers.push_back( text );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* print out warning if necessary */
|
||||
if ( unattached_mosh_servers.empty() ) {
|
||||
return;
|
||||
} else if ( unattached_mosh_servers.size() == 1 ) {
|
||||
printf( "\033[37;44mMosh: You have a detached Mosh session on this server (%s).\033[m\n\n",
|
||||
unattached_mosh_servers.front().c_str() );
|
||||
} else {
|
||||
string pid_string;
|
||||
|
||||
for ( vector< string >::const_iterator it = unattached_mosh_servers.begin();
|
||||
it != unattached_mosh_servers.end();
|
||||
it++ ) {
|
||||
pid_string += " - " + *it + "\n";
|
||||
}
|
||||
|
||||
printf( "\033[37;44mMosh: You have %d detached Mosh sessions on this server, with PIDs:\n%s\033[m\n",
|
||||
(int)unattached_mosh_servers.size(), pid_string.c_str() );
|
||||
}
|
||||
#endif /* HAVE_UTMPX_H */
|
||||
}
|
||||
459
vendor/mosh/src/frontend/mosh.cc
vendored
Normal file
459
vendor/mosh/src/frontend/mosh.cc
vendored
Normal file
@@ -0,0 +1,459 @@
|
||||
// Mosh: the mobile shell
|
||||
// Copyright 2012 Keith Winstein
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
//#include <vector>
|
||||
//#include <map>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <sys/socket.h>
|
||||
#include <getopt.h>
|
||||
#include <arpa/inet.h>
|
||||
// #include <netdb.h>
|
||||
//#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <libssh2.h>
|
||||
//#include <sys/ioctl.h>
|
||||
//#include <sys/types.h>
|
||||
//#include <sys/wait.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "iosclient.h"
|
||||
#include "terminalbridge.h"
|
||||
#include "locale_utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void die( const char *format, ... ) {
|
||||
va_list args;
|
||||
va_start( args, format );
|
||||
vfprintf( stderr, format, args );
|
||||
va_end( args );
|
||||
fprintf( stderr, "\n" );
|
||||
exit( 255 );
|
||||
}
|
||||
|
||||
static const char *usage_format =
|
||||
"Usage: %s [options] [--] [user@]host [command...]\n"
|
||||
" --client=PATH mosh client on local machine\n"
|
||||
" (default: mosh-client)\n"
|
||||
" --server=PATH mosh server on remote machine\n"
|
||||
" (default: mosh-server)\n"
|
||||
"\n"
|
||||
" --predict=adaptive local echo for slower links [default]\n"
|
||||
"-a --predict=always use local echo even on fast links\n"
|
||||
"-n --predict=never never use local echo\n"
|
||||
"\n"
|
||||
"-p NUM --port=NUM server-side UDP port\n"
|
||||
"\n"
|
||||
" --ssh=COMMAND ssh command to run when setting up session\n"
|
||||
" (example: \"ssh -p 2222\")\n"
|
||||
" (default: \"ssh\")\n"
|
||||
"\n"
|
||||
" --help this message\n"
|
||||
" --version version and copyright information\n"
|
||||
"\n"
|
||||
"Please report bugs to mosh-devel@mit.edu.\n"
|
||||
"Mosh home page: http://mosh.mit.edu";
|
||||
|
||||
static const char *version_format =
|
||||
"mosh %s\n"
|
||||
"Copyright 2012 Keith Winstein <mosh-devel@mit.edu>\n"
|
||||
"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n"
|
||||
"This is free software: you are free to change and redistribute it.\n"
|
||||
"There is NO WARRANTY, to the extent permitted by law.";
|
||||
|
||||
static const char *key_valid_char_set =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/+";
|
||||
|
||||
static char *argv0;
|
||||
|
||||
void predict_check( const string &predict, bool env_set )
|
||||
{
|
||||
if ( predict != "adaptive" &&
|
||||
predict != "always" &&
|
||||
predict != "never" ) {
|
||||
fprintf( stderr, "%s: Unknown mode \"%s\"%s.\n", argv0, predict.c_str(),
|
||||
env_set ? " (MOSH_PREDICTION_DISPLAY in environment)" : "" );
|
||||
die( usage_format, argv0 );
|
||||
}
|
||||
}
|
||||
|
||||
void cat( int ifd, int ofd )
|
||||
{
|
||||
char buf[4096];
|
||||
ssize_t n;
|
||||
while ( 1 ) {
|
||||
n = read( ifd, buf, sizeof( buf ) );
|
||||
if ( n==-1 ) {
|
||||
if (errno == EINTR ) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( n==0 ) {
|
||||
break;
|
||||
}
|
||||
n = write( ofd, buf, n );
|
||||
if ( n==-1 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
fd_set fd;
|
||||
fd_set *writefd = NULL;
|
||||
fd_set *readfd = NULL;
|
||||
int dir;
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
|
||||
FD_SET(socket_fd, &fd);
|
||||
|
||||
/* now make sure we wait in the correct direction */
|
||||
dir = libssh2_session_block_directions(session);
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
||||
readfd = &fd;
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
||||
writefd = &fd;
|
||||
|
||||
rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
argv0 = argv[0];
|
||||
// TODO: Make constants
|
||||
string client = "mosh-client";
|
||||
string server = "mosh-server";
|
||||
string ssh = "ssh";
|
||||
string predict, port_request;
|
||||
int help=0, version=0, fake_proxy=0;
|
||||
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{ "client", required_argument, 0, 'c' },
|
||||
{ "server", required_argument, 0, 's' },
|
||||
{ "predict", required_argument, 0, 'r' },
|
||||
{ "port", required_argument, 0, 'p' },
|
||||
{ "ssh", required_argument, 0, 'S' },
|
||||
{ "help", no_argument, &help, 1 },
|
||||
{ "version", no_argument, &version, 1 },
|
||||
{ "fake-proxy!", no_argument, &fake_proxy, 1 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
// TODO: Bootstrap func with opt parameters
|
||||
while ( 1 ) {
|
||||
int option_index = 0;
|
||||
int c = getopt_long( argc, argv, "anp:",
|
||||
long_options, &option_index );
|
||||
if ( c == -1 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( c ) {
|
||||
case 0:
|
||||
// flag has been set
|
||||
break;
|
||||
case 'c':
|
||||
client = optarg;
|
||||
break;
|
||||
case 's':
|
||||
server = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
predict = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
port_request = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
ssh = optarg;
|
||||
break;
|
||||
case 'a':
|
||||
predict = "always";
|
||||
break;
|
||||
case 'n':
|
||||
predict = "never";
|
||||
break;
|
||||
default:
|
||||
die( usage_format, argv[0] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( help ) {
|
||||
die( usage_format, argv[0] );
|
||||
}
|
||||
if ( version ) {
|
||||
die( version_format, PACKAGE_VERSION );
|
||||
}
|
||||
// TODO: Force predictive to adaptive
|
||||
if ( predict.size() ) {
|
||||
predict_check( predict, 0 );
|
||||
} else if ( getenv( "MOSH_PREDICTION_DELAY" ) ) {
|
||||
predict = getenv( "MOSH_PREDICTION_DELAY" );
|
||||
predict_check( predict, 1 );
|
||||
} else {
|
||||
predict = "adaptive";
|
||||
predict_check( predict, 0 );
|
||||
}
|
||||
|
||||
// TODO: Accept port request from value on field
|
||||
if ( port_request.size() ) {
|
||||
if ( port_request.find_first_not_of( "0123456789" ) != string::npos ||
|
||||
atoi( port_request.c_str() ) < 0 ||
|
||||
atoi( port_request.c_str() ) > 65535 ) {
|
||||
die( "%s: Server-side port (%s) must be within valid range [0..65535].",
|
||||
argv[0],
|
||||
port_request.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
unsetenv( "MOSH_PREDICTION_DISPLAY" );
|
||||
|
||||
//string userhost = argv[optind++];
|
||||
// Create ssh connection with those parameters
|
||||
struct sockaddr_in sin;
|
||||
int sock;
|
||||
|
||||
const char *host = "127.0.0.1";
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
int rc;
|
||||
unsigned long hostaddr;
|
||||
|
||||
hostaddr = inet_addr(host);
|
||||
|
||||
// Connect to port on host
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(22); // TODO: Use a custom ssh port
|
||||
sin.sin_addr.s_addr = hostaddr; // !! Always an IP address
|
||||
|
||||
if ((rc = connect(sock, (struct sockaddr*)(&sin),
|
||||
sizeof(struct sockaddr_in))) != 0) {
|
||||
die("failed to open socket for ssh connection!\n");
|
||||
}
|
||||
|
||||
session = libssh2_session_init();
|
||||
if (!session) {
|
||||
die("create session failed");
|
||||
}
|
||||
|
||||
// tell libssh2 we want it all done none non-blocking
|
||||
libssh2_session_set_blocking(session, 0);
|
||||
|
||||
// ... start it up. This will trade welcome banners, exchange keys,
|
||||
// and setup crypto, compression, and MAC layers
|
||||
while ((rc = libssh2_session_handshake(session, sock)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
die("Session handshake failed");
|
||||
}
|
||||
|
||||
const char *username = "simple";
|
||||
const char *password = "n0th1ng-more.";
|
||||
|
||||
//ignore knownhosts, etc... although we should save them on a file
|
||||
//libssh2_knownhost_init(...) [..]
|
||||
|
||||
while ((rc = libssh2_userauth_password(session, username, password)) ==
|
||||
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
die("Wrong password");
|
||||
}
|
||||
// while ((rc = libssh2_userauth_publickey_fromfile(session, username,
|
||||
// "/home/carlos/.ssh/id_rsa.pub",
|
||||
// "/home/carlos/.ssh/id_rsa",
|
||||
// password)) == LIBSSH2_ERROR_EAGAIN);
|
||||
// if (rc) {
|
||||
// die("Authentication failed");
|
||||
// }
|
||||
|
||||
/* Exec non-blocking on the remote host */
|
||||
while( (channel = libssh2_channel_open_session(session)) == NULL &&
|
||||
libssh2_session_last_error(session,NULL,NULL,0) ==
|
||||
LIBSSH2_ERROR_EAGAIN )
|
||||
{
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if( channel == NULL )
|
||||
{
|
||||
die("No channel found\n");
|
||||
}
|
||||
|
||||
// TODO: Add parameters to the server?
|
||||
// TODO: Fix color configuration
|
||||
const char *commandline = "mosh-server new";
|
||||
|
||||
while( (rc = libssh2_channel_exec(channel, commandline)) ==
|
||||
LIBSSH2_ERROR_EAGAIN )
|
||||
{
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if( rc != 0 )
|
||||
{
|
||||
die("Error executing command\n");
|
||||
}
|
||||
|
||||
string result;
|
||||
for( ;; )
|
||||
{
|
||||
/* loop until we block */
|
||||
int rc;
|
||||
do
|
||||
{
|
||||
char buffer[0x4000];
|
||||
rc = libssh2_channel_read( channel, buffer, sizeof(buffer) );
|
||||
|
||||
if( rc > 0 )
|
||||
{
|
||||
result.append(buffer);
|
||||
}
|
||||
else {
|
||||
if( rc != LIBSSH2_ERROR_EAGAIN )
|
||||
/* no need to output this for the EAGAIN case */
|
||||
fprintf(stderr, "libssh2_channel_read returned %d\n", rc);
|
||||
}
|
||||
}
|
||||
while( rc > 0 );
|
||||
|
||||
/* this is due to blocking that would occur otherwise so we loop on
|
||||
this condition */
|
||||
if( rc == LIBSSH2_ERROR_EAGAIN )
|
||||
{
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
// Close channel
|
||||
while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
|
||||
waitsocket(sock, session);
|
||||
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
|
||||
// Shutdown session
|
||||
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
|
||||
libssh2_session_free(session);
|
||||
|
||||
close(sock);
|
||||
libssh2_exit();
|
||||
|
||||
// TODO: It would be great to use the ssh conn and read in parallel, to save
|
||||
// any race conditions or other conditions.
|
||||
printf("%s", result.c_str());
|
||||
string ip(host), port, key;
|
||||
string line;
|
||||
std::istringstream response(result);
|
||||
while (std::getline(response, line)) {
|
||||
// Not needed as we use a real IP address.
|
||||
// if ( line.compare( 0, 8, "MOSH IP " ) == 0 ) { // MOSH IP 127.0.0.1
|
||||
// size_t ip_end = line.find_last_not_of( " \t\n\r" );
|
||||
// if ( ip_end != string::npos && ip_end >= 8 ) {
|
||||
// ip = line.substr( 8, ip_end + 1 - 8 );
|
||||
// }
|
||||
// } else
|
||||
if ( line.compare( 0, 13, "MOSH CONNECT " ) == 0 ) { // MOSH CONNECT 60002 0P/WOaijf73SUDP40RXG0A\r
|
||||
size_t port_end = line.find_first_not_of( "0123456789", 13 );
|
||||
if ( port_end != string::npos && port_end >= 13 ) {
|
||||
port = line.substr( 13, port_end - 13 );
|
||||
}
|
||||
string rest = line.substr( port_end + 1 );
|
||||
size_t key_end = rest.find_last_not_of( " \t\n\r" );
|
||||
size_t key_valid_end = rest.find_last_of( key_valid_char_set );
|
||||
if ( key_valid_end == key_end && key_end + 1 == 22 ) {
|
||||
key = rest.substr( 0, key_end + 1 );
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
printf( "%s\n", line.c_str() );
|
||||
}
|
||||
}
|
||||
printf( "Connecting to %s, with key %s\n", ip.c_str(), key.c_str());
|
||||
|
||||
// TODO: Make sure we have an IP address
|
||||
if ( !ip.size() ) {
|
||||
die( "%s: Did not find remote IP address (is SSH ProxyCommand disabled?).",
|
||||
argv[0] );
|
||||
}
|
||||
|
||||
if ( !key.size() || !port.size() ) {
|
||||
die( "%s: Did not find mosh server startup message.", argv[0] );
|
||||
}
|
||||
|
||||
printf("Good to go! Starting Mosh\n");
|
||||
|
||||
/* Adopt native locale */
|
||||
set_native_locale();
|
||||
|
||||
bool success = false;
|
||||
try {
|
||||
iOSClient client(fileno(stdin), fileno(stdout),
|
||||
ip.c_str(), port.c_str(),
|
||||
strdup(key.c_str()), predict.c_str() );
|
||||
// STMClient client( ip.c_str(), port.c_str(),
|
||||
// strdup(key.c_str()), predict.c_str() );
|
||||
client.init();
|
||||
|
||||
try {
|
||||
success = client.main();
|
||||
} catch ( ... ) {
|
||||
client.shutdown();
|
||||
throw;
|
||||
}
|
||||
|
||||
client.shutdown();
|
||||
} catch ( const Network::NetworkException &e ) {
|
||||
fprintf( stderr, "Network exception: %s\r\n",
|
||||
e.what() );
|
||||
success = false;
|
||||
} catch ( const Crypto::CryptoException &e ) {
|
||||
fprintf( stderr, "Crypto exception: %s\r\n",
|
||||
e.what() );
|
||||
success = false;
|
||||
} catch ( const std::exception &e ) {
|
||||
fprintf( stderr, "Error: %s\r\n", e.what() );
|
||||
success = false;
|
||||
}
|
||||
|
||||
printf( "\n[mosh is exiting.]\n" );
|
||||
|
||||
//free( key );
|
||||
|
||||
return !success;
|
||||
}
|
||||
43
vendor/mosh/src/frontend/moshiosbridge.cc
vendored
Normal file
43
vendor/mosh/src/frontend/moshiosbridge.cc
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "moshiosbridge.h"
|
||||
#include "iosclient.h"
|
||||
#include "locale_utils.h"
|
||||
|
||||
extern "C"
|
||||
int mosh_main(FILE *f_in, FILE *f_out, struct winsize *window_size,
|
||||
const char *ip, const char *port, const char *key, const char *predict_mode)
|
||||
{
|
||||
fwrite("Hello from the Bridge!\n", 22, 1, f_out);
|
||||
/* Adopt native locale */
|
||||
set_native_locale();
|
||||
|
||||
bool success = false;
|
||||
try {
|
||||
iOSClient client(fileno(f_in), f_out, window_size,
|
||||
ip, port, key, predict_mode);
|
||||
// STMClient client( ip.c_str(), port.c_str(),
|
||||
// strdup(key.c_str()), predict.c_str() );
|
||||
client.init();
|
||||
|
||||
try {
|
||||
success = client.main();
|
||||
} catch ( ... ) {
|
||||
client.shutdown();
|
||||
throw;
|
||||
}
|
||||
|
||||
client.shutdown();
|
||||
} catch ( const Network::NetworkException &e ) {
|
||||
fprintf( stderr, "Network exception: %s\r\n",
|
||||
e.what() );
|
||||
success = false;
|
||||
} catch ( const Crypto::CryptoException &e ) {
|
||||
fprintf( stderr, "Crypto exception: %s\r\n",
|
||||
e.what() );
|
||||
success = false;
|
||||
} catch ( const std::exception &e ) {
|
||||
fprintf( stderr, "Error: %s\r\n", e.what() );
|
||||
success = false;
|
||||
}
|
||||
|
||||
return !success;
|
||||
}
|
||||
13
vendor/mosh/src/frontend/moshiosbridge.h
vendored
Normal file
13
vendor/mosh/src/frontend/moshiosbridge.h
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef MOSHIOSBRIDGE_HPP
|
||||
#define MOSHIOSBRIDGE_HPP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#if __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
int mosh_main(FILE *f_in, FILE *f_out, struct winsize *window_size,
|
||||
const char *ip, const char *port, const char *key, const char *predict_mode);
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user