aptgrade.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. }
  44. }
  45. }
  46. }()
  47. //cmd.Stdout = os.Stdout
  48. cmd.Stderr = os.Stderr
  49. cmd.Stdin = os.Stdin
  50. cmd.SysProcAttr = &syscall.SysProcAttr{}
  51. cmd.SysProcAttr.Credential = &syscall.Credential{Uid: 0, Gid: 0}
  52. err = cmd.Run()
  53. fmt.Println(strings.Repeat("=", 50))
  54. return do_autoremove, err
  55. }
  56. func main() {
  57. if os.Geteuid() != 0 {
  58. fmt.Println("Use `sudo install -g 0 -o 0 -m 4755 aptgrade ~/bin/aptgrade`")
  59. fmt.Println("This program requires SETUID.")
  60. os.Exit(2)
  61. }
  62. _, err := run_command([]string{"/usr/bin/apt", "update"})
  63. if err != nil {
  64. fmt.Println("Did you forget to:")
  65. fmt.Println(" sudo chown root:root aptgrade")
  66. fmt.Println(" sudo chmod a+s aptgrade")
  67. fmt.Println("Command failed:", err)
  68. os.Exit(2)
  69. }
  70. do_autoremove, err := run_command([]string{"/usr/bin/apt", "upgrade", "-y"})
  71. if err != nil {
  72. fmt.Println("Command failed:", err)
  73. os.Exit(2)
  74. }
  75. if do_autoremove {
  76. _, err = run_command([]string{"/usr/bin/apt", "autoremove", "-y"})
  77. if err != nil {
  78. fmt.Println("Command failed:", err)
  79. os.Exit(2)
  80. }
  81. }
  82. fmt.Println("Done")
  83. }