package main import ( "bufio" "fmt" "path" "os" "os/exec" "os/user" "git.tilde.town/tildetown/town/towndb" ) func confirmRename() { fmt.Println("this will kill all of the user's current processes. if you're doing this live you should give them a good contact if things break") var text string for text != "y\n" { fmt.Print("enter 'y' to continue: ") reader := bufio.NewReader(os.Stdin) text, _ = reader.ReadString('\n') } } func killUser(name string) (err error) { cmd := exec.Command("pkill", "-SIGKILL", "-u", name) cmd.Stderr = os.Stderr if err = cmd.Run(); err != nil { if exiterr, ok := err.(*exec.ExitError); ok { if exiterr.ExitCode() == 1 { return nil } } return err } return nil } func usermod(old_name string, new_name string) (err error) { cmd := exec.Command( "usermod", "-l", new_name, "-m", "-d", path.Join("/home", new_name), old_name, ) cmd.Stderr = os.Stderr if err = cmd.Run(); err != nil { return err } cmd = exec.Command("groupmod", "-n", new_name, old_name) cmd.Stderr = os.Stderr if err = cmd.Run(); err != nil { return err } return } func renameDb(old_name string, new_name string) (err error) { db, err := towndb.ConnectDB() if err != nil { return err } err = towndb.RenameUser(db, old_name, new_name) if err != nil { return err } return nil } func quit(text string) { fmt.Println(text) os.Exit(1) } func main() { if len(os.Args) != 3 { quit("usage: rename username new_username") } old_name := os.Args[1] new_name := os.Args[2] user, err := user.Current() if err != nil { quit(fmt.Sprintf("couldn't get user info: %v", err)) } if user.Uid != "0" { quit("must be run as root") } confirmRename() if err := killUser(old_name); err != nil { quit(fmt.Sprintf("pkill failed: %v", err)) } fmt.Println("killed old processes") if err := usermod(old_name, new_name); err != nil { quit(fmt.Sprintf("unix user rename failed: %v", err)) } fmt.Println("renamed unix user") if err := renameDb(old_name, new_name); err != nil { fmt.Println(fmt.Sprintf("couldn't rename user in /town/var/town.db: %v", err)) fmt.Println("something might be amiss with town.db") } else { fmt.Println("renamed user in /town/var/town.db") } }