From 4e7d474fb3584dbc850cbfa4b5fa8025aa3353ac Mon Sep 17 00:00:00 2001 From: brent saner Date: Sat, 8 Aug 2026 00:13:34 -0400 Subject: [PATCH] v1.17.1 FIXED: * tplx/sprigx would throw errors on dnsx.IsPtr, because it returns a bool and net.IP instead of a boolen and optional error. Fixed by adding dnsx.IsPtrChk and using that instead. --- iox/fsx/doc.go | 4 + iox/fsx/funcs.go | 102 ++++++++++++++++++ .../fsx}/internal/todo/overlayfs/funcs.go | 0 .../todo/overlayfs/funcs_embedfsmember.go | 0 .../internal/todo/overlayfs/funcs_mergedfs.go | 0 .../todo/overlayfs/funcs_realfsmember.go | 0 .../fsx}/internal/todo/overlayfs/types.go | 0 netx/TODO | 1 + netx/dnsx/funcs.go | 96 ++++++++++------- tplx/sprigx/README.html | 2 +- tplx/sprigx/README.md | 2 +- tplx/sprigx/consts.go | 73 ++++++------- 12 files changed, 202 insertions(+), 78 deletions(-) create mode 100644 iox/fsx/doc.go create mode 100644 iox/fsx/funcs.go rename {fsx => iox/fsx}/internal/todo/overlayfs/funcs.go (100%) rename {fsx => iox/fsx}/internal/todo/overlayfs/funcs_embedfsmember.go (100%) rename {fsx => iox/fsx}/internal/todo/overlayfs/funcs_mergedfs.go (100%) rename {fsx => iox/fsx}/internal/todo/overlayfs/funcs_realfsmember.go (100%) rename {fsx => iox/fsx}/internal/todo/overlayfs/types.go (100%) create mode 100644 netx/TODO diff --git a/iox/fsx/doc.go b/iox/fsx/doc.go new file mode 100644 index 0000000..e23d93c --- /dev/null +++ b/iox/fsx/doc.go @@ -0,0 +1,4 @@ +/* +Package fsx provides some enhancements to [io/fs]. +*/ +package fsx diff --git a/iox/fsx/funcs.go b/iox/fsx/funcs.go new file mode 100644 index 0000000..2da9885 --- /dev/null +++ b/iox/fsx/funcs.go @@ -0,0 +1,102 @@ +package fsx + +import ( + "go/types" + "io/fs" + "path/filepath" +) + +/* +FsPaths returns all paths in [io/fs.FS] `fsys`. + +If `fsys` is nil, both `fsPaths` and `err` will be nil. + +`t` should be an OR'd [io/fs.FileMode] containing all filetypes that should be included. +Use [io/fs.ModeType] to match any non-regular-file object, or 0 to explicitly match regular files. +If `t` is non-zero but you wish to ALSO include regular files, then specify `inclFiles` as true. +(`inclFiles` is ignored if `t` == 0, as this inherently matches regular files only/explicitly.) +See [HasType] for more information on this filtering. + +`maxDepth` can be used to limit recursion depth. + + - If `maxDepth` == 0, only direct [io/fs.DirEntry] descendants of `fsys` + will be included in `fsPaths`. + - If `maxDepth` < 0, ALL [io/fs.DirEntry] descendants of `fsys` + will be included in `fsPaths`. + - If `maxDepth` > 0, then only children at a depth of this level or lower + ("higher" in a hierarchy) will be included in `fsPaths`. +*/ +func FsPaths(fsys fs.FS, t fs.FileMode, inclFiles bool, maxDepth int) (fsPaths map[string]fs.DirEntry, err error) { + + var idx int + var entries []fs.DirEntry + var t fs.FileMode = types.Type() + + if fsys == nil { + return + } + + if fsPaths, err = getEntries(fsys, t, inclFiles, maxDepth, "."); err != nil { + return + } + + return +} + +/* +HasType is just a convenience wrapper for: + + hasType = m & t != 0 + +The type(s) will be explicitly extracted from `m` and `t` first. + +Note that if `t` is an OR'd set of filetypes, then HasType will return true if ANY of the types +in `t` match `m`'s type (see [r00t2.io/goutils/bitmask] for more information on bitmasking). +If you wish to check if `m` is A SINGLE type, either ensure that `t` is not OR'd +(i.e. is a single fs.FileMode type) or use [IsType] instead. +*/ +func HasType(m, t fs.FileMode) (hasType bool) { return m.Type()&t.Type() != 0 } + +/* +IsType is just a convenience wrapper for: + + isType = m & t == t + +The type(s) will be explicitly extracted from `m` and `t` first. + +Note that if `t` is an OR'd set of filetypes, then IsType will *never* return true +as its type is single-valued/not bitmasked (see [r00t2.io/goutils/bitmask] for more information +on bitmasking). +If you wish to check if `m` is ONE OF multiple types in `t`, use [HasType] instead. +*/ +func IsType(m, t fs.FileMode) (isType bool) { return m&t == t } + +/* +getEntries is used to recursively fetch entries from `fsys`. + +It mostly serves as the recursion for [FsPaths], and the arguments +retain their exact meaning except that it requires `relPath` +and `maxDepth` (if > 0) will be decremanted in each recursion. +*/ +func getEntries(fsys fs.FS, t fs.FileMode, inclFiles bool, maxDepth int, relPath string) (fsPaths map[string]fs.DirEntry, err error) { + + var idx int + var p string + var e []fs.DirEntry + var subs map[string]fs.DirEntry = make(map[string]fs.DirEntry) + + if e, err = fs.ReadDir(fsys, relPath); err != nil { + return + } + + for idx = range e { + p = filepath.Join(relPath, e[idx].Name()) + if e[idx].IsDir() { + if subs, err = getEntries(fsys, t, inclFiles, maxDepth, p); err != nil { + return + } + } + } + + return +} diff --git a/fsx/internal/todo/overlayfs/funcs.go b/iox/fsx/internal/todo/overlayfs/funcs.go similarity index 100% rename from fsx/internal/todo/overlayfs/funcs.go rename to iox/fsx/internal/todo/overlayfs/funcs.go diff --git a/fsx/internal/todo/overlayfs/funcs_embedfsmember.go b/iox/fsx/internal/todo/overlayfs/funcs_embedfsmember.go similarity index 100% rename from fsx/internal/todo/overlayfs/funcs_embedfsmember.go rename to iox/fsx/internal/todo/overlayfs/funcs_embedfsmember.go diff --git a/fsx/internal/todo/overlayfs/funcs_mergedfs.go b/iox/fsx/internal/todo/overlayfs/funcs_mergedfs.go similarity index 100% rename from fsx/internal/todo/overlayfs/funcs_mergedfs.go rename to iox/fsx/internal/todo/overlayfs/funcs_mergedfs.go diff --git a/fsx/internal/todo/overlayfs/funcs_realfsmember.go b/iox/fsx/internal/todo/overlayfs/funcs_realfsmember.go similarity index 100% rename from fsx/internal/todo/overlayfs/funcs_realfsmember.go rename to iox/fsx/internal/todo/overlayfs/funcs_realfsmember.go diff --git a/fsx/internal/todo/overlayfs/types.go b/iox/fsx/internal/todo/overlayfs/types.go similarity index 100% rename from fsx/internal/todo/overlayfs/types.go rename to iox/fsx/internal/todo/overlayfs/types.go diff --git a/netx/TODO b/netx/TODO new file mode 100644 index 0000000..8e36a34 --- /dev/null +++ b/netx/TODO @@ -0,0 +1 @@ +- does IsAdd4Compat work properly with loopback ::1? diff --git a/netx/dnsx/funcs.go b/netx/dnsx/funcs.go index d1c7c23..f67333b 100644 --- a/netx/dnsx/funcs.go +++ b/netx/dnsx/funcs.go @@ -1,16 +1,16 @@ package dnsx import ( - `bytes` - `encoding/base32` - `fmt` - `math` - `net` - `net/netip` - `strings` + "bytes" + "encoding/base32" + "fmt" + "math" + "net" + "net/netip" + "strings" - `go4.org/netipx` - `r00t2.io/goutils/stringsx` + "go4.org/netipx" + "r00t2.io/goutils/stringsx" ) /* @@ -238,19 +238,19 @@ TXT records, etc. - not A/AAAA/CNAME, etc. - see RFC 8553 for details. See the following functions for allowing additional syntax/rule validation that have record-type-specific accommodations made: - * [IsFqdnDefinedTxt] - * [IsFqdnNsec3] - * [IsFqdnSrv] - * [IsFqdnWildcard] + - [IsFqdnDefinedTxt] + - [IsFqdnNsec3] + - [IsFqdnSrv] + - [IsFqdnWildcard] # RFC Coverage This function should conform properly to: - * RFC 952 - * RFC 1034 and RFC 1035 - * RFC 1123 - * RFC 2181 (selectively, see above) + - RFC 952 + - RFC 1034 and RFC 1035 + - RFC 1123 + - RFC 2181 (selectively, see above) preferring the most up-to-date rules where relevant (e.g. labels may start with digits, as per RFC 1123). It enforces/checks label and overall length limits as defined by RFC. @@ -265,12 +265,12 @@ the caller must perform translation first To reiterate, IDN/IDNA: - * RFC 3490 - * RFC 5890 - * RFC 5891 - * RFC 5892 - * RFC 5893 - * RFC 5894 + - RFC 3490 + - RFC 5890 + - RFC 5891 + - RFC 5892 + - RFC 5893 + - RFC 5894 and Punycode (RFC 3492) *MUST* use their ASCII forms, NOT the localized/Unicode formats. @@ -299,18 +299,18 @@ func IsFqdn(s string) (fqdn bool) { IsFqdnDefinedTxt is like [IsFqdn] but explicitly *only* allows fully-qualified RFC-defined TXT "subtypes": - * ACME DNS-01 (RFC 8555) - * BIMI (RFC draft [bimi]) - * DKIM (RFC 6376, RFC 8301, RFC 8463) - * DKIM ATPS (RFC 6541) - * DMARC (RFC 7489, RFC 9091, RFC 9616) - * MTA-STS (RFC 8461) - * TLSRPT (RFC 8460) + - ACME DNS-01 (RFC 8555) + - BIMI (RFC draft [bimi]) + - DKIM (RFC 6376, RFC 8301, RFC 8463) + - DKIM ATPS (RFC 6541) + - DMARC (RFC 7489, RFC 9091, RFC 9616) + - MTA-STS (RFC 8461) + - TLSRPT (RFC 8460) Note that the following TXT "subtypes" do not have special formatting in labels/name, and thus are not covered by this function: - * SPF (RFC 4408, RFC 7208) + - SPF (RFC 4408, RFC 7208) [bimi]: https://datatracker.ietf.org/doc/html/draft-brand-indicators-for-message-identification */ @@ -359,15 +359,15 @@ can't be 100% confirmed with certainty - only basic checks can be done. NSEC3 can be found via: - * RFC 5155 - * RFC 6840 - * RFC 6944 - * RFC 7129 - * RFC 8198 - * RFC 9077 - * RFC 9157 - * RFC 9276 - * RFC 9905 + - RFC 5155 + - RFC 6840 + - RFC 6944 + - RFC 7129 + - RFC 8198 + - RFC 9077 + - RFC 9157 + - RFC 9276 + - RFC 9905 At the time of writing, only one hashing algorithm (SHA-1) has been specified. However, because this function does not check against the IANA registration at runtime, @@ -524,6 +524,22 @@ func IsPtr(s string) (isPtr bool, addr net.IP) { return } +// IsPtrAddr is like IsPtr but only returns the `addr` value. +func IsPtrAddr(s string) (addr net.IP) { + + _, addr = IsPtr(s) + + return +} + +// IsPtrChk is like IsPtr but only returns the `isPtr` value. +func IsPtrChk(s string) (isPtr bool) { + + isPtr, _ = IsPtr(s) + + return +} + // commonFqdn is used to validate some rules common to all record names. func commonFqdn(s string) (isOk bool) { diff --git a/tplx/sprigx/README.html b/tplx/sprigx/README.html index 2385791..5cf6e10 100644 --- a/tplx/sprigx/README.html +++ b/tplx/sprigx/README.html @@ -636,7 +636,7 @@ pre.rouge .gs {
Brent Saner

