Compare commits

..

5 Commits

Author SHA1 Message Date
brent saner 8e70ffac38 v1.16.3
ADDED:
* envs.MustEnv(), envs.MustEnvNoBlank()

UPDATED:
* dep mods, Go version
2026-07-09 19:32:21 -04:00
brent saner d248d72b5a v1.16.2
BUMPED:
* deps resynced to goutils
2026-01-30 20:23:35 -05:00
brent saner 002067d3ac v1.16.1
FIXED:
* Some IDState things on *NIX-likes that have no clue what they're doing
2026-01-30 06:37:44 -05:00
brent saner ed44eb6230 v1.16.0
ADDED:
* Dummy implementation for IDState on Windows
2026-01-29 06:05:13 -05:00
brent saner 1130fb028d v1.15.1
UPDATED:
* Dep/go ver bumps
* gated some WIP stuff
2025-12-18 04:54:11 -05:00
39 changed files with 1168 additions and 47 deletions
View File
+47 -12
View File
@@ -1,28 +1,63 @@
- refactor the elevation detection stuff. I'm not terribly happy with it.
- password generator utility/library
- add generic password prompt func that takes in a `prompt []byte` param and returns `(passwd []byte, err error)`
```
func getPasswd(prompt []byte) (passwd []byte, err error) {
var b []byte
var newLnd bool
var origIn *term.State
var origOut *term.State
var fdIn int = int(os.Stdin.Fd())
var fdOut int = int(os.Stdout.Fd())
if origIn, err = term.GetState(fdIn); err != nil {
return
}
if origOut, err = term.GetState(fdOut); err != nil {
return
}
defer func() {
var tErr error
if !newLnd {
fmt.Println()
}
if tErr = term.Restore(fdIn, origIn); tErr != nil {
return
}
if tErr = term.Restore(fdOut, origOut); tErr != nil {
return
}
}()
os.Stdout.Write(prompt)
if b, err = term.ReadPassword(fdIn); err != nil {
return
}
passwd = b
fmt.Println()
newLnd = true
return
}
```
- password generator/hash+salter and "checksum/hash guesser" utility/library
-- incorporate with r00t2.io/pwgen
-- incorporate with https://github.com/tredoe/osutil ?
-- cli flag to dump flat hashes too (https://github.com/hlandau/passlib and others soon in pwgen)
- auger needs to be build-constrained to linux.
-- (i think i fixed this)
- unit tests
- constants/vars for errors
- func and struct to return segregated system-level env vars vs. user env vars (mostly usable on windows) (see envs/.TODO.go.UNFINISHED)
-- https://www3.ntu.edu.sg/home/ehchua/programming/howto/Environment_Variables.html
-- windows:
--- https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables
--- https://pureinfotech.com/list-environment-variables-windows-10/
--- https://gist.github.com/RebeccaWhit3/5dad8627b8227142e1bea432db3f8824
--- https://ss64.com/nt/syntax-variables.html
-- linux/XDG:
--- https://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
--- https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
-- macOS:
--- https://ss64.com/osx/syntax-env_vars.html
- validator for windows usernames, domains, etc. (for *NIX, https://unix.stackexchange.com/a/435120/284004)
-- https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/naming-conventions-for-computer-domain-site-ou
Executable
+19
View File
@@ -0,0 +1,19 @@
#!/bin/bash
# go tool dist list for all valid GOOS/GOARCH targets.
for tgt in $(go tool dist list);
do
o="$(echo ${tgt} | cut -f1 -d '/')"
a="$(echo ${tgt} | cut -f2 -d '/')"
out="$(env GOOS=${o} GOARCH=${a} go build ./... 2>&1)"
ret=${?}
if [ $ret -ne 0 ];
then
echo "OS: ${o}"
echo "ARCH: ${a}"
echo "${out}"
echo
echo
fi
done
+8
View File
@@ -0,0 +1,8 @@
//go:build !(windows || plan9 || wasip1 || js || ios)
/*
Package sysutils provides [IDState], a collection of process information as it relates to user/group access/membership.
Take note that this module's main functionality is in its child packages.
*/
package sysutils
+9
View File
@@ -0,0 +1,9 @@
/*
Package sysutils provides [IDState], a collection of process information as it relates to user/group access/membership.
NOTE: an [IDState], and all the functions/methods thereof, are fairly useless on Windows as all methods are NO-OPs and
[GetIDState]/[GetIDStateProc] just return an empty [IDState]. It is primarily provided on Windows for easier cross-platform development.
Take note that this module's main functionality is in its child packages.
*/
package sysutils
+7
View File
@@ -0,0 +1,7 @@
/*
Package osenvs contains information (and, in some cases, defaults and associated methods) for
[environment variables] ("env vars") as provided by/as part of the OS.
[environment variables]: https://www3.ntu.edu.sg/home/ehchua/programming/howto/Environment_Variables.html
*/
package osenvs
+56
View File
@@ -0,0 +1,56 @@
package osenvs
type (
/*
AppleEnv are default environment variables found in all macOS instances.
See also the [ss64 article].
macOS also has [POSIXEnv] env vars.
[ss64 article]: https://ss64.com/osx/syntax-env_vars.html
*/
AppleEnv string
/*
MSEnv are default environment variables found in Windows instances.
These include:
* [USMT environment variables]
* ONLY the [Environment Variables] for Poweshell
** Thus no Powershell ["Automatic variables"] or ["Preference variables"]
* standard system environment variables and user environment variables
See also the [ss64 article] and the [compiled Windows 10 list] and [Windows 10/11 list].
[USMT environment variables]: https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables
[Environment Variables]: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_environment_variables?view=powershell-7.5
["Automatic variables"]: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables
["Preference variables"]: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables
[ss64 article]: https://ss64.com/nt/syntax-variables.html
[compiled Windows 10 list]: https://gist.github.com/RebeccaWhit3/5dad8627b8227142e1bea432db3f8824
[Windows 10/11 list]: https://pureinfotech.com/list-environment-variables-windows-10/
*/
MSEnv string
/*
POSIXEnv are environment variables defined by/in [POSIX.1-2024] § [8. Environment Variables].
[POSIX.1-2024]: https://pubs.opengroup.org/onlinepubs/9799919799/
[8. Environment Variables]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap08.html
*/
POSIXEnv string
/*
XDGEnv are environment variables defined by the [FreeDesktop] [spec] for the
[XDG Base Directory Specification] § [3 Environment Variables].
Generally these are only found/expected on Linux, and only a subset of them at that.
Linux also has [POSIXEnv] env vars.
[FreeDesktop]: https://www.freedesktop.org/wiki/
[spec]: https://specifications.freedesktop.org/
[XDG Base Directory Specification]: https://specifications.freedesktop.org/basedir/latest/#variables
[3 Environment Variables]: https://specifications.freedesktop.org/basedir/latest/#variables
*/
XDGEnv string
)
+78
View File
@@ -0,0 +1,78 @@
- func and struct to return segregated system-level env vars vs. user env vars (mostly usable on windows) (see .TODO.go.UNFINISHED and ITERATION/EXPECTED DEFAULTS below)
- - for envs, provide helpers: UsernmEnv and PasswdEnv
-- each takes an argument, envVar, that specifies an env var name to lookup via envs.HasEnv.
-- returns (val string, ok bool, err error)
-- for PasswdEnv:
--- param `ask bool`; if envVar doesn't exist and `ask` is true, prompt user for password (https://pkg.go.dev/golang.org/x/term#ReadPassword)
--- param `prompt []byte`; if empty, use generic "enter password (will not echo back)", otherwise use `prompt` as prompt (only prompted if `ask` == true)
--- param `confirm bool`; if true, prompt for user confirmation
-- for UsernmEnv:
--- param `ask int`;
if > 0, always prompt user (using `prompt`) if EnvVar doesn't exist.
if == 0, use current username if `current == true` and prompt for confirmation/override (if `current == false`, always prompt).
if < 0, never prompt and fallback to current username if `current == true`, return empty/not ok if `current == false`.
--- param `current bool`; if envVar doesn't exist and `current` is true,
--- param `prompt []byte`; if empty, use generic "enter username" (use fmt.Scanln), otherwise use `prompt` as prompt (only prompted if `ask` >= 0)
#################################
## ITERATION/EXPECTED DEFAULTS ##
#################################
macOS:
HOME
LOGNAME
OLDPWD
PATH
PWD
SHELL
SHLVL
SSH_CLIENT
SSH_CONNECTION
SSH_TTY
TERM
TMPDIR
USER
_
e.g.
HOME=/Users/bts
LOGNAME=bts
OLDPWD=/Users/bts
PATH=/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin
PWD=/Users/bts
SHELL=/bin/zsh
SHLVL=1
SSH_CLIENT=192.168.2.99 39690 22
SSH_CONNECTION=192.168.2.99 39690 192.168.2.148 22
SSH_TTY=/dev/ttys000
TERM=xterm-256color
TMPDIR=/var/folders/qv/bm6dlyd94x5fs6qpkfpj0jsr0000gq/T/
USER=bts
_=/usr/bin/env
Windows:
https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src/shell/csidl.md
https://learn.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables
https://learn.microsoft.com/en-us/windows/win32/procthread/environment-variables
https://cdn.callback.com/help/CXH/RefDoc/html/T_callback_ShellBoost_Core_WindowsShell_CSIDL.htm
https://ss64.com/ps/syntax-env.html
https://ss64.com/nt/syntax-variables.html
Linux:
https://specifications.freedesktop.org/basedir/latest/
https://ss64.com/bash/syntax-variables.html
environ(7)?
Might need to do an LFS install and run `env` there.
get list of standard envs in addn to POSIX (see below)
macOS + Linux:
https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap08.html
enumerate default bash and zsh env vars on each, and switch on $SHELL.
macOS:
https://developer.apple.com/documentation/xcode/environment-variable-reference (XCode only?)
https://ss64.com/mac/syntax-variables.html
needs `env` in clean environment
+24
View File
@@ -332,6 +332,30 @@ func InterpolateString(s *string) (err error) {
return
}
// MustEnv wraps [GetEnvErr], but will panic on non-nil err.
func MustEnv(key string) (value string) {
var err error
if value, err = GetEnvErr(key); err != nil {
panic(err)
}
return
}
// MustEnvNoBlank wraps [GetEnvErrNoBlank], but will panic on non-nil err.
func MustEnvNoBlank(key string, ignoreWhitespace bool) (value string) {
var err error
if value, err = GetEnvErrNoBlank(key, ignoreWhitespace); err != nil {
panic(err)
}
return
}
// interpolateMap is used by [Interpolate] for maps. v should be a [reflect.Value] of a map.
func interpolateMap(v reflect.Value) (err error) {
+1 -1
View File
@@ -140,7 +140,7 @@ func (i *IDState) PPIDUIDsChecked() (checked bool) {
return
}
// SudoChecked is true if SudoEnvVars can be trusted
// SudoChecked is true if SudoEnvVars can be trusted.
func (i *IDState) SudoChecked() (checked bool) {
if i == nil {
+72
View File
@@ -0,0 +1,72 @@
//go:build windows
package sysutils
// Checked consolidates all the provided checked functions. This is a NO-OP on Windows.
func (i *IDState) Checked() (checked bool) {
return
}
/*
IsReal consolidates all the elevation/dropped-privs checks into a single method.
This is a NO-OP on Windows.
*/
func (i *IDState) IsReal(real bool) {
return
}
/*
IsSudoGroup is true if any of the group sudo env vars are set,
or the parent process has a different group (and is not PID 1).
This is a NO-OP on Windows.
*/
func (i *IDState) IsSudoGroup() (sudo bool) {
return
}
/*
IsSudoUser is true if any of the user sudo env vars are set,
or the parent process has a different owner (and is not PID 1).
This is a NO-OP on Windows.
*/
func (i *IDState) IsSudoUser() (sudo bool) {
return
}
// IsSuid is true if the RUID does not match EUID or SUID. This is a NO-OP on Windows.
func (i *IDState) IsSuid() (suid bool) {
return
}
// IsSgid is true if the RGID does not match EGID or SGID. This is a NO-OP on Windows.
func (i *IDState) IsSgid() (sgid bool) {
return
}
// GIDsChecked is true if the GIDs presented can be trusted. This is a NO-OP on Windows.
func (i *IDState) GIDsChecked() (checked bool) {
return
}
// PPIDGIDsChecked is true if PPIDGidMatch can be trusted. This is a NO-OP on Windows.
func (i *IDState) PPIDGIDsChecked() (checked bool) {
return
}
// PPIDUIDsChecked is true if PPIDUidMatch can be trusted. This is a NO-OP on Windows.
func (i *IDState) PPIDUIDsChecked() (checked bool) {
return
}
// SudoChecked is true if SudoEnvVars can be trusted. This is a NO-OP on Windows.
func (i *IDState) SudoChecked() (checked bool) {
return
}
// UIDsChecked is true if the UIDs presented can be trusted. This is a NO-OP on Windows.
func (i *IDState) UIDsChecked() (checked bool) {
return
}
+4 -4
View File
@@ -7,7 +7,7 @@ import (
`math`
"os"
`github.com/shirou/gopsutil/v3/process`
`github.com/shirou/gopsutil/v4/process`
"golang.org/x/sys/unix"
"r00t2.io/sysutils/envs"
`r00t2.io/sysutils/errs`
@@ -19,9 +19,9 @@ func GetIDState() (ids IDState) {
var err error
ids.RUID, ids.EUID, ids.SUID = unix.Getresuid()
ids.RUID, ids.EUID, ids.SUID = getresuid()
ids.uidsChecked = true
ids.RGID, ids.EGID, ids.SGID = unix.Getresgid()
ids.RGID, ids.EGID, ids.SGID = getresgid()
ids.gidsChecked = true
ids.SudoEnvCmd = envs.HasEnv(envSudoCmd)
@@ -59,7 +59,7 @@ func GetIDState() (ids IDState) {
func GetIDStateProc(pid uint32) (ids IDState, err error) {
var i32 int32
var ints []int32
var ints []uint32
var sudoUid bool
var sudoUname bool
var proc *process.Process
+31
View File
@@ -0,0 +1,31 @@
//go:build !(windows || plan9 || wasip1 || js || ios) && (aix || darwin || dragonfly || freebsd || illumos || netbsd || solaris)
package sysutils
import (
`golang.org/x/sys/unix`
)
// getresgid spoofs unix.Getresgid, as this file targets platforms that do not support it.
func getresgid() (rgid, egid, sgid int) {
// rgid, egid, sgid = unix.Getresgid()
rgid = unix.Getgid()
egid = unix.Getegid()
sgid = -1
return
}
// getresuid spoofs unix.Getresuid, as this file targets platforms that do not support it.
func getresuid() (ruid, euid, suid int) {
// ruid, euid, suid = unix.Getresuid()
ruid = unix.Getuid()
euid = unix.Geteuid()
suid = -1
return
}
+23
View File
@@ -0,0 +1,23 @@
//go:build !(windows || plan9 || wasip1 || js || ios) && !(aix || darwin || dragonfly || freebsd || illumos || netbsd || solaris)
package sysutils
import (
`golang.org/x/sys/unix`
)
// getresgid wraps unix.Getresgid, as this file targets platforms that fully support it.
func getresgid() (rgid, egid, sgid int) {
rgid, egid, sgid = unix.Getresgid()
return
}
// getresuid wraps unix.Getresuid, as this file targets platforms that fully support it.
func getresuid() (ruid, euid, suid int) {
ruid, euid, suid = unix.Getresuid()
return
}
+13
View File
@@ -0,0 +1,13 @@
//go:build windows
package sysutils
// GetIDState returns current ID/elevation information. This is a NO-OP on Windows.
func GetIDState() (ids IDState) {
return
}
// GetIDStateProc is like GetIDState but for an arbitrary PID. This is a NO-OP on Windows.
func GetIDStateProc(pid uint32) (ids IDState, err error) {
return
}
+17
View File
@@ -0,0 +1,17 @@
- clean up from PoC into unit tests and exported functions/constants etc.
- "Class" and "String" methods for each of the standard named resolutions
refs:
https://en.wikipedia.org/wiki/Display_resolution
https://en.wikipedia.org/wiki/Display_aspect_ratio
https://en.wikipedia.org/wiki/Display_resolution_standards
https://en.wikipedia.org/wiki/Video_Graphics_Array
https://en.wikipedia.org/wiki/Extended_Graphics_Array
https://en.wikipedia.org/wiki/Super_VGA
https://en.wikipedia.org/wiki/Digital_Cinema_Package
https://www.lenovo.com/us/en/glossary/what-is-sxga/
https://www.corsair.com/us/en/explorer/gamer/monitors/wuxga-resolution-explained/
https://www.lenovo.com/us/en/glossary/wqxga/
https://www.strong-eu.com/blog/hd-fhd-uhd-4k-what-are-the-differences
https://www.unravel.com.au/aspect-ratio-cheat-sheet
https://www.wearethefirehouse.com/aspect-ratio-cheat-sheet
+652
View File
@@ -0,0 +1,652 @@
package main
import (
"fmt"
`math`
`slices`
"strconv"
`strings`
mapset `github.com/deckarep/golang-set/v2`
)
type (
AspectRatio struct {
ar float64
arStr string
arW float64
arH float64
gcd int
res *Resolution
}
Resolution struct {
w int
h int
ar *AspectRatio
}
)
func (a *AspectRatio) AsFloat() (ar float64) {
if a == nil {
return
}
if a.ar == 0 {
a.ar = float64(a.res.w) / float64(a.res.h)
}
ar = a.ar
return
}
func (a *AspectRatio) AsSlice() (ar [2]float64) {
if a.arW == 0 {
a.arW = float64(a.res.w) / float64(a.GCD())
}
if a.arH == 0 {
a.arH = float64(a.res.h) / float64(a.GCD())
}
ar = [2]float64{
a.arW,
a.arH,
}
return
}
/*
Cmp is a comparison function that can be used for sorting.
The return cmp value has the same meaning as in [slices.SortFunc]:
If a comes before other, cmp == -1
If a comes after other, cmp == 1
If a and other are equal, cmp == 0
*/
func (a *AspectRatio) Cmp(other AspectRatio) (cmp int) {
var aSlice [2]float64
var oSlice [2]float64
if a == nil {
return
}
aSlice = a.AsSlice()
oSlice = other.AsSlice()
if aSlice[0] == oSlice[0] && aSlice[1] == oSlice[1] {
return
}
if aSlice[0] == oSlice[0] {
if aSlice[1] < oSlice[1] {
cmp = -1
} else {
cmp = 1
}
} else {
if aSlice[0] < oSlice[0] {
cmp = -1
} else {
cmp = 1
}
}
return
}
func (a *AspectRatio) Equals(other AspectRatio) (isEqual bool) {
isEqual = a.Cmp(other) == 0
return
}
func (a *AspectRatio) FloatString() (s string) {
if a == nil {
return
}
if a.ar == 0 {
a.ar = float64(a.res.w) / float64(a.res.h)
}
s = strconv.FormatFloat(a.ar, 'f', -1, 64)
return
}
func (a *AspectRatio) GCD() (gcd int) {
var x int
var y int
if a == nil {
return
}
if a.gcd == 0 {
x = a.res.w
y = a.res.h
// Euclidean GCD ("Greatest Common Divisor") algorithm
for y != 0 {
x, y = y, x%y
}
a.gcd = x
}
gcd = a.gcd
return
}
func (a *AspectRatio) Resolution() (r Resolution) {
var ar [2]float64
var resInts [2]int
if a == nil {
return
}
resInts = a.res.AsSlice()
ar = a.AsSlice()
// Return a fully populated copy.
r = Resolution{
w: resInts[0],
h: resInts[1],
}
r.ar = &AspectRatio{
ar: a.AsFloat(),
arStr: a.String(),
arW: ar[0],
arH: ar[1],
gcd: a.GCD(),
res: &r,
}
return
}
func (a *AspectRatio) String() (s string) {
if a == nil {
return
}
if a.arStr == "" {
if a.arW == 0 {
a.arW = float64(a.res.w) / float64(a.GCD())
}
if a.arH == 0 {
a.arH = float64(a.res.h) / float64(a.GCD())
}
a.arStr = fmt.Sprintf(
"%d:%d",
int(math.Round(a.arW)),
int(math.Round(a.arH)),
)
}
s = a.arStr
return
}
func (r *Resolution) AsSlice() (res [2]int) {
res = [2]int{r.w, r.h}
return
}
func (r *Resolution) AspectRatio() (ar AspectRatio) {
if r == nil {
return
}
if r.ar == nil {
r.ar = NewAspectRatio("", r.w, r.h)
}
ar = AspectRatio{
ar: r.ar.AsFloat(),
arStr: r.ar.String(),
arW: r.ar.arW,
arH: r.ar.arH,
gcd: r.ar.GCD(),
res: &Resolution{
w: r.w,
h: r.h,
},
}
ar.res.ar = &ar
return
}
/*
Cmp is a comparison function that can be used for sorting.
The return cmp value has the same meaning as in [slices.SortFunc]:
If r comes before other, cmp == -1
If r comes after other, cmp == 1
If r and other are equal, cmp == 0
*/
func (r *Resolution) Cmp(other Resolution) (cmp int) {
if r == nil {
return
}
if r.w == other.w && r.h == other.h {
return
}
if r.w == other.w {
if r.h < other.h {
cmp = -1
} else {
cmp = 1
}
} else {
if r.w < other.w {
cmp = -1
} else {
cmp = 1
}
}
return
}
func (r *Resolution) Equals(other Resolution) (isEqual bool) {
isEqual = r.Cmp(other) == 0
return
}
func (r *Resolution) Inverted() (i *Resolution) {
i = &Resolution{
w: r.h,
h: r.w,
}
i.ar = &AspectRatio{
res: i,
}
return
}
func (r *Resolution) String() (s string) {
s = fmt.Sprintf("%dx%d", r.w, r.h)
return
}
var (
resolutions [][2]int = [][2]int{
/*
Common
*/
// qqVGA ("Quarter-QVGA")
[2]int{120, 160}, // 3:4
[2]int{160, 120}, // 4:3, Standard qqVGA
[2]int{160, 128}, // 5:4
[2]int{320, 240}, // ???, qVGA ("Quarter VGA") (commonly inverted as 240x320 on mobile)
// HQVGA ("Half-qVGA")
[2]int{160, 240}, // ???
[2]int{240, 160}, // ???, Standard HQVGA
[2]int{240, 376}, // 3:2, WQVGA ("Wide qVGA")
[2]int{240, 432}, // 3:2, WQVGA
[2]int{360, 240}, // 3:2, WQVGA
[2]int{384, 240}, // 16:10 (8:5), WQVGA
[2]int{400, 240}, // 5:3, WQVGA
[2]int{426, 240}, // ???, WQVGA
[2]int{428, 240}, // ???, WQVGA
[2]int{432, 240}, // 18:10, WQVGA
[2]int{480, 240}, // ???, WQVGA
[2]int{480, 270}, // ???, WQVGA / HVGA ("Half-Size VGA")
[2]int{480, 272}, // ???, WQXGA / HVGA
[2]int{480, 320}, // 3:2, Standard HVGA
[2]int{480, 360}, // 4:3, HVGA
[2]int{640, 240}, // 8:3, HVGA
[2]int{640, 480}, // 4:3, VGA ("Video Graphics Array")
[2]int{640, 384}, // 15:9 (5:3), WVGA (WGA) ("Wide VGA")
[2]int{720, 480}, // 15:10 (3:2), WVGA
[2]int{768, 480}, // 16:10 (8:5), WVGA
[2]int{800, 450}, // 16:9, WVGA
[2]int{800, 480}, // 15:9 (5:3), Standard WVGA
[2]int{848, 480}, // ???, Standard WVGA
[2]int{852, 480}, // ???, Standard WVGA
[2]int{853, 480}, // ???, WVGA
[2]int{854, 480}, // ???, Full WVGA
[2]int{640, 400}, // ???, SVGA ("Super VGA") / UVGA ("Ultra VGA") / XVGA ("Extended VGA")
[2]int{640, 480}, // ???, SVGA / UVGA / XVGA
[2]int{800, 600}, // ???, Standard SVGA / UVGA
[2]int{830, 624}, // 4:3, SVGA / UVGA
[2]int{960, 640}, // 3:2, DVGA ("Double VGA") ("Retina")
[2]int{1136, 640}, // 16:9, DVGA (iPhone 5 variant)
[2]int{1024, 576}, // 16:9, WSVGA ("Wide SVGA")
[2]int{1024, 600}, // 128:75, WSVGA
[2]int{1024, 768}, // 4:3, XGA ("Extended Graphics Array") / SVGA
[2]int{1120, 832}, // 35:26, XGA+ ("Extended Graphics Array Plus")
[2]int{1152, 864}, // 4:3, Standard XGA+
[2]int{1152, 870}, // 192:145, XGA+
[2]int{1152, 900}, // 32:25, XGA+
[2]int{1152, 768}, // 16:9, WXGA ("Wide XGA")
[2]int{1280, 720}, // 16:9, WXGA
[2]int{1280, 768}, // 15:9, Standard WXGA
[2]int{1280, 800}, // 16:10, Standard WXGA
[2]int{1280, 854}, // ???, WXGA+ ("Wide XGA Plus")
[2]int{1360, 768}, // ???, FWXGA ("Full WXGA")
[2]int{1366, 768}, // ???, Standard WXGA / FWXGA
[2]int{1280, 960}, // 4:3, QuadVGA / SXVGA ("Super XVGA") / SXGA-
[2]int{1280, 1024}, // 5:4, SXGA ("Super XGA") / SVGA
[2]int{1360, 768}, // ???, FWXGA
[2]int{1366, 768}, // ???, WXGA
[2]int{1400, 1050}, // 4:3, SXGA+ ("Super XGA Plus")
[2]int{1440, 900}, // 16:10, WXGA+ / WSXGA ("Wide SXGA")
[2]int{1440, 960}, // 3:2, WSXGA
[2]int{1600, 1024}, // 25:16, WSXGA
[2]int{1600, 1200}, // 4:3, UXGA ("Ultra-XGA")
[2]int{1680, 1050}, // 16:10, WSXGA+
[2]int{1920, 1200}, // 16:10, WUXGA ("Widescreen UXGA")
[2]int{2048, 1152}, // 16:9, QWXGA ("Quad-WXGA")
[2]int{2048, 1536}, // 4:3, QXGA ("Quad-XGA")
[2]int{2560, 1600}, // 16:10, WQXGA ("Wide QXGA")
[2]int{2560, 2048}, // 5:4, QSXGA ("Quad-SXGA")
[2]int{2800, 2100}, // 4:3, QSXGA+ ("Quad-SXGA Plus")
[2]int{2880, 1800}, // 16:10, WQXGA+ ("Wide QXGA Plus")
[2]int{3200, 2048}, // 25:16, WQSXGA ("Wide QSXGA")
[2]int{3200, 2400}, // 4:3, QUXGA ("Quad Ultra-XGA")
[2]int{3840, 2400}, // 16:10, WQUXGA ("Wide QUXGA")
[2]int{1136, 640}, // 16:9, Apple variant
[2]int{1334, 750}, // 16:9, Apple variant
[2]int{1792, 828}, // ???, Apple variant
[2]int{2436, 1125}, // ???, Apple variant
[2]int{2532, 1170}, // ???, Apple variant
[2]int{2556, 1179}, // ???, Apple variant
[2]int{2688, 1242}, // ???, Apple variant
[2]int{2778, 1285}, // ???, Apple variant
[2]int{2796, 1290}, // ???, Apple variant
[2]int{2160, 1080}, // 2:1, Android variant
[2]int{2220, 1080}, // ???, Android variant
[2]int{2280, 1080}, // 19:9, Android variant
[2]int{2400, 1080}, // 20:9, Android variant
[2]int{2960, 1440}, // ???, Android variant
[2]int{3040, 1440}, // 19:9, Android variant
[2]int{3120, 1440}, // ???, Android variant
[2]int{2340, 1080}, // ???, Android/Apple variant
// Assorted rare res
[2]int{576, 720}, // 4:5
[2]int{900, 720}, // 5:4
[2]int{960, 720}, // 4:3
[2]int{1200, 720}, // 5:3
[2]int{1280, 720}, // 16:9
[2]int{1280, 524}, // ???
[2]int{1280, 532}, // ???
[2]int{1280, 536}, // ???
[2]int{1280, 540}, // ???
[2]int{1280, 544}, // ???
[2]int{1280, 640}, // ???
[2]int{1280, 674}, // ???
[2]int{1280, 692}, // ???
// 1:1 - Square
[2]int{1080, 1080}, // Square Standard
// 9:16 - Vertical
[2]int{1080, 1920}, // Standard Mobile
// 16:9 - Standard widescreen
[2]int{1920, 1080}, // 1080p ("Full HD"/"FHD")
[2]int{2560, 1440}, // 1440p ("Quad HD"/ "QHD")
[2]int{3840, 2160}, // 2160p ("4k Ultra-HD"/"4k UHD")
[2]int{7680, 4320}, // 4320p ("8k Ultra-HD"/"8k UHD")
// 16:10 - "Computer monitor" widescreen
[2]int{1920, 1200}, // WUXGA ("Widescreen Ultra Extended Graphics Array"), https://www.corsair.com/us/en/explorer/gamer/monitors/wuxga-resolution-explained/
[2]int{2560, 1600}, // WQXGA ("Wide Quad Extended Graphics Array"), https://www.lenovo.com/us/en/glossary/wqxga/
// 21:9 - Ultrawide
[2]int{2560, 1080}, // Ultrawide FHD
[2]int{3440, 1440}, // Ultrawide QHD
// 32:9 - Super Ultrawide
[2]int{5120, 1440},
/*
Cinema
*/
// 37:20 - Flat
[2]int{1998, 1080}, // 2k Flat DCP ("Digital Cinema Package")
[2]int{3996, 2160}, // 4k Flat DCP
// 1024:429 - Scope
[2]int{2048, 858}, // 2k Scope DCP
[2]int{4096, 1716}, // 4k Scope DCP
// 256:135 - Full Container
[2]int{2048, 1080}, // 2k Full Container DCP
[2]int{4096, 2160}, // 4k Full Container DCP
}
)
/*
NewAspectRatio returns a new Aspect Ratio from string form ar.
At least one of width or height must be > 0;
the other can be calculated from ar.
If both height and width are > 0, ar is ignored and it will be calculated from those instead.
If both height and width are <= 0, a will be nil.
If ar is an invalid format, a will be nil.
*/
func NewAspectRatio(ar string, width, height int) (a *AspectRatio) {
var err error
var arW float64
var arH float64
var arStr []string
if width <= 0 && height <= 0 {
return
} else if width > 0 && height > 0 {
// ar is ignored.
a = &AspectRatio{
ar: float64(width) / float64(height),
res: &Resolution{
w: width,
h: height,
},
}
a.res.ar = a
} else {
arStr = strings.SplitN(strings.TrimSpace(ar), ":", 2)
if len(arStr) != 2 {
return
}
if arH, err = strconv.ParseFloat(strings.TrimSpace(arStr[0]), 64); err != nil {
return
}
if arW, err = strconv.ParseFloat(strings.TrimSpace(arStr[1]), 64); err != nil {
return
}
a = &AspectRatio{
ar: arW / arH,
arW: arW,
arH: arH,
}
a.res.ar = a
if width > 0 {
a.res.w = width
a.res.h = int(math.Round(float64(a.res.w) / a.ar))
} else {
a.res.h = height
a.res.w = int(math.Round(float64(a.res.h) * a.ar))
}
}
return
}
func NewResolution(width, height int) (r Resolution) {
r = Resolution{
w: width,
h: height,
}
r.ar = &AspectRatio{
res: &r,
}
return
}
func NewResolutions(resGeom [][2]int) (rsltns []Resolution) {
var idx int
rsltns = make([]Resolution, len(resGeom))
for idx = range resGeom {
rsltns[idx] = NewResolution(resGeom[idx][0], resGeom[idx][1])
}
return
}
func SortAspectRatios(ar []AspectRatio) (sorted []AspectRatio) {
slices.SortStableFunc(
ar,
func(a, b AspectRatio) (cmp int) {
cmp = a.Cmp(b)
return
},
)
return
}
func SortResolutions(res []Resolution) {
slices.SortStableFunc(
res,
func(a, b Resolution) (cmp int) {
cmp = a.Cmp(b)
return
},
)
return
}
func main() {
var ok bool
var idx int
var arStr string
// var ars []string
var ar AspectRatio
var res Resolution
var rsltns []Resolution
var uniqAr mapset.Set[AspectRatio] = mapset.NewSet[AspectRatio]()
var uniqRes mapset.Set[[2]int] = mapset.NewSet[[2]int](resolutions...)
var arMap map[string]mapset.Set[Resolution] = make(map[string]mapset.Set[Resolution])
rsltns = NewResolutions(uniqRes.ToSlice())
SortResolutions(rsltns)
for idx, res = range rsltns {
uniqAr.Add(res.AspectRatio())
ar = res.AspectRatio()
arStr = ar.String()
if _, ok = arMap[arStr]; !ok {
arMap[arStr] = mapset.NewSet[Resolution]()
}
arMap[arStr].Add(res)
fmt.Printf("#%d: %s (%s)\n", idx, res.String(), ar.FloatString())
}
fmt.Println("\n====\n")
/*
for _, aspRatStr = range aspRatKeys {
fmt.Println(aspRatStr)
slices.SortStableFunc(
aspRatRes[aspRatStr],
func(resA, resB [2]int) (cmp int) {
// default cmp is 0, which means fully equal
if resA[0] == resB[0] {
if resA[1] > resB[1] {
cmp = 1
} else {
cmp = -1
}
} else {
if resA[0] > resB[0] {
cmp = 1
} else {
cmp = -1
}
}
return
},
)
for _, res = range aspRatRes[aspRatStr] {
fmt.Printf("\t%dx%d\n", res[0], res[1])
}
}
*/
}
+11 -11
View File
@@ -1,26 +1,26 @@
module r00t2.io/sysutils
go 1.24.5
go 1.26
require (
github.com/davecgh/go-spew v1.1.1
github.com/deckarep/golang-set/v2 v2.9.0
github.com/djherbis/times v1.6.0
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/shirou/gopsutil/v3 v3.24.5
github.com/shirou/gopsutil/v4 v4.25.10
golang.org/x/sync v0.17.0
golang.org/x/sys v0.37.0
github.com/shirou/gopsutil/v4 v4.26.6
golang.org/x/sync v0.22.0
golang.org/x/sys v0.47.0
honnef.co/go/augeas v0.0.0-20161110001225-ca62e35ed6b8
r00t2.io/goutils v1.10.3
r00t2.io/goutils v1.16.10
)
require (
github.com/ebitengine/purego v0.9.1 // indirect
github.com/ebitengine/purego v0.10.1 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect
github.com/lufia/plan9stats v0.0.0-20260627054121-477a66015f15 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/shoenig/go-m1cpu v0.1.7 // indirect
github.com/tklauser/go-sysconf v0.3.15 // indirect
github.com/tklauser/numcpus v0.10.0 // indirect
github.com/tklauser/go-sysconf v0.4.0 // indirect
github.com/tklauser/numcpus v0.12.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.mongodb.org/mongo-driver v1.17.9 // indirect
)
+34 -18
View File
@@ -1,9 +1,13 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set/v2 v2.9.0 h1:prva4eP9UysWagLyKrtn074ughi0NnkIf0A4M5yOCKI=
github.com/deckarep/golang-set/v2 v2.9.0/go.mod h1:EWknQXbs0mcFpat2QOoXV0Ee57cD+w6ZEN76BR2JVrM=
github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c=
github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0=
github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A=
github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/ebitengine/purego v0.10.1 h1:dewVBCBT2GaMu1SrNTYxQhgQBethzfhiwvZiLGP/qyY=
github.com/ebitengine/purego v0.10.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
@@ -13,37 +17,49 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k=
github.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
github.com/lufia/plan9stats v0.0.0-20260627054121-477a66015f15 h1:YkjVPl/YH5XlJ+/NiwzJtPYXXKRcyjmEUhsDci6YK3c=
github.com/lufia/plan9stats v0.0.0-20260627054121-477a66015f15/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA=
github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM=
github.com/shoenig/go-m1cpu v0.1.7 h1:C76Yd0ObKR82W4vhfjZiCp0HxcSZ8Nqd84v+HZ0qyI0=
github.com/shoenig/go-m1cpu v0.1.7/go.mod h1:KkDOw6m3ZJQAPHbrzkZki4hnx+pDRR1Lo+ldA56wD5w=
github.com/shoenig/test v1.7.0 h1:eWcHtTXa6QLnBvm0jgEabMRN/uJ4DMV3M8xUGgRkZmk=
github.com/shoenig/test v1.7.0/go.mod h1:UxJ6u/x2v/TNs/LoLxBNJRV9DiwBBKYxXSyczsBHFoI=
github.com/shirou/gopsutil/v4 v4.25.12 h1:e7PvW/0RmJ8p8vPGJH4jvNkOyLmbkXgXW4m6ZPic6CY=
github.com/shirou/gopsutil/v4 v4.25.12/go.mod h1:EivAfP5x2EhLp2ovdpKSozecVXn1TmuG7SMzs/Wh4PU=
github.com/shirou/gopsutil/v4 v4.26.6 h1:Mzr/npDtQC/xpeEuQKHZt8Zo9CmPvhTj8nkR8w5TLDs=
github.com/shirou/gopsutil/v4 v4.26.6/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=
github.com/tklauser/go-sysconf v0.4.0 h1:7H0uAN+7RkwWRaxhYXDLqa5V3LPrJeV8wmD9dRUgPQU=
github.com/tklauser/go-sysconf v0.4.0/go.mod h1:8mTNWyog7H+MpKijp4VmKJAd2bbYQ2zuUwkYRbUArPI=
github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=
github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ=
github.com/tklauser/numcpus v0.12.0 h1:NR85qdvHA9pFse3x3weVZ0r0ST8R6l5RHbZrlRaqob4=
github.com/tklauser/numcpus v0.12.0/go.mod h1:ABHeXzJnr/qqwguhClkZKT1/8VABcYrsyUiUGobwWJg=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw=
go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
go.mongodb.org/mongo-driver v1.17.9 h1:IexDdCuuNJ3BHrELgBlyaH9p60JXAvdzWR128q+U5tU=
go.mongodb.org/mongo-driver v1.17.9/go.mod h1:LlOhpH5NUEfhxcAwG0UEkMqwYcc4JU18gtCdGudk/tQ=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/augeas v0.0.0-20161110001225-ca62e35ed6b8 h1:FW42yWB1sGClqswyHIB68wo0+oPrav1IuQ+Tdy8Qp8E=
honnef.co/go/augeas v0.0.0-20161110001225-ca62e35ed6b8/go.mod h1:44w9OfBSQ9l3o59rc2w3AnABtE44bmtNnRMNC7z+oKE=
r00t2.io/goutils v1.10.3 h1:GmEtsM/nrrVWooYJllXDRsgInobEinv2dn5ccU4zGAA=
r00t2.io/goutils v1.10.3/go.mod h1:76AxpXUeL10uFklxRB11kQsrtj2AKiNm8AwG1bNoBCA=
r00t2.io/goutils v1.16.6 h1:nZ6lFqhiM3m/1yNvdIdiP2VvuQr5ZRvYPbj3oM657Aw=
r00t2.io/goutils v1.16.6/go.mod h1:VXsgdl3QoiP9bgqykYpJ/NwoxZ992jslMiV32EhaIOc=
r00t2.io/goutils v1.16.10 h1:2XSTVAyW35+hC/VEysQahMKTcSSEH7uaOv1a72lsnXc=
r00t2.io/goutils v1.16.10/go.mod h1:rv7k/RWprVhoZjacmL+Jv6GjvME3BpOO8OsdoXPqy8I=
+14
View File
@@ -1 +1,15 @@
- search criteria should *also* support a timestamp range (e.g. so a search can be restricted to both older than AND newer than; e.g. older than 00:00, newer than 01:00)
- need an ExpandHomeSys (...which will change ExpandHome behavior, if it switches to path instead of path/filepath...)
-- Should probably split out to a separate module or branch to v2.
-- get rid of the *Sys stuff? Normalize all to os.PathSep? provide package-level bool to control behavior?
-- separate modules ideal:
--- r00t2.io/paths/
<generic>
gopath/
<generic path separator - forward slash>
syspath/
<os.PathSeparator>
I could consolidate a LOT of code if I use a struct that has a mode (or typed against different separators?) etc. but...
--- Need to test with e.g. "network share paths" - URI format (<scheme>://<path>), \\host\share, etc.
+10 -1
View File
@@ -11,7 +11,16 @@ IDState collects information about the current running process.
It should only be used as returned from GetIDState().
Its methods WILL return false information if any of these values are altered.
FSUID/FSGID are not supported.
FSUID/FSGID are not currently supported.
Currently, macOS (and FreeBSD, and a couple others) will not populate:
* SUID
* SGID
due to Apple in their "infinite wisdom" allowing you to *set* these
but exposing no direct syscall whatsoever to *retrieve* them.
Enjoy your crippled OS, fanboys.
*/
type IDState struct {
// RUID: Real UID
+38
View File
@@ -0,0 +1,38 @@
//go:build windows
package sysutils
/*
IDState on *NIX-like platforms collects information about the current running process.
However, it is only present as a sort of dummy on Windows to make cross-platform development easier.
Do not expect any sort of usefulness from this struct on Windows other than parsing an IDState generated on *NIX.
*/
type IDState struct {
// RUID: Real UID
RUID int
// EUID: Effective UID
EUID int
// SUID: Saved Set UID
SUID int
// RGID: Real GID
RGID int
// EGID: Effective GID
EGID int
// SGID: Saved Set GID
SGID int
// SudoEnvUser is true if SUDO_USER or SUDO_UID is set.
SudoEnvUser bool
// SudoEnvGroup is true if SUDO_GID is set.
SudoEnvGroup bool
// SudoEnvCmd is true if SUDO_COMMAND is set.
SudoEnvCmd bool
// SudoEnvHome is true if SUDO_HOME is set.
SudoEnvHome bool
// SudoEnvVars is true if any of the "well-known" sudo environment variables are set.
SudoEnvVars bool
// PPIDUidMatch is true if the parent PID UID matches the current process UID (mismatch usually indicates sudo invocation).
PPIDUidMatch bool
// PPIDGidMatch is true if the parent PID GID matches the current process GID (mismatch usually indicates sudo invocation).
PPIDGidMatch bool
}