mirror of
https://github.com/Eugeny/tabby.git
synced 2025-07-20 18:38:01 +00:00
preserve file modes for up- and downloads - fixes #4141
This commit is contained in:
@@ -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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
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 {
|
|||||||
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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
|
|
||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
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 {
|
|||||||
return this.name
|
return this.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMode (): number {
|
||||||
|
return this.mode
|
||||||
|
}
|
||||||
|
|
||||||
getSize (): number {
|
getSize (): number {
|
||||||
return this.size
|
return this.size
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user