-Last rendered 2026-07-29 15:05:41 -0400 +Last rendered 2026-08-08 00:13:35 -0400
Table of Contents
diff --git a/tplx/sprigx/README.md b/tplx/sprigx/README.md index ac22b1f..af5320e 100644 --- a/tplx/sprigx/README.md +++ b/tplx/sprigx/README.md @@ -6,7 +6,7 @@ Brent Saner -Last rendered 2026-07-29 15:05:45 -0400 +Last rendered 2026-08-08 00:13:40 -0400
diff --git a/tplx/sprigx/consts.go b/tplx/sprigx/consts.go index 43fdb78..f06de2c 100644 --- a/tplx/sprigx/consts.go +++ b/tplx/sprigx/consts.go @@ -1,30 +1,30 @@ package sprigx import ( - `net` - `net/netip` - `os` - `os/user` - `path` - `path/filepath` - `runtime` - `time` + "net" + "net/netip" + "os" + "os/user" + "path" + "path/filepath" + "runtime" + "time" - `github.com/davecgh/go-spew/spew` - `github.com/shirou/gopsutil/v4/cpu` - `github.com/shirou/gopsutil/v4/disk` - `github.com/shirou/gopsutil/v4/host` - `github.com/shirou/gopsutil/v4/load` - `github.com/shirou/gopsutil/v4/mem` - psnet `github.com/shirou/gopsutil/v4/net` - `github.com/shirou/gopsutil/v4/process` - `github.com/shirou/gopsutil/v4/sensors` - `go4.org/netipx` - `r00t2.io/goutils/netx` - `r00t2.io/goutils/netx/dnsx` - `r00t2.io/goutils/stringsx` - `r00t2.io/goutils/timex` - `r00t2.io/sysutils` + "github.com/davecgh/go-spew/spew" + "github.com/shirou/gopsutil/v4/cpu" + "github.com/shirou/gopsutil/v4/disk" + "github.com/shirou/gopsutil/v4/host" + "github.com/shirou/gopsutil/v4/load" + "github.com/shirou/gopsutil/v4/mem" + psnet "github.com/shirou/gopsutil/v4/net" + "github.com/shirou/gopsutil/v4/process" + "github.com/shirou/gopsutil/v4/sensors" + "go4.org/netipx" + "r00t2.io/goutils/netx" + "r00t2.io/goutils/netx/dnsx" + "r00t2.io/goutils/stringsx" + "r00t2.io/goutils/timex" + "r00t2.io/sysutils" ) var ( @@ -98,19 +98,20 @@ var ( /* Networking (r00t.io/goutils/netx/dnsx) */ - "dnsxPtrAddr": dnsx.AddrFromPtr, - "dnsxAddrPtr": dnsx.AddrToPtr, - "dnsxStrWire": dnsx.DnsStrToWire, - "dnsxWireStr": dnsx.DnsWireToStr, - "dnsxPtrIp": dnsx.IpFromPtr, - "dnsxIpPtr": dnsx.IpToPtr, - "dnsxIsFqdn": dnsx.IsFqdn, - "dnsxIsTxt": dnsx.IsFqdnDefinedTxt, - "dnsxIsNsec3": dnsx.IsFqdnNsec3, - "dnsxIsSrv": dnsx.IsFqdnSrv, - "dnsxIsWild": dnsx.IsFqdnWildcard, - "dnsxIsLbl": dnsx.IsLabel, - "dnsxIsPtr": dnsx.IsPtr, + "dnsxPtrAddr": dnsx.AddrFromPtr, + "dnsxAddrPtr": dnsx.AddrToPtr, + "dnsxStrWire": dnsx.DnsStrToWire, + "dnsxWireStr": dnsx.DnsWireToStr, + "dnsxPtrIp": dnsx.IpFromPtr, + "dnsxIpPtr": dnsx.IpToPtr, + "dnsxIsFqdn": dnsx.IsFqdn, + "dnsxIsTxt": dnsx.IsFqdnDefinedTxt, + "dnsxIsNsec3": dnsx.IsFqdnNsec3, + "dnsxIsSrv": dnsx.IsFqdnSrv, + "dnsxIsWild": dnsx.IsFqdnWildcard, + "dnsxIsLbl": dnsx.IsLabel, + "dnsxIsPtrAddr": dnsx.IsPtrAddr, + "dnsxIsPtr": dnsx.IsPtrChk, /* Numbers/Math */