mirror of
https://github.com/ergochat/ergo.git
synced 2025-08-02 10:47:31 +02:00
Compare commits
28 Commits
v2.16.0-rc
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
65295cbafa | ||
![]() |
f0b1f34da7 | ||
![]() |
f918e28513 | ||
![]() |
8798676ae9 | ||
![]() |
cca400de73 | ||
![]() |
73e51333ad | ||
![]() |
a5e435a26b | ||
![]() |
17ed01c1ed | ||
![]() |
8f18454e8f | ||
![]() |
23844d4103 | ||
![]() |
3b7db7fff7 | ||
![]() |
4dcbc48159 | ||
![]() |
0f5603eca2 | ||
![]() |
7d4f5e4adf | ||
![]() |
16568c5ab7 | ||
![]() |
9a186f8e54 | ||
![]() |
7828218bc7 | ||
![]() |
7138e76151 | ||
![]() |
e4aac56bda | ||
![]() |
4da6511674 | ||
![]() |
253972a9d2 | ||
![]() |
a1c46a4be7 | ||
![]() |
7718081440 | ||
![]() |
e7501ef847 | ||
![]() |
e404942d83 | ||
![]() |
0a947115d6 | ||
![]() |
9b9c39ddd4 | ||
![]() |
e200e9fd8f |
@ -1,14 +1,15 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
All notable changes to Ergo will be documented in this file.
|
All notable changes to Ergo will be documented in this file.
|
||||||
|
|
||||||
## [2.16.0-rc1] - 2025-05-11
|
## [2.16.0] - 2025-05-18
|
||||||
We're pleased to be publishing the release candidate for v2.16.0 (the official release should follow within a week or so). This release contains bug fixes and some minor updates.
|
We're pleased to be publishing v2.16.0, a new stable release. This release contains bug fixes and some minor updates.
|
||||||
|
|
||||||
This release includes changes to the config file format, all of which are fully backwards-compatible and do not require updating the file before upgrading. It includes no changes to the database file format.
|
This release includes changes to the config file format, all of which are fully backwards-compatible and do not require updating the file before upgrading. It includes no changes to the database file format.
|
||||||
|
|
||||||
Many thanks to [@csmith](https://github.com/csmith), [@delthas](https://github.com/delthas), donio, [@emersion](https://github.com/emersion), [@KlaasT](https://github.com/KlaasT), [@knolley](https://github.com/knolley), [@Mailaender](https://github.com/Mailaender), and [@prdes](https://github.com/prdes) for reporting issues and helping test.
|
Many thanks to [@csmith](https://github.com/csmith), [@delthas](https://github.com/delthas), donio, [@emersion](https://github.com/emersion), [@KlaasT](https://github.com/KlaasT), [@knolley](https://github.com/knolley), [@Mailaender](https://github.com/Mailaender), and [@prdes](https://github.com/prdes) for reporting issues and helping test.
|
||||||
|
|
||||||
### Config changes
|
### Config changes
|
||||||
|
* Added `api` block for configuring the new HTTP API. If this block is absent, the API is disabled (#2231)
|
||||||
* Added `server.additional-isupport` for publishing arbitrary ISUPPORT tokens (#2220, #2240)
|
* Added `server.additional-isupport` for publishing arbitrary ISUPPORT tokens (#2220, #2240)
|
||||||
* Added `server.command-aliases` to configure aliases for server commands (#2229, #2236)
|
* Added `server.command-aliases` to configure aliases for server commands (#2229, #2236)
|
||||||
* Added options to `roleplay` to customize the NUH's sent for `NPC` and `SCENE`. Roleplay remains deprecated and disabled by default. (#2237)
|
* Added options to `roleplay` to customize the NUH's sent for `NPC` and `SCENE`. Roleplay remains deprecated and disabled by default. (#2237)
|
||||||
|
11
Makefile
11
Makefile
@ -1,5 +1,3 @@
|
|||||||
.PHONY: all install build release capdefs test smoke gofmt irctest
|
|
||||||
|
|
||||||
GIT_COMMIT := $(shell git rev-parse HEAD 2> /dev/null)
|
GIT_COMMIT := $(shell git rev-parse HEAD 2> /dev/null)
|
||||||
GIT_TAG := $(shell git tag --points-at HEAD 2> /dev/null | head -n 1)
|
GIT_TAG := $(shell git tag --points-at HEAD 2> /dev/null | head -n 1)
|
||||||
|
|
||||||
@ -9,33 +7,42 @@ export CGO_ENABLED ?= 0
|
|||||||
|
|
||||||
capdef_file = ./irc/caps/defs.go
|
capdef_file = ./irc/caps/defs.go
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
install:
|
install:
|
||||||
go install -v -ldflags "-X main.commit=$(GIT_COMMIT) -X main.version=$(GIT_TAG)"
|
go install -v -ldflags "-X main.commit=$(GIT_COMMIT) -X main.version=$(GIT_TAG)"
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
build:
|
build:
|
||||||
go build -v -ldflags "-X main.commit=$(GIT_COMMIT) -X main.version=$(GIT_TAG)"
|
go build -v -ldflags "-X main.commit=$(GIT_COMMIT) -X main.version=$(GIT_TAG)"
|
||||||
|
|
||||||
|
.PHONY: release
|
||||||
release:
|
release:
|
||||||
goreleaser --skip=publish --clean
|
goreleaser --skip=publish --clean
|
||||||
|
|
||||||
|
.PHONY: capdefs
|
||||||
capdefs:
|
capdefs:
|
||||||
python3 ./gencapdefs.py > ${capdef_file}
|
python3 ./gencapdefs.py > ${capdef_file}
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
python3 ./gencapdefs.py | diff - ${capdef_file}
|
python3 ./gencapdefs.py | diff - ${capdef_file}
|
||||||
go test ./...
|
go test ./...
|
||||||
go vet ./...
|
go vet ./...
|
||||||
./.check-gofmt.sh
|
./.check-gofmt.sh
|
||||||
|
|
||||||
|
.PHONY: smoke
|
||||||
smoke: install
|
smoke: install
|
||||||
ergo mkcerts --conf ./default.yaml || true
|
ergo mkcerts --conf ./default.yaml || true
|
||||||
ergo run --conf ./default.yaml --smoke
|
ergo run --conf ./default.yaml --smoke
|
||||||
|
|
||||||
|
.PHONY: gofmt
|
||||||
gofmt:
|
gofmt:
|
||||||
./.check-gofmt.sh --fix
|
./.check-gofmt.sh --fix
|
||||||
|
|
||||||
|
.PHONY: irctest
|
||||||
irctest: install
|
irctest: install
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
cd irctest && make ergo
|
cd irctest && make ergo
|
||||||
|
12
default.yaml
12
default.yaml
@ -522,7 +522,7 @@ accounts:
|
|||||||
# 1. these nicknames cannot be registered or reserved
|
# 1. these nicknames cannot be registered or reserved
|
||||||
# 2. if a client is automatically renamed by the server,
|
# 2. if a client is automatically renamed by the server,
|
||||||
# this is the template that will be used (e.g., Guest-nccj6rgmt97cg)
|
# this is the template that will be used (e.g., Guest-nccj6rgmt97cg)
|
||||||
# 3. if enforce-guest-format (see below) is enabled, clients without
|
# 3. if force-guest-format (see below) is enabled, clients without
|
||||||
# a registered account will have this template applied to their
|
# a registered account will have this template applied to their
|
||||||
# nicknames (e.g., 'katie' will become 'Guest-katie')
|
# nicknames (e.g., 'katie' will become 'Guest-katie')
|
||||||
guest-nickname-format: "Guest-*"
|
guest-nickname-format: "Guest-*"
|
||||||
@ -724,6 +724,7 @@ oper-classes:
|
|||||||
- "history" # modify or delete history messages
|
- "history" # modify or delete history messages
|
||||||
- "defcon" # use the DEFCON command (restrict server capabilities)
|
- "defcon" # use the DEFCON command (restrict server capabilities)
|
||||||
- "massmessage" # message all users on the server
|
- "massmessage" # message all users on the server
|
||||||
|
- "metadata" # modify arbitrary metadata on channels and users
|
||||||
|
|
||||||
# ircd operators
|
# ircd operators
|
||||||
opers:
|
opers:
|
||||||
@ -1087,6 +1088,15 @@ history:
|
|||||||
# e.g., ERGO__SERVER__MAX_SENDQ=128k. see the manual for more details.
|
# e.g., ERGO__SERVER__MAX_SENDQ=128k. see the manual for more details.
|
||||||
allow-environment-overrides: true
|
allow-environment-overrides: true
|
||||||
|
|
||||||
|
# metadata support for setting key/value data on channels and nicknames.
|
||||||
|
metadata:
|
||||||
|
# can clients store metadata?
|
||||||
|
enabled: true
|
||||||
|
# how many keys can a client subscribe to?
|
||||||
|
max-subs: 100
|
||||||
|
# how many keys can be stored per entity?
|
||||||
|
max-keys: 100
|
||||||
|
|
||||||
# experimental support for mobile push notifications
|
# experimental support for mobile push notifications
|
||||||
# see the manual for potential security, privacy, and performance implications.
|
# see the manual for potential security, privacy, and performance implications.
|
||||||
# DO NOT enable if you are running a Tor or I2P hidden service (i.e. one
|
# DO NOT enable if you are running a Tor or I2P hidden service (i.e. one
|
||||||
|
36
docs/API.md
36
docs/API.md
@ -51,6 +51,8 @@ The response is a JSON object with fields:
|
|||||||
* `success`: whether the account exists or not
|
* `success`: whether the account exists or not
|
||||||
* `accountName`: canonical, case-unfolded version of the account name
|
* `accountName`: canonical, case-unfolded version of the account name
|
||||||
* `email`: email address of the account provided
|
* `email`: email address of the account provided
|
||||||
|
* `registeredAt`: string, registration date/time of the account (in ISO8601 format)
|
||||||
|
* `channels`: array of strings, list of channels the account is registered on or associated with
|
||||||
|
|
||||||
`/v1/check_auth`
|
`/v1/check_auth`
|
||||||
----------------
|
----------------
|
||||||
@ -86,3 +88,37 @@ The response is a JSON object with fields:
|
|||||||
* `success`: whether the account creation succeeded
|
* `success`: whether the account creation succeeded
|
||||||
* `errorCode`: string, optional, machine-readable description of the error. Possible values include: `ACCOUNT_EXISTS`, `INVALID_PASSPHRASE`, `UNKNOWN_ERROR`.
|
* `errorCode`: string, optional, machine-readable description of the error. Possible values include: `ACCOUNT_EXISTS`, `INVALID_PASSPHRASE`, `UNKNOWN_ERROR`.
|
||||||
* `error`: string, optional, human-readable description of the failure.
|
* `error`: string, optional, human-readable description of the failure.
|
||||||
|
|
||||||
|
`/v1/account_list`
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
This endpoint fetches a list of all accounts. The request body is ignored and can be empty.
|
||||||
|
|
||||||
|
The response is a JSON object with fields:
|
||||||
|
|
||||||
|
* `success`: whether the request succeeded
|
||||||
|
* `accounts`: array of objects, each with fields:
|
||||||
|
* `success`: boolean, whether this individual account query succeeded
|
||||||
|
* `accountName`: string, canonical, case-unfolded version of the account name
|
||||||
|
* `totalCount`: integer, total number of accounts returned
|
||||||
|
|
||||||
|
|
||||||
|
`/v1/status`
|
||||||
|
-------------
|
||||||
|
|
||||||
|
This endpoint returns status information about the running Ergo server. The request body is ignored and can be empty.
|
||||||
|
|
||||||
|
The response is a JSON object with fields:
|
||||||
|
|
||||||
|
* `success`: whether the request succeeded
|
||||||
|
* `version`: string, Ergo server version string
|
||||||
|
* `go_version`: string, version of Go runtime used
|
||||||
|
* `start_time`: string, server start time in ISO8601 format
|
||||||
|
* `users`: object with fields:
|
||||||
|
* `total`: total number of users connected
|
||||||
|
* `invisible`: number of invisible users
|
||||||
|
* `operators`: number of operators connected
|
||||||
|
* `unknown`: number of users with unknown status
|
||||||
|
* `max`: maximum number of users seen connected at once
|
||||||
|
* `channels`: integer, number of channels currently active
|
||||||
|
* `servers`: integer, number of servers connected in the network
|
||||||
|
@ -86,7 +86,7 @@ Once you've registered your nickname, you can use it to register channels. By de
|
|||||||
/msg ChanServ register #myChannel
|
/msg ChanServ register #myChannel
|
||||||
```
|
```
|
||||||
|
|
||||||
You must already be an operator (have the `+o` channel mode --- your client may display this as an `@` next to your nickname). If you're not a channel operator in the channel you want to register, ask your server administrator for help.
|
The channel must exist (if it doesn't, you can create it with `/join #myChannel`) and you must already be an operator (have the `+o` channel mode --- your client may display this as an `@` next to your nickname). If you're not a channel operator in the channel you want to register, ask your server administrator for help.
|
||||||
|
|
||||||
# Always-on
|
# Always-on
|
||||||
|
|
||||||
|
@ -237,6 +237,13 @@ CAPDEFS = [
|
|||||||
url="https://github.com/ircv3/ircv3-specifications/pull/471",
|
url="https://github.com/ircv3/ircv3-specifications/pull/471",
|
||||||
standard="Soju/Goguma vendor",
|
standard="Soju/Goguma vendor",
|
||||||
),
|
),
|
||||||
|
CapDef(
|
||||||
|
identifier="Metadata",
|
||||||
|
name="draft/metadata-2",
|
||||||
|
url="https://ircv3.net/specs/extensions/metadata",
|
||||||
|
standard="draft IRCv3",
|
||||||
|
),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def validate_defs():
|
def validate_defs():
|
||||||
|
10
go.mod
10
go.mod
@ -18,14 +18,14 @@ require (
|
|||||||
github.com/stretchr/testify v1.4.0 // indirect
|
github.com/stretchr/testify v1.4.0 // indirect
|
||||||
github.com/tidwall/buntdb v1.3.2
|
github.com/tidwall/buntdb v1.3.2
|
||||||
github.com/xdg-go/scram v1.0.2
|
github.com/xdg-go/scram v1.0.2
|
||||||
golang.org/x/crypto v0.32.0
|
golang.org/x/crypto v0.38.0
|
||||||
golang.org/x/term v0.28.0
|
golang.org/x/term v0.32.0
|
||||||
golang.org/x/text v0.21.0
|
golang.org/x/text v0.25.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/emersion/go-msgauth v0.6.8
|
github.com/emersion/go-msgauth v0.7.0
|
||||||
github.com/ergochat/webpush-go/v2 v2.0.0
|
github.com/ergochat/webpush-go/v2 v2.0.0
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2
|
github.com/golang-jwt/jwt/v5 v5.2.2
|
||||||
)
|
)
|
||||||
@ -39,7 +39,7 @@ require (
|
|||||||
github.com/tidwall/rtred v0.1.2 // indirect
|
github.com/tidwall/rtred v0.1.2 // indirect
|
||||||
github.com/tidwall/tinyqueue v0.1.1 // indirect
|
github.com/tidwall/tinyqueue v0.1.1 // indirect
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||||
golang.org/x/sys v0.29.0 // indirect
|
golang.org/x/sys v0.33.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/gorilla/websocket => github.com/ergochat/websocket v1.4.2-oragono1
|
replace github.com/gorilla/websocket => github.com/ergochat/websocket v1.4.2-oragono1
|
||||||
|
10
go.sum
10
go.sum
@ -8,6 +8,8 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh
|
|||||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||||
github.com/emersion/go-msgauth v0.6.8 h1:kW/0E9E8Zx5CdKsERC/WnAvnXvX7q9wTHia1OA4944A=
|
github.com/emersion/go-msgauth v0.6.8 h1:kW/0E9E8Zx5CdKsERC/WnAvnXvX7q9wTHia1OA4944A=
|
||||||
github.com/emersion/go-msgauth v0.6.8/go.mod h1:YDwuyTCUHu9xxmAeVj0eW4INnwB6NNZoPdLerpSxRrc=
|
github.com/emersion/go-msgauth v0.6.8/go.mod h1:YDwuyTCUHu9xxmAeVj0eW4INnwB6NNZoPdLerpSxRrc=
|
||||||
|
github.com/emersion/go-msgauth v0.7.0 h1:vj2hMn6KhFtW41kshIBTXvp6KgYSqpA/ZN9Pv4g1INc=
|
||||||
|
github.com/emersion/go-msgauth v0.7.0/go.mod h1:mmS9I6HkSovrNgq0HNXTeu8l3sRAAuQ9RMvbM4KU7Ck=
|
||||||
github.com/ergochat/confusables v0.0.0-20201108231250-4ab98ab61fb1 h1:WLHTOodthVyv5NvYLIvWl112kSFv5IInKKrRN2qpons=
|
github.com/ergochat/confusables v0.0.0-20201108231250-4ab98ab61fb1 h1:WLHTOodthVyv5NvYLIvWl112kSFv5IInKKrRN2qpons=
|
||||||
github.com/ergochat/confusables v0.0.0-20201108231250-4ab98ab61fb1/go.mod h1:mov+uh1DPWsltdQnOdzn08UO9GsJ3MEvhtu0Ci37fdk=
|
github.com/ergochat/confusables v0.0.0-20201108231250-4ab98ab61fb1/go.mod h1:mov+uh1DPWsltdQnOdzn08UO9GsJ3MEvhtu0Ci37fdk=
|
||||||
github.com/ergochat/go-ident v0.0.0-20230911071154-8c30606d6881 h1:+J5m88nvybxB5AnBVGzTXM/yHVytt48rXBGcJGzSbms=
|
github.com/ergochat/go-ident v0.0.0-20230911071154-8c30606d6881 h1:+J5m88nvybxB5AnBVGzTXM/yHVytt48rXBGcJGzSbms=
|
||||||
@ -70,6 +72,8 @@ github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyh
|
|||||||
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
|
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
|
||||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||||
|
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
|
||||||
|
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
@ -78,12 +82,18 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||||
|
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
||||||
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||||
|
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
|
||||||
|
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
|
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
||||||
|
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
103
irc/api.go
103
irc/api.go
@ -5,7 +5,10 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ergochat/ergo/irc/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newAPIHandler(server *Server) http.Handler {
|
func newAPIHandler(server *Server) http.Handler {
|
||||||
@ -18,6 +21,8 @@ func newAPIHandler(server *Server) http.Handler {
|
|||||||
api.mux.HandleFunc("POST /v1/check_auth", api.handleCheckAuth)
|
api.mux.HandleFunc("POST /v1/check_auth", api.handleCheckAuth)
|
||||||
api.mux.HandleFunc("POST /v1/saregister", api.handleSaregister)
|
api.mux.HandleFunc("POST /v1/saregister", api.handleSaregister)
|
||||||
api.mux.HandleFunc("POST /v1/account_details", api.handleAccountDetails)
|
api.mux.HandleFunc("POST /v1/account_details", api.handleAccountDetails)
|
||||||
|
api.mux.HandleFunc("POST /v1/account_list", api.handleAccountList)
|
||||||
|
api.mux.HandleFunc("POST /v1/status", api.handleStatus)
|
||||||
|
|
||||||
return api
|
return api
|
||||||
}
|
}
|
||||||
@ -29,7 +34,6 @@ type ergoAPI struct {
|
|||||||
|
|
||||||
func (a *ergoAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (a *ergoAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
defer a.server.HandlePanic(nil)
|
defer a.server.HandlePanic(nil)
|
||||||
|
|
||||||
defer a.server.logger.Debug("api", r.URL.Path)
|
defer a.server.logger.Debug("api", r.URL.Path)
|
||||||
|
|
||||||
if a.checkBearerAuth(r.Header.Get("Authorization")) {
|
if a.checkBearerAuth(r.Header.Get("Authorization")) {
|
||||||
@ -117,8 +121,6 @@ func (a *ergoAPI) handleCheckAuth(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// try passphrase if present
|
// try passphrase if present
|
||||||
if request.AccountName != "" && request.Passphrase != "" {
|
if request.AccountName != "" && request.Passphrase != "" {
|
||||||
// TODO this only checks the internal database, not auth-script;
|
|
||||||
// it's a little weird to use both auth-script and the API but we should probably handle it
|
|
||||||
account, err := a.server.accounts.checkPassphrase(request.AccountName, request.Passphrase)
|
account, err := a.server.accounts.checkPassphrase(request.AccountName, request.Passphrase)
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
@ -133,7 +135,6 @@ func (a *ergoAPI) handleCheckAuth(w http.ResponseWriter, r *http.Request) {
|
|||||||
response.Error = err.Error()
|
response.Error = err.Error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// try certfp if present
|
// try certfp if present
|
||||||
if !response.Success && request.Certfp != "" {
|
if !response.Success && request.Certfp != "" {
|
||||||
// TODO support cerftp
|
// TODO support cerftp
|
||||||
@ -175,8 +176,10 @@ func (a *ergoAPI) handleSaregister(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
type apiAccountDetailsResponse struct {
|
type apiAccountDetailsResponse struct {
|
||||||
apiGenericResponse
|
apiGenericResponse
|
||||||
AccountName string `json:"accountName,omitempty"`
|
AccountName string `json:"accountName,omitempty"`
|
||||||
Email string `json:"email,omitempty"`
|
Email string `json:"email,omitempty"`
|
||||||
|
RegisteredAt string `json:"registeredAt,omitempty"`
|
||||||
|
Channels []string `json:"channels,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiAccountDetailsRequest struct {
|
type apiAccountDetailsRequest struct {
|
||||||
@ -191,8 +194,6 @@ func (a *ergoAPI) handleAccountDetails(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
var response apiAccountDetailsResponse
|
var response apiAccountDetailsResponse
|
||||||
|
|
||||||
// TODO could probably use better error handling and more details
|
|
||||||
|
|
||||||
if request.AccountName != "" {
|
if request.AccountName != "" {
|
||||||
accountData, err := a.server.accounts.LoadAccount(request.AccountName)
|
accountData, err := a.server.accounts.LoadAccount(request.AccountName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -207,6 +208,12 @@ func (a *ergoAPI) handleAccountDetails(w http.ResponseWriter, r *http.Request) {
|
|||||||
case nil:
|
case nil:
|
||||||
response.AccountName = accountData.Name
|
response.AccountName = accountData.Name
|
||||||
response.Email = accountData.Settings.Email
|
response.Email = accountData.Settings.Email
|
||||||
|
if !accountData.RegisteredAt.IsZero() {
|
||||||
|
response.RegisteredAt = accountData.RegisteredAt.Format(utils.IRCv3TimestampFormat)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get channels the account is in
|
||||||
|
response.Channels = a.server.channels.ChannelsForAccount(accountData.NameCasefolded)
|
||||||
response.Success = true
|
response.Success = true
|
||||||
case errAccountDoesNotExist, errAccountUnverified, errAccountSuspended:
|
case errAccountDoesNotExist, errAccountUnverified, errAccountSuspended:
|
||||||
response.Success = false
|
response.Success = false
|
||||||
@ -222,3 +229,83 @@ func (a *ergoAPI) handleAccountDetails(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
a.writeJSONResponse(response, w, r)
|
a.writeJSONResponse(response, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type apiAccountListResponse struct {
|
||||||
|
apiGenericResponse
|
||||||
|
Accounts []apiAccountDetailsResponse `json:"accounts"`
|
||||||
|
TotalCount int `json:"totalCount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *ergoAPI) handleAccountList(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var response apiAccountListResponse
|
||||||
|
|
||||||
|
// Get all account names
|
||||||
|
accounts := a.server.accounts.AllNicks()
|
||||||
|
response.TotalCount = len(accounts)
|
||||||
|
|
||||||
|
// Load account details
|
||||||
|
response.Accounts = make([]apiAccountDetailsResponse, len(accounts))
|
||||||
|
for i, account := range accounts {
|
||||||
|
accountData, err := a.server.accounts.LoadAccount(account)
|
||||||
|
if err != nil {
|
||||||
|
response.Accounts[i] = apiAccountDetailsResponse{
|
||||||
|
apiGenericResponse: apiGenericResponse{
|
||||||
|
Success: false,
|
||||||
|
Error: err.Error(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Accounts[i] = apiAccountDetailsResponse{
|
||||||
|
apiGenericResponse: apiGenericResponse{
|
||||||
|
Success: true,
|
||||||
|
},
|
||||||
|
AccountName: accountData.Name,
|
||||||
|
Email: accountData.Settings.Email,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Success = true
|
||||||
|
a.writeJSONResponse(response, w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
type apiStatusResponse struct {
|
||||||
|
apiGenericResponse
|
||||||
|
Version string `json:"version"`
|
||||||
|
GoVersion string `json:"go_version"`
|
||||||
|
Commit string `json:"commit,omitempty"`
|
||||||
|
StartTime string `json:"start_time"`
|
||||||
|
Users struct {
|
||||||
|
Total int `json:"total"`
|
||||||
|
Invisible int `json:"invisible"`
|
||||||
|
Operators int `json:"operators"`
|
||||||
|
Unknown int `json:"unknown"`
|
||||||
|
Max int `json:"max"`
|
||||||
|
} `json:"users"`
|
||||||
|
Channels int `json:"channels"`
|
||||||
|
Servers int `json:"servers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *ergoAPI) handleStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
|
server := a.server
|
||||||
|
stats := server.stats.GetValues()
|
||||||
|
|
||||||
|
response := apiStatusResponse{
|
||||||
|
apiGenericResponse: apiGenericResponse{Success: true},
|
||||||
|
Version: SemVer,
|
||||||
|
GoVersion: runtime.Version(),
|
||||||
|
Commit: Commit,
|
||||||
|
StartTime: server.ctime.Format(utils.IRCv3TimestampFormat),
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Users.Total = stats.Total
|
||||||
|
response.Users.Invisible = stats.Invisible
|
||||||
|
response.Users.Operators = stats.Operators
|
||||||
|
response.Users.Unknown = stats.Unknown
|
||||||
|
response.Users.Max = stats.Max
|
||||||
|
response.Channels = server.channels.Len()
|
||||||
|
response.Servers = 1
|
||||||
|
|
||||||
|
a.writeJSONResponse(response, w, r)
|
||||||
|
}
|
||||||
|
@ -44,10 +44,11 @@ func (b *buntdbDatastore) GetAll(table datastore.Table) (result []datastore.KV,
|
|||||||
tablePrefix := fmt.Sprintf("%x ", table)
|
tablePrefix := fmt.Sprintf("%x ", table)
|
||||||
err = b.db.View(func(tx *buntdb.Tx) error {
|
err = b.db.View(func(tx *buntdb.Tx) error {
|
||||||
err := tx.AscendGreaterOrEqual("", tablePrefix, func(key, value string) bool {
|
err := tx.AscendGreaterOrEqual("", tablePrefix, func(key, value string) bool {
|
||||||
if !strings.HasPrefix(key, tablePrefix) {
|
encUUID, ok := strings.CutPrefix(key, tablePrefix)
|
||||||
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
uuid, err := utils.DecodeUUID(strings.TrimPrefix(key, tablePrefix))
|
uuid, err := utils.DecodeUUID(encUUID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
result = append(result, datastore.KV{UUID: uuid, Value: []byte(value)})
|
result = append(result, datastore.KV{UUID: uuid, Value: []byte(value)})
|
||||||
} else {
|
} else {
|
||||||
|
@ -7,7 +7,7 @@ package caps
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// number of recognized capabilities:
|
// number of recognized capabilities:
|
||||||
numCapabs = 37
|
numCapabs = 38
|
||||||
// length of the uint32 array that represents the bitset:
|
// length of the uint32 array that represents the bitset:
|
||||||
bitsetLen = 2
|
bitsetLen = 2
|
||||||
)
|
)
|
||||||
@ -65,6 +65,10 @@ const (
|
|||||||
// https://github.com/progval/ircv3-specifications/blob/redaction/extensions/message-redaction.md
|
// https://github.com/progval/ircv3-specifications/blob/redaction/extensions/message-redaction.md
|
||||||
MessageRedaction Capability = iota
|
MessageRedaction Capability = iota
|
||||||
|
|
||||||
|
// Metadata is the draft IRCv3 capability named "draft/metadata-2":
|
||||||
|
// https://ircv3.net/specs/extensions/metadata
|
||||||
|
Metadata Capability = iota
|
||||||
|
|
||||||
// Multiline is the proposed IRCv3 capability named "draft/multiline":
|
// Multiline is the proposed IRCv3 capability named "draft/multiline":
|
||||||
// https://github.com/ircv3/ircv3-specifications/pull/398
|
// https://github.com/ircv3/ircv3-specifications/pull/398
|
||||||
Multiline Capability = iota
|
Multiline Capability = iota
|
||||||
@ -178,6 +182,7 @@ var (
|
|||||||
"draft/extended-isupport",
|
"draft/extended-isupport",
|
||||||
"draft/languages",
|
"draft/languages",
|
||||||
"draft/message-redaction",
|
"draft/message-redaction",
|
||||||
|
"draft/metadata-2",
|
||||||
"draft/multiline",
|
"draft/multiline",
|
||||||
"draft/no-implicit-names",
|
"draft/no-implicit-names",
|
||||||
"draft/persistence",
|
"draft/persistence",
|
||||||
|
@ -7,6 +7,7 @@ package irc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"iter"
|
||||||
"maps"
|
"maps"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -55,6 +56,7 @@ type Channel struct {
|
|||||||
dirtyBits uint
|
dirtyBits uint
|
||||||
settings ChannelSettings
|
settings ChannelSettings
|
||||||
uuid utils.UUID
|
uuid utils.UUID
|
||||||
|
metadata map[string]string
|
||||||
// these caches are paired to allow iteration over channel members without holding the lock
|
// these caches are paired to allow iteration over channel members without holding the lock
|
||||||
membersCache []*Client
|
membersCache []*Client
|
||||||
memberDataCache []*memberData
|
memberDataCache []*memberData
|
||||||
@ -126,6 +128,7 @@ func (channel *Channel) applyRegInfo(chanReg RegisteredChannel) {
|
|||||||
channel.userLimit = chanReg.UserLimit
|
channel.userLimit = chanReg.UserLimit
|
||||||
channel.settings = chanReg.Settings
|
channel.settings = chanReg.Settings
|
||||||
channel.forward = chanReg.Forward
|
channel.forward = chanReg.Forward
|
||||||
|
channel.metadata = chanReg.Metadata
|
||||||
|
|
||||||
for _, mode := range chanReg.Modes {
|
for _, mode := range chanReg.Modes {
|
||||||
channel.flags.SetMode(mode, true)
|
channel.flags.SetMode(mode, true)
|
||||||
@ -163,6 +166,7 @@ func (channel *Channel) ExportRegistration() (info RegisteredChannel) {
|
|||||||
info.AccountToUMode = maps.Clone(channel.accountToUMode)
|
info.AccountToUMode = maps.Clone(channel.accountToUMode)
|
||||||
|
|
||||||
info.Settings = channel.settings
|
info.Settings = channel.settings
|
||||||
|
info.Metadata = channel.metadata
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -892,6 +896,10 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
|||||||
rb.Add(nil, client.server.name, "MARKREAD", chname, client.GetReadMarker(chcfname))
|
rb.Add(nil, client.server.name, "MARKREAD", chname, client.GetReadMarker(chcfname))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rb.session.capabilities.Has(caps.Metadata) {
|
||||||
|
syncChannelMetadata(client.server, rb, channel)
|
||||||
|
}
|
||||||
|
|
||||||
if rb.session.client == client {
|
if rb.session.client == client {
|
||||||
// don't send topic and names for a SAJOIN of a different client
|
// don't send topic and names for a SAJOIN of a different client
|
||||||
channel.SendTopic(client, rb, false)
|
channel.SendTopic(client, rb, false)
|
||||||
@ -1669,6 +1677,20 @@ func (channel *Channel) auditoriumFriends(client *Client) (friends []*Client) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (channel *Channel) sessionsWithCaps(capabs ...caps.Capability) iter.Seq[*Session] {
|
||||||
|
return func(yield func(*Session) bool) {
|
||||||
|
for _, member := range channel.Members() {
|
||||||
|
for _, sess := range member.Sessions() {
|
||||||
|
if sess.capabilities.HasAll(capabs...) {
|
||||||
|
if !yield(sess) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// returns whether the client is visible to unprivileged users in the channel
|
// returns whether the client is visible to unprivileged users in the channel
|
||||||
// (i.e., respecting auditorium mode). note that this assumes that the client
|
// (i.e., respecting auditorium mode). note that this assumes that the client
|
||||||
// is a member; if the client is not, it may return true anyway
|
// is a member; if the client is not, it may return true anyway
|
||||||
|
@ -206,6 +206,10 @@ func (cm *ChannelManager) Cleanup(channel *Channel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cm *ChannelManager) SetRegistered(channelName string, account string) (err error) {
|
func (cm *ChannelManager) SetRegistered(channelName string, account string) (err error) {
|
||||||
|
if account == "" {
|
||||||
|
return errAuthRequired // this is already enforced by ChanServ, but do a final check
|
||||||
|
}
|
||||||
|
|
||||||
if cm.server.Defcon() <= 4 {
|
if cm.server.Defcon() <= 4 {
|
||||||
return errFeatureDisabled
|
return errFeatureDisabled
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,8 @@ type RegisteredChannel struct {
|
|||||||
Invites map[string]MaskInfo
|
Invites map[string]MaskInfo
|
||||||
// Settings are the chanserv-modifiable settings
|
// Settings are the chanserv-modifiable settings
|
||||||
Settings ChannelSettings
|
Settings ChannelSettings
|
||||||
|
// Metadata set using the METADATA command
|
||||||
|
Metadata map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RegisteredChannel) Serialize() ([]byte, error) {
|
func (r *RegisteredChannel) Serialize() ([]byte, error) {
|
||||||
|
@ -41,8 +41,7 @@ const (
|
|||||||
DefaultMaxLineLen = 512
|
DefaultMaxLineLen = 512
|
||||||
|
|
||||||
// IdentTimeout is how long before our ident (username) check times out.
|
// IdentTimeout is how long before our ident (username) check times out.
|
||||||
IdentTimeout = time.Second + 500*time.Millisecond
|
IdentTimeout = time.Second + 500*time.Millisecond
|
||||||
IRCv3TimestampFormat = utils.IRCv3TimestampFormat
|
|
||||||
// limit the number of device IDs a client can use, as a DoS mitigation
|
// limit the number of device IDs a client can use, as a DoS mitigation
|
||||||
maxDeviceIDsPerClient = 64
|
maxDeviceIDsPerClient = 64
|
||||||
// maximum total read markers that can be stored
|
// maximum total read markers that can be stored
|
||||||
@ -132,6 +131,7 @@ type Client struct {
|
|||||||
clearablePushMessages map[string]time.Time
|
clearablePushMessages map[string]time.Time
|
||||||
pushSubscriptionsExist atomic.Uint32 // this is a cache on len(pushSubscriptions) != 0
|
pushSubscriptionsExist atomic.Uint32 // this is a cache on len(pushSubscriptions) != 0
|
||||||
pushQueue pushQueue
|
pushQueue pushQueue
|
||||||
|
metadata map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
type saslStatus struct {
|
type saslStatus struct {
|
||||||
@ -215,6 +215,9 @@ type Session struct {
|
|||||||
batch MultilineBatch
|
batch MultilineBatch
|
||||||
|
|
||||||
webPushEndpoint string // goroutine-local: web push endpoint registered by the current session
|
webPushEndpoint string // goroutine-local: web push endpoint registered by the current session
|
||||||
|
|
||||||
|
metadataSubscriptions utils.HashSet[string]
|
||||||
|
metadataPreregVals map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// MultilineBatch tracks the state of a client-to-server multiline batch.
|
// MultilineBatch tracks the state of a client-to-server multiline batch.
|
||||||
@ -675,7 +678,7 @@ func (client *Client) run(session *Session) {
|
|||||||
isReattach := client.Registered()
|
isReattach := client.Registered()
|
||||||
if isReattach {
|
if isReattach {
|
||||||
client.Touch(session)
|
client.Touch(session)
|
||||||
client.playReattachMessages(session)
|
client.performReattach(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
firstLine := !isReattach
|
firstLine := !isReattach
|
||||||
@ -775,7 +778,9 @@ func (client *Client) run(session *Session) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) playReattachMessages(session *Session) {
|
func (client *Client) performReattach(session *Session) {
|
||||||
|
client.applyPreregMetadata(session)
|
||||||
|
|
||||||
client.server.playRegistrationBurst(session)
|
client.server.playRegistrationBurst(session)
|
||||||
hasHistoryCaps := session.HasHistoryCaps()
|
hasHistoryCaps := session.HasHistoryCaps()
|
||||||
for _, channel := range session.client.Channels() {
|
for _, channel := range session.client.Channels() {
|
||||||
@ -799,6 +804,34 @@ func (client *Client) playReattachMessages(session *Session) {
|
|||||||
session.autoreplayMissedSince = time.Time{}
|
session.autoreplayMissedSince = time.Time{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (client *Client) applyPreregMetadata(session *Session) {
|
||||||
|
if session.metadataPreregVals == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
session.metadataPreregVals = nil
|
||||||
|
}()
|
||||||
|
|
||||||
|
updates := client.UpdateMetadataFromPrereg(session.metadataPreregVals, client.server.Config().Metadata.MaxKeys)
|
||||||
|
if len(updates) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this is expensive
|
||||||
|
friends := client.FriendsMonitors(caps.Metadata)
|
||||||
|
for _, s := range client.Sessions() {
|
||||||
|
if s != session {
|
||||||
|
friends.Add(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target := client.Nick()
|
||||||
|
for k, v := range updates {
|
||||||
|
broadcastMetadataUpdate(client.server, maps.Keys(friends), session, target, k, v, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// idle, quit, timers and timeouts
|
// idle, quit, timers and timeouts
|
||||||
//
|
//
|
||||||
@ -1130,6 +1163,7 @@ func (client *Client) SetNick(nick, nickCasefolded, skeleton string) (success bo
|
|||||||
client.nickCasefolded = nickCasefolded
|
client.nickCasefolded = nickCasefolded
|
||||||
client.skeleton = skeleton
|
client.skeleton = skeleton
|
||||||
client.updateNickMaskNoMutex()
|
client.updateNickMaskNoMutex()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1463,7 +1497,7 @@ func (session *Session) sendFromClientInternal(blocking bool, serverTime time.Ti
|
|||||||
|
|
||||||
func composeMultilineBatch(batchID, fromNickMask, fromAccount string, isBot bool, tags map[string]string, command, target string, message utils.SplitMessage) (result []ircmsg.Message) {
|
func composeMultilineBatch(batchID, fromNickMask, fromAccount string, isBot bool, tags map[string]string, command, target string, message utils.SplitMessage) (result []ircmsg.Message) {
|
||||||
batchStart := ircmsg.MakeMessage(tags, fromNickMask, "BATCH", "+"+batchID, caps.MultilineBatchType, target)
|
batchStart := ircmsg.MakeMessage(tags, fromNickMask, "BATCH", "+"+batchID, caps.MultilineBatchType, target)
|
||||||
batchStart.SetTag("time", message.Time.Format(IRCv3TimestampFormat))
|
batchStart.SetTag("time", message.Time.Format(utils.IRCv3TimestampFormat))
|
||||||
batchStart.SetTag("msgid", message.Msgid)
|
batchStart.SetTag("msgid", message.Msgid)
|
||||||
if fromAccount != "*" {
|
if fromAccount != "*" {
|
||||||
batchStart.SetTag("account", fromAccount)
|
batchStart.SetTag("account", fromAccount)
|
||||||
@ -1571,7 +1605,7 @@ func (session *Session) setTimeTag(msg *ircmsg.Message, serverTime time.Time) {
|
|||||||
if serverTime.IsZero() {
|
if serverTime.IsZero() {
|
||||||
serverTime = time.Now()
|
serverTime = time.Now()
|
||||||
}
|
}
|
||||||
msg.SetTag("time", serverTime.UTC().Format(IRCv3TimestampFormat))
|
msg.SetTag("time", serverTime.UTC().Format(utils.IRCv3TimestampFormat))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,6 +209,11 @@ func init() {
|
|||||||
handler: markReadHandler,
|
handler: markReadHandler,
|
||||||
minParams: 0, // send FAIL instead of ERR_NEEDMOREPARAMS
|
minParams: 0, // send FAIL instead of ERR_NEEDMOREPARAMS
|
||||||
},
|
},
|
||||||
|
"METADATA": {
|
||||||
|
handler: metadataHandler,
|
||||||
|
minParams: 2,
|
||||||
|
usablePreReg: true,
|
||||||
|
},
|
||||||
"MODE": {
|
"MODE": {
|
||||||
handler: modeHandler,
|
handler: modeHandler,
|
||||||
minParams: 1,
|
minParams: 1,
|
||||||
|
@ -723,6 +723,13 @@ type Config struct {
|
|||||||
} `yaml:"tagmsg-storage"`
|
} `yaml:"tagmsg-storage"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Metadata struct {
|
||||||
|
Enabled bool
|
||||||
|
MaxSubs int `yaml:"max-subs"`
|
||||||
|
MaxKeys int `yaml:"max-keys"`
|
||||||
|
MaxValueBytes int `yaml:"max-value-length"`
|
||||||
|
}
|
||||||
|
|
||||||
WebPush struct {
|
WebPush struct {
|
||||||
Enabled bool
|
Enabled bool
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
@ -1637,6 +1644,27 @@ func LoadConfig(filename string) (config *Config, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !config.Metadata.Enabled {
|
||||||
|
config.Server.supportedCaps.Disable(caps.Metadata)
|
||||||
|
} else {
|
||||||
|
metadataValues := make([]string, 0, 4)
|
||||||
|
metadataValues = append(metadataValues, "before-connect")
|
||||||
|
// these are required for normal operation, so set sane defaults:
|
||||||
|
if config.Metadata.MaxSubs == 0 {
|
||||||
|
config.Metadata.MaxSubs = 10
|
||||||
|
}
|
||||||
|
metadataValues = append(metadataValues, fmt.Sprintf("max-subs=%d", config.Metadata.MaxSubs))
|
||||||
|
if config.Metadata.MaxKeys == 0 {
|
||||||
|
config.Metadata.MaxKeys = 10
|
||||||
|
}
|
||||||
|
metadataValues = append(metadataValues, fmt.Sprintf("max-keys=%d", config.Metadata.MaxKeys))
|
||||||
|
// this is not required since we enforce a hardcoded upper bound on key+value
|
||||||
|
if config.Metadata.MaxValueBytes > 0 {
|
||||||
|
metadataValues = append(metadataValues, fmt.Sprintf("max-value-bytes=%d", config.Metadata.MaxValueBytes))
|
||||||
|
}
|
||||||
|
config.Server.capValues[caps.Metadata] = strings.Join(metadataValues, ",")
|
||||||
|
}
|
||||||
|
|
||||||
err = config.processExtjwt()
|
err = config.processExtjwt()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -33,6 +33,7 @@ var (
|
|||||||
errAccountVerificationInvalidCode = errors.New("Invalid account verification code")
|
errAccountVerificationInvalidCode = errors.New("Invalid account verification code")
|
||||||
errAccountUpdateFailed = errors.New(`Error while updating your account information`)
|
errAccountUpdateFailed = errors.New(`Error while updating your account information`)
|
||||||
errAccountMustHoldNick = errors.New(`You must hold that nickname in order to register it`)
|
errAccountMustHoldNick = errors.New(`You must hold that nickname in order to register it`)
|
||||||
|
errAuthRequired = errors.New("You must be logged into an account to do this")
|
||||||
errAuthzidAuthcidMismatch = errors.New(`authcid and authzid must be the same`)
|
errAuthzidAuthcidMismatch = errors.New(`authcid and authzid must be the same`)
|
||||||
errCertfpAlreadyExists = errors.New(`An account already exists for your certificate fingerprint`)
|
errCertfpAlreadyExists = errors.New(`An account already exists for your certificate fingerprint`)
|
||||||
errChannelNotOwnedByAccount = errors.New("Channel not owned by the specified account")
|
errChannelNotOwnedByAccount = errors.New("Channel not owned by the specified account")
|
||||||
|
218
irc/getters.go
218
irc/getters.go
@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"maps"
|
"maps"
|
||||||
"net"
|
"net"
|
||||||
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ergochat/ergo/irc/caps"
|
"github.com/ergochat/ergo/irc/caps"
|
||||||
@ -517,7 +518,7 @@ func (client *Client) GetReadMarker(cfname string) (result string) {
|
|||||||
t, ok := client.readMarkers[cfname]
|
t, ok := client.readMarkers[cfname]
|
||||||
client.stateMutex.RUnlock()
|
client.stateMutex.RUnlock()
|
||||||
if ok {
|
if ok {
|
||||||
return fmt.Sprintf("timestamp=%s", t.Format(IRCv3TimestampFormat))
|
return fmt.Sprintf("timestamp=%s", t.Format(utils.IRCv3TimestampFormat))
|
||||||
}
|
}
|
||||||
return "*"
|
return "*"
|
||||||
}
|
}
|
||||||
@ -797,10 +798,12 @@ func (channel *Channel) Settings() (result ChannelSettings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) SetSettings(settings ChannelSettings) {
|
func (channel *Channel) SetSettings(settings ChannelSettings) {
|
||||||
|
defer channel.MarkDirty(IncludeSettings)
|
||||||
|
|
||||||
channel.stateMutex.Lock()
|
channel.stateMutex.Lock()
|
||||||
|
defer channel.stateMutex.Unlock()
|
||||||
|
|
||||||
channel.settings = settings
|
channel.settings = settings
|
||||||
channel.stateMutex.Unlock()
|
|
||||||
channel.MarkDirty(IncludeSettings)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) setForward(forward string) {
|
func (channel *Channel) setForward(forward string) {
|
||||||
@ -827,3 +830,212 @@ func (channel *Channel) UUID() utils.UUID {
|
|||||||
defer channel.stateMutex.RUnlock()
|
defer channel.stateMutex.RUnlock()
|
||||||
return channel.uuid
|
return channel.uuid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (session *Session) isSubscribedTo(key string) bool {
|
||||||
|
session.client.stateMutex.RLock()
|
||||||
|
defer session.client.stateMutex.RUnlock()
|
||||||
|
|
||||||
|
return session.metadataSubscriptions.Has(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (session *Session) SubscribeTo(keys ...string) ([]string, error) {
|
||||||
|
maxSubs := session.client.server.Config().Metadata.MaxSubs
|
||||||
|
|
||||||
|
session.client.stateMutex.Lock()
|
||||||
|
defer session.client.stateMutex.Unlock()
|
||||||
|
|
||||||
|
if session.metadataSubscriptions == nil {
|
||||||
|
session.metadataSubscriptions = make(utils.HashSet[string])
|
||||||
|
}
|
||||||
|
|
||||||
|
var added []string
|
||||||
|
|
||||||
|
for _, k := range keys {
|
||||||
|
if !session.metadataSubscriptions.Has(k) {
|
||||||
|
if len(session.metadataSubscriptions) > maxSubs {
|
||||||
|
return added, errMetadataTooManySubs
|
||||||
|
}
|
||||||
|
added = append(added, k)
|
||||||
|
session.metadataSubscriptions.Add(k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return added, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (session *Session) UnsubscribeFrom(keys ...string) []string {
|
||||||
|
session.client.stateMutex.Lock()
|
||||||
|
defer session.client.stateMutex.Unlock()
|
||||||
|
|
||||||
|
var removed []string
|
||||||
|
|
||||||
|
for k := range session.metadataSubscriptions {
|
||||||
|
if slices.Contains(keys, k) {
|
||||||
|
removed = append(removed, k)
|
||||||
|
session.metadataSubscriptions.Remove(k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return removed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (session *Session) MetadataSubscriptions() utils.HashSet[string] {
|
||||||
|
session.client.stateMutex.Lock()
|
||||||
|
defer session.client.stateMutex.Unlock()
|
||||||
|
|
||||||
|
return maps.Clone(session.metadataSubscriptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (channel *Channel) GetMetadata(key string) (string, bool) {
|
||||||
|
channel.stateMutex.RLock()
|
||||||
|
defer channel.stateMutex.RUnlock()
|
||||||
|
|
||||||
|
val, ok := channel.metadata[key]
|
||||||
|
return val, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (channel *Channel) SetMetadata(key string, value string, limit int) (updated bool, err error) {
|
||||||
|
defer channel.MarkDirty(IncludeAllAttrs)
|
||||||
|
|
||||||
|
channel.stateMutex.Lock()
|
||||||
|
defer channel.stateMutex.Unlock()
|
||||||
|
|
||||||
|
if channel.metadata == nil {
|
||||||
|
channel.metadata = make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
existing, ok := channel.metadata[key]
|
||||||
|
if !ok && len(channel.metadata) >= limit {
|
||||||
|
return false, errLimitExceeded
|
||||||
|
}
|
||||||
|
updated = !ok || value != existing
|
||||||
|
if updated {
|
||||||
|
channel.metadata[key] = value
|
||||||
|
}
|
||||||
|
return updated, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (channel *Channel) ListMetadata() map[string]string {
|
||||||
|
channel.stateMutex.RLock()
|
||||||
|
defer channel.stateMutex.RUnlock()
|
||||||
|
|
||||||
|
return maps.Clone(channel.metadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (channel *Channel) DeleteMetadata(key string) (updated bool) {
|
||||||
|
defer channel.MarkDirty(IncludeAllAttrs)
|
||||||
|
|
||||||
|
channel.stateMutex.Lock()
|
||||||
|
defer channel.stateMutex.Unlock()
|
||||||
|
|
||||||
|
_, updated = channel.metadata[key]
|
||||||
|
if updated {
|
||||||
|
delete(channel.metadata, key)
|
||||||
|
}
|
||||||
|
return updated
|
||||||
|
}
|
||||||
|
|
||||||
|
func (channel *Channel) ClearMetadata() map[string]string {
|
||||||
|
defer channel.MarkDirty(IncludeAllAttrs)
|
||||||
|
channel.stateMutex.Lock()
|
||||||
|
defer channel.stateMutex.Unlock()
|
||||||
|
|
||||||
|
oldMap := channel.metadata
|
||||||
|
channel.metadata = nil
|
||||||
|
|
||||||
|
return oldMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (channel *Channel) CountMetadata() int {
|
||||||
|
channel.stateMutex.RLock()
|
||||||
|
defer channel.stateMutex.RUnlock()
|
||||||
|
|
||||||
|
return len(channel.metadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) GetMetadata(key string) (string, bool) {
|
||||||
|
client.stateMutex.RLock()
|
||||||
|
defer client.stateMutex.RUnlock()
|
||||||
|
|
||||||
|
val, ok := client.metadata[key]
|
||||||
|
return val, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) SetMetadata(key string, value string, limit int) (updated bool, err error) {
|
||||||
|
client.stateMutex.Lock()
|
||||||
|
defer client.stateMutex.Unlock()
|
||||||
|
|
||||||
|
if client.metadata == nil {
|
||||||
|
client.metadata = make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
existing, ok := client.metadata[key]
|
||||||
|
if !ok && len(client.metadata) >= limit {
|
||||||
|
return false, errLimitExceeded
|
||||||
|
}
|
||||||
|
updated = !ok || value != existing
|
||||||
|
if updated {
|
||||||
|
client.metadata[key] = value
|
||||||
|
}
|
||||||
|
return updated, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) UpdateMetadataFromPrereg(preregData map[string]string, limit int) (updates map[string]string) {
|
||||||
|
updates = make(map[string]string, len(preregData))
|
||||||
|
|
||||||
|
client.stateMutex.Lock()
|
||||||
|
defer client.stateMutex.Unlock()
|
||||||
|
|
||||||
|
if client.metadata == nil {
|
||||||
|
client.metadata = make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range preregData {
|
||||||
|
// do not overwrite any existing keys
|
||||||
|
_, ok := client.metadata[k]
|
||||||
|
if ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(client.metadata) >= limit {
|
||||||
|
return // we know this is a new key
|
||||||
|
}
|
||||||
|
client.metadata[k] = v
|
||||||
|
updates[k] = v
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) ListMetadata() map[string]string {
|
||||||
|
client.stateMutex.RLock()
|
||||||
|
defer client.stateMutex.RUnlock()
|
||||||
|
|
||||||
|
return maps.Clone(client.metadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) DeleteMetadata(key string) (updated bool) {
|
||||||
|
client.stateMutex.Lock()
|
||||||
|
defer client.stateMutex.Unlock()
|
||||||
|
|
||||||
|
_, updated = client.metadata[key]
|
||||||
|
if updated {
|
||||||
|
delete(client.metadata, key)
|
||||||
|
}
|
||||||
|
return updated
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) ClearMetadata() map[string]string {
|
||||||
|
client.stateMutex.Lock()
|
||||||
|
defer client.stateMutex.Unlock()
|
||||||
|
|
||||||
|
oldMap := client.metadata
|
||||||
|
client.metadata = nil
|
||||||
|
|
||||||
|
return oldMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) CountMetadata() int {
|
||||||
|
client.stateMutex.RLock()
|
||||||
|
defer client.stateMutex.RUnlock()
|
||||||
|
|
||||||
|
return len(client.metadata)
|
||||||
|
}
|
||||||
|
309
irc/handlers.go
309
irc/handlers.go
@ -9,11 +9,13 @@ package irc
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"maps"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -149,11 +151,8 @@ func (server *Server) sendLoginSnomask(nickMask, accountName string) {
|
|||||||
// to indicate that it should be removed from the list
|
// to indicate that it should be removed from the list
|
||||||
func acceptHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
func acceptHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
||||||
for _, tNick := range strings.Split(msg.Params[0], ",") {
|
for _, tNick := range strings.Split(msg.Params[0], ",") {
|
||||||
add := true
|
tNick, negPrefix := strings.CutPrefix(tNick, "-")
|
||||||
if strings.HasPrefix(tNick, "-") {
|
add := !negPrefix
|
||||||
add = false
|
|
||||||
tNick = strings.TrimPrefix(tNick, "-")
|
|
||||||
}
|
|
||||||
|
|
||||||
target := server.clients.Get(tNick)
|
target := server.clients.Get(tNick)
|
||||||
if target == nil {
|
if target == nil {
|
||||||
@ -719,7 +718,7 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.Message, rb *
|
|||||||
for _, target := range targets {
|
for _, target := range targets {
|
||||||
name := server.UnfoldName(target.CfName)
|
name := server.UnfoldName(target.CfName)
|
||||||
rb.Add(nil, server.name, "CHATHISTORY", "TARGETS", name,
|
rb.Add(nil, server.name, "CHATHISTORY", "TARGETS", name,
|
||||||
target.Time.Format(IRCv3TimestampFormat))
|
target.Time.Format(utils.IRCv3TimestampFormat))
|
||||||
}
|
}
|
||||||
} else if channel != nil {
|
} else if channel != nil {
|
||||||
channel.replayHistoryItems(rb, items, true)
|
channel.replayHistoryItems(rb, items, true)
|
||||||
@ -754,7 +753,7 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.Message, rb *
|
|||||||
msgid, err = history.NormalizeMsgid(value), nil
|
msgid, err = history.NormalizeMsgid(value), nil
|
||||||
return
|
return
|
||||||
} else if identifier == "timestamp" {
|
} else if identifier == "timestamp" {
|
||||||
timestamp, err = time.Parse(IRCv3TimestampFormat, value)
|
timestamp, err = time.Parse(utils.IRCv3TimestampFormat, value)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
timestamp = timestamp.UTC()
|
timestamp = timestamp.UTC()
|
||||||
if timestamp.Before(unixEpoch) {
|
if timestamp.Before(unixEpoch) {
|
||||||
@ -2910,11 +2909,23 @@ func quitHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respons
|
|||||||
|
|
||||||
// REGISTER < account | * > < email | * > <password>
|
// REGISTER < account | * > < email | * > <password>
|
||||||
func registerHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) (exiting bool) {
|
func registerHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) (exiting bool) {
|
||||||
accountName := client.Nick()
|
var accountName string
|
||||||
if accountName == "*" {
|
if client.registered {
|
||||||
|
accountName = client.Nick()
|
||||||
|
} else {
|
||||||
accountName = client.preregNick
|
accountName = client.preregNick
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config := server.Config()
|
||||||
|
if client.registered && config.Accounts.NickReservation.ForceGuestFormat {
|
||||||
|
matches := config.Accounts.NickReservation.guestRegexp.FindStringSubmatch(accountName)
|
||||||
|
if matches == nil || len(matches) < 2 {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "REGISTER", "INVALID_USERNAME", utils.SafeErrorParam(accountName), client.t("Username invalid or not given"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
accountName = matches[1]
|
||||||
|
}
|
||||||
|
|
||||||
switch msg.Params[0] {
|
switch msg.Params[0] {
|
||||||
case "*", accountName:
|
case "*", accountName:
|
||||||
// ok
|
// ok
|
||||||
@ -2931,7 +2942,6 @@ func registerHandler(server *Server, client *Client, msg ircmsg.Message, rb *Res
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
config := server.Config()
|
|
||||||
if !config.Accounts.Registration.Enabled {
|
if !config.Accounts.Registration.Enabled {
|
||||||
rb.Add(nil, server.name, "FAIL", "REGISTER", "DISALLOWED", accountName, client.t("Account registration is disabled"))
|
rb.Add(nil, server.name, "FAIL", "REGISTER", "DISALLOWED", accountName, client.t("Account registration is disabled"))
|
||||||
return
|
return
|
||||||
@ -2977,7 +2987,7 @@ func registerHandler(server *Server, client *Client, msg ircmsg.Message, rb *Res
|
|||||||
announcePendingReg(client, rb, accountName)
|
announcePendingReg(client, rb, accountName)
|
||||||
}
|
}
|
||||||
case errAccountAlreadyRegistered, errAccountAlreadyUnregistered, errAccountMustHoldNick:
|
case errAccountAlreadyRegistered, errAccountAlreadyUnregistered, errAccountMustHoldNick:
|
||||||
rb.Add(nil, server.name, "FAIL", "REGISTER", "USERNAME_EXISTS", accountName, client.t("Username is already registered or otherwise unavailable"))
|
rb.Add(nil, server.name, "FAIL", "REGISTER", "ACCOUNT_EXISTS", accountName, client.t("Username is already registered or otherwise unavailable"))
|
||||||
case errAccountBadPassphrase:
|
case errAccountBadPassphrase:
|
||||||
rb.Add(nil, server.name, "FAIL", "REGISTER", "INVALID_PASSWORD", accountName, client.t("Password was invalid"))
|
rb.Add(nil, server.name, "FAIL", "REGISTER", "INVALID_PASSWORD", accountName, client.t("Password was invalid"))
|
||||||
default:
|
default:
|
||||||
@ -3055,14 +3065,14 @@ func markReadHandler(server *Server, client *Client, msg ircmsg.Message, rb *Res
|
|||||||
|
|
||||||
// "MARKREAD client set command": MARKREAD <target> <timestamp>
|
// "MARKREAD client set command": MARKREAD <target> <timestamp>
|
||||||
readTimestamp := strings.TrimPrefix(msg.Params[1], "timestamp=")
|
readTimestamp := strings.TrimPrefix(msg.Params[1], "timestamp=")
|
||||||
readTime, err := time.Parse(IRCv3TimestampFormat, readTimestamp)
|
readTime, err := time.Parse(utils.IRCv3TimestampFormat, readTimestamp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rb.Add(nil, server.name, "FAIL", "MARKREAD", "INVALID_PARAMS", utils.SafeErrorParam(readTimestamp), client.t("Invalid timestamp"))
|
rb.Add(nil, server.name, "FAIL", "MARKREAD", "INVALID_PARAMS", utils.SafeErrorParam(readTimestamp), client.t("Invalid timestamp"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
readTime = readTime.UTC()
|
readTime = readTime.UTC()
|
||||||
result := client.SetReadMarker(cftarget, readTime)
|
result := client.SetReadMarker(cftarget, readTime)
|
||||||
readTimestamp = fmt.Sprintf("timestamp=%s", result.Format(IRCv3TimestampFormat))
|
readTimestamp = fmt.Sprintf("timestamp=%s", result.Format(utils.IRCv3TimestampFormat))
|
||||||
// inform the originating session whether it was a success or a no-op:
|
// inform the originating session whether it was a success or a no-op:
|
||||||
rb.Add(nil, server.name, "MARKREAD", unfoldedTarget, readTimestamp)
|
rb.Add(nil, server.name, "MARKREAD", unfoldedTarget, readTimestamp)
|
||||||
if result.Equal(readTime) {
|
if result.Equal(readTime) {
|
||||||
@ -3089,6 +3099,275 @@ func markReadHandler(server *Server, client *Client, msg ircmsg.Message, rb *Res
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// METADATA <target> <subcommand> [<and so on>...]
|
||||||
|
func metadataHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) (exiting bool) {
|
||||||
|
config := server.Config()
|
||||||
|
if !config.Metadata.Enabled {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "FORBIDDEN", utils.SafeErrorParam(msg.Params[0]), "Metadata is disabled on this server")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
subcommand := strings.ToLower(msg.Params[1])
|
||||||
|
needsKey := subcommand == "set" || subcommand == "get" || subcommand == "sub" || subcommand == "unsub"
|
||||||
|
if needsKey && len(msg.Params) < 3 {
|
||||||
|
rb.Add(nil, server.name, ERR_NEEDMOREPARAMS, client.Nick(), msg.Command, client.t("Not enough parameters"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch subcommand {
|
||||||
|
case "sub", "unsub", "subs":
|
||||||
|
// these are session-local and function the same whether or not the client is registered
|
||||||
|
return metadataSubsHandler(client, subcommand, msg.Params, rb)
|
||||||
|
case "get", "set", "list", "clear", "sync":
|
||||||
|
if client.registered {
|
||||||
|
return metadataRegisteredHandler(client, config, subcommand, msg.Params, rb)
|
||||||
|
} else {
|
||||||
|
return metadataUnregisteredHandler(client, config, subcommand, msg.Params, rb)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "SUBCOMMAND_INVALID", utils.SafeErrorParam(msg.Params[1]), client.t("Invalid subcommand"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// metadataRegisteredHandler handles metadata-modifying commands from registered clients
|
||||||
|
func metadataRegisteredHandler(client *Client, config *Config, subcommand string, params []string, rb *ResponseBuffer) (exiting bool) {
|
||||||
|
server := client.server
|
||||||
|
target := params[0]
|
||||||
|
|
||||||
|
noKeyPerms := func(key string) {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "KEY_NO_PERMISSION", target, key, client.t("You do not have permission to perform this action"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if target == "*" {
|
||||||
|
target = client.Nick()
|
||||||
|
}
|
||||||
|
|
||||||
|
var targetObj MetadataHaver
|
||||||
|
var targetClient *Client
|
||||||
|
var targetChannel *Channel
|
||||||
|
if strings.HasPrefix(target, "#") {
|
||||||
|
targetChannel = server.channels.Get(target)
|
||||||
|
if targetChannel != nil {
|
||||||
|
targetObj = targetChannel
|
||||||
|
target = targetChannel.Name() // canonicalize case
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
targetClient = server.clients.Get(target)
|
||||||
|
if targetClient != nil {
|
||||||
|
targetObj = targetClient
|
||||||
|
target = targetClient.Nick() // canonicalize case
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if targetObj == nil {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "INVALID_TARGET", target, client.t("Invalid metadata target"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch subcommand {
|
||||||
|
case "set":
|
||||||
|
key := params[2]
|
||||||
|
if metadataKeyIsEvil(key) {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "KEY_INVALID", utils.SafeErrorParam(key), client.t("Invalid key name"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !metadataCanIEditThisKey(client, targetObj, key) {
|
||||||
|
noKeyPerms(key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(params) > 3 {
|
||||||
|
value := params[3]
|
||||||
|
|
||||||
|
config := client.server.Config()
|
||||||
|
if failMsg := metadataValueIsEvil(config, key, value); failMsg != "" {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "VALUE_INVALID", client.t(failMsg))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
updated, err := targetObj.SetMetadata(key, value, config.Metadata.MaxKeys)
|
||||||
|
if err != nil {
|
||||||
|
// errLimitExceeded is the only possible error
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "LIMIT_REACHED", client.t("Too many metadata keys"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// echo the value to the client whether or not there was a real update
|
||||||
|
rb.Add(nil, server.name, RPL_KEYVALUE, client.Nick(), target, key, "*", value)
|
||||||
|
if updated {
|
||||||
|
notifySubscribers(server, rb.session, targetObj, target, key, value, true)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if updated := targetObj.DeleteMetadata(key); updated {
|
||||||
|
notifySubscribers(server, rb.session, targetObj, target, key, "", false)
|
||||||
|
rb.Add(nil, server.name, RPL_KEYNOTSET, client.Nick(), target, key, client.t("Key deleted"))
|
||||||
|
} else {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "KEY_NOT_SET", utils.SafeErrorParam(key), client.t("Metadata key not set"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case "get":
|
||||||
|
if !metadataCanISeeThisTarget(client, targetObj) {
|
||||||
|
noKeyPerms("*")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
batchId := rb.StartNestedBatch("metadata", target)
|
||||||
|
defer rb.EndNestedBatch(batchId)
|
||||||
|
|
||||||
|
for _, key := range params[2:] {
|
||||||
|
if metadataKeyIsEvil(key) {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "KEY_INVALID", utils.SafeErrorParam(key), client.t("Invalid key name"))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val, ok := targetObj.GetMetadata(key)
|
||||||
|
if !ok {
|
||||||
|
rb.Add(nil, server.name, RPL_KEYNOTSET, client.Nick(), target, key, client.t("Key is not set"))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
visibility := "*"
|
||||||
|
rb.Add(nil, server.name, RPL_KEYVALUE, client.Nick(), target, key, visibility, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "list":
|
||||||
|
playMetadataList(rb, client.Nick(), target, targetObj.ListMetadata())
|
||||||
|
|
||||||
|
case "clear":
|
||||||
|
if !metadataCanIEditThisTarget(client, targetObj) {
|
||||||
|
noKeyPerms("*")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
values := targetObj.ClearMetadata()
|
||||||
|
|
||||||
|
playMetadataList(rb, client.Nick(), target, values)
|
||||||
|
|
||||||
|
case "sync":
|
||||||
|
if targetChannel != nil {
|
||||||
|
syncChannelMetadata(server, rb, targetChannel)
|
||||||
|
}
|
||||||
|
if targetClient != nil {
|
||||||
|
syncClientMetadata(server, rb, targetClient)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// metadataUnregisteredHandler handles metadata-modifying commands for pre-connection-registration
|
||||||
|
// clients. these operations act on a session-local buffer; if/when the client completes registration,
|
||||||
|
// they are applied to the final Client object (possibly a different client if there was a reattach)
|
||||||
|
// on a best-effort basis.
|
||||||
|
func metadataUnregisteredHandler(client *Client, config *Config, subcommand string, params []string, rb *ResponseBuffer) (exiting bool) {
|
||||||
|
server := client.server
|
||||||
|
if params[0] != "*" {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "KEY_NO_PERMISSION", utils.SafeErrorParam(params[0]), "*", client.t("You can only modify your own metadata before completing connection registration"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch subcommand {
|
||||||
|
case "set":
|
||||||
|
if rb.session.metadataPreregVals == nil {
|
||||||
|
rb.session.metadataPreregVals = make(map[string]string)
|
||||||
|
}
|
||||||
|
key := params[2]
|
||||||
|
if metadataKeyIsEvil(key) {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "KEY_INVALID", utils.SafeErrorParam(key), client.t("Invalid key name"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(params) >= 4 {
|
||||||
|
value := params[3]
|
||||||
|
// enforce a sane limit on prereg keys. we don't need to enforce the exact limit,
|
||||||
|
// that will be done when applying the buffer after registration
|
||||||
|
if len(rb.session.metadataPreregVals) > config.Metadata.MaxKeys {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "LIMIT_REACHED", client.t("Too many metadata keys"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if failMsg := metadataValueIsEvil(config, key, value); failMsg != "" {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "VALUE_INVALID", client.t(failMsg))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rb.session.metadataPreregVals[key] = value
|
||||||
|
rb.Add(nil, server.name, RPL_KEYVALUE, "*", "*", key, "*", value)
|
||||||
|
} else {
|
||||||
|
// unset
|
||||||
|
_, present := rb.session.metadataPreregVals[key]
|
||||||
|
if present {
|
||||||
|
delete(rb.session.metadataPreregVals, key)
|
||||||
|
rb.Add(nil, server.name, RPL_KEYNOTSET, "*", "*", key, client.t("Key deleted"))
|
||||||
|
} else {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "KEY_NOT_SET", utils.SafeErrorParam(key), client.t("Metadata key not set"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "list":
|
||||||
|
playMetadataList(rb, "*", "*", rb.session.metadataPreregVals)
|
||||||
|
case "clear":
|
||||||
|
oldMetadata := rb.session.metadataPreregVals
|
||||||
|
rb.session.metadataPreregVals = nil
|
||||||
|
playMetadataList(rb, "*", "*", oldMetadata)
|
||||||
|
case "sync":
|
||||||
|
rb.Add(nil, server.name, RPL_METADATASYNCLATER, "*", utils.SafeErrorParam(params[1]), "60") // lol
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// metadataSubsHandler handles subscription-related commands;
|
||||||
|
// these are handled the same whether the client is registered or not
|
||||||
|
func metadataSubsHandler(client *Client, subcommand string, params []string, rb *ResponseBuffer) (exiting bool) {
|
||||||
|
server := client.server
|
||||||
|
switch subcommand {
|
||||||
|
case "sub":
|
||||||
|
keys := params[2:]
|
||||||
|
for _, key := range keys {
|
||||||
|
if metadataKeyIsEvil(key) {
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "KEY_INVALID", utils.SafeErrorParam(key), client.t("Invalid key name"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
added, err := rb.session.SubscribeTo(keys...)
|
||||||
|
if err == errMetadataTooManySubs {
|
||||||
|
bad := keys[len(added)] // get the key that broke the camel's back
|
||||||
|
rb.Add(nil, server.name, "FAIL", "METADATA", "TOO_MANY_SUBS", utils.SafeErrorParam(bad), client.t("Too many subscriptions"))
|
||||||
|
}
|
||||||
|
|
||||||
|
lineLength := MaxLineLen - len(server.name) - len(RPL_METADATASUBOK) - len(client.Nick()) - 10
|
||||||
|
|
||||||
|
chunked := utils.ChunkifyParams(slices.Values(added), lineLength)
|
||||||
|
for _, line := range chunked {
|
||||||
|
params := append([]string{client.Nick()}, line...)
|
||||||
|
rb.Add(nil, server.name, RPL_METADATASUBOK, params...)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "unsub":
|
||||||
|
keys := params[2:]
|
||||||
|
removed := rb.session.UnsubscribeFrom(keys...)
|
||||||
|
|
||||||
|
lineLength := MaxLineLen - len(server.name) - len(RPL_METADATAUNSUBOK) - len(client.Nick()) - 10
|
||||||
|
chunked := utils.ChunkifyParams(slices.Values(removed), lineLength)
|
||||||
|
for _, line := range chunked {
|
||||||
|
params := append([]string{client.Nick()}, line...)
|
||||||
|
rb.Add(nil, server.name, RPL_METADATAUNSUBOK, params...)
|
||||||
|
}
|
||||||
|
|
||||||
|
case "subs":
|
||||||
|
lineLength := MaxLineLen - len(server.name) - len(RPL_METADATASUBS) - len(client.Nick()) - 10
|
||||||
|
|
||||||
|
subs := rb.session.MetadataSubscriptions()
|
||||||
|
|
||||||
|
batchID := rb.StartNestedBatch("metadata-subs")
|
||||||
|
defer rb.EndNestedBatch(batchID)
|
||||||
|
|
||||||
|
chunked := utils.ChunkifyParams(maps.Keys(subs), lineLength)
|
||||||
|
for _, line := range chunked {
|
||||||
|
params := append([]string{client.Nick()}, line...)
|
||||||
|
rb.Add(nil, server.name, RPL_METADATASUBS, params...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// REHASH
|
// REHASH
|
||||||
func rehashHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
func rehashHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
||||||
nick := client.Nick()
|
nick := client.Nick()
|
||||||
@ -4118,9 +4397,9 @@ func zncHandler(server *Server, client *Client, msg ircmsg.Message, rb *Response
|
|||||||
// fake handler for unknown commands
|
// fake handler for unknown commands
|
||||||
func unknownCommandHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
func unknownCommandHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
||||||
var message string
|
var message string
|
||||||
if strings.HasPrefix(msg.Command, "/") {
|
if trimmedCmd, initialSlash := strings.CutPrefix(msg.Command, "/"); initialSlash {
|
||||||
message = fmt.Sprintf(client.t("Unknown command; if you are using /QUOTE, the correct syntax is /QUOTE %[1]s, not /QUOTE %[2]s"),
|
message = fmt.Sprintf(client.t("Unknown command; if you are using /QUOTE, the correct syntax is /QUOTE %[1]s, not /QUOTE %[2]s"),
|
||||||
strings.TrimPrefix(msg.Command, "/"), msg.Command)
|
trimmedCmd, msg.Command)
|
||||||
} else {
|
} else {
|
||||||
message = client.t("Unknown command")
|
message = client.t("Unknown command")
|
||||||
}
|
}
|
||||||
|
15
irc/help.go
15
irc/help.go
@ -238,11 +238,10 @@ Get an explanation of <argument>, or "index" for a list of help topics.`,
|
|||||||
"history": {
|
"history": {
|
||||||
text: `HISTORY <target> [limit]
|
text: `HISTORY <target> [limit]
|
||||||
|
|
||||||
Replay message history. <target> can be a channel name, "me" to replay direct
|
Replay message history. <target> can be a channel name or a nickname you have
|
||||||
message history, or a nickname to replay another client's direct message
|
direct message history with. [limit] can be either an integer (the maximum
|
||||||
history (they must be logged into the same account as you). [limit] can be
|
number of messages to replay), or a time duration like 10m or 1h (the time
|
||||||
either an integer (the maximum number of messages to replay), or a time
|
window within which to replay messages).`,
|
||||||
duration like 10m or 1h (the time window within which to replay messages).`,
|
|
||||||
},
|
},
|
||||||
"info": {
|
"info": {
|
||||||
text: `INFO
|
text: `INFO
|
||||||
@ -339,6 +338,12 @@ command is processed by that server.`,
|
|||||||
MARKREAD updates an IRCv3 read message marker. It is not intended for use by
|
MARKREAD updates an IRCv3 read message marker. It is not intended for use by
|
||||||
end users. For more details, see the latest draft of the read-marker
|
end users. For more details, see the latest draft of the read-marker
|
||||||
specification.`,
|
specification.`,
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
text: `METADATA <target> <subcommand> [<everything else>...]
|
||||||
|
|
||||||
|
Retrieve and meddle with metadata for the given target.
|
||||||
|
Have a look at https://ircv3.net/specs/extensions/metadata for interesting technical information.`,
|
||||||
},
|
},
|
||||||
"mode": {
|
"mode": {
|
||||||
text: `MODE <target> [<modestring> [<mode arguments>...]]
|
text: `MODE <target> [<modestring> [<mode arguments>...]]
|
||||||
|
@ -164,7 +164,7 @@ func histservExportHandler(service *ircService, server *Server, client *Client,
|
|||||||
|
|
||||||
config := server.Config()
|
config := server.Config()
|
||||||
// don't include the account name in the filename because of escaping concerns
|
// don't include the account name in the filename because of escaping concerns
|
||||||
filename := fmt.Sprintf("%s-%s.json", utils.GenerateSecretToken(), time.Now().UTC().Format(IRCv3TimestampFormat))
|
filename := fmt.Sprintf("%s-%s.json", utils.GenerateSecretToken(), time.Now().UTC().Format(utils.IRCv3TimestampFormat))
|
||||||
pathname := config.getOutputPath(filename)
|
pathname := config.getOutputPath(filename)
|
||||||
outfile, err := os.Create(pathname)
|
outfile, err := os.Create(pathname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -45,7 +45,7 @@ type MessageCache struct {
|
|||||||
|
|
||||||
func addAllTags(msg *ircmsg.Message, tags map[string]string, serverTime time.Time, msgid, accountName string, isBot bool) {
|
func addAllTags(msg *ircmsg.Message, tags map[string]string, serverTime time.Time, msgid, accountName string, isBot bool) {
|
||||||
msg.UpdateTags(tags)
|
msg.UpdateTags(tags)
|
||||||
msg.SetTag("time", serverTime.Format(IRCv3TimestampFormat))
|
msg.SetTag("time", serverTime.Format(utils.IRCv3TimestampFormat))
|
||||||
if accountName != "*" {
|
if accountName != "*" {
|
||||||
msg.SetTag("account", accountName)
|
msg.SetTag("account", accountName)
|
||||||
}
|
}
|
||||||
|
174
irc/metadata.go
Normal file
174
irc/metadata.go
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
package irc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"iter"
|
||||||
|
"maps"
|
||||||
|
"regexp"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/ergochat/ergo/irc/caps"
|
||||||
|
"github.com/ergochat/ergo/irc/modes"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// metadata key + value need to be relayable on a single IRC RPL_KEYVALUE line
|
||||||
|
maxCombinedMetadataLenBytes = 350
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errMetadataTooManySubs = errors.New("too many subscriptions")
|
||||||
|
errMetadataNotFound = errors.New("key not found")
|
||||||
|
)
|
||||||
|
|
||||||
|
type MetadataHaver = interface {
|
||||||
|
SetMetadata(key string, value string, limit int) (updated bool, err error)
|
||||||
|
GetMetadata(key string) (string, bool)
|
||||||
|
DeleteMetadata(key string) (updated bool)
|
||||||
|
ListMetadata() map[string]string
|
||||||
|
ClearMetadata() map[string]string
|
||||||
|
CountMetadata() int
|
||||||
|
}
|
||||||
|
|
||||||
|
func notifySubscribers(server *Server, session *Session, targetObj MetadataHaver, targetName, key, value string, set bool) {
|
||||||
|
var recipientSessions iter.Seq[*Session]
|
||||||
|
|
||||||
|
switch target := targetObj.(type) {
|
||||||
|
case *Client:
|
||||||
|
// TODO this case is expensive and might warrant rate-limiting
|
||||||
|
friends := target.FriendsMonitors(caps.Metadata)
|
||||||
|
// broadcast metadata update to other connected sessions
|
||||||
|
for _, s := range target.Sessions() {
|
||||||
|
friends.Add(s)
|
||||||
|
}
|
||||||
|
recipientSessions = maps.Keys(friends)
|
||||||
|
case *Channel:
|
||||||
|
recipientSessions = target.sessionsWithCaps(caps.Metadata)
|
||||||
|
default:
|
||||||
|
return // impossible
|
||||||
|
}
|
||||||
|
|
||||||
|
broadcastMetadataUpdate(server, recipientSessions, session, targetName, key, value, set)
|
||||||
|
}
|
||||||
|
|
||||||
|
func broadcastMetadataUpdate(server *Server, sessions iter.Seq[*Session], originator *Session, target, key, value string, set bool) {
|
||||||
|
for s := range sessions {
|
||||||
|
// don't notify the session that made the change
|
||||||
|
if s == originator || !s.isSubscribedTo(key) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if set {
|
||||||
|
s.Send(nil, server.name, "METADATA", target, key, "*", value)
|
||||||
|
} else {
|
||||||
|
s.Send(nil, server.name, "METADATA", target, key, "*")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func syncClientMetadata(server *Server, rb *ResponseBuffer, target *Client) {
|
||||||
|
batchId := rb.StartNestedBatch("metadata", target.Nick())
|
||||||
|
defer rb.EndNestedBatch(batchId)
|
||||||
|
|
||||||
|
subs := rb.session.MetadataSubscriptions()
|
||||||
|
values := target.ListMetadata()
|
||||||
|
for k, v := range values {
|
||||||
|
if subs.Has(k) {
|
||||||
|
visibility := "*"
|
||||||
|
rb.Add(nil, server.name, "METADATA", target.Nick(), k, visibility, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func syncChannelMetadata(server *Server, rb *ResponseBuffer, channel *Channel) {
|
||||||
|
batchId := rb.StartNestedBatch("metadata", channel.Name())
|
||||||
|
defer rb.EndNestedBatch(batchId)
|
||||||
|
|
||||||
|
subs := rb.session.MetadataSubscriptions()
|
||||||
|
chname := channel.Name()
|
||||||
|
|
||||||
|
values := channel.ListMetadata()
|
||||||
|
for k, v := range values {
|
||||||
|
if subs.Has(k) {
|
||||||
|
visibility := "*"
|
||||||
|
rb.Add(nil, server.name, "METADATA", chname, k, visibility, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, client := range channel.Members() {
|
||||||
|
values := client.ListMetadata()
|
||||||
|
for k, v := range values {
|
||||||
|
if subs.Has(k) {
|
||||||
|
visibility := "*"
|
||||||
|
rb.Add(nil, server.name, "METADATA", client.Nick(), k, visibility, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func playMetadataList(rb *ResponseBuffer, nick, target string, values map[string]string) {
|
||||||
|
batchId := rb.StartNestedBatch("metadata", target)
|
||||||
|
defer rb.EndNestedBatch(batchId)
|
||||||
|
|
||||||
|
for key, val := range values {
|
||||||
|
visibility := "*"
|
||||||
|
rb.Add(nil, rb.session.client.server.name, RPL_KEYVALUE, nick, target, key, visibility, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func playMetadataVerbBatch(rb *ResponseBuffer, target string, values map[string]string) {
|
||||||
|
batchId := rb.StartNestedBatch("metadata", target)
|
||||||
|
defer rb.EndNestedBatch(batchId)
|
||||||
|
|
||||||
|
for key, val := range values {
|
||||||
|
visibility := "*"
|
||||||
|
rb.Add(nil, rb.session.client.server.name, "METADATA", target, key, visibility, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var validMetadataKeyRegexp = regexp.MustCompile("^[a-z0-9_./-]+$")
|
||||||
|
|
||||||
|
func metadataKeyIsEvil(key string) bool {
|
||||||
|
return !validMetadataKeyRegexp.MatchString(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func metadataValueIsEvil(config *Config, key, value string) (failMsg string) {
|
||||||
|
if !globalUtf8EnforcementSetting && !utf8.ValidString(value) {
|
||||||
|
return `METADATA values must be UTF-8`
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(key)+len(value) > maxCombinedMetadataLenBytes ||
|
||||||
|
(config.Metadata.MaxValueBytes > 0 && len(value) > config.Metadata.MaxValueBytes) {
|
||||||
|
|
||||||
|
return `Value is too long`
|
||||||
|
}
|
||||||
|
|
||||||
|
return "" // success
|
||||||
|
}
|
||||||
|
|
||||||
|
func metadataCanIEditThisKey(client *Client, targetObj MetadataHaver, key string) bool {
|
||||||
|
// no key-specific logic as yet
|
||||||
|
return metadataCanIEditThisTarget(client, targetObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func metadataCanIEditThisTarget(client *Client, targetObj MetadataHaver) bool {
|
||||||
|
switch target := targetObj.(type) {
|
||||||
|
case *Client:
|
||||||
|
return client == target || client.HasRoleCapabs("metadata")
|
||||||
|
case *Channel:
|
||||||
|
return target.ClientIsAtLeast(client, modes.Operator) || client.HasRoleCapabs("metadata")
|
||||||
|
default:
|
||||||
|
return false // impossible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func metadataCanISeeThisTarget(client *Client, targetObj MetadataHaver) bool {
|
||||||
|
switch target := targetObj.(type) {
|
||||||
|
case *Client:
|
||||||
|
return true
|
||||||
|
case *Channel:
|
||||||
|
return target.hasClient(client) || client.HasRoleCapabs("metadata")
|
||||||
|
default:
|
||||||
|
return false // impossible
|
||||||
|
}
|
||||||
|
}
|
25
irc/metadata_test.go
Normal file
25
irc/metadata_test.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package irc
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestKeyCheck(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
input string
|
||||||
|
isEvil bool
|
||||||
|
}{
|
||||||
|
{"ImNormalButIHaveCaps", true},
|
||||||
|
{"imnormalandidonthavecaps", false},
|
||||||
|
{"ergo.chat/vendor-extension", false},
|
||||||
|
{"", true},
|
||||||
|
{":imevil", true},
|
||||||
|
{"im:evil", true},
|
||||||
|
{"key£with$not%allowed^chars", true},
|
||||||
|
{"key.thats_completely/normal-and.fine", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
if metadataKeyIsEvil(c.input) != c.isEvil {
|
||||||
|
t.Errorf("%s should have returned %v. but it didn't. so that's not great", c.input, c.isEvil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1055,10 +1055,10 @@ func nsSaregisterHandler(service *ircService, server *Server, client *Client, co
|
|||||||
var failCode string
|
var failCode string
|
||||||
if err == errAccountAlreadyRegistered || err == errAccountAlreadyVerified {
|
if err == errAccountAlreadyRegistered || err == errAccountAlreadyVerified {
|
||||||
errMsg = client.t("Account already exists")
|
errMsg = client.t("Account already exists")
|
||||||
failCode = "USERNAME_EXISTS"
|
failCode = "ACCOUNT_EXISTS"
|
||||||
} else if err == errNameReserved {
|
} else if err == errNameReserved {
|
||||||
errMsg = client.t(err.Error())
|
errMsg = client.t(err.Error())
|
||||||
failCode = "USERNAME_EXISTS"
|
failCode = "ACCOUNT_EXISTS"
|
||||||
} else if err == errAccountBadPassphrase {
|
} else if err == errAccountBadPassphrase {
|
||||||
errMsg = client.t("Passphrase contains forbidden characters or is otherwise invalid")
|
errMsg = client.t("Passphrase contains forbidden characters or is otherwise invalid")
|
||||||
failCode = "INVALID_PASSWORD"
|
failCode = "INVALID_PASSWORD"
|
||||||
|
@ -183,6 +183,12 @@ const (
|
|||||||
RPL_MONLIST = "732"
|
RPL_MONLIST = "732"
|
||||||
RPL_ENDOFMONLIST = "733"
|
RPL_ENDOFMONLIST = "733"
|
||||||
ERR_MONLISTFULL = "734"
|
ERR_MONLISTFULL = "734"
|
||||||
|
RPL_KEYVALUE = "761" // metadata numerics
|
||||||
|
RPL_KEYNOTSET = "766"
|
||||||
|
RPL_METADATASUBOK = "770"
|
||||||
|
RPL_METADATAUNSUBOK = "771"
|
||||||
|
RPL_METADATASUBS = "772"
|
||||||
|
RPL_METADATASYNCLATER = "774"
|
||||||
RPL_LOGGEDIN = "900"
|
RPL_LOGGEDIN = "900"
|
||||||
RPL_LOGGEDOUT = "901"
|
RPL_LOGGEDOUT = "901"
|
||||||
ERR_NICKLOCKED = "902"
|
ERR_NICKLOCKED = "902"
|
||||||
|
@ -428,6 +428,8 @@ func (server *Server) tryRegister(c *Client, session *Session) (exiting bool) {
|
|||||||
c.SetMode(defaultMode, true)
|
c.SetMode(defaultMode, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.applyPreregMetadata(session)
|
||||||
|
|
||||||
// this is not a reattach, so if the client is always-on, this is the first time
|
// this is not a reattach, so if the client is always-on, this is the first time
|
||||||
// the Client object was created during the current server uptime. mark dirty in
|
// the Client object was created during the current server uptime. mark dirty in
|
||||||
// order to persist the realname and the user modes:
|
// order to persist the realname and the user modes:
|
||||||
@ -496,6 +498,9 @@ func (server *Server) playRegistrationBurst(session *Session) {
|
|||||||
if !(rb.session.capabilities.Has(caps.ExtendedISupport) && rb.session.isupportSentPrereg) {
|
if !(rb.session.capabilities.Has(caps.ExtendedISupport) && rb.session.isupportSentPrereg) {
|
||||||
server.RplISupport(c, rb)
|
server.RplISupport(c, rb)
|
||||||
}
|
}
|
||||||
|
if session.capabilities.Has(caps.Metadata) {
|
||||||
|
playMetadataVerbBatch(rb, d.nick, c.ListMetadata())
|
||||||
|
}
|
||||||
if d.account != "" && session.capabilities.Has(caps.Persistence) {
|
if d.account != "" && session.capabilities.Has(caps.Persistence) {
|
||||||
reportPersistenceStatus(c, rb, false)
|
reportPersistenceStatus(c, rb, false)
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ var globalCasemappingSetting Casemapping = CasemappingPRECIS
|
|||||||
|
|
||||||
// XXX analogous unsynchronized global variable controlling utf8 validation
|
// XXX analogous unsynchronized global variable controlling utf8 validation
|
||||||
// if this is off, you get the traditional IRC behavior (relaying any valid RFC1459
|
// if this is off, you get the traditional IRC behavior (relaying any valid RFC1459
|
||||||
// octets) and invalid utf8 messages are silently dropped for websocket clients only.
|
// octets), and websocket listeners are disabled.
|
||||||
// if this is on, invalid utf8 inputs get a FAIL reply.
|
// if this is on, invalid utf8 inputs get a FAIL reply.
|
||||||
var globalUtf8EnforcementSetting bool
|
var globalUtf8EnforcementSetting bool
|
||||||
|
|
||||||
|
28
irc/utils/chunks.go
Normal file
28
irc/utils/chunks.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import "iter"
|
||||||
|
|
||||||
|
func ChunkifyParams(params iter.Seq[string], maxChars int) [][]string {
|
||||||
|
var chunked [][]string
|
||||||
|
|
||||||
|
var acc []string
|
||||||
|
var length = 0
|
||||||
|
|
||||||
|
for p := range params {
|
||||||
|
length = length + len(p) + 1 // (accounting for the space)
|
||||||
|
|
||||||
|
if length > maxChars {
|
||||||
|
chunked = append(chunked, acc)
|
||||||
|
acc = []string{}
|
||||||
|
length = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
acc = append(acc, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(acc) != 0 {
|
||||||
|
chunked = append(chunked, acc)
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunked
|
||||||
|
}
|
@ -7,7 +7,7 @@ import "fmt"
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// SemVer is the semantic version of Ergo.
|
// SemVer is the semantic version of Ergo.
|
||||||
SemVer = "2.16.0-rc1"
|
SemVer = "2.17.0-unreleased"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
2
irctest
2
irctest
@ -1 +1 @@
|
|||||||
Subproject commit e9e37f5438bd5f02656b89dab0cd40ef113edac6
|
Subproject commit ccdacd990a09ac3cd3591613b8d7fee4301e08c8
|
@ -494,7 +494,7 @@ accounts:
|
|||||||
# 1. these nicknames cannot be registered or reserved
|
# 1. these nicknames cannot be registered or reserved
|
||||||
# 2. if a client is automatically renamed by the server,
|
# 2. if a client is automatically renamed by the server,
|
||||||
# this is the template that will be used (e.g., Guest-nccj6rgmt97cg)
|
# this is the template that will be used (e.g., Guest-nccj6rgmt97cg)
|
||||||
# 3. if enforce-guest-format (see below) is enabled, clients without
|
# 3. if force-guest-format (see below) is enabled, clients without
|
||||||
# a registered account will have this template applied to their
|
# a registered account will have this template applied to their
|
||||||
# nicknames (e.g., 'katie' will become 'Guest-katie')
|
# nicknames (e.g., 'katie' will become 'Guest-katie')
|
||||||
guest-nickname-format: "Guest-*"
|
guest-nickname-format: "Guest-*"
|
||||||
@ -695,6 +695,7 @@ oper-classes:
|
|||||||
- "history" # modify or delete history messages
|
- "history" # modify or delete history messages
|
||||||
- "defcon" # use the DEFCON command (restrict server capabilities)
|
- "defcon" # use the DEFCON command (restrict server capabilities)
|
||||||
- "massmessage" # message all users on the server
|
- "massmessage" # message all users on the server
|
||||||
|
- "metadata" # modify arbitrary metadata on channels and users
|
||||||
|
|
||||||
# ircd operators
|
# ircd operators
|
||||||
opers:
|
opers:
|
||||||
@ -1058,6 +1059,15 @@ history:
|
|||||||
# e.g., ERGO__SERVER__MAX_SENDQ=128k. see the manual for more details.
|
# e.g., ERGO__SERVER__MAX_SENDQ=128k. see the manual for more details.
|
||||||
allow-environment-overrides: true
|
allow-environment-overrides: true
|
||||||
|
|
||||||
|
# metadata support for setting key/value data on channels and nicknames.
|
||||||
|
metadata:
|
||||||
|
# can clients store metadata?
|
||||||
|
enabled: true
|
||||||
|
# how many keys can a client subscribe to?
|
||||||
|
max-subs: 100
|
||||||
|
# how many keys can be stored per entity?
|
||||||
|
max-keys: 100
|
||||||
|
|
||||||
# experimental support for mobile push notifications
|
# experimental support for mobile push notifications
|
||||||
# see the manual for potential security, privacy, and performance implications.
|
# see the manual for potential security, privacy, and performance implications.
|
||||||
# DO NOT enable if you are running a Tor or I2P hidden service (i.e. one
|
# DO NOT enable if you are running a Tor or I2P hidden service (i.e. one
|
||||||
|
7
vendor/github.com/emersion/go-msgauth/dkim/header.go
generated
vendored
7
vendor/github.com/emersion/go-msgauth/dkim/header.go
generated
vendored
@ -83,7 +83,12 @@ func parseHeaderParams(s string) (map[string]string, error) {
|
|||||||
return params, errors.New("dkim: malformed header params")
|
return params, errors.New("dkim: malformed header params")
|
||||||
}
|
}
|
||||||
|
|
||||||
params[strings.TrimSpace(key)] = strings.TrimSpace(value)
|
trimmedKey := strings.TrimSpace(key)
|
||||||
|
_, present := params[trimmedKey]
|
||||||
|
if present {
|
||||||
|
return params, errors.New("dkim: duplicate tag name")
|
||||||
|
}
|
||||||
|
params[trimmedKey] = strings.TrimSpace(value)
|
||||||
}
|
}
|
||||||
return params, nil
|
return params, nil
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/emersion/go-msgauth/dkim/query.go
generated
vendored
2
vendor/github.com/emersion/go-msgauth/dkim/query.go
generated
vendored
@ -100,7 +100,7 @@ func queryDNSTXT(domain, selector string, txtLookup txtLookupFunc) (*queryResult
|
|||||||
func parsePublicKey(s string) (*queryResult, error) {
|
func parsePublicKey(s string) (*queryResult, error) {
|
||||||
params, err := parseHeaderParams(s)
|
params, err := parseHeaderParams(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, permFailError("key syntax error: " + err.Error())
|
return nil, permFailError("key record error: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
res := new(queryResult)
|
res := new(queryResult)
|
||||||
|
36
vendor/golang.org/x/sys/unix/auxv.go
generated
vendored
Normal file
36
vendor/golang.org/x/sys/unix/auxv.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2025 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos)
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:linkname runtime_getAuxv runtime.getAuxv
|
||||||
|
func runtime_getAuxv() []uintptr
|
||||||
|
|
||||||
|
// Auxv returns the ELF auxiliary vector as a sequence of key/value pairs.
|
||||||
|
// The returned slice is always a fresh copy, owned by the caller.
|
||||||
|
// It returns an error on non-ELF platforms, or if the auxiliary vector cannot be accessed,
|
||||||
|
// which happens in some locked-down environments and build modes.
|
||||||
|
func Auxv() ([][2]uintptr, error) {
|
||||||
|
vec := runtime_getAuxv()
|
||||||
|
vecLen := len(vec)
|
||||||
|
|
||||||
|
if vecLen == 0 {
|
||||||
|
return nil, syscall.ENOENT
|
||||||
|
}
|
||||||
|
|
||||||
|
if vecLen%2 != 0 {
|
||||||
|
return nil, syscall.EINVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]uintptr, vecLen)
|
||||||
|
copy(result, vec)
|
||||||
|
return unsafe.Slice((*[2]uintptr)(unsafe.Pointer(&result[0])), vecLen/2), nil
|
||||||
|
}
|
13
vendor/golang.org/x/sys/unix/auxv_unsupported.go
generated
vendored
Normal file
13
vendor/golang.org/x/sys/unix/auxv_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright 2025 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos)
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
func Auxv() ([][2]uintptr, error) {
|
||||||
|
return nil, syscall.ENOTSUP
|
||||||
|
}
|
149
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
149
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
@ -602,7 +602,150 @@ func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocI
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error)
|
// sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error)
|
||||||
|
const minIovec = 8
|
||||||
|
|
||||||
|
func Readv(fd int, iovs [][]byte) (n int, err error) {
|
||||||
|
if !darwinKernelVersionMin(11, 0, 0) {
|
||||||
|
return 0, ENOSYS
|
||||||
|
}
|
||||||
|
|
||||||
|
iovecs := make([]Iovec, 0, minIovec)
|
||||||
|
iovecs = appendBytes(iovecs, iovs)
|
||||||
|
n, err = readv(fd, iovecs)
|
||||||
|
readvRacedetect(iovecs, n, err)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
|
||||||
|
if !darwinKernelVersionMin(11, 0, 0) {
|
||||||
|
return 0, ENOSYS
|
||||||
|
}
|
||||||
|
iovecs := make([]Iovec, 0, minIovec)
|
||||||
|
iovecs = appendBytes(iovecs, iovs)
|
||||||
|
n, err = preadv(fd, iovecs, offset)
|
||||||
|
readvRacedetect(iovecs, n, err)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func Writev(fd int, iovs [][]byte) (n int, err error) {
|
||||||
|
if !darwinKernelVersionMin(11, 0, 0) {
|
||||||
|
return 0, ENOSYS
|
||||||
|
}
|
||||||
|
|
||||||
|
iovecs := make([]Iovec, 0, minIovec)
|
||||||
|
iovecs = appendBytes(iovecs, iovs)
|
||||||
|
if raceenabled {
|
||||||
|
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
||||||
|
}
|
||||||
|
n, err = writev(fd, iovecs)
|
||||||
|
writevRacedetect(iovecs, n)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
|
||||||
|
if !darwinKernelVersionMin(11, 0, 0) {
|
||||||
|
return 0, ENOSYS
|
||||||
|
}
|
||||||
|
|
||||||
|
iovecs := make([]Iovec, 0, minIovec)
|
||||||
|
iovecs = appendBytes(iovecs, iovs)
|
||||||
|
if raceenabled {
|
||||||
|
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
||||||
|
}
|
||||||
|
n, err = pwritev(fd, iovecs, offset)
|
||||||
|
writevRacedetect(iovecs, n)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendBytes(vecs []Iovec, bs [][]byte) []Iovec {
|
||||||
|
for _, b := range bs {
|
||||||
|
var v Iovec
|
||||||
|
v.SetLen(len(b))
|
||||||
|
if len(b) > 0 {
|
||||||
|
v.Base = &b[0]
|
||||||
|
} else {
|
||||||
|
v.Base = (*byte)(unsafe.Pointer(&_zero))
|
||||||
|
}
|
||||||
|
vecs = append(vecs, v)
|
||||||
|
}
|
||||||
|
return vecs
|
||||||
|
}
|
||||||
|
|
||||||
|
func writevRacedetect(iovecs []Iovec, n int) {
|
||||||
|
if !raceenabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i := 0; n > 0 && i < len(iovecs); i++ {
|
||||||
|
m := int(iovecs[i].Len)
|
||||||
|
if m > n {
|
||||||
|
m = n
|
||||||
|
}
|
||||||
|
n -= m
|
||||||
|
if m > 0 {
|
||||||
|
raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func readvRacedetect(iovecs []Iovec, n int, err error) {
|
||||||
|
if !raceenabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i := 0; n > 0 && i < len(iovecs); i++ {
|
||||||
|
m := int(iovecs[i].Len)
|
||||||
|
if m > n {
|
||||||
|
m = n
|
||||||
|
}
|
||||||
|
n -= m
|
||||||
|
if m > 0 {
|
||||||
|
raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
raceAcquire(unsafe.Pointer(&ioSync))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func darwinMajorMinPatch() (maj, min, patch int, err error) {
|
||||||
|
var un Utsname
|
||||||
|
err = Uname(&un)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var mmp [3]int
|
||||||
|
c := 0
|
||||||
|
Loop:
|
||||||
|
for _, b := range un.Release[:] {
|
||||||
|
switch {
|
||||||
|
case b >= '0' && b <= '9':
|
||||||
|
mmp[c] = 10*mmp[c] + int(b-'0')
|
||||||
|
case b == '.':
|
||||||
|
c++
|
||||||
|
if c > 2 {
|
||||||
|
return 0, 0, 0, ENOTSUP
|
||||||
|
}
|
||||||
|
case b == 0:
|
||||||
|
break Loop
|
||||||
|
default:
|
||||||
|
return 0, 0, 0, ENOTSUP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c != 2 {
|
||||||
|
return 0, 0, 0, ENOTSUP
|
||||||
|
}
|
||||||
|
return mmp[0], mmp[1], mmp[2], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func darwinKernelVersionMin(maj, min, patch int) bool {
|
||||||
|
actualMaj, actualMin, actualPatch, err := darwinMajorMinPatch()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return actualMaj > maj || actualMaj == maj && (actualMin > min || actualMin == min && actualPatch >= patch)
|
||||||
|
}
|
||||||
|
|
||||||
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
|
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
|
||||||
|
|
||||||
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
|
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
|
||||||
@ -705,3 +848,7 @@ func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocI
|
|||||||
//sys write(fd int, p []byte) (n int, err error)
|
//sys write(fd int, p []byte) (n int, err error)
|
||||||
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
|
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
|
||||||
//sys munmap(addr uintptr, length uintptr) (err error)
|
//sys munmap(addr uintptr, length uintptr) (err error)
|
||||||
|
//sys readv(fd int, iovecs []Iovec) (n int, err error)
|
||||||
|
//sys preadv(fd int, iovecs []Iovec, offset int64) (n int, err error)
|
||||||
|
//sys writev(fd int, iovecs []Iovec) (n int, err error)
|
||||||
|
//sys pwritev(fd int, iovecs []Iovec, offset int64) (n int, err error)
|
||||||
|
42
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
42
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
@ -13,6 +13,7 @@ package unix
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
@ -417,7 +418,7 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
|||||||
return nil, 0, EINVAL
|
return nil, 0, EINVAL
|
||||||
}
|
}
|
||||||
sa.raw.Family = AF_UNIX
|
sa.raw.Family = AF_UNIX
|
||||||
for i := 0; i < n; i++ {
|
for i := range n {
|
||||||
sa.raw.Path[i] = int8(name[i])
|
sa.raw.Path[i] = int8(name[i])
|
||||||
}
|
}
|
||||||
// length is family (uint16), name, NUL.
|
// length is family (uint16), name, NUL.
|
||||||
@ -507,7 +508,7 @@ func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
|||||||
psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm))
|
psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm))
|
||||||
psm[0] = byte(sa.PSM)
|
psm[0] = byte(sa.PSM)
|
||||||
psm[1] = byte(sa.PSM >> 8)
|
psm[1] = byte(sa.PSM >> 8)
|
||||||
for i := 0; i < len(sa.Addr); i++ {
|
for i := range len(sa.Addr) {
|
||||||
sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i]
|
sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i]
|
||||||
}
|
}
|
||||||
cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid))
|
cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid))
|
||||||
@ -589,11 +590,11 @@ func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
|||||||
sa.raw.Family = AF_CAN
|
sa.raw.Family = AF_CAN
|
||||||
sa.raw.Ifindex = int32(sa.Ifindex)
|
sa.raw.Ifindex = int32(sa.Ifindex)
|
||||||
rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
|
rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
|
||||||
for i := 0; i < 4; i++ {
|
for i := range 4 {
|
||||||
sa.raw.Addr[i] = rx[i]
|
sa.raw.Addr[i] = rx[i]
|
||||||
}
|
}
|
||||||
tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
|
tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
|
||||||
for i := 0; i < 4; i++ {
|
for i := range 4 {
|
||||||
sa.raw.Addr[i+4] = tx[i]
|
sa.raw.Addr[i+4] = tx[i]
|
||||||
}
|
}
|
||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
|
||||||
@ -618,11 +619,11 @@ func (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
|||||||
sa.raw.Family = AF_CAN
|
sa.raw.Family = AF_CAN
|
||||||
sa.raw.Ifindex = int32(sa.Ifindex)
|
sa.raw.Ifindex = int32(sa.Ifindex)
|
||||||
n := (*[8]byte)(unsafe.Pointer(&sa.Name))
|
n := (*[8]byte)(unsafe.Pointer(&sa.Name))
|
||||||
for i := 0; i < 8; i++ {
|
for i := range 8 {
|
||||||
sa.raw.Addr[i] = n[i]
|
sa.raw.Addr[i] = n[i]
|
||||||
}
|
}
|
||||||
p := (*[4]byte)(unsafe.Pointer(&sa.PGN))
|
p := (*[4]byte)(unsafe.Pointer(&sa.PGN))
|
||||||
for i := 0; i < 4; i++ {
|
for i := range 4 {
|
||||||
sa.raw.Addr[i+8] = p[i]
|
sa.raw.Addr[i+8] = p[i]
|
||||||
}
|
}
|
||||||
sa.raw.Addr[12] = sa.Addr
|
sa.raw.Addr[12] = sa.Addr
|
||||||
@ -911,7 +912,7 @@ func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
|||||||
// These are EBCDIC encoded by the kernel, but we still need to pad them
|
// These are EBCDIC encoded by the kernel, but we still need to pad them
|
||||||
// with blanks. Initializing with blanks allows the caller to feed in either
|
// with blanks. Initializing with blanks allows the caller to feed in either
|
||||||
// a padded or an unpadded string.
|
// a padded or an unpadded string.
|
||||||
for i := 0; i < 8; i++ {
|
for i := range 8 {
|
||||||
sa.raw.Nodeid[i] = ' '
|
sa.raw.Nodeid[i] = ' '
|
||||||
sa.raw.User_id[i] = ' '
|
sa.raw.User_id[i] = ' '
|
||||||
sa.raw.Name[i] = ' '
|
sa.raw.Name[i] = ' '
|
||||||
@ -1148,7 +1149,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
|||||||
var user [8]byte
|
var user [8]byte
|
||||||
var name [8]byte
|
var name [8]byte
|
||||||
|
|
||||||
for i := 0; i < 8; i++ {
|
for i := range 8 {
|
||||||
user[i] = byte(pp.User_id[i])
|
user[i] = byte(pp.User_id[i])
|
||||||
name[i] = byte(pp.Name[i])
|
name[i] = byte(pp.Name[i])
|
||||||
}
|
}
|
||||||
@ -1173,11 +1174,11 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
|||||||
Ifindex: int(pp.Ifindex),
|
Ifindex: int(pp.Ifindex),
|
||||||
}
|
}
|
||||||
name := (*[8]byte)(unsafe.Pointer(&sa.Name))
|
name := (*[8]byte)(unsafe.Pointer(&sa.Name))
|
||||||
for i := 0; i < 8; i++ {
|
for i := range 8 {
|
||||||
name[i] = pp.Addr[i]
|
name[i] = pp.Addr[i]
|
||||||
}
|
}
|
||||||
pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN))
|
pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN))
|
||||||
for i := 0; i < 4; i++ {
|
for i := range 4 {
|
||||||
pgn[i] = pp.Addr[i+8]
|
pgn[i] = pp.Addr[i+8]
|
||||||
}
|
}
|
||||||
addr := (*[1]byte)(unsafe.Pointer(&sa.Addr))
|
addr := (*[1]byte)(unsafe.Pointer(&sa.Addr))
|
||||||
@ -1188,11 +1189,11 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
|||||||
Ifindex: int(pp.Ifindex),
|
Ifindex: int(pp.Ifindex),
|
||||||
}
|
}
|
||||||
rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
|
rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
|
||||||
for i := 0; i < 4; i++ {
|
for i := range 4 {
|
||||||
rx[i] = pp.Addr[i]
|
rx[i] = pp.Addr[i]
|
||||||
}
|
}
|
||||||
tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
|
tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
|
||||||
for i := 0; i < 4; i++ {
|
for i := range 4 {
|
||||||
tx[i] = pp.Addr[i+4]
|
tx[i] = pp.Addr[i+4]
|
||||||
}
|
}
|
||||||
return sa, nil
|
return sa, nil
|
||||||
@ -2216,10 +2217,7 @@ func readvRacedetect(iovecs []Iovec, n int, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for i := 0; n > 0 && i < len(iovecs); i++ {
|
for i := 0; n > 0 && i < len(iovecs); i++ {
|
||||||
m := int(iovecs[i].Len)
|
m := min(int(iovecs[i].Len), n)
|
||||||
if m > n {
|
|
||||||
m = n
|
|
||||||
}
|
|
||||||
n -= m
|
n -= m
|
||||||
if m > 0 {
|
if m > 0 {
|
||||||
raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
|
raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
|
||||||
@ -2270,10 +2268,7 @@ func writevRacedetect(iovecs []Iovec, n int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for i := 0; n > 0 && i < len(iovecs); i++ {
|
for i := 0; n > 0 && i < len(iovecs); i++ {
|
||||||
m := int(iovecs[i].Len)
|
m := min(int(iovecs[i].Len), n)
|
||||||
if m > n {
|
|
||||||
m = n
|
|
||||||
}
|
|
||||||
n -= m
|
n -= m
|
||||||
if m > 0 {
|
if m > 0 {
|
||||||
raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
|
raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
|
||||||
@ -2320,12 +2315,7 @@ func isGroupMember(gid int) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, g := range groups {
|
return slices.Contains(groups, gid)
|
||||||
if g == gid {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isCapDacOverrideSet() bool {
|
func isCapDacOverrideSet() bool {
|
||||||
|
87
vendor/golang.org/x/sys/unix/syscall_solaris.go
generated
vendored
87
vendor/golang.org/x/sys/unix/syscall_solaris.go
generated
vendored
@ -1102,3 +1102,90 @@ func (s *Strioctl) SetInt(i int) {
|
|||||||
func IoctlSetStrioctlRetInt(fd int, req int, s *Strioctl) (int, error) {
|
func IoctlSetStrioctlRetInt(fd int, req int, s *Strioctl) (int, error) {
|
||||||
return ioctlPtrRet(fd, req, unsafe.Pointer(s))
|
return ioctlPtrRet(fd, req, unsafe.Pointer(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ucred Helpers
|
||||||
|
// See ucred(3c) and getpeerucred(3c)
|
||||||
|
|
||||||
|
//sys getpeerucred(fd uintptr, ucred *uintptr) (err error)
|
||||||
|
//sys ucredFree(ucred uintptr) = ucred_free
|
||||||
|
//sys ucredGet(pid int) (ucred uintptr, err error) = ucred_get
|
||||||
|
//sys ucredGeteuid(ucred uintptr) (uid int) = ucred_geteuid
|
||||||
|
//sys ucredGetegid(ucred uintptr) (gid int) = ucred_getegid
|
||||||
|
//sys ucredGetruid(ucred uintptr) (uid int) = ucred_getruid
|
||||||
|
//sys ucredGetrgid(ucred uintptr) (gid int) = ucred_getrgid
|
||||||
|
//sys ucredGetsuid(ucred uintptr) (uid int) = ucred_getsuid
|
||||||
|
//sys ucredGetsgid(ucred uintptr) (gid int) = ucred_getsgid
|
||||||
|
//sys ucredGetpid(ucred uintptr) (pid int) = ucred_getpid
|
||||||
|
|
||||||
|
// Ucred is an opaque struct that holds user credentials.
|
||||||
|
type Ucred struct {
|
||||||
|
ucred uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to ensure that ucredFree is called on the underlying ucred
|
||||||
|
// when the Ucred is garbage collected.
|
||||||
|
func ucredFinalizer(u *Ucred) {
|
||||||
|
ucredFree(u.ucred)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPeerUcred(fd uintptr) (*Ucred, error) {
|
||||||
|
var ucred uintptr
|
||||||
|
err := getpeerucred(fd, &ucred)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result := &Ucred{
|
||||||
|
ucred: ucred,
|
||||||
|
}
|
||||||
|
// set the finalizer on the result so that the ucred will be freed
|
||||||
|
runtime.SetFinalizer(result, ucredFinalizer)
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UcredGet(pid int) (*Ucred, error) {
|
||||||
|
ucred, err := ucredGet(pid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result := &Ucred{
|
||||||
|
ucred: ucred,
|
||||||
|
}
|
||||||
|
// set the finalizer on the result so that the ucred will be freed
|
||||||
|
runtime.SetFinalizer(result, ucredFinalizer)
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Ucred) Geteuid() int {
|
||||||
|
defer runtime.KeepAlive(u)
|
||||||
|
return ucredGeteuid(u.ucred)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Ucred) Getruid() int {
|
||||||
|
defer runtime.KeepAlive(u)
|
||||||
|
return ucredGetruid(u.ucred)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Ucred) Getsuid() int {
|
||||||
|
defer runtime.KeepAlive(u)
|
||||||
|
return ucredGetsuid(u.ucred)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Ucred) Getegid() int {
|
||||||
|
defer runtime.KeepAlive(u)
|
||||||
|
return ucredGetegid(u.ucred)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Ucred) Getrgid() int {
|
||||||
|
defer runtime.KeepAlive(u)
|
||||||
|
return ucredGetrgid(u.ucred)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Ucred) Getsgid() int {
|
||||||
|
defer runtime.KeepAlive(u)
|
||||||
|
return ucredGetsgid(u.ucred)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Ucred) Getpid() int {
|
||||||
|
defer runtime.KeepAlive(u)
|
||||||
|
return ucredGetpid(u.ucred)
|
||||||
|
}
|
||||||
|
20
vendor/golang.org/x/sys/unix/zerrors_linux.go
generated
vendored
20
vendor/golang.org/x/sys/unix/zerrors_linux.go
generated
vendored
@ -1245,6 +1245,7 @@ const (
|
|||||||
FAN_REPORT_DFID_NAME = 0xc00
|
FAN_REPORT_DFID_NAME = 0xc00
|
||||||
FAN_REPORT_DFID_NAME_TARGET = 0x1e00
|
FAN_REPORT_DFID_NAME_TARGET = 0x1e00
|
||||||
FAN_REPORT_DIR_FID = 0x400
|
FAN_REPORT_DIR_FID = 0x400
|
||||||
|
FAN_REPORT_FD_ERROR = 0x2000
|
||||||
FAN_REPORT_FID = 0x200
|
FAN_REPORT_FID = 0x200
|
||||||
FAN_REPORT_NAME = 0x800
|
FAN_REPORT_NAME = 0x800
|
||||||
FAN_REPORT_PIDFD = 0x80
|
FAN_REPORT_PIDFD = 0x80
|
||||||
@ -1330,8 +1331,10 @@ const (
|
|||||||
FUSE_SUPER_MAGIC = 0x65735546
|
FUSE_SUPER_MAGIC = 0x65735546
|
||||||
FUTEXFS_SUPER_MAGIC = 0xbad1dea
|
FUTEXFS_SUPER_MAGIC = 0xbad1dea
|
||||||
F_ADD_SEALS = 0x409
|
F_ADD_SEALS = 0x409
|
||||||
|
F_CREATED_QUERY = 0x404
|
||||||
F_DUPFD = 0x0
|
F_DUPFD = 0x0
|
||||||
F_DUPFD_CLOEXEC = 0x406
|
F_DUPFD_CLOEXEC = 0x406
|
||||||
|
F_DUPFD_QUERY = 0x403
|
||||||
F_EXLCK = 0x4
|
F_EXLCK = 0x4
|
||||||
F_GETFD = 0x1
|
F_GETFD = 0x1
|
||||||
F_GETFL = 0x3
|
F_GETFL = 0x3
|
||||||
@ -1551,6 +1554,7 @@ const (
|
|||||||
IPPROTO_ROUTING = 0x2b
|
IPPROTO_ROUTING = 0x2b
|
||||||
IPPROTO_RSVP = 0x2e
|
IPPROTO_RSVP = 0x2e
|
||||||
IPPROTO_SCTP = 0x84
|
IPPROTO_SCTP = 0x84
|
||||||
|
IPPROTO_SMC = 0x100
|
||||||
IPPROTO_TCP = 0x6
|
IPPROTO_TCP = 0x6
|
||||||
IPPROTO_TP = 0x1d
|
IPPROTO_TP = 0x1d
|
||||||
IPPROTO_UDP = 0x11
|
IPPROTO_UDP = 0x11
|
||||||
@ -1623,6 +1627,8 @@ const (
|
|||||||
IPV6_UNICAST_IF = 0x4c
|
IPV6_UNICAST_IF = 0x4c
|
||||||
IPV6_USER_FLOW = 0xe
|
IPV6_USER_FLOW = 0xe
|
||||||
IPV6_V6ONLY = 0x1a
|
IPV6_V6ONLY = 0x1a
|
||||||
|
IPV6_VERSION = 0x60
|
||||||
|
IPV6_VERSION_MASK = 0xf0
|
||||||
IPV6_XFRM_POLICY = 0x23
|
IPV6_XFRM_POLICY = 0x23
|
||||||
IP_ADD_MEMBERSHIP = 0x23
|
IP_ADD_MEMBERSHIP = 0x23
|
||||||
IP_ADD_SOURCE_MEMBERSHIP = 0x27
|
IP_ADD_SOURCE_MEMBERSHIP = 0x27
|
||||||
@ -1867,6 +1873,7 @@ const (
|
|||||||
MADV_UNMERGEABLE = 0xd
|
MADV_UNMERGEABLE = 0xd
|
||||||
MADV_WILLNEED = 0x3
|
MADV_WILLNEED = 0x3
|
||||||
MADV_WIPEONFORK = 0x12
|
MADV_WIPEONFORK = 0x12
|
||||||
|
MAP_DROPPABLE = 0x8
|
||||||
MAP_FILE = 0x0
|
MAP_FILE = 0x0
|
||||||
MAP_FIXED = 0x10
|
MAP_FIXED = 0x10
|
||||||
MAP_FIXED_NOREPLACE = 0x100000
|
MAP_FIXED_NOREPLACE = 0x100000
|
||||||
@ -1967,6 +1974,7 @@ const (
|
|||||||
MSG_PEEK = 0x2
|
MSG_PEEK = 0x2
|
||||||
MSG_PROXY = 0x10
|
MSG_PROXY = 0x10
|
||||||
MSG_RST = 0x1000
|
MSG_RST = 0x1000
|
||||||
|
MSG_SOCK_DEVMEM = 0x2000000
|
||||||
MSG_SYN = 0x400
|
MSG_SYN = 0x400
|
||||||
MSG_TRUNC = 0x20
|
MSG_TRUNC = 0x20
|
||||||
MSG_TRYHARD = 0x4
|
MSG_TRYHARD = 0x4
|
||||||
@ -2083,6 +2091,7 @@ const (
|
|||||||
NFC_ATR_REQ_MAXSIZE = 0x40
|
NFC_ATR_REQ_MAXSIZE = 0x40
|
||||||
NFC_ATR_RES_GB_MAXSIZE = 0x2f
|
NFC_ATR_RES_GB_MAXSIZE = 0x2f
|
||||||
NFC_ATR_RES_MAXSIZE = 0x40
|
NFC_ATR_RES_MAXSIZE = 0x40
|
||||||
|
NFC_ATS_MAXSIZE = 0x14
|
||||||
NFC_COMM_ACTIVE = 0x0
|
NFC_COMM_ACTIVE = 0x0
|
||||||
NFC_COMM_PASSIVE = 0x1
|
NFC_COMM_PASSIVE = 0x1
|
||||||
NFC_DEVICE_NAME_MAXSIZE = 0x8
|
NFC_DEVICE_NAME_MAXSIZE = 0x8
|
||||||
@ -2163,6 +2172,7 @@ const (
|
|||||||
NFNL_SUBSYS_QUEUE = 0x3
|
NFNL_SUBSYS_QUEUE = 0x3
|
||||||
NFNL_SUBSYS_ULOG = 0x4
|
NFNL_SUBSYS_ULOG = 0x4
|
||||||
NFS_SUPER_MAGIC = 0x6969
|
NFS_SUPER_MAGIC = 0x6969
|
||||||
|
NFT_BITWISE_BOOL = 0x0
|
||||||
NFT_CHAIN_FLAGS = 0x7
|
NFT_CHAIN_FLAGS = 0x7
|
||||||
NFT_CHAIN_MAXNAMELEN = 0x100
|
NFT_CHAIN_MAXNAMELEN = 0x100
|
||||||
NFT_CT_MAX = 0x17
|
NFT_CT_MAX = 0x17
|
||||||
@ -2491,6 +2501,7 @@ const (
|
|||||||
PR_GET_PDEATHSIG = 0x2
|
PR_GET_PDEATHSIG = 0x2
|
||||||
PR_GET_SECCOMP = 0x15
|
PR_GET_SECCOMP = 0x15
|
||||||
PR_GET_SECUREBITS = 0x1b
|
PR_GET_SECUREBITS = 0x1b
|
||||||
|
PR_GET_SHADOW_STACK_STATUS = 0x4a
|
||||||
PR_GET_SPECULATION_CTRL = 0x34
|
PR_GET_SPECULATION_CTRL = 0x34
|
||||||
PR_GET_TAGGED_ADDR_CTRL = 0x38
|
PR_GET_TAGGED_ADDR_CTRL = 0x38
|
||||||
PR_GET_THP_DISABLE = 0x2a
|
PR_GET_THP_DISABLE = 0x2a
|
||||||
@ -2499,6 +2510,7 @@ const (
|
|||||||
PR_GET_TIMING = 0xd
|
PR_GET_TIMING = 0xd
|
||||||
PR_GET_TSC = 0x19
|
PR_GET_TSC = 0x19
|
||||||
PR_GET_UNALIGN = 0x5
|
PR_GET_UNALIGN = 0x5
|
||||||
|
PR_LOCK_SHADOW_STACK_STATUS = 0x4c
|
||||||
PR_MCE_KILL = 0x21
|
PR_MCE_KILL = 0x21
|
||||||
PR_MCE_KILL_CLEAR = 0x0
|
PR_MCE_KILL_CLEAR = 0x0
|
||||||
PR_MCE_KILL_DEFAULT = 0x2
|
PR_MCE_KILL_DEFAULT = 0x2
|
||||||
@ -2525,6 +2537,8 @@ const (
|
|||||||
PR_PAC_GET_ENABLED_KEYS = 0x3d
|
PR_PAC_GET_ENABLED_KEYS = 0x3d
|
||||||
PR_PAC_RESET_KEYS = 0x36
|
PR_PAC_RESET_KEYS = 0x36
|
||||||
PR_PAC_SET_ENABLED_KEYS = 0x3c
|
PR_PAC_SET_ENABLED_KEYS = 0x3c
|
||||||
|
PR_PMLEN_MASK = 0x7f000000
|
||||||
|
PR_PMLEN_SHIFT = 0x18
|
||||||
PR_PPC_DEXCR_CTRL_CLEAR = 0x4
|
PR_PPC_DEXCR_CTRL_CLEAR = 0x4
|
||||||
PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC = 0x10
|
PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC = 0x10
|
||||||
PR_PPC_DEXCR_CTRL_EDITABLE = 0x1
|
PR_PPC_DEXCR_CTRL_EDITABLE = 0x1
|
||||||
@ -2592,6 +2606,7 @@ const (
|
|||||||
PR_SET_PTRACER = 0x59616d61
|
PR_SET_PTRACER = 0x59616d61
|
||||||
PR_SET_SECCOMP = 0x16
|
PR_SET_SECCOMP = 0x16
|
||||||
PR_SET_SECUREBITS = 0x1c
|
PR_SET_SECUREBITS = 0x1c
|
||||||
|
PR_SET_SHADOW_STACK_STATUS = 0x4b
|
||||||
PR_SET_SPECULATION_CTRL = 0x35
|
PR_SET_SPECULATION_CTRL = 0x35
|
||||||
PR_SET_SYSCALL_USER_DISPATCH = 0x3b
|
PR_SET_SYSCALL_USER_DISPATCH = 0x3b
|
||||||
PR_SET_TAGGED_ADDR_CTRL = 0x37
|
PR_SET_TAGGED_ADDR_CTRL = 0x37
|
||||||
@ -2602,6 +2617,9 @@ const (
|
|||||||
PR_SET_UNALIGN = 0x6
|
PR_SET_UNALIGN = 0x6
|
||||||
PR_SET_VMA = 0x53564d41
|
PR_SET_VMA = 0x53564d41
|
||||||
PR_SET_VMA_ANON_NAME = 0x0
|
PR_SET_VMA_ANON_NAME = 0x0
|
||||||
|
PR_SHADOW_STACK_ENABLE = 0x1
|
||||||
|
PR_SHADOW_STACK_PUSH = 0x4
|
||||||
|
PR_SHADOW_STACK_WRITE = 0x2
|
||||||
PR_SME_GET_VL = 0x40
|
PR_SME_GET_VL = 0x40
|
||||||
PR_SME_SET_VL = 0x3f
|
PR_SME_SET_VL = 0x3f
|
||||||
PR_SME_SET_VL_ONEXEC = 0x40000
|
PR_SME_SET_VL_ONEXEC = 0x40000
|
||||||
@ -2911,7 +2929,6 @@ const (
|
|||||||
RTM_NEWNEXTHOP = 0x68
|
RTM_NEWNEXTHOP = 0x68
|
||||||
RTM_NEWNEXTHOPBUCKET = 0x74
|
RTM_NEWNEXTHOPBUCKET = 0x74
|
||||||
RTM_NEWNSID = 0x58
|
RTM_NEWNSID = 0x58
|
||||||
RTM_NEWNVLAN = 0x70
|
|
||||||
RTM_NEWPREFIX = 0x34
|
RTM_NEWPREFIX = 0x34
|
||||||
RTM_NEWQDISC = 0x24
|
RTM_NEWQDISC = 0x24
|
||||||
RTM_NEWROUTE = 0x18
|
RTM_NEWROUTE = 0x18
|
||||||
@ -2920,6 +2937,7 @@ const (
|
|||||||
RTM_NEWTCLASS = 0x28
|
RTM_NEWTCLASS = 0x28
|
||||||
RTM_NEWTFILTER = 0x2c
|
RTM_NEWTFILTER = 0x2c
|
||||||
RTM_NEWTUNNEL = 0x78
|
RTM_NEWTUNNEL = 0x78
|
||||||
|
RTM_NEWVLAN = 0x70
|
||||||
RTM_NR_FAMILIES = 0x1b
|
RTM_NR_FAMILIES = 0x1b
|
||||||
RTM_NR_MSGTYPES = 0x6c
|
RTM_NR_MSGTYPES = 0x6c
|
||||||
RTM_SETDCB = 0x4f
|
RTM_SETDCB = 0x4f
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_386.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_386.go
generated
vendored
@ -116,6 +116,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x800
|
IN_NONBLOCK = 0x800
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||||
ISIG = 0x1
|
ISIG = 0x1
|
||||||
IUCLC = 0x200
|
IUCLC = 0x200
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
@ -304,6 +306,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
generated
vendored
@ -116,6 +116,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x800
|
IN_NONBLOCK = 0x800
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||||
ISIG = 0x1
|
ISIG = 0x1
|
||||||
IUCLC = 0x200
|
IUCLC = 0x200
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
@ -305,6 +307,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
generated
vendored
@ -115,6 +115,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x800
|
IN_NONBLOCK = 0x800
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||||
ISIG = 0x1
|
ISIG = 0x1
|
||||||
IUCLC = 0x200
|
IUCLC = 0x200
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
@ -310,6 +312,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
4
vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
generated
vendored
@ -109,6 +109,7 @@ const (
|
|||||||
F_SETOWN = 0x8
|
F_SETOWN = 0x8
|
||||||
F_UNLCK = 0x2
|
F_UNLCK = 0x2
|
||||||
F_WRLCK = 0x1
|
F_WRLCK = 0x1
|
||||||
|
GCS_MAGIC = 0x47435300
|
||||||
HIDIOCGRAWINFO = 0x80084803
|
HIDIOCGRAWINFO = 0x80084803
|
||||||
HIDIOCGRDESC = 0x90044802
|
HIDIOCGRDESC = 0x90044802
|
||||||
HIDIOCGRDESCSIZE = 0x80044801
|
HIDIOCGRDESCSIZE = 0x80044801
|
||||||
@ -119,6 +120,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x800
|
IN_NONBLOCK = 0x800
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||||
ISIG = 0x1
|
ISIG = 0x1
|
||||||
IUCLC = 0x200
|
IUCLC = 0x200
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
@ -302,6 +305,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go
generated
vendored
@ -116,6 +116,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x800
|
IN_NONBLOCK = 0x800
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||||
ISIG = 0x1
|
ISIG = 0x1
|
||||||
IUCLC = 0x200
|
IUCLC = 0x200
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
@ -297,6 +299,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
generated
vendored
@ -115,6 +115,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x80
|
IN_NONBLOCK = 0x80
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xfffffff
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xfffff
|
||||||
ISIG = 0x1
|
ISIG = 0x1
|
||||||
IUCLC = 0x200
|
IUCLC = 0x200
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
@ -303,6 +305,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
generated
vendored
@ -115,6 +115,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x80
|
IN_NONBLOCK = 0x80
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xfffffff
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xfffff
|
||||||
ISIG = 0x1
|
ISIG = 0x1
|
||||||
IUCLC = 0x200
|
IUCLC = 0x200
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
@ -303,6 +305,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
generated
vendored
@ -115,6 +115,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x80
|
IN_NONBLOCK = 0x80
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||||
ISIG = 0x1
|
ISIG = 0x1
|
||||||
IUCLC = 0x200
|
IUCLC = 0x200
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
@ -303,6 +305,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
generated
vendored
@ -115,6 +115,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x80
|
IN_NONBLOCK = 0x80
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||||
ISIG = 0x1
|
ISIG = 0x1
|
||||||
IUCLC = 0x200
|
IUCLC = 0x200
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
@ -303,6 +305,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go
generated
vendored
@ -115,6 +115,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x800
|
IN_NONBLOCK = 0x800
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xfffffff
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xfffff
|
||||||
ISIG = 0x80
|
ISIG = 0x80
|
||||||
IUCLC = 0x1000
|
IUCLC = 0x1000
|
||||||
IXOFF = 0x400
|
IXOFF = 0x400
|
||||||
@ -358,6 +360,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
generated
vendored
@ -115,6 +115,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x800
|
IN_NONBLOCK = 0x800
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xfffffff
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xfffff
|
||||||
ISIG = 0x80
|
ISIG = 0x80
|
||||||
IUCLC = 0x1000
|
IUCLC = 0x1000
|
||||||
IXOFF = 0x400
|
IXOFF = 0x400
|
||||||
@ -362,6 +364,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
generated
vendored
@ -115,6 +115,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x800
|
IN_NONBLOCK = 0x800
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||||
ISIG = 0x80
|
ISIG = 0x80
|
||||||
IUCLC = 0x1000
|
IUCLC = 0x1000
|
||||||
IXOFF = 0x400
|
IXOFF = 0x400
|
||||||
@ -362,6 +364,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
generated
vendored
@ -115,6 +115,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x800
|
IN_NONBLOCK = 0x800
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xffffff0f
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xffff0f00
|
||||||
ISIG = 0x1
|
ISIG = 0x1
|
||||||
IUCLC = 0x200
|
IUCLC = 0x200
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
@ -294,6 +296,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
generated
vendored
@ -115,6 +115,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x80000
|
IN_CLOEXEC = 0x80000
|
||||||
IN_NONBLOCK = 0x800
|
IN_NONBLOCK = 0x800
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xfffffff
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xfffff
|
||||||
ISIG = 0x1
|
ISIG = 0x1
|
||||||
IUCLC = 0x200
|
IUCLC = 0x200
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
@ -366,6 +368,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
|
SCM_TS_OPT_ID = 0x51
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
3
vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
generated
vendored
3
vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
generated
vendored
@ -119,6 +119,8 @@ const (
|
|||||||
IN_CLOEXEC = 0x400000
|
IN_CLOEXEC = 0x400000
|
||||||
IN_NONBLOCK = 0x4000
|
IN_NONBLOCK = 0x4000
|
||||||
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
|
||||||
|
IPV6_FLOWINFO_MASK = 0xfffffff
|
||||||
|
IPV6_FLOWLABEL_MASK = 0xfffff
|
||||||
ISIG = 0x1
|
ISIG = 0x1
|
||||||
IUCLC = 0x200
|
IUCLC = 0x200
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
@ -357,6 +359,7 @@ const (
|
|||||||
SCM_TIMESTAMPING_OPT_STATS = 0x38
|
SCM_TIMESTAMPING_OPT_STATS = 0x38
|
||||||
SCM_TIMESTAMPING_PKTINFO = 0x3c
|
SCM_TIMESTAMPING_PKTINFO = 0x3c
|
||||||
SCM_TIMESTAMPNS = 0x21
|
SCM_TIMESTAMPNS = 0x21
|
||||||
|
SCM_TS_OPT_ID = 0x5a
|
||||||
SCM_TXTIME = 0x3f
|
SCM_TXTIME = 0x3f
|
||||||
SCM_WIFI_STATUS = 0x25
|
SCM_WIFI_STATUS = 0x25
|
||||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
84
vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
generated
vendored
84
vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
generated
vendored
@ -2512,6 +2512,90 @@ var libc_munmap_trampoline_addr uintptr
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func readv(fd int, iovecs []Iovec) (n int, err error) {
|
||||||
|
var _p0 unsafe.Pointer
|
||||||
|
if len(iovecs) > 0 {
|
||||||
|
_p0 = unsafe.Pointer(&iovecs[0])
|
||||||
|
} else {
|
||||||
|
_p0 = unsafe.Pointer(&_zero)
|
||||||
|
}
|
||||||
|
r0, _, e1 := syscall_syscall(libc_readv_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
|
||||||
|
n = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_readv_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_readv readv "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func preadv(fd int, iovecs []Iovec, offset int64) (n int, err error) {
|
||||||
|
var _p0 unsafe.Pointer
|
||||||
|
if len(iovecs) > 0 {
|
||||||
|
_p0 = unsafe.Pointer(&iovecs[0])
|
||||||
|
} else {
|
||||||
|
_p0 = unsafe.Pointer(&_zero)
|
||||||
|
}
|
||||||
|
r0, _, e1 := syscall_syscall6(libc_preadv_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)), uintptr(offset), 0, 0)
|
||||||
|
n = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_preadv_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_preadv preadv "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func writev(fd int, iovecs []Iovec) (n int, err error) {
|
||||||
|
var _p0 unsafe.Pointer
|
||||||
|
if len(iovecs) > 0 {
|
||||||
|
_p0 = unsafe.Pointer(&iovecs[0])
|
||||||
|
} else {
|
||||||
|
_p0 = unsafe.Pointer(&_zero)
|
||||||
|
}
|
||||||
|
r0, _, e1 := syscall_syscall(libc_writev_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
|
||||||
|
n = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_writev_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_writev writev "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func pwritev(fd int, iovecs []Iovec, offset int64) (n int, err error) {
|
||||||
|
var _p0 unsafe.Pointer
|
||||||
|
if len(iovecs) > 0 {
|
||||||
|
_p0 = unsafe.Pointer(&iovecs[0])
|
||||||
|
} else {
|
||||||
|
_p0 = unsafe.Pointer(&_zero)
|
||||||
|
}
|
||||||
|
r0, _, e1 := syscall_syscall6(libc_pwritev_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)), uintptr(offset), 0, 0)
|
||||||
|
n = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_pwritev_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_pwritev pwritev "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Fstat(fd int, stat *Stat_t) (err error) {
|
func Fstat(fd int, stat *Stat_t) (err error) {
|
||||||
_, _, e1 := syscall_syscall(libc_fstat64_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
|
_, _, e1 := syscall_syscall(libc_fstat64_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
20
vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
generated
vendored
20
vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
generated
vendored
@ -738,6 +738,26 @@ TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0
|
|||||||
GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8
|
GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8
|
||||||
DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB)
|
DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB)
|
||||||
|
|
||||||
|
TEXT libc_readv_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_readv(SB)
|
||||||
|
GLOBL ·libc_readv_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_readv_trampoline_addr(SB)/8, $libc_readv_trampoline<>(SB)
|
||||||
|
|
||||||
|
TEXT libc_preadv_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_preadv(SB)
|
||||||
|
GLOBL ·libc_preadv_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_preadv_trampoline_addr(SB)/8, $libc_preadv_trampoline<>(SB)
|
||||||
|
|
||||||
|
TEXT libc_writev_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_writev(SB)
|
||||||
|
GLOBL ·libc_writev_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_writev_trampoline_addr(SB)/8, $libc_writev_trampoline<>(SB)
|
||||||
|
|
||||||
|
TEXT libc_pwritev_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_pwritev(SB)
|
||||||
|
GLOBL ·libc_pwritev_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_pwritev_trampoline_addr(SB)/8, $libc_pwritev_trampoline<>(SB)
|
||||||
|
|
||||||
TEXT libc_fstat64_trampoline<>(SB),NOSPLIT,$0-0
|
TEXT libc_fstat64_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
JMP libc_fstat64(SB)
|
JMP libc_fstat64(SB)
|
||||||
GLOBL ·libc_fstat64_trampoline_addr(SB), RODATA, $8
|
GLOBL ·libc_fstat64_trampoline_addr(SB), RODATA, $8
|
||||||
|
84
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
generated
vendored
84
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
generated
vendored
@ -2512,6 +2512,90 @@ var libc_munmap_trampoline_addr uintptr
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func readv(fd int, iovecs []Iovec) (n int, err error) {
|
||||||
|
var _p0 unsafe.Pointer
|
||||||
|
if len(iovecs) > 0 {
|
||||||
|
_p0 = unsafe.Pointer(&iovecs[0])
|
||||||
|
} else {
|
||||||
|
_p0 = unsafe.Pointer(&_zero)
|
||||||
|
}
|
||||||
|
r0, _, e1 := syscall_syscall(libc_readv_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
|
||||||
|
n = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_readv_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_readv readv "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func preadv(fd int, iovecs []Iovec, offset int64) (n int, err error) {
|
||||||
|
var _p0 unsafe.Pointer
|
||||||
|
if len(iovecs) > 0 {
|
||||||
|
_p0 = unsafe.Pointer(&iovecs[0])
|
||||||
|
} else {
|
||||||
|
_p0 = unsafe.Pointer(&_zero)
|
||||||
|
}
|
||||||
|
r0, _, e1 := syscall_syscall6(libc_preadv_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)), uintptr(offset), 0, 0)
|
||||||
|
n = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_preadv_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_preadv preadv "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func writev(fd int, iovecs []Iovec) (n int, err error) {
|
||||||
|
var _p0 unsafe.Pointer
|
||||||
|
if len(iovecs) > 0 {
|
||||||
|
_p0 = unsafe.Pointer(&iovecs[0])
|
||||||
|
} else {
|
||||||
|
_p0 = unsafe.Pointer(&_zero)
|
||||||
|
}
|
||||||
|
r0, _, e1 := syscall_syscall(libc_writev_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
|
||||||
|
n = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_writev_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_writev writev "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func pwritev(fd int, iovecs []Iovec, offset int64) (n int, err error) {
|
||||||
|
var _p0 unsafe.Pointer
|
||||||
|
if len(iovecs) > 0 {
|
||||||
|
_p0 = unsafe.Pointer(&iovecs[0])
|
||||||
|
} else {
|
||||||
|
_p0 = unsafe.Pointer(&_zero)
|
||||||
|
}
|
||||||
|
r0, _, e1 := syscall_syscall6(libc_pwritev_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(iovecs)), uintptr(offset), 0, 0)
|
||||||
|
n = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var libc_pwritev_trampoline_addr uintptr
|
||||||
|
|
||||||
|
//go:cgo_import_dynamic libc_pwritev pwritev "/usr/lib/libSystem.B.dylib"
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Fstat(fd int, stat *Stat_t) (err error) {
|
func Fstat(fd int, stat *Stat_t) (err error) {
|
||||||
_, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
|
_, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
20
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
generated
vendored
20
vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
generated
vendored
@ -738,6 +738,26 @@ TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0
|
|||||||
GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8
|
GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8
|
||||||
DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB)
|
DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB)
|
||||||
|
|
||||||
|
TEXT libc_readv_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_readv(SB)
|
||||||
|
GLOBL ·libc_readv_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_readv_trampoline_addr(SB)/8, $libc_readv_trampoline<>(SB)
|
||||||
|
|
||||||
|
TEXT libc_preadv_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_preadv(SB)
|
||||||
|
GLOBL ·libc_preadv_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_preadv_trampoline_addr(SB)/8, $libc_preadv_trampoline<>(SB)
|
||||||
|
|
||||||
|
TEXT libc_writev_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_writev(SB)
|
||||||
|
GLOBL ·libc_writev_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_writev_trampoline_addr(SB)/8, $libc_writev_trampoline<>(SB)
|
||||||
|
|
||||||
|
TEXT libc_pwritev_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
|
JMP libc_pwritev(SB)
|
||||||
|
GLOBL ·libc_pwritev_trampoline_addr(SB), RODATA, $8
|
||||||
|
DATA ·libc_pwritev_trampoline_addr(SB)/8, $libc_pwritev_trampoline<>(SB)
|
||||||
|
|
||||||
TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0
|
TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0
|
||||||
JMP libc_fstat(SB)
|
JMP libc_fstat(SB)
|
||||||
GLOBL ·libc_fstat_trampoline_addr(SB), RODATA, $8
|
GLOBL ·libc_fstat_trampoline_addr(SB), RODATA, $8
|
||||||
|
114
vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
generated
vendored
114
vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
generated
vendored
@ -141,6 +141,16 @@ import (
|
|||||||
//go:cgo_import_dynamic libc_getpeername getpeername "libsocket.so"
|
//go:cgo_import_dynamic libc_getpeername getpeername "libsocket.so"
|
||||||
//go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so"
|
//go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so"
|
||||||
//go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so"
|
//go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so"
|
||||||
|
//go:cgo_import_dynamic libc_getpeerucred getpeerucred "libc.so"
|
||||||
|
//go:cgo_import_dynamic libc_ucred_get ucred_get "libc.so"
|
||||||
|
//go:cgo_import_dynamic libc_ucred_geteuid ucred_geteuid "libc.so"
|
||||||
|
//go:cgo_import_dynamic libc_ucred_getegid ucred_getegid "libc.so"
|
||||||
|
//go:cgo_import_dynamic libc_ucred_getruid ucred_getruid "libc.so"
|
||||||
|
//go:cgo_import_dynamic libc_ucred_getrgid ucred_getrgid "libc.so"
|
||||||
|
//go:cgo_import_dynamic libc_ucred_getsuid ucred_getsuid "libc.so"
|
||||||
|
//go:cgo_import_dynamic libc_ucred_getsgid ucred_getsgid "libc.so"
|
||||||
|
//go:cgo_import_dynamic libc_ucred_getpid ucred_getpid "libc.so"
|
||||||
|
//go:cgo_import_dynamic libc_ucred_free ucred_free "libc.so"
|
||||||
//go:cgo_import_dynamic libc_port_create port_create "libc.so"
|
//go:cgo_import_dynamic libc_port_create port_create "libc.so"
|
||||||
//go:cgo_import_dynamic libc_port_associate port_associate "libc.so"
|
//go:cgo_import_dynamic libc_port_associate port_associate "libc.so"
|
||||||
//go:cgo_import_dynamic libc_port_dissociate port_dissociate "libc.so"
|
//go:cgo_import_dynamic libc_port_dissociate port_dissociate "libc.so"
|
||||||
@ -280,6 +290,16 @@ import (
|
|||||||
//go:linkname procgetpeername libc_getpeername
|
//go:linkname procgetpeername libc_getpeername
|
||||||
//go:linkname procsetsockopt libc_setsockopt
|
//go:linkname procsetsockopt libc_setsockopt
|
||||||
//go:linkname procrecvfrom libc_recvfrom
|
//go:linkname procrecvfrom libc_recvfrom
|
||||||
|
//go:linkname procgetpeerucred libc_getpeerucred
|
||||||
|
//go:linkname procucred_get libc_ucred_get
|
||||||
|
//go:linkname procucred_geteuid libc_ucred_geteuid
|
||||||
|
//go:linkname procucred_getegid libc_ucred_getegid
|
||||||
|
//go:linkname procucred_getruid libc_ucred_getruid
|
||||||
|
//go:linkname procucred_getrgid libc_ucred_getrgid
|
||||||
|
//go:linkname procucred_getsuid libc_ucred_getsuid
|
||||||
|
//go:linkname procucred_getsgid libc_ucred_getsgid
|
||||||
|
//go:linkname procucred_getpid libc_ucred_getpid
|
||||||
|
//go:linkname procucred_free libc_ucred_free
|
||||||
//go:linkname procport_create libc_port_create
|
//go:linkname procport_create libc_port_create
|
||||||
//go:linkname procport_associate libc_port_associate
|
//go:linkname procport_associate libc_port_associate
|
||||||
//go:linkname procport_dissociate libc_port_dissociate
|
//go:linkname procport_dissociate libc_port_dissociate
|
||||||
@ -420,6 +440,16 @@ var (
|
|||||||
procgetpeername,
|
procgetpeername,
|
||||||
procsetsockopt,
|
procsetsockopt,
|
||||||
procrecvfrom,
|
procrecvfrom,
|
||||||
|
procgetpeerucred,
|
||||||
|
procucred_get,
|
||||||
|
procucred_geteuid,
|
||||||
|
procucred_getegid,
|
||||||
|
procucred_getruid,
|
||||||
|
procucred_getrgid,
|
||||||
|
procucred_getsuid,
|
||||||
|
procucred_getsgid,
|
||||||
|
procucred_getpid,
|
||||||
|
procucred_free,
|
||||||
procport_create,
|
procport_create,
|
||||||
procport_associate,
|
procport_associate,
|
||||||
procport_dissociate,
|
procport_dissociate,
|
||||||
@ -2029,6 +2059,90 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func getpeerucred(fd uintptr, ucred *uintptr) (err error) {
|
||||||
|
_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetpeerucred)), 2, uintptr(fd), uintptr(unsafe.Pointer(ucred)), 0, 0, 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func ucredGet(pid int) (ucred uintptr, err error) {
|
||||||
|
r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procucred_get)), 1, uintptr(pid), 0, 0, 0, 0, 0)
|
||||||
|
ucred = uintptr(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func ucredGeteuid(ucred uintptr) (uid int) {
|
||||||
|
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_geteuid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||||
|
uid = int(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func ucredGetegid(ucred uintptr) (gid int) {
|
||||||
|
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getegid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||||
|
gid = int(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func ucredGetruid(ucred uintptr) (uid int) {
|
||||||
|
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getruid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||||
|
uid = int(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func ucredGetrgid(ucred uintptr) (gid int) {
|
||||||
|
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getrgid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||||
|
gid = int(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func ucredGetsuid(ucred uintptr) (uid int) {
|
||||||
|
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getsuid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||||
|
uid = int(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func ucredGetsgid(ucred uintptr) (gid int) {
|
||||||
|
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getsgid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||||
|
gid = int(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func ucredGetpid(ucred uintptr) (pid int) {
|
||||||
|
r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getpid)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||||
|
pid = int(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func ucredFree(ucred uintptr) {
|
||||||
|
sysvicall6(uintptr(unsafe.Pointer(&procucred_free)), 1, uintptr(ucred), 0, 0, 0, 0, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func port_create() (n int, err error) {
|
func port_create() (n int, err error) {
|
||||||
r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procport_create)), 0, 0, 0, 0, 0, 0, 0)
|
r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procport_create)), 0, 0, 0, 0, 0, 0, 0)
|
||||||
n = int(r0)
|
n = int(r0)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
generated
vendored
@ -458,4 +458,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 460
|
SYS_LSM_SET_SELF_ATTR = 460
|
||||||
SYS_LSM_LIST_MODULES = 461
|
SYS_LSM_LIST_MODULES = 461
|
||||||
SYS_MSEAL = 462
|
SYS_MSEAL = 462
|
||||||
|
SYS_SETXATTRAT = 463
|
||||||
|
SYS_GETXATTRAT = 464
|
||||||
|
SYS_LISTXATTRAT = 465
|
||||||
|
SYS_REMOVEXATTRAT = 466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
generated
vendored
@ -381,4 +381,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 460
|
SYS_LSM_SET_SELF_ATTR = 460
|
||||||
SYS_LSM_LIST_MODULES = 461
|
SYS_LSM_LIST_MODULES = 461
|
||||||
SYS_MSEAL = 462
|
SYS_MSEAL = 462
|
||||||
|
SYS_SETXATTRAT = 463
|
||||||
|
SYS_GETXATTRAT = 464
|
||||||
|
SYS_LISTXATTRAT = 465
|
||||||
|
SYS_REMOVEXATTRAT = 466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
generated
vendored
@ -422,4 +422,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 460
|
SYS_LSM_SET_SELF_ATTR = 460
|
||||||
SYS_LSM_LIST_MODULES = 461
|
SYS_LSM_LIST_MODULES = 461
|
||||||
SYS_MSEAL = 462
|
SYS_MSEAL = 462
|
||||||
|
SYS_SETXATTRAT = 463
|
||||||
|
SYS_GETXATTRAT = 464
|
||||||
|
SYS_LISTXATTRAT = 465
|
||||||
|
SYS_REMOVEXATTRAT = 466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
generated
vendored
@ -325,4 +325,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 460
|
SYS_LSM_SET_SELF_ATTR = 460
|
||||||
SYS_LSM_LIST_MODULES = 461
|
SYS_LSM_LIST_MODULES = 461
|
||||||
SYS_MSEAL = 462
|
SYS_MSEAL = 462
|
||||||
|
SYS_SETXATTRAT = 463
|
||||||
|
SYS_GETXATTRAT = 464
|
||||||
|
SYS_LISTXATTRAT = 465
|
||||||
|
SYS_REMOVEXATTRAT = 466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go
generated
vendored
@ -321,4 +321,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 460
|
SYS_LSM_SET_SELF_ATTR = 460
|
||||||
SYS_LSM_LIST_MODULES = 461
|
SYS_LSM_LIST_MODULES = 461
|
||||||
SYS_MSEAL = 462
|
SYS_MSEAL = 462
|
||||||
|
SYS_SETXATTRAT = 463
|
||||||
|
SYS_GETXATTRAT = 464
|
||||||
|
SYS_LISTXATTRAT = 465
|
||||||
|
SYS_REMOVEXATTRAT = 466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go
generated
vendored
@ -442,4 +442,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 4460
|
SYS_LSM_SET_SELF_ATTR = 4460
|
||||||
SYS_LSM_LIST_MODULES = 4461
|
SYS_LSM_LIST_MODULES = 4461
|
||||||
SYS_MSEAL = 4462
|
SYS_MSEAL = 4462
|
||||||
|
SYS_SETXATTRAT = 4463
|
||||||
|
SYS_GETXATTRAT = 4464
|
||||||
|
SYS_LISTXATTRAT = 4465
|
||||||
|
SYS_REMOVEXATTRAT = 4466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go
generated
vendored
@ -372,4 +372,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 5460
|
SYS_LSM_SET_SELF_ATTR = 5460
|
||||||
SYS_LSM_LIST_MODULES = 5461
|
SYS_LSM_LIST_MODULES = 5461
|
||||||
SYS_MSEAL = 5462
|
SYS_MSEAL = 5462
|
||||||
|
SYS_SETXATTRAT = 5463
|
||||||
|
SYS_GETXATTRAT = 5464
|
||||||
|
SYS_LISTXATTRAT = 5465
|
||||||
|
SYS_REMOVEXATTRAT = 5466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go
generated
vendored
@ -372,4 +372,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 5460
|
SYS_LSM_SET_SELF_ATTR = 5460
|
||||||
SYS_LSM_LIST_MODULES = 5461
|
SYS_LSM_LIST_MODULES = 5461
|
||||||
SYS_MSEAL = 5462
|
SYS_MSEAL = 5462
|
||||||
|
SYS_SETXATTRAT = 5463
|
||||||
|
SYS_GETXATTRAT = 5464
|
||||||
|
SYS_LISTXATTRAT = 5465
|
||||||
|
SYS_REMOVEXATTRAT = 5466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go
generated
vendored
@ -442,4 +442,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 4460
|
SYS_LSM_SET_SELF_ATTR = 4460
|
||||||
SYS_LSM_LIST_MODULES = 4461
|
SYS_LSM_LIST_MODULES = 4461
|
||||||
SYS_MSEAL = 4462
|
SYS_MSEAL = 4462
|
||||||
|
SYS_SETXATTRAT = 4463
|
||||||
|
SYS_GETXATTRAT = 4464
|
||||||
|
SYS_LISTXATTRAT = 4465
|
||||||
|
SYS_REMOVEXATTRAT = 4466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go
generated
vendored
@ -449,4 +449,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 460
|
SYS_LSM_SET_SELF_ATTR = 460
|
||||||
SYS_LSM_LIST_MODULES = 461
|
SYS_LSM_LIST_MODULES = 461
|
||||||
SYS_MSEAL = 462
|
SYS_MSEAL = 462
|
||||||
|
SYS_SETXATTRAT = 463
|
||||||
|
SYS_GETXATTRAT = 464
|
||||||
|
SYS_LISTXATTRAT = 465
|
||||||
|
SYS_REMOVEXATTRAT = 466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
generated
vendored
@ -421,4 +421,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 460
|
SYS_LSM_SET_SELF_ATTR = 460
|
||||||
SYS_LSM_LIST_MODULES = 461
|
SYS_LSM_LIST_MODULES = 461
|
||||||
SYS_MSEAL = 462
|
SYS_MSEAL = 462
|
||||||
|
SYS_SETXATTRAT = 463
|
||||||
|
SYS_GETXATTRAT = 464
|
||||||
|
SYS_LISTXATTRAT = 465
|
||||||
|
SYS_REMOVEXATTRAT = 466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
generated
vendored
@ -421,4 +421,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 460
|
SYS_LSM_SET_SELF_ATTR = 460
|
||||||
SYS_LSM_LIST_MODULES = 461
|
SYS_LSM_LIST_MODULES = 461
|
||||||
SYS_MSEAL = 462
|
SYS_MSEAL = 462
|
||||||
|
SYS_SETXATTRAT = 463
|
||||||
|
SYS_GETXATTRAT = 464
|
||||||
|
SYS_LISTXATTRAT = 465
|
||||||
|
SYS_REMOVEXATTRAT = 466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
generated
vendored
@ -326,4 +326,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 460
|
SYS_LSM_SET_SELF_ATTR = 460
|
||||||
SYS_LSM_LIST_MODULES = 461
|
SYS_LSM_LIST_MODULES = 461
|
||||||
SYS_MSEAL = 462
|
SYS_MSEAL = 462
|
||||||
|
SYS_SETXATTRAT = 463
|
||||||
|
SYS_GETXATTRAT = 464
|
||||||
|
SYS_LISTXATTRAT = 465
|
||||||
|
SYS_REMOVEXATTRAT = 466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go
generated
vendored
@ -387,4 +387,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 460
|
SYS_LSM_SET_SELF_ATTR = 460
|
||||||
SYS_LSM_LIST_MODULES = 461
|
SYS_LSM_LIST_MODULES = 461
|
||||||
SYS_MSEAL = 462
|
SYS_MSEAL = 462
|
||||||
|
SYS_SETXATTRAT = 463
|
||||||
|
SYS_GETXATTRAT = 464
|
||||||
|
SYS_LISTXATTRAT = 465
|
||||||
|
SYS_REMOVEXATTRAT = 466
|
||||||
)
|
)
|
||||||
|
4
vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go
generated
vendored
@ -400,4 +400,8 @@ const (
|
|||||||
SYS_LSM_SET_SELF_ATTR = 460
|
SYS_LSM_SET_SELF_ATTR = 460
|
||||||
SYS_LSM_LIST_MODULES = 461
|
SYS_LSM_LIST_MODULES = 461
|
||||||
SYS_MSEAL = 462
|
SYS_MSEAL = 462
|
||||||
|
SYS_SETXATTRAT = 463
|
||||||
|
SYS_GETXATTRAT = 464
|
||||||
|
SYS_LISTXATTRAT = 465
|
||||||
|
SYS_REMOVEXATTRAT = 466
|
||||||
)
|
)
|
||||||
|
6
vendor/golang.org/x/sys/unix/ztypes_linux.go
generated
vendored
6
vendor/golang.org/x/sys/unix/ztypes_linux.go
generated
vendored
@ -4747,7 +4747,7 @@ const (
|
|||||||
NL80211_ATTR_MAC_HINT = 0xc8
|
NL80211_ATTR_MAC_HINT = 0xc8
|
||||||
NL80211_ATTR_MAC_MASK = 0xd7
|
NL80211_ATTR_MAC_MASK = 0xd7
|
||||||
NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca
|
NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca
|
||||||
NL80211_ATTR_MAX = 0x14c
|
NL80211_ATTR_MAX = 0x14d
|
||||||
NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4
|
NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4
|
||||||
NL80211_ATTR_MAX_CSA_COUNTERS = 0xce
|
NL80211_ATTR_MAX_CSA_COUNTERS = 0xce
|
||||||
NL80211_ATTR_MAX_MATCH_SETS = 0x85
|
NL80211_ATTR_MAX_MATCH_SETS = 0x85
|
||||||
@ -5519,7 +5519,7 @@ const (
|
|||||||
NL80211_MNTR_FLAG_CONTROL = 0x3
|
NL80211_MNTR_FLAG_CONTROL = 0x3
|
||||||
NL80211_MNTR_FLAG_COOK_FRAMES = 0x5
|
NL80211_MNTR_FLAG_COOK_FRAMES = 0x5
|
||||||
NL80211_MNTR_FLAG_FCSFAIL = 0x1
|
NL80211_MNTR_FLAG_FCSFAIL = 0x1
|
||||||
NL80211_MNTR_FLAG_MAX = 0x6
|
NL80211_MNTR_FLAG_MAX = 0x7
|
||||||
NL80211_MNTR_FLAG_OTHER_BSS = 0x4
|
NL80211_MNTR_FLAG_OTHER_BSS = 0x4
|
||||||
NL80211_MNTR_FLAG_PLCPFAIL = 0x2
|
NL80211_MNTR_FLAG_PLCPFAIL = 0x2
|
||||||
NL80211_MPATH_FLAG_ACTIVE = 0x1
|
NL80211_MPATH_FLAG_ACTIVE = 0x1
|
||||||
@ -6174,3 +6174,5 @@ type SockDiagReq struct {
|
|||||||
Family uint8
|
Family uint8
|
||||||
Protocol uint8
|
Protocol uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RTM_NEWNVLAN = 0x70
|
||||||
|
49
vendor/golang.org/x/sys/windows/security_windows.go
generated
vendored
49
vendor/golang.org/x/sys/windows/security_windows.go
generated
vendored
@ -1303,7 +1303,10 @@ func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DE
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if absoluteSDSize > 0 {
|
if absoluteSDSize > 0 {
|
||||||
absoluteSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, absoluteSDSize)[0]))
|
absoluteSD = new(SECURITY_DESCRIPTOR)
|
||||||
|
if unsafe.Sizeof(*absoluteSD) < uintptr(absoluteSDSize) {
|
||||||
|
panic("sizeof(SECURITY_DESCRIPTOR) too small")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
dacl *ACL
|
dacl *ACL
|
||||||
@ -1312,19 +1315,55 @@ func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DE
|
|||||||
group *SID
|
group *SID
|
||||||
)
|
)
|
||||||
if daclSize > 0 {
|
if daclSize > 0 {
|
||||||
dacl = (*ACL)(unsafe.Pointer(&make([]byte, daclSize)[0]))
|
dacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, daclSize))))
|
||||||
}
|
}
|
||||||
if saclSize > 0 {
|
if saclSize > 0 {
|
||||||
sacl = (*ACL)(unsafe.Pointer(&make([]byte, saclSize)[0]))
|
sacl = (*ACL)(unsafe.Pointer(unsafe.SliceData(make([]byte, saclSize))))
|
||||||
}
|
}
|
||||||
if ownerSize > 0 {
|
if ownerSize > 0 {
|
||||||
owner = (*SID)(unsafe.Pointer(&make([]byte, ownerSize)[0]))
|
owner = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, ownerSize))))
|
||||||
}
|
}
|
||||||
if groupSize > 0 {
|
if groupSize > 0 {
|
||||||
group = (*SID)(unsafe.Pointer(&make([]byte, groupSize)[0]))
|
group = (*SID)(unsafe.Pointer(unsafe.SliceData(make([]byte, groupSize))))
|
||||||
}
|
}
|
||||||
|
// We call into Windows via makeAbsoluteSD, which sets up
|
||||||
|
// pointers within absoluteSD that point to other chunks of memory
|
||||||
|
// we pass into makeAbsoluteSD, and that happens outside the view of the GC.
|
||||||
|
// We therefore take some care here to then verify the pointers are as we expect
|
||||||
|
// and set them explicitly in view of the GC. See https://go.dev/issue/73199.
|
||||||
|
// TODO: consider weak pointers once Go 1.24 is appropriate. See suggestion in https://go.dev/cl/663575.
|
||||||
err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize,
|
err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize,
|
||||||
dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize)
|
dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize)
|
||||||
|
if err != nil {
|
||||||
|
// Don't return absoluteSD, which might be partially initialized.
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Before using any fields, verify absoluteSD is in the format we expect according to Windows.
|
||||||
|
// See https://learn.microsoft.com/en-us/windows/win32/secauthz/absolute-and-self-relative-security-descriptors
|
||||||
|
absControl, _, err := absoluteSD.Control()
|
||||||
|
if err != nil {
|
||||||
|
panic("absoluteSD: " + err.Error())
|
||||||
|
}
|
||||||
|
if absControl&SE_SELF_RELATIVE != 0 {
|
||||||
|
panic("absoluteSD not in absolute format")
|
||||||
|
}
|
||||||
|
if absoluteSD.dacl != dacl {
|
||||||
|
panic("dacl pointer mismatch")
|
||||||
|
}
|
||||||
|
if absoluteSD.sacl != sacl {
|
||||||
|
panic("sacl pointer mismatch")
|
||||||
|
}
|
||||||
|
if absoluteSD.owner != owner {
|
||||||
|
panic("owner pointer mismatch")
|
||||||
|
}
|
||||||
|
if absoluteSD.group != group {
|
||||||
|
panic("group pointer mismatch")
|
||||||
|
}
|
||||||
|
absoluteSD.dacl = dacl
|
||||||
|
absoluteSD.sacl = sacl
|
||||||
|
absoluteSD.owner = owner
|
||||||
|
absoluteSD.group = group
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
vendor/golang.org/x/sys/windows/syscall_windows.go
generated
vendored
6
vendor/golang.org/x/sys/windows/syscall_windows.go
generated
vendored
@ -870,6 +870,7 @@ const socket_error = uintptr(^uint32(0))
|
|||||||
//sys WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom
|
//sys WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom
|
||||||
//sys WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo
|
//sys WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo
|
||||||
//sys WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, group uint32, flags uint32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.WSASocketW
|
//sys WSASocket(af int32, typ int32, protocol int32, protoInfo *WSAProtocolInfo, group uint32, flags uint32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.WSASocketW
|
||||||
|
//sys WSADuplicateSocket(s Handle, processID uint32, info *WSAProtocolInfo) (err error) [failretval!=0] = ws2_32.WSADuplicateSocketW
|
||||||
//sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname
|
//sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname
|
||||||
//sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname
|
//sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname
|
||||||
//sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
|
//sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
|
||||||
@ -1698,8 +1699,9 @@ func NewNTUnicodeString(s string) (*NTUnicodeString, error) {
|
|||||||
|
|
||||||
// Slice returns a uint16 slice that aliases the data in the NTUnicodeString.
|
// Slice returns a uint16 slice that aliases the data in the NTUnicodeString.
|
||||||
func (s *NTUnicodeString) Slice() []uint16 {
|
func (s *NTUnicodeString) Slice() []uint16 {
|
||||||
slice := unsafe.Slice(s.Buffer, s.MaximumLength)
|
// Note: this rounds the length down, if it happens
|
||||||
return slice[:s.Length]
|
// to (incorrectly) be odd. Probably safer than rounding up.
|
||||||
|
return unsafe.Slice(s.Buffer, s.MaximumLength/2)[:s.Length/2]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *NTUnicodeString) String() string {
|
func (s *NTUnicodeString) String() string {
|
||||||
|
239
vendor/golang.org/x/sys/windows/types_windows.go
generated
vendored
239
vendor/golang.org/x/sys/windows/types_windows.go
generated
vendored
@ -1074,6 +1074,7 @@ const (
|
|||||||
IP_ADD_MEMBERSHIP = 0xc
|
IP_ADD_MEMBERSHIP = 0xc
|
||||||
IP_DROP_MEMBERSHIP = 0xd
|
IP_DROP_MEMBERSHIP = 0xd
|
||||||
IP_PKTINFO = 0x13
|
IP_PKTINFO = 0x13
|
||||||
|
IP_MTU_DISCOVER = 0x47
|
||||||
|
|
||||||
IPV6_V6ONLY = 0x1b
|
IPV6_V6ONLY = 0x1b
|
||||||
IPV6_UNICAST_HOPS = 0x4
|
IPV6_UNICAST_HOPS = 0x4
|
||||||
@ -1083,6 +1084,7 @@ const (
|
|||||||
IPV6_JOIN_GROUP = 0xc
|
IPV6_JOIN_GROUP = 0xc
|
||||||
IPV6_LEAVE_GROUP = 0xd
|
IPV6_LEAVE_GROUP = 0xd
|
||||||
IPV6_PKTINFO = 0x13
|
IPV6_PKTINFO = 0x13
|
||||||
|
IPV6_MTU_DISCOVER = 0x47
|
||||||
|
|
||||||
MSG_OOB = 0x1
|
MSG_OOB = 0x1
|
||||||
MSG_PEEK = 0x2
|
MSG_PEEK = 0x2
|
||||||
@ -1132,6 +1134,15 @@ const (
|
|||||||
WSASYS_STATUS_LEN = 128
|
WSASYS_STATUS_LEN = 128
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// enum PMTUD_STATE from ws2ipdef.h
|
||||||
|
const (
|
||||||
|
IP_PMTUDISC_NOT_SET = 0
|
||||||
|
IP_PMTUDISC_DO = 1
|
||||||
|
IP_PMTUDISC_DONT = 2
|
||||||
|
IP_PMTUDISC_PROBE = 3
|
||||||
|
IP_PMTUDISC_MAX = 4
|
||||||
|
)
|
||||||
|
|
||||||
type WSABuf struct {
|
type WSABuf struct {
|
||||||
Len uint32
|
Len uint32
|
||||||
Buf *byte
|
Buf *byte
|
||||||
@ -1146,6 +1157,22 @@ type WSAMsg struct {
|
|||||||
Flags uint32
|
Flags uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WSACMSGHDR struct {
|
||||||
|
Len uintptr
|
||||||
|
Level int32
|
||||||
|
Type int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type IN_PKTINFO struct {
|
||||||
|
Addr [4]byte
|
||||||
|
Ifindex uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type IN6_PKTINFO struct {
|
||||||
|
Addr [16]byte
|
||||||
|
Ifindex uint32
|
||||||
|
}
|
||||||
|
|
||||||
// Flags for WSASocket
|
// Flags for WSASocket
|
||||||
const (
|
const (
|
||||||
WSA_FLAG_OVERLAPPED = 0x01
|
WSA_FLAG_OVERLAPPED = 0x01
|
||||||
@ -2673,6 +2700,8 @@ type CommTimeouts struct {
|
|||||||
|
|
||||||
// NTUnicodeString is a UTF-16 string for NT native APIs, corresponding to UNICODE_STRING.
|
// NTUnicodeString is a UTF-16 string for NT native APIs, corresponding to UNICODE_STRING.
|
||||||
type NTUnicodeString struct {
|
type NTUnicodeString struct {
|
||||||
|
// Note: Length and MaximumLength are in *bytes*, not uint16s.
|
||||||
|
// They should always be even.
|
||||||
Length uint16
|
Length uint16
|
||||||
MaximumLength uint16
|
MaximumLength uint16
|
||||||
Buffer *uint16
|
Buffer *uint16
|
||||||
@ -3601,3 +3630,213 @@ const (
|
|||||||
KLF_NOTELLSHELL = 0x00000080
|
KLF_NOTELLSHELL = 0x00000080
|
||||||
KLF_SETFORPROCESS = 0x00000100
|
KLF_SETFORPROCESS = 0x00000100
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Virtual Key codes
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
|
||||||
|
const (
|
||||||
|
VK_LBUTTON = 0x01
|
||||||
|
VK_RBUTTON = 0x02
|
||||||
|
VK_CANCEL = 0x03
|
||||||
|
VK_MBUTTON = 0x04
|
||||||
|
VK_XBUTTON1 = 0x05
|
||||||
|
VK_XBUTTON2 = 0x06
|
||||||
|
VK_BACK = 0x08
|
||||||
|
VK_TAB = 0x09
|
||||||
|
VK_CLEAR = 0x0C
|
||||||
|
VK_RETURN = 0x0D
|
||||||
|
VK_SHIFT = 0x10
|
||||||
|
VK_CONTROL = 0x11
|
||||||
|
VK_MENU = 0x12
|
||||||
|
VK_PAUSE = 0x13
|
||||||
|
VK_CAPITAL = 0x14
|
||||||
|
VK_KANA = 0x15
|
||||||
|
VK_HANGEUL = 0x15
|
||||||
|
VK_HANGUL = 0x15
|
||||||
|
VK_IME_ON = 0x16
|
||||||
|
VK_JUNJA = 0x17
|
||||||
|
VK_FINAL = 0x18
|
||||||
|
VK_HANJA = 0x19
|
||||||
|
VK_KANJI = 0x19
|
||||||
|
VK_IME_OFF = 0x1A
|
||||||
|
VK_ESCAPE = 0x1B
|
||||||
|
VK_CONVERT = 0x1C
|
||||||
|
VK_NONCONVERT = 0x1D
|
||||||
|
VK_ACCEPT = 0x1E
|
||||||
|
VK_MODECHANGE = 0x1F
|
||||||
|
VK_SPACE = 0x20
|
||||||
|
VK_PRIOR = 0x21
|
||||||
|
VK_NEXT = 0x22
|
||||||
|
VK_END = 0x23
|
||||||
|
VK_HOME = 0x24
|
||||||
|
VK_LEFT = 0x25
|
||||||
|
VK_UP = 0x26
|
||||||
|
VK_RIGHT = 0x27
|
||||||
|
VK_DOWN = 0x28
|
||||||
|
VK_SELECT = 0x29
|
||||||
|
VK_PRINT = 0x2A
|
||||||
|
VK_EXECUTE = 0x2B
|
||||||
|
VK_SNAPSHOT = 0x2C
|
||||||
|
VK_INSERT = 0x2D
|
||||||
|
VK_DELETE = 0x2E
|
||||||
|
VK_HELP = 0x2F
|
||||||
|
VK_LWIN = 0x5B
|
||||||
|
VK_RWIN = 0x5C
|
||||||
|
VK_APPS = 0x5D
|
||||||
|
VK_SLEEP = 0x5F
|
||||||
|
VK_NUMPAD0 = 0x60
|
||||||
|
VK_NUMPAD1 = 0x61
|
||||||
|
VK_NUMPAD2 = 0x62
|
||||||
|
VK_NUMPAD3 = 0x63
|
||||||
|
VK_NUMPAD4 = 0x64
|
||||||
|
VK_NUMPAD5 = 0x65
|
||||||
|
VK_NUMPAD6 = 0x66
|
||||||
|
VK_NUMPAD7 = 0x67
|
||||||
|
VK_NUMPAD8 = 0x68
|
||||||
|
VK_NUMPAD9 = 0x69
|
||||||
|
VK_MULTIPLY = 0x6A
|
||||||
|
VK_ADD = 0x6B
|
||||||
|
VK_SEPARATOR = 0x6C
|
||||||
|
VK_SUBTRACT = 0x6D
|
||||||
|
VK_DECIMAL = 0x6E
|
||||||
|
VK_DIVIDE = 0x6F
|
||||||
|
VK_F1 = 0x70
|
||||||
|
VK_F2 = 0x71
|
||||||
|
VK_F3 = 0x72
|
||||||
|
VK_F4 = 0x73
|
||||||
|
VK_F5 = 0x74
|
||||||
|
VK_F6 = 0x75
|
||||||
|
VK_F7 = 0x76
|
||||||
|
VK_F8 = 0x77
|
||||||
|
VK_F9 = 0x78
|
||||||
|
VK_F10 = 0x79
|
||||||
|
VK_F11 = 0x7A
|
||||||
|
VK_F12 = 0x7B
|
||||||
|
VK_F13 = 0x7C
|
||||||
|
VK_F14 = 0x7D
|
||||||
|
VK_F15 = 0x7E
|
||||||
|
VK_F16 = 0x7F
|
||||||
|
VK_F17 = 0x80
|
||||||
|
VK_F18 = 0x81
|
||||||
|
VK_F19 = 0x82
|
||||||
|
VK_F20 = 0x83
|
||||||
|
VK_F21 = 0x84
|
||||||
|
VK_F22 = 0x85
|
||||||
|
VK_F23 = 0x86
|
||||||
|
VK_F24 = 0x87
|
||||||
|
VK_NUMLOCK = 0x90
|
||||||
|
VK_SCROLL = 0x91
|
||||||
|
VK_OEM_NEC_EQUAL = 0x92
|
||||||
|
VK_OEM_FJ_JISHO = 0x92
|
||||||
|
VK_OEM_FJ_MASSHOU = 0x93
|
||||||
|
VK_OEM_FJ_TOUROKU = 0x94
|
||||||
|
VK_OEM_FJ_LOYA = 0x95
|
||||||
|
VK_OEM_FJ_ROYA = 0x96
|
||||||
|
VK_LSHIFT = 0xA0
|
||||||
|
VK_RSHIFT = 0xA1
|
||||||
|
VK_LCONTROL = 0xA2
|
||||||
|
VK_RCONTROL = 0xA3
|
||||||
|
VK_LMENU = 0xA4
|
||||||
|
VK_RMENU = 0xA5
|
||||||
|
VK_BROWSER_BACK = 0xA6
|
||||||
|
VK_BROWSER_FORWARD = 0xA7
|
||||||
|
VK_BROWSER_REFRESH = 0xA8
|
||||||
|
VK_BROWSER_STOP = 0xA9
|
||||||
|
VK_BROWSER_SEARCH = 0xAA
|
||||||
|
VK_BROWSER_FAVORITES = 0xAB
|
||||||
|
VK_BROWSER_HOME = 0xAC
|
||||||
|
VK_VOLUME_MUTE = 0xAD
|
||||||
|
VK_VOLUME_DOWN = 0xAE
|
||||||
|
VK_VOLUME_UP = 0xAF
|
||||||
|
VK_MEDIA_NEXT_TRACK = 0xB0
|
||||||
|
VK_MEDIA_PREV_TRACK = 0xB1
|
||||||
|
VK_MEDIA_STOP = 0xB2
|
||||||
|
VK_MEDIA_PLAY_PAUSE = 0xB3
|
||||||
|
VK_LAUNCH_MAIL = 0xB4
|
||||||
|
VK_LAUNCH_MEDIA_SELECT = 0xB5
|
||||||
|
VK_LAUNCH_APP1 = 0xB6
|
||||||
|
VK_LAUNCH_APP2 = 0xB7
|
||||||
|
VK_OEM_1 = 0xBA
|
||||||
|
VK_OEM_PLUS = 0xBB
|
||||||
|
VK_OEM_COMMA = 0xBC
|
||||||
|
VK_OEM_MINUS = 0xBD
|
||||||
|
VK_OEM_PERIOD = 0xBE
|
||||||
|
VK_OEM_2 = 0xBF
|
||||||
|
VK_OEM_3 = 0xC0
|
||||||
|
VK_OEM_4 = 0xDB
|
||||||
|
VK_OEM_5 = 0xDC
|
||||||
|
VK_OEM_6 = 0xDD
|
||||||
|
VK_OEM_7 = 0xDE
|
||||||
|
VK_OEM_8 = 0xDF
|
||||||
|
VK_OEM_AX = 0xE1
|
||||||
|
VK_OEM_102 = 0xE2
|
||||||
|
VK_ICO_HELP = 0xE3
|
||||||
|
VK_ICO_00 = 0xE4
|
||||||
|
VK_PROCESSKEY = 0xE5
|
||||||
|
VK_ICO_CLEAR = 0xE6
|
||||||
|
VK_OEM_RESET = 0xE9
|
||||||
|
VK_OEM_JUMP = 0xEA
|
||||||
|
VK_OEM_PA1 = 0xEB
|
||||||
|
VK_OEM_PA2 = 0xEC
|
||||||
|
VK_OEM_PA3 = 0xED
|
||||||
|
VK_OEM_WSCTRL = 0xEE
|
||||||
|
VK_OEM_CUSEL = 0xEF
|
||||||
|
VK_OEM_ATTN = 0xF0
|
||||||
|
VK_OEM_FINISH = 0xF1
|
||||||
|
VK_OEM_COPY = 0xF2
|
||||||
|
VK_OEM_AUTO = 0xF3
|
||||||
|
VK_OEM_ENLW = 0xF4
|
||||||
|
VK_OEM_BACKTAB = 0xF5
|
||||||
|
VK_ATTN = 0xF6
|
||||||
|
VK_CRSEL = 0xF7
|
||||||
|
VK_EXSEL = 0xF8
|
||||||
|
VK_EREOF = 0xF9
|
||||||
|
VK_PLAY = 0xFA
|
||||||
|
VK_ZOOM = 0xFB
|
||||||
|
VK_NONAME = 0xFC
|
||||||
|
VK_PA1 = 0xFD
|
||||||
|
VK_OEM_CLEAR = 0xFE
|
||||||
|
)
|
||||||
|
|
||||||
|
// Mouse button constants.
|
||||||
|
// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str
|
||||||
|
const (
|
||||||
|
FROM_LEFT_1ST_BUTTON_PRESSED = 0x0001
|
||||||
|
RIGHTMOST_BUTTON_PRESSED = 0x0002
|
||||||
|
FROM_LEFT_2ND_BUTTON_PRESSED = 0x0004
|
||||||
|
FROM_LEFT_3RD_BUTTON_PRESSED = 0x0008
|
||||||
|
FROM_LEFT_4TH_BUTTON_PRESSED = 0x0010
|
||||||
|
)
|
||||||
|
|
||||||
|
// Control key state constaints.
|
||||||
|
// https://docs.microsoft.com/en-us/windows/console/key-event-record-str
|
||||||
|
// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str
|
||||||
|
const (
|
||||||
|
CAPSLOCK_ON = 0x0080
|
||||||
|
ENHANCED_KEY = 0x0100
|
||||||
|
LEFT_ALT_PRESSED = 0x0002
|
||||||
|
LEFT_CTRL_PRESSED = 0x0008
|
||||||
|
NUMLOCK_ON = 0x0020
|
||||||
|
RIGHT_ALT_PRESSED = 0x0001
|
||||||
|
RIGHT_CTRL_PRESSED = 0x0004
|
||||||
|
SCROLLLOCK_ON = 0x0040
|
||||||
|
SHIFT_PRESSED = 0x0010
|
||||||
|
)
|
||||||
|
|
||||||
|
// Mouse event record event flags.
|
||||||
|
// https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str
|
||||||
|
const (
|
||||||
|
MOUSE_MOVED = 0x0001
|
||||||
|
DOUBLE_CLICK = 0x0002
|
||||||
|
MOUSE_WHEELED = 0x0004
|
||||||
|
MOUSE_HWHEELED = 0x0008
|
||||||
|
)
|
||||||
|
|
||||||
|
// Input Record Event Types
|
||||||
|
// https://learn.microsoft.com/en-us/windows/console/input-record-str
|
||||||
|
const (
|
||||||
|
FOCUS_EVENT = 0x0010
|
||||||
|
KEY_EVENT = 0x0001
|
||||||
|
MENU_EVENT = 0x0008
|
||||||
|
MOUSE_EVENT = 0x0002
|
||||||
|
WINDOW_BUFFER_SIZE_EVENT = 0x0004
|
||||||
|
)
|
||||||
|
9
vendor/golang.org/x/sys/windows/zsyscall_windows.go
generated
vendored
9
vendor/golang.org/x/sys/windows/zsyscall_windows.go
generated
vendored
@ -511,6 +511,7 @@ var (
|
|||||||
procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW")
|
procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW")
|
||||||
procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW")
|
procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW")
|
||||||
procWSACleanup = modws2_32.NewProc("WSACleanup")
|
procWSACleanup = modws2_32.NewProc("WSACleanup")
|
||||||
|
procWSADuplicateSocketW = modws2_32.NewProc("WSADuplicateSocketW")
|
||||||
procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW")
|
procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW")
|
||||||
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
|
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
|
||||||
procWSAIoctl = modws2_32.NewProc("WSAIoctl")
|
procWSAIoctl = modws2_32.NewProc("WSAIoctl")
|
||||||
@ -4391,6 +4392,14 @@ func WSACleanup() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WSADuplicateSocket(s Handle, processID uint32, info *WSAProtocolInfo) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procWSADuplicateSocketW.Addr(), 3, uintptr(s), uintptr(processID), uintptr(unsafe.Pointer(info)))
|
||||||
|
if r1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) {
|
func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) {
|
||||||
r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength)))
|
r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength)))
|
||||||
n = int32(r0)
|
n = int32(r0)
|
||||||
|
77
vendor/golang.org/x/term/terminal.go
generated
vendored
77
vendor/golang.org/x/term/terminal.go
generated
vendored
@ -6,6 +6,7 @@ package term
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -36,6 +37,26 @@ var vt100EscapeCodes = EscapeCodes{
|
|||||||
Reset: []byte{keyEscape, '[', '0', 'm'},
|
Reset: []byte{keyEscape, '[', '0', 'm'},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A History provides a (possibly bounded) queue of input lines read by [Terminal.ReadLine].
|
||||||
|
type History interface {
|
||||||
|
// Add will be called by [Terminal.ReadLine] to add
|
||||||
|
// a new, most recent entry to the history.
|
||||||
|
// It is allowed to drop any entry, including
|
||||||
|
// the entry being added (e.g., if it's deemed an invalid entry),
|
||||||
|
// the least-recent entry (e.g., to keep the history bounded),
|
||||||
|
// or any other entry.
|
||||||
|
Add(entry string)
|
||||||
|
|
||||||
|
// Len returns the number of entries in the history.
|
||||||
|
Len() int
|
||||||
|
|
||||||
|
// At returns an entry from the history.
|
||||||
|
// Index 0 is the most-recently added entry and
|
||||||
|
// index Len()-1 is the least-recently added entry.
|
||||||
|
// If index is < 0 or >= Len(), it panics.
|
||||||
|
At(idx int) string
|
||||||
|
}
|
||||||
|
|
||||||
// Terminal contains the state for running a VT100 terminal that is capable of
|
// Terminal contains the state for running a VT100 terminal that is capable of
|
||||||
// reading lines of input.
|
// reading lines of input.
|
||||||
type Terminal struct {
|
type Terminal struct {
|
||||||
@ -44,6 +65,8 @@ type Terminal struct {
|
|||||||
// bytes, as an index into |line|). If it returns ok=false, the key
|
// bytes, as an index into |line|). If it returns ok=false, the key
|
||||||
// press is processed normally. Otherwise it returns a replacement line
|
// press is processed normally. Otherwise it returns a replacement line
|
||||||
// and the new cursor position.
|
// and the new cursor position.
|
||||||
|
//
|
||||||
|
// This will be disabled during ReadPassword.
|
||||||
AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool)
|
AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool)
|
||||||
|
|
||||||
// Escape contains a pointer to the escape codes for this terminal.
|
// Escape contains a pointer to the escape codes for this terminal.
|
||||||
@ -84,9 +107,14 @@ type Terminal struct {
|
|||||||
remainder []byte
|
remainder []byte
|
||||||
inBuf [256]byte
|
inBuf [256]byte
|
||||||
|
|
||||||
// history contains previously entered commands so that they can be
|
// History records and retrieves lines of input read by [ReadLine] which
|
||||||
// accessed with the up and down keys.
|
// a user can retrieve and navigate using the up and down arrow keys.
|
||||||
history stRingBuffer
|
//
|
||||||
|
// It is not safe to call ReadLine concurrently with any methods on History.
|
||||||
|
//
|
||||||
|
// [NewTerminal] sets this to a default implementation that records the
|
||||||
|
// last 100 lines of input.
|
||||||
|
History History
|
||||||
// historyIndex stores the currently accessed history entry, where zero
|
// historyIndex stores the currently accessed history entry, where zero
|
||||||
// means the immediately previous entry.
|
// means the immediately previous entry.
|
||||||
historyIndex int
|
historyIndex int
|
||||||
@ -109,6 +137,7 @@ func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
|
|||||||
termHeight: 24,
|
termHeight: 24,
|
||||||
echo: true,
|
echo: true,
|
||||||
historyIndex: -1,
|
historyIndex: -1,
|
||||||
|
History: &stRingBuffer{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,6 +477,23 @@ func visualLength(runes []rune) int {
|
|||||||
return length
|
return length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// histroryAt unlocks the terminal and relocks it while calling History.At.
|
||||||
|
func (t *Terminal) historyAt(idx int) (string, bool) {
|
||||||
|
t.lock.Unlock() // Unlock to avoid deadlock if History methods use the output writer.
|
||||||
|
defer t.lock.Lock() // panic in At (or Len) protection.
|
||||||
|
if idx < 0 || idx >= t.History.Len() {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
return t.History.At(idx), true
|
||||||
|
}
|
||||||
|
|
||||||
|
// historyAdd unlocks the terminal and relocks it while calling History.Add.
|
||||||
|
func (t *Terminal) historyAdd(entry string) {
|
||||||
|
t.lock.Unlock() // Unlock to avoid deadlock if History methods use the output writer.
|
||||||
|
defer t.lock.Lock() // panic in Add protection.
|
||||||
|
t.History.Add(entry)
|
||||||
|
}
|
||||||
|
|
||||||
// handleKey processes the given key and, optionally, returns a line of text
|
// handleKey processes the given key and, optionally, returns a line of text
|
||||||
// that the user has entered.
|
// that the user has entered.
|
||||||
func (t *Terminal) handleKey(key rune) (line string, ok bool) {
|
func (t *Terminal) handleKey(key rune) (line string, ok bool) {
|
||||||
@ -495,7 +541,7 @@ func (t *Terminal) handleKey(key rune) (line string, ok bool) {
|
|||||||
t.pos = len(t.line)
|
t.pos = len(t.line)
|
||||||
t.moveCursorToPos(t.pos)
|
t.moveCursorToPos(t.pos)
|
||||||
case keyUp:
|
case keyUp:
|
||||||
entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1)
|
entry, ok := t.historyAt(t.historyIndex + 1)
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
@ -514,7 +560,7 @@ func (t *Terminal) handleKey(key rune) (line string, ok bool) {
|
|||||||
t.setLine(runes, len(runes))
|
t.setLine(runes, len(runes))
|
||||||
t.historyIndex--
|
t.historyIndex--
|
||||||
default:
|
default:
|
||||||
entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1)
|
entry, ok := t.historyAt(t.historyIndex - 1)
|
||||||
if ok {
|
if ok {
|
||||||
t.historyIndex--
|
t.historyIndex--
|
||||||
runes := []rune(entry)
|
runes := []rune(entry)
|
||||||
@ -692,6 +738,8 @@ func (t *Terminal) Write(buf []byte) (n int, err error) {
|
|||||||
|
|
||||||
// ReadPassword temporarily changes the prompt and reads a password, without
|
// ReadPassword temporarily changes the prompt and reads a password, without
|
||||||
// echo, from the terminal.
|
// echo, from the terminal.
|
||||||
|
//
|
||||||
|
// The AutoCompleteCallback is disabled during this call.
|
||||||
func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
|
func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
|
||||||
t.lock.Lock()
|
t.lock.Lock()
|
||||||
defer t.lock.Unlock()
|
defer t.lock.Unlock()
|
||||||
@ -699,6 +747,11 @@ func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
|
|||||||
oldPrompt := t.prompt
|
oldPrompt := t.prompt
|
||||||
t.prompt = []rune(prompt)
|
t.prompt = []rune(prompt)
|
||||||
t.echo = false
|
t.echo = false
|
||||||
|
oldAutoCompleteCallback := t.AutoCompleteCallback
|
||||||
|
t.AutoCompleteCallback = nil
|
||||||
|
defer func() {
|
||||||
|
t.AutoCompleteCallback = oldAutoCompleteCallback
|
||||||
|
}()
|
||||||
|
|
||||||
line, err = t.readLine()
|
line, err = t.readLine()
|
||||||
|
|
||||||
@ -772,7 +825,7 @@ func (t *Terminal) readLine() (line string, err error) {
|
|||||||
if lineOk {
|
if lineOk {
|
||||||
if t.echo {
|
if t.echo {
|
||||||
t.historyIndex = -1
|
t.historyIndex = -1
|
||||||
t.history.Add(line)
|
t.historyAdd(line)
|
||||||
}
|
}
|
||||||
if lineIsPasted {
|
if lineIsPasted {
|
||||||
err = ErrPasteIndicator
|
err = ErrPasteIndicator
|
||||||
@ -929,19 +982,23 @@ func (s *stRingBuffer) Add(a string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NthPreviousEntry returns the value passed to the nth previous call to Add.
|
func (s *stRingBuffer) Len() int {
|
||||||
|
return s.size
|
||||||
|
}
|
||||||
|
|
||||||
|
// At returns the value passed to the nth previous call to Add.
|
||||||
// If n is zero then the immediately prior value is returned, if one, then the
|
// If n is zero then the immediately prior value is returned, if one, then the
|
||||||
// next most recent, and so on. If such an element doesn't exist then ok is
|
// next most recent, and so on. If such an element doesn't exist then ok is
|
||||||
// false.
|
// false.
|
||||||
func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
|
func (s *stRingBuffer) At(n int) string {
|
||||||
if n < 0 || n >= s.size {
|
if n < 0 || n >= s.size {
|
||||||
return "", false
|
panic(fmt.Sprintf("term: history index [%d] out of range [0,%d)", n, s.size))
|
||||||
}
|
}
|
||||||
index := s.head - n
|
index := s.head - n
|
||||||
if index < 0 {
|
if index < 0 {
|
||||||
index += s.max
|
index += s.max
|
||||||
}
|
}
|
||||||
return s.entries[index], true
|
return s.entries[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
// readPasswordLine reads from reader until it finds \n or io.EOF.
|
// readPasswordLine reads from reader until it finds \n or io.EOF.
|
||||||
|
2
vendor/golang.org/x/text/language/parse.go
generated
vendored
2
vendor/golang.org/x/text/language/parse.go
generated
vendored
@ -59,7 +59,7 @@ func (c CanonType) Parse(s string) (t Tag, err error) {
|
|||||||
if changed {
|
if changed {
|
||||||
tt.RemakeString()
|
tt.RemakeString()
|
||||||
}
|
}
|
||||||
return makeTag(tt), err
|
return makeTag(tt), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compose creates a Tag from individual parts, which may be of type Tag, Base,
|
// Compose creates a Tag from individual parts, which may be of type Tag, Base,
|
||||||
|
22
vendor/modules.txt
vendored
22
vendor/modules.txt
vendored
@ -10,7 +10,7 @@ github.com/GehirnInc/crypt/md5_crypt
|
|||||||
# github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
|
# github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
|
||||||
## explicit
|
## explicit
|
||||||
github.com/docopt/docopt-go
|
github.com/docopt/docopt-go
|
||||||
# github.com/emersion/go-msgauth v0.6.8
|
# github.com/emersion/go-msgauth v0.7.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
github.com/emersion/go-msgauth/dkim
|
github.com/emersion/go-msgauth/dkim
|
||||||
# github.com/ergochat/confusables v0.0.0-20201108231250-4ab98ab61fb1
|
# github.com/ergochat/confusables v0.0.0-20201108231250-4ab98ab61fb1
|
||||||
@ -31,8 +31,6 @@ github.com/ergochat/webpush-go/v2
|
|||||||
# github.com/go-sql-driver/mysql v1.7.0
|
# github.com/go-sql-driver/mysql v1.7.0
|
||||||
## explicit; go 1.13
|
## explicit; go 1.13
|
||||||
github.com/go-sql-driver/mysql
|
github.com/go-sql-driver/mysql
|
||||||
# github.com/go-test/deep v1.0.6
|
|
||||||
## explicit; go 1.13
|
|
||||||
# github.com/gofrs/flock v0.8.1
|
# github.com/gofrs/flock v0.8.1
|
||||||
## explicit
|
## explicit
|
||||||
github.com/gofrs/flock
|
github.com/gofrs/flock
|
||||||
@ -76,31 +74,29 @@ github.com/tidwall/rtred/base
|
|||||||
# github.com/tidwall/tinyqueue v0.1.1
|
# github.com/tidwall/tinyqueue v0.1.1
|
||||||
## explicit; go 1.15
|
## explicit; go 1.15
|
||||||
github.com/tidwall/tinyqueue
|
github.com/tidwall/tinyqueue
|
||||||
# github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208
|
|
||||||
## explicit
|
|
||||||
# github.com/xdg-go/pbkdf2 v1.0.0
|
# github.com/xdg-go/pbkdf2 v1.0.0
|
||||||
## explicit; go 1.9
|
## explicit; go 1.9
|
||||||
github.com/xdg-go/pbkdf2
|
github.com/xdg-go/pbkdf2
|
||||||
# github.com/xdg-go/scram v1.0.2 => github.com/ergochat/scram v1.0.2-ergo1
|
# github.com/xdg-go/scram v1.0.2 => github.com/ergochat/scram v1.0.2-ergo1
|
||||||
## explicit; go 1.11
|
## explicit; go 1.11
|
||||||
github.com/xdg-go/scram
|
github.com/xdg-go/scram
|
||||||
# golang.org/x/crypto v0.32.0
|
# golang.org/x/crypto v0.38.0
|
||||||
## explicit; go 1.20
|
## explicit; go 1.23.0
|
||||||
golang.org/x/crypto/bcrypt
|
golang.org/x/crypto/bcrypt
|
||||||
golang.org/x/crypto/blowfish
|
golang.org/x/crypto/blowfish
|
||||||
golang.org/x/crypto/ed25519
|
golang.org/x/crypto/ed25519
|
||||||
golang.org/x/crypto/hkdf
|
golang.org/x/crypto/hkdf
|
||||||
golang.org/x/crypto/pbkdf2
|
golang.org/x/crypto/pbkdf2
|
||||||
# golang.org/x/sys v0.29.0
|
# golang.org/x/sys v0.33.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.23.0
|
||||||
golang.org/x/sys/plan9
|
golang.org/x/sys/plan9
|
||||||
golang.org/x/sys/unix
|
golang.org/x/sys/unix
|
||||||
golang.org/x/sys/windows
|
golang.org/x/sys/windows
|
||||||
# golang.org/x/term v0.28.0
|
# golang.org/x/term v0.32.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.23.0
|
||||||
golang.org/x/term
|
golang.org/x/term
|
||||||
# golang.org/x/text v0.21.0
|
# golang.org/x/text v0.25.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.23.0
|
||||||
golang.org/x/text/cases
|
golang.org/x/text/cases
|
||||||
golang.org/x/text/internal
|
golang.org/x/text/internal
|
||||||
golang.org/x/text/internal/language
|
golang.org/x/text/internal/language
|
||||||
|
Loading…
x
Reference in New Issue
Block a user