Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
4e7d474fb3
|
@@ -0,0 +1,4 @@
|
||||
/*
|
||||
Package fsx provides some enhancements to [io/fs].
|
||||
*/
|
||||
package fsx
|
||||
@@ -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
|
||||
}
|
||||
+56
-40
@@ -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) {
|
||||
|
||||
|
||||
@@ -636,7 +636,7 @@ pre.rouge .gs {
|
||||
<div class="details">
|
||||
<span id="author" class="author">Brent Saner</span><br>
|
||||
<span id="email" class="email"><a href="mailto:bts@square-r00t.net">bts@square-r00t.net</a></span><br>
|
||||
<span id="revdate">Last rendered 2026-07-29 15:05:41 -0400</span>
|
||||
<span id="revdate">Last rendered 2026-08-08 00:13:35 -0400</span>
|
||||
</div>
|
||||
<div id="toc" class="toc2">
|
||||
<div id="toctitle">Table of Contents</div>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<span id="author" class="author">Brent Saner</span>
|
||||
<span id="email" class="email"><bts@square-r00t.net></span>
|
||||
<span id="revdate">Last rendered 2026-07-29 15:05:45 -0400</span>
|
||||
<span id="revdate">Last rendered 2026-08-08 00:13:40 -0400</span>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
+25
-24
@@ -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 (
|
||||
@@ -110,7 +110,8 @@ var (
|
||||
"dnsxIsSrv": dnsx.IsFqdnSrv,
|
||||
"dnsxIsWild": dnsx.IsFqdnWildcard,
|
||||
"dnsxIsLbl": dnsx.IsLabel,
|
||||
"dnsxIsPtr": dnsx.IsPtr,
|
||||
"dnsxIsPtrAddr": dnsx.IsPtrAddr,
|
||||
"dnsxIsPtr": dnsx.IsPtrChk,
|
||||
/*
|
||||
Numbers/Math
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user