mirror of
https://github.com/rclone/rclone.git
synced 2025-12-06 00:03:32 +00:00
Compare commits
12 Commits
copilot/fi
...
pr-6474-pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3450d049b5 | ||
|
|
16b383e18f | ||
|
|
d59909fb8c | ||
|
|
cec47699d3 | ||
|
|
0687a263f8 | ||
|
|
3192e00f4f | ||
|
|
14534c573a | ||
|
|
408d0c729b | ||
|
|
a716dc2533 | ||
|
|
28f0c08a98 | ||
|
|
458c477ad8 | ||
|
|
7130a6d2e4 |
@@ -62,7 +62,7 @@ func startProgress() func() {
|
|||||||
printProgress("")
|
printProgress("")
|
||||||
fs.LogPrint = oldLogPrint
|
fs.LogPrint = oldLogPrint
|
||||||
operations.SyncPrintf = oldSyncPrint
|
operations.SyncPrintf = oldSyncPrint
|
||||||
fmt.Println("")
|
fmt.Fprintln(terminal.Out, "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ var (
|
|||||||
// When nil, no encryption will be used for saving.
|
// When nil, no encryption will be used for saving.
|
||||||
configKey []byte
|
configKey []byte
|
||||||
|
|
||||||
// PasswordPromptOutput is output of prompt for password
|
|
||||||
PasswordPromptOutput = os.Stderr
|
|
||||||
|
|
||||||
// PassConfigKeyForDaemonization if set to true, the configKey
|
// PassConfigKeyForDaemonization if set to true, the configKey
|
||||||
// is obscured with obscure.Obscure and saved to a temp file
|
// is obscured with obscure.Obscure and saved to a temp file
|
||||||
// when it is calculated from the password. The path of that
|
// when it is calculated from the password. The path of that
|
||||||
|
|||||||
@@ -716,9 +716,9 @@ func checkPassword(password string) (string, error) {
|
|||||||
|
|
||||||
// GetPassword asks the user for a password with the prompt given.
|
// GetPassword asks the user for a password with the prompt given.
|
||||||
func GetPassword(prompt string) string {
|
func GetPassword(prompt string) string {
|
||||||
_, _ = fmt.Fprintln(PasswordPromptOutput, prompt)
|
_, _ = fmt.Fprintln(terminal.Out, prompt)
|
||||||
for {
|
for {
|
||||||
_, _ = fmt.Fprint(PasswordPromptOutput, "password:")
|
_, _ = fmt.Fprint(terminal.Out, "password:")
|
||||||
password := ReadPassword()
|
password := ReadPassword()
|
||||||
password, err := checkPassword(password)
|
password, err := checkPassword(password)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
@@ -9,17 +9,17 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/rclone/rclone/fs/config"
|
"github.com/rclone/rclone/lib/terminal"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
// redirectStderr to the file passed in
|
// redirectStderr to the file passed in
|
||||||
func redirectStderr(f *os.File) {
|
func redirectStderr(f *os.File) {
|
||||||
passPromptFd, err := unix.Dup(int(os.Stderr.Fd()))
|
termFd, err := unix.Dup(int(os.Stderr.Fd()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to duplicate stderr: %v", err)
|
log.Fatalf("Failed to duplicate stderr: %v", err)
|
||||||
}
|
}
|
||||||
config.PasswordPromptOutput = os.NewFile(uintptr(passPromptFd), "passPrompt")
|
terminal.RawOut = os.NewFile(uintptr(termFd), "termOut")
|
||||||
err = unix.Dup2(int(f.Fd()), int(os.Stderr.Fd()))
|
err = unix.Dup2(int(f.Fd()), int(os.Stderr.Fd()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to redirect stderr to file: %v", err)
|
log.Fatalf("Failed to redirect stderr to file: %v", err)
|
||||||
|
|||||||
@@ -12,29 +12,43 @@ package log
|
|||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
|
||||||
|
"github.com/rclone/rclone/lib/terminal"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// dup oldfd creating a functional copy as newfd
|
||||||
kernel32 = syscall.MustLoadDLL("kernel32.dll")
|
// conceptually the same as the unix `dup()` function
|
||||||
procSetStdHandle = kernel32.MustFindProc("SetStdHandle")
|
func dup(oldfd uintptr) (newfd uintptr, err error) {
|
||||||
)
|
var (
|
||||||
|
newfdHandle windows.Handle
|
||||||
func setStdHandle(stdhandle int32, handle syscall.Handle) error {
|
processHandle = windows.CurrentProcess()
|
||||||
r0, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0)
|
)
|
||||||
if r0 == 0 {
|
err = windows.DuplicateHandle(
|
||||||
if e1 != 0 {
|
processHandle, // hSourceProcessHandle
|
||||||
return error(e1)
|
windows.Handle(oldfd), // hSourceHandle
|
||||||
}
|
processHandle, // hTargetProcessHandle
|
||||||
return syscall.EINVAL
|
&newfdHandle, // lpTargetHandle
|
||||||
|
0, // dwDesiredAccess
|
||||||
|
true, // bInheritHandle
|
||||||
|
windows.DUPLICATE_SAME_ACCESS, // dwOptions
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
return nil
|
return uintptr(newfdHandle), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// redirectStderr to the file passed in
|
// redirectStderr to the file passed in
|
||||||
func redirectStderr(f *os.File) {
|
func redirectStderr(f *os.File) {
|
||||||
err := setStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(f.Fd()))
|
termFd, err := dup(os.Stderr.Fd())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to duplicate stderr: %v", err)
|
||||||
|
}
|
||||||
|
terminal.RawOut = os.NewFile(termFd, "termOut")
|
||||||
|
err = windows.SetStdHandle(windows.STD_ERROR_HANDLE, windows.Handle(f.Fd()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to redirect stderr to file: %v", err)
|
log.Fatalf("Failed to redirect stderr to file: %v", err)
|
||||||
}
|
}
|
||||||
|
os.Stderr = f
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,17 +68,23 @@ const (
|
|||||||
var (
|
var (
|
||||||
// make sure that start is only called once
|
// make sure that start is only called once
|
||||||
once sync.Once
|
once sync.Once
|
||||||
|
|
||||||
|
// RawOut is the underlying *os.File intended for terminal output
|
||||||
|
RawOut = os.Stderr
|
||||||
)
|
)
|
||||||
|
|
||||||
// Start the terminal - must be called before use
|
// Start the terminal - must be called before use
|
||||||
func Start() {
|
func Start() {
|
||||||
once.Do(func() {
|
once.Do(func() {
|
||||||
f := os.Stdout
|
f := RawOut
|
||||||
if !IsTerminal(int(f.Fd())) {
|
if !IsTerminal(int(f.Fd())) {
|
||||||
// If stdout not a tty then remove escape codes
|
// If output is not a tty then remove escape codes
|
||||||
Out = colorable.NewNonColorable(f)
|
Out = colorable.NewNonColorable(f)
|
||||||
} else if runtime.GOOS == "windows" && os.Getenv("TERM") != "" {
|
} else if runtime.GOOS == "windows" && os.Getenv("TERM") != "" {
|
||||||
// If TERM is set just use stdout
|
// If TERM is set on Windows then we should just send output
|
||||||
|
// straight to the terminal for cygwin/git bash environments.
|
||||||
|
// We don't want to use NewColorable here because it will
|
||||||
|
// use Windows console calls which cygwin/git bash don't support.
|
||||||
Out = f
|
Out = f
|
||||||
} else {
|
} else {
|
||||||
Out = colorable.NewColorable(f)
|
Out = colorable.NewColorable(f)
|
||||||
|
|||||||
@@ -34,5 +34,5 @@ func ReadPassword(fd int) ([]byte, error) {
|
|||||||
|
|
||||||
// WriteTerminalTitle writes a string to the terminal title
|
// WriteTerminalTitle writes a string to the terminal title
|
||||||
func WriteTerminalTitle(title string) {
|
func WriteTerminalTitle(title string) {
|
||||||
fmt.Printf(ChangeTitle + title + BEL)
|
fmt.Fprintf(Out, ChangeTitle+title+BEL)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user