82 lines
2.2 KiB
Go
82 lines
2.2 KiB
Go
// Package cli provides utilities for writing command line utilities that
|
|
// interact with services.
|
|
package cli
|
|
|
|
import "os"
|
|
import "fmt"
|
|
import "flag"
|
|
import "os/user"
|
|
import "strings"
|
|
import "strconv"
|
|
import "path/filepath"
|
|
|
|
// Sayf is like Printf, but prints the program name before the message. This is
|
|
// used for printing messages and errors.
|
|
func Sayf (format string, values ...any) {
|
|
Printf(os.Args[0] + ": " + format, values...)
|
|
}
|
|
|
|
// Printf prints to stderr.
|
|
func Printf (format string, values ...any) {
|
|
fmt.Fprintf(flag.CommandLine.Output(), format, values...)
|
|
}
|
|
|
|
// ServiceUser returns the system user that corresponds to the given service
|
|
// name. This is not necissarily equivalent Hnakra user, although it is good
|
|
// practice to have a 1:1 correspondance between them.
|
|
func ServiceUser (service string) string {
|
|
return "hn-" + strings.ToLower(service)
|
|
}
|
|
|
|
// DataDir returns the standard Hnakra data directory.
|
|
func DataDir () string {
|
|
return "/var/hnakra"
|
|
}
|
|
|
|
// ServiceDir returns the standard data directory of a service.
|
|
func ServiceDir (service string) string {
|
|
return filepath.Join(DataDir(), "services", ServiceUser(service))
|
|
}
|
|
|
|
// NeedRoot halts the program and displays an error if it is not being run as
|
|
// root. This should be called whenever an operation takes place that requires
|
|
// root privelages.
|
|
func NeedRoot() {
|
|
uid := os.Getuid()
|
|
if uid != 0 {
|
|
Sayf("this utility must be run as root")
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
// MkdirFor makes a directory makes the specified directory (if it doesnt
|
|
// already exist) and gives ownership of it to the specified uid and gid.
|
|
func MkdirFor (directory string, uid, gid int) error {
|
|
err := os.MkdirAll(directory, 0755)
|
|
if err != nil { return err }
|
|
err = os.Chmod(directory, 0770)
|
|
if err != nil { return err }
|
|
err = os.Chown(directory, uid, gid)
|
|
if err != nil { return err }
|
|
|
|
return nil
|
|
}
|
|
|
|
// LookupUID returns the uid and gid of the given username, if it exists.
|
|
func LookupUID (name string) (uid, gid uint32, err error) {
|
|
user, err := user.Lookup(name)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
|
|
puid, err := strconv.Atoi(user.Uid)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
pgid, err := strconv.Atoi(user.Gid)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
return uint32(puid), uint32(pgid), nil
|
|
}
|