confirm_and_run_shebang.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
  2. package tool
  3. import (
  4. "fmt"
  5. "os"
  6. "os/exec"
  7. "golang.org/x/sys/unix"
  8. "kitty/kittens/ask"
  9. "kitty/tools/cli"
  10. "kitty/tools/cli/markup"
  11. "kitty/tools/utils"
  12. )
  13. var _ = fmt.Print
  14. func ask_for_permission(script_path string) (response string, err error) {
  15. opts := &ask.Options{Type: "choices", Default: "n", Choices: []string{"y;green:Yes", "n;red:No", "v;yellow:View", "e;magenta:Edit"}}
  16. ctx := markup.New(true)
  17. opts.Message = ctx.Prettify(fmt.Sprintf(
  18. "Attempting to execute the script: :yellow:`%s`\nExecuting untrusted scripts can be dangerous. Proceed anyway?", script_path))
  19. response, err = ask.GetChoices(opts)
  20. return response, err
  21. }
  22. func confirm_and_run_shebang(args []string) (rc int, err error) {
  23. script_path := args[len(args)-1]
  24. if unix.Access(script_path, unix.X_OK) != nil {
  25. response, err := ask_for_permission(script_path)
  26. if err != nil {
  27. return 1, err
  28. }
  29. switch response {
  30. default:
  31. return 1, fmt.Errorf("Execution of %s was denied by user", script_path)
  32. case "v":
  33. raw, err := os.ReadFile(script_path)
  34. if err != nil {
  35. return 1, err
  36. }
  37. cli.ShowHelpInPager(utils.UnsafeBytesToString(raw))
  38. return confirm_and_run_shebang(args)
  39. case "e":
  40. exe, err := os.Executable()
  41. if err != nil {
  42. return 1, err
  43. }
  44. editor := exec.Command(exe, "edit-in-kitty", script_path)
  45. editor.Stdin = os.Stdin
  46. editor.Stdout = os.Stdout
  47. editor.Stderr = os.Stderr
  48. editor.Run()
  49. return confirm_and_run_shebang(args)
  50. case "y":
  51. }
  52. }
  53. exe := utils.FindExe(args[0])
  54. if exe == "" {
  55. return 1, fmt.Errorf("Failed to find the script interpreter: %s", args[0])
  56. }
  57. err = unix.Exec(exe, args, os.Environ())
  58. if err != nil {
  59. rc = 1
  60. }
  61. return
  62. }