forked from External/ergo
Compare commits
31 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfb027b647 | ||
|
|
3b0fecd381 | ||
|
|
d73b6bac86 | ||
| d26235e9a9 | |||
|
|
711af30aa8 | ||
|
|
1bdc45ebb4 | ||
|
|
eddd4cc723 | ||
|
|
726d997d07 | ||
|
|
9577e87d9a | ||
|
|
7586520032 | ||
|
|
f68d32b4ee | ||
|
|
f4c03b6765 | ||
|
|
796bc198ed | ||
|
|
64ebb1f480 | ||
|
|
f9a0be2473 | ||
|
|
df6aa4c34b | ||
|
|
a529158fe1 | ||
|
|
f80854e95a | ||
|
|
e5bf5bee6f | ||
|
|
13e1315ad9 | ||
|
|
979188cf2a | ||
| 60172a0be4 | |||
| ca62b268b0 | |||
|
|
30f47a9b22 | ||
|
|
92a23229f8 | ||
|
|
825b4298b8 | ||
|
|
eba6d532ea | ||
|
|
7d3971835e | ||
|
|
99393d49bf | ||
|
|
82c50cc497 | ||
|
|
ce41f501c9 |
159 changed files with 10969 additions and 5109 deletions
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
|
@ -19,7 +19,7 @@ jobs:
|
||||||
- name: "setup go"
|
- name: "setup go"
|
||||||
uses: "actions/setup-go@v3"
|
uses: "actions/setup-go@v3"
|
||||||
with:
|
with:
|
||||||
go-version: "1.22"
|
go-version: "1.23"
|
||||||
- name: "install python3-pytest"
|
- name: "install python3-pytest"
|
||||||
run: "sudo apt install -y python3-pytest"
|
run: "sudo apt install -y python3-pytest"
|
||||||
- name: "make install"
|
- name: "make install"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
# .goreleaser.yml
|
# .goreleaser.yml
|
||||||
# Build customization
|
# Build customization
|
||||||
|
version: 2
|
||||||
project_name: ergo
|
project_name: ergo
|
||||||
builds:
|
builds:
|
||||||
- main: ergo.go
|
- main: ergo.go
|
||||||
|
|
@ -54,11 +55,12 @@ builds:
|
||||||
|
|
||||||
archives:
|
archives:
|
||||||
-
|
-
|
||||||
name_template: "{{ .ProjectName }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
|
name_template: >-
|
||||||
|
{{ .ProjectName }}-{{ .Version }}-
|
||||||
|
{{- if eq .Os "darwin" }}macos{{- else }}{{ .Os }}{{ end -}}-
|
||||||
|
{{- if eq .Arch "amd64" }}x86_64{{- else }}{{ .Arch }}{{ end -}}
|
||||||
|
{{ if .Arm }}v{{ .Arm }}{{ end -}}
|
||||||
format: tar.gz
|
format: tar.gz
|
||||||
replacements:
|
|
||||||
amd64: x86_64
|
|
||||||
darwin: macos
|
|
||||||
format_overrides:
|
format_overrides:
|
||||||
- goos: windows
|
- goos: windows
|
||||||
format: zip
|
format: zip
|
||||||
|
|
|
||||||
18
Dockerfile
18
Dockerfile
|
|
@ -1,7 +1,8 @@
|
||||||
## build ergo binary
|
## build ergo binary
|
||||||
FROM docker.io/golang:1.22-alpine AS build-env
|
FROM docker.io/golang:1.23-alpine AS build-env
|
||||||
|
|
||||||
RUN apk upgrade -U --force-refresh --no-cache && apk add --no-cache --purge --clean-protected -l -u make git
|
RUN apk upgrade -U --force-refresh --no-cache
|
||||||
|
RUN apk add --no-cache --purge --clean-protected -l -u make git
|
||||||
|
|
||||||
# copy ergo source
|
# copy ergo source
|
||||||
WORKDIR /go/src/github.com/ergochat/ergo
|
WORKDIR /go/src/github.com/ergochat/ergo
|
||||||
|
|
@ -18,13 +19,6 @@ RUN make install
|
||||||
## build ergo container
|
## build ergo container
|
||||||
FROM docker.io/alpine:3.19
|
FROM docker.io/alpine:3.19
|
||||||
|
|
||||||
# metadata
|
|
||||||
LABEL maintainer="Daniel Oaks <daniel@danieloaks.net>,Daniel Thamdrup <dallemon@protonmail.com>" \
|
|
||||||
description="Ergo is a modern, experimental IRC server written in Go"
|
|
||||||
|
|
||||||
# standard ports listened on
|
|
||||||
EXPOSE 6667/tcp 6697/tcp
|
|
||||||
|
|
||||||
# ergo itself
|
# ergo itself
|
||||||
COPY --from=build-env /go/bin/ergo \
|
COPY --from=build-env /go/bin/ergo \
|
||||||
/go/src/github.com/ergochat/ergo/default.yaml \
|
/go/src/github.com/ergochat/ergo/default.yaml \
|
||||||
|
|
@ -39,10 +33,4 @@ WORKDIR /ircd
|
||||||
# default motd
|
# default motd
|
||||||
COPY --from=build-env /go/src/github.com/ergochat/ergo/ergo.motd /ircd/ergo.motd
|
COPY --from=build-env /go/src/github.com/ergochat/ergo/ergo.motd /ircd/ergo.motd
|
||||||
|
|
||||||
# launch
|
|
||||||
ENTRYPOINT ["/ircd-bin/run.sh"]
|
ENTRYPOINT ["/ircd-bin/run.sh"]
|
||||||
|
|
||||||
# # uncomment to debug
|
|
||||||
# RUN apk add --no-cache bash
|
|
||||||
# RUN apk add --no-cache vim
|
|
||||||
# CMD /bin/bash
|
|
||||||
|
|
|
||||||
6
Makefile
6
Makefile
|
|
@ -12,13 +12,13 @@ capdef_file = ./irc/caps/defs.go
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
install:
|
install:
|
||||||
go install -v -ldflags "-X main.commit=$(GIT_COMMIT) -X main.version=$(GIT_TAG)"
|
go install -mod=mod -v -ldflags "-X main.commit=$(GIT_COMMIT) -X main.version=$(GIT_TAG)"
|
||||||
|
|
||||||
build:
|
build:
|
||||||
go build -v -ldflags "-X main.commit=$(GIT_COMMIT) -X main.version=$(GIT_TAG)"
|
go build -mod=mod -v -ldflags "-X main.commit=$(GIT_COMMIT) -X main.version=$(GIT_TAG)"
|
||||||
|
|
||||||
release:
|
release:
|
||||||
goreleaser --skip-publish --rm-dist
|
goreleaser --skip=publish --clean
|
||||||
|
|
||||||
capdefs:
|
capdefs:
|
||||||
python3 ./gencapdefs.py > ${capdef_file}
|
python3 ./gencapdefs.py > ${capdef_file}
|
||||||
|
|
|
||||||
10
default.yaml
10
default.yaml
|
|
@ -369,7 +369,7 @@ server:
|
||||||
# in a "closed-loop" system where you control the server and all the clients,
|
# in a "closed-loop" system where you control the server and all the clients,
|
||||||
# you may want to increase the maximum (non-tag) length of an IRC line from
|
# you may want to increase the maximum (non-tag) length of an IRC line from
|
||||||
# the default value of 512. DO NOT change this on a public server:
|
# the default value of 512. DO NOT change this on a public server:
|
||||||
#max-line-len: 512
|
max-line-len: 2048
|
||||||
|
|
||||||
# send all 0's as the LUSERS (user counts) output to non-operators; potentially useful
|
# send all 0's as the LUSERS (user counts) output to non-operators; potentially useful
|
||||||
# if you don't want to publicize how popular the server is
|
# if you don't want to publicize how popular the server is
|
||||||
|
|
@ -820,7 +820,7 @@ lock-file: "ircd.lock"
|
||||||
|
|
||||||
# datastore configuration
|
# datastore configuration
|
||||||
datastore:
|
datastore:
|
||||||
# path to the datastore
|
# path to the database file (used to store account and channel registrations):
|
||||||
path: ircd.db
|
path: ircd.db
|
||||||
|
|
||||||
# if the database schema requires an upgrade, `autoupgrade` will attempt to
|
# if the database schema requires an upgrade, `autoupgrade` will attempt to
|
||||||
|
|
@ -1067,3 +1067,9 @@ history:
|
||||||
# whether to allow customization of the config at runtime using environment variables,
|
# whether to allow customization of the config at runtime using environment variables,
|
||||||
# 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
|
||||||
|
|
||||||
|
cef:
|
||||||
|
imagor:
|
||||||
|
url: "https://example.com/embed/"
|
||||||
|
secret: "secretgoeshere"
|
||||||
|
redis: "redis://user:password@localhost:6379/0?protocol=3"
|
||||||
|
|
@ -219,6 +219,12 @@ CAPDEFS = [
|
||||||
url="https://github.com/ircv3/ircv3-specifications/pull/527",
|
url="https://github.com/ircv3/ircv3-specifications/pull/527",
|
||||||
standard="proposed IRCv3",
|
standard="proposed IRCv3",
|
||||||
),
|
),
|
||||||
|
CapDef(
|
||||||
|
identifier="ExtendedISupport",
|
||||||
|
name="draft/extended-isupport",
|
||||||
|
url="https://github.com/ircv3/ircv3-specifications/pull/543",
|
||||||
|
standard="proposed IRCv3",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
def validate_defs():
|
def validate_defs():
|
||||||
|
|
|
||||||
23
go.mod
23
go.mod
|
|
@ -1,6 +1,6 @@
|
||||||
module github.com/ergochat/ergo
|
module github.com/ergochat/ergo
|
||||||
|
|
||||||
go 1.22
|
go 1.23
|
||||||
|
|
||||||
require (
|
require (
|
||||||
code.cloudfoundry.org/bytefmt v0.0.0-20200131002437-cf55d5288a48
|
code.cloudfoundry.org/bytefmt v0.0.0-20200131002437-cf55d5288a48
|
||||||
|
|
@ -8,7 +8,7 @@ require (
|
||||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
|
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
|
||||||
github.com/ergochat/confusables v0.0.0-20201108231250-4ab98ab61fb1
|
github.com/ergochat/confusables v0.0.0-20201108231250-4ab98ab61fb1
|
||||||
github.com/ergochat/go-ident v0.0.0-20230911071154-8c30606d6881
|
github.com/ergochat/go-ident v0.0.0-20230911071154-8c30606d6881
|
||||||
github.com/ergochat/irc-go v0.5.0-rc1
|
github.com/ergochat/irc-go v0.5.0-rc2
|
||||||
github.com/go-sql-driver/mysql v1.7.0
|
github.com/go-sql-driver/mysql v1.7.0
|
||||||
github.com/go-test/deep v1.0.6 // indirect
|
github.com/go-test/deep v1.0.6 // indirect
|
||||||
github.com/gofrs/flock v0.8.1
|
github.com/gofrs/flock v0.8.1
|
||||||
|
|
@ -16,19 +16,24 @@ require (
|
||||||
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd
|
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd
|
||||||
github.com/onsi/ginkgo v1.12.0 // indirect
|
github.com/onsi/ginkgo v1.12.0 // indirect
|
||||||
github.com/onsi/gomega v1.9.0 // indirect
|
github.com/onsi/gomega v1.9.0 // indirect
|
||||||
github.com/stretchr/testify v1.4.0 // indirect
|
github.com/tidwall/buntdb v1.3.1
|
||||||
github.com/tidwall/buntdb v1.2.10
|
|
||||||
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208
|
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208
|
||||||
github.com/xdg-go/scram v1.0.2
|
github.com/xdg-go/scram v1.0.2
|
||||||
golang.org/x/crypto v0.17.0
|
golang.org/x/crypto v0.25.0
|
||||||
golang.org/x/term v0.15.0
|
golang.org/x/term v0.22.0
|
||||||
golang.org/x/text v0.14.0
|
golang.org/x/text v0.16.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require github.com/golang-jwt/jwt/v5 v5.2.0
|
require (
|
||||||
|
github.com/cshum/imagor v1.4.13
|
||||||
|
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||||
|
github.com/redis/go-redis/v9 v9.6.1
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/tidwall/btree v1.4.2 // indirect
|
github.com/tidwall/btree v1.4.2 // indirect
|
||||||
github.com/tidwall/gjson v1.14.3 // indirect
|
github.com/tidwall/gjson v1.14.3 // indirect
|
||||||
github.com/tidwall/grect v0.1.4 // indirect
|
github.com/tidwall/grect v0.1.4 // indirect
|
||||||
|
|
@ -37,7 +42,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.15.0 // indirect
|
golang.org/x/sys v0.22.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
|
||||||
|
|
|
||||||
56
go.sum
56
go.sum
|
|
@ -2,18 +2,28 @@ code.cloudfoundry.org/bytefmt v0.0.0-20200131002437-cf55d5288a48 h1:/EMHruHCFXR9
|
||||||
code.cloudfoundry.org/bytefmt v0.0.0-20200131002437-cf55d5288a48/go.mod h1:wN/zk7mhREp/oviagqUXY3EwuHhWyOvAdsn5Y4CzOrc=
|
code.cloudfoundry.org/bytefmt v0.0.0-20200131002437-cf55d5288a48/go.mod h1:wN/zk7mhREp/oviagqUXY3EwuHhWyOvAdsn5Y4CzOrc=
|
||||||
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 h1:KeNholpO2xKjgaaSyd+DyQRrsQjhbSeS7qe4nEw8aQw=
|
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 h1:KeNholpO2xKjgaaSyd+DyQRrsQjhbSeS7qe4nEw8aQw=
|
||||||
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962/go.mod h1:kC29dT1vFpj7py2OvG1khBdQpo3kInWP+6QipLbdngo=
|
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962/go.mod h1:kC29dT1vFpj7py2OvG1khBdQpo3kInWP+6QipLbdngo=
|
||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||||
|
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||||
|
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/cshum/imagor v1.4.13 h1:BFcSpsTUOJj+Wv5SzDeXa8bhsT/Ehw7EcrFD0UTdpmU=
|
||||||
|
github.com/cshum/imagor v1.4.13/go.mod h1:LHxXgks6Y06GzEHitnlO8vcD5gznxIHWPdvGsnlGpMo=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ=
|
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ=
|
||||||
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/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=
|
||||||
github.com/ergochat/go-ident v0.0.0-20230911071154-8c30606d6881/go.mod h1:ASYJtQujNitna6cVHsNQTGrfWvMPJ5Sa2lZlmsH65uM=
|
github.com/ergochat/go-ident v0.0.0-20230911071154-8c30606d6881/go.mod h1:ASYJtQujNitna6cVHsNQTGrfWvMPJ5Sa2lZlmsH65uM=
|
||||||
github.com/ergochat/irc-go v0.4.0 h1:0YibCKfAAtwxQdNjLQd9xpIEPisLcJ45f8FNsMHAuZc=
|
|
||||||
github.com/ergochat/irc-go v0.4.0/go.mod h1:2vi7KNpIPWnReB5hmLpl92eMywQvuIeIIGdt/FQCph0=
|
|
||||||
github.com/ergochat/irc-go v0.5.0-rc1 h1:kFoIHExoNFQ2CV+iShAVna/H4xrXQB4t4jK5Sep2j9k=
|
github.com/ergochat/irc-go v0.5.0-rc1 h1:kFoIHExoNFQ2CV+iShAVna/H4xrXQB4t4jK5Sep2j9k=
|
||||||
github.com/ergochat/irc-go v0.5.0-rc1/go.mod h1:2vi7KNpIPWnReB5hmLpl92eMywQvuIeIIGdt/FQCph0=
|
github.com/ergochat/irc-go v0.5.0-rc1/go.mod h1:2vi7KNpIPWnReB5hmLpl92eMywQvuIeIIGdt/FQCph0=
|
||||||
|
github.com/ergochat/irc-go v0.5.0-rc2 h1:VuSQJF5K4hWvYSzGa4b8vgL6kzw8HF6LSOejE+RWpAo=
|
||||||
|
github.com/ergochat/irc-go v0.5.0-rc2/go.mod h1:2vi7KNpIPWnReB5hmLpl92eMywQvuIeIIGdt/FQCph0=
|
||||||
github.com/ergochat/scram v1.0.2-ergo1 h1:2bYXiRFQH636pT0msOG39fmEYl4Eq+OuutcyDsCix/g=
|
github.com/ergochat/scram v1.0.2-ergo1 h1:2bYXiRFQH636pT0msOG39fmEYl4Eq+OuutcyDsCix/g=
|
||||||
github.com/ergochat/scram v1.0.2-ergo1/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
github.com/ergochat/scram v1.0.2-ergo1/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
||||||
github.com/ergochat/websocket v1.4.2-oragono1 h1:plMUunFBM6UoSCIYCKKclTdy/TkkHfUslhOfJQzfueM=
|
github.com/ergochat/websocket v1.4.2-oragono1 h1:plMUunFBM6UoSCIYCKKclTdy/TkkHfUslhOfJQzfueM=
|
||||||
|
|
@ -25,8 +35,8 @@ github.com/go-test/deep v1.0.6 h1:UHSEyLZUwX9Qoi99vVwvewiMC8mM2bf7XEM2nqvzEn8=
|
||||||
github.com/go-test/deep v1.0.6/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
|
github.com/go-test/deep v1.0.6/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
|
||||||
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||||
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
|
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
|
@ -40,15 +50,16 @@ github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg=
|
||||||
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4=
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/tidwall/assert v0.1.0 h1:aWcKyRBUAdLoVebxo95N7+YZVTFF/ASTr7BN4sLP6XI=
|
github.com/tidwall/assert v0.1.0 h1:aWcKyRBUAdLoVebxo95N7+YZVTFF/ASTr7BN4sLP6XI=
|
||||||
github.com/tidwall/assert v0.1.0/go.mod h1:QLYtGyeqse53vuELQheYl9dngGCJQ+mTtlxcktb+Kj8=
|
github.com/tidwall/assert v0.1.0/go.mod h1:QLYtGyeqse53vuELQheYl9dngGCJQ+mTtlxcktb+Kj8=
|
||||||
github.com/tidwall/btree v1.4.2 h1:PpkaieETJMUxYNADsjgtNRcERX7mGc/GP2zp/r5FM3g=
|
github.com/tidwall/btree v1.4.2 h1:PpkaieETJMUxYNADsjgtNRcERX7mGc/GP2zp/r5FM3g=
|
||||||
github.com/tidwall/btree v1.4.2/go.mod h1:LGm8L/DZjPLmeWGjv5kFrY8dL4uVhMmzmmLYmsObdKE=
|
github.com/tidwall/btree v1.4.2/go.mod h1:LGm8L/DZjPLmeWGjv5kFrY8dL4uVhMmzmmLYmsObdKE=
|
||||||
github.com/tidwall/buntdb v1.2.10 h1:U/ebfkmYPBnyiNZIirUiWFcxA/mgzjbKlyPynFsPtyM=
|
github.com/tidwall/buntdb v1.3.1 h1:HKoDF01/aBhl9RjYtbaLnvX9/OuenwvQiC3OP1CcL4o=
|
||||||
github.com/tidwall/buntdb v1.2.10/go.mod h1:lZZrZUWzlyDJKlLQ6DKAy53LnG7m5kHyrEHvvcDmBpU=
|
github.com/tidwall/buntdb v1.3.1/go.mod h1:lZZrZUWzlyDJKlLQ6DKAy53LnG7m5kHyrEHvvcDmBpU=
|
||||||
github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw=
|
github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw=
|
||||||
github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
|
|
@ -70,22 +81,22 @@ github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||||
github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc=
|
github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc=
|
||||||
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.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||||
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.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
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.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
||||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
|
||||||
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.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||||
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=
|
||||||
|
|
@ -95,7 +106,8 @@ gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,11 @@ const (
|
||||||
BotTagName = "bot"
|
BotTagName = "bot"
|
||||||
// https://ircv3.net/specs/extensions/chathistory
|
// https://ircv3.net/specs/extensions/chathistory
|
||||||
ChathistoryTargetsBatchType = "draft/chathistory-targets"
|
ChathistoryTargetsBatchType = "draft/chathistory-targets"
|
||||||
|
ExtendedISupportBatchType = "draft/extended-isupport"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
nameToCapability = make(map[string]Capability)
|
nameToCapability = make(map[string]Capability, numCapabs)
|
||||||
for capab, name := range capabilityNames {
|
for capab, name := range capabilityNames {
|
||||||
nameToCapability[name] = Capability(capab)
|
nameToCapability[name] = Capability(capab)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ package caps
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// number of recognized capabilities:
|
// number of recognized capabilities:
|
||||||
numCapabs = 34
|
numCapabs = 36
|
||||||
// length of the uint32 array that represents the bitset:
|
// length of the uint32 array that represents the bitset:
|
||||||
bitsetLen = 2
|
bitsetLen = 2
|
||||||
)
|
)
|
||||||
|
|
@ -53,6 +53,10 @@ const (
|
||||||
// https://github.com/ircv3/ircv3-specifications/pull/362
|
// https://github.com/ircv3/ircv3-specifications/pull/362
|
||||||
EventPlayback Capability = iota
|
EventPlayback Capability = iota
|
||||||
|
|
||||||
|
// ExtendedISupport is the proposed IRCv3 capability named "draft/extended-isupport":
|
||||||
|
// https://github.com/ircv3/ircv3-specifications/pull/543
|
||||||
|
ExtendedISupport Capability = iota
|
||||||
|
|
||||||
// Languages is the proposed IRCv3 capability named "draft/languages":
|
// Languages is the proposed IRCv3 capability named "draft/languages":
|
||||||
// https://gist.github.com/DanielOaks/8126122f74b26012a3de37db80e4e0c6
|
// https://gist.github.com/DanielOaks/8126122f74b26012a3de37db80e4e0c6
|
||||||
Languages Capability = iota
|
Languages Capability = iota
|
||||||
|
|
@ -148,6 +152,8 @@ const (
|
||||||
// ZNCSelfMessage is the ZNC vendor capability named "znc.in/self-message":
|
// ZNCSelfMessage is the ZNC vendor capability named "znc.in/self-message":
|
||||||
// https://wiki.znc.in/Query_buffers
|
// https://wiki.znc.in/Query_buffers
|
||||||
ZNCSelfMessage Capability = iota
|
ZNCSelfMessage Capability = iota
|
||||||
|
|
||||||
|
ExtendedNames Capability = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
// `capabilityNames[capab]` is the string name of the capability `capab`
|
// `capabilityNames[capab]` is the string name of the capability `capab`
|
||||||
|
|
@ -163,6 +169,7 @@ var (
|
||||||
"draft/channel-rename",
|
"draft/channel-rename",
|
||||||
"draft/chathistory",
|
"draft/chathistory",
|
||||||
"draft/event-playback",
|
"draft/event-playback",
|
||||||
|
"draft/extended-isupport",
|
||||||
"draft/languages",
|
"draft/languages",
|
||||||
"draft/message-redaction",
|
"draft/message-redaction",
|
||||||
"draft/multiline",
|
"draft/multiline",
|
||||||
|
|
@ -187,5 +194,6 @@ var (
|
||||||
"userhost-in-names",
|
"userhost-in-names",
|
||||||
"znc.in/playback",
|
"znc.in/playback",
|
||||||
"znc.in/self-message",
|
"znc.in/self-message",
|
||||||
|
"cef/extended-names",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
194
irc/cef.go
Normal file
194
irc/cef.go
Normal file
|
|
@ -0,0 +1,194 @@
|
||||||
|
package irc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/cshum/imagor/imagorpath"
|
||||||
|
"github.com/ergochat/ergo/irc/caps"
|
||||||
|
"github.com/ergochat/irc-go/ircmsg"
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ctx = context.Background()
|
||||||
|
|
||||||
|
func (channel *Channel) RedisBroadcast(message ...string) {
|
||||||
|
if channel.server.redis == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := channel.server.redis.Publish(ctx, "channel."+channel.NameCasefolded(), strings.Join(message, " ")).Err()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Channel broadcast error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) RedisBroadcast(message ...string) {
|
||||||
|
err := client.server.redis.Publish(ctx, "user."+client.NickCasefolded(), strings.Join(message, " ")).Err()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("User broadcast error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (channel *Channel) Broadcast(command string, params ...string) {
|
||||||
|
channel.BroadcastFrom(channel.server.name, command, params...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (channel *Channel) BroadcastFrom(prefix string, command string, params ...string) {
|
||||||
|
for _, member := range channel.Members() {
|
||||||
|
for _, session := range member.Sessions() {
|
||||||
|
session.Send(nil, prefix, command, params...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChannelSub Actions and info centering around channels
|
||||||
|
func (server *Server) ChannelSub() {
|
||||||
|
pubsub := server.redis.PSubscribe(ctx, "channel.*")
|
||||||
|
defer pubsub.Close()
|
||||||
|
|
||||||
|
ch := pubsub.Channel()
|
||||||
|
|
||||||
|
for msg := range ch {
|
||||||
|
server.logger.Info("RedisMessage", msg.Channel, msg.Payload)
|
||||||
|
line := strings.Split(msg.Payload, " ")
|
||||||
|
channelName := strings.SplitN(msg.Channel, ".", 2)[1]
|
||||||
|
channel := server.channels.Get(channelName)
|
||||||
|
if len(line) == 0 {
|
||||||
|
println("Empty string dumped into ", msg.Channel, " channel")
|
||||||
|
}
|
||||||
|
if channel == nil {
|
||||||
|
server.logger.Warning("RedisMessage", "Unknown channel")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch line[0] {
|
||||||
|
case "VOICEPART":
|
||||||
|
channel.Broadcast("VOICEPART", channelName, line[1])
|
||||||
|
case "VOICESTATE":
|
||||||
|
channel.Broadcast("VOICESTATE", channelName, line[1], line[2], line[3])
|
||||||
|
case "BROADCASTTO":
|
||||||
|
for _, person := range channel.Members() {
|
||||||
|
person.Send(nil, server.name, line[1], line[2:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserSub Handles things pertaining to users
|
||||||
|
func (server *Server) UserSub() {
|
||||||
|
pubsub := server.redis.PSubscribe(ctx, "user.*")
|
||||||
|
defer pubsub.Close()
|
||||||
|
|
||||||
|
ch := pubsub.Channel()
|
||||||
|
|
||||||
|
for msg := range ch {
|
||||||
|
server.logger.Info("RedisMessage", msg.Channel, msg.Payload)
|
||||||
|
line := strings.Split(msg.Payload, " ")
|
||||||
|
userName := strings.SplitN(msg.Channel, ".", 2)[1]
|
||||||
|
user := server.clients.Get(userName)
|
||||||
|
if len(line) == 0 {
|
||||||
|
println("Empty string dumped into ", msg.Channel, " channel")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch line[0] {
|
||||||
|
case "FULLYREMOVE":
|
||||||
|
if user != nil {
|
||||||
|
user.destroy(nil)
|
||||||
|
err := server.accounts.Unregister(user.Account(), true)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case "BROADCASTAS":
|
||||||
|
if user != nil {
|
||||||
|
// I'm not too sure what the capability bit is, I think it's just ones that match
|
||||||
|
for friend := range user.Friends(caps.ExtendedNames) {
|
||||||
|
friend.Send(nil, user.NickMaskString(), line[1], line[2:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startRedis(server *Server) {
|
||||||
|
go server.ChannelSub()
|
||||||
|
go server.UserSub()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (server *Server) GenerateImagorSignaturesFromMessage(message *ircmsg.Message) string {
|
||||||
|
line, err := message.Line()
|
||||||
|
if err == nil {
|
||||||
|
return server.GenerateImagorSignatures(line)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (server *Server) GetUrlMime(url string) string {
|
||||||
|
config := server.Config()
|
||||||
|
// hacky, should fix
|
||||||
|
if !strings.Contains(url, "?") {
|
||||||
|
url += "?"
|
||||||
|
}
|
||||||
|
params := imagorpath.Params{
|
||||||
|
Image: url,
|
||||||
|
Meta: true,
|
||||||
|
}
|
||||||
|
metaPath := imagorpath.Generate(params, imagorpath.NewHMACSigner(sha256.New, 0, config.Cef.Imagor.Secret))
|
||||||
|
client := http.Client{
|
||||||
|
Timeout: 5 * time.Second,
|
||||||
|
}
|
||||||
|
resp, err := client.Get(config.Cef.Imagor.Url + metaPath)
|
||||||
|
if err != nil {
|
||||||
|
println("Failed on the initial get")
|
||||||
|
println(err.Error())
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
var meta map[string]interface{}
|
||||||
|
err = json.NewDecoder(resp.Body).Decode(&meta)
|
||||||
|
if err != nil {
|
||||||
|
println("Failed on the JSON decode")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
contentType, valid := meta["format"].(string)
|
||||||
|
if !valid {
|
||||||
|
println("No content type")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return contentType
|
||||||
|
}
|
||||||
|
|
||||||
|
var urlRegex = regexp.MustCompile("https?:\\/\\/[\\w-]+(\\.[\\w-]+)+([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?")
|
||||||
|
|
||||||
|
// Process a message to add Imagor signatures
|
||||||
|
func (server *Server) GenerateImagorSignatures(str string) string {
|
||||||
|
urls := urlRegex.FindAllString(str, -1)
|
||||||
|
var sigs []string
|
||||||
|
for _, url := range urls {
|
||||||
|
params := imagorpath.Params{
|
||||||
|
Image: url,
|
||||||
|
FitIn: true,
|
||||||
|
Width: 600,
|
||||||
|
Height: 600,
|
||||||
|
}
|
||||||
|
path := imagorpath.Generate(params, imagorpath.NewHMACSigner(sha256.New, 0, server.Config().Cef.Imagor.Secret))
|
||||||
|
signature := path[:strings.IndexByte(path, '/')]
|
||||||
|
contentType := server.GetUrlMime(url)
|
||||||
|
if contentType != "" {
|
||||||
|
sigs = append(sigs, signature+"|"+strings.ReplaceAll(contentType, "/", "_"))
|
||||||
|
} else {
|
||||||
|
sigs = append(sigs, signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if len(sigs) > 0 {
|
||||||
|
return strings.Join(sigs, ",")
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
@ -477,6 +477,12 @@ func (channel *Channel) Names(client *Client, rb *ResponseBuffer) {
|
||||||
if respectAuditorium && memberData.modes.HighestChannelUserMode() == modes.Mode(0) {
|
if respectAuditorium && memberData.modes.HighestChannelUserMode() == modes.Mode(0) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if rb.session.capabilities.Has(caps.ExtendedNames) {
|
||||||
|
away, _ := target.Away()
|
||||||
|
if away {
|
||||||
|
nick = nick + "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
tl.AddParts(memberData.modes.Prefixes(isMultiPrefix), nick)
|
tl.AddParts(memberData.modes.Prefixes(isMultiPrefix), nick)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -721,6 +727,9 @@ func (channel *Channel) AddHistoryItem(item history.Item, account string) (err e
|
||||||
if !itemIsStorable(&item, channel.server.Config()) {
|
if !itemIsStorable(&item, channel.server.Config()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if item.Target == "" {
|
||||||
|
item.Target = channel.nameCasefolded
|
||||||
|
}
|
||||||
|
|
||||||
status, target, _ := channel.historyStatus(channel.server.Config())
|
status, target, _ := channel.historyStatus(channel.server.Config())
|
||||||
if status == HistoryPersistent {
|
if status == HistoryPersistent {
|
||||||
|
|
@ -795,6 +804,8 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
||||||
}
|
}
|
||||||
|
|
||||||
client.server.logger.Debug("channels", fmt.Sprintf("%s joined channel %s", details.nick, chname))
|
client.server.logger.Debug("channels", fmt.Sprintf("%s joined channel %s", details.nick, chname))
|
||||||
|
// I think this is assured to always be a good join point
|
||||||
|
channel.RedisBroadcast("VOICEPOLL")
|
||||||
|
|
||||||
givenMode := func() (givenMode modes.Mode) {
|
givenMode := func() (givenMode modes.Mode) {
|
||||||
channel.joinPartMutex.Lock()
|
channel.joinPartMutex.Lock()
|
||||||
|
|
@ -830,8 +841,9 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
||||||
histItem := history.Item{
|
histItem := history.Item{
|
||||||
Type: history.Join,
|
Type: history.Join,
|
||||||
Nick: details.nickMask,
|
Nick: details.nickMask,
|
||||||
AccountName: details.accountName,
|
Account: details.account,
|
||||||
Message: message,
|
Message: message,
|
||||||
|
Target: channel.NameCasefolded(),
|
||||||
IsBot: isBot,
|
IsBot: isBot,
|
||||||
}
|
}
|
||||||
histItem.Params[0] = details.realname
|
histItem.Params[0] = details.realname
|
||||||
|
|
@ -963,7 +975,7 @@ func (channel *Channel) autoReplayHistory(client *Client, rb *ResponseBuffer, sk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if 0 < numItems {
|
if 0 < numItems {
|
||||||
channel.replayHistoryItems(rb, items, false)
|
channel.replayHistoryItems(rb, items, false, "", "", numItems)
|
||||||
rb.Flush(true)
|
rb.Flush(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -991,6 +1003,7 @@ func (channel *Channel) playJoinForSession(session *Session) {
|
||||||
channel.Names(client, sessionRb)
|
channel.Names(client, sessionRb)
|
||||||
}
|
}
|
||||||
sessionRb.Send(false)
|
sessionRb.Send(false)
|
||||||
|
channel.RedisBroadcast("VOICEPOLL")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Part parts the given client from this channel, with the given message.
|
// Part parts the given client from this channel, with the given message.
|
||||||
|
|
@ -1044,8 +1057,9 @@ func (channel *Channel) Part(client *Client, message string, rb *ResponseBuffer)
|
||||||
channel.AddHistoryItem(history.Item{
|
channel.AddHistoryItem(history.Item{
|
||||||
Type: history.Part,
|
Type: history.Part,
|
||||||
Nick: details.nickMask,
|
Nick: details.nickMask,
|
||||||
AccountName: details.accountName,
|
Account: details.account,
|
||||||
Message: splitMessage,
|
Message: splitMessage,
|
||||||
|
Target: channel.NameCasefolded(),
|
||||||
IsBot: isBot,
|
IsBot: isBot,
|
||||||
}, details.account)
|
}, details.account)
|
||||||
}
|
}
|
||||||
|
|
@ -1053,7 +1067,7 @@ func (channel *Channel) Part(client *Client, message string, rb *ResponseBuffer)
|
||||||
client.server.logger.Debug("channels", fmt.Sprintf("%s left channel %s", details.nick, chname))
|
client.server.logger.Debug("channels", fmt.Sprintf("%s left channel %s", details.nick, chname))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.Item, chathistoryCommand bool) {
|
func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.Item, chathistoryCommand bool, identifier string, preposition string, limit int) {
|
||||||
// send an empty batch if necessary, as per the CHATHISTORY spec
|
// send an empty batch if necessary, as per the CHATHISTORY spec
|
||||||
chname := channel.Name()
|
chname := channel.Name()
|
||||||
client := rb.target
|
client := rb.target
|
||||||
|
|
@ -1073,19 +1087,19 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
batchID := rb.StartNestedBatch("chathistory", chname)
|
batchID := rb.StartNestedBatch("chathistory", chname, identifier, preposition, strconv.Itoa(limit))
|
||||||
defer rb.EndNestedBatch(batchID)
|
defer rb.EndNestedBatch(batchID)
|
||||||
|
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
nick := NUHToNick(item.Nick)
|
nick := NUHToNick(item.Nick)
|
||||||
switch item.Type {
|
switch item.Type {
|
||||||
case history.Privmsg:
|
case history.Privmsg:
|
||||||
rb.AddSplitMessageFromClient(item.Nick, item.AccountName, item.IsBot, item.Tags, "PRIVMSG", chname, item.Message)
|
rb.AddSplitMessageFromClientWithReactions(item.Nick, item.Account, item.IsBot, item.Tags, "PRIVMSG", chname, item.Message, item.Reactions)
|
||||||
case history.Notice:
|
case history.Notice:
|
||||||
rb.AddSplitMessageFromClient(item.Nick, item.AccountName, item.IsBot, item.Tags, "NOTICE", chname, item.Message)
|
rb.AddSplitMessageFromClientWithReactions(item.Nick, item.Account, item.IsBot, item.Tags, "NOTICE", chname, item.Message, item.Reactions)
|
||||||
case history.Tagmsg:
|
case history.Tagmsg:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddSplitMessageFromClient(item.Nick, item.AccountName, item.IsBot, item.Tags, "TAGMSG", chname, item.Message)
|
rb.AddSplitMessageFromClient(item.Nick, item.Account, item.IsBot, item.Tags, "TAGMSG", chname, item.Message)
|
||||||
} else if chathistoryCommand {
|
} else if chathistoryCommand {
|
||||||
// #1676, we have to send something here or else it breaks pagination
|
// #1676, we have to send something here or else it breaks pagination
|
||||||
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, fmt.Sprintf(client.t("%s sent a TAGMSG"), nick))
|
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, fmt.Sprintf(client.t("%s sent a TAGMSG"), nick))
|
||||||
|
|
@ -1093,25 +1107,25 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
|
||||||
case history.Join:
|
case history.Join:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
if extendedJoin {
|
if extendedJoin {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "JOIN", chname, item.AccountName, item.Params[0])
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.Account, item.IsBot, nil, "JOIN", chname, item.Account, item.Params[0])
|
||||||
} else {
|
} else {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "JOIN", chname)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.Account, item.IsBot, nil, "JOIN", chname)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !playJoinsAsPrivmsg {
|
if !playJoinsAsPrivmsg {
|
||||||
continue // #474
|
continue // #474
|
||||||
}
|
}
|
||||||
var message string
|
var message string
|
||||||
if item.AccountName == "*" {
|
if item.Account == "*" {
|
||||||
message = fmt.Sprintf(client.t("%s joined the channel"), nick)
|
message = fmt.Sprintf(client.t("%s joined the channel"), nick)
|
||||||
} else {
|
} else {
|
||||||
message = fmt.Sprintf(client.t("%[1]s [account: %[2]s] joined the channel"), nick, item.AccountName)
|
message = fmt.Sprintf(client.t("%[1]s [account: %[2]s] joined the channel"), nick, item.Account)
|
||||||
}
|
}
|
||||||
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
||||||
}
|
}
|
||||||
case history.Part:
|
case history.Part:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "PART", chname, item.Message.Message)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.Account, item.IsBot, nil, "PART", chname, item.Message.Message)
|
||||||
} else {
|
} else {
|
||||||
if !playJoinsAsPrivmsg {
|
if !playJoinsAsPrivmsg {
|
||||||
continue // #474
|
continue // #474
|
||||||
|
|
@ -1121,14 +1135,14 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
|
||||||
}
|
}
|
||||||
case history.Kick:
|
case history.Kick:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "KICK", chname, item.Params[0], item.Message.Message)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.Account, item.IsBot, nil, "KICK", chname, item.Params[0], item.Message.Message)
|
||||||
} else {
|
} else {
|
||||||
message := fmt.Sprintf(client.t("%[1]s kicked %[2]s (%[3]s)"), nick, item.Params[0], item.Message.Message)
|
message := fmt.Sprintf(client.t("%[1]s kicked %[2]s (%[3]s)"), nick, item.Params[0], item.Message.Message)
|
||||||
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
||||||
}
|
}
|
||||||
case history.Quit:
|
case history.Quit:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "QUIT", item.Message.Message)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.Account, item.IsBot, nil, "QUIT", item.Message.Message)
|
||||||
} else {
|
} else {
|
||||||
if !playJoinsAsPrivmsg {
|
if !playJoinsAsPrivmsg {
|
||||||
continue // #474
|
continue // #474
|
||||||
|
|
@ -1138,14 +1152,14 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
|
||||||
}
|
}
|
||||||
case history.Nick:
|
case history.Nick:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "NICK", item.Params[0])
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.Account, item.IsBot, nil, "NICK", item.Params[0])
|
||||||
} else {
|
} else {
|
||||||
message := fmt.Sprintf(client.t("%[1]s changed nick to %[2]s"), nick, item.Params[0])
|
message := fmt.Sprintf(client.t("%[1]s changed nick to %[2]s"), nick, item.Params[0])
|
||||||
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
||||||
}
|
}
|
||||||
case history.Topic:
|
case history.Topic:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "TOPIC", chname, item.Message.Message)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.Account, item.IsBot, nil, "TOPIC", chname, item.Message.Message)
|
||||||
} else {
|
} else {
|
||||||
message := fmt.Sprintf(client.t("%[1]s set the channel topic to: %[2]s"), nick, item.Message.Message)
|
message := fmt.Sprintf(client.t("%[1]s set the channel topic to: %[2]s"), nick, item.Message.Message)
|
||||||
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
||||||
|
|
@ -1157,7 +1171,7 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
|
||||||
params[i+1] = pair.Message
|
params[i+1] = pair.Message
|
||||||
}
|
}
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "MODE", params...)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.Account, item.IsBot, nil, "MODE", params...)
|
||||||
} else {
|
} else {
|
||||||
message := fmt.Sprintf(client.t("%[1]s set channel modes: %[2]s"), nick, strings.Join(params[1:], " "))
|
message := fmt.Sprintf(client.t("%[1]s set channel modes: %[2]s"), nick, strings.Join(params[1:], " "))
|
||||||
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
||||||
|
|
@ -1229,9 +1243,10 @@ func (channel *Channel) SetTopic(client *Client, topic string, rb *ResponseBuffe
|
||||||
channel.AddHistoryItem(history.Item{
|
channel.AddHistoryItem(history.Item{
|
||||||
Type: history.Topic,
|
Type: history.Topic,
|
||||||
Nick: details.nickMask,
|
Nick: details.nickMask,
|
||||||
AccountName: details.accountName,
|
Account: details.account,
|
||||||
Message: message,
|
Message: message,
|
||||||
IsBot: isBot,
|
IsBot: isBot,
|
||||||
|
Target: channel.NameCasefolded(),
|
||||||
}, details.account)
|
}, details.account)
|
||||||
|
|
||||||
channel.MarkDirty(IncludeTopic)
|
channel.MarkDirty(IncludeTopic)
|
||||||
|
|
@ -1374,9 +1389,10 @@ func (channel *Channel) SendSplitMessage(command string, minPrefixMode modes.Mod
|
||||||
Type: histType,
|
Type: histType,
|
||||||
Message: message,
|
Message: message,
|
||||||
Nick: details.nickMask,
|
Nick: details.nickMask,
|
||||||
AccountName: details.accountName,
|
Account: details.accountName,
|
||||||
Tags: clientOnlyTags,
|
Tags: clientOnlyTags,
|
||||||
IsBot: isBot,
|
IsBot: isBot,
|
||||||
|
Target: channel.NameCasefolded(),
|
||||||
}, details.account)
|
}, details.account)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1450,6 +1466,7 @@ func (channel *Channel) Quit(client *Client) {
|
||||||
client.server.channels.Cleanup(channel)
|
client.server.channels.Cleanup(channel)
|
||||||
}
|
}
|
||||||
client.removeChannel(channel)
|
client.removeChannel(channel)
|
||||||
|
channel.Broadcast("KICK", client.NickCasefolded())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) Kick(client *Client, target *Client, comment string, rb *ResponseBuffer, hasPrivs bool) {
|
func (channel *Channel) Kick(client *Client, target *Client, comment string, rb *ResponseBuffer, hasPrivs bool) {
|
||||||
|
|
@ -1484,9 +1501,10 @@ func (channel *Channel) Kick(client *Client, target *Client, comment string, rb
|
||||||
histItem := history.Item{
|
histItem := history.Item{
|
||||||
Type: history.Kick,
|
Type: history.Kick,
|
||||||
Nick: details.nickMask,
|
Nick: details.nickMask,
|
||||||
AccountName: details.accountName,
|
Account: details.account,
|
||||||
Message: message,
|
Message: message,
|
||||||
IsBot: isBot,
|
IsBot: isBot,
|
||||||
|
Target: channel.NameCasefolded(),
|
||||||
}
|
}
|
||||||
histItem.Params[0] = targetNick
|
histItem.Params[0] = targetNick
|
||||||
channel.AddHistoryItem(histItem, details.account)
|
channel.AddHistoryItem(histItem, details.account)
|
||||||
|
|
@ -1513,7 +1531,7 @@ func (channel *Channel) Purge(source string) {
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
for _, member := range members {
|
for _, member := range members {
|
||||||
tnick := member.Nick()
|
tnick := member.Nick()
|
||||||
msgid := utils.GenerateSecretToken()
|
msgid := utils.GenerateMessageIdStr()
|
||||||
for _, session := range member.Sessions() {
|
for _, session := range member.Sessions() {
|
||||||
session.sendFromClientInternal(false, now, msgid, source, "*", false, nil, "KICK", chname, tnick, member.t("This channel has been purged by the server administrators and cannot be used"))
|
session.sendFromClientInternal(false, now, msgid, source, "*", false, nil, "KICK", chname, tnick, member.t("This channel has been purged by the server administrators and cannot be used"))
|
||||||
}
|
}
|
||||||
|
|
@ -1563,6 +1581,8 @@ func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuf
|
||||||
item := history.Item{
|
item := history.Item{
|
||||||
Type: history.Invite,
|
Type: history.Invite,
|
||||||
Message: message,
|
Message: message,
|
||||||
|
Account: inviter.Account(),
|
||||||
|
Target: invitee.Account(),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, member := range channel.Members() {
|
for _, member := range channel.Members() {
|
||||||
|
|
|
||||||
|
|
@ -753,6 +753,7 @@ func csListHandler(service *ircService, server *Server, client *Client, command
|
||||||
}
|
}
|
||||||
|
|
||||||
func csInfoHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
func csInfoHandler(service *ircService, server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||||
|
|
||||||
if len(params) == 0 {
|
if len(params) == 0 {
|
||||||
// #765
|
// #765
|
||||||
listRegisteredChannels(service, client.Account(), rb)
|
listRegisteredChannels(service, client.Account(), rb)
|
||||||
|
|
@ -765,37 +766,41 @@ func csInfoHandler(service *ircService, server *Server, client *Client, command
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// purge status
|
|
||||||
if client.HasRoleCapabs("chanreg") {
|
|
||||||
purgeRecord, err := server.channels.LoadPurgeRecord(chname)
|
|
||||||
if err == nil {
|
|
||||||
service.Notice(rb, fmt.Sprintf(client.t("Channel %s was purged by the server operators and cannot be used"), chname))
|
|
||||||
service.Notice(rb, fmt.Sprintf(client.t("Purged by operator: %s"), purgeRecord.Oper))
|
|
||||||
service.Notice(rb, fmt.Sprintf(client.t("Purged at: %s"), purgeRecord.PurgedAt.Format(time.RFC1123)))
|
|
||||||
if purgeRecord.Reason != "" {
|
|
||||||
service.Notice(rb, fmt.Sprintf(client.t("Purge reason: %s"), purgeRecord.Reason))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if server.channels.IsPurged(chname) {
|
|
||||||
service.Notice(rb, fmt.Sprintf(client.t("Channel %s was purged by the server operators and cannot be used"), chname))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var chinfo RegisteredChannel
|
var chinfo RegisteredChannel
|
||||||
channel := server.channels.Get(params[0])
|
channel := server.channels.Get(params[0])
|
||||||
if channel != nil {
|
if channel != nil {
|
||||||
chinfo = channel.exportSummary()
|
chinfo = channel.exportSummary()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tags := map[string]string{
|
||||||
|
"target": chinfo.Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
// purge status
|
||||||
|
if client.HasRoleCapabs("chanreg") {
|
||||||
|
purgeRecord, err := server.channels.LoadPurgeRecord(chname)
|
||||||
|
if err == nil {
|
||||||
|
service.TaggedNotice(rb, fmt.Sprintf(client.t("Channel %s was purged by the server operators and cannot be used"), chname), tags)
|
||||||
|
service.TaggedNotice(rb, fmt.Sprintf(client.t("Purged by operator: %s"), purgeRecord.Oper), tags)
|
||||||
|
service.TaggedNotice(rb, fmt.Sprintf(client.t("Purged at: %s"), purgeRecord.PurgedAt.Format(time.RFC1123)), tags)
|
||||||
|
if purgeRecord.Reason != "" {
|
||||||
|
service.TaggedNotice(rb, fmt.Sprintf(client.t("Purge reason: %s"), purgeRecord.Reason), tags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if server.channels.IsPurged(chname) {
|
||||||
|
service.TaggedNotice(rb, fmt.Sprintf(client.t("Channel %s was purged by the server operators and cannot be used"), chname), tags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// channel exists but is unregistered, or doesn't exist:
|
// channel exists but is unregistered, or doesn't exist:
|
||||||
if chinfo.Founder == "" {
|
if chinfo.Founder == "" {
|
||||||
service.Notice(rb, fmt.Sprintf(client.t("Channel %s is not registered"), chname))
|
service.TaggedNotice(rb, fmt.Sprintf(client.t("Channel %s is not registered"), chname), tags)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
service.Notice(rb, fmt.Sprintf(client.t("Channel %s is registered"), chinfo.Name))
|
service.TaggedNotice(rb, fmt.Sprintf(client.t("Channel %s is registered"), chinfo.Name), tags)
|
||||||
service.Notice(rb, fmt.Sprintf(client.t("Founder: %s"), chinfo.Founder))
|
service.TaggedNotice(rb, fmt.Sprintf(client.t("Founder: %s"), chinfo.Founder), tags)
|
||||||
service.Notice(rb, fmt.Sprintf(client.t("Registered at: %s"), chinfo.RegisteredAt.Format(time.RFC1123)))
|
service.TaggedNotice(rb, fmt.Sprintf(client.t("Registered at: %s"), chinfo.RegisteredAt.Format(time.RFC1123)), tags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func displayChannelSetting(service *ircService, settingName string, settings ChannelSettings, client *Client, rb *ResponseBuffer) {
|
func displayChannelSetting(service *ircService, settingName string, settings ChannelSettings, client *Client, rb *ResponseBuffer) {
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// maximum IRC line length, not including tags
|
// Set to 4096 because CEF doesn't care about compatibility
|
||||||
DefaultMaxLineLen = 512
|
DefaultMaxLineLen = 4096
|
||||||
|
|
||||||
// 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
|
||||||
|
|
@ -179,6 +179,8 @@ type Session struct {
|
||||||
|
|
||||||
batchCounter atomic.Uint32
|
batchCounter atomic.Uint32
|
||||||
|
|
||||||
|
isupportSentPrereg bool
|
||||||
|
|
||||||
quitMessage string
|
quitMessage string
|
||||||
|
|
||||||
awayMessage string
|
awayMessage string
|
||||||
|
|
@ -649,6 +651,17 @@ func (client *Client) run(session *Session) {
|
||||||
|
|
||||||
firstLine := !isReattach
|
firstLine := !isReattach
|
||||||
|
|
||||||
|
correspondents, _ := client.server.historyDB.GetPMs(client.Account())
|
||||||
|
// For safety, let's keep this within the 4096 character barrier
|
||||||
|
var lineBuilder utils.TokenLineBuilder
|
||||||
|
lineBuilder.Initialize(MaxLineLen, ",")
|
||||||
|
for username, timestamp := range correspondents {
|
||||||
|
lineBuilder.Add(fmt.Sprintf("%s %d", client.server.getCurrentNick(username), timestamp))
|
||||||
|
}
|
||||||
|
for _, message := range lineBuilder.Lines() {
|
||||||
|
session.Send(nil, client.server.name, "PMS", message)
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
var invalidUtf8 bool
|
var invalidUtf8 bool
|
||||||
line, err := session.socket.Read()
|
line, err := session.socket.Read()
|
||||||
|
|
@ -862,14 +875,14 @@ func (session *Session) Ping() {
|
||||||
session.Send(nil, "", "PING", session.client.Nick())
|
session.Send(nil, "", "PING", session.client.Nick())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.Item, target string, chathistoryCommand bool) {
|
func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.Item, target string, chathistoryCommand bool, identifier string, preposition string, limit int) {
|
||||||
var batchID string
|
var batchID string
|
||||||
details := client.Details()
|
details := client.Details()
|
||||||
nick := details.nick
|
nick := details.nick
|
||||||
if target == "" {
|
if target == "" {
|
||||||
target = nick
|
target = nick
|
||||||
}
|
}
|
||||||
batchID = rb.StartNestedBatch("chathistory", target)
|
batchID = rb.StartNestedBatch("chathistory", target, identifier, preposition, strconv.Itoa(limit))
|
||||||
|
|
||||||
isSelfMessage := func(item *history.Item) bool {
|
isSelfMessage := func(item *history.Item) bool {
|
||||||
// XXX: Params[0] is the message target. if the source of this message is an in-memory
|
// XXX: Params[0] is the message target. if the source of this message is an in-memory
|
||||||
|
|
@ -890,7 +903,7 @@ func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.I
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if hasEventPlayback {
|
if hasEventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "INVITE", nick, item.Message.Message)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.Account, item.IsBot, nil, "INVITE", nick, item.Message.Message)
|
||||||
} else {
|
} else {
|
||||||
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", fmt.Sprintf(client.t("%[1]s invited you to channel %[2]s"), NUHToNick(item.Nick), item.Message.Message))
|
rb.AddFromClient(item.Message.Time, history.HistservMungeMsgid(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", fmt.Sprintf(client.t("%[1]s invited you to channel %[2]s"), NUHToNick(item.Nick), item.Message.Message))
|
||||||
}
|
}
|
||||||
|
|
@ -918,11 +931,11 @@ func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.I
|
||||||
tags = item.Tags
|
tags = item.Tags
|
||||||
}
|
}
|
||||||
if !isSelfMessage(&item) {
|
if !isSelfMessage(&item) {
|
||||||
rb.AddSplitMessageFromClient(item.Nick, item.AccountName, item.IsBot, tags, command, nick, item.Message)
|
rb.AddSplitMessageFromClientWithReactions(item.Nick, item.Account, item.IsBot, tags, command, nick, item.Message, item.Reactions)
|
||||||
} else {
|
} else {
|
||||||
// this message was sent *from* the client to another nick; the target is item.Params[0]
|
// this message was sent *from* the client to another nick; the target is item.Params[0]
|
||||||
// substitute client's current nickmask in case client changed nick
|
// substitute client's current nickmask in case client changed nick
|
||||||
rb.AddSplitMessageFromClient(details.nickMask, item.AccountName, item.IsBot, tags, command, item.Params[0], item.Message)
|
rb.AddSplitMessageFromClientWithReactions(details.nickMask, item.Account, item.IsBot, tags, command, item.Params[0], item.Message, item.Reactions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1354,7 +1367,7 @@ func (client *Client) destroy(session *Session) {
|
||||||
quitItem = history.Item{
|
quitItem = history.Item{
|
||||||
Type: history.Quit,
|
Type: history.Quit,
|
||||||
Nick: details.nickMask,
|
Nick: details.nickMask,
|
||||||
AccountName: details.accountName,
|
Account: details.accountName,
|
||||||
Message: splitQuitMessage,
|
Message: splitQuitMessage,
|
||||||
IsBot: isBot,
|
IsBot: isBot,
|
||||||
}
|
}
|
||||||
|
|
@ -1436,6 +1449,10 @@ func composeMultilineBatch(batchID, fromNickMask, fromAccount string, isBot bool
|
||||||
for _, msg := range message.Split {
|
for _, msg := range message.Split {
|
||||||
message := ircmsg.MakeMessage(nil, fromNickMask, command, target, msg.Message)
|
message := ircmsg.MakeMessage(nil, fromNickMask, command, target, msg.Message)
|
||||||
message.SetTag("batch", batchID)
|
message.SetTag("batch", batchID)
|
||||||
|
for k, v := range msg.Tags {
|
||||||
|
message.SetTag(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
if msg.Concat {
|
if msg.Concat {
|
||||||
message.SetTag(caps.MultilineConcatTag, "")
|
message.SetTag(caps.MultilineConcatTag, "")
|
||||||
}
|
}
|
||||||
|
|
@ -1673,7 +1690,7 @@ func (client *Client) addHistoryItem(target *Client, item history.Item, details,
|
||||||
}
|
}
|
||||||
|
|
||||||
item.Nick = details.nickMask
|
item.Nick = details.nickMask
|
||||||
item.AccountName = details.accountName
|
item.Account = details.account
|
||||||
targetedItem := item
|
targetedItem := item
|
||||||
targetedItem.Params[0] = tDetails.nick
|
targetedItem.Params[0] = tDetails.nick
|
||||||
|
|
||||||
|
|
@ -1681,15 +1698,15 @@ func (client *Client) addHistoryItem(target *Client, item history.Item, details,
|
||||||
tStatus, _ := target.historyStatus(config)
|
tStatus, _ := target.historyStatus(config)
|
||||||
// add to ephemeral history
|
// add to ephemeral history
|
||||||
if cStatus == HistoryEphemeral {
|
if cStatus == HistoryEphemeral {
|
||||||
targetedItem.CfCorrespondent = tDetails.nickCasefolded
|
targetedItem.Target = tDetails.account
|
||||||
client.history.Add(targetedItem)
|
client.history.Add(targetedItem)
|
||||||
}
|
}
|
||||||
if tStatus == HistoryEphemeral && client != target {
|
if tStatus == HistoryEphemeral && client != target {
|
||||||
item.CfCorrespondent = details.nickCasefolded
|
item.Target = target.Account()
|
||||||
target.history.Add(item)
|
target.history.Add(item)
|
||||||
}
|
}
|
||||||
if cStatus == HistoryPersistent || tStatus == HistoryPersistent {
|
if cStatus == HistoryPersistent || tStatus == HistoryPersistent {
|
||||||
targetedItem.CfCorrespondent = ""
|
targetedItem.Target = target.account
|
||||||
client.server.historyDB.AddDirectMessage(details.nickCasefolded, details.account, tDetails.nickCasefolded, tDetails.account, targetedItem)
|
client.server.historyDB.AddDirectMessage(details.nickCasefolded, details.account, tDetails.nickCasefolded, tDetails.account, targetedItem)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,10 @@ func init() {
|
||||||
handler: isonHandler,
|
handler: isonHandler,
|
||||||
minParams: 1,
|
minParams: 1,
|
||||||
},
|
},
|
||||||
|
"ISUPPORT": {
|
||||||
|
handler: isupportHandler,
|
||||||
|
usablePreReg: true,
|
||||||
|
},
|
||||||
"JOIN": {
|
"JOIN": {
|
||||||
handler: joinHandler,
|
handler: joinHandler,
|
||||||
minParams: 1,
|
minParams: 1,
|
||||||
|
|
@ -379,6 +383,11 @@ func init() {
|
||||||
handler: zncHandler,
|
handler: zncHandler,
|
||||||
minParams: 1,
|
minParams: 1,
|
||||||
},
|
},
|
||||||
|
// CEF custom commands
|
||||||
|
"REACT": {
|
||||||
|
handler: reactHandler,
|
||||||
|
minParams: 2,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeServices()
|
initializeServices()
|
||||||
|
|
|
||||||
|
|
@ -709,6 +709,14 @@ type Config struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
Filename string
|
Filename string
|
||||||
|
|
||||||
|
Cef struct {
|
||||||
|
Imagor struct {
|
||||||
|
Url string
|
||||||
|
Secret string
|
||||||
|
}
|
||||||
|
Redis string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OperClass defines an assembled operator class.
|
// OperClass defines an assembled operator class.
|
||||||
|
|
@ -1656,6 +1664,7 @@ func (config *Config) generateISupport() (err error) {
|
||||||
isupport.Add("RPCHAN", "E")
|
isupport.Add("RPCHAN", "E")
|
||||||
isupport.Add("RPUSER", "E")
|
isupport.Add("RPUSER", "E")
|
||||||
}
|
}
|
||||||
|
isupport.Add("SAFELIST", "")
|
||||||
isupport.Add("STATUSMSG", "~&@%+")
|
isupport.Add("STATUSMSG", "~&@%+")
|
||||||
isupport.Add("TARGMAX", fmt.Sprintf("NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:%s,TAGMSG:%s,NOTICE:%s,MONITOR:%d", maxTargetsString, maxTargetsString, maxTargetsString, config.Limits.MonitorEntries))
|
isupport.Add("TARGMAX", fmt.Sprintf("NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:%s,TAGMSG:%s,NOTICE:%s,MONITOR:%d", maxTargetsString, maxTargetsString, maxTargetsString, config.Limits.MonitorEntries))
|
||||||
isupport.Add("TOPICLEN", strconv.Itoa(config.Limits.TopicLen))
|
isupport.Add("TOPICLEN", strconv.Itoa(config.Limits.TopicLen))
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ package irc
|
||||||
const (
|
const (
|
||||||
// maxLastArgLength is used to simply cap off the final argument when creating general messages where we need to select a limit.
|
// maxLastArgLength is used to simply cap off the final argument when creating general messages where we need to select a limit.
|
||||||
// for instance, in MONITOR lists, RPL_ISUPPORT lists, etc.
|
// for instance, in MONITOR lists, RPL_ISUPPORT lists, etc.
|
||||||
maxLastArgLength = 400
|
maxLastArgLength = 1024
|
||||||
// maxTargets is the maximum number of targets for PRIVMSG and NOTICE.
|
// maxTargets is the maximum number of targets for PRIVMSG and NOTICE.
|
||||||
maxTargets = 4
|
maxTargets = 4
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -275,6 +275,6 @@ func (dm *DLineManager) loadFromDatastore() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) loadDLines() {
|
func (server *Server) loadDLines() {
|
||||||
s.dlines = NewDLineManager(s)
|
server.dlines = NewDLineManager(server)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build !plan9
|
//go:build !(plan9 || solaris)
|
||||||
|
|
||||||
package flock
|
package flock
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
//go:build plan9
|
//go:build plan9 || solaris
|
||||||
|
|
||||||
package flock
|
package flock
|
||||||
|
|
||||||
|
|
@ -410,7 +410,11 @@ func (client *Client) SetMode(mode modes.Mode, on bool) bool {
|
||||||
|
|
||||||
func (client *Client) SetRealname(realname string) {
|
func (client *Client) SetRealname(realname string) {
|
||||||
client.stateMutex.Lock()
|
client.stateMutex.Lock()
|
||||||
|
// TODO: make this configurable
|
||||||
client.realname = realname
|
client.realname = realname
|
||||||
|
if len(realname) > 128 {
|
||||||
|
client.realname = client.realname[:128]
|
||||||
|
}
|
||||||
alwaysOn := client.registered && client.alwaysOn
|
alwaysOn := client.registered && client.alwaysOn
|
||||||
client.stateMutex.Unlock()
|
client.stateMutex.Unlock()
|
||||||
if alwaysOn {
|
if alwaysOn {
|
||||||
|
|
|
||||||
151
irc/handlers.go
151
irc/handlers.go
|
|
@ -570,6 +570,16 @@ func batchHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respon
|
||||||
// XXX changing the label inside a handler is a bit dodgy, but it works here
|
// XXX changing the label inside a handler is a bit dodgy, but it works here
|
||||||
// because there's no way we could have triggered a flush up to this point
|
// because there's no way we could have triggered a flush up to this point
|
||||||
rb.Label = batch.responseLabel
|
rb.Label = batch.responseLabel
|
||||||
|
|
||||||
|
for _, msg := range batch.message.Split {
|
||||||
|
signatures := server.GenerateImagorSignatures(msg.Message)
|
||||||
|
if len(signatures) > 0 {
|
||||||
|
if msg.Tags == nil {
|
||||||
|
msg.Tags = make(map[string]string)
|
||||||
|
}
|
||||||
|
msg.Tags["signatures"] = signatures
|
||||||
|
}
|
||||||
|
}
|
||||||
dispatchMessageToTarget(client, batch.tags, histType, batch.command, batch.target, batch.message, rb)
|
dispatchMessageToTarget(client, batch.tags, histType, batch.command, batch.target, batch.message, rb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -702,6 +712,14 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.Message, rb *
|
||||||
var err error
|
var err error
|
||||||
var listTargets bool
|
var listTargets bool
|
||||||
var targets []history.TargetListing
|
var targets []history.TargetListing
|
||||||
|
var _, batchIdentifier = msg.GetTag("identifier")
|
||||||
|
var assuredPreposition = "error"
|
||||||
|
var limit int
|
||||||
|
|
||||||
|
if len(batchIdentifier) == 0 {
|
||||||
|
batchIdentifier = "UNIDENTIFIED"
|
||||||
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
// errors are sent either without a batch, or in a draft/labeled-response batch as usual
|
// errors are sent either without a batch, or in a draft/labeled-response batch as usual
|
||||||
if err == utils.ErrInvalidParams {
|
if err == utils.ErrInvalidParams {
|
||||||
|
|
@ -721,9 +739,9 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.Message, rb *
|
||||||
target.Time.Format(IRCv3TimestampFormat))
|
target.Time.Format(IRCv3TimestampFormat))
|
||||||
}
|
}
|
||||||
} else if channel != nil {
|
} else if channel != nil {
|
||||||
channel.replayHistoryItems(rb, items, true)
|
channel.replayHistoryItems(rb, items, true, batchIdentifier, assuredPreposition, limit)
|
||||||
} else {
|
} else {
|
||||||
client.replayPrivmsgHistory(rb, items, target, true)
|
client.replayPrivmsgHistory(rb, items, target, true, batchIdentifier, assuredPreposition, limit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
@ -776,7 +794,6 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.Message, rb *
|
||||||
|
|
||||||
paramPos := 2
|
paramPos := 2
|
||||||
var start, end history.Selector
|
var start, end history.Selector
|
||||||
var limit int
|
|
||||||
switch preposition {
|
switch preposition {
|
||||||
case "targets":
|
case "targets":
|
||||||
// use the same selector parsing as BETWEEN,
|
// use the same selector parsing as BETWEEN,
|
||||||
|
|
@ -831,6 +848,7 @@ func chathistoryHandler(server *Server, client *Client, msg ircmsg.Message, rb *
|
||||||
err = utils.ErrInvalidParams
|
err = utils.ErrInvalidParams
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
assuredPreposition = preposition
|
||||||
|
|
||||||
if listTargets {
|
if listTargets {
|
||||||
targets, err = client.listTargets(start, end, limit)
|
targets, err = client.listTargets(start, end, limit)
|
||||||
|
|
@ -855,7 +873,6 @@ func debugHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respon
|
||||||
switch param {
|
switch param {
|
||||||
case "GCSTATS":
|
case "GCSTATS":
|
||||||
stats := debug.GCStats{
|
stats := debug.GCStats{
|
||||||
Pause: make([]time.Duration, 10),
|
|
||||||
PauseQuantiles: make([]time.Duration, 5),
|
PauseQuantiles: make([]time.Duration, 5),
|
||||||
}
|
}
|
||||||
debug.ReadGCStats(&stats)
|
debug.ReadGCStats(&stats)
|
||||||
|
|
@ -1128,6 +1145,12 @@ func extjwtHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respo
|
||||||
}
|
}
|
||||||
|
|
||||||
claims["channel"] = channel.Name()
|
claims["channel"] = channel.Name()
|
||||||
|
|
||||||
|
var channelModeStrings []string
|
||||||
|
for _, mode := range channel.flags.AllModes() {
|
||||||
|
channelModeStrings = append(channelModeStrings, mode.String())
|
||||||
|
}
|
||||||
|
claims["chanModes"] = channelModeStrings
|
||||||
claims["joined"] = 0
|
claims["joined"] = 0
|
||||||
claims["cmodes"] = []string{}
|
claims["cmodes"] = []string{}
|
||||||
if present, joinTimeSecs, cModes := channel.ClientStatus(client); present {
|
if present, joinTimeSecs, cModes := channel.ClientStatus(client); present {
|
||||||
|
|
@ -1211,6 +1234,8 @@ Get an explanation of <argument>, or "index" for a list of help topics.`), rb)
|
||||||
// HISTORY alice 15
|
// HISTORY alice 15
|
||||||
// HISTORY #darwin 1h
|
// HISTORY #darwin 1h
|
||||||
func historyHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
func historyHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
||||||
|
rb.Notice(client.t("This command is currently disabled. Please use CHATHISTORY"))
|
||||||
|
/*
|
||||||
config := server.Config()
|
config := server.Config()
|
||||||
if !config.History.Enabled {
|
if !config.History.Enabled {
|
||||||
rb.Notice(client.t("This command has been disabled by the server administrators"))
|
rb.Notice(client.t("This command has been disabled by the server administrators"))
|
||||||
|
|
@ -1227,13 +1252,16 @@ func historyHandler(server *Server, client *Client, msg ircmsg.Message, rb *Resp
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _, batchIdentifier = msg.GetTag("identifier")
|
||||||
|
|
||||||
if len(items) != 0 {
|
if len(items) != 0 {
|
||||||
if channel != nil {
|
if channel != nil {
|
||||||
channel.replayHistoryItems(rb, items, true)
|
channel.replayHistoryItems(rb, items, true, batchIdentifier)
|
||||||
} else {
|
} else {
|
||||||
client.replayPrivmsgHistory(rb, items, "", true)
|
client.replayPrivmsgHistory(rb, items, "", true, batchIdentifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1321,6 +1349,15 @@ func isonHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respons
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ISUPPORT
|
||||||
|
func isupportHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
||||||
|
server.RplISupport(client, rb)
|
||||||
|
if !client.registered {
|
||||||
|
rb.session.isupportSentPrereg = true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// JOIN <channel>{,<channel>} [<key>{,<key>}]
|
// JOIN <channel>{,<channel>} [<key>{,<key>}]
|
||||||
func joinHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
func joinHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
||||||
// #1417: allow `JOIN 0` with a confirmation code
|
// #1417: allow `JOIN 0` with a confirmation code
|
||||||
|
|
@ -1891,8 +1928,9 @@ func announceCmodeChanges(channel *Channel, applied modes.ModeChanges, source, a
|
||||||
channel.AddHistoryItem(history.Item{
|
channel.AddHistoryItem(history.Item{
|
||||||
Type: history.Mode,
|
Type: history.Mode,
|
||||||
Nick: source,
|
Nick: source,
|
||||||
AccountName: accountName,
|
Account: accountName,
|
||||||
Message: message,
|
Message: message,
|
||||||
|
Target: channel.NameCasefolded(),
|
||||||
IsBot: isBot,
|
IsBot: isBot,
|
||||||
}, account)
|
}, account)
|
||||||
}
|
}
|
||||||
|
|
@ -2234,7 +2272,7 @@ func absorbBatchedMessage(server *Server, client *Client, msg ircmsg.Message, ba
|
||||||
if !isConcat && len(rb.session.batch.message.Split) != 0 {
|
if !isConcat && len(rb.session.batch.message.Split) != 0 {
|
||||||
rb.session.batch.lenBytes++ // bill for the newline
|
rb.session.batch.lenBytes++ // bill for the newline
|
||||||
}
|
}
|
||||||
rb.session.batch.message.Append(msg.Params[1], isConcat)
|
rb.session.batch.message.Append(msg.Params[1], isConcat, msg.ClientOnlyTags())
|
||||||
rb.session.batch.lenBytes += len(msg.Params[1])
|
rb.session.batch.lenBytes += len(msg.Params[1])
|
||||||
config := server.Config()
|
config := server.Config()
|
||||||
if config.Limits.Multiline.MaxBytes < rb.session.batch.lenBytes {
|
if config.Limits.Multiline.MaxBytes < rb.session.batch.lenBytes {
|
||||||
|
|
@ -2312,11 +2350,53 @@ func messageHandler(server *Server, client *Client, msg ircmsg.Message, rb *Resp
|
||||||
|
|
||||||
// each target gets distinct msgids
|
// each target gets distinct msgids
|
||||||
splitMsg := utils.MakeMessage(message)
|
splitMsg := utils.MakeMessage(message)
|
||||||
|
signatures := server.GenerateImagorSignaturesFromMessage(&msg)
|
||||||
|
if len(signatures) > 0 {
|
||||||
|
if clientOnlyTags == nil {
|
||||||
|
clientOnlyTags = make(map[string]string)
|
||||||
|
}
|
||||||
|
clientOnlyTags["signatures"] = signatures
|
||||||
|
}
|
||||||
dispatchMessageToTarget(client, clientOnlyTags, histType, msg.Command, targetString, splitMsg, rb)
|
dispatchMessageToTarget(client, clientOnlyTags, histType, msg.Command, targetString, splitMsg, rb)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not really sure how to do this in Go
|
||||||
|
var endChars = map[int32]bool{
|
||||||
|
' ': true,
|
||||||
|
'@': true,
|
||||||
|
':': true,
|
||||||
|
'!': true,
|
||||||
|
'?': true,
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectMentions(message string) (mentions []string) {
|
||||||
|
buf := ""
|
||||||
|
mentions = []string{}
|
||||||
|
working := false
|
||||||
|
for _, char := range message {
|
||||||
|
if char == '@' {
|
||||||
|
working = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !working {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, stop := endChars[char]; stop {
|
||||||
|
working = false
|
||||||
|
mentions = append(mentions, buf)
|
||||||
|
buf = ""
|
||||||
|
} else {
|
||||||
|
buf += string(char)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(buf) != 0 {
|
||||||
|
mentions = append(mentions, buf)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func dispatchMessageToTarget(client *Client, tags map[string]string, histType history.ItemType, command, target string, message utils.SplitMessage, rb *ResponseBuffer) {
|
func dispatchMessageToTarget(client *Client, tags map[string]string, histType history.ItemType, command, target string, message utils.SplitMessage, rb *ResponseBuffer) {
|
||||||
server := client.server
|
server := client.server
|
||||||
|
|
||||||
|
|
@ -2333,7 +2413,15 @@ func dispatchMessageToTarget(client *Client, tags map[string]string, histType hi
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// This likely isn't that great for performance. Should figure out some way to deal with this at some point
|
||||||
|
mentions := detectMentions(message.Message)
|
||||||
channel.SendSplitMessage(command, lowestPrefix, tags, client, message, rb)
|
channel.SendSplitMessage(command, lowestPrefix, tags, client, message, rb)
|
||||||
|
for _, mention := range mentions {
|
||||||
|
user := client.server.clients.Get(mention)
|
||||||
|
if user != nil {
|
||||||
|
user.RedisBroadcast("MENTION", channel.Name(), message.Msgid)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if target[0] == '$' && len(target) > 2 && client.Oper().HasRoleCapab("massmessage") {
|
} else if target[0] == '$' && len(target) > 2 && client.Oper().HasRoleCapab("massmessage") {
|
||||||
details := client.Details()
|
details := client.Details()
|
||||||
matcher, err := utils.CompileGlob(target[2:], false)
|
matcher, err := utils.CompileGlob(target[2:], false)
|
||||||
|
|
@ -2356,6 +2444,7 @@ func dispatchMessageToTarget(client *Client, tags map[string]string, histType hi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// PMs
|
||||||
lowercaseTarget := strings.ToLower(target)
|
lowercaseTarget := strings.ToLower(target)
|
||||||
service, isService := ErgoServices[lowercaseTarget]
|
service, isService := ErgoServices[lowercaseTarget]
|
||||||
_, isZNC := zncHandlers[lowercaseTarget]
|
_, isZNC := zncHandlers[lowercaseTarget]
|
||||||
|
|
@ -2455,8 +2544,13 @@ func dispatchMessageToTarget(client *Client, tags map[string]string, histType hi
|
||||||
Type: histType,
|
Type: histType,
|
||||||
Message: message,
|
Message: message,
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
|
Target: user.Account(),
|
||||||
|
Account: client.Account(),
|
||||||
}
|
}
|
||||||
|
|
||||||
client.addHistoryItem(user, item, &details, &tDetails, config)
|
client.addHistoryItem(user, item, &details, &tDetails, config)
|
||||||
|
user.RedisBroadcast("MENTION", user.NickCasefolded(), message.Msgid)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2745,7 +2839,7 @@ func redactHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respo
|
||||||
var members []*Client // members of a channel, or both parties of a PM
|
var members []*Client // members of a channel, or both parties of a PM
|
||||||
var canDelete CanDelete
|
var canDelete CanDelete
|
||||||
|
|
||||||
msgid := utils.GenerateSecretToken()
|
msgid := utils.GenerateMessageIdStr()
|
||||||
time := time.Now().UTC().Round(0)
|
time := time.Now().UTC().Round(0)
|
||||||
details := client.Details()
|
details := client.Details()
|
||||||
isBot := client.HasMode(modes.Bot)
|
isBot := client.HasMode(modes.Bot)
|
||||||
|
|
@ -2772,16 +2866,16 @@ func redactHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respo
|
||||||
rb.Add(nil, server.name, "FAIL", "REDACT", "REDACT_FORBIDDEN", utils.SafeErrorParam(target), utils.SafeErrorParam(targetmsgid), client.t("You are not authorized to delete messages"))
|
rb.Add(nil, server.name, "FAIL", "REDACT", "REDACT_FORBIDDEN", utils.SafeErrorParam(target), utils.SafeErrorParam(targetmsgid), client.t("You are not authorized to delete messages"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
accountName := "*"
|
account := "*"
|
||||||
if canDelete == canDeleteSelf {
|
if canDelete == canDeleteSelf {
|
||||||
accountName = client.AccountName()
|
account = client.account
|
||||||
if accountName == "*" {
|
if account == "*" {
|
||||||
rb.Add(nil, server.name, "FAIL", "REDACT", "REDACT_FORBIDDEN", utils.SafeErrorParam(target), utils.SafeErrorParam(targetmsgid), client.t("You are not authorized to delete this message"))
|
rb.Add(nil, server.name, "FAIL", "REDACT", "REDACT_FORBIDDEN", utils.SafeErrorParam(target), utils.SafeErrorParam(targetmsgid), client.t("You are not authorized to delete this message"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := server.DeleteMessage(target, targetmsgid, accountName)
|
err := server.DeleteMessage(target, targetmsgid, account)
|
||||||
if err == errNoop {
|
if err == errNoop {
|
||||||
rb.Add(nil, server.name, "FAIL", "REDACT", "UNKNOWN_MSGID", utils.SafeErrorParam(target), utils.SafeErrorParam(targetmsgid), client.t("This message does not exist or is too old"))
|
rb.Add(nil, server.name, "FAIL", "REDACT", "UNKNOWN_MSGID", utils.SafeErrorParam(target), utils.SafeErrorParam(targetmsgid), client.t("This message does not exist or is too old"))
|
||||||
return false
|
return false
|
||||||
|
|
@ -2798,7 +2892,7 @@ func redactHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respo
|
||||||
if target[0] != '#' {
|
if target[0] != '#' {
|
||||||
// If this is a PM, we just removed the message from the buffer of the other party;
|
// If this is a PM, we just removed the message from the buffer of the other party;
|
||||||
// now we have to remove it from the buffer of the client who sent the REDACT command
|
// now we have to remove it from the buffer of the client who sent the REDACT command
|
||||||
err := server.DeleteMessage(client.Nick(), targetmsgid, accountName)
|
err := server.DeleteMessage(client.Nick(), targetmsgid, account)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
client.server.logger.Error("internal", fmt.Sprintf("Private message %s is not deletable by %s from their own buffer's even though we just deleted it from %s's. This is a bug, please report it in details.", targetmsgid, client.Nick(), target), client.Nick())
|
client.server.logger.Error("internal", fmt.Sprintf("Private message %s is not deletable by %s from their own buffer's even though we just deleted it from %s's. This is a bug, please report it in details.", targetmsgid, client.Nick(), target), client.Nick())
|
||||||
|
|
@ -3124,6 +3218,8 @@ func relaymsgHandler(server *Server, client *Client, msg ircmsg.Message, rb *Res
|
||||||
Type: history.Privmsg,
|
Type: history.Privmsg,
|
||||||
Message: message,
|
Message: message,
|
||||||
Nick: nuh,
|
Nick: nuh,
|
||||||
|
Target: channel.NameCasefolded(),
|
||||||
|
Account: "$RELAYMSG",
|
||||||
}, "")
|
}, "")
|
||||||
|
|
||||||
// 3 possibilities for tags:
|
// 3 possibilities for tags:
|
||||||
|
|
@ -3989,6 +4085,33 @@ func zncHandler(server *Server, client *Client, msg ircmsg.Message, rb *Response
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// REACT <msgid> :<reaction>
|
||||||
|
func reactHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
||||||
|
// This directly uses SQL stuff, since it's targeted at CEF, which requires a DB.
|
||||||
|
_, _, target, sender, _, pm, err := server.historyDB.GetMessage(msg.Params[0])
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var operation string
|
||||||
|
if server.historyDB.HasReactionFromUser(msg.Params[0], client.AccountName(), msg.Params[1]) {
|
||||||
|
server.historyDB.DeleteReaction(msg.Params[0], client.AccountName(), msg.Params[1])
|
||||||
|
operation = "DEL"
|
||||||
|
} else {
|
||||||
|
server.historyDB.AddReaction(msg.Params[0], client.AccountName(), msg.Params[1])
|
||||||
|
operation = "ADD"
|
||||||
|
}
|
||||||
|
|
||||||
|
if pm {
|
||||||
|
server.clients.Get(target).Send(nil, client.NickMaskString(), "REACT", operation, msg.Params[0], msg.Params[1])
|
||||||
|
server.clients.Get(sender).Send(nil, client.NickMaskString(), "REACT", operation, msg.Params[0], msg.Params[1])
|
||||||
|
} else {
|
||||||
|
server.channels.Get(target).BroadcastFrom(client.NickMaskString(), "REACT", operation, msg.Params[0], msg.Params[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
|
|
||||||
11
irc/help.go
11
irc/help.go
|
|
@ -259,6 +259,11 @@ appropriate channel privs.`,
|
||||||
text: `ISON <nickname>{ <nickname>}
|
text: `ISON <nickname>{ <nickname>}
|
||||||
|
|
||||||
Returns whether the given nicks exist on the network.`,
|
Returns whether the given nicks exist on the network.`,
|
||||||
|
},
|
||||||
|
"isupport": {
|
||||||
|
text: `ISUPPORT
|
||||||
|
|
||||||
|
Returns RPL_ISUPPORT lines describing the server's capabilities.`,
|
||||||
},
|
},
|
||||||
"join": {
|
"join": {
|
||||||
text: `JOIN <channel>{,<channel>} [<key>{,<key>}]
|
text: `JOIN <channel>{,<channel>} [<key>{,<key>}]
|
||||||
|
|
@ -629,6 +634,12 @@ for direct use by end users.`,
|
||||||
duplicate: true,
|
duplicate: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"react": {
|
||||||
|
text: `REACT <msgid> <reaction>
|
||||||
|
|
||||||
|
Toggles a reaction to a message. CEF-specific`,
|
||||||
|
},
|
||||||
|
|
||||||
// Informational
|
// Informational
|
||||||
"modes": {
|
"modes": {
|
||||||
textGenerator: modesTextGenerator,
|
textGenerator: modesTextGenerator,
|
||||||
|
|
|
||||||
|
|
@ -32,13 +32,20 @@ const (
|
||||||
initialAutoSize = 32
|
initialAutoSize = 32
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Reaction struct {
|
||||||
|
Name string
|
||||||
|
Total int
|
||||||
|
SampleUsers []string
|
||||||
|
}
|
||||||
|
|
||||||
// Item represents an event (e.g., a PRIVMSG or a JOIN) and its associated data
|
// Item represents an event (e.g., a PRIVMSG or a JOIN) and its associated data
|
||||||
type Item struct {
|
type Item struct {
|
||||||
Type ItemType
|
Type ItemType
|
||||||
|
|
||||||
Nick string
|
Nick string
|
||||||
// this is the uncasefolded account name, if there's no account it should be set to "*"
|
// this is the uncasefolded account name, if there's no account it should be set to "*"
|
||||||
AccountName string
|
// in cef, this is always set, at least in theory. cant wait for bugs toc rop up
|
||||||
|
Account string
|
||||||
// for non-privmsg items, we may stuff some other data in here
|
// for non-privmsg items, we may stuff some other data in here
|
||||||
Message utils.SplitMessage
|
Message utils.SplitMessage
|
||||||
Tags map[string]string
|
Tags map[string]string
|
||||||
|
|
@ -46,8 +53,10 @@ type Item struct {
|
||||||
// for a DM, this is the casefolded nickname of the other party (whether this is
|
// for a DM, this is the casefolded nickname of the other party (whether this is
|
||||||
// an incoming or outgoing message). this lets us emulate the "query buffer" functionality
|
// an incoming or outgoing message). this lets us emulate the "query buffer" functionality
|
||||||
// required by CHATHISTORY:
|
// required by CHATHISTORY:
|
||||||
CfCorrespondent string `json:"CfCorrespondent,omitempty"`
|
Target string `json:"Target"`
|
||||||
IsBot bool `json:"IsBot,omitempty"`
|
IsBot bool `json:"IsBot,omitempty"`
|
||||||
|
|
||||||
|
Reactions []Reaction
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasMsgid tests whether a message has the message id `msgid`.
|
// HasMsgid tests whether a message has the message id `msgid`.
|
||||||
|
|
@ -213,10 +222,10 @@ func (list *Buffer) allCorrespondents() (results []TargetListing) {
|
||||||
stop := list.start
|
stop := list.start
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if !seen.Has(list.buffer[pos].CfCorrespondent) {
|
if !seen.Has(list.buffer[pos].Target) {
|
||||||
seen.Add(list.buffer[pos].CfCorrespondent)
|
seen.Add(list.buffer[pos].Target)
|
||||||
results = append(results, TargetListing{
|
results = append(results, TargetListing{
|
||||||
CfName: list.buffer[pos].CfCorrespondent,
|
CfName: list.buffer[pos].Target,
|
||||||
Time: list.buffer[pos].Message.Time,
|
Time: list.buffer[pos].Message.Time,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -281,7 +290,7 @@ func (list *Buffer) MakeSequence(correspondent string, cutoff time.Time) Sequenc
|
||||||
var pred Predicate
|
var pred Predicate
|
||||||
if correspondent != "" {
|
if correspondent != "" {
|
||||||
pred = func(item *Item) bool {
|
pred = func(item *Item) bool {
|
||||||
return item.CfCorrespondent == correspondent
|
return item.Target == correspondent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &bufferSequence{
|
return &bufferSequence{
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ func (t *JwtServiceConfig) Enabled() bool {
|
||||||
|
|
||||||
func (t *JwtServiceConfig) Sign(claims MapClaims) (result string, err error) {
|
func (t *JwtServiceConfig) Sign(claims MapClaims) (result string, err error) {
|
||||||
claims["exp"] = time.Now().Unix() + int64(t.Expiration/time.Second)
|
claims["exp"] = time.Now().Unix() + int64(t.Expiration/time.Second)
|
||||||
|
claims["now"] = time.Now().Unix()
|
||||||
if t.rsaPrivateKey != nil {
|
if t.rsaPrivateKey != nil {
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims(claims))
|
token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims(claims))
|
||||||
return token.SignedString(t.rsaPrivateKey)
|
return token.SignedString(t.rsaPrivateKey)
|
||||||
|
|
|
||||||
|
|
@ -253,6 +253,6 @@ func (km *KLineManager) loadFromDatastore() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) loadKLines() {
|
func (server *Server) loadKLines() {
|
||||||
s.klines = NewKLineManager(s)
|
server.klines = NewKLineManager(server)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,6 @@ const (
|
||||||
// maximum length in bytes of any message target (nickname or channel name) in its
|
// maximum length in bytes of any message target (nickname or channel name) in its
|
||||||
// canonicalized (i.e., casefolded) state:
|
// canonicalized (i.e., casefolded) state:
|
||||||
MaxTargetLength = 64
|
MaxTargetLength = 64
|
||||||
|
|
||||||
// latest schema of the db
|
|
||||||
latestDbSchema = "2"
|
|
||||||
keySchemaVersion = "db.version"
|
|
||||||
// minor version indicates rollback-safe upgrades, i.e.,
|
|
||||||
// you can downgrade oragono and everything will work
|
|
||||||
latestDbMinorVersion = "2"
|
|
||||||
keySchemaMinorVersion = "db.minorversion"
|
|
||||||
cleanupRowLimit = 50
|
cleanupRowLimit = 50
|
||||||
cleanupPauseTime = 10 * time.Minute
|
cleanupPauseTime = 10 * time.Minute
|
||||||
)
|
)
|
||||||
|
|
@ -50,11 +42,16 @@ type MySQL struct {
|
||||||
logger *logger.Manager
|
logger *logger.Manager
|
||||||
|
|
||||||
insertHistory *sql.Stmt
|
insertHistory *sql.Stmt
|
||||||
insertSequence *sql.Stmt
|
|
||||||
insertConversation *sql.Stmt
|
insertConversation *sql.Stmt
|
||||||
insertCorrespondent *sql.Stmt
|
|
||||||
insertAccountMessage *sql.Stmt
|
insertAccountMessage *sql.Stmt
|
||||||
|
|
||||||
|
getReactionsQuery *sql.Stmt
|
||||||
|
getSingleReaction *sql.Stmt
|
||||||
|
addReaction *sql.Stmt
|
||||||
|
deleteReaction *sql.Stmt
|
||||||
|
|
||||||
|
getMessageById *sql.Stmt
|
||||||
|
|
||||||
stateMutex sync.Mutex
|
stateMutex sync.Mutex
|
||||||
config Config
|
config Config
|
||||||
|
|
||||||
|
|
@ -89,197 +86,55 @@ func (mysql *MySQL) getExpireTime() (expireTime time.Duration) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MySQL) Open() (err error) {
|
func (mysql *MySQL) Open() (err error) {
|
||||||
var address string
|
var address string
|
||||||
if m.config.SocketPath != "" {
|
if mysql.config.SocketPath != "" {
|
||||||
address = fmt.Sprintf("unix(%s)", m.config.SocketPath)
|
address = fmt.Sprintf("unix(%s)", mysql.config.SocketPath)
|
||||||
} else if m.config.Port != 0 {
|
} else if mysql.config.Port != 0 {
|
||||||
address = fmt.Sprintf("tcp(%s:%d)", m.config.Host, m.config.Port)
|
address = fmt.Sprintf("tcp(%s:%d)", mysql.config.Host, mysql.config.Port)
|
||||||
}
|
}
|
||||||
|
|
||||||
m.db, err = sql.Open("mysql", fmt.Sprintf("%s:%s@%s/%s", m.config.User, m.config.Password, address, m.config.HistoryDatabase))
|
mysql.db, err = sql.Open("mysql", fmt.Sprintf("%s:%s@%s/%s", mysql.config.User, mysql.config.Password, address, mysql.config.HistoryDatabase))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.config.MaxConns != 0 {
|
if mysql.config.MaxConns != 0 {
|
||||||
m.db.SetMaxOpenConns(m.config.MaxConns)
|
mysql.db.SetMaxOpenConns(mysql.config.MaxConns)
|
||||||
m.db.SetMaxIdleConns(m.config.MaxConns)
|
mysql.db.SetMaxIdleConns(mysql.config.MaxConns)
|
||||||
}
|
}
|
||||||
if m.config.ConnMaxLifetime != 0 {
|
if mysql.config.ConnMaxLifetime != 0 {
|
||||||
m.db.SetConnMaxLifetime(m.config.ConnMaxLifetime)
|
mysql.db.SetConnMaxLifetime(mysql.config.ConnMaxLifetime)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = m.fixSchemas()
|
err = mysql.fixSchemas()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = m.prepareStatements()
|
err = mysql.prepareStatements()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
go m.cleanupLoop()
|
go mysql.cleanupLoop()
|
||||||
go m.forgetLoop()
|
go mysql.forgetLoop()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mysql *MySQL) fixSchemas() (err error) {
|
func (mysql *MySQL) fixSchemas() (err error) {
|
||||||
_, err = mysql.db.Exec(`CREATE TABLE IF NOT EXISTS metadata (
|
// 3M now handles this
|
||||||
key_name VARCHAR(32) primary key,
|
|
||||||
value VARCHAR(32) NOT NULL
|
|
||||||
) CHARSET=ascii COLLATE=ascii_bin;`)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var schema string
|
|
||||||
err = mysql.db.QueryRow(`select value from metadata where key_name = ?;`, keySchemaVersion).Scan(&schema)
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
err = mysql.createTables()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, err = mysql.db.Exec(`insert into metadata (key_name, value) values (?, ?);`, keySchemaVersion, latestDbSchema)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, err = mysql.db.Exec(`insert into metadata (key_name, value) values (?, ?);`, keySchemaMinorVersion, latestDbMinorVersion)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
} else if err == nil && schema != latestDbSchema {
|
|
||||||
// TODO figure out what to do about schema changes
|
|
||||||
return fmt.Errorf("incompatible schema: got %s, expected %s", schema, latestDbSchema)
|
|
||||||
} else if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var minorVersion string
|
|
||||||
err = mysql.db.QueryRow(`select value from metadata where key_name = ?;`, keySchemaMinorVersion).Scan(&minorVersion)
|
|
||||||
if err == sql.ErrNoRows {
|
|
||||||
// XXX for now, the only minor version upgrade is the account tracking tables
|
|
||||||
err = mysql.createComplianceTables()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = mysql.createCorrespondentsTable()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, err = mysql.db.Exec(`insert into metadata (key_name, value) values (?, ?);`, keySchemaMinorVersion, latestDbMinorVersion)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else if err == nil && minorVersion == "1" {
|
|
||||||
// upgrade from 2.1 to 2.2: create the correspondents table
|
|
||||||
err = mysql.createCorrespondentsTable()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, err = mysql.db.Exec(`update metadata set value = ? where key_name = ?;`, latestDbMinorVersion, keySchemaMinorVersion)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else if err == nil && minorVersion != latestDbMinorVersion {
|
|
||||||
// TODO: if minorVersion < latestDbMinorVersion, upgrade,
|
|
||||||
// if latestDbMinorVersion < minorVersion, ignore because backwards compatible
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mysql *MySQL) createTables() (err error) {
|
func (mysql *MySQL) createTables() (err error) {
|
||||||
_, err = mysql.db.Exec(`CREATE TABLE history (
|
// 3M now handles this
|
||||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
data BLOB NOT NULL,
|
|
||||||
msgid BINARY(16) NOT NULL,
|
|
||||||
KEY (msgid(4))
|
|
||||||
) CHARSET=ascii COLLATE=ascii_bin;`)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = mysql.db.Exec(fmt.Sprintf(`CREATE TABLE sequence (
|
|
||||||
history_id BIGINT UNSIGNED NOT NULL PRIMARY KEY,
|
|
||||||
target VARBINARY(%[1]d) NOT NULL,
|
|
||||||
nanotime BIGINT UNSIGNED NOT NULL,
|
|
||||||
KEY (target, nanotime)
|
|
||||||
) CHARSET=ascii COLLATE=ascii_bin;`, MaxTargetLength))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
/* XXX: this table used to be:
|
|
||||||
CREATE TABLE sequence (
|
|
||||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
target VARBINARY(%[1]d) NOT NULL,
|
|
||||||
nanotime BIGINT UNSIGNED NOT NULL,
|
|
||||||
history_id BIGINT NOT NULL,
|
|
||||||
KEY (target, nanotime),
|
|
||||||
KEY (history_id)
|
|
||||||
) CHARSET=ascii COLLATE=ascii_bin;
|
|
||||||
Some users may still be using the old schema.
|
|
||||||
*/
|
|
||||||
|
|
||||||
_, err = mysql.db.Exec(fmt.Sprintf(`CREATE TABLE conversations (
|
|
||||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
target VARBINARY(%[1]d) NOT NULL,
|
|
||||||
correspondent VARBINARY(%[1]d) NOT NULL,
|
|
||||||
nanotime BIGINT UNSIGNED NOT NULL,
|
|
||||||
history_id BIGINT NOT NULL,
|
|
||||||
KEY (target, correspondent, nanotime),
|
|
||||||
KEY (history_id)
|
|
||||||
) CHARSET=ascii COLLATE=ascii_bin;`, MaxTargetLength))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mysql.createCorrespondentsTable()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mysql.createComplianceTables()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mysql *MySQL) createCorrespondentsTable() (err error) {
|
|
||||||
_, err = mysql.db.Exec(fmt.Sprintf(`CREATE TABLE correspondents (
|
|
||||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
target VARBINARY(%[1]d) NOT NULL,
|
|
||||||
correspondent VARBINARY(%[1]d) NOT NULL,
|
|
||||||
nanotime BIGINT UNSIGNED NOT NULL,
|
|
||||||
UNIQUE KEY (target, correspondent),
|
|
||||||
KEY (target, nanotime),
|
|
||||||
KEY (nanotime)
|
|
||||||
) CHARSET=ascii COLLATE=ascii_bin;`, MaxTargetLength))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mysql *MySQL) createComplianceTables() (err error) {
|
func (mysql *MySQL) createComplianceTables() (err error) {
|
||||||
_, err = mysql.db.Exec(fmt.Sprintf(`CREATE TABLE account_messages (
|
// 3M now handles this
|
||||||
history_id BIGINT UNSIGNED NOT NULL PRIMARY KEY,
|
|
||||||
account VARBINARY(%[1]d) NOT NULL,
|
|
||||||
KEY (account, history_id)
|
|
||||||
) CHARSET=ascii COLLATE=ascii_bin;`, MaxTargetLength))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = mysql.db.Exec(fmt.Sprintf(`CREATE TABLE forget (
|
|
||||||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
||||||
account VARBINARY(%[1]d) NOT NULL
|
|
||||||
) CHARSET=ascii COLLATE=ascii_bin;`, MaxTargetLength))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -327,10 +182,6 @@ func (mysql *MySQL) doCleanup(age time.Duration) (count int, err error) {
|
||||||
|
|
||||||
mysql.logger.Debug("mysql", fmt.Sprintf("deleting %d history rows, max age %s", len(ids), utils.NanoToTimestamp(maxNanotime)))
|
mysql.logger.Debug("mysql", fmt.Sprintf("deleting %d history rows, max age %s", len(ids), utils.NanoToTimestamp(maxNanotime)))
|
||||||
|
|
||||||
if maxNanotime != 0 {
|
|
||||||
mysql.deleteCorrespondents(ctx, maxNanotime)
|
|
||||||
}
|
|
||||||
|
|
||||||
return len(ids), mysql.deleteHistoryIDs(ctx, ids)
|
return len(ids), mysql.deleteHistoryIDs(ctx, ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -347,21 +198,14 @@ func (mysql *MySQL) deleteHistoryIDs(ctx context.Context, ids []uint64) (err err
|
||||||
inBuf.WriteRune(')')
|
inBuf.WriteRune(')')
|
||||||
inClause := inBuf.String()
|
inClause := inBuf.String()
|
||||||
|
|
||||||
_, err = mysql.db.ExecContext(ctx, fmt.Sprintf(`DELETE FROM conversations WHERE history_id in %s;`, inClause))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, err = mysql.db.ExecContext(ctx, fmt.Sprintf(`DELETE FROM sequence WHERE history_id in %s;`, inClause))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if mysql.isTrackingAccountMessages() {
|
if mysql.isTrackingAccountMessages() {
|
||||||
_, err = mysql.db.ExecContext(ctx, fmt.Sprintf(`DELETE FROM account_messages WHERE history_id in %s;`, inClause))
|
_, err = mysql.db.ExecContext(ctx, fmt.Sprintf(`DELETE FROM account_messages WHERE history_id in %s;`, inClause))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_, err = mysql.db.ExecContext(ctx, fmt.Sprintf(`DELETE FROM history WHERE id in %s;`, inClause))
|
fmt.Printf(`DELETE FROM history WHERE msgid in %s;`, inClause)
|
||||||
|
_, err = mysql.db.ExecContext(ctx, fmt.Sprintf(`DELETE FROM history WHERE msgid in %s;`, inClause))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -370,57 +214,35 @@ func (mysql *MySQL) deleteHistoryIDs(ctx context.Context, ids []uint64) (err err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mysql *MySQL) selectCleanupIDs(ctx context.Context, age time.Duration) (ids []uint64, maxNanotime int64, err error) {
|
func (mysql *MySQL) selectCleanupIDs(ctx context.Context, age time.Duration) (ids []uint64, maxNanotime int64, err error) {
|
||||||
|
before := timestampSnowflake(time.Now().Add(-age))
|
||||||
|
maxNanotime = time.Now().Add(-age).Unix() * 1000000000
|
||||||
|
|
||||||
rows, err := mysql.db.QueryContext(ctx, `
|
rows, err := mysql.db.QueryContext(ctx, `
|
||||||
SELECT history.id, sequence.nanotime, conversations.nanotime
|
SELECT history.msgid
|
||||||
FROM history
|
FROM history
|
||||||
LEFT JOIN sequence ON history.id = sequence.history_id
|
WHERE msgid < ?
|
||||||
LEFT JOIN conversations on history.id = conversations.history_id
|
ORDER BY history.msgid LIMIT ?;`, before, cleanupRowLimit)
|
||||||
ORDER BY history.id LIMIT ?;`, cleanupRowLimit)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
idset := make(map[uint64]struct{}, cleanupRowLimit)
|
ids = make([]uint64, cleanupRowLimit)
|
||||||
threshold := time.Now().Add(-age).UnixNano()
|
|
||||||
|
i := 0
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var id uint64
|
var id uint64
|
||||||
var seqNano, convNano sql.NullInt64
|
err = rows.Scan(&id)
|
||||||
err = rows.Scan(&id, &seqNano, &convNano)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nanotime := extractNanotime(seqNano, convNano)
|
|
||||||
// returns 0 if not found; in that case the data is inconsistent
|
|
||||||
// and we should delete the entry
|
|
||||||
if nanotime < threshold {
|
|
||||||
idset[id] = struct{}{}
|
|
||||||
if nanotime > maxNanotime {
|
|
||||||
maxNanotime = nanotime
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ids = make([]uint64, len(idset))
|
|
||||||
i := 0
|
|
||||||
for id := range idset {
|
|
||||||
ids[i] = id
|
ids[i] = id
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
ids = ids[0:i]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mysql *MySQL) deleteCorrespondents(ctx context.Context, threshold int64) {
|
|
||||||
result, err := mysql.db.ExecContext(ctx, `DELETE FROM correspondents WHERE nanotime <= (?);`, threshold)
|
|
||||||
if err != nil {
|
|
||||||
mysql.logError("error deleting correspondents", err)
|
|
||||||
} else {
|
|
||||||
count, err := result.RowsAffected()
|
|
||||||
if !mysql.logError("error deleting correspondents", err) {
|
|
||||||
mysql.logger.Debug(fmt.Sprintf("deleted %d correspondents entries", count))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait for forget queue items and process them one by one
|
// wait for forget queue items and process them one by one
|
||||||
func (mysql *MySQL) forgetLoop() {
|
func (mysql *MySQL) forgetLoop() {
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|
@ -526,23 +348,7 @@ func (mysql *MySQL) doForgetIteration(account string) (count int, err error) {
|
||||||
|
|
||||||
func (mysql *MySQL) prepareStatements() (err error) {
|
func (mysql *MySQL) prepareStatements() (err error) {
|
||||||
mysql.insertHistory, err = mysql.db.Prepare(`INSERT INTO history
|
mysql.insertHistory, err = mysql.db.Prepare(`INSERT INTO history
|
||||||
(data, msgid) VALUES (?, ?);`)
|
(data, msgid, target, sender, nanotime) VALUES (?, ?, ?, ?, ?);`)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mysql.insertSequence, err = mysql.db.Prepare(`INSERT INTO sequence
|
|
||||||
(target, nanotime, history_id) VALUES (?, ?, ?);`)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mysql.insertConversation, err = mysql.db.Prepare(`INSERT INTO conversations
|
|
||||||
(target, correspondent, nanotime, history_id) VALUES (?, ?, ?, ?);`)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mysql.insertCorrespondent, err = mysql.db.Prepare(`INSERT INTO correspondents
|
|
||||||
(target, correspondent, nanotime) VALUES (?, ?, ?)
|
|
||||||
ON DUPLICATE KEY UPDATE nanotime = GREATEST(nanotime, ?);`)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -552,6 +358,38 @@ func (mysql *MySQL) prepareStatements() (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mysql.getReactionsQuery, err = mysql.db.Prepare(`select react, count(*) as total, (select JSON_ARRAYAGG(user)
|
||||||
|
from reactions r
|
||||||
|
where r.msgid = main.msgid
|
||||||
|
and r.react = main.react
|
||||||
|
limit 3) as sample
|
||||||
|
from reactions as main
|
||||||
|
where main.msgid = ?
|
||||||
|
group by react, msgid;`)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql.getSingleReaction, err = mysql.db.Prepare(`SELECT COUNT(*) FROM reactions WHERE msgid = ? AND user = ? AND react = ?`)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql.deleteReaction, err = mysql.db.Prepare(`DELETE FROM reactions WHERE msgid = ? AND user = ? AND react = ?`)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql.addReaction, err = mysql.db.Prepare(`INSERT INTO reactions(msgid, user, react) VALUES (?, ?, ?)`)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql.getMessageById, err = mysql.db.Prepare(`SELECT msgid, data, target, sender, nanotime, pm FROM history WHERE msgid = ?`)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -608,11 +446,6 @@ func (mysql *MySQL) AddChannelItem(target string, item history.Item, account str
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mysql.insertSequenceEntry(ctx, target, item.Message.Time.UnixNano(), id)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mysql.insertAccountMessageEntry(ctx, id, account)
|
err = mysql.insertAccountMessageEntry(ctx, id, account)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
@ -621,39 +454,21 @@ func (mysql *MySQL) AddChannelItem(target string, item history.Item, account str
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mysql *MySQL) insertSequenceEntry(ctx context.Context, target string, messageTime int64, id int64) (err error) {
|
|
||||||
_, err = mysql.insertSequence.ExecContext(ctx, target, messageTime, id)
|
|
||||||
mysql.logError("could not insert sequence entry", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mysql *MySQL) insertConversationEntry(ctx context.Context, target, correspondent string, messageTime int64, id int64) (err error) {
|
|
||||||
_, err = mysql.insertConversation.ExecContext(ctx, target, correspondent, messageTime, id)
|
|
||||||
mysql.logError("could not insert conversations entry", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mysql *MySQL) insertCorrespondentsEntry(ctx context.Context, target, correspondent string, messageTime int64, historyId int64) (err error) {
|
|
||||||
_, err = mysql.insertCorrespondent.ExecContext(ctx, target, correspondent, messageTime, messageTime)
|
|
||||||
mysql.logError("could not insert conversations entry", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mysql *MySQL) insertBase(ctx context.Context, item history.Item) (id int64, err error) {
|
func (mysql *MySQL) insertBase(ctx context.Context, item history.Item) (id int64, err error) {
|
||||||
value, err := marshalItem(&item)
|
var value []byte
|
||||||
|
value, err = marshalItem(&item)
|
||||||
if mysql.logError("could not marshal item", err) {
|
if mysql.logError("could not marshal item", err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
var account = item.Account
|
||||||
msgidBytes, err := decodeMsgid(item.Message.Msgid)
|
if account == "" {
|
||||||
if mysql.logError("could not decode msgid", err) {
|
account = "*"
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
result, err := mysql.insertHistory.ExecContext(ctx, value, item.Message.Msgid, item.Target, account, item.Message.Time.UnixNano())
|
||||||
result, err := mysql.insertHistory.ExecContext(ctx, value, msgidBytes)
|
|
||||||
if mysql.logError("could not insert item", err) {
|
if mysql.logError("could not insert item", err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err = result.LastInsertId()
|
id, err = result.LastInsertId()
|
||||||
if mysql.logError("could not insert item", err) {
|
if mysql.logError("could not insert item", err) {
|
||||||
return
|
return
|
||||||
|
|
@ -687,36 +502,7 @@ func (mysql *MySQL) AddDirectMessage(sender, senderAccount, recipient, recipient
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), mysql.getTimeout())
|
ctx, cancel := context.WithTimeout(context.Background(), mysql.getTimeout())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
id, err := mysql.insertBase(ctx, item)
|
_, err = mysql.insertBase(ctx, item)
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
nanotime := item.Message.Time.UnixNano()
|
|
||||||
|
|
||||||
if senderAccount != "" {
|
|
||||||
err = mysql.insertConversationEntry(ctx, senderAccount, recipient, nanotime, id)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = mysql.insertCorrespondentsEntry(ctx, senderAccount, recipient, nanotime, id)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if recipientAccount != "" && sender != recipient {
|
|
||||||
err = mysql.insertConversationEntry(ctx, recipientAccount, sender, nanotime, id)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = mysql.insertCorrespondentsEntry(ctx, recipientAccount, sender, nanotime, id)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = mysql.insertAccountMessageEntry(ctx, id, senderAccount)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -725,7 +511,7 @@ func (mysql *MySQL) AddDirectMessage(sender, senderAccount, recipient, recipient
|
||||||
}
|
}
|
||||||
|
|
||||||
// note that accountName is the unfolded name
|
// note that accountName is the unfolded name
|
||||||
func (mysql *MySQL) DeleteMsgid(msgid, accountName string) (err error) {
|
func (mysql *MySQL) DeleteMsgid(msgid, account string) (err error) {
|
||||||
if mysql.db == nil {
|
if mysql.db == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -738,11 +524,11 @@ func (mysql *MySQL) DeleteMsgid(msgid, accountName string) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if accountName != "*" {
|
if account != "*" {
|
||||||
var item history.Item
|
var item history.Item
|
||||||
err = unmarshalItem(data, &item)
|
err = unmarshalItem(data, &item)
|
||||||
// delete if the entry is corrupt
|
// delete if the entry is corrupt
|
||||||
if err == nil && item.AccountName != accountName {
|
if err == nil && item.Account != account {
|
||||||
return ErrDisallowed
|
return ErrDisallowed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -753,7 +539,10 @@ func (mysql *MySQL) DeleteMsgid(msgid, accountName string) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mysql *MySQL) Export(account string, writer io.Writer) {
|
func (mysql *MySQL) Export(account string, writer io.Writer) {
|
||||||
if mysql.db == nil {
|
// no eu presence...
|
||||||
|
// maybe fix this when i know the new schema works
|
||||||
|
return
|
||||||
|
/*if mysql.db == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -765,10 +554,8 @@ func (mysql *MySQL) Export(account string, writer io.Writer) {
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
rows, rowsErr := mysql.db.QueryContext(ctx, `
|
rows, rowsErr := mysql.db.QueryContext(ctx, `
|
||||||
SELECT account_messages.history_id, history.data, sequence.target FROM account_messages
|
SELECT history.data, msgid, target FROM history
|
||||||
INNER JOIN history ON history.id = account_messages.history_id
|
WHERE sender = ? AND account_messages.history_id > ?
|
||||||
INNER JOIN sequence ON account_messages.history_id = sequence.history_id
|
|
||||||
WHERE account_messages.account = ? AND account_messages.history_id > ?
|
|
||||||
LIMIT ?`, account, lastSeen, cleanupRowLimit)
|
LIMIT ?`, account, lastSeen, cleanupRowLimit)
|
||||||
if rowsErr != nil {
|
if rowsErr != nil {
|
||||||
err = rowsErr
|
err = rowsErr
|
||||||
|
|
@ -780,7 +567,7 @@ func (mysql *MySQL) Export(account string, writer io.Writer) {
|
||||||
var blob, jsonBlob []byte
|
var blob, jsonBlob []byte
|
||||||
var target string
|
var target string
|
||||||
var item history.Item
|
var item history.Item
|
||||||
err = rows.Scan(&id, &blob, &target)
|
err = rows.Scan(&blob, &id, &target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -788,7 +575,7 @@ func (mysql *MySQL) Export(account string, writer io.Writer) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
item.CfCorrespondent = target
|
item.Target = target
|
||||||
jsonBlob, err = json.Marshal(item)
|
jsonBlob, err = json.Marshal(item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
@ -808,28 +595,66 @@ func (mysql *MySQL) Export(account string, writer io.Writer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql.logError("could not export history", err)
|
mysql.logError("could not export history", err)
|
||||||
|
return*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kinda an intermediary function due to the CEF DB structure
|
||||||
|
func (mysql *MySQL) GetMessage(msgid string) (id uint64, item history.Item, target string, sender string, nanotime uint64, pm bool, err error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), mysql.getTimeout())
|
||||||
|
defer cancel()
|
||||||
|
var data []byte
|
||||||
|
|
||||||
|
row := mysql.getMessageById.QueryRowContext(ctx, msgid)
|
||||||
|
err = row.Scan(&id, &data, &target, &sender, &nanotime, &pm)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = unmarshalItem(data, &item)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mysql *MySQL) HasReactionFromUser(msgid string, user string, reaction string) (exists bool) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), mysql.getTimeout())
|
||||||
|
defer cancel()
|
||||||
|
row := mysql.getSingleReaction.QueryRowContext(ctx, msgid, user, reaction)
|
||||||
|
var count int
|
||||||
|
row.Scan(&count)
|
||||||
|
return count > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mysql *MySQL) AddReaction(msgid string, user string, reaction string) (err error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), mysql.getTimeout())
|
||||||
|
defer cancel()
|
||||||
|
_, err = mysql.addReaction.ExecContext(ctx, msgid, user, reaction)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mysql *MySQL) DeleteReaction(msgid string, user string, reaction string) (err error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), mysql.getTimeout())
|
||||||
|
defer cancel()
|
||||||
|
_, err = mysql.deleteReaction.ExecContext(ctx, msgid, user, reaction)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mysql *MySQL) lookupMsgid(ctx context.Context, msgid string, includeData bool) (result time.Time, id uint64, data []byte, err error) {
|
func (mysql *MySQL) lookupMsgid(ctx context.Context, msgid string, includeData bool) (result time.Time, id uint64, data []byte, err error) {
|
||||||
decoded, err := decodeMsgid(msgid)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cols := `sequence.nanotime, conversations.nanotime`
|
cols := `history.nanotime`
|
||||||
if includeData {
|
if includeData {
|
||||||
cols = `sequence.nanotime, conversations.nanotime, history.id, history.data`
|
cols = `history.nanotime, history.id, history.data`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Since CEF uses snowflakes and vanilla ergo uses blobs, we cast as int to make it function.
|
||||||
|
// May have to adjust it some day
|
||||||
row := mysql.db.QueryRowContext(ctx, fmt.Sprintf(`
|
row := mysql.db.QueryRowContext(ctx, fmt.Sprintf(`
|
||||||
SELECT %s FROM history
|
SELECT %s FROM history
|
||||||
LEFT JOIN sequence ON history.id = sequence.history_id
|
WHERE history.msgid = CAST(? AS UNSIGNED) LIMIT 1;`, cols), msgid)
|
||||||
LEFT JOIN conversations ON history.id = conversations.history_id
|
var nanoSeq sql.NullInt64
|
||||||
WHERE history.msgid = ? LIMIT 1;`, cols), decoded)
|
|
||||||
var nanoSeq, nanoConv sql.NullInt64
|
|
||||||
if !includeData {
|
if !includeData {
|
||||||
err = row.Scan(&nanoSeq, &nanoConv)
|
err = row.Scan(&nanoSeq)
|
||||||
} else {
|
} else {
|
||||||
err = row.Scan(&nanoSeq, &nanoConv, &id, &data)
|
err = row.Scan(&nanoSeq, &id, &data)
|
||||||
}
|
}
|
||||||
if err != sql.ErrNoRows {
|
if err != sql.ErrNoRows {
|
||||||
mysql.logError("could not resolve msgid to time", err)
|
mysql.logError("could not resolve msgid to time", err)
|
||||||
|
|
@ -837,7 +662,7 @@ func (mysql *MySQL) lookupMsgid(ctx context.Context, msgid string, includeData b
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nanotime := extractNanotime(nanoSeq, nanoConv)
|
nanotime := nanoSeq.Int64
|
||||||
if nanotime == 0 {
|
if nanotime == 0 {
|
||||||
err = sql.ErrNoRows
|
err = sql.ErrNoRows
|
||||||
return
|
return
|
||||||
|
|
@ -846,15 +671,6 @@ func (mysql *MySQL) lookupMsgid(ctx context.Context, msgid string, includeData b
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractNanotime(seq, conv sql.NullInt64) (result int64) {
|
|
||||||
if seq.Valid {
|
|
||||||
return seq.Int64
|
|
||||||
} else if conv.Valid {
|
|
||||||
return conv.Int64
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mysql *MySQL) selectItems(ctx context.Context, query string, args ...interface{}) (results []history.Item, err error) {
|
func (mysql *MySQL) selectItems(ctx context.Context, query string, args ...interface{}) (results []history.Item, err error) {
|
||||||
rows, err := mysql.db.QueryContext(ctx, query, args...)
|
rows, err := mysql.db.QueryContext(ctx, query, args...)
|
||||||
if mysql.logError("could not select history items", err) {
|
if mysql.logError("could not select history items", err) {
|
||||||
|
|
@ -865,8 +681,10 @@ func (mysql *MySQL) selectItems(ctx context.Context, query string, args ...inter
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var blob []byte
|
var blob []byte
|
||||||
|
var msgid uint64
|
||||||
var item history.Item
|
var item history.Item
|
||||||
err = rows.Scan(&blob)
|
|
||||||
|
err = rows.Scan(&blob, &msgid)
|
||||||
if mysql.logError("could not scan history item", err) {
|
if mysql.logError("could not scan history item", err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -874,17 +692,36 @@ func (mysql *MySQL) selectItems(ctx context.Context, query string, args ...inter
|
||||||
if mysql.logError("could not unmarshal history item", err) {
|
if mysql.logError("could not unmarshal history item", err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
reactions, rErr := mysql.getReactionsQuery.Query(msgid)
|
||||||
|
if mysql.logError("could not get reactions", rErr) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var react string
|
||||||
|
var total int
|
||||||
|
var sample string
|
||||||
|
for reactions.Next() {
|
||||||
|
reactions.Scan(&react, &total, &sample)
|
||||||
|
var sampleDecoded []string
|
||||||
|
json.Unmarshal([]byte(sample), &sampleDecoded)
|
||||||
|
|
||||||
|
item.Reactions = append(item.Reactions, history.Reaction{
|
||||||
|
Name: react,
|
||||||
|
Total: total,
|
||||||
|
SampleUsers: sampleDecoded,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
results = append(results, item)
|
results = append(results, item)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func timestampSnowflake(t time.Time) uint64 {
|
||||||
|
var ts = t.Unix() & 0xffffffffffff
|
||||||
|
return uint64(ts << 16)
|
||||||
|
}
|
||||||
|
|
||||||
func (mysql *MySQL) betweenTimestamps(ctx context.Context, target, correspondent string, after, before, cutoff time.Time, limit int) (results []history.Item, err error) {
|
func (mysql *MySQL) betweenTimestamps(ctx context.Context, target, correspondent string, after, before, cutoff time.Time, limit int) (results []history.Item, err error) {
|
||||||
useSequence := correspondent == ""
|
|
||||||
table := "sequence"
|
|
||||||
if !useSequence {
|
|
||||||
table = "conversations"
|
|
||||||
}
|
|
||||||
|
|
||||||
after, before, ascending := history.MinMaxAsc(after, before, cutoff)
|
after, before, ascending := history.MinMaxAsc(after, before, cutoff)
|
||||||
direction := "ASC"
|
direction := "ASC"
|
||||||
|
|
@ -893,27 +730,25 @@ func (mysql *MySQL) betweenTimestamps(ctx context.Context, target, correspondent
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryBuf strings.Builder
|
var queryBuf strings.Builder
|
||||||
|
args := make([]interface{}, 0, 7)
|
||||||
args := make([]interface{}, 0, 6)
|
if correspondent == "" {
|
||||||
fmt.Fprintf(&queryBuf,
|
fmt.Fprintf(&queryBuf, "SELECT data, msgid FROM history WHERE target = ? ")
|
||||||
"SELECT history.data from history INNER JOIN %[1]s ON history.id = %[1]s.history_id WHERE", table)
|
|
||||||
if useSequence {
|
|
||||||
fmt.Fprintf(&queryBuf, " sequence.target = ?")
|
|
||||||
args = append(args, target)
|
args = append(args, target)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(&queryBuf, " conversations.target = ? AND conversations.correspondent = ?")
|
fmt.Fprintf(&queryBuf, "SELECT data, msgid FROM history WHERE (target = ? and sender = ?) OR (target = ? and sender = ?)")
|
||||||
args = append(args, target)
|
args = append(args, target, correspondent, correspondent, target)
|
||||||
args = append(args, correspondent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !after.IsZero() {
|
if !after.IsZero() {
|
||||||
fmt.Fprintf(&queryBuf, " AND %s.nanotime > ?", table)
|
fmt.Fprintf(&queryBuf, " AND nanotime > ?")
|
||||||
args = append(args, after.UnixNano())
|
args = append(args, after.UnixNano())
|
||||||
}
|
}
|
||||||
if !before.IsZero() {
|
if !before.IsZero() {
|
||||||
fmt.Fprintf(&queryBuf, " AND %s.nanotime < ?", table)
|
fmt.Fprintf(&queryBuf, " AND nanotime <= ?")
|
||||||
args = append(args, before.UnixNano())
|
args = append(args, before.UnixNano())
|
||||||
}
|
}
|
||||||
fmt.Fprintf(&queryBuf, " ORDER BY %[1]s.nanotime %[2]s LIMIT ?;", table, direction)
|
|
||||||
|
fmt.Fprintf(&queryBuf, " ORDER BY nanotime %[1]s LIMIT ?;", direction)
|
||||||
args = append(args, limit)
|
args = append(args, limit)
|
||||||
|
|
||||||
results, err = mysql.selectItems(ctx, queryBuf.String(), args...)
|
results, err = mysql.selectItems(ctx, queryBuf.String(), args...)
|
||||||
|
|
@ -931,19 +766,19 @@ func (mysql *MySQL) listCorrespondentsInternal(ctx context.Context, target strin
|
||||||
}
|
}
|
||||||
|
|
||||||
var queryBuf strings.Builder
|
var queryBuf strings.Builder
|
||||||
args := make([]interface{}, 0, 4)
|
args := make([]interface{}, 0, 5)
|
||||||
queryBuf.WriteString(`SELECT correspondents.correspondent, correspondents.nanotime from correspondents
|
queryBuf.WriteString(`SELECT target, sender, nanotime from history
|
||||||
WHERE target = ?`)
|
WHERE target = ? OR (sender = ? and pm = true)`)
|
||||||
args = append(args, target)
|
args = append(args, target, target)
|
||||||
if !after.IsZero() {
|
if !after.IsZero() {
|
||||||
queryBuf.WriteString(" AND correspondents.nanotime > ?")
|
queryBuf.WriteString(" AND nanotime > ?")
|
||||||
args = append(args, after.UnixNano())
|
args = append(args, after.UnixNano())
|
||||||
}
|
}
|
||||||
if !before.IsZero() {
|
if !before.IsZero() {
|
||||||
queryBuf.WriteString(" AND correspondents.nanotime < ?")
|
queryBuf.WriteString(" AND nanotime < ?")
|
||||||
args = append(args, before.UnixNano())
|
args = append(args, before.UnixNano())
|
||||||
}
|
}
|
||||||
fmt.Fprintf(&queryBuf, " ORDER BY correspondents.nanotime %s LIMIT ?;", direction)
|
fmt.Fprintf(&queryBuf, " ORDER BY nanotime %s LIMIT ?;", direction)
|
||||||
args = append(args, limit)
|
args = append(args, limit)
|
||||||
query := queryBuf.String()
|
query := queryBuf.String()
|
||||||
|
|
||||||
|
|
@ -952,17 +787,26 @@ func (mysql *MySQL) listCorrespondentsInternal(ctx context.Context, target strin
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
var correspondent string
|
var msgTarget string
|
||||||
|
var msgSender string
|
||||||
var nanotime int64
|
var nanotime int64
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
err = rows.Scan(&correspondent, &nanotime)
|
err = rows.Scan(&msgTarget, &msgSender, &nanotime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if msgTarget == target {
|
||||||
results = append(results, history.TargetListing{
|
results = append(results, history.TargetListing{
|
||||||
CfName: correspondent,
|
CfName: msgSender,
|
||||||
Time: time.Unix(0, nanotime),
|
Time: time.Unix(0, nanotime),
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
results = append(results, history.TargetListing{
|
||||||
|
CfName: msgTarget,
|
||||||
|
Time: time.Unix(0, nanotime),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ascending {
|
if !ascending {
|
||||||
|
|
@ -1042,6 +886,7 @@ func (s *mySQLHistorySequence) Between(start, end history.Selector, limit int) (
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
startTime := start.Time
|
startTime := start.Time
|
||||||
|
|
||||||
if start.Msgid != "" {
|
if start.Msgid != "" {
|
||||||
startTime, _, _, err = s.mysql.lookupMsgid(ctx, start.Msgid, false)
|
startTime, _, _, err = s.mysql.lookupMsgid(ctx, start.Msgid, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1055,6 +900,7 @@ func (s *mySQLHistorySequence) Between(start, end history.Selector, limit int) (
|
||||||
endTime := end.Time
|
endTime := end.Time
|
||||||
if end.Msgid != "" {
|
if end.Msgid != "" {
|
||||||
endTime, _, _, err = s.mysql.lookupMsgid(ctx, end.Msgid, false)
|
endTime, _, _, err = s.mysql.lookupMsgid(ctx, end.Msgid, false)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
@ -1101,3 +947,41 @@ func (mysql *MySQL) MakeSequence(target, correspondent string, cutoff time.Time)
|
||||||
cutoff: cutoff,
|
cutoff: cutoff,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mysql *MySQL) GetPMs(casefoldedUser string) (results map[string]int64, err error) {
|
||||||
|
if mysql.db == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
results = make(map[string]int64)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), mysql.getTimeout())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
var queryBuf strings.Builder
|
||||||
|
args := make([]interface{}, 0)
|
||||||
|
|
||||||
|
queryBuf.WriteString(`SELECT max(nanotime), target, sender FROM history WHERE target = ? OR (sender = ? and pm = true) GROUP BY target, sender;`)
|
||||||
|
args = append(args, casefoldedUser, casefoldedUser)
|
||||||
|
|
||||||
|
rows, err := mysql.db.QueryContext(ctx, queryBuf.String(), args...)
|
||||||
|
if mysql.logError("could not get pms", err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var last int64
|
||||||
|
var target, sender string
|
||||||
|
for rows.Next() {
|
||||||
|
err = rows.Scan(&last, &target, &sender)
|
||||||
|
if mysql.logError("could not get pms", err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// We really don't need nanosecond precision
|
||||||
|
if target != casefoldedUser {
|
||||||
|
results[target] = last / 1000000
|
||||||
|
} else {
|
||||||
|
results[sender] = last / 1000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/ergochat/ergo/irc/history"
|
"github.com/ergochat/ergo/irc/history"
|
||||||
"github.com/ergochat/ergo/irc/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 123 / '{' is the magic number that means JSON;
|
// 123 / '{' is the magic number that means JSON;
|
||||||
|
|
@ -17,7 +16,3 @@ func marshalItem(item *history.Item) (result []byte, err error) {
|
||||||
func unmarshalItem(data []byte, result *history.Item) (err error) {
|
func unmarshalItem(data []byte, result *history.Item) (err error) {
|
||||||
return json.Unmarshal(data, result)
|
return json.Unmarshal(data, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeMsgid(msgid string) ([]byte, error) {
|
|
||||||
return utils.B32Encoder.DecodeString(msgid)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ func performNickChange(server *Server, client *Client, target *Client, session *
|
||||||
histItem := history.Item{
|
histItem := history.Item{
|
||||||
Type: history.Nick,
|
Type: history.Nick,
|
||||||
Nick: origNickMask,
|
Nick: origNickMask,
|
||||||
AccountName: details.accountName,
|
Account: details.account,
|
||||||
Message: message,
|
Message: message,
|
||||||
IsBot: isBot,
|
IsBot: isBot,
|
||||||
}
|
}
|
||||||
|
|
@ -123,6 +123,8 @@ func performNickChange(server *Server, client *Client, target *Client, session *
|
||||||
|
|
||||||
for _, channel := range target.Channels() {
|
for _, channel := range target.Channels() {
|
||||||
if channel.memberIsVisible(client) {
|
if channel.memberIsVisible(client) {
|
||||||
|
// I LOVE MUTATING STATE!
|
||||||
|
histItem.Target = channel.NameCasefolded()
|
||||||
channel.AddHistoryItem(histItem, details.account)
|
channel.AddHistoryItem(histItem, details.account)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@
|
||||||
package irc
|
package irc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/ergochat/ergo/irc/history"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ergochat/ergo/irc/caps"
|
"github.com/ergochat/ergo/irc/caps"
|
||||||
|
|
@ -121,8 +124,12 @@ func (rb *ResponseBuffer) AddFromClient(time time.Time, msgid string, fromNickMa
|
||||||
rb.AddMessage(msg)
|
rb.AddMessage(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddSplitMessageFromClient adds a new split message from a specific client to our queue.
|
|
||||||
func (rb *ResponseBuffer) AddSplitMessageFromClient(fromNickMask string, fromAccount string, isBot bool, tags map[string]string, command string, target string, message utils.SplitMessage) {
|
func (rb *ResponseBuffer) AddSplitMessageFromClient(fromNickMask string, fromAccount string, isBot bool, tags map[string]string, command string, target string, message utils.SplitMessage) {
|
||||||
|
rb.AddSplitMessageFromClientWithReactions(fromNickMask, fromAccount, isBot, tags, command, target, message, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddSplitMessageFromClient adds a new split message from a specific client to our queue.
|
||||||
|
func (rb *ResponseBuffer) AddSplitMessageFromClientWithReactions(fromNickMask string, fromAccount string, isBot bool, tags map[string]string, command string, target string, message utils.SplitMessage, reactions []history.Reaction) {
|
||||||
if message.Is512() {
|
if message.Is512() {
|
||||||
if message.Message == "" {
|
if message.Message == "" {
|
||||||
// XXX this is a TAGMSG
|
// XXX this is a TAGMSG
|
||||||
|
|
@ -142,8 +149,23 @@ func (rb *ResponseBuffer) AddSplitMessageFromClient(fromNickMask string, fromAcc
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
msgid = message.Msgid
|
msgid = message.Msgid
|
||||||
}
|
}
|
||||||
rb.AddFromClient(message.Time, msgid, fromNickMask, fromAccount, isBot, tags, command, target, messagePair.Message)
|
mergedTags := make(map[string]string)
|
||||||
|
for k, v := range tags {
|
||||||
|
mergedTags[k] = v
|
||||||
}
|
}
|
||||||
|
for k, v := range messagePair.Tags {
|
||||||
|
mergedTags[k] = v
|
||||||
|
}
|
||||||
|
rb.AddFromClient(message.Time, msgid, fromNickMask, fromAccount, isBot, mergedTags, command, target, messagePair.Message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if reactions != nil && len(reactions) >= 1 {
|
||||||
|
var text string
|
||||||
|
for _, react := range reactions {
|
||||||
|
text = strings.Join([]string{message.Msgid, react.Name, strconv.Itoa(react.Total)}, " ")
|
||||||
|
text += " " + strings.Join(react.SampleUsers, " ")
|
||||||
|
rb.Add(nil, rb.target.server.name, "REACTIONS", text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,9 @@ func sendRoleplayMessage(server *Server, client *Client, source string, targetSt
|
||||||
Type: history.Privmsg,
|
Type: history.Privmsg,
|
||||||
Message: splitMessage,
|
Message: splitMessage,
|
||||||
Nick: sourceMask,
|
Nick: sourceMask,
|
||||||
|
Target: target,
|
||||||
|
// TODO: does this work?
|
||||||
|
Account: "$RP",
|
||||||
}, client.Account())
|
}, client.Account())
|
||||||
} else {
|
} else {
|
||||||
target, err := CasefoldName(targetString)
|
target, err := CasefoldName(targetString)
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,11 @@ package irc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
|
"net/http"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
@ -21,7 +24,27 @@ type scriptResponse struct {
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RunHttp(command string, args []string, input []byte, timeout time.Duration) (output []byte, err error) {
|
||||||
|
client := http.Client{
|
||||||
|
Timeout: timeout,
|
||||||
|
}
|
||||||
|
post, err := client.Post(command, "application/json", bytes.NewBuffer(input))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer post.Body.Close()
|
||||||
|
output, err = io.ReadAll(post.Body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func RunScript(command string, args []string, input []byte, timeout, killTimeout time.Duration) (output []byte, err error) {
|
func RunScript(command string, args []string, input []byte, timeout, killTimeout time.Duration) (output []byte, err error) {
|
||||||
|
if strings.HasPrefix(command, "http") {
|
||||||
|
return RunHttp(command, args, input, timeout)
|
||||||
|
}
|
||||||
cmd := exec.Command(command, args...)
|
cmd := exec.Command(command, args...)
|
||||||
stdin, err := cmd.StdinPipe()
|
stdin, err := cmd.StdinPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ import (
|
||||||
"github.com/ergochat/ergo/irc/mysql"
|
"github.com/ergochat/ergo/irc/mysql"
|
||||||
"github.com/ergochat/ergo/irc/sno"
|
"github.com/ergochat/ergo/irc/sno"
|
||||||
"github.com/ergochat/ergo/irc/utils"
|
"github.com/ergochat/ergo/irc/utils"
|
||||||
|
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -96,6 +98,9 @@ type Server struct {
|
||||||
semaphores ServerSemaphores
|
semaphores ServerSemaphores
|
||||||
flock flock.Flocker
|
flock flock.Flocker
|
||||||
defcon atomic.Uint32
|
defcon atomic.Uint32
|
||||||
|
|
||||||
|
// CEF
|
||||||
|
redis *redis.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServer returns a new Oragono server.
|
// NewServer returns a new Oragono server.
|
||||||
|
|
@ -163,6 +168,13 @@ func (server *Server) Shutdown() {
|
||||||
func (server *Server) Run() {
|
func (server *Server) Run() {
|
||||||
defer server.Shutdown()
|
defer server.Shutdown()
|
||||||
|
|
||||||
|
redisOpts, err := redis.ParseURL(server.Config().Cef.Redis)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
server.redis = redis.NewClient(redisOpts)
|
||||||
|
startRedis(server)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-server.exitSignals:
|
case <-server.exitSignals:
|
||||||
|
|
@ -434,7 +446,9 @@ func (server *Server) playRegistrationBurst(session *Session) {
|
||||||
session.Send(nil, server.name, RPL_MYINFO, d.nick, server.name, Ver, rplMyInfo1, rplMyInfo2, rplMyInfo3)
|
session.Send(nil, server.name, RPL_MYINFO, d.nick, server.name, Ver, rplMyInfo1, rplMyInfo2, rplMyInfo3)
|
||||||
|
|
||||||
rb := NewResponseBuffer(session)
|
rb := NewResponseBuffer(session)
|
||||||
|
if !(rb.session.capabilities.Has(caps.ExtendedISupport) && rb.session.isupportSentPrereg) {
|
||||||
server.RplISupport(c, rb)
|
server.RplISupport(c, rb)
|
||||||
|
}
|
||||||
if d.account != "" && session.capabilities.Has(caps.Persistence) {
|
if d.account != "" && session.capabilities.Has(caps.Persistence) {
|
||||||
reportPersistenceStatus(c, rb, false)
|
reportPersistenceStatus(c, rb, false)
|
||||||
}
|
}
|
||||||
|
|
@ -456,10 +470,17 @@ func (server *Server) playRegistrationBurst(session *Session) {
|
||||||
|
|
||||||
// RplISupport outputs our ISUPPORT lines to the client. This is used on connection and in VERSION responses.
|
// RplISupport outputs our ISUPPORT lines to the client. This is used on connection and in VERSION responses.
|
||||||
func (server *Server) RplISupport(client *Client, rb *ResponseBuffer) {
|
func (server *Server) RplISupport(client *Client, rb *ResponseBuffer) {
|
||||||
|
server.sendRplISupportLines(client, rb, server.Config().Server.isupport.CachedReply)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (server *Server) sendRplISupportLines(client *Client, rb *ResponseBuffer, lines [][]string) {
|
||||||
|
if rb.session.capabilities.Has(caps.ExtendedISupport) {
|
||||||
|
batchID := rb.StartNestedBatch(caps.ExtendedISupportBatchType)
|
||||||
|
defer rb.EndNestedBatch(batchID)
|
||||||
|
}
|
||||||
translatedISupport := client.t("are supported by this server")
|
translatedISupport := client.t("are supported by this server")
|
||||||
nick := client.Nick()
|
nick := client.Nick()
|
||||||
config := server.Config()
|
for _, cachedTokenLine := range lines {
|
||||||
for _, cachedTokenLine := range config.Server.isupport.CachedReply {
|
|
||||||
length := len(cachedTokenLine) + 2
|
length := len(cachedTokenLine) + 2
|
||||||
tokenline := make([]string, length)
|
tokenline := make([]string, length)
|
||||||
tokenline[0] = nick
|
tokenline[0] = nick
|
||||||
|
|
@ -794,13 +815,19 @@ func (server *Server) applyConfig(config *Config) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !initial {
|
if !initial {
|
||||||
// push new info to all of our clients
|
// send 005 updates (somewhat rare)
|
||||||
|
if len(newISupportReplies) != 0 {
|
||||||
for _, sClient := range server.clients.AllClients() {
|
for _, sClient := range server.clients.AllClients() {
|
||||||
for _, tokenline := range newISupportReplies {
|
for _, session := range sClient.Sessions() {
|
||||||
sClient.Send(nil, server.name, RPL_ISUPPORT, append([]string{sClient.nick}, tokenline...)...)
|
rb := NewResponseBuffer(session)
|
||||||
|
server.sendRplISupportLines(sClient, rb, newISupportReplies)
|
||||||
|
rb.Send(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sendRawOutputNotice {
|
if sendRawOutputNotice {
|
||||||
|
for _, sClient := range server.clients.AllClients() {
|
||||||
sClient.Notice(sClient.t("This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
|
sClient.Notice(sClient.t("This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1052,7 +1079,7 @@ func (server *Server) ForgetHistory(accountName string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate := func(item *history.Item) bool { return item.AccountName == accountName }
|
predicate := func(item *history.Item) bool { return item.Account == accountName }
|
||||||
|
|
||||||
for _, channel := range server.channels.Channels() {
|
for _, channel := range server.channels.Channels() {
|
||||||
channel.history.Delete(predicate)
|
channel.history.Delete(predicate)
|
||||||
|
|
@ -1066,7 +1093,7 @@ func (server *Server) ForgetHistory(accountName string) {
|
||||||
// deletes a message. target is a hint about what buffer it's in (not required for
|
// deletes a message. target is a hint about what buffer it's in (not required for
|
||||||
// persistent history, where all the msgids are indexed together). if accountName
|
// persistent history, where all the msgids are indexed together). if accountName
|
||||||
// is anything other than "*", it must match the recorded AccountName of the message
|
// is anything other than "*", it must match the recorded AccountName of the message
|
||||||
func (server *Server) DeleteMessage(target, msgid, accountName string) (err error) {
|
func (server *Server) DeleteMessage(target, msgid, account string) (err error) {
|
||||||
config := server.Config()
|
config := server.Config()
|
||||||
var hist *history.Buffer
|
var hist *history.Buffer
|
||||||
|
|
||||||
|
|
@ -1089,10 +1116,10 @@ func (server *Server) DeleteMessage(target, msgid, accountName string) (err erro
|
||||||
}
|
}
|
||||||
|
|
||||||
if hist == nil {
|
if hist == nil {
|
||||||
err = server.historyDB.DeleteMsgid(msgid, accountName)
|
err = server.historyDB.DeleteMsgid(msgid, account)
|
||||||
} else {
|
} else {
|
||||||
count := hist.Delete(func(item *history.Item) bool {
|
count := hist.Delete(func(item *history.Item) bool {
|
||||||
return item.Message.Msgid == msgid && (accountName == "*" || item.AccountName == accountName)
|
return item.Message.Msgid == msgid && (account == "*" || item.Account == account)
|
||||||
})
|
})
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
err = errNoop
|
err = errNoop
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,10 @@ func (service *ircService) Notice(rb *ResponseBuffer, text string) {
|
||||||
rb.Add(nil, service.prefix, "NOTICE", rb.target.Nick(), text)
|
rb.Add(nil, service.prefix, "NOTICE", rb.target.Nick(), text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (service *ircService) TaggedNotice(rb *ResponseBuffer, text string, tags map[string]string) {
|
||||||
|
rb.Add(tags, service.prefix, "NOTICE", rb.target.Nick(), text)
|
||||||
|
}
|
||||||
|
|
||||||
// all service commands at the protocol level, by uppercase command name
|
// all service commands at the protocol level, by uppercase command name
|
||||||
// e.g., NICKSERV, NS
|
// e.g., NICKSERV, NS
|
||||||
var ergoServicesByCommandAlias map[string]*ircService
|
var ergoServicesByCommandAlias map[string]*ircService
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
@ -31,8 +32,26 @@ var (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SecretTokenLength = 26
|
SecretTokenLength = 26
|
||||||
|
MachineId = 1 // Since there's no scaling Ergo, id is fixed at 1. Other things can have 2-127
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var inc uint64 = 0
|
||||||
|
|
||||||
|
// slingamn, if you ever see this, i'm sorry - I just didn't want to attach what i think is redundant data to every
|
||||||
|
// message.
|
||||||
|
func GenerateMessageId() uint64 {
|
||||||
|
inc++
|
||||||
|
var ts = time.Now().Unix() & 0xffffffffffff
|
||||||
|
var flake = uint64(ts << 16)
|
||||||
|
flake |= MachineId << 10
|
||||||
|
flake |= inc % 0x3ff
|
||||||
|
return flake
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateMessageIdStr() string {
|
||||||
|
return strconv.FormatUint(GenerateMessageId(), 10)
|
||||||
|
}
|
||||||
|
|
||||||
// generate a secret token that cannot be brute-forced via online attacks
|
// generate a secret token that cannot be brute-forced via online attacks
|
||||||
func GenerateSecretToken() string {
|
func GenerateSecretToken() string {
|
||||||
// 128 bits of entropy are enough to resist any online attack:
|
// 128 bits of entropy are enough to resist any online attack:
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ func IsRestrictedCTCPMessage(message string) bool {
|
||||||
|
|
||||||
type MessagePair struct {
|
type MessagePair struct {
|
||||||
Message string
|
Message string
|
||||||
|
Tags map[string]string
|
||||||
Concat bool // should be relayed with the multiline-concat tag
|
Concat bool // should be relayed with the multiline-concat tag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,19 +38,20 @@ type SplitMessage struct {
|
||||||
|
|
||||||
func MakeMessage(original string) (result SplitMessage) {
|
func MakeMessage(original string) (result SplitMessage) {
|
||||||
result.Message = original
|
result.Message = original
|
||||||
result.Msgid = GenerateSecretToken()
|
result.Msgid = GenerateMessageIdStr()
|
||||||
result.SetTime()
|
result.SetTime()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *SplitMessage) Append(message string, concat bool) {
|
func (sm *SplitMessage) Append(message string, concat bool, tags map[string]string) {
|
||||||
if sm.Msgid == "" {
|
if sm.Msgid == "" {
|
||||||
sm.Msgid = GenerateSecretToken()
|
sm.Msgid = GenerateMessageIdStr()
|
||||||
}
|
}
|
||||||
sm.Split = append(sm.Split, MessagePair{
|
sm.Split = append(sm.Split, MessagePair{
|
||||||
Message: message,
|
Message: message,
|
||||||
Concat: concat,
|
Concat: concat,
|
||||||
|
Tags: tags,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import "fmt"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// SemVer is the semantic version of Ergo.
|
// SemVer is the semantic version of Ergo.
|
||||||
SemVer = "2.14.0"
|
SemVer = "2.15.0-unreleased"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,7 @@ func zncPlayPrivmsgsFrom(client *Client, rb *ResponseBuffer, target string, star
|
||||||
zncMax := client.server.Config().History.ZNCMax
|
zncMax := client.server.Config().History.ZNCMax
|
||||||
items, err := sequence.Between(history.Selector{Time: start}, history.Selector{Time: end}, zncMax)
|
items, err := sequence.Between(history.Selector{Time: start}, history.Selector{Time: end}, zncMax)
|
||||||
if err == nil && len(items) != 0 {
|
if err == nil && len(items) != 0 {
|
||||||
client.replayPrivmsgHistory(rb, items, target, false)
|
client.replayPrivmsgHistory(rb, items, target, false, "", "", 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,7 +211,7 @@ func zncPlayPrivmsgsFromAll(client *Client, rb *ResponseBuffer, start, end time.
|
||||||
zncMax := client.server.Config().History.ZNCMax
|
zncMax := client.server.Config().History.ZNCMax
|
||||||
items, err := client.privmsgsBetween(start, end, maxDMTargetsForAutoplay, zncMax)
|
items, err := client.privmsgsBetween(start, end, maxDMTargetsForAutoplay, zncMax)
|
||||||
if err == nil && len(items) != 0 {
|
if err == nil && len(items) != 0 {
|
||||||
client.replayPrivmsgHistory(rb, items, "", false)
|
client.replayPrivmsgHistory(rb, items, "", false, "", "", 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
2
irctest
2
irctest
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9856317a64e0b72f925bd1a77cbce7e0f460eb59
|
Subproject commit a1324407893b603fe6b55ce7c4ee385938291ae1
|
||||||
|
|
@ -791,7 +791,7 @@ lock-file: "ircd.lock"
|
||||||
|
|
||||||
# datastore configuration
|
# datastore configuration
|
||||||
datastore:
|
datastore:
|
||||||
# path to the datastore
|
# path to the database file (used to store account and channel registrations):
|
||||||
path: ircd.db
|
path: ircd.db
|
||||||
|
|
||||||
# if the database schema requires an upgrade, `autoupgrade` will attempt to
|
# if the database schema requires an upgrade, `autoupgrade` will attempt to
|
||||||
|
|
|
||||||
20
vendor/github.com/ergochat/irc-go/ircmsg/message.go
generated
vendored
20
vendor/github.com/ergochat/irc-go/ircmsg/message.go
generated
vendored
|
|
@ -196,6 +196,15 @@ func trimInitialSpaces(str string) string {
|
||||||
return str[i:]
|
return str[i:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isASCII(str string) bool {
|
||||||
|
for i := 0; i < len(str); i++ {
|
||||||
|
if str[i] > 127 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func parseLine(line string, maxTagDataLength int, truncateLen int) (ircmsg Message, err error) {
|
func parseLine(line string, maxTagDataLength int, truncateLen int) (ircmsg Message, err error) {
|
||||||
// remove either \n or \r\n from the end of the line:
|
// remove either \n or \r\n from the end of the line:
|
||||||
line = strings.TrimSuffix(line, "\n")
|
line = strings.TrimSuffix(line, "\n")
|
||||||
|
|
@ -265,11 +274,16 @@ func parseLine(line string, maxTagDataLength int, truncateLen int) (ircmsg Messa
|
||||||
commandEnd = len(line)
|
commandEnd = len(line)
|
||||||
paramStart = len(line)
|
paramStart = len(line)
|
||||||
}
|
}
|
||||||
// normalize command to uppercase:
|
baseCommand := line[:commandEnd]
|
||||||
ircmsg.Command = strings.ToUpper(line[:commandEnd])
|
if len(baseCommand) == 0 {
|
||||||
if len(ircmsg.Command) == 0 {
|
|
||||||
return ircmsg, ErrorLineIsEmpty
|
return ircmsg, ErrorLineIsEmpty
|
||||||
}
|
}
|
||||||
|
// technically this must be either letters or a 3-digit numeric:
|
||||||
|
if !isASCII(baseCommand) {
|
||||||
|
return ircmsg, ErrorLineContainsBadChar
|
||||||
|
}
|
||||||
|
// normalize command to uppercase:
|
||||||
|
ircmsg.Command = strings.ToUpper(baseCommand)
|
||||||
line = line[paramStart:]
|
line = line[paramStart:]
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
|
|
||||||
44
vendor/github.com/ergochat/irc-go/ircutils/sasl.go
generated
vendored
44
vendor/github.com/ergochat/irc-go/ircutils/sasl.go
generated
vendored
|
|
@ -3,7 +3,6 @@ package ircutils
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -25,6 +24,7 @@ func EncodeSASLResponse(raw []byte) (result []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
response := base64.StdEncoding.EncodeToString(raw)
|
response := base64.StdEncoding.EncodeToString(raw)
|
||||||
|
result = make([]string, 0, (len(response)/400)+1)
|
||||||
lastLen := 0
|
lastLen := 0
|
||||||
for len(response) > 0 {
|
for len(response) > 0 {
|
||||||
// TODO once we require go 1.21, this can be: lastLen = min(len(response), 400)
|
// TODO once we require go 1.21, this can be: lastLen = min(len(response), 400)
|
||||||
|
|
@ -48,11 +48,11 @@ func EncodeSASLResponse(raw []byte) (result []string) {
|
||||||
// Do not copy a SASLBuffer after first use.
|
// Do not copy a SASLBuffer after first use.
|
||||||
type SASLBuffer struct {
|
type SASLBuffer struct {
|
||||||
maxLength int
|
maxLength int
|
||||||
buffer strings.Builder
|
buf []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSASLBuffer returns a new SASLBuffer. maxLength is the maximum amount of
|
// NewSASLBuffer returns a new SASLBuffer. maxLength is the maximum amount of
|
||||||
// base64'ed data to buffer (0 for no limit).
|
// data to buffer (0 for no limit).
|
||||||
func NewSASLBuffer(maxLength int) *SASLBuffer {
|
func NewSASLBuffer(maxLength int) *SASLBuffer {
|
||||||
result := new(SASLBuffer)
|
result := new(SASLBuffer)
|
||||||
result.Initialize(maxLength)
|
result.Initialize(maxLength)
|
||||||
|
|
@ -69,37 +69,43 @@ func (b *SASLBuffer) Initialize(maxLength int) {
|
||||||
// response along with any decoding or protocol errors detected.
|
// response along with any decoding or protocol errors detected.
|
||||||
func (b *SASLBuffer) Add(value string) (done bool, output []byte, err error) {
|
func (b *SASLBuffer) Add(value string) (done bool, output []byte, err error) {
|
||||||
if value == "+" {
|
if value == "+" {
|
||||||
output, err = b.getAndReset()
|
// total size is a multiple of 400 (possibly 0)
|
||||||
return true, output, err
|
output = b.buf
|
||||||
|
b.Clear()
|
||||||
|
return true, output, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(value) > 400 {
|
if len(value) > 400 {
|
||||||
b.buffer.Reset()
|
b.Clear()
|
||||||
return true, nil, ErrSASLTooLong
|
return true, nil, ErrSASLTooLong
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.maxLength != 0 && (b.buffer.Len()+len(value)) > b.maxLength {
|
curLen := len(b.buf)
|
||||||
b.buffer.Reset()
|
chunkDecodedLen := base64.StdEncoding.DecodedLen(len(value))
|
||||||
|
if b.maxLength != 0 && (curLen+chunkDecodedLen) > b.maxLength {
|
||||||
|
b.Clear()
|
||||||
return true, nil, ErrSASLLimitExceeded
|
return true, nil, ErrSASLLimitExceeded
|
||||||
}
|
}
|
||||||
|
|
||||||
b.buffer.WriteString(value)
|
// "append-make pattern" as in the bytes.Buffer implementation:
|
||||||
|
b.buf = append(b.buf, make([]byte, chunkDecodedLen)...)
|
||||||
|
n, err := base64.StdEncoding.Decode(b.buf[curLen:], []byte(value))
|
||||||
|
b.buf = b.buf[0 : curLen+n]
|
||||||
|
if err != nil {
|
||||||
|
b.Clear()
|
||||||
|
return true, nil, err
|
||||||
|
}
|
||||||
if len(value) < 400 {
|
if len(value) < 400 {
|
||||||
output, err = b.getAndReset()
|
output = b.buf
|
||||||
return true, output, err
|
b.Clear()
|
||||||
|
return true, output, nil
|
||||||
} else {
|
} else {
|
||||||
// 400 bytes, wait for continuation line or +
|
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear resets the buffer state.
|
// Clear resets the buffer state.
|
||||||
func (b *SASLBuffer) Clear() {
|
func (b *SASLBuffer) Clear() {
|
||||||
b.buffer.Reset()
|
// we can't reuse this buffer in general since we may have returned it
|
||||||
}
|
b.buf = nil
|
||||||
|
|
||||||
func (b *SASLBuffer) getAndReset() (output []byte, err error) {
|
|
||||||
output, err = base64.StdEncoding.DecodeString(b.buffer.String())
|
|
||||||
b.buffer.Reset()
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
vendor/github.com/golang-jwt/jwt/v5/ecdsa.go
generated
vendored
4
vendor/github.com/golang-jwt/jwt/v5/ecdsa.go
generated
vendored
|
|
@ -62,7 +62,7 @@ func (m *SigningMethodECDSA) Verify(signingString string, sig []byte, key interf
|
||||||
case *ecdsa.PublicKey:
|
case *ecdsa.PublicKey:
|
||||||
ecdsaKey = k
|
ecdsaKey = k
|
||||||
default:
|
default:
|
||||||
return newError("ECDSA verify expects *ecsda.PublicKey", ErrInvalidKeyType)
|
return newError("ECDSA verify expects *ecdsa.PublicKey", ErrInvalidKeyType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(sig) != 2*m.KeySize {
|
if len(sig) != 2*m.KeySize {
|
||||||
|
|
@ -96,7 +96,7 @@ func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) ([]byte
|
||||||
case *ecdsa.PrivateKey:
|
case *ecdsa.PrivateKey:
|
||||||
ecdsaKey = k
|
ecdsaKey = k
|
||||||
default:
|
default:
|
||||||
return nil, newError("ECDSA sign expects *ecsda.PrivateKey", ErrInvalidKeyType)
|
return nil, newError("ECDSA sign expects *ecdsa.PrivateKey", ErrInvalidKeyType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the hasher
|
// Create the hasher
|
||||||
|
|
|
||||||
4
vendor/github.com/golang-jwt/jwt/v5/hmac.go
generated
vendored
4
vendor/github.com/golang-jwt/jwt/v5/hmac.go
generated
vendored
|
|
@ -91,7 +91,7 @@ func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key interfa
|
||||||
func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) ([]byte, error) {
|
func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) ([]byte, error) {
|
||||||
if keyBytes, ok := key.([]byte); ok {
|
if keyBytes, ok := key.([]byte); ok {
|
||||||
if !m.Hash.Available() {
|
if !m.Hash.Available() {
|
||||||
return nil, newError("HMAC sign expects []byte", ErrInvalidKeyType)
|
return nil, ErrHashUnavailable
|
||||||
}
|
}
|
||||||
|
|
||||||
hasher := hmac.New(m.Hash.New, keyBytes)
|
hasher := hmac.New(m.Hash.New, keyBytes)
|
||||||
|
|
@ -100,5 +100,5 @@ func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) ([]byte,
|
||||||
return hasher.Sum(nil), nil
|
return hasher.Sum(nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, ErrInvalidKeyType
|
return nil, newError("HMAC sign expects []byte", ErrInvalidKeyType)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
32
vendor/github.com/tidwall/buntdb/buntdb.go
generated
vendored
32
vendor/github.com/tidwall/buntdb/buntdb.go
generated
vendored
|
|
@ -61,6 +61,8 @@ var (
|
||||||
ErrTxIterating = errors.New("tx is iterating")
|
ErrTxIterating = errors.New("tx is iterating")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const useAbsEx = true
|
||||||
|
|
||||||
// DB represents a collection of key-value pairs that persist on disk.
|
// DB represents a collection of key-value pairs that persist on disk.
|
||||||
// Transactions are used for all forms of data access to the DB.
|
// Transactions are used for all forms of data access to the DB.
|
||||||
type DB struct {
|
type DB struct {
|
||||||
|
|
@ -895,24 +897,35 @@ func (db *DB) readLoad(rd io.Reader, modTime time.Time) (n int64, err error) {
|
||||||
return totalSize, ErrInvalid
|
return totalSize, ErrInvalid
|
||||||
}
|
}
|
||||||
if len(parts) == 5 {
|
if len(parts) == 5 {
|
||||||
if strings.ToLower(parts[3]) != "ex" {
|
arg := strings.ToLower(parts[3])
|
||||||
|
if arg != "ex" && arg != "ae" {
|
||||||
return totalSize, ErrInvalid
|
return totalSize, ErrInvalid
|
||||||
}
|
}
|
||||||
ex, err := strconv.ParseUint(parts[4], 10, 64)
|
ex, err := strconv.ParseInt(parts[4], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return totalSize, err
|
return totalSize, err
|
||||||
}
|
}
|
||||||
|
var exat time.Time
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
if arg == "ex" {
|
||||||
dur := (time.Duration(ex) * time.Second) - now.Sub(modTime)
|
dur := (time.Duration(ex) * time.Second) - now.Sub(modTime)
|
||||||
if dur > 0 {
|
exat = now.Add(dur)
|
||||||
|
} else {
|
||||||
|
exat = time.Unix(ex, 0)
|
||||||
|
}
|
||||||
|
if exat.After(now) {
|
||||||
db.insertIntoDatabase(&dbItem{
|
db.insertIntoDatabase(&dbItem{
|
||||||
key: parts[1],
|
key: parts[1],
|
||||||
val: parts[2],
|
val: parts[2],
|
||||||
opts: &dbItemOpts{
|
opts: &dbItemOpts{
|
||||||
ex: true,
|
ex: true,
|
||||||
exat: now.Add(dur),
|
exat: exat,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
db.deleteFromDatabase(&dbItem{
|
||||||
|
key: parts[1],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
db.insertIntoDatabase(&dbItem{key: parts[1], val: parts[2]})
|
db.insertIntoDatabase(&dbItem{key: parts[1], val: parts[2]})
|
||||||
|
|
@ -1330,13 +1343,19 @@ func appendBulkString(buf []byte, s string) []byte {
|
||||||
// writeSetTo writes an item as a single SET record to the a bufio Writer.
|
// writeSetTo writes an item as a single SET record to the a bufio Writer.
|
||||||
func (dbi *dbItem) writeSetTo(buf []byte, now time.Time) []byte {
|
func (dbi *dbItem) writeSetTo(buf []byte, now time.Time) []byte {
|
||||||
if dbi.opts != nil && dbi.opts.ex {
|
if dbi.opts != nil && dbi.opts.ex {
|
||||||
ex := dbi.opts.exat.Sub(now) / time.Second
|
|
||||||
buf = appendArray(buf, 5)
|
buf = appendArray(buf, 5)
|
||||||
buf = appendBulkString(buf, "set")
|
buf = appendBulkString(buf, "set")
|
||||||
buf = appendBulkString(buf, dbi.key)
|
buf = appendBulkString(buf, dbi.key)
|
||||||
buf = appendBulkString(buf, dbi.val)
|
buf = appendBulkString(buf, dbi.val)
|
||||||
|
if useAbsEx {
|
||||||
|
ex := dbi.opts.exat.Unix()
|
||||||
|
buf = appendBulkString(buf, "ae")
|
||||||
|
buf = appendBulkString(buf, strconv.FormatUint(uint64(ex), 10))
|
||||||
|
} else {
|
||||||
|
ex := dbi.opts.exat.Sub(now) / time.Second
|
||||||
buf = appendBulkString(buf, "ex")
|
buf = appendBulkString(buf, "ex")
|
||||||
buf = appendBulkString(buf, strconv.FormatUint(uint64(ex), 10))
|
buf = appendBulkString(buf, strconv.FormatUint(uint64(ex), 10))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
buf = appendArray(buf, 3)
|
buf = appendArray(buf, 3)
|
||||||
buf = appendBulkString(buf, "set")
|
buf = appendBulkString(buf, "set")
|
||||||
|
|
@ -1622,6 +1641,9 @@ func (tx *Tx) scan(desc, gt, lt bool, index, start, stop string,
|
||||||
// wrap a btree specific iterator around the user-defined iterator.
|
// wrap a btree specific iterator around the user-defined iterator.
|
||||||
iter := func(item interface{}) bool {
|
iter := func(item interface{}) bool {
|
||||||
dbi := item.(*dbItem)
|
dbi := item.(*dbItem)
|
||||||
|
if dbi.expired() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
return iterator(dbi.key, dbi.val)
|
return iterator(dbi.key, dbi.val)
|
||||||
}
|
}
|
||||||
var tr *btree.BTree
|
var tr *btree.BTree
|
||||||
|
|
|
||||||
2
vendor/golang.org/x/crypto/bcrypt/bcrypt.go
generated
vendored
2
vendor/golang.org/x/crypto/bcrypt/bcrypt.go
generated
vendored
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing
|
// Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing
|
||||||
// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
|
// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
|
||||||
package bcrypt // import "golang.org/x/crypto/bcrypt"
|
package bcrypt
|
||||||
|
|
||||||
// The code is a port of Provos and Mazières's C implementation.
|
// The code is a port of Provos and Mazières's C implementation.
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
2
vendor/golang.org/x/crypto/blowfish/cipher.go
generated
vendored
2
vendor/golang.org/x/crypto/blowfish/cipher.go
generated
vendored
|
|
@ -11,7 +11,7 @@
|
||||||
// Deprecated: any new system should use AES (from crypto/aes, if necessary in
|
// Deprecated: any new system should use AES (from crypto/aes, if necessary in
|
||||||
// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
|
// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
|
||||||
// golang.org/x/crypto/chacha20poly1305).
|
// golang.org/x/crypto/chacha20poly1305).
|
||||||
package blowfish // import "golang.org/x/crypto/blowfish"
|
package blowfish
|
||||||
|
|
||||||
// The code is a port of Bruce Schneier's C implementation.
|
// The code is a port of Bruce Schneier's C implementation.
|
||||||
// See https://www.schneier.com/blowfish.html.
|
// See https://www.schneier.com/blowfish.html.
|
||||||
|
|
|
||||||
2
vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
generated
vendored
2
vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
generated
vendored
|
|
@ -16,7 +16,7 @@ Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To
|
||||||
choose, you can pass the `New` functions from the different SHA packages to
|
choose, you can pass the `New` functions from the different SHA packages to
|
||||||
pbkdf2.Key.
|
pbkdf2.Key.
|
||||||
*/
|
*/
|
||||||
package pbkdf2 // import "golang.org/x/crypto/pbkdf2"
|
package pbkdf2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
|
|
|
||||||
2
vendor/golang.org/x/crypto/sha3/doc.go
generated
vendored
2
vendor/golang.org/x/crypto/sha3/doc.go
generated
vendored
|
|
@ -59,4 +59,4 @@
|
||||||
// They produce output of the same length, with the same security strengths
|
// They produce output of the same length, with the same security strengths
|
||||||
// against all attacks. This means, in particular, that SHA3-256 only has
|
// against all attacks. This means, in particular, that SHA3-256 only has
|
||||||
// 128-bit collision resistance, because its output length is 32 bytes.
|
// 128-bit collision resistance, because its output length is 32 bytes.
|
||||||
package sha3 // import "golang.org/x/crypto/sha3"
|
package sha3
|
||||||
|
|
|
||||||
42
vendor/golang.org/x/crypto/sha3/hashes.go
generated
vendored
42
vendor/golang.org/x/crypto/sha3/hashes.go
generated
vendored
|
|
@ -9,6 +9,7 @@ package sha3
|
||||||
// bytes.
|
// bytes.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
"hash"
|
"hash"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -16,39 +17,50 @@ import (
|
||||||
// Its generic security strength is 224 bits against preimage attacks,
|
// Its generic security strength is 224 bits against preimage attacks,
|
||||||
// and 112 bits against collision attacks.
|
// and 112 bits against collision attacks.
|
||||||
func New224() hash.Hash {
|
func New224() hash.Hash {
|
||||||
if h := new224Asm(); h != nil {
|
return new224()
|
||||||
return h
|
|
||||||
}
|
|
||||||
return &state{rate: 144, outputLen: 28, dsbyte: 0x06}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New256 creates a new SHA3-256 hash.
|
// New256 creates a new SHA3-256 hash.
|
||||||
// Its generic security strength is 256 bits against preimage attacks,
|
// Its generic security strength is 256 bits against preimage attacks,
|
||||||
// and 128 bits against collision attacks.
|
// and 128 bits against collision attacks.
|
||||||
func New256() hash.Hash {
|
func New256() hash.Hash {
|
||||||
if h := new256Asm(); h != nil {
|
return new256()
|
||||||
return h
|
|
||||||
}
|
|
||||||
return &state{rate: 136, outputLen: 32, dsbyte: 0x06}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New384 creates a new SHA3-384 hash.
|
// New384 creates a new SHA3-384 hash.
|
||||||
// Its generic security strength is 384 bits against preimage attacks,
|
// Its generic security strength is 384 bits against preimage attacks,
|
||||||
// and 192 bits against collision attacks.
|
// and 192 bits against collision attacks.
|
||||||
func New384() hash.Hash {
|
func New384() hash.Hash {
|
||||||
if h := new384Asm(); h != nil {
|
return new384()
|
||||||
return h
|
|
||||||
}
|
|
||||||
return &state{rate: 104, outputLen: 48, dsbyte: 0x06}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New512 creates a new SHA3-512 hash.
|
// New512 creates a new SHA3-512 hash.
|
||||||
// Its generic security strength is 512 bits against preimage attacks,
|
// Its generic security strength is 512 bits against preimage attacks,
|
||||||
// and 256 bits against collision attacks.
|
// and 256 bits against collision attacks.
|
||||||
func New512() hash.Hash {
|
func New512() hash.Hash {
|
||||||
if h := new512Asm(); h != nil {
|
return new512()
|
||||||
return h
|
}
|
||||||
}
|
|
||||||
|
func init() {
|
||||||
|
crypto.RegisterHash(crypto.SHA3_224, New224)
|
||||||
|
crypto.RegisterHash(crypto.SHA3_256, New256)
|
||||||
|
crypto.RegisterHash(crypto.SHA3_384, New384)
|
||||||
|
crypto.RegisterHash(crypto.SHA3_512, New512)
|
||||||
|
}
|
||||||
|
|
||||||
|
func new224Generic() *state {
|
||||||
|
return &state{rate: 144, outputLen: 28, dsbyte: 0x06}
|
||||||
|
}
|
||||||
|
|
||||||
|
func new256Generic() *state {
|
||||||
|
return &state{rate: 136, outputLen: 32, dsbyte: 0x06}
|
||||||
|
}
|
||||||
|
|
||||||
|
func new384Generic() *state {
|
||||||
|
return &state{rate: 104, outputLen: 48, dsbyte: 0x06}
|
||||||
|
}
|
||||||
|
|
||||||
|
func new512Generic() *state {
|
||||||
return &state{rate: 72, outputLen: 64, dsbyte: 0x06}
|
return &state{rate: 72, outputLen: 64, dsbyte: 0x06}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
27
vendor/golang.org/x/crypto/sha3/hashes_generic.go
generated
vendored
27
vendor/golang.org/x/crypto/sha3/hashes_generic.go
generated
vendored
|
|
@ -1,27 +0,0 @@
|
||||||
// Copyright 2017 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 !gc || purego || !s390x
|
|
||||||
|
|
||||||
package sha3
|
|
||||||
|
|
||||||
import (
|
|
||||||
"hash"
|
|
||||||
)
|
|
||||||
|
|
||||||
// new224Asm returns an assembly implementation of SHA3-224 if available,
|
|
||||||
// otherwise it returns nil.
|
|
||||||
func new224Asm() hash.Hash { return nil }
|
|
||||||
|
|
||||||
// new256Asm returns an assembly implementation of SHA3-256 if available,
|
|
||||||
// otherwise it returns nil.
|
|
||||||
func new256Asm() hash.Hash { return nil }
|
|
||||||
|
|
||||||
// new384Asm returns an assembly implementation of SHA3-384 if available,
|
|
||||||
// otherwise it returns nil.
|
|
||||||
func new384Asm() hash.Hash { return nil }
|
|
||||||
|
|
||||||
// new512Asm returns an assembly implementation of SHA3-512 if available,
|
|
||||||
// otherwise it returns nil.
|
|
||||||
func new512Asm() hash.Hash { return nil }
|
|
||||||
23
vendor/golang.org/x/crypto/sha3/hashes_noasm.go
generated
vendored
Normal file
23
vendor/golang.org/x/crypto/sha3/hashes_noasm.go
generated
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright 2023 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 !gc || purego || !s390x
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
func new224() *state {
|
||||||
|
return new224Generic()
|
||||||
|
}
|
||||||
|
|
||||||
|
func new256() *state {
|
||||||
|
return new256Generic()
|
||||||
|
}
|
||||||
|
|
||||||
|
func new384() *state {
|
||||||
|
return new384Generic()
|
||||||
|
}
|
||||||
|
|
||||||
|
func new512() *state {
|
||||||
|
return new512Generic()
|
||||||
|
}
|
||||||
18
vendor/golang.org/x/crypto/sha3/register.go
generated
vendored
18
vendor/golang.org/x/crypto/sha3/register.go
generated
vendored
|
|
@ -1,18 +0,0 @@
|
||||||
// Copyright 2014 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.4
|
|
||||||
|
|
||||||
package sha3
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
crypto.RegisterHash(crypto.SHA3_224, New224)
|
|
||||||
crypto.RegisterHash(crypto.SHA3_256, New256)
|
|
||||||
crypto.RegisterHash(crypto.SHA3_384, New384)
|
|
||||||
crypto.RegisterHash(crypto.SHA3_512, New512)
|
|
||||||
}
|
|
||||||
62
vendor/golang.org/x/crypto/sha3/sha3.go
generated
vendored
62
vendor/golang.org/x/crypto/sha3/sha3.go
generated
vendored
|
|
@ -23,7 +23,6 @@ const (
|
||||||
type state struct {
|
type state struct {
|
||||||
// Generic sponge components.
|
// Generic sponge components.
|
||||||
a [25]uint64 // main state of the hash
|
a [25]uint64 // main state of the hash
|
||||||
buf []byte // points into storage
|
|
||||||
rate int // the number of bytes of state to use
|
rate int // the number of bytes of state to use
|
||||||
|
|
||||||
// dsbyte contains the "domain separation" bits and the first bit of
|
// dsbyte contains the "domain separation" bits and the first bit of
|
||||||
|
|
@ -40,7 +39,8 @@ type state struct {
|
||||||
// Extendable-Output Functions (May 2014)"
|
// Extendable-Output Functions (May 2014)"
|
||||||
dsbyte byte
|
dsbyte byte
|
||||||
|
|
||||||
storage storageBuf
|
i, n int // storage[i:n] is the buffer, i is only used while squeezing
|
||||||
|
storage [maxRate]byte
|
||||||
|
|
||||||
// Specific to SHA-3 and SHAKE.
|
// Specific to SHA-3 and SHAKE.
|
||||||
outputLen int // the default output size in bytes
|
outputLen int // the default output size in bytes
|
||||||
|
|
@ -54,24 +54,18 @@ func (d *state) BlockSize() int { return d.rate }
|
||||||
func (d *state) Size() int { return d.outputLen }
|
func (d *state) Size() int { return d.outputLen }
|
||||||
|
|
||||||
// Reset clears the internal state by zeroing the sponge state and
|
// Reset clears the internal state by zeroing the sponge state and
|
||||||
// the byte buffer, and setting Sponge.state to absorbing.
|
// the buffer indexes, and setting Sponge.state to absorbing.
|
||||||
func (d *state) Reset() {
|
func (d *state) Reset() {
|
||||||
// Zero the permutation's state.
|
// Zero the permutation's state.
|
||||||
for i := range d.a {
|
for i := range d.a {
|
||||||
d.a[i] = 0
|
d.a[i] = 0
|
||||||
}
|
}
|
||||||
d.state = spongeAbsorbing
|
d.state = spongeAbsorbing
|
||||||
d.buf = d.storage.asBytes()[:0]
|
d.i, d.n = 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *state) clone() *state {
|
func (d *state) clone() *state {
|
||||||
ret := *d
|
ret := *d
|
||||||
if ret.state == spongeAbsorbing {
|
|
||||||
ret.buf = ret.storage.asBytes()[:len(ret.buf)]
|
|
||||||
} else {
|
|
||||||
ret.buf = ret.storage.asBytes()[d.rate-cap(d.buf) : d.rate]
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ret
|
return &ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,43 +76,40 @@ func (d *state) permute() {
|
||||||
case spongeAbsorbing:
|
case spongeAbsorbing:
|
||||||
// If we're absorbing, we need to xor the input into the state
|
// If we're absorbing, we need to xor the input into the state
|
||||||
// before applying the permutation.
|
// before applying the permutation.
|
||||||
xorIn(d, d.buf)
|
xorIn(d, d.storage[:d.rate])
|
||||||
d.buf = d.storage.asBytes()[:0]
|
d.n = 0
|
||||||
keccakF1600(&d.a)
|
keccakF1600(&d.a)
|
||||||
case spongeSqueezing:
|
case spongeSqueezing:
|
||||||
// If we're squeezing, we need to apply the permutation before
|
// If we're squeezing, we need to apply the permutation before
|
||||||
// copying more output.
|
// copying more output.
|
||||||
keccakF1600(&d.a)
|
keccakF1600(&d.a)
|
||||||
d.buf = d.storage.asBytes()[:d.rate]
|
d.i = 0
|
||||||
copyOut(d, d.buf)
|
copyOut(d, d.storage[:d.rate])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pads appends the domain separation bits in dsbyte, applies
|
// pads appends the domain separation bits in dsbyte, applies
|
||||||
// the multi-bitrate 10..1 padding rule, and permutes the state.
|
// the multi-bitrate 10..1 padding rule, and permutes the state.
|
||||||
func (d *state) padAndPermute(dsbyte byte) {
|
func (d *state) padAndPermute() {
|
||||||
if d.buf == nil {
|
|
||||||
d.buf = d.storage.asBytes()[:0]
|
|
||||||
}
|
|
||||||
// Pad with this instance's domain-separator bits. We know that there's
|
// Pad with this instance's domain-separator bits. We know that there's
|
||||||
// at least one byte of space in d.buf because, if it were full,
|
// at least one byte of space in d.buf because, if it were full,
|
||||||
// permute would have been called to empty it. dsbyte also contains the
|
// permute would have been called to empty it. dsbyte also contains the
|
||||||
// first one bit for the padding. See the comment in the state struct.
|
// first one bit for the padding. See the comment in the state struct.
|
||||||
d.buf = append(d.buf, dsbyte)
|
d.storage[d.n] = d.dsbyte
|
||||||
zerosStart := len(d.buf)
|
d.n++
|
||||||
d.buf = d.storage.asBytes()[:d.rate]
|
for d.n < d.rate {
|
||||||
for i := zerosStart; i < d.rate; i++ {
|
d.storage[d.n] = 0
|
||||||
d.buf[i] = 0
|
d.n++
|
||||||
}
|
}
|
||||||
// This adds the final one bit for the padding. Because of the way that
|
// This adds the final one bit for the padding. Because of the way that
|
||||||
// bits are numbered from the LSB upwards, the final bit is the MSB of
|
// bits are numbered from the LSB upwards, the final bit is the MSB of
|
||||||
// the last byte.
|
// the last byte.
|
||||||
d.buf[d.rate-1] ^= 0x80
|
d.storage[d.rate-1] ^= 0x80
|
||||||
// Apply the permutation
|
// Apply the permutation
|
||||||
d.permute()
|
d.permute()
|
||||||
d.state = spongeSqueezing
|
d.state = spongeSqueezing
|
||||||
d.buf = d.storage.asBytes()[:d.rate]
|
d.n = d.rate
|
||||||
copyOut(d, d.buf)
|
copyOut(d, d.storage[:d.rate])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write absorbs more data into the hash's state. It panics if any
|
// Write absorbs more data into the hash's state. It panics if any
|
||||||
|
|
@ -127,28 +118,25 @@ func (d *state) Write(p []byte) (written int, err error) {
|
||||||
if d.state != spongeAbsorbing {
|
if d.state != spongeAbsorbing {
|
||||||
panic("sha3: Write after Read")
|
panic("sha3: Write after Read")
|
||||||
}
|
}
|
||||||
if d.buf == nil {
|
|
||||||
d.buf = d.storage.asBytes()[:0]
|
|
||||||
}
|
|
||||||
written = len(p)
|
written = len(p)
|
||||||
|
|
||||||
for len(p) > 0 {
|
for len(p) > 0 {
|
||||||
if len(d.buf) == 0 && len(p) >= d.rate {
|
if d.n == 0 && len(p) >= d.rate {
|
||||||
// The fast path; absorb a full "rate" bytes of input and apply the permutation.
|
// The fast path; absorb a full "rate" bytes of input and apply the permutation.
|
||||||
xorIn(d, p[:d.rate])
|
xorIn(d, p[:d.rate])
|
||||||
p = p[d.rate:]
|
p = p[d.rate:]
|
||||||
keccakF1600(&d.a)
|
keccakF1600(&d.a)
|
||||||
} else {
|
} else {
|
||||||
// The slow path; buffer the input until we can fill the sponge, and then xor it in.
|
// The slow path; buffer the input until we can fill the sponge, and then xor it in.
|
||||||
todo := d.rate - len(d.buf)
|
todo := d.rate - d.n
|
||||||
if todo > len(p) {
|
if todo > len(p) {
|
||||||
todo = len(p)
|
todo = len(p)
|
||||||
}
|
}
|
||||||
d.buf = append(d.buf, p[:todo]...)
|
d.n += copy(d.storage[d.n:], p[:todo])
|
||||||
p = p[todo:]
|
p = p[todo:]
|
||||||
|
|
||||||
// If the sponge is full, apply the permutation.
|
// If the sponge is full, apply the permutation.
|
||||||
if len(d.buf) == d.rate {
|
if d.n == d.rate {
|
||||||
d.permute()
|
d.permute()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -161,19 +149,19 @@ func (d *state) Write(p []byte) (written int, err error) {
|
||||||
func (d *state) Read(out []byte) (n int, err error) {
|
func (d *state) Read(out []byte) (n int, err error) {
|
||||||
// If we're still absorbing, pad and apply the permutation.
|
// If we're still absorbing, pad and apply the permutation.
|
||||||
if d.state == spongeAbsorbing {
|
if d.state == spongeAbsorbing {
|
||||||
d.padAndPermute(d.dsbyte)
|
d.padAndPermute()
|
||||||
}
|
}
|
||||||
|
|
||||||
n = len(out)
|
n = len(out)
|
||||||
|
|
||||||
// Now, do the squeezing.
|
// Now, do the squeezing.
|
||||||
for len(out) > 0 {
|
for len(out) > 0 {
|
||||||
n := copy(out, d.buf)
|
n := copy(out, d.storage[d.i:d.n])
|
||||||
d.buf = d.buf[n:]
|
d.i += n
|
||||||
out = out[n:]
|
out = out[n:]
|
||||||
|
|
||||||
// Apply the permutation if we've squeezed the sponge dry.
|
// Apply the permutation if we've squeezed the sponge dry.
|
||||||
if len(d.buf) == 0 {
|
if d.i == d.rate {
|
||||||
d.permute()
|
d.permute()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
63
vendor/golang.org/x/crypto/sha3/sha3_s390x.go
generated
vendored
63
vendor/golang.org/x/crypto/sha3/sha3_s390x.go
generated
vendored
|
|
@ -143,6 +143,12 @@ func (s *asmState) Write(b []byte) (int, error) {
|
||||||
|
|
||||||
// Read squeezes an arbitrary number of bytes from the sponge.
|
// Read squeezes an arbitrary number of bytes from the sponge.
|
||||||
func (s *asmState) Read(out []byte) (n int, err error) {
|
func (s *asmState) Read(out []byte) (n int, err error) {
|
||||||
|
// The 'compute last message digest' instruction only stores the digest
|
||||||
|
// at the first operand (dst) for SHAKE functions.
|
||||||
|
if s.function != shake_128 && s.function != shake_256 {
|
||||||
|
panic("sha3: can only call Read for SHAKE functions")
|
||||||
|
}
|
||||||
|
|
||||||
n = len(out)
|
n = len(out)
|
||||||
|
|
||||||
// need to pad if we were absorbing
|
// need to pad if we were absorbing
|
||||||
|
|
@ -202,8 +208,17 @@ func (s *asmState) Sum(b []byte) []byte {
|
||||||
|
|
||||||
// Hash the buffer. Note that we don't clear it because we
|
// Hash the buffer. Note that we don't clear it because we
|
||||||
// aren't updating the state.
|
// aren't updating the state.
|
||||||
|
switch s.function {
|
||||||
|
case sha3_224, sha3_256, sha3_384, sha3_512:
|
||||||
klmd(s.function, &a, nil, s.buf)
|
klmd(s.function, &a, nil, s.buf)
|
||||||
return append(b, a[:s.outputLen]...)
|
return append(b, a[:s.outputLen]...)
|
||||||
|
case shake_128, shake_256:
|
||||||
|
d := make([]byte, s.outputLen, 64)
|
||||||
|
klmd(s.function, &a, d, s.buf)
|
||||||
|
return append(b, d[:s.outputLen]...)
|
||||||
|
default:
|
||||||
|
panic("sha3: unknown function")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset resets the Hash to its initial state.
|
// Reset resets the Hash to its initial state.
|
||||||
|
|
@ -233,56 +248,56 @@ func (s *asmState) Clone() ShakeHash {
|
||||||
return s.clone()
|
return s.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
// new224Asm returns an assembly implementation of SHA3-224 if available,
|
// new224 returns an assembly implementation of SHA3-224 if available,
|
||||||
// otherwise it returns nil.
|
// otherwise it returns a generic implementation.
|
||||||
func new224Asm() hash.Hash {
|
func new224() hash.Hash {
|
||||||
if cpu.S390X.HasSHA3 {
|
if cpu.S390X.HasSHA3 {
|
||||||
return newAsmState(sha3_224)
|
return newAsmState(sha3_224)
|
||||||
}
|
}
|
||||||
return nil
|
return new224Generic()
|
||||||
}
|
}
|
||||||
|
|
||||||
// new256Asm returns an assembly implementation of SHA3-256 if available,
|
// new256 returns an assembly implementation of SHA3-256 if available,
|
||||||
// otherwise it returns nil.
|
// otherwise it returns a generic implementation.
|
||||||
func new256Asm() hash.Hash {
|
func new256() hash.Hash {
|
||||||
if cpu.S390X.HasSHA3 {
|
if cpu.S390X.HasSHA3 {
|
||||||
return newAsmState(sha3_256)
|
return newAsmState(sha3_256)
|
||||||
}
|
}
|
||||||
return nil
|
return new256Generic()
|
||||||
}
|
}
|
||||||
|
|
||||||
// new384Asm returns an assembly implementation of SHA3-384 if available,
|
// new384 returns an assembly implementation of SHA3-384 if available,
|
||||||
// otherwise it returns nil.
|
// otherwise it returns a generic implementation.
|
||||||
func new384Asm() hash.Hash {
|
func new384() hash.Hash {
|
||||||
if cpu.S390X.HasSHA3 {
|
if cpu.S390X.HasSHA3 {
|
||||||
return newAsmState(sha3_384)
|
return newAsmState(sha3_384)
|
||||||
}
|
}
|
||||||
return nil
|
return new384Generic()
|
||||||
}
|
}
|
||||||
|
|
||||||
// new512Asm returns an assembly implementation of SHA3-512 if available,
|
// new512 returns an assembly implementation of SHA3-512 if available,
|
||||||
// otherwise it returns nil.
|
// otherwise it returns a generic implementation.
|
||||||
func new512Asm() hash.Hash {
|
func new512() hash.Hash {
|
||||||
if cpu.S390X.HasSHA3 {
|
if cpu.S390X.HasSHA3 {
|
||||||
return newAsmState(sha3_512)
|
return newAsmState(sha3_512)
|
||||||
}
|
}
|
||||||
return nil
|
return new512Generic()
|
||||||
}
|
}
|
||||||
|
|
||||||
// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
|
// newShake128 returns an assembly implementation of SHAKE-128 if available,
|
||||||
// otherwise it returns nil.
|
// otherwise it returns a generic implementation.
|
||||||
func newShake128Asm() ShakeHash {
|
func newShake128() ShakeHash {
|
||||||
if cpu.S390X.HasSHA3 {
|
if cpu.S390X.HasSHA3 {
|
||||||
return newAsmState(shake_128)
|
return newAsmState(shake_128)
|
||||||
}
|
}
|
||||||
return nil
|
return newShake128Generic()
|
||||||
}
|
}
|
||||||
|
|
||||||
// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
|
// newShake256 returns an assembly implementation of SHAKE-256 if available,
|
||||||
// otherwise it returns nil.
|
// otherwise it returns a generic implementation.
|
||||||
func newShake256Asm() ShakeHash {
|
func newShake256() ShakeHash {
|
||||||
if cpu.S390X.HasSHA3 {
|
if cpu.S390X.HasSHA3 {
|
||||||
return newAsmState(shake_256)
|
return newAsmState(shake_256)
|
||||||
}
|
}
|
||||||
return nil
|
return newShake256Generic()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
16
vendor/golang.org/x/crypto/sha3/shake.go
generated
vendored
16
vendor/golang.org/x/crypto/sha3/shake.go
generated
vendored
|
|
@ -115,19 +115,21 @@ func (c *state) Clone() ShakeHash {
|
||||||
// Its generic security strength is 128 bits against all attacks if at
|
// Its generic security strength is 128 bits against all attacks if at
|
||||||
// least 32 bytes of its output are used.
|
// least 32 bytes of its output are used.
|
||||||
func NewShake128() ShakeHash {
|
func NewShake128() ShakeHash {
|
||||||
if h := newShake128Asm(); h != nil {
|
return newShake128()
|
||||||
return h
|
|
||||||
}
|
|
||||||
return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
|
// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
|
||||||
// Its generic security strength is 256 bits against all attacks if
|
// Its generic security strength is 256 bits against all attacks if
|
||||||
// at least 64 bytes of its output are used.
|
// at least 64 bytes of its output are used.
|
||||||
func NewShake256() ShakeHash {
|
func NewShake256() ShakeHash {
|
||||||
if h := newShake256Asm(); h != nil {
|
return newShake256()
|
||||||
return h
|
}
|
||||||
}
|
|
||||||
|
func newShake128Generic() *state {
|
||||||
|
return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newShake256Generic() *state {
|
||||||
return &state{rate: rate256, outputLen: 64, dsbyte: dsbyteShake}
|
return &state{rate: rate256, outputLen: 64, dsbyte: dsbyteShake}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
19
vendor/golang.org/x/crypto/sha3/shake_generic.go
generated
vendored
19
vendor/golang.org/x/crypto/sha3/shake_generic.go
generated
vendored
|
|
@ -1,19 +0,0 @@
|
||||||
// Copyright 2017 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 !gc || purego || !s390x
|
|
||||||
|
|
||||||
package sha3
|
|
||||||
|
|
||||||
// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
|
|
||||||
// otherwise it returns nil.
|
|
||||||
func newShake128Asm() ShakeHash {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
|
|
||||||
// otherwise it returns nil.
|
|
||||||
func newShake256Asm() ShakeHash {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
15
vendor/golang.org/x/crypto/sha3/shake_noasm.go
generated
vendored
Normal file
15
vendor/golang.org/x/crypto/sha3/shake_noasm.go
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2023 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 !gc || purego || !s390x
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
func newShake128() *state {
|
||||||
|
return newShake128Generic()
|
||||||
|
}
|
||||||
|
|
||||||
|
func newShake256() *state {
|
||||||
|
return newShake256Generic()
|
||||||
|
}
|
||||||
45
vendor/golang.org/x/crypto/sha3/xor.go
generated
vendored
45
vendor/golang.org/x/crypto/sha3/xor.go
generated
vendored
|
|
@ -2,22 +2,39 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build (!amd64 && !386 && !ppc64le) || purego
|
|
||||||
|
|
||||||
package sha3
|
package sha3
|
||||||
|
|
||||||
// A storageBuf is an aligned array of maxRate bytes.
|
import (
|
||||||
type storageBuf [maxRate]byte
|
"crypto/subtle"
|
||||||
|
"encoding/binary"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
func (b *storageBuf) asBytes() *[maxRate]byte {
|
"golang.org/x/sys/cpu"
|
||||||
return (*[maxRate]byte)(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
xorIn = xorInGeneric
|
|
||||||
copyOut = copyOutGeneric
|
|
||||||
xorInUnaligned = xorInGeneric
|
|
||||||
copyOutUnaligned = copyOutGeneric
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const xorImplementationUnaligned = "generic"
|
// xorIn xors the bytes in buf into the state.
|
||||||
|
func xorIn(d *state, buf []byte) {
|
||||||
|
if cpu.IsBigEndian {
|
||||||
|
for i := 0; len(buf) >= 8; i++ {
|
||||||
|
a := binary.LittleEndian.Uint64(buf)
|
||||||
|
d.a[i] ^= a
|
||||||
|
buf = buf[8:]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ab := (*[25 * 64 / 8]byte)(unsafe.Pointer(&d.a))
|
||||||
|
subtle.XORBytes(ab[:], ab[:], buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copyOut copies uint64s to a byte buffer.
|
||||||
|
func copyOut(d *state, b []byte) {
|
||||||
|
if cpu.IsBigEndian {
|
||||||
|
for i := 0; len(b) >= 8; i++ {
|
||||||
|
binary.LittleEndian.PutUint64(b, d.a[i])
|
||||||
|
b = b[8:]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ab := (*[25 * 64 / 8]byte)(unsafe.Pointer(&d.a))
|
||||||
|
copy(b, ab[:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
28
vendor/golang.org/x/crypto/sha3/xor_generic.go
generated
vendored
28
vendor/golang.org/x/crypto/sha3/xor_generic.go
generated
vendored
|
|
@ -1,28 +0,0 @@
|
||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
package sha3
|
|
||||||
|
|
||||||
import "encoding/binary"
|
|
||||||
|
|
||||||
// xorInGeneric xors the bytes in buf into the state; it
|
|
||||||
// makes no non-portable assumptions about memory layout
|
|
||||||
// or alignment.
|
|
||||||
func xorInGeneric(d *state, buf []byte) {
|
|
||||||
n := len(buf) / 8
|
|
||||||
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
a := binary.LittleEndian.Uint64(buf)
|
|
||||||
d.a[i] ^= a
|
|
||||||
buf = buf[8:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// copyOutGeneric copies uint64s to a byte buffer.
|
|
||||||
func copyOutGeneric(d *state, b []byte) {
|
|
||||||
for i := 0; len(b) >= 8; i++ {
|
|
||||||
binary.LittleEndian.PutUint64(b, d.a[i])
|
|
||||||
b = b[8:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
66
vendor/golang.org/x/crypto/sha3/xor_unaligned.go
generated
vendored
66
vendor/golang.org/x/crypto/sha3/xor_unaligned.go
generated
vendored
|
|
@ -1,66 +0,0 @@
|
||||||
// Copyright 2015 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 (amd64 || 386 || ppc64le) && !purego
|
|
||||||
|
|
||||||
package sha3
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
// A storageBuf is an aligned array of maxRate bytes.
|
|
||||||
type storageBuf [maxRate / 8]uint64
|
|
||||||
|
|
||||||
func (b *storageBuf) asBytes() *[maxRate]byte {
|
|
||||||
return (*[maxRate]byte)(unsafe.Pointer(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
|
|
||||||
// XOR buf.
|
|
||||||
func xorInUnaligned(d *state, buf []byte) {
|
|
||||||
n := len(buf)
|
|
||||||
bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
|
|
||||||
if n >= 72 {
|
|
||||||
d.a[0] ^= bw[0]
|
|
||||||
d.a[1] ^= bw[1]
|
|
||||||
d.a[2] ^= bw[2]
|
|
||||||
d.a[3] ^= bw[3]
|
|
||||||
d.a[4] ^= bw[4]
|
|
||||||
d.a[5] ^= bw[5]
|
|
||||||
d.a[6] ^= bw[6]
|
|
||||||
d.a[7] ^= bw[7]
|
|
||||||
d.a[8] ^= bw[8]
|
|
||||||
}
|
|
||||||
if n >= 104 {
|
|
||||||
d.a[9] ^= bw[9]
|
|
||||||
d.a[10] ^= bw[10]
|
|
||||||
d.a[11] ^= bw[11]
|
|
||||||
d.a[12] ^= bw[12]
|
|
||||||
}
|
|
||||||
if n >= 136 {
|
|
||||||
d.a[13] ^= bw[13]
|
|
||||||
d.a[14] ^= bw[14]
|
|
||||||
d.a[15] ^= bw[15]
|
|
||||||
d.a[16] ^= bw[16]
|
|
||||||
}
|
|
||||||
if n >= 144 {
|
|
||||||
d.a[17] ^= bw[17]
|
|
||||||
}
|
|
||||||
if n >= 168 {
|
|
||||||
d.a[18] ^= bw[18]
|
|
||||||
d.a[19] ^= bw[19]
|
|
||||||
d.a[20] ^= bw[20]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyOutUnaligned(d *state, buf []byte) {
|
|
||||||
ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0]))
|
|
||||||
copy(buf, ab[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
xorIn = xorInUnaligned
|
|
||||||
copyOut = copyOutUnaligned
|
|
||||||
)
|
|
||||||
|
|
||||||
const xorImplementationUnaligned = "unaligned"
|
|
||||||
1
vendor/golang.org/x/sys/cpu/cpu.go
generated
vendored
1
vendor/golang.org/x/sys/cpu/cpu.go
generated
vendored
|
|
@ -103,6 +103,7 @@ var ARM64 struct {
|
||||||
HasASIMDDP bool // Advanced SIMD double precision instruction set
|
HasASIMDDP bool // Advanced SIMD double precision instruction set
|
||||||
HasSHA512 bool // SHA512 hardware implementation
|
HasSHA512 bool // SHA512 hardware implementation
|
||||||
HasSVE bool // Scalable Vector Extensions
|
HasSVE bool // Scalable Vector Extensions
|
||||||
|
HasSVE2 bool // Scalable Vector Extensions 2
|
||||||
HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
|
HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
|
||||||
_ CacheLinePad
|
_ CacheLinePad
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
vendor/golang.org/x/sys/cpu/cpu_arm64.go
generated
vendored
10
vendor/golang.org/x/sys/cpu/cpu_arm64.go
generated
vendored
|
|
@ -28,6 +28,7 @@ func initOptions() {
|
||||||
{Name: "sm3", Feature: &ARM64.HasSM3},
|
{Name: "sm3", Feature: &ARM64.HasSM3},
|
||||||
{Name: "sm4", Feature: &ARM64.HasSM4},
|
{Name: "sm4", Feature: &ARM64.HasSM4},
|
||||||
{Name: "sve", Feature: &ARM64.HasSVE},
|
{Name: "sve", Feature: &ARM64.HasSVE},
|
||||||
|
{Name: "sve2", Feature: &ARM64.HasSVE2},
|
||||||
{Name: "crc32", Feature: &ARM64.HasCRC32},
|
{Name: "crc32", Feature: &ARM64.HasCRC32},
|
||||||
{Name: "atomics", Feature: &ARM64.HasATOMICS},
|
{Name: "atomics", Feature: &ARM64.HasATOMICS},
|
||||||
{Name: "asimdhp", Feature: &ARM64.HasASIMDHP},
|
{Name: "asimdhp", Feature: &ARM64.HasASIMDHP},
|
||||||
|
|
@ -164,6 +165,15 @@ func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) {
|
||||||
switch extractBits(pfr0, 32, 35) {
|
switch extractBits(pfr0, 32, 35) {
|
||||||
case 1:
|
case 1:
|
||||||
ARM64.HasSVE = true
|
ARM64.HasSVE = true
|
||||||
|
|
||||||
|
parseARM64SVERegister(getzfr0())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseARM64SVERegister(zfr0 uint64) {
|
||||||
|
switch extractBits(zfr0, 0, 3) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasSVE2 = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
8
vendor/golang.org/x/sys/cpu/cpu_arm64.s
generated
vendored
8
vendor/golang.org/x/sys/cpu/cpu_arm64.s
generated
vendored
|
|
@ -29,3 +29,11 @@ TEXT ·getpfr0(SB),NOSPLIT,$0-8
|
||||||
WORD $0xd5380400
|
WORD $0xd5380400
|
||||||
MOVD R0, ret+0(FP)
|
MOVD R0, ret+0(FP)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
// func getzfr0() uint64
|
||||||
|
TEXT ·getzfr0(SB),NOSPLIT,$0-8
|
||||||
|
// get SVE Feature Register 0 into x0
|
||||||
|
// mrs x0, ID_AA64ZFR0_EL1 = d5380480
|
||||||
|
WORD $0xd5380480
|
||||||
|
MOVD R0, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
|
||||||
1
vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
generated
vendored
1
vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
generated
vendored
|
|
@ -9,3 +9,4 @@ package cpu
|
||||||
func getisar0() uint64
|
func getisar0() uint64
|
||||||
func getisar1() uint64
|
func getisar1() uint64
|
||||||
func getpfr0() uint64
|
func getpfr0() uint64
|
||||||
|
func getzfr0() uint64
|
||||||
|
|
|
||||||
5
vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
generated
vendored
5
vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
generated
vendored
|
|
@ -35,6 +35,8 @@ const (
|
||||||
hwcap_SHA512 = 1 << 21
|
hwcap_SHA512 = 1 << 21
|
||||||
hwcap_SVE = 1 << 22
|
hwcap_SVE = 1 << 22
|
||||||
hwcap_ASIMDFHM = 1 << 23
|
hwcap_ASIMDFHM = 1 << 23
|
||||||
|
|
||||||
|
hwcap2_SVE2 = 1 << 1
|
||||||
)
|
)
|
||||||
|
|
||||||
// linuxKernelCanEmulateCPUID reports whether we're running
|
// linuxKernelCanEmulateCPUID reports whether we're running
|
||||||
|
|
@ -104,6 +106,9 @@ func doinit() {
|
||||||
ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512)
|
ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512)
|
||||||
ARM64.HasSVE = isSet(hwCap, hwcap_SVE)
|
ARM64.HasSVE = isSet(hwCap, hwcap_SVE)
|
||||||
ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM)
|
ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM)
|
||||||
|
|
||||||
|
// HWCAP2 feature bits
|
||||||
|
ARM64.HasSVE2 = isSet(hwCap2, hwcap2_SVE2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSet(hwc uint, value uint) bool {
|
func isSet(hwc uint, value uint) bool {
|
||||||
|
|
|
||||||
2
vendor/golang.org/x/sys/unix/aliases.go
generated
vendored
2
vendor/golang.org/x/sys/unix/aliases.go
generated
vendored
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9
|
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
|
|
||||||
579
vendor/golang.org/x/sys/unix/asm_zos_s390x.s
generated
vendored
579
vendor/golang.org/x/sys/unix/asm_zos_s390x.s
generated
vendored
|
|
@ -9,9 +9,11 @@
|
||||||
#define PSALAA 1208(R0)
|
#define PSALAA 1208(R0)
|
||||||
#define GTAB64(x) 80(x)
|
#define GTAB64(x) 80(x)
|
||||||
#define LCA64(x) 88(x)
|
#define LCA64(x) 88(x)
|
||||||
#define CAA(x) 8(x)
|
|
||||||
#define EDCHPXV(x) 1016(x) // in the CAA
|
|
||||||
#define SAVSTACK_ASYNC(x) 336(x) // in the LCA
|
#define SAVSTACK_ASYNC(x) 336(x) // in the LCA
|
||||||
|
#define CAA(x) 8(x)
|
||||||
|
#define CEECAATHDID(x) 976(x) // in the CAA
|
||||||
|
#define EDCHPXV(x) 1016(x) // in the CAA
|
||||||
|
#define GOCB(x) 1104(x) // in the CAA
|
||||||
|
|
||||||
// SS_*, where x=SAVSTACK_ASYNC
|
// SS_*, where x=SAVSTACK_ASYNC
|
||||||
#define SS_LE(x) 0(x)
|
#define SS_LE(x) 0(x)
|
||||||
|
|
@ -19,15 +21,38 @@
|
||||||
#define SS_ERRNO(x) 16(x)
|
#define SS_ERRNO(x) 16(x)
|
||||||
#define SS_ERRNOJR(x) 20(x)
|
#define SS_ERRNOJR(x) 20(x)
|
||||||
|
|
||||||
#define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6
|
// Function Descriptor Offsets
|
||||||
|
#define __errno 0x156*16
|
||||||
|
#define __err2ad 0x16C*16
|
||||||
|
|
||||||
TEXT ·clearErrno(SB),NOSPLIT,$0-0
|
// Call Instructions
|
||||||
|
#define LE_CALL BYTE $0x0D; BYTE $0x76 // BL R7, R6
|
||||||
|
#define SVC_LOAD BYTE $0x0A; BYTE $0x08 // SVC 08 LOAD
|
||||||
|
#define SVC_DELETE BYTE $0x0A; BYTE $0x09 // SVC 09 DELETE
|
||||||
|
|
||||||
|
DATA zosLibVec<>(SB)/8, $0
|
||||||
|
GLOBL zosLibVec<>(SB), NOPTR, $8
|
||||||
|
|
||||||
|
TEXT ·initZosLibVec(SB), NOSPLIT|NOFRAME, $0-0
|
||||||
|
MOVW PSALAA, R8
|
||||||
|
MOVD LCA64(R8), R8
|
||||||
|
MOVD CAA(R8), R8
|
||||||
|
MOVD EDCHPXV(R8), R8
|
||||||
|
MOVD R8, zosLibVec<>(SB)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·GetZosLibVec(SB), NOSPLIT|NOFRAME, $0-0
|
||||||
|
MOVD zosLibVec<>(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·clearErrno(SB), NOSPLIT, $0-0
|
||||||
BL addrerrno<>(SB)
|
BL addrerrno<>(SB)
|
||||||
MOVD $0, 0(R3)
|
MOVD $0, 0(R3)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// Returns the address of errno in R3.
|
// Returns the address of errno in R3.
|
||||||
TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0
|
TEXT addrerrno<>(SB), NOSPLIT|NOFRAME, $0-0
|
||||||
// Get library control area (LCA).
|
// Get library control area (LCA).
|
||||||
MOVW PSALAA, R8
|
MOVW PSALAA, R8
|
||||||
MOVD LCA64(R8), R8
|
MOVD LCA64(R8), R8
|
||||||
|
|
@ -35,7 +60,7 @@ TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0
|
||||||
// Get __errno FuncDesc.
|
// Get __errno FuncDesc.
|
||||||
MOVD CAA(R8), R9
|
MOVD CAA(R8), R9
|
||||||
MOVD EDCHPXV(R9), R9
|
MOVD EDCHPXV(R9), R9
|
||||||
ADD $(0x156*16), R9
|
ADD $(__errno), R9
|
||||||
LMG 0(R9), R5, R6
|
LMG 0(R9), R5, R6
|
||||||
|
|
||||||
// Switch to saved LE stack.
|
// Switch to saved LE stack.
|
||||||
|
|
@ -52,298 +77,8 @@ TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
MOVD R4, 0(R9) // Save stack pointer.
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT ·syscall_syscall(SB),NOSPLIT,$0-56
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVD a1+8(FP), R1
|
|
||||||
MOVD a2+16(FP), R2
|
|
||||||
MOVD a3+24(FP), R3
|
|
||||||
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get function.
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD EDCHPXV(R9), R9
|
|
||||||
MOVD trap+0(FP), R5
|
|
||||||
SLD $4, R5
|
|
||||||
ADD R5, R9
|
|
||||||
LMG 0(R9), R5, R6
|
|
||||||
|
|
||||||
// Restore LE stack.
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R4
|
|
||||||
MOVD $0, 0(R9)
|
|
||||||
|
|
||||||
// Call function.
|
|
||||||
LE_CALL
|
|
||||||
NOPH
|
|
||||||
XOR R0, R0 // Restore R0 to $0.
|
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
|
||||||
|
|
||||||
MOVD R3, r1+32(FP)
|
|
||||||
MOVD R0, r2+40(FP)
|
|
||||||
MOVD R0, err+48(FP)
|
|
||||||
MOVW R3, R4
|
|
||||||
CMP R4, $-1
|
|
||||||
BNE done
|
|
||||||
BL addrerrno<>(SB)
|
|
||||||
MOVWZ 0(R3), R3
|
|
||||||
MOVD R3, err+48(FP)
|
|
||||||
done:
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56
|
|
||||||
MOVD a1+8(FP), R1
|
|
||||||
MOVD a2+16(FP), R2
|
|
||||||
MOVD a3+24(FP), R3
|
|
||||||
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get function.
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD EDCHPXV(R9), R9
|
|
||||||
MOVD trap+0(FP), R5
|
|
||||||
SLD $4, R5
|
|
||||||
ADD R5, R9
|
|
||||||
LMG 0(R9), R5, R6
|
|
||||||
|
|
||||||
// Restore LE stack.
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R4
|
|
||||||
MOVD $0, 0(R9)
|
|
||||||
|
|
||||||
// Call function.
|
|
||||||
LE_CALL
|
|
||||||
NOPH
|
|
||||||
XOR R0, R0 // Restore R0 to $0.
|
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
|
||||||
|
|
||||||
MOVD R3, r1+32(FP)
|
|
||||||
MOVD R0, r2+40(FP)
|
|
||||||
MOVD R0, err+48(FP)
|
|
||||||
MOVW R3, R4
|
|
||||||
CMP R4, $-1
|
|
||||||
BNE done
|
|
||||||
BL addrerrno<>(SB)
|
|
||||||
MOVWZ 0(R3), R3
|
|
||||||
MOVD R3, err+48(FP)
|
|
||||||
done:
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVD a1+8(FP), R1
|
|
||||||
MOVD a2+16(FP), R2
|
|
||||||
MOVD a3+24(FP), R3
|
|
||||||
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get function.
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD EDCHPXV(R9), R9
|
|
||||||
MOVD trap+0(FP), R5
|
|
||||||
SLD $4, R5
|
|
||||||
ADD R5, R9
|
|
||||||
LMG 0(R9), R5, R6
|
|
||||||
|
|
||||||
// Restore LE stack.
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R4
|
|
||||||
MOVD $0, 0(R9)
|
|
||||||
|
|
||||||
// Fill in parameter list.
|
|
||||||
MOVD a4+32(FP), R12
|
|
||||||
MOVD R12, (2176+24)(R4)
|
|
||||||
MOVD a5+40(FP), R12
|
|
||||||
MOVD R12, (2176+32)(R4)
|
|
||||||
MOVD a6+48(FP), R12
|
|
||||||
MOVD R12, (2176+40)(R4)
|
|
||||||
|
|
||||||
// Call function.
|
|
||||||
LE_CALL
|
|
||||||
NOPH
|
|
||||||
XOR R0, R0 // Restore R0 to $0.
|
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
|
||||||
|
|
||||||
MOVD R3, r1+56(FP)
|
|
||||||
MOVD R0, r2+64(FP)
|
|
||||||
MOVD R0, err+72(FP)
|
|
||||||
MOVW R3, R4
|
|
||||||
CMP R4, $-1
|
|
||||||
BNE done
|
|
||||||
BL addrerrno<>(SB)
|
|
||||||
MOVWZ 0(R3), R3
|
|
||||||
MOVD R3, err+72(FP)
|
|
||||||
done:
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80
|
|
||||||
MOVD a1+8(FP), R1
|
|
||||||
MOVD a2+16(FP), R2
|
|
||||||
MOVD a3+24(FP), R3
|
|
||||||
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get function.
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD EDCHPXV(R9), R9
|
|
||||||
MOVD trap+0(FP), R5
|
|
||||||
SLD $4, R5
|
|
||||||
ADD R5, R9
|
|
||||||
LMG 0(R9), R5, R6
|
|
||||||
|
|
||||||
// Restore LE stack.
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R4
|
|
||||||
MOVD $0, 0(R9)
|
|
||||||
|
|
||||||
// Fill in parameter list.
|
|
||||||
MOVD a4+32(FP), R12
|
|
||||||
MOVD R12, (2176+24)(R4)
|
|
||||||
MOVD a5+40(FP), R12
|
|
||||||
MOVD R12, (2176+32)(R4)
|
|
||||||
MOVD a6+48(FP), R12
|
|
||||||
MOVD R12, (2176+40)(R4)
|
|
||||||
|
|
||||||
// Call function.
|
|
||||||
LE_CALL
|
|
||||||
NOPH
|
|
||||||
XOR R0, R0 // Restore R0 to $0.
|
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
|
||||||
|
|
||||||
MOVD R3, r1+56(FP)
|
|
||||||
MOVD R0, r2+64(FP)
|
|
||||||
MOVD R0, err+72(FP)
|
|
||||||
MOVW R3, R4
|
|
||||||
CMP R4, $-1
|
|
||||||
BNE done
|
|
||||||
BL ·rrno<>(SB)
|
|
||||||
MOVWZ 0(R3), R3
|
|
||||||
MOVD R3, err+72(FP)
|
|
||||||
done:
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·syscall_syscall9(SB),NOSPLIT,$0
|
|
||||||
BL runtime·entersyscall(SB)
|
|
||||||
MOVD a1+8(FP), R1
|
|
||||||
MOVD a2+16(FP), R2
|
|
||||||
MOVD a3+24(FP), R3
|
|
||||||
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get function.
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD EDCHPXV(R9), R9
|
|
||||||
MOVD trap+0(FP), R5
|
|
||||||
SLD $4, R5
|
|
||||||
ADD R5, R9
|
|
||||||
LMG 0(R9), R5, R6
|
|
||||||
|
|
||||||
// Restore LE stack.
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R4
|
|
||||||
MOVD $0, 0(R9)
|
|
||||||
|
|
||||||
// Fill in parameter list.
|
|
||||||
MOVD a4+32(FP), R12
|
|
||||||
MOVD R12, (2176+24)(R4)
|
|
||||||
MOVD a5+40(FP), R12
|
|
||||||
MOVD R12, (2176+32)(R4)
|
|
||||||
MOVD a6+48(FP), R12
|
|
||||||
MOVD R12, (2176+40)(R4)
|
|
||||||
MOVD a7+56(FP), R12
|
|
||||||
MOVD R12, (2176+48)(R4)
|
|
||||||
MOVD a8+64(FP), R12
|
|
||||||
MOVD R12, (2176+56)(R4)
|
|
||||||
MOVD a9+72(FP), R12
|
|
||||||
MOVD R12, (2176+64)(R4)
|
|
||||||
|
|
||||||
// Call function.
|
|
||||||
LE_CALL
|
|
||||||
NOPH
|
|
||||||
XOR R0, R0 // Restore R0 to $0.
|
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
|
||||||
|
|
||||||
MOVD R3, r1+80(FP)
|
|
||||||
MOVD R0, r2+88(FP)
|
|
||||||
MOVD R0, err+96(FP)
|
|
||||||
MOVW R3, R4
|
|
||||||
CMP R4, $-1
|
|
||||||
BNE done
|
|
||||||
BL addrerrno<>(SB)
|
|
||||||
MOVWZ 0(R3), R3
|
|
||||||
MOVD R3, err+96(FP)
|
|
||||||
done:
|
|
||||||
BL runtime·exitsyscall(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0
|
|
||||||
MOVD a1+8(FP), R1
|
|
||||||
MOVD a2+16(FP), R2
|
|
||||||
MOVD a3+24(FP), R3
|
|
||||||
|
|
||||||
// Get library control area (LCA).
|
|
||||||
MOVW PSALAA, R8
|
|
||||||
MOVD LCA64(R8), R8
|
|
||||||
|
|
||||||
// Get function.
|
|
||||||
MOVD CAA(R8), R9
|
|
||||||
MOVD EDCHPXV(R9), R9
|
|
||||||
MOVD trap+0(FP), R5
|
|
||||||
SLD $4, R5
|
|
||||||
ADD R5, R9
|
|
||||||
LMG 0(R9), R5, R6
|
|
||||||
|
|
||||||
// Restore LE stack.
|
|
||||||
MOVD SAVSTACK_ASYNC(R8), R9
|
|
||||||
MOVD 0(R9), R4
|
|
||||||
MOVD $0, 0(R9)
|
|
||||||
|
|
||||||
// Fill in parameter list.
|
|
||||||
MOVD a4+32(FP), R12
|
|
||||||
MOVD R12, (2176+24)(R4)
|
|
||||||
MOVD a5+40(FP), R12
|
|
||||||
MOVD R12, (2176+32)(R4)
|
|
||||||
MOVD a6+48(FP), R12
|
|
||||||
MOVD R12, (2176+40)(R4)
|
|
||||||
MOVD a7+56(FP), R12
|
|
||||||
MOVD R12, (2176+48)(R4)
|
|
||||||
MOVD a8+64(FP), R12
|
|
||||||
MOVD R12, (2176+56)(R4)
|
|
||||||
MOVD a9+72(FP), R12
|
|
||||||
MOVD R12, (2176+64)(R4)
|
|
||||||
|
|
||||||
// Call function.
|
|
||||||
LE_CALL
|
|
||||||
NOPH
|
|
||||||
XOR R0, R0 // Restore R0 to $0.
|
|
||||||
MOVD R4, 0(R9) // Save stack pointer.
|
|
||||||
|
|
||||||
MOVD R3, r1+80(FP)
|
|
||||||
MOVD R0, r2+88(FP)
|
|
||||||
MOVD R0, err+96(FP)
|
|
||||||
MOVW R3, R4
|
|
||||||
CMP R4, $-1
|
|
||||||
BNE done
|
|
||||||
BL addrerrno<>(SB)
|
|
||||||
MOVWZ 0(R3), R3
|
|
||||||
MOVD R3, err+96(FP)
|
|
||||||
done:
|
|
||||||
RET
|
|
||||||
|
|
||||||
// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
|
// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
|
||||||
TEXT ·svcCall(SB),NOSPLIT,$0
|
TEXT ·svcCall(SB), NOSPLIT, $0
|
||||||
BL runtime·save_g(SB) // Save g and stack pointer
|
BL runtime·save_g(SB) // Save g and stack pointer
|
||||||
MOVW PSALAA, R8
|
MOVW PSALAA, R8
|
||||||
MOVD LCA64(R8), R8
|
MOVD LCA64(R8), R8
|
||||||
|
|
@ -366,13 +101,12 @@ TEXT ·svcCall(SB),NOSPLIT,$0
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// func svcLoad(name *byte) unsafe.Pointer
|
// func svcLoad(name *byte) unsafe.Pointer
|
||||||
TEXT ·svcLoad(SB),NOSPLIT,$0
|
TEXT ·svcLoad(SB), NOSPLIT, $0
|
||||||
MOVD R15, R2 // Save go stack pointer
|
MOVD R15, R2 // Save go stack pointer
|
||||||
MOVD name+0(FP), R0 // Move SVC args into registers
|
MOVD name+0(FP), R0 // Move SVC args into registers
|
||||||
MOVD $0x80000000, R1
|
MOVD $0x80000000, R1
|
||||||
MOVD $0, R15
|
MOVD $0, R15
|
||||||
BYTE $0x0A // SVC 08 LOAD
|
SVC_LOAD
|
||||||
BYTE $0x08
|
|
||||||
MOVW R15, R3 // Save return code from SVC
|
MOVW R15, R3 // Save return code from SVC
|
||||||
MOVD R2, R15 // Restore go stack pointer
|
MOVD R2, R15 // Restore go stack pointer
|
||||||
CMP R3, $0 // Check SVC return code
|
CMP R3, $0 // Check SVC return code
|
||||||
|
|
@ -380,33 +114,32 @@ TEXT ·svcLoad(SB),NOSPLIT,$0
|
||||||
|
|
||||||
MOVD $-2, R3 // Reset last bit of entry point to zero
|
MOVD $-2, R3 // Reset last bit of entry point to zero
|
||||||
AND R0, R3
|
AND R0, R3
|
||||||
MOVD R3, addr+8(FP) // Return entry point returned by SVC
|
MOVD R3, ret+8(FP) // Return entry point returned by SVC
|
||||||
CMP R0, R3 // Check if last bit of entry point was set
|
CMP R0, R3 // Check if last bit of entry point was set
|
||||||
BNE done
|
BNE done
|
||||||
|
|
||||||
MOVD R15, R2 // Save go stack pointer
|
MOVD R15, R2 // Save go stack pointer
|
||||||
MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)
|
MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)
|
||||||
BYTE $0x0A // SVC 09 DELETE
|
SVC_DELETE
|
||||||
BYTE $0x09
|
|
||||||
MOVD R2, R15 // Restore go stack pointer
|
MOVD R2, R15 // Restore go stack pointer
|
||||||
|
|
||||||
error:
|
error:
|
||||||
MOVD $0, addr+8(FP) // Return 0 on failure
|
MOVD $0, ret+8(FP) // Return 0 on failure
|
||||||
|
|
||||||
done:
|
done:
|
||||||
XOR R0, R0 // Reset r0 to 0
|
XOR R0, R0 // Reset r0 to 0
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
|
// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
|
||||||
TEXT ·svcUnload(SB),NOSPLIT,$0
|
TEXT ·svcUnload(SB), NOSPLIT, $0
|
||||||
MOVD R15, R2 // Save go stack pointer
|
MOVD R15, R2 // Save go stack pointer
|
||||||
MOVD name+0(FP), R0 // Move SVC args into registers
|
MOVD name+0(FP), R0 // Move SVC args into registers
|
||||||
MOVD addr+8(FP), R15
|
MOVD fnptr+8(FP), R15
|
||||||
BYTE $0x0A // SVC 09
|
SVC_DELETE
|
||||||
BYTE $0x09
|
|
||||||
XOR R0, R0 // Reset r0 to 0
|
XOR R0, R0 // Reset r0 to 0
|
||||||
MOVD R15, R1 // Save SVC return code
|
MOVD R15, R1 // Save SVC return code
|
||||||
MOVD R2, R15 // Restore go stack pointer
|
MOVD R2, R15 // Restore go stack pointer
|
||||||
MOVD R1, rc+0(FP) // Return SVC return code
|
MOVD R1, ret+16(FP) // Return SVC return code
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// func gettid() uint64
|
// func gettid() uint64
|
||||||
|
|
@ -417,7 +150,233 @@ TEXT ·gettid(SB), NOSPLIT, $0
|
||||||
|
|
||||||
// Get CEECAATHDID
|
// Get CEECAATHDID
|
||||||
MOVD CAA(R8), R9
|
MOVD CAA(R8), R9
|
||||||
MOVD 0x3D0(R9), R9
|
MOVD CEECAATHDID(R9), R9
|
||||||
MOVD R9, ret+0(FP)
|
MOVD R9, ret+0(FP)
|
||||||
|
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call LE function, if the return is -1
|
||||||
|
// errno and errno2 is retrieved
|
||||||
|
//
|
||||||
|
TEXT ·CallLeFuncWithErr(SB), NOSPLIT, $0
|
||||||
|
MOVW PSALAA, R8
|
||||||
|
MOVD LCA64(R8), R8
|
||||||
|
MOVD CAA(R8), R9
|
||||||
|
MOVD g, GOCB(R9)
|
||||||
|
|
||||||
|
// Restore LE stack.
|
||||||
|
MOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address
|
||||||
|
MOVD 0(R9), R4 // R4-> restore previously saved stack frame pointer
|
||||||
|
|
||||||
|
MOVD parms_base+8(FP), R7 // R7 -> argument array
|
||||||
|
MOVD parms_len+16(FP), R8 // R8 number of arguments
|
||||||
|
|
||||||
|
// arg 1 ---> R1
|
||||||
|
CMP R8, $0
|
||||||
|
BEQ docall
|
||||||
|
SUB $1, R8
|
||||||
|
MOVD 0(R7), R1
|
||||||
|
|
||||||
|
// arg 2 ---> R2
|
||||||
|
CMP R8, $0
|
||||||
|
BEQ docall
|
||||||
|
SUB $1, R8
|
||||||
|
ADD $8, R7
|
||||||
|
MOVD 0(R7), R2
|
||||||
|
|
||||||
|
// arg 3 --> R3
|
||||||
|
CMP R8, $0
|
||||||
|
BEQ docall
|
||||||
|
SUB $1, R8
|
||||||
|
ADD $8, R7
|
||||||
|
MOVD 0(R7), R3
|
||||||
|
|
||||||
|
CMP R8, $0
|
||||||
|
BEQ docall
|
||||||
|
MOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument
|
||||||
|
|
||||||
|
repeat:
|
||||||
|
ADD $8, R7
|
||||||
|
MOVD 0(R7), R0 // advance arg pointer by 8 byte
|
||||||
|
ADD $8, R6 // advance LE argument address by 8 byte
|
||||||
|
MOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame
|
||||||
|
SUB $1, R8
|
||||||
|
CMP R8, $0
|
||||||
|
BNE repeat
|
||||||
|
|
||||||
|
docall:
|
||||||
|
MOVD funcdesc+0(FP), R8 // R8-> function descriptor
|
||||||
|
LMG 0(R8), R5, R6
|
||||||
|
MOVD $0, 0(R9) // R9 address of SAVSTACK_ASYNC
|
||||||
|
LE_CALL // balr R7, R6 (return #1)
|
||||||
|
NOPH
|
||||||
|
MOVD R3, ret+32(FP)
|
||||||
|
CMP R3, $-1 // compare result to -1
|
||||||
|
BNE done
|
||||||
|
|
||||||
|
// retrieve errno and errno2
|
||||||
|
MOVD zosLibVec<>(SB), R8
|
||||||
|
ADD $(__errno), R8
|
||||||
|
LMG 0(R8), R5, R6
|
||||||
|
LE_CALL // balr R7, R6 __errno (return #3)
|
||||||
|
NOPH
|
||||||
|
MOVWZ 0(R3), R3
|
||||||
|
MOVD R3, err+48(FP)
|
||||||
|
MOVD zosLibVec<>(SB), R8
|
||||||
|
ADD $(__err2ad), R8
|
||||||
|
LMG 0(R8), R5, R6
|
||||||
|
LE_CALL // balr R7, R6 __err2ad (return #2)
|
||||||
|
NOPH
|
||||||
|
MOVW (R3), R2 // retrieve errno2
|
||||||
|
MOVD R2, errno2+40(FP) // store in return area
|
||||||
|
|
||||||
|
done:
|
||||||
|
MOVD R4, 0(R9) // Save stack pointer.
|
||||||
|
RET
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call LE function, if the return is 0
|
||||||
|
// errno and errno2 is retrieved
|
||||||
|
//
|
||||||
|
TEXT ·CallLeFuncWithPtrReturn(SB), NOSPLIT, $0
|
||||||
|
MOVW PSALAA, R8
|
||||||
|
MOVD LCA64(R8), R8
|
||||||
|
MOVD CAA(R8), R9
|
||||||
|
MOVD g, GOCB(R9)
|
||||||
|
|
||||||
|
// Restore LE stack.
|
||||||
|
MOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address
|
||||||
|
MOVD 0(R9), R4 // R4-> restore previously saved stack frame pointer
|
||||||
|
|
||||||
|
MOVD parms_base+8(FP), R7 // R7 -> argument array
|
||||||
|
MOVD parms_len+16(FP), R8 // R8 number of arguments
|
||||||
|
|
||||||
|
// arg 1 ---> R1
|
||||||
|
CMP R8, $0
|
||||||
|
BEQ docall
|
||||||
|
SUB $1, R8
|
||||||
|
MOVD 0(R7), R1
|
||||||
|
|
||||||
|
// arg 2 ---> R2
|
||||||
|
CMP R8, $0
|
||||||
|
BEQ docall
|
||||||
|
SUB $1, R8
|
||||||
|
ADD $8, R7
|
||||||
|
MOVD 0(R7), R2
|
||||||
|
|
||||||
|
// arg 3 --> R3
|
||||||
|
CMP R8, $0
|
||||||
|
BEQ docall
|
||||||
|
SUB $1, R8
|
||||||
|
ADD $8, R7
|
||||||
|
MOVD 0(R7), R3
|
||||||
|
|
||||||
|
CMP R8, $0
|
||||||
|
BEQ docall
|
||||||
|
MOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument
|
||||||
|
|
||||||
|
repeat:
|
||||||
|
ADD $8, R7
|
||||||
|
MOVD 0(R7), R0 // advance arg pointer by 8 byte
|
||||||
|
ADD $8, R6 // advance LE argument address by 8 byte
|
||||||
|
MOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame
|
||||||
|
SUB $1, R8
|
||||||
|
CMP R8, $0
|
||||||
|
BNE repeat
|
||||||
|
|
||||||
|
docall:
|
||||||
|
MOVD funcdesc+0(FP), R8 // R8-> function descriptor
|
||||||
|
LMG 0(R8), R5, R6
|
||||||
|
MOVD $0, 0(R9) // R9 address of SAVSTACK_ASYNC
|
||||||
|
LE_CALL // balr R7, R6 (return #1)
|
||||||
|
NOPH
|
||||||
|
MOVD R3, ret+32(FP)
|
||||||
|
CMP R3, $0 // compare result to 0
|
||||||
|
BNE done
|
||||||
|
|
||||||
|
// retrieve errno and errno2
|
||||||
|
MOVD zosLibVec<>(SB), R8
|
||||||
|
ADD $(__errno), R8
|
||||||
|
LMG 0(R8), R5, R6
|
||||||
|
LE_CALL // balr R7, R6 __errno (return #3)
|
||||||
|
NOPH
|
||||||
|
MOVWZ 0(R3), R3
|
||||||
|
MOVD R3, err+48(FP)
|
||||||
|
MOVD zosLibVec<>(SB), R8
|
||||||
|
ADD $(__err2ad), R8
|
||||||
|
LMG 0(R8), R5, R6
|
||||||
|
LE_CALL // balr R7, R6 __err2ad (return #2)
|
||||||
|
NOPH
|
||||||
|
MOVW (R3), R2 // retrieve errno2
|
||||||
|
MOVD R2, errno2+40(FP) // store in return area
|
||||||
|
XOR R2, R2
|
||||||
|
MOVWZ R2, (R3) // clear errno2
|
||||||
|
|
||||||
|
done:
|
||||||
|
MOVD R4, 0(R9) // Save stack pointer.
|
||||||
|
RET
|
||||||
|
|
||||||
|
//
|
||||||
|
// function to test if a pointer can be safely dereferenced (content read)
|
||||||
|
// return 0 for succces
|
||||||
|
//
|
||||||
|
TEXT ·ptrtest(SB), NOSPLIT, $0-16
|
||||||
|
MOVD arg+0(FP), R10 // test pointer in R10
|
||||||
|
|
||||||
|
// set up R2 to point to CEECAADMC
|
||||||
|
BYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt 2,1208
|
||||||
|
BYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22 // llgtr 2,2
|
||||||
|
BYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF // nilh 2,32767
|
||||||
|
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg 2,88(2)
|
||||||
|
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg 2,8(2)
|
||||||
|
BYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68 // la 2,872(2)
|
||||||
|
|
||||||
|
// set up R5 to point to the "shunt" path which set 1 to R3 (failure)
|
||||||
|
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33 // xgr 3,3
|
||||||
|
BYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04 // bras 5,lbl1
|
||||||
|
BYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01 // lghi 3,1
|
||||||
|
|
||||||
|
// if r3 is not zero (failed) then branch to finish
|
||||||
|
BYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33 // lbl1 ltgr 3,3
|
||||||
|
BYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08 // brc b'0111',lbl2
|
||||||
|
|
||||||
|
// stomic store shunt address in R5 into CEECAADMC
|
||||||
|
BYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 5,0(2)
|
||||||
|
|
||||||
|
// now try reading from the test pointer in R10, if it fails it branches to the "lghi" instruction above
|
||||||
|
BYTE $0xE3; BYTE $0x9A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg 9,0(10)
|
||||||
|
|
||||||
|
// finish here, restore 0 into CEECAADMC
|
||||||
|
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99 // lbl2 xgr 9,9
|
||||||
|
BYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 9,0(2)
|
||||||
|
MOVD R3, ret+8(FP) // result in R3
|
||||||
|
RET
|
||||||
|
|
||||||
|
//
|
||||||
|
// function to test if a untptr can be loaded from a pointer
|
||||||
|
// return 1: the 8-byte content
|
||||||
|
// 2: 0 for success, 1 for failure
|
||||||
|
//
|
||||||
|
// func safeload(ptr uintptr) ( value uintptr, error uintptr)
|
||||||
|
TEXT ·safeload(SB), NOSPLIT, $0-24
|
||||||
|
MOVD ptr+0(FP), R10 // test pointer in R10
|
||||||
|
MOVD $0x0, R6
|
||||||
|
BYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt 2,1208
|
||||||
|
BYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22 // llgtr 2,2
|
||||||
|
BYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF // nilh 2,32767
|
||||||
|
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg 2,88(2)
|
||||||
|
BYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg 2,8(2)
|
||||||
|
BYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68 // la 2,872(2)
|
||||||
|
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33 // xgr 3,3
|
||||||
|
BYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04 // bras 5,lbl1
|
||||||
|
BYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01 // lghi 3,1
|
||||||
|
BYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33 // lbl1 ltgr 3,3
|
||||||
|
BYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08 // brc b'0111',lbl2
|
||||||
|
BYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 5,0(2)
|
||||||
|
BYTE $0xE3; BYTE $0x6A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg 6,0(10)
|
||||||
|
BYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99 // lbl2 xgr 9,9
|
||||||
|
BYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 9,0(2)
|
||||||
|
MOVD R6, value+8(FP) // result in R6
|
||||||
|
MOVD R3, error+16(FP) // error in R3
|
||||||
|
RET
|
||||||
|
|
|
||||||
657
vendor/golang.org/x/sys/unix/bpxsvc_zos.go
generated
vendored
Normal file
657
vendor/golang.org/x/sys/unix/bpxsvc_zos.go
generated
vendored
Normal file
|
|
@ -0,0 +1,657 @@
|
||||||
|
// Copyright 2024 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 zos
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func bpxcall(plist []unsafe.Pointer, bpx_offset int64)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func A2e([]byte)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func E2a([]byte)
|
||||||
|
|
||||||
|
const (
|
||||||
|
BPX4STA = 192 // stat
|
||||||
|
BPX4FST = 104 // fstat
|
||||||
|
BPX4LST = 132 // lstat
|
||||||
|
BPX4OPN = 156 // open
|
||||||
|
BPX4CLO = 72 // close
|
||||||
|
BPX4CHR = 500 // chattr
|
||||||
|
BPX4FCR = 504 // fchattr
|
||||||
|
BPX4LCR = 1180 // lchattr
|
||||||
|
BPX4CTW = 492 // cond_timed_wait
|
||||||
|
BPX4GTH = 1056 // __getthent
|
||||||
|
BPX4PTQ = 412 // pthread_quiesc
|
||||||
|
BPX4PTR = 320 // ptrace
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
//options
|
||||||
|
//byte1
|
||||||
|
BPX_OPNFHIGH = 0x80
|
||||||
|
//byte2
|
||||||
|
BPX_OPNFEXEC = 0x80
|
||||||
|
//byte3
|
||||||
|
BPX_O_NOLARGEFILE = 0x08
|
||||||
|
BPX_O_LARGEFILE = 0x04
|
||||||
|
BPX_O_ASYNCSIG = 0x02
|
||||||
|
BPX_O_SYNC = 0x01
|
||||||
|
//byte4
|
||||||
|
BPX_O_CREXCL = 0xc0
|
||||||
|
BPX_O_CREAT = 0x80
|
||||||
|
BPX_O_EXCL = 0x40
|
||||||
|
BPX_O_NOCTTY = 0x20
|
||||||
|
BPX_O_TRUNC = 0x10
|
||||||
|
BPX_O_APPEND = 0x08
|
||||||
|
BPX_O_NONBLOCK = 0x04
|
||||||
|
BPX_FNDELAY = 0x04
|
||||||
|
BPX_O_RDWR = 0x03
|
||||||
|
BPX_O_RDONLY = 0x02
|
||||||
|
BPX_O_WRONLY = 0x01
|
||||||
|
BPX_O_ACCMODE = 0x03
|
||||||
|
BPX_O_GETFL = 0x0f
|
||||||
|
|
||||||
|
//mode
|
||||||
|
// byte1 (file type)
|
||||||
|
BPX_FT_DIR = 1
|
||||||
|
BPX_FT_CHARSPEC = 2
|
||||||
|
BPX_FT_REGFILE = 3
|
||||||
|
BPX_FT_FIFO = 4
|
||||||
|
BPX_FT_SYMLINK = 5
|
||||||
|
BPX_FT_SOCKET = 6
|
||||||
|
//byte3
|
||||||
|
BPX_S_ISUID = 0x08
|
||||||
|
BPX_S_ISGID = 0x04
|
||||||
|
BPX_S_ISVTX = 0x02
|
||||||
|
BPX_S_IRWXU1 = 0x01
|
||||||
|
BPX_S_IRUSR = 0x01
|
||||||
|
//byte4
|
||||||
|
BPX_S_IRWXU2 = 0xc0
|
||||||
|
BPX_S_IWUSR = 0x80
|
||||||
|
BPX_S_IXUSR = 0x40
|
||||||
|
BPX_S_IRWXG = 0x38
|
||||||
|
BPX_S_IRGRP = 0x20
|
||||||
|
BPX_S_IWGRP = 0x10
|
||||||
|
BPX_S_IXGRP = 0x08
|
||||||
|
BPX_S_IRWXOX = 0x07
|
||||||
|
BPX_S_IROTH = 0x04
|
||||||
|
BPX_S_IWOTH = 0x02
|
||||||
|
BPX_S_IXOTH = 0x01
|
||||||
|
|
||||||
|
CW_INTRPT = 1
|
||||||
|
CW_CONDVAR = 32
|
||||||
|
CW_TIMEOUT = 64
|
||||||
|
|
||||||
|
PGTHA_NEXT = 2
|
||||||
|
PGTHA_CURRENT = 1
|
||||||
|
PGTHA_FIRST = 0
|
||||||
|
PGTHA_LAST = 3
|
||||||
|
PGTHA_PROCESS = 0x80
|
||||||
|
PGTHA_CONTTY = 0x40
|
||||||
|
PGTHA_PATH = 0x20
|
||||||
|
PGTHA_COMMAND = 0x10
|
||||||
|
PGTHA_FILEDATA = 0x08
|
||||||
|
PGTHA_THREAD = 0x04
|
||||||
|
PGTHA_PTAG = 0x02
|
||||||
|
PGTHA_COMMANDLONG = 0x01
|
||||||
|
PGTHA_THREADFAST = 0x80
|
||||||
|
PGTHA_FILEPATH = 0x40
|
||||||
|
PGTHA_THDSIGMASK = 0x20
|
||||||
|
// thread quiece mode
|
||||||
|
QUIESCE_TERM int32 = 1
|
||||||
|
QUIESCE_FORCE int32 = 2
|
||||||
|
QUIESCE_QUERY int32 = 3
|
||||||
|
QUIESCE_FREEZE int32 = 4
|
||||||
|
QUIESCE_UNFREEZE int32 = 5
|
||||||
|
FREEZE_THIS_THREAD int32 = 6
|
||||||
|
FREEZE_EXIT int32 = 8
|
||||||
|
QUIESCE_SRB int32 = 9
|
||||||
|
)
|
||||||
|
|
||||||
|
type Pgtha struct {
|
||||||
|
Pid uint32 // 0
|
||||||
|
Tid0 uint32 // 4
|
||||||
|
Tid1 uint32
|
||||||
|
Accesspid byte // C
|
||||||
|
Accesstid byte // D
|
||||||
|
Accessasid uint16 // E
|
||||||
|
Loginname [8]byte // 10
|
||||||
|
Flag1 byte // 18
|
||||||
|
Flag1b2 byte // 19
|
||||||
|
}
|
||||||
|
|
||||||
|
type Bpxystat_t struct { // DSECT BPXYSTAT
|
||||||
|
St_id [4]uint8 // 0
|
||||||
|
St_length uint16 // 0x4
|
||||||
|
St_version uint16 // 0x6
|
||||||
|
St_mode uint32 // 0x8
|
||||||
|
St_ino uint32 // 0xc
|
||||||
|
St_dev uint32 // 0x10
|
||||||
|
St_nlink uint32 // 0x14
|
||||||
|
St_uid uint32 // 0x18
|
||||||
|
St_gid uint32 // 0x1c
|
||||||
|
St_size uint64 // 0x20
|
||||||
|
St_atime uint32 // 0x28
|
||||||
|
St_mtime uint32 // 0x2c
|
||||||
|
St_ctime uint32 // 0x30
|
||||||
|
St_rdev uint32 // 0x34
|
||||||
|
St_auditoraudit uint32 // 0x38
|
||||||
|
St_useraudit uint32 // 0x3c
|
||||||
|
St_blksize uint32 // 0x40
|
||||||
|
St_createtime uint32 // 0x44
|
||||||
|
St_auditid [4]uint32 // 0x48
|
||||||
|
St_res01 uint32 // 0x58
|
||||||
|
Ft_ccsid uint16 // 0x5c
|
||||||
|
Ft_flags uint16 // 0x5e
|
||||||
|
St_res01a [2]uint32 // 0x60
|
||||||
|
St_res02 uint32 // 0x68
|
||||||
|
St_blocks uint32 // 0x6c
|
||||||
|
St_opaque [3]uint8 // 0x70
|
||||||
|
St_visible uint8 // 0x73
|
||||||
|
St_reftime uint32 // 0x74
|
||||||
|
St_fid uint64 // 0x78
|
||||||
|
St_filefmt uint8 // 0x80
|
||||||
|
St_fspflag2 uint8 // 0x81
|
||||||
|
St_res03 [2]uint8 // 0x82
|
||||||
|
St_ctimemsec uint32 // 0x84
|
||||||
|
St_seclabel [8]uint8 // 0x88
|
||||||
|
St_res04 [4]uint8 // 0x90
|
||||||
|
// end of version 1
|
||||||
|
_ uint32 // 0x94
|
||||||
|
St_atime64 uint64 // 0x98
|
||||||
|
St_mtime64 uint64 // 0xa0
|
||||||
|
St_ctime64 uint64 // 0xa8
|
||||||
|
St_createtime64 uint64 // 0xb0
|
||||||
|
St_reftime64 uint64 // 0xb8
|
||||||
|
_ uint64 // 0xc0
|
||||||
|
St_res05 [16]uint8 // 0xc8
|
||||||
|
// end of version 2
|
||||||
|
}
|
||||||
|
|
||||||
|
type BpxFilestatus struct {
|
||||||
|
Oflag1 byte
|
||||||
|
Oflag2 byte
|
||||||
|
Oflag3 byte
|
||||||
|
Oflag4 byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type BpxMode struct {
|
||||||
|
Ftype byte
|
||||||
|
Mode1 byte
|
||||||
|
Mode2 byte
|
||||||
|
Mode3 byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thr attribute structure for extended attributes
|
||||||
|
type Bpxyatt_t struct { // DSECT BPXYATT
|
||||||
|
Att_id [4]uint8
|
||||||
|
Att_version uint16
|
||||||
|
Att_res01 [2]uint8
|
||||||
|
Att_setflags1 uint8
|
||||||
|
Att_setflags2 uint8
|
||||||
|
Att_setflags3 uint8
|
||||||
|
Att_setflags4 uint8
|
||||||
|
Att_mode uint32
|
||||||
|
Att_uid uint32
|
||||||
|
Att_gid uint32
|
||||||
|
Att_opaquemask [3]uint8
|
||||||
|
Att_visblmaskres uint8
|
||||||
|
Att_opaque [3]uint8
|
||||||
|
Att_visibleres uint8
|
||||||
|
Att_size_h uint32
|
||||||
|
Att_size_l uint32
|
||||||
|
Att_atime uint32
|
||||||
|
Att_mtime uint32
|
||||||
|
Att_auditoraudit uint32
|
||||||
|
Att_useraudit uint32
|
||||||
|
Att_ctime uint32
|
||||||
|
Att_reftime uint32
|
||||||
|
// end of version 1
|
||||||
|
Att_filefmt uint8
|
||||||
|
Att_res02 [3]uint8
|
||||||
|
Att_filetag uint32
|
||||||
|
Att_res03 [8]uint8
|
||||||
|
// end of version 2
|
||||||
|
Att_atime64 uint64
|
||||||
|
Att_mtime64 uint64
|
||||||
|
Att_ctime64 uint64
|
||||||
|
Att_reftime64 uint64
|
||||||
|
Att_seclabel [8]uint8
|
||||||
|
Att_ver3res02 [8]uint8
|
||||||
|
// end of version 3
|
||||||
|
}
|
||||||
|
|
||||||
|
func BpxOpen(name string, options *BpxFilestatus, mode *BpxMode) (rv int32, rc int32, rn int32) {
|
||||||
|
if len(name) < 1024 {
|
||||||
|
var namebuf [1024]byte
|
||||||
|
sz := int32(copy(namebuf[:], name))
|
||||||
|
A2e(namebuf[:sz])
|
||||||
|
var parms [7]unsafe.Pointer
|
||||||
|
parms[0] = unsafe.Pointer(&sz)
|
||||||
|
parms[1] = unsafe.Pointer(&namebuf[0])
|
||||||
|
parms[2] = unsafe.Pointer(options)
|
||||||
|
parms[3] = unsafe.Pointer(mode)
|
||||||
|
parms[4] = unsafe.Pointer(&rv)
|
||||||
|
parms[5] = unsafe.Pointer(&rc)
|
||||||
|
parms[6] = unsafe.Pointer(&rn)
|
||||||
|
bpxcall(parms[:], BPX4OPN)
|
||||||
|
return rv, rc, rn
|
||||||
|
}
|
||||||
|
return -1, -1, -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func BpxClose(fd int32) (rv int32, rc int32, rn int32) {
|
||||||
|
var parms [4]unsafe.Pointer
|
||||||
|
parms[0] = unsafe.Pointer(&fd)
|
||||||
|
parms[1] = unsafe.Pointer(&rv)
|
||||||
|
parms[2] = unsafe.Pointer(&rc)
|
||||||
|
parms[3] = unsafe.Pointer(&rn)
|
||||||
|
bpxcall(parms[:], BPX4CLO)
|
||||||
|
return rv, rc, rn
|
||||||
|
}
|
||||||
|
|
||||||
|
func BpxFileFStat(fd int32, st *Bpxystat_t) (rv int32, rc int32, rn int32) {
|
||||||
|
st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}
|
||||||
|
st.St_version = 2
|
||||||
|
stat_sz := uint32(unsafe.Sizeof(*st))
|
||||||
|
var parms [6]unsafe.Pointer
|
||||||
|
parms[0] = unsafe.Pointer(&fd)
|
||||||
|
parms[1] = unsafe.Pointer(&stat_sz)
|
||||||
|
parms[2] = unsafe.Pointer(st)
|
||||||
|
parms[3] = unsafe.Pointer(&rv)
|
||||||
|
parms[4] = unsafe.Pointer(&rc)
|
||||||
|
parms[5] = unsafe.Pointer(&rn)
|
||||||
|
bpxcall(parms[:], BPX4FST)
|
||||||
|
return rv, rc, rn
|
||||||
|
}
|
||||||
|
|
||||||
|
func BpxFileStat(name string, st *Bpxystat_t) (rv int32, rc int32, rn int32) {
|
||||||
|
if len(name) < 1024 {
|
||||||
|
var namebuf [1024]byte
|
||||||
|
sz := int32(copy(namebuf[:], name))
|
||||||
|
A2e(namebuf[:sz])
|
||||||
|
st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}
|
||||||
|
st.St_version = 2
|
||||||
|
stat_sz := uint32(unsafe.Sizeof(*st))
|
||||||
|
var parms [7]unsafe.Pointer
|
||||||
|
parms[0] = unsafe.Pointer(&sz)
|
||||||
|
parms[1] = unsafe.Pointer(&namebuf[0])
|
||||||
|
parms[2] = unsafe.Pointer(&stat_sz)
|
||||||
|
parms[3] = unsafe.Pointer(st)
|
||||||
|
parms[4] = unsafe.Pointer(&rv)
|
||||||
|
parms[5] = unsafe.Pointer(&rc)
|
||||||
|
parms[6] = unsafe.Pointer(&rn)
|
||||||
|
bpxcall(parms[:], BPX4STA)
|
||||||
|
return rv, rc, rn
|
||||||
|
}
|
||||||
|
return -1, -1, -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func BpxFileLStat(name string, st *Bpxystat_t) (rv int32, rc int32, rn int32) {
|
||||||
|
if len(name) < 1024 {
|
||||||
|
var namebuf [1024]byte
|
||||||
|
sz := int32(copy(namebuf[:], name))
|
||||||
|
A2e(namebuf[:sz])
|
||||||
|
st.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}
|
||||||
|
st.St_version = 2
|
||||||
|
stat_sz := uint32(unsafe.Sizeof(*st))
|
||||||
|
var parms [7]unsafe.Pointer
|
||||||
|
parms[0] = unsafe.Pointer(&sz)
|
||||||
|
parms[1] = unsafe.Pointer(&namebuf[0])
|
||||||
|
parms[2] = unsafe.Pointer(&stat_sz)
|
||||||
|
parms[3] = unsafe.Pointer(st)
|
||||||
|
parms[4] = unsafe.Pointer(&rv)
|
||||||
|
parms[5] = unsafe.Pointer(&rc)
|
||||||
|
parms[6] = unsafe.Pointer(&rn)
|
||||||
|
bpxcall(parms[:], BPX4LST)
|
||||||
|
return rv, rc, rn
|
||||||
|
}
|
||||||
|
return -1, -1, -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func BpxChattr(path string, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {
|
||||||
|
if len(path) >= 1024 {
|
||||||
|
return -1, -1, -1
|
||||||
|
}
|
||||||
|
var namebuf [1024]byte
|
||||||
|
sz := int32(copy(namebuf[:], path))
|
||||||
|
A2e(namebuf[:sz])
|
||||||
|
attr_sz := uint32(unsafe.Sizeof(*attr))
|
||||||
|
var parms [7]unsafe.Pointer
|
||||||
|
parms[0] = unsafe.Pointer(&sz)
|
||||||
|
parms[1] = unsafe.Pointer(&namebuf[0])
|
||||||
|
parms[2] = unsafe.Pointer(&attr_sz)
|
||||||
|
parms[3] = unsafe.Pointer(attr)
|
||||||
|
parms[4] = unsafe.Pointer(&rv)
|
||||||
|
parms[5] = unsafe.Pointer(&rc)
|
||||||
|
parms[6] = unsafe.Pointer(&rn)
|
||||||
|
bpxcall(parms[:], BPX4CHR)
|
||||||
|
return rv, rc, rn
|
||||||
|
}
|
||||||
|
|
||||||
|
func BpxLchattr(path string, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {
|
||||||
|
if len(path) >= 1024 {
|
||||||
|
return -1, -1, -1
|
||||||
|
}
|
||||||
|
var namebuf [1024]byte
|
||||||
|
sz := int32(copy(namebuf[:], path))
|
||||||
|
A2e(namebuf[:sz])
|
||||||
|
attr_sz := uint32(unsafe.Sizeof(*attr))
|
||||||
|
var parms [7]unsafe.Pointer
|
||||||
|
parms[0] = unsafe.Pointer(&sz)
|
||||||
|
parms[1] = unsafe.Pointer(&namebuf[0])
|
||||||
|
parms[2] = unsafe.Pointer(&attr_sz)
|
||||||
|
parms[3] = unsafe.Pointer(attr)
|
||||||
|
parms[4] = unsafe.Pointer(&rv)
|
||||||
|
parms[5] = unsafe.Pointer(&rc)
|
||||||
|
parms[6] = unsafe.Pointer(&rn)
|
||||||
|
bpxcall(parms[:], BPX4LCR)
|
||||||
|
return rv, rc, rn
|
||||||
|
}
|
||||||
|
|
||||||
|
func BpxFchattr(fd int32, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {
|
||||||
|
attr_sz := uint32(unsafe.Sizeof(*attr))
|
||||||
|
var parms [6]unsafe.Pointer
|
||||||
|
parms[0] = unsafe.Pointer(&fd)
|
||||||
|
parms[1] = unsafe.Pointer(&attr_sz)
|
||||||
|
parms[2] = unsafe.Pointer(attr)
|
||||||
|
parms[3] = unsafe.Pointer(&rv)
|
||||||
|
parms[4] = unsafe.Pointer(&rc)
|
||||||
|
parms[5] = unsafe.Pointer(&rn)
|
||||||
|
bpxcall(parms[:], BPX4FCR)
|
||||||
|
return rv, rc, rn
|
||||||
|
}
|
||||||
|
|
||||||
|
func BpxCondTimedWait(sec uint32, nsec uint32, events uint32, secrem *uint32, nsecrem *uint32) (rv int32, rc int32, rn int32) {
|
||||||
|
var parms [8]unsafe.Pointer
|
||||||
|
parms[0] = unsafe.Pointer(&sec)
|
||||||
|
parms[1] = unsafe.Pointer(&nsec)
|
||||||
|
parms[2] = unsafe.Pointer(&events)
|
||||||
|
parms[3] = unsafe.Pointer(secrem)
|
||||||
|
parms[4] = unsafe.Pointer(nsecrem)
|
||||||
|
parms[5] = unsafe.Pointer(&rv)
|
||||||
|
parms[6] = unsafe.Pointer(&rc)
|
||||||
|
parms[7] = unsafe.Pointer(&rn)
|
||||||
|
bpxcall(parms[:], BPX4CTW)
|
||||||
|
return rv, rc, rn
|
||||||
|
}
|
||||||
|
func BpxGetthent(in *Pgtha, outlen *uint32, out unsafe.Pointer) (rv int32, rc int32, rn int32) {
|
||||||
|
var parms [7]unsafe.Pointer
|
||||||
|
inlen := uint32(26) // nothing else will work. Go says Pgtha is 28-byte because of alignment, but Pgtha is "packed" and must be 26-byte
|
||||||
|
parms[0] = unsafe.Pointer(&inlen)
|
||||||
|
parms[1] = unsafe.Pointer(&in)
|
||||||
|
parms[2] = unsafe.Pointer(outlen)
|
||||||
|
parms[3] = unsafe.Pointer(&out)
|
||||||
|
parms[4] = unsafe.Pointer(&rv)
|
||||||
|
parms[5] = unsafe.Pointer(&rc)
|
||||||
|
parms[6] = unsafe.Pointer(&rn)
|
||||||
|
bpxcall(parms[:], BPX4GTH)
|
||||||
|
return rv, rc, rn
|
||||||
|
}
|
||||||
|
func ZosJobname() (jobname string, err error) {
|
||||||
|
var pgtha Pgtha
|
||||||
|
pgtha.Pid = uint32(Getpid())
|
||||||
|
pgtha.Accesspid = PGTHA_CURRENT
|
||||||
|
pgtha.Flag1 = PGTHA_PROCESS
|
||||||
|
var out [256]byte
|
||||||
|
var outlen uint32
|
||||||
|
outlen = 256
|
||||||
|
rv, rc, rn := BpxGetthent(&pgtha, &outlen, unsafe.Pointer(&out[0]))
|
||||||
|
if rv == 0 {
|
||||||
|
gthc := []byte{0x87, 0xa3, 0x88, 0x83} // 'gthc' in ebcdic
|
||||||
|
ix := bytes.Index(out[:], gthc)
|
||||||
|
if ix == -1 {
|
||||||
|
err = fmt.Errorf("BPX4GTH: gthc return data not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
jn := out[ix+80 : ix+88] // we didn't declare Pgthc, but jobname is 8-byte at offset 80
|
||||||
|
E2a(jn)
|
||||||
|
jobname = string(bytes.TrimRight(jn, " "))
|
||||||
|
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("BPX4GTH: rc=%d errno=%d reason=code=0x%x", rv, rc, rn)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func Bpx4ptq(code int32, data string) (rv int32, rc int32, rn int32) {
|
||||||
|
var userdata [8]byte
|
||||||
|
var parms [5]unsafe.Pointer
|
||||||
|
copy(userdata[:], data+" ")
|
||||||
|
A2e(userdata[:])
|
||||||
|
parms[0] = unsafe.Pointer(&code)
|
||||||
|
parms[1] = unsafe.Pointer(&userdata[0])
|
||||||
|
parms[2] = unsafe.Pointer(&rv)
|
||||||
|
parms[3] = unsafe.Pointer(&rc)
|
||||||
|
parms[4] = unsafe.Pointer(&rn)
|
||||||
|
bpxcall(parms[:], BPX4PTQ)
|
||||||
|
return rv, rc, rn
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
PT_TRACE_ME = 0 // Debug this process
|
||||||
|
PT_READ_I = 1 // Read a full word
|
||||||
|
PT_READ_D = 2 // Read a full word
|
||||||
|
PT_READ_U = 3 // Read control info
|
||||||
|
PT_WRITE_I = 4 //Write a full word
|
||||||
|
PT_WRITE_D = 5 //Write a full word
|
||||||
|
PT_CONTINUE = 7 //Continue the process
|
||||||
|
PT_KILL = 8 //Terminate the process
|
||||||
|
PT_READ_GPR = 11 // Read GPR, CR, PSW
|
||||||
|
PT_READ_FPR = 12 // Read FPR
|
||||||
|
PT_READ_VR = 13 // Read VR
|
||||||
|
PT_WRITE_GPR = 14 // Write GPR, CR, PSW
|
||||||
|
PT_WRITE_FPR = 15 // Write FPR
|
||||||
|
PT_WRITE_VR = 16 // Write VR
|
||||||
|
PT_READ_BLOCK = 17 // Read storage
|
||||||
|
PT_WRITE_BLOCK = 19 // Write storage
|
||||||
|
PT_READ_GPRH = 20 // Read GPRH
|
||||||
|
PT_WRITE_GPRH = 21 // Write GPRH
|
||||||
|
PT_REGHSET = 22 // Read all GPRHs
|
||||||
|
PT_ATTACH = 30 // Attach to a process
|
||||||
|
PT_DETACH = 31 // Detach from a process
|
||||||
|
PT_REGSET = 32 // Read all GPRs
|
||||||
|
PT_REATTACH = 33 // Reattach to a process
|
||||||
|
PT_LDINFO = 34 // Read loader info
|
||||||
|
PT_MULTI = 35 // Multi process mode
|
||||||
|
PT_LD64INFO = 36 // RMODE64 Info Area
|
||||||
|
PT_BLOCKREQ = 40 // Block request
|
||||||
|
PT_THREAD_INFO = 60 // Read thread info
|
||||||
|
PT_THREAD_MODIFY = 61
|
||||||
|
PT_THREAD_READ_FOCUS = 62
|
||||||
|
PT_THREAD_WRITE_FOCUS = 63
|
||||||
|
PT_THREAD_HOLD = 64
|
||||||
|
PT_THREAD_SIGNAL = 65
|
||||||
|
PT_EXPLAIN = 66
|
||||||
|
PT_EVENTS = 67
|
||||||
|
PT_THREAD_INFO_EXTENDED = 68
|
||||||
|
PT_REATTACH2 = 71
|
||||||
|
PT_CAPTURE = 72
|
||||||
|
PT_UNCAPTURE = 73
|
||||||
|
PT_GET_THREAD_TCB = 74
|
||||||
|
PT_GET_ALET = 75
|
||||||
|
PT_SWAPIN = 76
|
||||||
|
PT_EXTENDED_EVENT = 98
|
||||||
|
PT_RECOVER = 99 // Debug a program check
|
||||||
|
PT_GPR0 = 0 // General purpose register 0
|
||||||
|
PT_GPR1 = 1 // General purpose register 1
|
||||||
|
PT_GPR2 = 2 // General purpose register 2
|
||||||
|
PT_GPR3 = 3 // General purpose register 3
|
||||||
|
PT_GPR4 = 4 // General purpose register 4
|
||||||
|
PT_GPR5 = 5 // General purpose register 5
|
||||||
|
PT_GPR6 = 6 // General purpose register 6
|
||||||
|
PT_GPR7 = 7 // General purpose register 7
|
||||||
|
PT_GPR8 = 8 // General purpose register 8
|
||||||
|
PT_GPR9 = 9 // General purpose register 9
|
||||||
|
PT_GPR10 = 10 // General purpose register 10
|
||||||
|
PT_GPR11 = 11 // General purpose register 11
|
||||||
|
PT_GPR12 = 12 // General purpose register 12
|
||||||
|
PT_GPR13 = 13 // General purpose register 13
|
||||||
|
PT_GPR14 = 14 // General purpose register 14
|
||||||
|
PT_GPR15 = 15 // General purpose register 15
|
||||||
|
PT_FPR0 = 16 // Floating point register 0
|
||||||
|
PT_FPR1 = 17 // Floating point register 1
|
||||||
|
PT_FPR2 = 18 // Floating point register 2
|
||||||
|
PT_FPR3 = 19 // Floating point register 3
|
||||||
|
PT_FPR4 = 20 // Floating point register 4
|
||||||
|
PT_FPR5 = 21 // Floating point register 5
|
||||||
|
PT_FPR6 = 22 // Floating point register 6
|
||||||
|
PT_FPR7 = 23 // Floating point register 7
|
||||||
|
PT_FPR8 = 24 // Floating point register 8
|
||||||
|
PT_FPR9 = 25 // Floating point register 9
|
||||||
|
PT_FPR10 = 26 // Floating point register 10
|
||||||
|
PT_FPR11 = 27 // Floating point register 11
|
||||||
|
PT_FPR12 = 28 // Floating point register 12
|
||||||
|
PT_FPR13 = 29 // Floating point register 13
|
||||||
|
PT_FPR14 = 30 // Floating point register 14
|
||||||
|
PT_FPR15 = 31 // Floating point register 15
|
||||||
|
PT_FPC = 32 // Floating point control register
|
||||||
|
PT_PSW = 40 // PSW
|
||||||
|
PT_PSW0 = 40 // Left half of the PSW
|
||||||
|
PT_PSW1 = 41 // Right half of the PSW
|
||||||
|
PT_CR0 = 42 // Control register 0
|
||||||
|
PT_CR1 = 43 // Control register 1
|
||||||
|
PT_CR2 = 44 // Control register 2
|
||||||
|
PT_CR3 = 45 // Control register 3
|
||||||
|
PT_CR4 = 46 // Control register 4
|
||||||
|
PT_CR5 = 47 // Control register 5
|
||||||
|
PT_CR6 = 48 // Control register 6
|
||||||
|
PT_CR7 = 49 // Control register 7
|
||||||
|
PT_CR8 = 50 // Control register 8
|
||||||
|
PT_CR9 = 51 // Control register 9
|
||||||
|
PT_CR10 = 52 // Control register 10
|
||||||
|
PT_CR11 = 53 // Control register 11
|
||||||
|
PT_CR12 = 54 // Control register 12
|
||||||
|
PT_CR13 = 55 // Control register 13
|
||||||
|
PT_CR14 = 56 // Control register 14
|
||||||
|
PT_CR15 = 57 // Control register 15
|
||||||
|
PT_GPRH0 = 58 // GP High register 0
|
||||||
|
PT_GPRH1 = 59 // GP High register 1
|
||||||
|
PT_GPRH2 = 60 // GP High register 2
|
||||||
|
PT_GPRH3 = 61 // GP High register 3
|
||||||
|
PT_GPRH4 = 62 // GP High register 4
|
||||||
|
PT_GPRH5 = 63 // GP High register 5
|
||||||
|
PT_GPRH6 = 64 // GP High register 6
|
||||||
|
PT_GPRH7 = 65 // GP High register 7
|
||||||
|
PT_GPRH8 = 66 // GP High register 8
|
||||||
|
PT_GPRH9 = 67 // GP High register 9
|
||||||
|
PT_GPRH10 = 68 // GP High register 10
|
||||||
|
PT_GPRH11 = 69 // GP High register 11
|
||||||
|
PT_GPRH12 = 70 // GP High register 12
|
||||||
|
PT_GPRH13 = 71 // GP High register 13
|
||||||
|
PT_GPRH14 = 72 // GP High register 14
|
||||||
|
PT_GPRH15 = 73 // GP High register 15
|
||||||
|
PT_VR0 = 74 // Vector register 0
|
||||||
|
PT_VR1 = 75 // Vector register 1
|
||||||
|
PT_VR2 = 76 // Vector register 2
|
||||||
|
PT_VR3 = 77 // Vector register 3
|
||||||
|
PT_VR4 = 78 // Vector register 4
|
||||||
|
PT_VR5 = 79 // Vector register 5
|
||||||
|
PT_VR6 = 80 // Vector register 6
|
||||||
|
PT_VR7 = 81 // Vector register 7
|
||||||
|
PT_VR8 = 82 // Vector register 8
|
||||||
|
PT_VR9 = 83 // Vector register 9
|
||||||
|
PT_VR10 = 84 // Vector register 10
|
||||||
|
PT_VR11 = 85 // Vector register 11
|
||||||
|
PT_VR12 = 86 // Vector register 12
|
||||||
|
PT_VR13 = 87 // Vector register 13
|
||||||
|
PT_VR14 = 88 // Vector register 14
|
||||||
|
PT_VR15 = 89 // Vector register 15
|
||||||
|
PT_VR16 = 90 // Vector register 16
|
||||||
|
PT_VR17 = 91 // Vector register 17
|
||||||
|
PT_VR18 = 92 // Vector register 18
|
||||||
|
PT_VR19 = 93 // Vector register 19
|
||||||
|
PT_VR20 = 94 // Vector register 20
|
||||||
|
PT_VR21 = 95 // Vector register 21
|
||||||
|
PT_VR22 = 96 // Vector register 22
|
||||||
|
PT_VR23 = 97 // Vector register 23
|
||||||
|
PT_VR24 = 98 // Vector register 24
|
||||||
|
PT_VR25 = 99 // Vector register 25
|
||||||
|
PT_VR26 = 100 // Vector register 26
|
||||||
|
PT_VR27 = 101 // Vector register 27
|
||||||
|
PT_VR28 = 102 // Vector register 28
|
||||||
|
PT_VR29 = 103 // Vector register 29
|
||||||
|
PT_VR30 = 104 // Vector register 30
|
||||||
|
PT_VR31 = 105 // Vector register 31
|
||||||
|
PT_PSWG = 106 // PSWG
|
||||||
|
PT_PSWG0 = 106 // Bytes 0-3
|
||||||
|
PT_PSWG1 = 107 // Bytes 4-7
|
||||||
|
PT_PSWG2 = 108 // Bytes 8-11 (IA high word)
|
||||||
|
PT_PSWG3 = 109 // Bytes 12-15 (IA low word)
|
||||||
|
)
|
||||||
|
|
||||||
|
func Bpx4ptr(request int32, pid int32, addr unsafe.Pointer, data unsafe.Pointer, buffer unsafe.Pointer) (rv int32, rc int32, rn int32) {
|
||||||
|
var parms [8]unsafe.Pointer
|
||||||
|
parms[0] = unsafe.Pointer(&request)
|
||||||
|
parms[1] = unsafe.Pointer(&pid)
|
||||||
|
parms[2] = unsafe.Pointer(&addr)
|
||||||
|
parms[3] = unsafe.Pointer(&data)
|
||||||
|
parms[4] = unsafe.Pointer(&buffer)
|
||||||
|
parms[5] = unsafe.Pointer(&rv)
|
||||||
|
parms[6] = unsafe.Pointer(&rc)
|
||||||
|
parms[7] = unsafe.Pointer(&rn)
|
||||||
|
bpxcall(parms[:], BPX4PTR)
|
||||||
|
return rv, rc, rn
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyU8(val uint8, dest []uint8) int {
|
||||||
|
if len(dest) < 1 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
dest[0] = val
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyU8Arr(src, dest []uint8) int {
|
||||||
|
if len(dest) < len(src) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
for i, v := range src {
|
||||||
|
dest[i] = v
|
||||||
|
}
|
||||||
|
return len(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyU16(val uint16, dest []uint16) int {
|
||||||
|
if len(dest) < 1 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
dest[0] = val
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyU32(val uint32, dest []uint32) int {
|
||||||
|
if len(dest) < 1 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
dest[0] = val
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyU32Arr(src, dest []uint32) int {
|
||||||
|
if len(dest) < len(src) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
for i, v := range src {
|
||||||
|
dest[i] = v
|
||||||
|
}
|
||||||
|
return len(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyU64(val uint64, dest []uint64) int {
|
||||||
|
if len(dest) < 1 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
dest[0] = val
|
||||||
|
return 1
|
||||||
|
}
|
||||||
192
vendor/golang.org/x/sys/unix/bpxsvc_zos.s
generated
vendored
Normal file
192
vendor/golang.org/x/sys/unix/bpxsvc_zos.s
generated
vendored
Normal file
|
|
@ -0,0 +1,192 @@
|
||||||
|
// Copyright 2024 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.
|
||||||
|
|
||||||
|
#include "go_asm.h"
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// function to call USS assembly language services
|
||||||
|
//
|
||||||
|
// doc: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_3.1.0/com.ibm.zos.v3r1.bpxb100/bit64env.htm
|
||||||
|
//
|
||||||
|
// arg1 unsafe.Pointer array that ressembles an OS PLIST
|
||||||
|
//
|
||||||
|
// arg2 function offset as in
|
||||||
|
// doc: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_3.1.0/com.ibm.zos.v3r1.bpxb100/bpx2cr_List_of_offsets.htm
|
||||||
|
//
|
||||||
|
// func bpxcall(plist []unsafe.Pointer, bpx_offset int64)
|
||||||
|
|
||||||
|
TEXT ·bpxcall(SB), NOSPLIT|NOFRAME, $0
|
||||||
|
MOVD plist_base+0(FP), R1 // r1 points to plist
|
||||||
|
MOVD bpx_offset+24(FP), R2 // r2 offset to BPX vector table
|
||||||
|
MOVD R14, R7 // save r14
|
||||||
|
MOVD R15, R8 // save r15
|
||||||
|
MOVWZ 16(R0), R9
|
||||||
|
MOVWZ 544(R9), R9
|
||||||
|
MOVWZ 24(R9), R9 // call vector in r9
|
||||||
|
ADD R2, R9 // add offset to vector table
|
||||||
|
MOVWZ (R9), R9 // r9 points to entry point
|
||||||
|
BYTE $0x0D // BL R14,R9 --> basr r14,r9
|
||||||
|
BYTE $0xE9 // clobbers 0,1,14,15
|
||||||
|
MOVD R8, R15 // restore 15
|
||||||
|
JMP R7 // return via saved return address
|
||||||
|
|
||||||
|
// func A2e(arr [] byte)
|
||||||
|
// code page conversion from 819 to 1047
|
||||||
|
TEXT ·A2e(SB), NOSPLIT|NOFRAME, $0
|
||||||
|
MOVD arg_base+0(FP), R2 // pointer to arry of characters
|
||||||
|
MOVD arg_len+8(FP), R3 // count
|
||||||
|
XOR R0, R0
|
||||||
|
XOR R1, R1
|
||||||
|
BYTE $0xA7; BYTE $0x15; BYTE $0x00; BYTE $0x82 // BRAS 1,(2+(256/2))
|
||||||
|
|
||||||
|
// ASCII -> EBCDIC conversion table:
|
||||||
|
BYTE $0x00; BYTE $0x01; BYTE $0x02; BYTE $0x03
|
||||||
|
BYTE $0x37; BYTE $0x2d; BYTE $0x2e; BYTE $0x2f
|
||||||
|
BYTE $0x16; BYTE $0x05; BYTE $0x15; BYTE $0x0b
|
||||||
|
BYTE $0x0c; BYTE $0x0d; BYTE $0x0e; BYTE $0x0f
|
||||||
|
BYTE $0x10; BYTE $0x11; BYTE $0x12; BYTE $0x13
|
||||||
|
BYTE $0x3c; BYTE $0x3d; BYTE $0x32; BYTE $0x26
|
||||||
|
BYTE $0x18; BYTE $0x19; BYTE $0x3f; BYTE $0x27
|
||||||
|
BYTE $0x1c; BYTE $0x1d; BYTE $0x1e; BYTE $0x1f
|
||||||
|
BYTE $0x40; BYTE $0x5a; BYTE $0x7f; BYTE $0x7b
|
||||||
|
BYTE $0x5b; BYTE $0x6c; BYTE $0x50; BYTE $0x7d
|
||||||
|
BYTE $0x4d; BYTE $0x5d; BYTE $0x5c; BYTE $0x4e
|
||||||
|
BYTE $0x6b; BYTE $0x60; BYTE $0x4b; BYTE $0x61
|
||||||
|
BYTE $0xf0; BYTE $0xf1; BYTE $0xf2; BYTE $0xf3
|
||||||
|
BYTE $0xf4; BYTE $0xf5; BYTE $0xf6; BYTE $0xf7
|
||||||
|
BYTE $0xf8; BYTE $0xf9; BYTE $0x7a; BYTE $0x5e
|
||||||
|
BYTE $0x4c; BYTE $0x7e; BYTE $0x6e; BYTE $0x6f
|
||||||
|
BYTE $0x7c; BYTE $0xc1; BYTE $0xc2; BYTE $0xc3
|
||||||
|
BYTE $0xc4; BYTE $0xc5; BYTE $0xc6; BYTE $0xc7
|
||||||
|
BYTE $0xc8; BYTE $0xc9; BYTE $0xd1; BYTE $0xd2
|
||||||
|
BYTE $0xd3; BYTE $0xd4; BYTE $0xd5; BYTE $0xd6
|
||||||
|
BYTE $0xd7; BYTE $0xd8; BYTE $0xd9; BYTE $0xe2
|
||||||
|
BYTE $0xe3; BYTE $0xe4; BYTE $0xe5; BYTE $0xe6
|
||||||
|
BYTE $0xe7; BYTE $0xe8; BYTE $0xe9; BYTE $0xad
|
||||||
|
BYTE $0xe0; BYTE $0xbd; BYTE $0x5f; BYTE $0x6d
|
||||||
|
BYTE $0x79; BYTE $0x81; BYTE $0x82; BYTE $0x83
|
||||||
|
BYTE $0x84; BYTE $0x85; BYTE $0x86; BYTE $0x87
|
||||||
|
BYTE $0x88; BYTE $0x89; BYTE $0x91; BYTE $0x92
|
||||||
|
BYTE $0x93; BYTE $0x94; BYTE $0x95; BYTE $0x96
|
||||||
|
BYTE $0x97; BYTE $0x98; BYTE $0x99; BYTE $0xa2
|
||||||
|
BYTE $0xa3; BYTE $0xa4; BYTE $0xa5; BYTE $0xa6
|
||||||
|
BYTE $0xa7; BYTE $0xa8; BYTE $0xa9; BYTE $0xc0
|
||||||
|
BYTE $0x4f; BYTE $0xd0; BYTE $0xa1; BYTE $0x07
|
||||||
|
BYTE $0x20; BYTE $0x21; BYTE $0x22; BYTE $0x23
|
||||||
|
BYTE $0x24; BYTE $0x25; BYTE $0x06; BYTE $0x17
|
||||||
|
BYTE $0x28; BYTE $0x29; BYTE $0x2a; BYTE $0x2b
|
||||||
|
BYTE $0x2c; BYTE $0x09; BYTE $0x0a; BYTE $0x1b
|
||||||
|
BYTE $0x30; BYTE $0x31; BYTE $0x1a; BYTE $0x33
|
||||||
|
BYTE $0x34; BYTE $0x35; BYTE $0x36; BYTE $0x08
|
||||||
|
BYTE $0x38; BYTE $0x39; BYTE $0x3a; BYTE $0x3b
|
||||||
|
BYTE $0x04; BYTE $0x14; BYTE $0x3e; BYTE $0xff
|
||||||
|
BYTE $0x41; BYTE $0xaa; BYTE $0x4a; BYTE $0xb1
|
||||||
|
BYTE $0x9f; BYTE $0xb2; BYTE $0x6a; BYTE $0xb5
|
||||||
|
BYTE $0xbb; BYTE $0xb4; BYTE $0x9a; BYTE $0x8a
|
||||||
|
BYTE $0xb0; BYTE $0xca; BYTE $0xaf; BYTE $0xbc
|
||||||
|
BYTE $0x90; BYTE $0x8f; BYTE $0xea; BYTE $0xfa
|
||||||
|
BYTE $0xbe; BYTE $0xa0; BYTE $0xb6; BYTE $0xb3
|
||||||
|
BYTE $0x9d; BYTE $0xda; BYTE $0x9b; BYTE $0x8b
|
||||||
|
BYTE $0xb7; BYTE $0xb8; BYTE $0xb9; BYTE $0xab
|
||||||
|
BYTE $0x64; BYTE $0x65; BYTE $0x62; BYTE $0x66
|
||||||
|
BYTE $0x63; BYTE $0x67; BYTE $0x9e; BYTE $0x68
|
||||||
|
BYTE $0x74; BYTE $0x71; BYTE $0x72; BYTE $0x73
|
||||||
|
BYTE $0x78; BYTE $0x75; BYTE $0x76; BYTE $0x77
|
||||||
|
BYTE $0xac; BYTE $0x69; BYTE $0xed; BYTE $0xee
|
||||||
|
BYTE $0xeb; BYTE $0xef; BYTE $0xec; BYTE $0xbf
|
||||||
|
BYTE $0x80; BYTE $0xfd; BYTE $0xfe; BYTE $0xfb
|
||||||
|
BYTE $0xfc; BYTE $0xba; BYTE $0xae; BYTE $0x59
|
||||||
|
BYTE $0x44; BYTE $0x45; BYTE $0x42; BYTE $0x46
|
||||||
|
BYTE $0x43; BYTE $0x47; BYTE $0x9c; BYTE $0x48
|
||||||
|
BYTE $0x54; BYTE $0x51; BYTE $0x52; BYTE $0x53
|
||||||
|
BYTE $0x58; BYTE $0x55; BYTE $0x56; BYTE $0x57
|
||||||
|
BYTE $0x8c; BYTE $0x49; BYTE $0xcd; BYTE $0xce
|
||||||
|
BYTE $0xcb; BYTE $0xcf; BYTE $0xcc; BYTE $0xe1
|
||||||
|
BYTE $0x70; BYTE $0xdd; BYTE $0xde; BYTE $0xdb
|
||||||
|
BYTE $0xdc; BYTE $0x8d; BYTE $0x8e; BYTE $0xdf
|
||||||
|
|
||||||
|
retry:
|
||||||
|
WORD $0xB9931022 // TROO 2,2,b'0001'
|
||||||
|
BVS retry
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func e2a(arr [] byte)
|
||||||
|
// code page conversion from 1047 to 819
|
||||||
|
TEXT ·E2a(SB), NOSPLIT|NOFRAME, $0
|
||||||
|
MOVD arg_base+0(FP), R2 // pointer to arry of characters
|
||||||
|
MOVD arg_len+8(FP), R3 // count
|
||||||
|
XOR R0, R0
|
||||||
|
XOR R1, R1
|
||||||
|
BYTE $0xA7; BYTE $0x15; BYTE $0x00; BYTE $0x82 // BRAS 1,(2+(256/2))
|
||||||
|
|
||||||
|
// EBCDIC -> ASCII conversion table:
|
||||||
|
BYTE $0x00; BYTE $0x01; BYTE $0x02; BYTE $0x03
|
||||||
|
BYTE $0x9c; BYTE $0x09; BYTE $0x86; BYTE $0x7f
|
||||||
|
BYTE $0x97; BYTE $0x8d; BYTE $0x8e; BYTE $0x0b
|
||||||
|
BYTE $0x0c; BYTE $0x0d; BYTE $0x0e; BYTE $0x0f
|
||||||
|
BYTE $0x10; BYTE $0x11; BYTE $0x12; BYTE $0x13
|
||||||
|
BYTE $0x9d; BYTE $0x0a; BYTE $0x08; BYTE $0x87
|
||||||
|
BYTE $0x18; BYTE $0x19; BYTE $0x92; BYTE $0x8f
|
||||||
|
BYTE $0x1c; BYTE $0x1d; BYTE $0x1e; BYTE $0x1f
|
||||||
|
BYTE $0x80; BYTE $0x81; BYTE $0x82; BYTE $0x83
|
||||||
|
BYTE $0x84; BYTE $0x85; BYTE $0x17; BYTE $0x1b
|
||||||
|
BYTE $0x88; BYTE $0x89; BYTE $0x8a; BYTE $0x8b
|
||||||
|
BYTE $0x8c; BYTE $0x05; BYTE $0x06; BYTE $0x07
|
||||||
|
BYTE $0x90; BYTE $0x91; BYTE $0x16; BYTE $0x93
|
||||||
|
BYTE $0x94; BYTE $0x95; BYTE $0x96; BYTE $0x04
|
||||||
|
BYTE $0x98; BYTE $0x99; BYTE $0x9a; BYTE $0x9b
|
||||||
|
BYTE $0x14; BYTE $0x15; BYTE $0x9e; BYTE $0x1a
|
||||||
|
BYTE $0x20; BYTE $0xa0; BYTE $0xe2; BYTE $0xe4
|
||||||
|
BYTE $0xe0; BYTE $0xe1; BYTE $0xe3; BYTE $0xe5
|
||||||
|
BYTE $0xe7; BYTE $0xf1; BYTE $0xa2; BYTE $0x2e
|
||||||
|
BYTE $0x3c; BYTE $0x28; BYTE $0x2b; BYTE $0x7c
|
||||||
|
BYTE $0x26; BYTE $0xe9; BYTE $0xea; BYTE $0xeb
|
||||||
|
BYTE $0xe8; BYTE $0xed; BYTE $0xee; BYTE $0xef
|
||||||
|
BYTE $0xec; BYTE $0xdf; BYTE $0x21; BYTE $0x24
|
||||||
|
BYTE $0x2a; BYTE $0x29; BYTE $0x3b; BYTE $0x5e
|
||||||
|
BYTE $0x2d; BYTE $0x2f; BYTE $0xc2; BYTE $0xc4
|
||||||
|
BYTE $0xc0; BYTE $0xc1; BYTE $0xc3; BYTE $0xc5
|
||||||
|
BYTE $0xc7; BYTE $0xd1; BYTE $0xa6; BYTE $0x2c
|
||||||
|
BYTE $0x25; BYTE $0x5f; BYTE $0x3e; BYTE $0x3f
|
||||||
|
BYTE $0xf8; BYTE $0xc9; BYTE $0xca; BYTE $0xcb
|
||||||
|
BYTE $0xc8; BYTE $0xcd; BYTE $0xce; BYTE $0xcf
|
||||||
|
BYTE $0xcc; BYTE $0x60; BYTE $0x3a; BYTE $0x23
|
||||||
|
BYTE $0x40; BYTE $0x27; BYTE $0x3d; BYTE $0x22
|
||||||
|
BYTE $0xd8; BYTE $0x61; BYTE $0x62; BYTE $0x63
|
||||||
|
BYTE $0x64; BYTE $0x65; BYTE $0x66; BYTE $0x67
|
||||||
|
BYTE $0x68; BYTE $0x69; BYTE $0xab; BYTE $0xbb
|
||||||
|
BYTE $0xf0; BYTE $0xfd; BYTE $0xfe; BYTE $0xb1
|
||||||
|
BYTE $0xb0; BYTE $0x6a; BYTE $0x6b; BYTE $0x6c
|
||||||
|
BYTE $0x6d; BYTE $0x6e; BYTE $0x6f; BYTE $0x70
|
||||||
|
BYTE $0x71; BYTE $0x72; BYTE $0xaa; BYTE $0xba
|
||||||
|
BYTE $0xe6; BYTE $0xb8; BYTE $0xc6; BYTE $0xa4
|
||||||
|
BYTE $0xb5; BYTE $0x7e; BYTE $0x73; BYTE $0x74
|
||||||
|
BYTE $0x75; BYTE $0x76; BYTE $0x77; BYTE $0x78
|
||||||
|
BYTE $0x79; BYTE $0x7a; BYTE $0xa1; BYTE $0xbf
|
||||||
|
BYTE $0xd0; BYTE $0x5b; BYTE $0xde; BYTE $0xae
|
||||||
|
BYTE $0xac; BYTE $0xa3; BYTE $0xa5; BYTE $0xb7
|
||||||
|
BYTE $0xa9; BYTE $0xa7; BYTE $0xb6; BYTE $0xbc
|
||||||
|
BYTE $0xbd; BYTE $0xbe; BYTE $0xdd; BYTE $0xa8
|
||||||
|
BYTE $0xaf; BYTE $0x5d; BYTE $0xb4; BYTE $0xd7
|
||||||
|
BYTE $0x7b; BYTE $0x41; BYTE $0x42; BYTE $0x43
|
||||||
|
BYTE $0x44; BYTE $0x45; BYTE $0x46; BYTE $0x47
|
||||||
|
BYTE $0x48; BYTE $0x49; BYTE $0xad; BYTE $0xf4
|
||||||
|
BYTE $0xf6; BYTE $0xf2; BYTE $0xf3; BYTE $0xf5
|
||||||
|
BYTE $0x7d; BYTE $0x4a; BYTE $0x4b; BYTE $0x4c
|
||||||
|
BYTE $0x4d; BYTE $0x4e; BYTE $0x4f; BYTE $0x50
|
||||||
|
BYTE $0x51; BYTE $0x52; BYTE $0xb9; BYTE $0xfb
|
||||||
|
BYTE $0xfc; BYTE $0xf9; BYTE $0xfa; BYTE $0xff
|
||||||
|
BYTE $0x5c; BYTE $0xf7; BYTE $0x53; BYTE $0x54
|
||||||
|
BYTE $0x55; BYTE $0x56; BYTE $0x57; BYTE $0x58
|
||||||
|
BYTE $0x59; BYTE $0x5a; BYTE $0xb2; BYTE $0xd4
|
||||||
|
BYTE $0xd6; BYTE $0xd2; BYTE $0xd3; BYTE $0xd5
|
||||||
|
BYTE $0x30; BYTE $0x31; BYTE $0x32; BYTE $0x33
|
||||||
|
BYTE $0x34; BYTE $0x35; BYTE $0x36; BYTE $0x37
|
||||||
|
BYTE $0x38; BYTE $0x39; BYTE $0xb3; BYTE $0xdb
|
||||||
|
BYTE $0xdc; BYTE $0xd9; BYTE $0xda; BYTE $0x9f
|
||||||
|
|
||||||
|
retry:
|
||||||
|
WORD $0xB9931022 // TROO 2,2,b'0001'
|
||||||
|
BVS retry
|
||||||
|
RET
|
||||||
220
vendor/golang.org/x/sys/unix/epoll_zos.go
generated
vendored
220
vendor/golang.org/x/sys/unix/epoll_zos.go
generated
vendored
|
|
@ -1,220 +0,0 @@
|
||||||
// Copyright 2020 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 zos && s390x
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This file simulates epoll on z/OS using poll.
|
|
||||||
|
|
||||||
// Analogous to epoll_event on Linux.
|
|
||||||
// TODO(neeilan): Pad is because the Linux kernel expects a 96-bit struct. We never pass this to the kernel; remove?
|
|
||||||
type EpollEvent struct {
|
|
||||||
Events uint32
|
|
||||||
Fd int32
|
|
||||||
Pad int32
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
EPOLLERR = 0x8
|
|
||||||
EPOLLHUP = 0x10
|
|
||||||
EPOLLIN = 0x1
|
|
||||||
EPOLLMSG = 0x400
|
|
||||||
EPOLLOUT = 0x4
|
|
||||||
EPOLLPRI = 0x2
|
|
||||||
EPOLLRDBAND = 0x80
|
|
||||||
EPOLLRDNORM = 0x40
|
|
||||||
EPOLLWRBAND = 0x200
|
|
||||||
EPOLLWRNORM = 0x100
|
|
||||||
EPOLL_CTL_ADD = 0x1
|
|
||||||
EPOLL_CTL_DEL = 0x2
|
|
||||||
EPOLL_CTL_MOD = 0x3
|
|
||||||
// The following constants are part of the epoll API, but represent
|
|
||||||
// currently unsupported functionality on z/OS.
|
|
||||||
// EPOLL_CLOEXEC = 0x80000
|
|
||||||
// EPOLLET = 0x80000000
|
|
||||||
// EPOLLONESHOT = 0x40000000
|
|
||||||
// EPOLLRDHUP = 0x2000 // Typically used with edge-triggered notis
|
|
||||||
// EPOLLEXCLUSIVE = 0x10000000 // Exclusive wake-up mode
|
|
||||||
// EPOLLWAKEUP = 0x20000000 // Relies on Linux's BLOCK_SUSPEND capability
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO(neeilan): We can eliminate these epToPoll / pToEpoll calls by using identical mask values for POLL/EPOLL
|
|
||||||
// constants where possible The lower 16 bits of epoll events (uint32) can fit any system poll event (int16).
|
|
||||||
|
|
||||||
// epToPollEvt converts epoll event field to poll equivalent.
|
|
||||||
// In epoll, Events is a 32-bit field, while poll uses 16 bits.
|
|
||||||
func epToPollEvt(events uint32) int16 {
|
|
||||||
var ep2p = map[uint32]int16{
|
|
||||||
EPOLLIN: POLLIN,
|
|
||||||
EPOLLOUT: POLLOUT,
|
|
||||||
EPOLLHUP: POLLHUP,
|
|
||||||
EPOLLPRI: POLLPRI,
|
|
||||||
EPOLLERR: POLLERR,
|
|
||||||
}
|
|
||||||
|
|
||||||
var pollEvts int16 = 0
|
|
||||||
for epEvt, pEvt := range ep2p {
|
|
||||||
if (events & epEvt) != 0 {
|
|
||||||
pollEvts |= pEvt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pollEvts
|
|
||||||
}
|
|
||||||
|
|
||||||
// pToEpollEvt converts 16 bit poll event bitfields to 32-bit epoll event fields.
|
|
||||||
func pToEpollEvt(revents int16) uint32 {
|
|
||||||
var p2ep = map[int16]uint32{
|
|
||||||
POLLIN: EPOLLIN,
|
|
||||||
POLLOUT: EPOLLOUT,
|
|
||||||
POLLHUP: EPOLLHUP,
|
|
||||||
POLLPRI: EPOLLPRI,
|
|
||||||
POLLERR: EPOLLERR,
|
|
||||||
}
|
|
||||||
|
|
||||||
var epollEvts uint32 = 0
|
|
||||||
for pEvt, epEvt := range p2ep {
|
|
||||||
if (revents & pEvt) != 0 {
|
|
||||||
epollEvts |= epEvt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return epollEvts
|
|
||||||
}
|
|
||||||
|
|
||||||
// Per-process epoll implementation.
|
|
||||||
type epollImpl struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
epfd2ep map[int]*eventPoll
|
|
||||||
nextEpfd int
|
|
||||||
}
|
|
||||||
|
|
||||||
// eventPoll holds a set of file descriptors being watched by the process. A process can have multiple epoll instances.
|
|
||||||
// On Linux, this is an in-kernel data structure accessed through a fd.
|
|
||||||
type eventPoll struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
fds map[int]*EpollEvent
|
|
||||||
}
|
|
||||||
|
|
||||||
// epoll impl for this process.
|
|
||||||
var impl epollImpl = epollImpl{
|
|
||||||
epfd2ep: make(map[int]*eventPoll),
|
|
||||||
nextEpfd: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *epollImpl) epollcreate(size int) (epfd int, err error) {
|
|
||||||
e.mu.Lock()
|
|
||||||
defer e.mu.Unlock()
|
|
||||||
epfd = e.nextEpfd
|
|
||||||
e.nextEpfd++
|
|
||||||
|
|
||||||
e.epfd2ep[epfd] = &eventPoll{
|
|
||||||
fds: make(map[int]*EpollEvent),
|
|
||||||
}
|
|
||||||
return epfd, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *epollImpl) epollcreate1(flag int) (fd int, err error) {
|
|
||||||
return e.epollcreate(4)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *epollImpl) epollctl(epfd int, op int, fd int, event *EpollEvent) (err error) {
|
|
||||||
e.mu.Lock()
|
|
||||||
defer e.mu.Unlock()
|
|
||||||
|
|
||||||
ep, ok := e.epfd2ep[epfd]
|
|
||||||
if !ok {
|
|
||||||
|
|
||||||
return EBADF
|
|
||||||
}
|
|
||||||
|
|
||||||
switch op {
|
|
||||||
case EPOLL_CTL_ADD:
|
|
||||||
// TODO(neeilan): When we make epfds and fds disjoint, detect epoll
|
|
||||||
// loops here (instances watching each other) and return ELOOP.
|
|
||||||
if _, ok := ep.fds[fd]; ok {
|
|
||||||
return EEXIST
|
|
||||||
}
|
|
||||||
ep.fds[fd] = event
|
|
||||||
case EPOLL_CTL_MOD:
|
|
||||||
if _, ok := ep.fds[fd]; !ok {
|
|
||||||
return ENOENT
|
|
||||||
}
|
|
||||||
ep.fds[fd] = event
|
|
||||||
case EPOLL_CTL_DEL:
|
|
||||||
if _, ok := ep.fds[fd]; !ok {
|
|
||||||
return ENOENT
|
|
||||||
}
|
|
||||||
delete(ep.fds, fd)
|
|
||||||
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Must be called while holding ep.mu
|
|
||||||
func (ep *eventPoll) getFds() []int {
|
|
||||||
fds := make([]int, len(ep.fds))
|
|
||||||
for fd := range ep.fds {
|
|
||||||
fds = append(fds, fd)
|
|
||||||
}
|
|
||||||
return fds
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *epollImpl) epollwait(epfd int, events []EpollEvent, msec int) (n int, err error) {
|
|
||||||
e.mu.Lock() // in [rare] case of concurrent epollcreate + epollwait
|
|
||||||
ep, ok := e.epfd2ep[epfd]
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
e.mu.Unlock()
|
|
||||||
return 0, EBADF
|
|
||||||
}
|
|
||||||
|
|
||||||
pollfds := make([]PollFd, 4)
|
|
||||||
for fd, epollevt := range ep.fds {
|
|
||||||
pollfds = append(pollfds, PollFd{Fd: int32(fd), Events: epToPollEvt(epollevt.Events)})
|
|
||||||
}
|
|
||||||
e.mu.Unlock()
|
|
||||||
|
|
||||||
n, err = Poll(pollfds, msec)
|
|
||||||
if err != nil {
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
i := 0
|
|
||||||
for _, pFd := range pollfds {
|
|
||||||
if pFd.Revents != 0 {
|
|
||||||
events[i] = EpollEvent{Fd: pFd.Fd, Events: pToEpollEvt(pFd.Revents)}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
if i == n {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func EpollCreate(size int) (fd int, err error) {
|
|
||||||
return impl.epollcreate(size)
|
|
||||||
}
|
|
||||||
|
|
||||||
func EpollCreate1(flag int) (fd int, err error) {
|
|
||||||
return impl.epollcreate1(flag)
|
|
||||||
}
|
|
||||||
|
|
||||||
func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
|
|
||||||
return impl.epollctl(epfd, op, fd, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Because EpollWait mutates events, the caller is expected to coordinate
|
|
||||||
// concurrent access if calling with the same epfd from multiple goroutines.
|
|
||||||
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
|
|
||||||
return impl.epollwait(epfd, events, msec)
|
|
||||||
}
|
|
||||||
163
vendor/golang.org/x/sys/unix/fstatfs_zos.go
generated
vendored
163
vendor/golang.org/x/sys/unix/fstatfs_zos.go
generated
vendored
|
|
@ -1,163 +0,0 @@
|
||||||
// Copyright 2020 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 zos && s390x
|
|
||||||
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This file simulates fstatfs on z/OS using fstatvfs and w_getmntent.
|
|
||||||
|
|
||||||
func Fstatfs(fd int, stat *Statfs_t) (err error) {
|
|
||||||
var stat_v Statvfs_t
|
|
||||||
err = Fstatvfs(fd, &stat_v)
|
|
||||||
if err == nil {
|
|
||||||
// populate stat
|
|
||||||
stat.Type = 0
|
|
||||||
stat.Bsize = stat_v.Bsize
|
|
||||||
stat.Blocks = stat_v.Blocks
|
|
||||||
stat.Bfree = stat_v.Bfree
|
|
||||||
stat.Bavail = stat_v.Bavail
|
|
||||||
stat.Files = stat_v.Files
|
|
||||||
stat.Ffree = stat_v.Ffree
|
|
||||||
stat.Fsid = stat_v.Fsid
|
|
||||||
stat.Namelen = stat_v.Namemax
|
|
||||||
stat.Frsize = stat_v.Frsize
|
|
||||||
stat.Flags = stat_v.Flag
|
|
||||||
for passn := 0; passn < 5; passn++ {
|
|
||||||
switch passn {
|
|
||||||
case 0:
|
|
||||||
err = tryGetmntent64(stat)
|
|
||||||
break
|
|
||||||
case 1:
|
|
||||||
err = tryGetmntent128(stat)
|
|
||||||
break
|
|
||||||
case 2:
|
|
||||||
err = tryGetmntent256(stat)
|
|
||||||
break
|
|
||||||
case 3:
|
|
||||||
err = tryGetmntent512(stat)
|
|
||||||
break
|
|
||||||
case 4:
|
|
||||||
err = tryGetmntent1024(stat)
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
//proceed to return if: err is nil (found), err is nonnil but not ERANGE (another error occurred)
|
|
||||||
if err == nil || err != nil && err != ERANGE {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func tryGetmntent64(stat *Statfs_t) (err error) {
|
|
||||||
var mnt_ent_buffer struct {
|
|
||||||
header W_Mnth
|
|
||||||
filesys_info [64]W_Mntent
|
|
||||||
}
|
|
||||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
|
|
||||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = ERANGE //return ERANGE if no match is found in this batch
|
|
||||||
for i := 0; i < fs_count; i++ {
|
|
||||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
|
|
||||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
|
|
||||||
err = nil
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func tryGetmntent128(stat *Statfs_t) (err error) {
|
|
||||||
var mnt_ent_buffer struct {
|
|
||||||
header W_Mnth
|
|
||||||
filesys_info [128]W_Mntent
|
|
||||||
}
|
|
||||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
|
|
||||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = ERANGE //return ERANGE if no match is found in this batch
|
|
||||||
for i := 0; i < fs_count; i++ {
|
|
||||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
|
|
||||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
|
|
||||||
err = nil
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func tryGetmntent256(stat *Statfs_t) (err error) {
|
|
||||||
var mnt_ent_buffer struct {
|
|
||||||
header W_Mnth
|
|
||||||
filesys_info [256]W_Mntent
|
|
||||||
}
|
|
||||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
|
|
||||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = ERANGE //return ERANGE if no match is found in this batch
|
|
||||||
for i := 0; i < fs_count; i++ {
|
|
||||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
|
|
||||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
|
|
||||||
err = nil
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func tryGetmntent512(stat *Statfs_t) (err error) {
|
|
||||||
var mnt_ent_buffer struct {
|
|
||||||
header W_Mnth
|
|
||||||
filesys_info [512]W_Mntent
|
|
||||||
}
|
|
||||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
|
|
||||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = ERANGE //return ERANGE if no match is found in this batch
|
|
||||||
for i := 0; i < fs_count; i++ {
|
|
||||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
|
|
||||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
|
|
||||||
err = nil
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func tryGetmntent1024(stat *Statfs_t) (err error) {
|
|
||||||
var mnt_ent_buffer struct {
|
|
||||||
header W_Mnth
|
|
||||||
filesys_info [1024]W_Mntent
|
|
||||||
}
|
|
||||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
|
|
||||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = ERANGE //return ERANGE if no match is found in this batch
|
|
||||||
for i := 0; i < fs_count; i++ {
|
|
||||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
|
|
||||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
|
|
||||||
err = nil
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
41
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
41
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
|
|
@ -248,6 +248,7 @@ struct ltchars {
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mount.h>
|
#include <linux/mount.h>
|
||||||
#include <linux/netfilter/nfnetlink.h>
|
#include <linux/netfilter/nfnetlink.h>
|
||||||
|
#include <linux/netfilter/nf_tables.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <linux/net_namespace.h>
|
#include <linux/net_namespace.h>
|
||||||
#include <linux/nfc.h>
|
#include <linux/nfc.h>
|
||||||
|
|
@ -262,6 +263,7 @@ struct ltchars {
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/seccomp.h>
|
#include <linux/seccomp.h>
|
||||||
#include <linux/serial.h>
|
#include <linux/serial.h>
|
||||||
|
#include <linux/sock_diag.h>
|
||||||
#include <linux/sockios.h>
|
#include <linux/sockios.h>
|
||||||
#include <linux/taskstats.h>
|
#include <linux/taskstats.h>
|
||||||
#include <linux/tipc.h>
|
#include <linux/tipc.h>
|
||||||
|
|
@ -283,10 +285,6 @@ struct ltchars {
|
||||||
#include <asm/termbits.h>
|
#include <asm/termbits.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MSG_FASTOPEN
|
|
||||||
#define MSG_FASTOPEN 0x20000000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PTRACE_GETREGS
|
#ifndef PTRACE_GETREGS
|
||||||
#define PTRACE_GETREGS 0xc
|
#define PTRACE_GETREGS 0xc
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -295,14 +293,6 @@ struct ltchars {
|
||||||
#define PTRACE_SETREGS 0xd
|
#define PTRACE_SETREGS 0xd
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SOL_NETLINK
|
|
||||||
#define SOL_NETLINK 270
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SOL_SMC
|
|
||||||
#define SOL_SMC 286
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SOL_BLUETOOTH
|
#ifdef SOL_BLUETOOTH
|
||||||
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
|
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
|
||||||
// but it is already in bluetooth_linux.go
|
// but it is already in bluetooth_linux.go
|
||||||
|
|
@ -319,10 +309,23 @@ struct ltchars {
|
||||||
#undef TIPC_WAIT_FOREVER
|
#undef TIPC_WAIT_FOREVER
|
||||||
#define TIPC_WAIT_FOREVER 0xffffffff
|
#define TIPC_WAIT_FOREVER 0xffffffff
|
||||||
|
|
||||||
// Copied from linux/l2tp.h
|
// Copied from linux/netfilter/nf_nat.h
|
||||||
// Including linux/l2tp.h here causes conflicts between linux/in.h
|
// Including linux/netfilter/nf_nat.h here causes conflicts between linux/in.h
|
||||||
// and netinet/in.h included via net/route.h above.
|
// and netinet/in.h.
|
||||||
#define IPPROTO_L2TP 115
|
#define NF_NAT_RANGE_MAP_IPS (1 << 0)
|
||||||
|
#define NF_NAT_RANGE_PROTO_SPECIFIED (1 << 1)
|
||||||
|
#define NF_NAT_RANGE_PROTO_RANDOM (1 << 2)
|
||||||
|
#define NF_NAT_RANGE_PERSISTENT (1 << 3)
|
||||||
|
#define NF_NAT_RANGE_PROTO_RANDOM_FULLY (1 << 4)
|
||||||
|
#define NF_NAT_RANGE_PROTO_OFFSET (1 << 5)
|
||||||
|
#define NF_NAT_RANGE_NETMAP (1 << 6)
|
||||||
|
#define NF_NAT_RANGE_PROTO_RANDOM_ALL \
|
||||||
|
(NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
|
||||||
|
#define NF_NAT_RANGE_MASK \
|
||||||
|
(NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED | \
|
||||||
|
NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PERSISTENT | \
|
||||||
|
NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET | \
|
||||||
|
NF_NAT_RANGE_NETMAP)
|
||||||
|
|
||||||
// Copied from linux/hid.h.
|
// Copied from linux/hid.h.
|
||||||
// Keep in sync with the size of the referenced fields.
|
// Keep in sync with the size of the referenced fields.
|
||||||
|
|
@ -547,6 +550,7 @@ ccflags="$@"
|
||||||
$2 !~ "NLA_TYPE_MASK" &&
|
$2 !~ "NLA_TYPE_MASK" &&
|
||||||
$2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ &&
|
$2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ &&
|
||||||
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ ||
|
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ ||
|
||||||
|
$2 ~ /^SOCK_|SK_DIAG_|SKNLGRP_$/ ||
|
||||||
$2 ~ /^FIORDCHK$/ ||
|
$2 ~ /^FIORDCHK$/ ||
|
||||||
$2 ~ /^SIOC/ ||
|
$2 ~ /^SIOC/ ||
|
||||||
$2 ~ /^TIOC/ ||
|
$2 ~ /^TIOC/ ||
|
||||||
|
|
@ -582,7 +586,7 @@ ccflags="$@"
|
||||||
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
|
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
|
||||||
$2 ~ /^KEYCTL_/ ||
|
$2 ~ /^KEYCTL_/ ||
|
||||||
$2 ~ /^PERF_/ ||
|
$2 ~ /^PERF_/ ||
|
||||||
$2 ~ /^SECCOMP_MODE_/ ||
|
$2 ~ /^SECCOMP_/ ||
|
||||||
$2 ~ /^SEEK_/ ||
|
$2 ~ /^SEEK_/ ||
|
||||||
$2 ~ /^SCHED_/ ||
|
$2 ~ /^SCHED_/ ||
|
||||||
$2 ~ /^SPLICE_/ ||
|
$2 ~ /^SPLICE_/ ||
|
||||||
|
|
@ -603,6 +607,9 @@ ccflags="$@"
|
||||||
$2 ~ /^FSOPT_/ ||
|
$2 ~ /^FSOPT_/ ||
|
||||||
$2 ~ /^WDIO[CFS]_/ ||
|
$2 ~ /^WDIO[CFS]_/ ||
|
||||||
$2 ~ /^NFN/ ||
|
$2 ~ /^NFN/ ||
|
||||||
|
$2 !~ /^NFT_META_IIFTYPE/ &&
|
||||||
|
$2 ~ /^NFT_/ ||
|
||||||
|
$2 ~ /^NF_NAT_/ ||
|
||||||
$2 ~ /^XDP_/ ||
|
$2 ~ /^XDP_/ ||
|
||||||
$2 ~ /^RWF_/ ||
|
$2 ~ /^RWF_/ ||
|
||||||
$2 ~ /^(HDIO|WIN|SMART)_/ ||
|
$2 ~ /^(HDIO|WIN|SMART)_/ ||
|
||||||
|
|
|
||||||
2
vendor/golang.org/x/sys/unix/mmap_nomremap.go
generated
vendored
2
vendor/golang.org/x/sys/unix/mmap_nomremap.go
generated
vendored
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris
|
//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris || zos
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
|
|
||||||
5
vendor/golang.org/x/sys/unix/mremap.go
generated
vendored
5
vendor/golang.org/x/sys/unix/mremap.go
generated
vendored
|
|
@ -50,3 +50,8 @@ func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data [
|
||||||
func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
|
func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
|
||||||
return mapper.Mremap(oldData, newLength, flags)
|
return mapper.Mremap(oldData, newLength, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MremapPtr(oldAddr unsafe.Pointer, oldSize uintptr, newAddr unsafe.Pointer, newSize uintptr, flags int) (ret unsafe.Pointer, err error) {
|
||||||
|
xaddr, err := mapper.mremap(uintptr(oldAddr), oldSize, newSize, flags, uintptr(newAddr))
|
||||||
|
return unsafe.Pointer(xaddr), err
|
||||||
|
}
|
||||||
|
|
|
||||||
2
vendor/golang.org/x/sys/unix/pagesize_unix.go
generated
vendored
2
vendor/golang.org/x/sys/unix/pagesize_unix.go
generated
vendored
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||||
|
|
||||||
// For Unix, get the pagesize from the runtime.
|
// For Unix, get the pagesize from the runtime.
|
||||||
|
|
||||||
|
|
|
||||||
2
vendor/golang.org/x/sys/unix/readdirent_getdirentries.go
generated
vendored
2
vendor/golang.org/x/sys/unix/readdirent_getdirentries.go
generated
vendored
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build darwin
|
//go:build darwin || zos
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
|
|
||||||
58
vendor/golang.org/x/sys/unix/sockcmsg_zos.go
generated
vendored
Normal file
58
vendor/golang.org/x/sys/unix/sockcmsg_zos.go
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright 2024 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.
|
||||||
|
|
||||||
|
// Socket control messages
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// UnixCredentials encodes credentials into a socket control message
|
||||||
|
// for sending to another process. This can be used for
|
||||||
|
// authentication.
|
||||||
|
func UnixCredentials(ucred *Ucred) []byte {
|
||||||
|
b := make([]byte, CmsgSpace(SizeofUcred))
|
||||||
|
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||||
|
h.Level = SOL_SOCKET
|
||||||
|
h.Type = SCM_CREDENTIALS
|
||||||
|
h.SetLen(CmsgLen(SizeofUcred))
|
||||||
|
*(*Ucred)(h.data(0)) = *ucred
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseUnixCredentials decodes a socket control message that contains
|
||||||
|
// credentials in a Ucred structure. To receive such a message, the
|
||||||
|
// SO_PASSCRED option must be enabled on the socket.
|
||||||
|
func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) {
|
||||||
|
if m.Header.Level != SOL_SOCKET {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
if m.Header.Type != SCM_CREDENTIALS {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
|
||||||
|
return &ucred, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PktInfo4 encodes Inet4Pktinfo into a socket control message of type IP_PKTINFO.
|
||||||
|
func PktInfo4(info *Inet4Pktinfo) []byte {
|
||||||
|
b := make([]byte, CmsgSpace(SizeofInet4Pktinfo))
|
||||||
|
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||||
|
h.Level = SOL_IP
|
||||||
|
h.Type = IP_PKTINFO
|
||||||
|
h.SetLen(CmsgLen(SizeofInet4Pktinfo))
|
||||||
|
*(*Inet4Pktinfo)(h.data(0)) = *info
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// PktInfo6 encodes Inet6Pktinfo into a socket control message of type IPV6_PKTINFO.
|
||||||
|
func PktInfo6(info *Inet6Pktinfo) []byte {
|
||||||
|
b := make([]byte, CmsgSpace(SizeofInet6Pktinfo))
|
||||||
|
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||||
|
h.Level = SOL_IPV6
|
||||||
|
h.Type = IPV6_PKTINFO
|
||||||
|
h.SetLen(CmsgLen(SizeofInet6Pktinfo))
|
||||||
|
*(*Inet6Pktinfo)(h.data(0)) = *info
|
||||||
|
return b
|
||||||
|
}
|
||||||
75
vendor/golang.org/x/sys/unix/symaddr_zos_s390x.s
generated
vendored
Normal file
75
vendor/golang.org/x/sys/unix/symaddr_zos_s390x.s
generated
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
// Copyright 2024 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 zos && s390x && gc
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// provide the address of function variable to be fixed up.
|
||||||
|
|
||||||
|
TEXT ·getPipe2Addr(SB), NOSPLIT|NOFRAME, $0-8
|
||||||
|
MOVD $·Pipe2(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·get_FlockAddr(SB), NOSPLIT|NOFRAME, $0-8
|
||||||
|
MOVD $·Flock(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·get_GetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
|
||||||
|
MOVD $·Getxattr(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·get_NanosleepAddr(SB), NOSPLIT|NOFRAME, $0-8
|
||||||
|
MOVD $·Nanosleep(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·get_SetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8
|
||||||
|
MOVD $·Setxattr(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·get_Wait4Addr(SB), NOSPLIT|NOFRAME, $0-8
|
||||||
|
MOVD $·Wait4(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·get_MountAddr(SB), NOSPLIT|NOFRAME, $0-8
|
||||||
|
MOVD $·Mount(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·get_UnmountAddr(SB), NOSPLIT|NOFRAME, $0-8
|
||||||
|
MOVD $·Unmount(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·get_UtimesNanoAtAddr(SB), NOSPLIT|NOFRAME, $0-8
|
||||||
|
MOVD $·UtimesNanoAt(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·get_UtimesNanoAddr(SB), NOSPLIT|NOFRAME, $0-8
|
||||||
|
MOVD $·UtimesNano(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·get_MkfifoatAddr(SB), NOSPLIT|NOFRAME, $0-8
|
||||||
|
MOVD $·Mkfifoat(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·get_ChtagAddr(SB), NOSPLIT|NOFRAME, $0-8
|
||||||
|
MOVD $·Chtag(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·get_ReadlinkatAddr(SB), NOSPLIT|NOFRAME, $0-8
|
||||||
|
MOVD $·Readlinkat(SB), R8
|
||||||
|
MOVD R8, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
12
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
12
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
|
|
@ -542,6 +542,18 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//sys pthread_chdir_np(path string) (err error)
|
||||||
|
|
||||||
|
func PthreadChdir(path string) (err error) {
|
||||||
|
return pthread_chdir_np(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys pthread_fchdir_np(fd int) (err error)
|
||||||
|
|
||||||
|
func PthreadFchdir(fd int) (err error) {
|
||||||
|
return pthread_fchdir_np(fd)
|
||||||
|
}
|
||||||
|
|
||||||
//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)
|
||||||
|
|
|
||||||
2
vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go
generated
vendored
2
vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go
generated
vendored
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build darwin && go1.12
|
//go:build darwin
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
|
|
||||||
12
vendor/golang.org/x/sys/unix/syscall_freebsd.go
generated
vendored
12
vendor/golang.org/x/sys/unix/syscall_freebsd.go
generated
vendored
|
|
@ -13,6 +13,7 @@
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"sync"
|
"sync"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
@ -169,25 +170,26 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
||||||
func Uname(uname *Utsname) error {
|
func Uname(uname *Utsname) error {
|
||||||
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
|
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
|
||||||
n := unsafe.Sizeof(uname.Sysname)
|
n := unsafe.Sizeof(uname.Sysname)
|
||||||
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
|
// Suppress ENOMEM errors to be compatible with the C library __xuname() implementation.
|
||||||
|
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
|
mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
|
||||||
n = unsafe.Sizeof(uname.Nodename)
|
n = unsafe.Sizeof(uname.Nodename)
|
||||||
if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
|
if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
|
mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
|
||||||
n = unsafe.Sizeof(uname.Release)
|
n = unsafe.Sizeof(uname.Release)
|
||||||
if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
|
if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mib = []_C_int{CTL_KERN, KERN_VERSION}
|
mib = []_C_int{CTL_KERN, KERN_VERSION}
|
||||||
n = unsafe.Sizeof(uname.Version)
|
n = unsafe.Sizeof(uname.Version)
|
||||||
if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
|
if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,7 +207,7 @@ func Uname(uname *Utsname) error {
|
||||||
|
|
||||||
mib = []_C_int{CTL_HW, HW_MACHINE}
|
mib = []_C_int{CTL_HW, HW_MACHINE}
|
||||||
n = unsafe.Sizeof(uname.Machine)
|
n = unsafe.Sizeof(uname.Machine)
|
||||||
if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
|
if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
99
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
99
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
|
|
@ -1849,6 +1849,105 @@ func Dup2(oldfd, newfd int) error {
|
||||||
//sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error)
|
//sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error)
|
||||||
//sys Fsopen(fsName string, flags int) (fd int, err error)
|
//sys Fsopen(fsName string, flags int) (fd int, err error)
|
||||||
//sys Fspick(dirfd int, pathName string, flags int) (fd int, err error)
|
//sys Fspick(dirfd int, pathName string, flags int) (fd int, err error)
|
||||||
|
|
||||||
|
//sys fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error)
|
||||||
|
|
||||||
|
func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) {
|
||||||
|
var keyp *byte
|
||||||
|
if keyp, err = BytePtrFromString(key); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return fsconfig(fd, cmd, keyp, value, aux)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigSetFlag is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_SET_FLAG.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
// key the parameter key to set.
|
||||||
|
func FsconfigSetFlag(fd int, key string) (err error) {
|
||||||
|
return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigSetString is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_SET_STRING.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
// key the parameter key to set.
|
||||||
|
// value is the parameter value to set.
|
||||||
|
func FsconfigSetString(fd int, key string, value string) (err error) {
|
||||||
|
var valuep *byte
|
||||||
|
if valuep, err = BytePtrFromString(value); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigSetBinary is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_SET_BINARY.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
// key the parameter key to set.
|
||||||
|
// value is the parameter value to set.
|
||||||
|
func FsconfigSetBinary(fd int, key string, value []byte) (err error) {
|
||||||
|
if len(value) == 0 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigSetPath is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_SET_PATH.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
// key the parameter key to set.
|
||||||
|
// path is a non-empty path for specified key.
|
||||||
|
// atfd is a file descriptor at which to start lookup from or AT_FDCWD.
|
||||||
|
func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) {
|
||||||
|
var valuep *byte
|
||||||
|
if valuep, err = BytePtrFromString(path); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigSetPathEmpty is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_SET_PATH_EMPTY. The same as
|
||||||
|
// FconfigSetPath but with AT_PATH_EMPTY implied.
|
||||||
|
func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) {
|
||||||
|
var valuep *byte
|
||||||
|
if valuep, err = BytePtrFromString(path); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigSetFd is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_SET_FD.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
// key the parameter key to set.
|
||||||
|
// value is a file descriptor to be assigned to specified key.
|
||||||
|
func FsconfigSetFd(fd int, key string, value int) (err error) {
|
||||||
|
return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigCreate is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_CMD_CREATE.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
func FsconfigCreate(fd int) (err error) {
|
||||||
|
return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FsconfigReconfigure is equivalent to fsconfig(2) called
|
||||||
|
// with cmd == FSCONFIG_CMD_RECONFIGURE.
|
||||||
|
//
|
||||||
|
// fd is the filesystem context to act upon.
|
||||||
|
func FsconfigReconfigure(fd int) (err error) {
|
||||||
|
return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0)
|
||||||
|
}
|
||||||
|
|
||||||
//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
|
//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
|
||||||
//sysnb Getpgid(pid int) (pgid int, err error)
|
//sysnb Getpgid(pid int) (pgid int, err error)
|
||||||
|
|
||||||
|
|
|
||||||
9
vendor/golang.org/x/sys/unix/syscall_unix.go
generated
vendored
9
vendor/golang.org/x/sys/unix/syscall_unix.go
generated
vendored
|
|
@ -154,6 +154,15 @@ func Munmap(b []byte) (err error) {
|
||||||
return mapper.Munmap(b)
|
return mapper.Munmap(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) {
|
||||||
|
xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset)
|
||||||
|
return unsafe.Pointer(xaddr), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) {
|
||||||
|
return mapper.munmap(uintptr(addr), length)
|
||||||
|
}
|
||||||
|
|
||||||
func Read(fd int, p []byte) (n int, err error) {
|
func Read(fd int, p []byte) (n int, err error) {
|
||||||
n, err = read(fd, p)
|
n, err = read(fd, p)
|
||||||
if raceenabled {
|
if raceenabled {
|
||||||
|
|
|
||||||
1489
vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
generated
vendored
1489
vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
generated
vendored
File diff suppressed because it is too large
Load diff
2
vendor/golang.org/x/sys/unix/sysvshm_unix.go
generated
vendored
2
vendor/golang.org/x/sys/unix/sysvshm_unix.go
generated
vendored
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build (darwin && !ios) || linux
|
//go:build (darwin && !ios) || linux || zos
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
|
|
||||||
2
vendor/golang.org/x/sys/unix/sysvshm_unix_other.go
generated
vendored
2
vendor/golang.org/x/sys/unix/sysvshm_unix_other.go
generated
vendored
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build darwin && !ios
|
//go:build (darwin && !ios) || zos
|
||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
|
|
||||||
117
vendor/golang.org/x/sys/unix/zerrors_linux.go
generated
vendored
117
vendor/golang.org/x/sys/unix/zerrors_linux.go
generated
vendored
|
|
@ -491,6 +491,7 @@ const (
|
||||||
BPF_F_REPLACE = 0x4
|
BPF_F_REPLACE = 0x4
|
||||||
BPF_F_SLEEPABLE = 0x10
|
BPF_F_SLEEPABLE = 0x10
|
||||||
BPF_F_STRICT_ALIGNMENT = 0x1
|
BPF_F_STRICT_ALIGNMENT = 0x1
|
||||||
|
BPF_F_TEST_REG_INVARIANTS = 0x80
|
||||||
BPF_F_TEST_RND_HI32 = 0x4
|
BPF_F_TEST_RND_HI32 = 0x4
|
||||||
BPF_F_TEST_RUN_ON_CPU = 0x1
|
BPF_F_TEST_RUN_ON_CPU = 0x1
|
||||||
BPF_F_TEST_STATE_FREQ = 0x8
|
BPF_F_TEST_STATE_FREQ = 0x8
|
||||||
|
|
@ -501,6 +502,7 @@ const (
|
||||||
BPF_IMM = 0x0
|
BPF_IMM = 0x0
|
||||||
BPF_IND = 0x40
|
BPF_IND = 0x40
|
||||||
BPF_JA = 0x0
|
BPF_JA = 0x0
|
||||||
|
BPF_JCOND = 0xe0
|
||||||
BPF_JEQ = 0x10
|
BPF_JEQ = 0x10
|
||||||
BPF_JGE = 0x30
|
BPF_JGE = 0x30
|
||||||
BPF_JGT = 0x20
|
BPF_JGT = 0x20
|
||||||
|
|
@ -656,6 +658,9 @@ const (
|
||||||
CAN_NPROTO = 0x8
|
CAN_NPROTO = 0x8
|
||||||
CAN_RAW = 0x1
|
CAN_RAW = 0x1
|
||||||
CAN_RAW_FILTER_MAX = 0x200
|
CAN_RAW_FILTER_MAX = 0x200
|
||||||
|
CAN_RAW_XL_VCID_RX_FILTER = 0x4
|
||||||
|
CAN_RAW_XL_VCID_TX_PASS = 0x2
|
||||||
|
CAN_RAW_XL_VCID_TX_SET = 0x1
|
||||||
CAN_RTR_FLAG = 0x40000000
|
CAN_RTR_FLAG = 0x40000000
|
||||||
CAN_SFF_ID_BITS = 0xb
|
CAN_SFF_ID_BITS = 0xb
|
||||||
CAN_SFF_MASK = 0x7ff
|
CAN_SFF_MASK = 0x7ff
|
||||||
|
|
@ -1338,6 +1343,7 @@ const (
|
||||||
F_OFD_SETLK = 0x25
|
F_OFD_SETLK = 0x25
|
||||||
F_OFD_SETLKW = 0x26
|
F_OFD_SETLKW = 0x26
|
||||||
F_OK = 0x0
|
F_OK = 0x0
|
||||||
|
F_SEAL_EXEC = 0x20
|
||||||
F_SEAL_FUTURE_WRITE = 0x10
|
F_SEAL_FUTURE_WRITE = 0x10
|
||||||
F_SEAL_GROW = 0x4
|
F_SEAL_GROW = 0x4
|
||||||
F_SEAL_SEAL = 0x1
|
F_SEAL_SEAL = 0x1
|
||||||
|
|
@ -1626,6 +1632,7 @@ const (
|
||||||
IP_FREEBIND = 0xf
|
IP_FREEBIND = 0xf
|
||||||
IP_HDRINCL = 0x3
|
IP_HDRINCL = 0x3
|
||||||
IP_IPSEC_POLICY = 0x10
|
IP_IPSEC_POLICY = 0x10
|
||||||
|
IP_LOCAL_PORT_RANGE = 0x33
|
||||||
IP_MAXPACKET = 0xffff
|
IP_MAXPACKET = 0xffff
|
||||||
IP_MAX_MEMBERSHIPS = 0x14
|
IP_MAX_MEMBERSHIPS = 0x14
|
||||||
IP_MF = 0x2000
|
IP_MF = 0x2000
|
||||||
|
|
@ -1652,6 +1659,7 @@ const (
|
||||||
IP_PMTUDISC_OMIT = 0x5
|
IP_PMTUDISC_OMIT = 0x5
|
||||||
IP_PMTUDISC_PROBE = 0x3
|
IP_PMTUDISC_PROBE = 0x3
|
||||||
IP_PMTUDISC_WANT = 0x1
|
IP_PMTUDISC_WANT = 0x1
|
||||||
|
IP_PROTOCOL = 0x34
|
||||||
IP_RECVERR = 0xb
|
IP_RECVERR = 0xb
|
||||||
IP_RECVERR_RFC4884 = 0x1a
|
IP_RECVERR_RFC4884 = 0x1a
|
||||||
IP_RECVFRAGSIZE = 0x19
|
IP_RECVFRAGSIZE = 0x19
|
||||||
|
|
@ -1697,6 +1705,7 @@ const (
|
||||||
KEXEC_ARCH_S390 = 0x160000
|
KEXEC_ARCH_S390 = 0x160000
|
||||||
KEXEC_ARCH_SH = 0x2a0000
|
KEXEC_ARCH_SH = 0x2a0000
|
||||||
KEXEC_ARCH_X86_64 = 0x3e0000
|
KEXEC_ARCH_X86_64 = 0x3e0000
|
||||||
|
KEXEC_FILE_DEBUG = 0x8
|
||||||
KEXEC_FILE_NO_INITRAMFS = 0x4
|
KEXEC_FILE_NO_INITRAMFS = 0x4
|
||||||
KEXEC_FILE_ON_CRASH = 0x2
|
KEXEC_FILE_ON_CRASH = 0x2
|
||||||
KEXEC_FILE_UNLOAD = 0x1
|
KEXEC_FILE_UNLOAD = 0x1
|
||||||
|
|
@ -1785,6 +1794,8 @@ const (
|
||||||
LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20
|
LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20
|
||||||
LANDLOCK_ACCESS_FS_TRUNCATE = 0x4000
|
LANDLOCK_ACCESS_FS_TRUNCATE = 0x4000
|
||||||
LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2
|
LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2
|
||||||
|
LANDLOCK_ACCESS_NET_BIND_TCP = 0x1
|
||||||
|
LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2
|
||||||
LANDLOCK_CREATE_RULESET_VERSION = 0x1
|
LANDLOCK_CREATE_RULESET_VERSION = 0x1
|
||||||
LINUX_REBOOT_CMD_CAD_OFF = 0x0
|
LINUX_REBOOT_CMD_CAD_OFF = 0x0
|
||||||
LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef
|
LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef
|
||||||
|
|
@ -1896,6 +1907,7 @@ const (
|
||||||
MNT_DETACH = 0x2
|
MNT_DETACH = 0x2
|
||||||
MNT_EXPIRE = 0x4
|
MNT_EXPIRE = 0x4
|
||||||
MNT_FORCE = 0x1
|
MNT_FORCE = 0x1
|
||||||
|
MNT_ID_REQ_SIZE_VER0 = 0x18
|
||||||
MODULE_INIT_COMPRESSED_FILE = 0x4
|
MODULE_INIT_COMPRESSED_FILE = 0x4
|
||||||
MODULE_INIT_IGNORE_MODVERSIONS = 0x1
|
MODULE_INIT_IGNORE_MODVERSIONS = 0x1
|
||||||
MODULE_INIT_IGNORE_VERMAGIC = 0x2
|
MODULE_INIT_IGNORE_VERMAGIC = 0x2
|
||||||
|
|
@ -2127,6 +2139,60 @@ 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_CHAIN_FLAGS = 0x7
|
||||||
|
NFT_CHAIN_MAXNAMELEN = 0x100
|
||||||
|
NFT_CT_MAX = 0x17
|
||||||
|
NFT_DATA_RESERVED_MASK = 0xffffff00
|
||||||
|
NFT_DATA_VALUE_MAXLEN = 0x40
|
||||||
|
NFT_EXTHDR_OP_MAX = 0x4
|
||||||
|
NFT_FIB_RESULT_MAX = 0x3
|
||||||
|
NFT_INNER_MASK = 0xf
|
||||||
|
NFT_LOGLEVEL_MAX = 0x8
|
||||||
|
NFT_NAME_MAXLEN = 0x100
|
||||||
|
NFT_NG_MAX = 0x1
|
||||||
|
NFT_OBJECT_CONNLIMIT = 0x5
|
||||||
|
NFT_OBJECT_COUNTER = 0x1
|
||||||
|
NFT_OBJECT_CT_EXPECT = 0x9
|
||||||
|
NFT_OBJECT_CT_HELPER = 0x3
|
||||||
|
NFT_OBJECT_CT_TIMEOUT = 0x7
|
||||||
|
NFT_OBJECT_LIMIT = 0x4
|
||||||
|
NFT_OBJECT_MAX = 0xa
|
||||||
|
NFT_OBJECT_QUOTA = 0x2
|
||||||
|
NFT_OBJECT_SECMARK = 0x8
|
||||||
|
NFT_OBJECT_SYNPROXY = 0xa
|
||||||
|
NFT_OBJECT_TUNNEL = 0x6
|
||||||
|
NFT_OBJECT_UNSPEC = 0x0
|
||||||
|
NFT_OBJ_MAXNAMELEN = 0x100
|
||||||
|
NFT_OSF_MAXGENRELEN = 0x10
|
||||||
|
NFT_QUEUE_FLAG_BYPASS = 0x1
|
||||||
|
NFT_QUEUE_FLAG_CPU_FANOUT = 0x2
|
||||||
|
NFT_QUEUE_FLAG_MASK = 0x3
|
||||||
|
NFT_REG32_COUNT = 0x10
|
||||||
|
NFT_REG32_SIZE = 0x4
|
||||||
|
NFT_REG_MAX = 0x4
|
||||||
|
NFT_REG_SIZE = 0x10
|
||||||
|
NFT_REJECT_ICMPX_MAX = 0x3
|
||||||
|
NFT_RT_MAX = 0x4
|
||||||
|
NFT_SECMARK_CTX_MAXLEN = 0x100
|
||||||
|
NFT_SET_MAXNAMELEN = 0x100
|
||||||
|
NFT_SOCKET_MAX = 0x3
|
||||||
|
NFT_TABLE_F_MASK = 0x7
|
||||||
|
NFT_TABLE_MAXNAMELEN = 0x100
|
||||||
|
NFT_TRACETYPE_MAX = 0x3
|
||||||
|
NFT_TUNNEL_F_MASK = 0x7
|
||||||
|
NFT_TUNNEL_MAX = 0x1
|
||||||
|
NFT_TUNNEL_MODE_MAX = 0x2
|
||||||
|
NFT_USERDATA_MAXLEN = 0x100
|
||||||
|
NFT_XFRM_KEY_MAX = 0x6
|
||||||
|
NF_NAT_RANGE_MAP_IPS = 0x1
|
||||||
|
NF_NAT_RANGE_MASK = 0x7f
|
||||||
|
NF_NAT_RANGE_NETMAP = 0x40
|
||||||
|
NF_NAT_RANGE_PERSISTENT = 0x8
|
||||||
|
NF_NAT_RANGE_PROTO_OFFSET = 0x20
|
||||||
|
NF_NAT_RANGE_PROTO_RANDOM = 0x4
|
||||||
|
NF_NAT_RANGE_PROTO_RANDOM_ALL = 0x14
|
||||||
|
NF_NAT_RANGE_PROTO_RANDOM_FULLY = 0x10
|
||||||
|
NF_NAT_RANGE_PROTO_SPECIFIED = 0x2
|
||||||
NILFS_SUPER_MAGIC = 0x3434
|
NILFS_SUPER_MAGIC = 0x3434
|
||||||
NL0 = 0x0
|
NL0 = 0x0
|
||||||
NL1 = 0x100
|
NL1 = 0x100
|
||||||
|
|
@ -2246,6 +2312,7 @@ const (
|
||||||
PERF_AUX_FLAG_PARTIAL = 0x4
|
PERF_AUX_FLAG_PARTIAL = 0x4
|
||||||
PERF_AUX_FLAG_PMU_FORMAT_TYPE_MASK = 0xff00
|
PERF_AUX_FLAG_PMU_FORMAT_TYPE_MASK = 0xff00
|
||||||
PERF_AUX_FLAG_TRUNCATED = 0x1
|
PERF_AUX_FLAG_TRUNCATED = 0x1
|
||||||
|
PERF_BRANCH_ENTRY_INFO_BITS_MAX = 0x21
|
||||||
PERF_BR_ARM64_DEBUG_DATA = 0x7
|
PERF_BR_ARM64_DEBUG_DATA = 0x7
|
||||||
PERF_BR_ARM64_DEBUG_EXIT = 0x5
|
PERF_BR_ARM64_DEBUG_EXIT = 0x5
|
||||||
PERF_BR_ARM64_DEBUG_HALT = 0x4
|
PERF_BR_ARM64_DEBUG_HALT = 0x4
|
||||||
|
|
@ -2343,6 +2410,7 @@ const (
|
||||||
PERF_RECORD_MISC_USER = 0x2
|
PERF_RECORD_MISC_USER = 0x2
|
||||||
PERF_SAMPLE_BRANCH_PLM_ALL = 0x7
|
PERF_SAMPLE_BRANCH_PLM_ALL = 0x7
|
||||||
PERF_SAMPLE_WEIGHT_TYPE = 0x1004000
|
PERF_SAMPLE_WEIGHT_TYPE = 0x1004000
|
||||||
|
PID_FS_MAGIC = 0x50494446
|
||||||
PIPEFS_MAGIC = 0x50495045
|
PIPEFS_MAGIC = 0x50495045
|
||||||
PPPIOCGNPMODE = 0xc008744c
|
PPPIOCGNPMODE = 0xc008744c
|
||||||
PPPIOCNEWUNIT = 0xc004743e
|
PPPIOCNEWUNIT = 0xc004743e
|
||||||
|
|
@ -2411,6 +2479,7 @@ const (
|
||||||
PR_MCE_KILL_GET = 0x22
|
PR_MCE_KILL_GET = 0x22
|
||||||
PR_MCE_KILL_LATE = 0x0
|
PR_MCE_KILL_LATE = 0x0
|
||||||
PR_MCE_KILL_SET = 0x1
|
PR_MCE_KILL_SET = 0x1
|
||||||
|
PR_MDWE_NO_INHERIT = 0x2
|
||||||
PR_MDWE_REFUSE_EXEC_GAIN = 0x1
|
PR_MDWE_REFUSE_EXEC_GAIN = 0x1
|
||||||
PR_MPX_DISABLE_MANAGEMENT = 0x2c
|
PR_MPX_DISABLE_MANAGEMENT = 0x2c
|
||||||
PR_MPX_ENABLE_MANAGEMENT = 0x2b
|
PR_MPX_ENABLE_MANAGEMENT = 0x2b
|
||||||
|
|
@ -2615,8 +2684,9 @@ const (
|
||||||
RTAX_FEATURES = 0xc
|
RTAX_FEATURES = 0xc
|
||||||
RTAX_FEATURE_ALLFRAG = 0x8
|
RTAX_FEATURE_ALLFRAG = 0x8
|
||||||
RTAX_FEATURE_ECN = 0x1
|
RTAX_FEATURE_ECN = 0x1
|
||||||
RTAX_FEATURE_MASK = 0xf
|
RTAX_FEATURE_MASK = 0x1f
|
||||||
RTAX_FEATURE_SACK = 0x2
|
RTAX_FEATURE_SACK = 0x2
|
||||||
|
RTAX_FEATURE_TCP_USEC_TS = 0x10
|
||||||
RTAX_FEATURE_TIMESTAMP = 0x4
|
RTAX_FEATURE_TIMESTAMP = 0x4
|
||||||
RTAX_HOPLIMIT = 0xa
|
RTAX_HOPLIMIT = 0xa
|
||||||
RTAX_INITCWND = 0xb
|
RTAX_INITCWND = 0xb
|
||||||
|
|
@ -2834,8 +2904,9 @@ const (
|
||||||
RWF_APPEND = 0x10
|
RWF_APPEND = 0x10
|
||||||
RWF_DSYNC = 0x2
|
RWF_DSYNC = 0x2
|
||||||
RWF_HIPRI = 0x1
|
RWF_HIPRI = 0x1
|
||||||
|
RWF_NOAPPEND = 0x20
|
||||||
RWF_NOWAIT = 0x8
|
RWF_NOWAIT = 0x8
|
||||||
RWF_SUPPORTED = 0x1f
|
RWF_SUPPORTED = 0x3f
|
||||||
RWF_SYNC = 0x4
|
RWF_SYNC = 0x4
|
||||||
RWF_WRITE_LIFE_NOT_SET = 0x0
|
RWF_WRITE_LIFE_NOT_SET = 0x0
|
||||||
SCHED_BATCH = 0x3
|
SCHED_BATCH = 0x3
|
||||||
|
|
@ -2856,12 +2927,43 @@ const (
|
||||||
SCHED_RESET_ON_FORK = 0x40000000
|
SCHED_RESET_ON_FORK = 0x40000000
|
||||||
SCHED_RR = 0x2
|
SCHED_RR = 0x2
|
||||||
SCM_CREDENTIALS = 0x2
|
SCM_CREDENTIALS = 0x2
|
||||||
|
SCM_PIDFD = 0x4
|
||||||
SCM_RIGHTS = 0x1
|
SCM_RIGHTS = 0x1
|
||||||
|
SCM_SECURITY = 0x3
|
||||||
SCM_TIMESTAMP = 0x1d
|
SCM_TIMESTAMP = 0x1d
|
||||||
SC_LOG_FLUSH = 0x100000
|
SC_LOG_FLUSH = 0x100000
|
||||||
|
SECCOMP_ADDFD_FLAG_SEND = 0x2
|
||||||
|
SECCOMP_ADDFD_FLAG_SETFD = 0x1
|
||||||
|
SECCOMP_FILTER_FLAG_LOG = 0x2
|
||||||
|
SECCOMP_FILTER_FLAG_NEW_LISTENER = 0x8
|
||||||
|
SECCOMP_FILTER_FLAG_SPEC_ALLOW = 0x4
|
||||||
|
SECCOMP_FILTER_FLAG_TSYNC = 0x1
|
||||||
|
SECCOMP_FILTER_FLAG_TSYNC_ESRCH = 0x10
|
||||||
|
SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV = 0x20
|
||||||
|
SECCOMP_GET_ACTION_AVAIL = 0x2
|
||||||
|
SECCOMP_GET_NOTIF_SIZES = 0x3
|
||||||
|
SECCOMP_IOCTL_NOTIF_RECV = 0xc0502100
|
||||||
|
SECCOMP_IOCTL_NOTIF_SEND = 0xc0182101
|
||||||
|
SECCOMP_IOC_MAGIC = '!'
|
||||||
SECCOMP_MODE_DISABLED = 0x0
|
SECCOMP_MODE_DISABLED = 0x0
|
||||||
SECCOMP_MODE_FILTER = 0x2
|
SECCOMP_MODE_FILTER = 0x2
|
||||||
SECCOMP_MODE_STRICT = 0x1
|
SECCOMP_MODE_STRICT = 0x1
|
||||||
|
SECCOMP_RET_ACTION = 0x7fff0000
|
||||||
|
SECCOMP_RET_ACTION_FULL = 0xffff0000
|
||||||
|
SECCOMP_RET_ALLOW = 0x7fff0000
|
||||||
|
SECCOMP_RET_DATA = 0xffff
|
||||||
|
SECCOMP_RET_ERRNO = 0x50000
|
||||||
|
SECCOMP_RET_KILL = 0x0
|
||||||
|
SECCOMP_RET_KILL_PROCESS = 0x80000000
|
||||||
|
SECCOMP_RET_KILL_THREAD = 0x0
|
||||||
|
SECCOMP_RET_LOG = 0x7ffc0000
|
||||||
|
SECCOMP_RET_TRACE = 0x7ff00000
|
||||||
|
SECCOMP_RET_TRAP = 0x30000
|
||||||
|
SECCOMP_RET_USER_NOTIF = 0x7fc00000
|
||||||
|
SECCOMP_SET_MODE_FILTER = 0x1
|
||||||
|
SECCOMP_SET_MODE_STRICT = 0x0
|
||||||
|
SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP = 0x1
|
||||||
|
SECCOMP_USER_NOTIF_FLAG_CONTINUE = 0x1
|
||||||
SECRETMEM_MAGIC = 0x5345434d
|
SECRETMEM_MAGIC = 0x5345434d
|
||||||
SECURITYFS_MAGIC = 0x73636673
|
SECURITYFS_MAGIC = 0x73636673
|
||||||
SEEK_CUR = 0x1
|
SEEK_CUR = 0x1
|
||||||
|
|
@ -2960,6 +3062,8 @@ const (
|
||||||
SIOCSMIIREG = 0x8949
|
SIOCSMIIREG = 0x8949
|
||||||
SIOCSRARP = 0x8962
|
SIOCSRARP = 0x8962
|
||||||
SIOCWANDEV = 0x894a
|
SIOCWANDEV = 0x894a
|
||||||
|
SK_DIAG_BPF_STORAGE_MAX = 0x3
|
||||||
|
SK_DIAG_BPF_STORAGE_REQ_MAX = 0x1
|
||||||
SMACK_MAGIC = 0x43415d53
|
SMACK_MAGIC = 0x43415d53
|
||||||
SMART_AUTOSAVE = 0xd2
|
SMART_AUTOSAVE = 0xd2
|
||||||
SMART_AUTO_OFFLINE = 0xdb
|
SMART_AUTO_OFFLINE = 0xdb
|
||||||
|
|
@ -2980,6 +3084,8 @@ const (
|
||||||
SOCKFS_MAGIC = 0x534f434b
|
SOCKFS_MAGIC = 0x534f434b
|
||||||
SOCK_BUF_LOCK_MASK = 0x3
|
SOCK_BUF_LOCK_MASK = 0x3
|
||||||
SOCK_DCCP = 0x6
|
SOCK_DCCP = 0x6
|
||||||
|
SOCK_DESTROY = 0x15
|
||||||
|
SOCK_DIAG_BY_FAMILY = 0x14
|
||||||
SOCK_IOC_TYPE = 0x89
|
SOCK_IOC_TYPE = 0x89
|
||||||
SOCK_PACKET = 0xa
|
SOCK_PACKET = 0xa
|
||||||
SOCK_RAW = 0x3
|
SOCK_RAW = 0x3
|
||||||
|
|
@ -3021,6 +3127,7 @@ const (
|
||||||
SOL_TIPC = 0x10f
|
SOL_TIPC = 0x10f
|
||||||
SOL_TLS = 0x11a
|
SOL_TLS = 0x11a
|
||||||
SOL_UDP = 0x11
|
SOL_UDP = 0x11
|
||||||
|
SOL_VSOCK = 0x11f
|
||||||
SOL_X25 = 0x106
|
SOL_X25 = 0x106
|
||||||
SOL_XDP = 0x11b
|
SOL_XDP = 0x11b
|
||||||
SOMAXCONN = 0x1000
|
SOMAXCONN = 0x1000
|
||||||
|
|
@ -3080,6 +3187,7 @@ const (
|
||||||
STATX_GID = 0x10
|
STATX_GID = 0x10
|
||||||
STATX_INO = 0x100
|
STATX_INO = 0x100
|
||||||
STATX_MNT_ID = 0x1000
|
STATX_MNT_ID = 0x1000
|
||||||
|
STATX_MNT_ID_UNIQUE = 0x4000
|
||||||
STATX_MODE = 0x2
|
STATX_MODE = 0x2
|
||||||
STATX_MTIME = 0x40
|
STATX_MTIME = 0x40
|
||||||
STATX_NLINK = 0x4
|
STATX_NLINK = 0x4
|
||||||
|
|
@ -3167,6 +3275,7 @@ const (
|
||||||
TCP_MAX_WINSHIFT = 0xe
|
TCP_MAX_WINSHIFT = 0xe
|
||||||
TCP_MD5SIG = 0xe
|
TCP_MD5SIG = 0xe
|
||||||
TCP_MD5SIG_EXT = 0x20
|
TCP_MD5SIG_EXT = 0x20
|
||||||
|
TCP_MD5SIG_FLAG_IFINDEX = 0x2
|
||||||
TCP_MD5SIG_FLAG_PREFIX = 0x1
|
TCP_MD5SIG_FLAG_PREFIX = 0x1
|
||||||
TCP_MD5SIG_MAXKEYLEN = 0x50
|
TCP_MD5SIG_MAXKEYLEN = 0x50
|
||||||
TCP_MSS = 0x200
|
TCP_MSS = 0x200
|
||||||
|
|
@ -3474,12 +3583,16 @@ const (
|
||||||
XDP_RX_RING = 0x2
|
XDP_RX_RING = 0x2
|
||||||
XDP_SHARED_UMEM = 0x1
|
XDP_SHARED_UMEM = 0x1
|
||||||
XDP_STATISTICS = 0x7
|
XDP_STATISTICS = 0x7
|
||||||
|
XDP_TXMD_FLAGS_CHECKSUM = 0x2
|
||||||
|
XDP_TXMD_FLAGS_TIMESTAMP = 0x1
|
||||||
|
XDP_TX_METADATA = 0x2
|
||||||
XDP_TX_RING = 0x3
|
XDP_TX_RING = 0x3
|
||||||
XDP_UMEM_COMPLETION_RING = 0x6
|
XDP_UMEM_COMPLETION_RING = 0x6
|
||||||
XDP_UMEM_FILL_RING = 0x5
|
XDP_UMEM_FILL_RING = 0x5
|
||||||
XDP_UMEM_PGOFF_COMPLETION_RING = 0x180000000
|
XDP_UMEM_PGOFF_COMPLETION_RING = 0x180000000
|
||||||
XDP_UMEM_PGOFF_FILL_RING = 0x100000000
|
XDP_UMEM_PGOFF_FILL_RING = 0x100000000
|
||||||
XDP_UMEM_REG = 0x4
|
XDP_UMEM_REG = 0x4
|
||||||
|
XDP_UMEM_TX_SW_CSUM = 0x2
|
||||||
XDP_UMEM_UNALIGNED_CHUNK_FLAG = 0x1
|
XDP_UMEM_UNALIGNED_CHUNK_FLAG = 0x1
|
||||||
XDP_USE_NEED_WAKEUP = 0x8
|
XDP_USE_NEED_WAKEUP = 0x8
|
||||||
XDP_USE_SG = 0x10
|
XDP_USE_SG = 0x10
|
||||||
|
|
|
||||||
4
vendor/golang.org/x/sys/unix/zerrors_linux_386.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zerrors_linux_386.go
generated
vendored
|
|
@ -118,6 +118,7 @@ const (
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
IXON = 0x400
|
IXON = 0x400
|
||||||
MAP_32BIT = 0x40
|
MAP_32BIT = 0x40
|
||||||
|
MAP_ABOVE4G = 0x80
|
||||||
MAP_ANON = 0x20
|
MAP_ANON = 0x20
|
||||||
MAP_ANONYMOUS = 0x20
|
MAP_ANONYMOUS = 0x20
|
||||||
MAP_DENYWRITE = 0x800
|
MAP_DENYWRITE = 0x800
|
||||||
|
|
@ -281,6 +282,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
||||||
4
vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
generated
vendored
4
vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
generated
vendored
|
|
@ -118,6 +118,7 @@ const (
|
||||||
IXOFF = 0x1000
|
IXOFF = 0x1000
|
||||||
IXON = 0x400
|
IXON = 0x400
|
||||||
MAP_32BIT = 0x40
|
MAP_32BIT = 0x40
|
||||||
|
MAP_ABOVE4G = 0x80
|
||||||
MAP_ANON = 0x20
|
MAP_ANON = 0x20
|
||||||
MAP_ANONYMOUS = 0x20
|
MAP_ANONYMOUS = 0x20
|
||||||
MAP_DENYWRITE = 0x800
|
MAP_DENYWRITE = 0x800
|
||||||
|
|
@ -282,6 +283,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
||||||
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
|
|
@ -288,6 +288,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
||||||
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
|
|
@ -87,6 +87,7 @@ const (
|
||||||
FICLONE = 0x40049409
|
FICLONE = 0x40049409
|
||||||
FICLONERANGE = 0x4020940d
|
FICLONERANGE = 0x4020940d
|
||||||
FLUSHO = 0x1000
|
FLUSHO = 0x1000
|
||||||
|
FPMR_MAGIC = 0x46504d52
|
||||||
FPSIMD_MAGIC = 0x46508001
|
FPSIMD_MAGIC = 0x46508001
|
||||||
FS_IOC_ENABLE_VERITY = 0x40806685
|
FS_IOC_ENABLE_VERITY = 0x40806685
|
||||||
FS_IOC_GETFLAGS = 0x80086601
|
FS_IOC_GETFLAGS = 0x80086601
|
||||||
|
|
@ -278,6 +279,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
||||||
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
|
|
@ -275,6 +275,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
||||||
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
|
|
@ -281,6 +281,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x80
|
SFD_NONBLOCK = 0x80
|
||||||
SIOCATMARK = 0x40047307
|
SIOCATMARK = 0x40047307
|
||||||
|
|
|
||||||
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
|
|
@ -281,6 +281,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x80
|
SFD_NONBLOCK = 0x80
|
||||||
SIOCATMARK = 0x40047307
|
SIOCATMARK = 0x40047307
|
||||||
|
|
|
||||||
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
|
|
@ -281,6 +281,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x80
|
SFD_NONBLOCK = 0x80
|
||||||
SIOCATMARK = 0x40047307
|
SIOCATMARK = 0x40047307
|
||||||
|
|
|
||||||
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
|
|
@ -281,6 +281,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x80
|
SFD_NONBLOCK = 0x80
|
||||||
SIOCATMARK = 0x40047307
|
SIOCATMARK = 0x40047307
|
||||||
|
|
|
||||||
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
|
|
@ -336,6 +336,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
||||||
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
|
|
@ -340,6 +340,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
||||||
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
|
|
@ -340,6 +340,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue