124 lines
2.4 KiB
Go
124 lines
2.4 KiB
Go
package camfish
|
|
|
|
import "fmt"
|
|
import "log"
|
|
import "time"
|
|
import "iter"
|
|
import "errors"
|
|
import "strconv"
|
|
import "syscall"
|
|
import "os/user"
|
|
import "strings"
|
|
import "context"
|
|
import "sync/atomic"
|
|
import "unicode/utf8"
|
|
|
|
func defaul[T comparable](value, def T) T {
|
|
var zero T
|
|
if value == zero { return def }
|
|
return value
|
|
}
|
|
|
|
func panicWrap(f func() error) (err error) {
|
|
defer func () {
|
|
if pan := recover(); pan != nil {
|
|
if panErr, ok := pan.(error); ok {
|
|
err = panErr
|
|
} else {
|
|
err = errors.New(fmt.Sprint(pan))
|
|
}
|
|
}
|
|
} ()
|
|
|
|
err = f()
|
|
return
|
|
}
|
|
|
|
func panicWrapCtx(ctx context.Context, f func(context.Context) error) (err error) {
|
|
defer func () {
|
|
if pan := recover(); pan != nil {
|
|
if panErr, ok := pan.(error); ok {
|
|
err = panErr
|
|
} else {
|
|
err = errors.New(fmt.Sprint(pan))
|
|
}
|
|
}
|
|
} ()
|
|
|
|
err = f(ctx)
|
|
return
|
|
}
|
|
|
|
type atomicDuration atomic.Int64
|
|
type atomicInt64Ptr = *atomic.Int64
|
|
|
|
func (duration* atomicDuration) Load() time.Duration {
|
|
return time.Duration((*atomic.Int64)(duration).Load())
|
|
}
|
|
|
|
func (duration *atomicDuration) Store(newDuration time.Duration) {
|
|
(*atomic.Int64)(duration).Store(int64(newDuration))
|
|
}
|
|
|
|
func logActors (actors iter.Seq[Actor]) {
|
|
output := "actors: "
|
|
x := utf8.RuneCountInString(output)
|
|
first := true
|
|
line := func () {
|
|
if output == "" { return }
|
|
if first {
|
|
first = false
|
|
log.Println("(i)", output)
|
|
} else {
|
|
log.Println(" ", output)
|
|
}
|
|
output = ""
|
|
x = 0
|
|
}
|
|
types := make(map[string] int)
|
|
for actor := range actors {
|
|
typ := actor.Type()
|
|
if named, ok := actor.(Named); ok {
|
|
typ = fmt.Sprintf("%s/%s", typ, named.Name())
|
|
}
|
|
types[typ] += 1
|
|
}
|
|
for typ, count := range types {
|
|
if count > 1 {
|
|
typ += fmt.Sprintf("(%d)", count)
|
|
}
|
|
typ += ", "
|
|
x += 2
|
|
typeLen := utf8.RuneCountInString(typ)
|
|
if x + typeLen >= 60 {
|
|
line()
|
|
}
|
|
output += typ
|
|
x += typeLen
|
|
}
|
|
if output != "" {
|
|
output = strings.TrimSuffix(output, ", ")
|
|
}
|
|
line()
|
|
}
|
|
|
|
func dropPrivelege (usr, group string) error {
|
|
if group != "" {
|
|
groupInfo, err := user.LookupGroup(group)
|
|
if err != nil { return err }
|
|
gid, err := strconv.Atoi(groupInfo.Gid)
|
|
if err != nil { return err }
|
|
err = syscall.Setgid(gid)
|
|
if err != nil { return err }
|
|
}
|
|
if usr != "" {
|
|
usrInfo, err := user.Lookup(usr)
|
|
if err != nil { return err }
|
|
uid, err := strconv.Atoi(usrInfo.Uid)
|
|
if err != nil { return err }
|
|
err = syscall.Setuid(uid)
|
|
if err != nil { return err }
|
|
}
|
|
return nil
|
|
}
|