preserve file modes for up- and downloads - fixes #4141

上级 3e61630c
...@@ -21,6 +21,7 @@ export interface MessageBoxResult { ...@@ -21,6 +21,7 @@ export interface MessageBoxResult {
export abstract class FileTransfer { export abstract class FileTransfer {
abstract getName (): string abstract getName (): string
abstract getMode (): number
abstract getSize (): number abstract getSize (): number
abstract close (): void abstract close (): void
...@@ -95,7 +96,7 @@ export abstract class PlatformService { ...@@ -95,7 +96,7 @@ export abstract class PlatformService {
abstract loadConfig (): Promise<string> abstract loadConfig (): Promise<string>
abstract saveConfig (content: string): Promise<void> abstract saveConfig (content: string): Promise<void>
abstract startDownload (name: string, size: number): Promise<FileDownload|null> abstract startDownload (name: string, mode: number, size: number): Promise<FileDownload|null>
abstract startUpload (options?: FileUploadOptions): Promise<FileUpload[]> abstract startUpload (options?: FileUploadOptions): Promise<FileUpload[]>
startUploadFromDragEvent (event: DragEvent, multiple = false): FileUpload[] { startUploadFromDragEvent (event: DragEvent, multiple = false): FileUpload[] {
...@@ -188,6 +189,10 @@ export class HTMLFileUpload extends FileUpload { ...@@ -188,6 +189,10 @@ export class HTMLFileUpload extends FileUpload {
return this.file.name return this.file.name
} }
getMode (): number {
return 0o644
}
getSize (): number { getSize (): number {
return this.file.size return this.file.size
} }
......
...@@ -205,7 +205,7 @@ export class ElectronPlatformService extends PlatformService { ...@@ -205,7 +205,7 @@ export class ElectronPlatformService extends PlatformService {
})) }))
} }
async startDownload (name: string, size: number): Promise<FileDownload|null> { async startDownload (name: string, mode: number, size: number): Promise<FileDownload|null> {
const result = await this.electron.dialog.showSaveDialog( const result = await this.electron.dialog.showSaveDialog(
this.hostWindow.getWindow(), this.hostWindow.getWindow(),
{ {
...@@ -215,7 +215,7 @@ export class ElectronPlatformService extends PlatformService { ...@@ -215,7 +215,7 @@ export class ElectronPlatformService extends PlatformService {
if (!result.filePath) { if (!result.filePath) {
return null return null
} }
const transfer = new ElectronFileDownload(result.filePath, size) const transfer = new ElectronFileDownload(result.filePath, mode, size)
await wrapPromise(this.zone, transfer.open()) await wrapPromise(this.zone, transfer.open())
this.fileTransferStarted.next(transfer) this.fileTransferStarted.next(transfer)
return transfer return transfer
...@@ -230,6 +230,7 @@ export class ElectronPlatformService extends PlatformService { ...@@ -230,6 +230,7 @@ export class ElectronPlatformService extends PlatformService {
class ElectronFileUpload extends FileUpload { class ElectronFileUpload extends FileUpload {
private size: number private size: number
private mode: number
private file: fs.FileHandle private file: fs.FileHandle
private buffer: Buffer private buffer: Buffer
...@@ -239,7 +240,9 @@ class ElectronFileUpload extends FileUpload { ...@@ -239,7 +240,9 @@ class ElectronFileUpload extends FileUpload {
} }
async open (): Promise<void> { async open (): Promise<void> {
this.size = (await fs.stat(this.filePath)).size const stat = await fs.stat(this.filePath)
this.size = stat.size
this.mode = stat.mode
this.file = await fs.open(this.filePath, 'r') this.file = await fs.open(this.filePath, 'r')
} }
...@@ -247,6 +250,10 @@ class ElectronFileUpload extends FileUpload { ...@@ -247,6 +250,10 @@ class ElectronFileUpload extends FileUpload {
return path.basename(this.filePath) return path.basename(this.filePath)
} }
getMode (): number {
return this.mode
}
getSize (): number { getSize (): number {
return this.size return this.size
} }
...@@ -267,19 +274,24 @@ class ElectronFileDownload extends FileDownload { ...@@ -267,19 +274,24 @@ class ElectronFileDownload extends FileDownload {
constructor ( constructor (
private filePath: string, private filePath: string,
private mode: number,
private size: number, private size: number,
) { ) {
super() super()
} }
async open (): Promise<void> { async open (): Promise<void> {
this.file = await fs.open(this.filePath, 'w') this.file = await fs.open(this.filePath, 'w', this.mode)
} }
getName (): string { getName (): string {
return path.basename(this.filePath) return path.basename(this.filePath)
} }
getMode (): number {
return this.mode
}
getSize (): number { getSize (): number {
return this.size return this.size
} }
......
...@@ -82,10 +82,10 @@ export class SFTPPanelComponent { ...@@ -82,10 +82,10 @@ export class SFTPPanelComponent {
if (stat.isDirectory) { if (stat.isDirectory) {
await this.navigate(item.fullPath) await this.navigate(item.fullPath)
} else { } else {
await this.download(item.fullPath, stat.size) await this.download(item.fullPath, stat.mode, stat.size)
} }
} else { } else {
await this.download(item.fullPath, item.size) await this.download(item.fullPath, item.mode, item.size)
} }
} }
...@@ -117,8 +117,8 @@ export class SFTPPanelComponent { ...@@ -117,8 +117,8 @@ export class SFTPPanelComponent {
} }
} }
async download (itemPath: string, size: number): Promise<void> { async download (itemPath: string, mode: number, size: number): Promise<void> {
const transfer = await this.platform.startDownload(path.basename(itemPath), size) const transfer = await this.platform.startDownload(path.basename(itemPath), mode, size)
if (!transfer) { if (!transfer) {
return return
} }
......
...@@ -71,7 +71,7 @@ export class DebugDecorator extends TerminalDecorator { ...@@ -71,7 +71,7 @@ export class DebugDecorator extends TerminalDecorator {
private async saveFile (content: string, name: string) { private async saveFile (content: string, name: string) {
const data = Buffer.from(content) const data = Buffer.from(content)
const transfer = await this.platform.startDownload(name, data.length) const transfer = await this.platform.startDownload(name, 0o644, data.length)
if (transfer) { if (transfer) {
transfer.write(data) transfer.write(data)
transfer.close() transfer.close()
......
...@@ -113,7 +113,7 @@ export class ZModemDecorator extends TerminalDecorator { ...@@ -113,7 +113,7 @@ export class ZModemDecorator extends TerminalDecorator {
this.showMessage(terminal, colors.bgYellow.black(' Offered ') + ' ' + details.name, true) this.showMessage(terminal, colors.bgYellow.black(' Offered ') + ' ' + details.name, true)
this.logger.info('offered', xfer) this.logger.info('offered', xfer)
const transfer = await this.platform.startDownload(details.name, details.size) const transfer = await this.platform.startDownload(details.name, 0o644, details.size)
if (!transfer) { if (!transfer) {
this.showMessage(terminal, colors.bgRed.black(' Rejected ') + ' ' + details.name) this.showMessage(terminal, colors.bgRed.black(' Rejected ') + ' ' + details.name)
xfer.skip() xfer.skip()
......
...@@ -108,8 +108,8 @@ export class WebPlatformService extends PlatformService { ...@@ -108,8 +108,8 @@ export class WebPlatformService extends PlatformService {
window.close() window.close()
} }
async startDownload (name: string, size: number): Promise<FileDownload|null> { async startDownload (name: string, mode: number, size: number): Promise<FileDownload|null> {
const transfer = new HTMLFileDownload(name, size) const transfer = new HTMLFileDownload(name, mode, size)
this.fileTransferStarted.next(transfer) this.fileTransferStarted.next(transfer)
return transfer return transfer
} }
...@@ -145,6 +145,7 @@ class HTMLFileDownload extends FileDownload { ...@@ -145,6 +145,7 @@ class HTMLFileDownload extends FileDownload {
constructor ( constructor (
private name: string, private name: string,
private mode: number,
private size: number, private size: number,
) { ) {
super() super()
...@@ -154,6 +155,10 @@ class HTMLFileDownload extends FileDownload { ...@@ -154,6 +155,10 @@ class HTMLFileDownload extends FileDownload {
return this.name return this.name
} }
getMode (): number {
return this.mode
}
getSize (): number { getSize (): number {
return this.size return this.size
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册