aptgrade.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package main
  2. import (
  3. "errors"
  4. "fmt"
  5. "io"
  6. "os"
  7. "os/exec"
  8. "strings"
  9. "syscall"
  10. )
  11. // Run the given command, showing output.
  12. func run_command(command []string) (bool, error) {
  13. fmt.Println(strings.Repeat("=", 64))
  14. fmt.Println(command)
  15. cmd := exec.Command(command[0], command[1:]...)
  16. // Connections
  17. stdout, err := cmd.StdoutPipe()
  18. if err != nil {
  19. return false, fmt.Errorf("Failed getting stdout pipe: %v", err)
  20. }
  21. var do_autoremove bool = false
  22. go func() {
  23. var (
  24. buf []byte = make([]byte, 1024)
  25. read int
  26. err error
  27. text string
  28. )
  29. for {
  30. read, err = stdout.Read(buf)
  31. if err != nil {
  32. if errors.Is(err, os.ErrClosed) || errors.Is(err, io.EOF) {
  33. return
  34. }
  35. fmt.Println("While reading:", err)
  36. return
  37. }
  38. if read != 0 {
  39. text = string(buf[0:read])
  40. fmt.Print(text)
  41. if strings.Contains(text, "autoremove") {
  42. do_autoremove = true
  43. return
  44. }
  45. }
  46. }
  47. }()
  48. //cmd.Stdout = os.Stdout
  49. cmd.Stderr = os.Stderr
  50. cmd.Stdin = os.Stdin
  51. cmd.SysProcAttr = &syscall.SysProcAttr{}
  52. cmd.SysProcAttr.Credential = &syscall.Credential{Uid: 0, Gid: 0}
  53. err = cmd.Run()
  54. fmt.Println(strings.Repeat("=", 50))
  55. return do_autoremove, err
  56. }
  57. func main() {
  58. if os.Geteuid() != 0 {
  59. fmt.Println("Use `sudo install -g 0 -o 0 -m 4755 aptgrade ~/bin/aptgrade`")
  60. fmt.Println("This program requires SETUID.")
  61. os.Exit(2)
  62. }
  63. _, err := run_command([]string{"/usr/bin/apt", "update"})
  64. if err != nil {
  65. fmt.Println("Did you forget to:")
  66. fmt.Println(" sudo chown root:root aptgrade")
  67. fmt.Println(" sudo chmod a+s aptgrade")
  68. fmt.Println("Command failed:", err)
  69. os.Exit(2)
  70. }
  71. do_autoremove, err := run_command([]string{"/usr/bin/apt", "upgrade", "-y"})
  72. if err != nil {
  73. fmt.Println("Command failed:", err)
  74. os.Exit(2)
  75. }
  76. if do_autoremove {
  77. _, err = run_command([]string{"/usr/bin/apt", "autoremove", "-y"})
  78. if err != nil {
  79. fmt.Println("Command failed:", err)
  80. os.Exit(2)
  81. }
  82. }
  83. fmt.Println("Done")
  84. }