74 lines
1.8 KiB
Go
74 lines
1.8 KiB
Go
//go:build linux
|
|
// +build linux
|
|
|
|
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
func relaunchWithAdminIfNeeded() (bool, error) {
|
|
if os.Geteuid() == 0 {
|
|
return false, nil
|
|
}
|
|
|
|
exePath, err := os.Executable()
|
|
if err != nil {
|
|
return false, fmt.Errorf("get executable path: %w", err)
|
|
}
|
|
|
|
workDir, err := os.Getwd()
|
|
if err != nil {
|
|
return false, fmt.Errorf("get working directory: %w", err)
|
|
}
|
|
|
|
args := make([]string, 0, len(os.Args))
|
|
args = append(args, shellQuote(exePath))
|
|
for _, arg := range os.Args[1:] {
|
|
args = append(args, shellQuote(arg))
|
|
}
|
|
|
|
logPath := filepath.Join(os.TempDir(), "firefly-go-proxy.log")
|
|
command := fmt.Sprintf(
|
|
"cd %s && nohup %s >> %s 2>&1 &",
|
|
shellQuote(workDir),
|
|
strings.Join(args, " "),
|
|
shellQuote(logPath),
|
|
)
|
|
|
|
if pkexecPath, err := exec.LookPath("pkexec"); err == nil {
|
|
if out, err := exec.Command(pkexecPath, "sh", "-c", command).CombinedOutput(); err == nil {
|
|
return true, nil
|
|
} else if _, sudoErr := exec.LookPath("sudo"); sudoErr != nil {
|
|
return false, formatCommandError("relaunch proxy as admin with pkexec", err, out)
|
|
}
|
|
}
|
|
|
|
sudoPath, err := exec.LookPath("sudo")
|
|
if err != nil {
|
|
return false, errors.New("pkexec or sudo is required to relaunch with admin privileges")
|
|
}
|
|
if out, err := exec.Command(sudoPath, "sh", "-c", command).CombinedOutput(); err != nil {
|
|
return false, formatCommandError("relaunch proxy as admin with sudo", err, out)
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
func shellQuote(value string) string {
|
|
return "'" + strings.ReplaceAll(value, "'", "'\\''") + "'"
|
|
}
|
|
|
|
func formatCommandError(action string, err error, out []byte) error {
|
|
msg := strings.TrimSpace(string(out))
|
|
if msg == "" {
|
|
return fmt.Errorf("%s: %w", action, err)
|
|
}
|
|
return fmt.Errorf("%s: %w: %s", action, err, msg)
|
|
}
|