zmodem support (fixes #693)

This commit is contained in:
Eugene Pankov
2019-12-31 20:10:37 +01:00
parent c11a10144e
commit c40294628a
9 changed files with 251 additions and 34 deletions

View File

@@ -30,8 +30,8 @@ export interface ChildProcess {
const windowsDirectoryRegex = /([a-zA-Z]:[^\:\[\]\?\"\<\>\|]+)/mi
const catalinaDataVolumePrefix = '/System/Volumes/Data'
const OSC1337Prefix = '\x1b]1337;'
const OSC1337Suffix = '\x07'
const OSC1337Prefix = Buffer.from('\x1b]1337;')
const OSC1337Suffix = Buffer.from('\x07')
/**
* A session object for a [[BaseTerminalTabComponent]]
@@ -42,27 +42,31 @@ export abstract class BaseSession {
name: string
truePID: number
protected output = new Subject<string>()
protected binaryOutput = new Subject<Buffer>()
protected closed = new Subject<void>()
protected destroyed = new Subject<void>()
private initialDataBuffer = ''
private initialDataBuffer = Buffer.from('')
private initialDataBufferReleased = false
get output$ (): Observable<string> { return this.output }
get binaryOutput$ (): Observable<Buffer> { return this.binaryOutput }
get closed$ (): Observable<void> { return this.closed }
get destroyed$ (): Observable<void> { return this.destroyed }
emitOutput (data: string) {
emitOutput (data: Buffer) {
if (!this.initialDataBufferReleased) {
this.initialDataBuffer += data
this.initialDataBuffer = Buffer.concat([this.initialDataBuffer, data])
} else {
this.output.next(data)
this.output.next(data.toString())
this.binaryOutput.next(data)
}
}
releaseInitialDataBuffer () {
this.initialDataBufferReleased = true
this.output.next(this.initialDataBuffer)
this.initialDataBuffer = ''
this.output.next(this.initialDataBuffer.toString())
this.binaryOutput.next(this.initialDataBuffer)
this.initialDataBuffer = Buffer.from('')
}
async destroy (): Promise<void> {
@@ -71,6 +75,7 @@ export abstract class BaseSession {
this.closed.next()
this.destroyed.next()
this.output.complete()
this.binaryOutput.complete()
await this.gracefullyKillProcess()
}
}
@@ -129,6 +134,7 @@ export class Session extends BaseSession {
name: 'xterm-256color',
cols: options.width || 80,
rows: options.height || 30,
encoding: null,
cwd,
env: env,
// `1` instead of `true` forces ConPTY even if unstable
@@ -150,11 +156,11 @@ export class Session extends BaseSession {
this.open = true
this.pty.on('data-buffered', data => {
this.pty.on('data-buffered', (data: Buffer) => {
data = this.processOSC1337(data)
this.emitOutput(data)
if (process.platform === 'win32') {
this.guessWindowsCWD(data)
this.guessWindowsCWD(data.toString())
}
})
@@ -168,7 +174,7 @@ export class Session extends BaseSession {
this.pty.on('close', () => {
if (this.pauseAfterExit) {
this.emitOutput('\r\nPress any key to close\r\n')
this.emitOutput(Buffer.from('\r\nPress any key to close\r\n'))
} else if (this.open) {
this.destroy()
}
@@ -177,19 +183,19 @@ export class Session extends BaseSession {
this.pauseAfterExit = options.pauseAfterExit || false
}
processOSC1337 (data: string) {
processOSC1337 (data: Buffer) {
if (data.includes(OSC1337Prefix)) {
const preData = data.substring(0, data.indexOf(OSC1337Prefix))
let params = data.substring(data.indexOf(OSC1337Prefix) + OSC1337Prefix.length)
const postData = params.substring(params.indexOf(OSC1337Suffix) + OSC1337Suffix.length)
params = params.substring(0, params.indexOf(OSC1337Suffix))
const preData = data.subarray(0, data.indexOf(OSC1337Prefix))
let params = data.subarray(data.indexOf(OSC1337Prefix) + OSC1337Prefix.length)
const postData = params.subarray(params.indexOf(OSC1337Suffix) + OSC1337Suffix.length)
const paramString = params.subarray(0, params.indexOf(OSC1337Suffix)).toString()
if (params.startsWith('CurrentDir=')) {
this.reportedCWD = params.split('=')[1]
if (paramString.startsWith('CurrentDir=')) {
this.reportedCWD = paramString.split('=')[1]
if (this.reportedCWD.startsWith('~')) {
this.reportedCWD = os.homedir() + this.reportedCWD.substring(1)
}
data = preData + postData
data = Buffer.concat([preData, postData])
}
}
return data