Update vendor (whatsapp)

This commit is contained in:
Wim 2022-03-12 23:02:04 +01:00
parent 1b9877fda4
commit aefa70891c
206 changed files with 367071 additions and 164229 deletions

12
go.mod
View File

@ -45,7 +45,7 @@ require (
github.com/writeas/go-strip-markdown v2.0.1+incompatible github.com/writeas/go-strip-markdown v2.0.1+incompatible
github.com/yaegashi/msgraph.go v0.1.4 github.com/yaegashi/msgraph.go v0.1.4
github.com/zfjagann/golang-ring v0.0.0-20210116075443-7c86fdb43134 github.com/zfjagann/golang-ring v0.0.0-20210116075443-7c86fdb43134
go.mau.fi/whatsmeow v0.0.0-20220128124639-e64fb976bf15 go.mau.fi/whatsmeow v0.0.0-20220312175208-0c4681a6ff52
golang.org/x/image v0.0.0-20220302094943-723b81ca9867 golang.org/x/image v0.0.0-20220302094943-723b81ca9867
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a
golang.org/x/text v0.3.7 golang.org/x/text v0.3.7
@ -53,7 +53,7 @@ require (
google.golang.org/protobuf v1.27.1 google.golang.org/protobuf v1.27.1
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376
layeh.com/gumble v0.0.0-20200818122324-146f9205029b layeh.com/gumble v0.0.0-20200818122324-146f9205029b
modernc.org/sqlite v1.14.5 modernc.org/sqlite v1.14.8
) )
require ( require (
@ -124,11 +124,11 @@ require (
github.com/wiggin77/cfg v1.0.2 // indirect github.com/wiggin77/cfg v1.0.2 // indirect
github.com/wiggin77/merror v1.0.3 // indirect github.com/wiggin77/merror v1.0.3 // indirect
github.com/wiggin77/srslog v1.0.1 // indirect github.com/wiggin77/srslog v1.0.1 // indirect
go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910 // indirect go.mau.fi/libsignal v0.0.0-20220308120827-0d87a03fd7c7 // indirect
go.uber.org/atomic v1.9.0 // indirect go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.7.0 // indirect go.uber.org/multierr v1.7.0 // indirect
go.uber.org/zap v1.17.0 // indirect go.uber.org/zap v1.17.0 // indirect
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 // indirect golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70 // indirect
golang.org/x/mod v0.5.1 // indirect golang.org/x/mod v0.5.1 // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
@ -143,8 +143,8 @@ require (
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
lukechampine.com/uint128 v1.1.1 // indirect lukechampine.com/uint128 v1.1.1 // indirect
modernc.org/cc/v3 v3.35.22 // indirect modernc.org/cc/v3 v3.35.22 // indirect
modernc.org/ccgo/v3 v3.15.1 // indirect modernc.org/ccgo/v3 v3.15.14 // indirect
modernc.org/libc v1.14.1 // indirect modernc.org/libc v1.14.6 // indirect
modernc.org/mathutil v1.4.1 // indirect modernc.org/mathutil v1.4.1 // indirect
modernc.org/memory v1.0.5 // indirect modernc.org/memory v1.0.5 // indirect
modernc.org/opt v0.1.1 // indirect modernc.org/opt v0.1.1 // indirect

25
go.sum
View File

@ -10,7 +10,6 @@ github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo=
github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
github.com/Philipp15b/go-steam v1.0.1-0.20200727090957-6ae9b3c0a560 h1:ItnC9PEEMESzTbFayxrhKBbuFQOXDBI8yy7NudTcEWs= github.com/Philipp15b/go-steam v1.0.1-0.20200727090957-6ae9b3c0a560 h1:ItnC9PEEMESzTbFayxrhKBbuFQOXDBI8yy7NudTcEWs=
github.com/Philipp15b/go-steam v1.0.1-0.20200727090957-6ae9b3c0a560/go.mod h1:o38AwUFFS4gzbjSoyIgrZ1h9UeDrKwcci1Pj6baifvI= github.com/Philipp15b/go-steam v1.0.1-0.20200727090957-6ae9b3c0a560/go.mod h1:o38AwUFFS4gzbjSoyIgrZ1h9UeDrKwcci1Pj6baifvI=
github.com/Rhymen/go-whatsapp v0.1.2-0.20211102134409-31a2e740845c/go.mod h1:DNSFRLFDFIqm2+0aJzSOVfn25020vldM4SRqz6YtLgI=
github.com/SevereCloud/vksdk/v2 v2.13.1 h1:D11NaP275mW01v2hRF0ycDHdJaIyZEvasZV4MSkg5Sk= github.com/SevereCloud/vksdk/v2 v2.13.1 h1:D11NaP275mW01v2hRF0ycDHdJaIyZEvasZV4MSkg5Sk=
github.com/SevereCloud/vksdk/v2 v2.13.1/go.mod h1:UyOgSj/CYt2dByu3Fyf/y1yT1NoahVi4zECvvrbtPU4= github.com/SevereCloud/vksdk/v2 v2.13.1/go.mod h1:UyOgSj/CYt2dByu3Fyf/y1yT1NoahVi4zECvvrbtPU4=
github.com/apex/log v1.9.0 h1:FHtw/xuaM8AgmvDDTI9fiwoAL25Sq2cxojnZICUU8l0= github.com/apex/log v1.9.0 h1:FHtw/xuaM8AgmvDDTI9fiwoAL25Sq2cxojnZICUU8l0=
@ -227,18 +226,18 @@ github.com/yaegashi/msgraph.go v0.1.4 h1:leDXSczAbwBpYFSmmZrdByTiPoUw8dbTfNMetAj
github.com/yaegashi/msgraph.go v0.1.4/go.mod h1:vgeYhHa5skJt/3lTyjGXThTZhwbhRnGo6uUxzoJIGME= github.com/yaegashi/msgraph.go v0.1.4/go.mod h1:vgeYhHa5skJt/3lTyjGXThTZhwbhRnGo6uUxzoJIGME=
github.com/zfjagann/golang-ring v0.0.0-20210116075443-7c86fdb43134 h1:itYC8Ycx8aVBN7a8q1Yr187W5WmQthvYU13+f4rOWkU= github.com/zfjagann/golang-ring v0.0.0-20210116075443-7c86fdb43134 h1:itYC8Ycx8aVBN7a8q1Yr187W5WmQthvYU13+f4rOWkU=
github.com/zfjagann/golang-ring v0.0.0-20210116075443-7c86fdb43134/go.mod h1:0MsIttMJIF/8Y7x0XjonJP7K99t3sR6bjj4m5S4JmqU= github.com/zfjagann/golang-ring v0.0.0-20210116075443-7c86fdb43134/go.mod h1:0MsIttMJIF/8Y7x0XjonJP7K99t3sR6bjj4m5S4JmqU=
go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910 h1:9FFhG0OmkuMau5UEaTgiUQ+7cSbtbOQ7hiWKdN8OI3I= go.mau.fi/libsignal v0.0.0-20220308120827-0d87a03fd7c7 h1:L09XYQRGJwC6KbJumz3cD/6JTUAPNZHfnu8hroqm1KE=
go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910/go.mod h1:AufGrvVh+00Nc07Jm4hTquh7yleZyn20tKJI2wCPAKg= go.mau.fi/libsignal v0.0.0-20220308120827-0d87a03fd7c7/go.mod h1:LjEYzdnRUcRArJJUUHQUfMU1A+WzEM73qBTirXluuaY=
go.mau.fi/whatsmeow v0.0.0-20220128124639-e64fb976bf15 h1:BmdZu7K6IHsb+sPxvzkEjAINKxTMNeSiJRe1cvfesIY= go.mau.fi/whatsmeow v0.0.0-20220312175208-0c4681a6ff52 h1:CVJ4dVzluwsUFI8zBLQBlrtYHuMcEYM6oLeAbplCrI4=
go.mau.fi/whatsmeow v0.0.0-20220128124639-e64fb976bf15/go.mod h1:8jUjOAi3xtGubxcZgG8uSHpAdyQXBRbWAfxkctX/4y4= go.mau.fi/whatsmeow v0.0.0-20220312175208-0c4681a6ff52/go.mod h1:nH4IwHZf+Ks61nM5p71jZqLXiT0NpG+0uR/WqzCqHH8=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI= golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70 h1:syTAU9FwmvzEoIYMqcPHOcVm4H3U5u90WsvuYgwpETU=
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/image v0.0.0-20220302094943-723b81ca9867 h1:TcHcE0vrmgzNH1v3ppjcMGbhG5+9fMuvOmUYwNEF4q4= golang.org/x/image v0.0.0-20220302094943-723b81ca9867 h1:TcHcE0vrmgzNH1v3ppjcMGbhG5+9fMuvOmUYwNEF4q4=
golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
@ -281,18 +280,18 @@ lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
modernc.org/cc/v3 v3.35.22 h1:BzShpwCAP7TWzFppM4k2t03RhXhgYqaibROWkrWq7lE= modernc.org/cc/v3 v3.35.22 h1:BzShpwCAP7TWzFppM4k2t03RhXhgYqaibROWkrWq7lE=
modernc.org/cc/v3 v3.35.22/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= modernc.org/cc/v3 v3.35.22/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/ccgo/v3 v3.15.1 h1:bagyhO7uFlYWedkh6mfIYf8LZGYnVGPYh2FqXisaOV4= modernc.org/ccgo/v3 v3.15.14 h1:/Pcjoc5mPznDMH3CErDeX4mHLAAQyR5lzr3s2FpqDY0=
modernc.org/ccgo/v3 v3.15.1/go.mod h1:md59wBwDT2LznX/OTCPoVS6KIsdRgY8xqQwBV+hkTH0= modernc.org/ccgo/v3 v3.15.14/go.mod h1:144Sz2iBCKogb9OKwsu7hQEub3EVgOlyI8wMUPGKUXQ=
modernc.org/libc v1.14.1 h1:rwx9uVJU/fEmsmV5ECGRwdAiXgUm6k6tsFA+L8kQb6E= modernc.org/libc v1.14.6 h1:SSiZiE5199iYsGM9gtkDj90xqcXVwubWG8CtoYE+Mnk=
modernc.org/libc v1.14.1/go.mod h1:npFeGWjmZTjFeWALQLrvklVmAxv4m80jnG3+xI8FdJk= modernc.org/libc v1.14.6/go.mod h1:2PJHINagVxO4QW/5OQdRrvMYo+bm5ClpUFfyXCYl9ak=
modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8= modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/memory v1.0.5 h1:XRch8trV7GgvTec2i7jc33YlUI0RKVDBvZ5eZ5m8y14= modernc.org/memory v1.0.5 h1:XRch8trV7GgvTec2i7jc33YlUI0RKVDBvZ5eZ5m8y14=
modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM= modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM=
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A= modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sqlite v1.14.5 h1:bYrrjwH9Y7QUGk1MbchZDhRfmpGuEAs/D45sVjNbfvs= modernc.org/sqlite v1.14.8 h1:2OOqfZAyU4x4qusilvHoRXXqsAgaZobi1o+mjQ5MUpw=
modernc.org/sqlite v1.14.5/go.mod h1:YyX5Rx0WbXokitdWl2GJIDy4BrPxBP0PwwhpXOHCDLE= modernc.org/sqlite v1.14.8/go.mod h1:TFmXjym+/jR31fxc2B5eHnKMuJJGY7i1L/T5A0jzVww=
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs= modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=

View File

@ -1,21 +1,13 @@
# whatsmeow # whatsmeow
[![godocs.io](https://godocs.io/go.mau.fi/whatsmeow?status.svg)](https://godocs.io/go.mau.fi/whatsmeow) [![Go Reference](https://pkg.go.dev/badge/go.mau.fi/whatsmeow.svg)](https://pkg.go.dev/go.mau.fi/whatsmeow)
whatsmeow is a Go library for the WhatsApp web multidevice API. whatsmeow is a Go library for the WhatsApp web multidevice API.
This was initially forked from [go-whatsapp] (MIT license), but large parts of
the code have been rewritten for multidevice support. Parts of the code are
ported from [WhatsappWeb4j] and [Baileys] (also MIT license).
[go-whatsapp]: https://github.com/Rhymen/go-whatsapp
[WhatsappWeb4j]: https://github.com/Auties00/WhatsappWeb4j
[Baileys]: https://github.com/adiwajshing/Baileys
## Discussion ## Discussion
Matrix room: [#whatsmeow:maunium.net](https://matrix.to/#/#whatsmeow:maunium.net) Matrix room: [#whatsmeow:maunium.net](https://matrix.to/#/#whatsmeow:maunium.net)
## Usage ## Usage
The [godoc](https://godocs.io/go.mau.fi/whatsmeow) includes docs for all methods and event types. The [godoc](https://pkg.go.dev/go.mau.fi/whatsmeow) includes docs for all methods and event types.
There's also a [simple example](https://godocs.io/go.mau.fi/whatsmeow#example-package) at the top. There's also a [simple example](https://godocs.io/go.mau.fi/whatsmeow#example-package) at the top.
Also see [mdtest](./mdtest) for a CLI tool you can easily try out whatsmeow with. Also see [mdtest](./mdtest) for a CLI tool you can easily try out whatsmeow with.

View File

@ -1,4 +1,4 @@
// Copyright (c) 2021 Tulir Asokan // Copyright (c) 2022 Tulir Asokan
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this // License, v. 2.0. If a copy of the MPL was not distributed with this
@ -13,6 +13,7 @@ import (
"go.mau.fi/whatsmeow/appstate" "go.mau.fi/whatsmeow/appstate"
waBinary "go.mau.fi/whatsmeow/binary" waBinary "go.mau.fi/whatsmeow/binary"
waProto "go.mau.fi/whatsmeow/binary/proto" waProto "go.mau.fi/whatsmeow/binary/proto"
"go.mau.fi/whatsmeow/store"
"go.mau.fi/whatsmeow/types" "go.mau.fi/whatsmeow/types"
"go.mau.fi/whatsmeow/types/events" "go.mau.fi/whatsmeow/types/events"
) )
@ -54,7 +55,18 @@ func (cli *Client) FetchAppState(name appstate.WAPatchName, fullSync, onlyIfNotS
if err != nil { if err != nil {
return fmt.Errorf("failed to decode app state %s patches: %w", name, err) return fmt.Errorf("failed to decode app state %s patches: %w", name, err)
} }
wasFullSync := state.Version == 0 && patches.Snapshot != nil
state = newState state = newState
if name == appstate.WAPatchCriticalUnblockLow && wasFullSync && !cli.EmitAppStateEventsOnFullSync {
var contacts []store.ContactEntry
mutations, contacts = cli.filterContacts(mutations)
cli.Log.Debugf("Mass inserting app state snapshot with %d contacts into the store", len(contacts))
err = cli.Store.Contacts.PutAllContactNames(contacts)
if err != nil {
// This is a fairly serious failure, so just abort the whole thing
return fmt.Errorf("failed to update contact store with data from snapshot: %v", err)
}
}
for _, mutation := range mutations { for _, mutation := range mutations {
cli.dispatchAppState(mutation, !fullSync || cli.EmitAppStateEventsOnFullSync) cli.dispatchAppState(mutation, !fullSync || cli.EmitAppStateEventsOnFullSync)
} }
@ -68,6 +80,25 @@ func (cli *Client) FetchAppState(name appstate.WAPatchName, fullSync, onlyIfNotS
return nil return nil
} }
func (cli *Client) filterContacts(mutations []appstate.Mutation) ([]appstate.Mutation, []store.ContactEntry) {
filteredMutations := mutations[:0]
contacts := make([]store.ContactEntry, 0, len(mutations))
for _, mutation := range mutations {
if mutation.Index[0] == "contact" && len(mutation.Index) > 1 {
jid, _ := types.ParseJID(mutation.Index[1])
act := mutation.Action.GetContactAction()
contacts = append(contacts, store.ContactEntry{
JID: jid,
FirstName: act.GetFirstName(),
FullName: act.GetFullName(),
})
} else {
filteredMutations = append(filteredMutations, mutation)
}
}
return filteredMutations, contacts
}
func (cli *Client) dispatchAppState(mutation appstate.Mutation, dispatchEvts bool) { func (cli *Client) dispatchAppState(mutation appstate.Mutation, dispatchEvts bool) {
if mutation.Operation != waProto.SyncdMutation_SET { if mutation.Operation != waProto.SyncdMutation_SET {
return return
@ -144,6 +175,12 @@ func (cli *Client) dispatchAppState(mutation appstate.Mutation, dispatchEvts boo
evt.SenderJID, _ = types.ParseJID(mutation.Index[4]) evt.SenderJID, _ = types.ParseJID(mutation.Index[4])
} }
eventToDispatch = &evt eventToDispatch = &evt
case "markChatAsRead":
eventToDispatch = &events.MarkChatAsRead{
JID: jid,
Timestamp: ts,
Action: mutation.Action.GetMarkChatAsReadAction(),
}
case "setting_pushName": case "setting_pushName":
eventToDispatch = &events.PushNameSetting{Timestamp: ts, Action: mutation.Action.GetPushNameSetting()} eventToDispatch = &events.PushNameSetting{Timestamp: ts, Action: mutation.Action.GetPushNameSetting()}
cli.Store.PushName = mutation.Action.GetPushNameSetting().GetName() cli.Store.PushName = mutation.Action.GetPushNameSetting().GetName()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,10 @@ var (
} }
) )
// DictVersion is the version number of the token lists above.
// It's sent when connecting to the websocket so the server knows which tokens are supported.
const DictVersion = 2
type doubleByteTokenIndex struct { type doubleByteTokenIndex struct {
dictionary byte dictionary byte
index byte index byte

View File

@ -13,6 +13,8 @@ import (
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt" "fmt"
"net/http"
"net/url"
"runtime/debug" "runtime/debug"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -56,6 +58,8 @@ type Client struct {
LastSuccessfulConnect time.Time LastSuccessfulConnect time.Time
AutoReconnectErrors int AutoReconnectErrors int
sendActiveReceipts uint32
// EmitAppStateEventsOnFullSync can be set to true if you want to get app state events emitted // EmitAppStateEventsOnFullSync can be set to true if you want to get app state events emitted
// even when re-syncing the whole state. // even when re-syncing the whole state.
EmitAppStateEventsOnFullSync bool EmitAppStateEventsOnFullSync bool
@ -100,6 +104,9 @@ type Client struct {
uniqueID string uniqueID string
idCounter uint32 idCounter uint32
proxy socket.Proxy
http *http.Client
} }
// Size of buffer for the channel that all incoming XML nodes go through. // Size of buffer for the channel that all incoming XML nodes go through.
@ -128,6 +135,10 @@ func NewClient(deviceStore *store.Device, log waLog.Logger) *Client {
randomBytes := make([]byte, 2) randomBytes := make([]byte, 2)
_, _ = rand.Read(randomBytes) _, _ = rand.Read(randomBytes)
cli := &Client{ cli := &Client{
http: &http.Client{
Transport: (http.DefaultTransport.(*http.Transport)).Clone(),
},
proxy: http.ProxyFromEnvironment,
Store: deviceStore, Store: deviceStore,
Log: log, Log: log,
recvLog: log.Sub("Recv"), recvLog: log.Sub("Recv"),
@ -159,10 +170,46 @@ func NewClient(deviceStore *store.Device, log waLog.Logger) *Client {
"stream:error": cli.handleStreamError, "stream:error": cli.handleStreamError,
"iq": cli.handleIQ, "iq": cli.handleIQ,
"ib": cli.handleIB, "ib": cli.handleIB,
// Apparently there's also an <error> node which can have a code=479 and means "Invalid stanza sent (smax-invalid)"
} }
return cli return cli
} }
// SetProxyAddress is a helper method that parses a URL string and calls SetProxy.
//
// Returns an error if url.Parse fails to parse the given address.
func (cli *Client) SetProxyAddress(addr string) error {
parsed, err := url.Parse(addr)
if err != nil {
return err
}
cli.SetProxy(http.ProxyURL(parsed))
return nil
}
// SetProxy sets the proxy to use for WhatsApp web websocket connections and media uploads/downloads.
//
// Must be called before Connect() to take effect in the websocket connection.
// If you want to change the proxy after connecting, you must call Disconnect() and then Connect() again manually.
//
// By default, the client will find the proxy from the https_proxy environment variable like Go's net/http does.
//
// To disable reading proxy info from environment variables, explicitly set the proxy to nil:
// cli.SetProxy(nil)
//
// To use a different proxy for the websocket and media, pass a function that checks the request path or headers:
// cli.SetProxy(func(r *http.Request) (*url.URL, error) {
// if r.URL.Host == "web.whatsapp.com" && r.URL.Path == "/ws/chat" {
// return websocketProxyURL, nil
// } else {
// return mediaProxyURL, nil
// }
// })
func (cli *Client) SetProxy(proxy socket.Proxy) {
cli.proxy = proxy
cli.http.Transport.(*http.Transport).Proxy = proxy
}
// Connect connects the client to the WhatsApp web websocket. After connection, it will either // Connect connects the client to the WhatsApp web websocket. After connection, it will either
// authenticate if there's data in the device store, or emit a QREvent to set up a new link. // authenticate if there's data in the device store, or emit a QREvent to set up a new link.
func (cli *Client) Connect() error { func (cli *Client) Connect() error {
@ -177,7 +224,7 @@ func (cli *Client) Connect() error {
} }
cli.resetExpectedDisconnect() cli.resetExpectedDisconnect()
fs := socket.NewFrameSocket(cli.Log.Sub("Socket"), socket.WAConnHeader) fs := socket.NewFrameSocket(cli.Log.Sub("Socket"), socket.WAConnHeader, cli.proxy)
if err := fs.Connect(); err != nil { if err := fs.Connect(); err != nil {
fs.Close(0) fs.Close(0)
return err return err

View File

@ -33,7 +33,7 @@ func (cli *Client) handleStreamError(node *waBinary.Node) {
case code == "401" && conflictType == "device_removed": case code == "401" && conflictType == "device_removed":
cli.expectDisconnect() cli.expectDisconnect()
cli.Log.Infof("Got device removed stream error, sending LoggedOut event and deleting session") cli.Log.Infof("Got device removed stream error, sending LoggedOut event and deleting session")
go cli.dispatchEvent(&events.LoggedOut{OnConnect: false}) go cli.dispatchEvent(&events.LoggedOut{OnConnect: false, Reason: events.ConnectFailureLoggedOut})
err := cli.Store.Delete() err := cli.Store.Delete()
if err != nil { if err != nil {
cli.Log.Warnf("Failed to delete store after device_removed error: %v", err) cli.Log.Warnf("Failed to delete store after device_removed error: %v", err)
@ -77,17 +77,30 @@ func (cli *Client) handleIB(node *waBinary.Node) {
func (cli *Client) handleConnectFailure(node *waBinary.Node) { func (cli *Client) handleConnectFailure(node *waBinary.Node) {
ag := node.AttrGetter() ag := node.AttrGetter()
reason := ag.String("reason") reason := events.ConnectFailureReason(ag.Int("reason"))
if reason == "401" {
cli.expectDisconnect() cli.expectDisconnect()
cli.Log.Infof("Got 401 connect failure, sending LoggedOut event and deleting session") if reason.IsLoggedOut() {
go cli.dispatchEvent(&events.LoggedOut{OnConnect: true}) cli.Log.Infof("Got %s connect failure, sending LoggedOut event and deleting session", reason)
go cli.dispatchEvent(&events.LoggedOut{OnConnect: true, Reason: reason})
err := cli.Store.Delete() err := cli.Store.Delete()
if err != nil { if err != nil {
cli.Log.Warnf("Failed to delete store after 401 failure: %v", err) cli.Log.Warnf("Failed to delete store after %d failure: %v", int(reason), err)
} }
} else if reason == events.ConnectFailureTempBanned {
cli.Log.Warnf("Temporary ban connect failure: %s", node.XMLString())
expiryTimeUnix := ag.Int64("expire")
var expiryTime time.Time
if expiryTimeUnix > 0 {
expiryTime = time.Unix(expiryTimeUnix, 0)
}
go cli.dispatchEvent(&events.TemporaryBan{
Code: events.TempBanReason(ag.Int("code")),
Expire: expiryTime,
})
} else if reason == events.ConnectFailureClientOutdated {
cli.Log.Errorf("Client outdated (405) connect failure")
go cli.dispatchEvent(&events.ClientOutdated{})
} else { } else {
cli.expectDisconnect()
cli.Log.Warnf("Unknown connect failure: %s", node.XMLString()) cli.Log.Warnf("Unknown connect failure: %s", node.XMLString())
go cli.dispatchEvent(&events.ConnectFailure{Reason: reason, Raw: node}) go cli.dispatchEvent(&events.ConnectFailure{Reason: reason, Raw: node})
} }

View File

@ -18,6 +18,7 @@ import (
"google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoreflect"
waProto "go.mau.fi/whatsmeow/binary/proto" waProto "go.mau.fi/whatsmeow/binary/proto"
"go.mau.fi/whatsmeow/socket"
"go.mau.fi/whatsmeow/util/cbcutil" "go.mau.fi/whatsmeow/util/cbcutil"
"go.mau.fi/whatsmeow/util/hkdfutil" "go.mau.fi/whatsmeow/util/hkdfutil"
) )
@ -34,9 +35,14 @@ const (
MediaDocument MediaType = "WhatsApp Document Keys" MediaDocument MediaType = "WhatsApp Document Keys"
MediaHistory MediaType = "WhatsApp History Keys" MediaHistory MediaType = "WhatsApp History Keys"
MediaAppState MediaType = "WhatsApp App State Keys" MediaAppState MediaType = "WhatsApp App State Keys"
MediaLinkThumbnail MediaType = "WhatsApp Link Thumbnail Keys"
) )
// DownloadableMessage represents a protobuf message that contains attachment info. // DownloadableMessage represents a protobuf message that contains attachment info.
//
// All of the downloadable messages inside a Message struct implement this interface
// (ImageMessage, VideoMessage, AudioMessage, DocumentMessage, StickerMessage).
type DownloadableMessage interface { type DownloadableMessage interface {
proto.Message proto.Message
GetDirectPath() string GetDirectPath() string
@ -45,6 +51,17 @@ type DownloadableMessage interface {
GetFileEncSha256() []byte GetFileEncSha256() []byte
} }
// DownloadableThumbnail represents a protobuf message that contains a thumbnail attachment.
//
// This is primarily meant for link preview thumbnails in ExtendedTextMessage.
type DownloadableThumbnail interface {
proto.Message
GetThumbnailDirectPath() string
GetThumbnailSha256() []byte
GetThumbnailEncSha256() []byte
GetMediaKey() []byte
}
// All the message types that are intended to be downloadable // All the message types that are intended to be downloadable
var ( var (
_ DownloadableMessage = (*waProto.ImageMessage)(nil) _ DownloadableMessage = (*waProto.ImageMessage)(nil)
@ -54,6 +71,7 @@ var (
_ DownloadableMessage = (*waProto.StickerMessage)(nil) _ DownloadableMessage = (*waProto.StickerMessage)(nil)
_ DownloadableMessage = (*waProto.HistorySyncNotification)(nil) _ DownloadableMessage = (*waProto.HistorySyncNotification)(nil)
_ DownloadableMessage = (*waProto.ExternalBlobReference)(nil) _ DownloadableMessage = (*waProto.ExternalBlobReference)(nil)
_ DownloadableThumbnail = (*waProto.ExtendedTextMessage)(nil)
) )
type downloadableMessageWithLength interface { type downloadableMessageWithLength interface {
@ -82,6 +100,10 @@ var classToMediaType = map[protoreflect.Name]MediaType{
"ExternalBlobReference": MediaAppState, "ExternalBlobReference": MediaAppState,
} }
var classToThumbnailMediaType = map[protoreflect.Name]MediaType{
"ExtendedTextMessage": MediaLinkThumbnail,
}
var mediaTypeToMMSType = map[MediaType]string{ var mediaTypeToMMSType = map[MediaType]string{
MediaImage: "image", MediaImage: "image",
MediaAudio: "audio", MediaAudio: "audio",
@ -89,17 +111,29 @@ var mediaTypeToMMSType = map[MediaType]string{
MediaDocument: "document", MediaDocument: "document",
MediaHistory: "md-msg-hist", MediaHistory: "md-msg-hist",
MediaAppState: "md-app-state", MediaAppState: "md-app-state",
MediaLinkThumbnail: "thumbnail-link",
} }
// DownloadAny loops through the downloadable parts of the given message and downloads the first non-nil item. // DownloadAny loops through the downloadable parts of the given message and downloads the first non-nil item.
func (cli *Client) DownloadAny(msg *waProto.Message) (data []byte, err error) { func (cli *Client) DownloadAny(msg *waProto.Message) (data []byte, err error) {
downloadables := []DownloadableMessage{msg.GetImageMessage(), msg.GetAudioMessage(), msg.GetVideoMessage(), msg.GetDocumentMessage(), msg.GetStickerMessage()} if msg == nil {
for _, downloadable := range downloadables {
if downloadable != nil {
return cli.Download(downloadable)
}
}
return nil, ErrNothingDownloadableFound return nil, ErrNothingDownloadableFound
}
switch {
case msg.ImageMessage != nil:
return cli.Download(msg.ImageMessage)
case msg.VideoMessage != nil:
return cli.Download(msg.VideoMessage)
case msg.AudioMessage != nil:
return cli.Download(msg.AudioMessage)
case msg.DocumentMessage != nil:
return cli.Download(msg.DocumentMessage)
case msg.StickerMessage != nil:
return cli.Download(msg.StickerMessage)
default:
return nil, ErrNothingDownloadableFound
}
} }
func getSize(msg DownloadableMessage) int { func getSize(msg DownloadableMessage) int {
@ -113,30 +147,63 @@ func getSize(msg DownloadableMessage) int {
} }
} }
// DownloadThumbnail downloads a thumbnail from a message.
//
// This is primarily intended for downloading link preview thumbnails, which are in ExtendedTextMessage:
// var msg *waProto.Message
// ...
// thumbnailImageBytes, err := cli.DownloadThumbnail(msg.GetExtendedTextMessage())
func (cli *Client) DownloadThumbnail(msg DownloadableThumbnail) ([]byte, error) {
mediaType, ok := classToThumbnailMediaType[msg.ProtoReflect().Descriptor().Name()]
if !ok {
return nil, fmt.Errorf("%w '%s'", ErrUnknownMediaType, string(msg.ProtoReflect().Descriptor().Name()))
} else if len(msg.GetThumbnailDirectPath()) > 0 {
return cli.DownloadMediaWithPath(msg.GetThumbnailDirectPath(), msg.GetThumbnailEncSha256(), msg.GetThumbnailSha256(), msg.GetMediaKey(), -1, mediaType, mediaTypeToMMSType[mediaType])
} else {
return nil, ErrNoURLPresent
}
}
// GetMediaType returns the MediaType value corresponding to the given protobuf message.
func GetMediaType(msg DownloadableMessage) MediaType {
return classToMediaType[msg.ProtoReflect().Descriptor().Name()]
}
// Download downloads the attachment from the given protobuf message. // Download downloads the attachment from the given protobuf message.
func (cli *Client) Download(msg DownloadableMessage) (data []byte, err error) { //
// The attachment is a specific part of a Message protobuf struct, not the message itself, e.g.
// var msg *waProto.Message
// ...
// imageData, err := cli.Download(msg.GetImageMessage())
//
// You can also use DownloadAny to download the first non-nil sub-message.
func (cli *Client) Download(msg DownloadableMessage) ([]byte, error) {
mediaType, ok := classToMediaType[msg.ProtoReflect().Descriptor().Name()] mediaType, ok := classToMediaType[msg.ProtoReflect().Descriptor().Name()]
if !ok { if !ok {
return nil, fmt.Errorf("%w '%s'", ErrUnknownMediaType, string(msg.ProtoReflect().Descriptor().Name())) return nil, fmt.Errorf("%w '%s'", ErrUnknownMediaType, string(msg.ProtoReflect().Descriptor().Name()))
} }
urlable, ok := msg.(downloadableMessageWithURL) urlable, ok := msg.(downloadableMessageWithURL)
if ok && len(urlable.GetUrl()) > 0 { if ok && len(urlable.GetUrl()) > 0 {
return downloadAndDecrypt(urlable.GetUrl(), msg.GetMediaKey(), mediaType, getSize(msg), msg.GetFileEncSha256(), msg.GetFileSha256()) return cli.downloadAndDecrypt(urlable.GetUrl(), msg.GetMediaKey(), mediaType, getSize(msg), msg.GetFileEncSha256(), msg.GetFileSha256())
} else if len(msg.GetDirectPath()) > 0 { } else if len(msg.GetDirectPath()) > 0 {
return cli.downloadMediaWithPath(msg.GetDirectPath(), msg.GetFileEncSha256(), msg.GetFileSha256(), msg.GetMediaKey(), getSize(msg), mediaType, mediaTypeToMMSType[mediaType]) return cli.DownloadMediaWithPath(msg.GetDirectPath(), msg.GetFileEncSha256(), msg.GetFileSha256(), msg.GetMediaKey(), getSize(msg), mediaType, mediaTypeToMMSType[mediaType])
} else { } else {
return nil, ErrNoURLPresent return nil, ErrNoURLPresent
} }
} }
func (cli *Client) downloadMediaWithPath(directPath string, encFileHash, fileHash, mediaKey []byte, fileLength int, mediaType MediaType, mmsType string) (data []byte, err error) { // DownloadMediaWithPath downloads an attachment by manually specifying the path and encryption details.
func (cli *Client) DownloadMediaWithPath(directPath string, encFileHash, fileHash, mediaKey []byte, fileLength int, mediaType MediaType, mmsType string) (data []byte, err error) {
err = cli.refreshMediaConn(false) err = cli.refreshMediaConn(false)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to refresh media connections: %w", err) return nil, fmt.Errorf("failed to refresh media connections: %w", err)
} }
if len(mmsType) == 0 {
mmsType = mediaTypeToMMSType[mediaType]
}
for i, host := range cli.mediaConn.Hosts { for i, host := range cli.mediaConn.Hosts {
mediaURL := fmt.Sprintf("https://%s%s&hash=%s&mms-type=%s&__wa-mms=", host.Hostname, directPath, base64.URLEncoding.EncodeToString(encFileHash), mmsType) mediaURL := fmt.Sprintf("https://%s%s&hash=%s&mms-type=%s&__wa-mms=", host.Hostname, directPath, base64.URLEncoding.EncodeToString(encFileHash), mmsType)
data, err = downloadAndDecrypt(mediaURL, mediaKey, mediaType, fileLength, encFileHash, fileHash) data, err = cli.downloadAndDecrypt(mediaURL, mediaKey, mediaType, fileLength, encFileHash, fileHash)
// TODO there are probably some errors that shouldn't retry // TODO there are probably some errors that shouldn't retry
if err != nil { if err != nil {
if i >= len(cli.mediaConn.Hosts)-1 { if i >= len(cli.mediaConn.Hosts)-1 {
@ -148,10 +215,10 @@ func (cli *Client) downloadMediaWithPath(directPath string, encFileHash, fileHas
return return
} }
func downloadAndDecrypt(url string, mediaKey []byte, appInfo MediaType, fileLength int, fileEncSha256, fileSha256 []byte) (data []byte, err error) { func (cli *Client) downloadAndDecrypt(url string, mediaKey []byte, appInfo MediaType, fileLength int, fileEncSha256, fileSha256 []byte) (data []byte, err error) {
iv, cipherKey, macKey, _ := getMediaKeys(mediaKey, appInfo) iv, cipherKey, macKey, _ := getMediaKeys(mediaKey, appInfo)
var ciphertext, mac []byte var ciphertext, mac []byte
if ciphertext, mac, err = downloadEncryptedMedia(url, fileEncSha256); err != nil { if ciphertext, mac, err = cli.downloadEncryptedMedia(url, fileEncSha256); err != nil {
} else if err = validateMedia(iv, ciphertext, macKey, mac); err != nil { } else if err = validateMedia(iv, ciphertext, macKey, mac); err != nil {
@ -170,9 +237,17 @@ func getMediaKeys(mediaKey []byte, appInfo MediaType) (iv, cipherKey, macKey, re
return mediaKeyExpanded[:16], mediaKeyExpanded[16:48], mediaKeyExpanded[48:80], mediaKeyExpanded[80:] return mediaKeyExpanded[:16], mediaKeyExpanded[16:48], mediaKeyExpanded[48:80], mediaKeyExpanded[80:]
} }
func downloadEncryptedMedia(url string, checksum []byte) (file, mac []byte, err error) { func (cli *Client) downloadEncryptedMedia(url string, checksum []byte) (file, mac []byte, err error) {
var req *http.Request
req, err = http.NewRequest(http.MethodGet, url, nil)
if err != nil {
err = fmt.Errorf("failed to prepare request: %w", err)
return
}
req.Header.Set("Origin", socket.Origin)
req.Header.Set("Referer", socket.Origin+"/")
var resp *http.Response var resp *http.Response
resp, err = http.Get(url) resp, err = cli.http.Do(req)
if err != nil { if err != nil {
return return
} }

View File

@ -45,6 +45,8 @@ var (
ErrInviteLinkRevoked = errors.New("that group invite link has been revoked") ErrInviteLinkRevoked = errors.New("that group invite link has been revoked")
// ErrBusinessMessageLinkNotFound is returned by ResolveBusinessMessageLink if the link doesn't exist or has been revoked. // ErrBusinessMessageLinkNotFound is returned by ResolveBusinessMessageLink if the link doesn't exist or has been revoked.
ErrBusinessMessageLinkNotFound = errors.New("that business message link does not exist or has been revoked") ErrBusinessMessageLinkNotFound = errors.New("that business message link does not exist or has been revoked")
// ErrInvalidImageFormat is returned by SetGroupPhoto if the given photo is not in the correct format.
ErrInvalidImageFormat = errors.New("the given data is not a valid image")
) )
// Some errors that Client.SendMessage can return // Some errors that Client.SendMessage can return

View File

@ -106,6 +106,40 @@ func (cli *Client) UpdateGroupParticipants(jid types.JID, participantChanges map
return resp, nil return resp, nil
} }
// SetGroupPhoto updates the group picture/icon of the given group on WhatsApp.
// The avatar should be a JPEG photo, other formats may be rejected with ErrInvalidImageFormat.
// The bytes can be nil to remove the photo. Returns the new picture ID.
func (cli *Client) SetGroupPhoto(jid types.JID, avatar []byte) (string, error) {
var content interface{}
if avatar != nil {
content = []waBinary.Node{{
Tag: "picture",
Attrs: waBinary.Attrs{"type": "image"},
Content: avatar,
}}
}
resp, err := cli.sendIQ(infoQuery{
Namespace: "w:profile:picture",
Type: iqSet,
To: types.ServerJID,
Target: jid,
Content: content,
})
if errors.Is(err, ErrIQNotAcceptable) {
return "", wrapIQError(ErrInvalidImageFormat, err)
} else if err != nil {
return "", err
}
if avatar == nil {
return "remove", nil
}
pictureID, ok := resp.GetChildByTag("picture").Attrs["id"].(string)
if !ok {
return "", fmt.Errorf("didn't find picture ID in response")
}
return pictureID, nil
}
// SetGroupName updates the name (subject) of the given group on WhatsApp. // SetGroupName updates the name (subject) of the given group on WhatsApp.
func (cli *Client) SetGroupName(jid types.JID, name string) error { func (cli *Client) SetGroupName(jid types.JID, name string) error {
_, err := cli.sendGroupIQ(iqSet, jid, waBinary.Node{ _, err := cli.sendGroupIQ(iqSet, jid, waBinary.Node{
@ -385,7 +419,8 @@ func (cli *Client) parseGroupNode(groupNode *waBinary.Node) (*types.GroupInfo, e
case "description": case "description":
body, bodyOK := child.GetOptionalChildByTag("body") body, bodyOK := child.GetOptionalChildByTag("body")
if bodyOK { if bodyOK {
group.Topic, _ = body.Content.(string) topicBytes, _ := body.Content.([]byte)
group.Topic = string(topicBytes)
group.TopicID = childAG.String("id") group.TopicID = childAG.String("id")
group.TopicSetBy = childAG.OptionalJIDOrEmpty("participant") group.TopicSetBy = childAG.OptionalJIDOrEmpty("participant")
group.TopicSetAt = time.Unix(childAG.Int64("t"), 0) group.TopicSetAt = time.Unix(childAG.Int64("t"), 0)

163
vendor/go.mau.fi/whatsmeow/mediaretry.go vendored Normal file
View File

@ -0,0 +1,163 @@
// Copyright (c) 2022 Tulir Asokan
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package whatsmeow
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"fmt"
"time"
"google.golang.org/protobuf/proto"
waBinary "go.mau.fi/whatsmeow/binary"
waProto "go.mau.fi/whatsmeow/binary/proto"
"go.mau.fi/whatsmeow/types"
"go.mau.fi/whatsmeow/types/events"
"go.mau.fi/whatsmeow/util/hkdfutil"
)
func getMediaRetryKey(mediaKey []byte) (cipherKey []byte) {
return hkdfutil.SHA256(mediaKey, nil, []byte("WhatsApp Media Retry Notification"), 32)
}
func prepareMediaRetryGCM(mediaKey []byte) (cipher.AEAD, error) {
block, err := aes.NewCipher(getMediaRetryKey(mediaKey))
if err != nil {
return nil, fmt.Errorf("failed to initialize AES cipher: %w", err)
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, fmt.Errorf("failed to initialize GCM: %w", err)
}
return gcm, nil
}
func encryptMediaRetryReceipt(messageID types.MessageID, mediaKey []byte) (ciphertext, iv []byte, err error) {
receipt := &waProto.ServerErrorReceipt{
StanzaId: proto.String(messageID),
}
var plaintext []byte
plaintext, err = proto.Marshal(receipt)
if err != nil {
err = fmt.Errorf("failed to marshal payload: %w", err)
return
}
var gcm cipher.AEAD
gcm, err = prepareMediaRetryGCM(mediaKey)
if err != nil {
return
}
iv = make([]byte, 12)
_, err = rand.Read(iv)
if err != nil {
panic(err)
}
ciphertext = gcm.Seal(plaintext[:0], iv, plaintext, []byte(messageID))
return
}
// SendMediaRetryReceipt sends a request to the phone to re-upload the media in a message.
//
// The response will come as an *events.MediaRetry. The response will then have to be decrypted
// using DecryptMediaRetryNotification and the same media key passed here.
func (cli *Client) SendMediaRetryReceipt(message *types.MessageInfo, mediaKey []byte) error {
ciphertext, iv, err := encryptMediaRetryReceipt(message.ID, mediaKey)
if err != nil {
return fmt.Errorf("failed to prepare encrypted retry receipt: %w", err)
}
rmrAttrs := waBinary.Attrs{
"jid": message.Chat,
"from_me": message.IsFromMe,
}
if message.IsGroup {
rmrAttrs["participant"] = message.Sender
}
encryptedRequest := []waBinary.Node{
{Tag: "enc_p", Content: ciphertext},
{Tag: "enc_iv", Content: iv},
}
err = cli.sendNode(waBinary.Node{
Tag: "receipt",
Attrs: waBinary.Attrs{
"id": message.ID,
"to": cli.Store.ID.ToNonAD(),
"type": "server-error",
},
Content: []waBinary.Node{
{Tag: "encrypt", Content: encryptedRequest},
{Tag: "rmr", Attrs: rmrAttrs},
},
})
if err != nil {
return err
}
return nil
}
// DecryptMediaRetryNotification decrypts a media retry notification using the media key.
func DecryptMediaRetryNotification(evt *events.MediaRetry, mediaKey []byte) (*waProto.MediaRetryNotification, error) {
gcm, err := prepareMediaRetryGCM(mediaKey)
if err != nil {
return nil, err
}
plaintext, err := gcm.Open(nil, evt.IV, evt.Ciphertext, []byte(evt.MessageID))
if err != nil {
return nil, fmt.Errorf("failed to decrypt notification: %w", err)
}
var notif waProto.MediaRetryNotification
err = proto.Unmarshal(plaintext, &notif)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal notification (invalid encryption key?): %w", err)
}
return &notif, nil
}
func parseMediaRetryNotification(node *waBinary.Node) (*events.MediaRetry, error) {
ag := node.AttrGetter()
var evt events.MediaRetry
evt.Timestamp = time.Unix(ag.Int64("t"), 0)
evt.MessageID = types.MessageID(ag.String("id"))
if !ag.OK() {
return nil, ag.Error()
}
rmr, ok := node.GetOptionalChildByTag("rmr")
if !ok {
return nil, &ElementMissingError{Tag: "rmr", In: "retry notification"}
}
rmrAG := rmr.AttrGetter()
evt.ChatID = rmrAG.JID("jid")
evt.FromMe = rmrAG.Bool("from_me")
evt.SenderID = rmrAG.OptionalJIDOrEmpty("participant")
if !rmrAG.OK() {
return nil, fmt.Errorf("missing attributes in <rmr> tag: %w", rmrAG.Error())
}
evt.Ciphertext, ok = node.GetChildByTag("encrypt", "enc_p").Content.([]byte)
if !ok {
return nil, &ElementMissingError{Tag: "enc_p", In: fmt.Sprintf("retry notification %s", evt.MessageID)}
}
evt.IV, ok = node.GetChildByTag("encrypt", "enc_iv").Content.([]byte)
if !ok {
return nil, &ElementMissingError{Tag: "enc_iv", In: fmt.Sprintf("retry notification %s", evt.MessageID)}
}
return &evt, nil
}
func (cli *Client) handleMediaRetryNotification(node *waBinary.Node) {
// TODO handle errors (e.g. <error code="2"/>)
evt, err := parseMediaRetryNotification(node)
if err != nil {
cli.Log.Warnf("Failed to parse media retry notification: %v", err)
return
}
cli.dispatchEvent(evt)
}

View File

@ -283,6 +283,7 @@ func (cli *Client) handleHistorySyncNotification(notif *waProto.HistorySyncNotif
} }
func (cli *Client) handleAppStateSyncKeyShare(keys *waProto.AppStateSyncKeyShare) { func (cli *Client) handleAppStateSyncKeyShare(keys *waProto.AppStateSyncKeyShare) {
cli.Log.Debugf("Got %d new app state keys", len(keys.GetKeys()))
for _, key := range keys.GetKeys() { for _, key := range keys.GetKeys() {
marshaledFingerprint, err := proto.Marshal(key.GetKeyData().GetFingerprint()) marshaledFingerprint, err := proto.Marshal(key.GetKeyData().GetFingerprint())
if err != nil { if err != nil {
@ -365,7 +366,7 @@ func (cli *Client) handleDecryptedMessage(info *types.MessageInfo, msg *waProto.
} }
func (cli *Client) sendProtocolMessageReceipt(id, msgType string) { func (cli *Client) sendProtocolMessageReceipt(id, msgType string) {
if len(id) == 0 { if len(id) == 0 || cli.Store.ID == nil {
return return
} }
err := cli.sendNode(waBinary.Node{ err := cli.sendNode(waBinary.Node{

View File

@ -199,6 +199,9 @@ func (cli *Client) handleNotification(node *waBinary.Node) {
} }
case "picture": case "picture":
go cli.handlePictureNotification(node) go cli.handlePictureNotification(node)
case "mediaretry":
go cli.handleMediaRetryNotification(node)
// Other types: business, disappearing_mode, server, status, pay, psa, privacy_token
default: default:
cli.Log.Debugf("Unhandled notification with type %s", notifType) cli.Log.Debugf("Unhandled notification with type %s", notifType)
} }

View File

@ -7,6 +7,7 @@
package whatsmeow package whatsmeow
import ( import (
"sync/atomic"
"time" "time"
waBinary "go.mau.fi/whatsmeow/binary" waBinary "go.mau.fi/whatsmeow/binary"
@ -23,12 +24,14 @@ func (cli *Client) handleChatState(node *waBinary.Node) {
} else { } else {
child := node.GetChildren()[0] child := node.GetChildren()[0]
presence := types.ChatPresence(child.Tag) presence := types.ChatPresence(child.Tag)
if presence != types.ChatPresenceComposing && presence != types.ChatPresenceRecording && presence != types.ChatPresencePaused { if presence != types.ChatPresenceComposing && presence != types.ChatPresencePaused {
cli.Log.Warnf("Unrecognized chat presence state %s", child.Tag) cli.Log.Warnf("Unrecognized chat presence state %s", child.Tag)
} }
media := types.ChatPresenceMedia(child.AttrGetter().OptionalString("media"))
cli.dispatchEvent(&events.ChatPresence{ cli.dispatchEvent(&events.ChatPresence{
MessageSource: source, MessageSource: source,
State: presence, State: presence,
Media: media,
}) })
} }
} }
@ -62,6 +65,11 @@ func (cli *Client) SendPresence(state types.Presence) error {
if len(cli.Store.PushName) == 0 { if len(cli.Store.PushName) == 0 {
return ErrNoPushName return ErrNoPushName
} }
if state == types.PresenceAvailable {
atomic.CompareAndSwapUint32(&cli.sendActiveReceipts, 0, 1)
} else {
atomic.CompareAndSwapUint32(&cli.sendActiveReceipts, 1, 0)
}
return cli.sendNode(waBinary.Node{ return cli.sendNode(waBinary.Node{
Tag: "presence", Tag: "presence",
Attrs: waBinary.Attrs{ Attrs: waBinary.Attrs{
@ -89,13 +97,21 @@ func (cli *Client) SubscribePresence(jid types.JID) error {
} }
// SendChatPresence updates the user's typing status in a specific chat. // SendChatPresence updates the user's typing status in a specific chat.
func (cli *Client) SendChatPresence(state types.ChatPresence, jid types.JID) error { //
// The media parameter can be set to indicate the user is recording media (like a voice message) rather than typing a text message.
func (cli *Client) SendChatPresence(jid types.JID, state types.ChatPresence, media types.ChatPresenceMedia) error {
content := []waBinary.Node{{Tag: string(state)}}
if state == types.ChatPresenceComposing && len(media) > 0 {
content[0].Attrs = waBinary.Attrs{
"media": string(media),
}
}
return cli.sendNode(waBinary.Node{ return cli.sendNode(waBinary.Node{
Tag: "chatstate", Tag: "chatstate",
Attrs: waBinary.Attrs{ Attrs: waBinary.Attrs{
"from": *cli.Store.ID, "from": *cli.Store.ID,
"to": jid, "to": jid,
}, },
Content: []waBinary.Node{{Tag: string(state)}}, Content: content,
}) })
} }

View File

@ -1,4 +1,4 @@
// Copyright (c) 2021 Tulir Asokan // Copyright (c) 2022 Tulir Asokan
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this // License, v. 2.0. If a copy of the MPL was not distributed with this
@ -36,6 +36,8 @@ var (
// QRChannelErrUnexpectedEvent is emitted from GetQRChannel if an unexpected connection event is received, // QRChannelErrUnexpectedEvent is emitted from GetQRChannel if an unexpected connection event is received,
// as that likely means that the pairing has already happened before the channel was set up. // as that likely means that the pairing has already happened before the channel was set up.
QRChannelErrUnexpectedEvent = QRChannelItem{Event: "err-unexpected-state"} QRChannelErrUnexpectedEvent = QRChannelItem{Event: "err-unexpected-state"}
// QRChannelClientOutdated is emitted from GetQRChannel if events.ClientOutdated is received.
QRChannelClientOutdated = QRChannelItem{Event: "err-client-outdated"}
// QRChannelScannedWithoutMultidevice is emitted from GetQRChannel if events.QRScannedWithoutMultidevice is received. // QRChannelScannedWithoutMultidevice is emitted from GetQRChannel if events.QRScannedWithoutMultidevice is received.
QRChannelScannedWithoutMultidevice = QRChannelItem{Event: "err-scanned-without-multidevice"} QRChannelScannedWithoutMultidevice = QRChannelItem{Event: "err-scanned-without-multidevice"}
) )
@ -117,6 +119,8 @@ func (qrc *qrChannel) handleEvent(rawEvt interface{}) {
qrc.log.Debugf("QR code scanned without multidevice enabled") qrc.log.Debugf("QR code scanned without multidevice enabled")
qrc.output <- QRChannelScannedWithoutMultidevice qrc.output <- QRChannelScannedWithoutMultidevice
return return
case *events.ClientOutdated:
outputType = QRChannelClientOutdated
case *events.PairSuccess: case *events.PairSuccess:
outputType = QRChannelSuccess outputType = QRChannelSuccess
case *events.PairError: case *events.PairError:
@ -126,7 +130,7 @@ func (qrc *qrChannel) handleEvent(rawEvt interface{}) {
} }
case *events.Disconnected: case *events.Disconnected:
outputType = QRChannelTimeout outputType = QRChannelTimeout
case *events.Connected, *events.ConnectFailure, *events.LoggedOut: case *events.Connected, *events.ConnectFailure, *events.LoggedOut, *events.TemporaryBan:
outputType = QRChannelErrUnexpectedEvent outputType = QRChannelErrUnexpectedEvent
default: default:
return return

View File

@ -8,6 +8,7 @@ package whatsmeow
import ( import (
"fmt" "fmt"
"sync/atomic"
"time" "time"
waBinary "go.mau.fi/whatsmeow/binary" waBinary "go.mau.fi/whatsmeow/binary"
@ -123,13 +124,35 @@ func (cli *Client) MarkRead(ids []types.MessageID, timestamp time.Time, chat, se
return cli.sendNode(node) return cli.sendNode(node)
} }
// SetForceActiveDeliveryReceipts will force the client to send normal delivery
// receipts (which will show up as the two gray ticks on WhatsApp), even if the
// client isn't marked as online.
//
// By default, clients that haven't been marked as online will send delivery
// receipts with type="inactive", which is transmitted to the sender, but not
// rendered in the official WhatsApp apps. This is consistent with how WhatsApp
// web works when it's not in the foreground.
//
// To mark the client as online, use
// cli.SendPresence(types.PresenceAvailable)
//
// Note that if you turn this off (i.e. call SetForceActiveDeliveryReceipts(false)),
// receipts will act like the client is offline until SendPresence is called again.
func (cli *Client) SetForceActiveDeliveryReceipts(active bool) {
if active {
atomic.StoreUint32(&cli.sendActiveReceipts, 2)
} else {
atomic.StoreUint32(&cli.sendActiveReceipts, 0)
}
}
func (cli *Client) sendMessageReceipt(info *types.MessageInfo) { func (cli *Client) sendMessageReceipt(info *types.MessageInfo) {
attrs := waBinary.Attrs{ attrs := waBinary.Attrs{
"id": info.ID, "id": info.ID,
} }
if info.IsFromMe { if info.IsFromMe {
attrs["type"] = "sender" attrs["type"] = "sender"
} else { } else if atomic.LoadUint32(&cli.sendActiveReceipts) == 0 {
attrs["type"] = "inactive" attrs["type"] = "inactive"
} }
attrs["to"] = info.Chat attrs["to"] = info.Chat
@ -137,6 +160,9 @@ func (cli *Client) sendMessageReceipt(info *types.MessageInfo) {
attrs["participant"] = info.Sender attrs["participant"] = info.Sender
} else if info.IsFromMe { } else if info.IsFromMe {
attrs["recipient"] = info.Sender attrs["recipient"] = info.Sender
} else {
// Override the to attribute with the JID version with a device number
attrs["to"] = info.Sender
} }
err := cli.sendNode(waBinary.Node{ err := cli.sendNode(waBinary.Node{
Tag: "receipt", Tag: "receipt",

View File

@ -78,6 +78,7 @@ type infoQuery struct {
Namespace string Namespace string
Type infoQueryType Type infoQueryType
To types.JID To types.JID
Target types.JID
ID string ID string
Content interface{} Content interface{}
@ -98,6 +99,9 @@ func (cli *Client) sendIQAsync(query infoQuery) (<-chan *waBinary.Node, error) {
if !query.To.IsEmpty() { if !query.To.IsEmpty() {
attrs["to"] = query.To attrs["to"] = query.To
} }
if !query.Target.IsEmpty() {
attrs["target"] = query.Target
}
err := cli.sendNode(waBinary.Node{ err := cli.sendNode(waBinary.Node{
Tag: "iq", Tag: "iq",
Attrs: attrs, Attrs: attrs,
@ -116,7 +120,7 @@ func (cli *Client) sendIQ(query infoQuery) (*waBinary.Node, error) {
return nil, err return nil, err
} }
if query.Timeout == 0 { if query.Timeout == 0 {
query.Timeout = 1 * time.Minute query.Timeout = 75 * time.Second
} }
if query.Context == nil { if query.Context == nil {
query.Context = context.Background() query.Context = context.Background()

View File

@ -30,6 +30,9 @@ import (
) )
// GenerateMessageID generates a random string that can be used as a message ID on WhatsApp. // GenerateMessageID generates a random string that can be used as a message ID on WhatsApp.
//
// msgID := whatsmeow.GenerateMessageID()
// cli.SendMessage(targetJID, msgID, &waProto.Message{...})
func GenerateMessageID() types.MessageID { func GenerateMessageID() types.MessageID {
id := make([]byte, 16) id := make([]byte, 16)
_, err := rand.Read(id) _, err := rand.Read(id)
@ -46,6 +49,20 @@ func GenerateMessageID() types.MessageID {
// //
// This method will wait for the server to acknowledge the message before returning. // This method will wait for the server to acknowledge the message before returning.
// The return value is the timestamp of the message from the server. // The return value is the timestamp of the message from the server.
//
// The message itself can contain anything you want (within the protobuf schema).
// e.g. for a simple text message, use the Conversation field:
// cli.SendMessage(targetJID, "", &waProto.Message{
// Conversation: proto.String("Hello, World!"),
// })
//
// Things like replies, mentioning users and the "forwarded" flag are stored in ContextInfo,
// which can be put in ExtendedTextMessage and any of the media message types.
//
// For uploading and sending media/attachments, see the Upload method.
//
// For other message types, you'll have to figure it out yourself. Looking at the protobuf schema
// in binary/proto/def.proto may be useful to find out all the allowed fields.
func (cli *Client) SendMessage(to types.JID, id types.MessageID, message *waProto.Message) (time.Time, error) { func (cli *Client) SendMessage(to types.JID, id types.MessageID, message *waProto.Message) (time.Time, error) {
if to.AD { if to.AD {
return time.Time{}, ErrRecipientADJID return time.Time{}, ErrRecipientADJID
@ -210,7 +227,7 @@ func (cli *Client) prepareMessageNode(to types.JID, id types.MessageID, message
Content: participantNodes, Content: participantNodes,
}}, }},
} }
if message.ProtocolMessage != nil && message.GetProtocolMessage().GetType() == waProto.ProtocolMessage_REVOKE { if message.ProtocolMessage != nil && message.GetProtocolMessage().GetType() == waProto.ProtocolMessage_REVOKE && message.GetProtocolMessage().GetKey() != nil {
node.Attrs["edit"] = "7" node.Attrs["edit"] = "7"
} }
if includeIdentity { if includeIdentity {

View File

@ -10,7 +10,11 @@
// The Client struct in the top-level whatsmeow package handles everything. // The Client struct in the top-level whatsmeow package handles everything.
package socket package socket
import "errors" import (
"errors"
"go.mau.fi/whatsmeow/binary/token"
)
const ( const (
// Origin is the Origin header for all WhatsApp websocket connections // Origin is the Origin header for all WhatsApp websocket connections
@ -22,11 +26,10 @@ const (
const ( const (
NoiseStartPattern = "Noise_XX_25519_AESGCM_SHA256\x00\x00\x00\x00" NoiseStartPattern = "Noise_XX_25519_AESGCM_SHA256\x00\x00\x00\x00"
WADictVersion = 2
WAMagicValue = 5 WAMagicValue = 5
) )
var WAConnHeader = []byte{'W', 'A', WAMagicValue, WADictVersion} var WAConnHeader = []byte{'W', 'A', WAMagicValue, token.DictVersion}
const ( const (
FrameMaxSize = 2 << 23 FrameMaxSize = 2 << 23

View File

@ -11,6 +11,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"net/url"
"sync" "sync"
"time" "time"
@ -19,6 +20,8 @@ import (
waLog "go.mau.fi/whatsmeow/util/log" waLog "go.mau.fi/whatsmeow/util/log"
) )
type Proxy = func(*http.Request) (*url.URL, error)
type FrameSocket struct { type FrameSocket struct {
conn *websocket.Conn conn *websocket.Conn
ctx context.Context ctx context.Context
@ -31,6 +34,7 @@ type FrameSocket struct {
WriteTimeout time.Duration WriteTimeout time.Duration
Header []byte Header []byte
Proxy Proxy
incomingLength int incomingLength int
receivedLength int receivedLength int
@ -38,12 +42,14 @@ type FrameSocket struct {
partialHeader []byte partialHeader []byte
} }
func NewFrameSocket(log waLog.Logger, header []byte) *FrameSocket { func NewFrameSocket(log waLog.Logger, header []byte, proxy Proxy) *FrameSocket {
return &FrameSocket{ return &FrameSocket{
conn: nil, conn: nil,
log: log, log: log,
Header: header, Header: header,
Frames: make(chan []byte), Frames: make(chan []byte),
Proxy: proxy,
} }
} }
@ -92,7 +98,9 @@ func (fs *FrameSocket) Connect() error {
return ErrSocketAlreadyOpen return ErrSocketAlreadyOpen
} }
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
dialer := websocket.Dialer{} dialer := websocket.Dialer{
Proxy: fs.Proxy,
}
headers := http.Header{"Origin": []string{Origin}} headers := http.Header{"Origin": []string{Origin}}
fs.log.Debugf("Dialing %s", URL) fs.log.Debugf("Dialing %s", URL)

View File

@ -20,36 +20,98 @@ import (
waProto "go.mau.fi/whatsmeow/binary/proto" waProto "go.mau.fi/whatsmeow/binary/proto"
) )
// WAVersionContainer is a container for a WhatsApp web version number.
type WAVersionContainer [3]uint32
// ParseVersion parses a version string (three dot-separated numbers) into a WAVersionContainer.
func ParseVersion(version string) (parsed WAVersionContainer, err error) {
var part1, part2, part3 int
if parts := strings.Split(version, "."); len(parts) != 3 {
err = fmt.Errorf("'%s' doesn't contain three dot-separated parts", version)
} else if part1, err = strconv.Atoi(parts[0]); err != nil {
err = fmt.Errorf("first part of '%s' is not a number: %w", version, err)
} else if part2, err = strconv.Atoi(parts[1]); err != nil {
err = fmt.Errorf("second part of '%s' is not a number: %w", version, err)
} else if part3, err = strconv.Atoi(parts[2]); err != nil {
err = fmt.Errorf("third part of '%s' is not a number: %w", version, err)
} else {
parsed = WAVersionContainer{uint32(part1), uint32(part2), uint32(part3)}
}
return
}
func (vc WAVersionContainer) LessThan(other WAVersionContainer) bool {
return vc[0] < other[0] ||
(vc[0] == other[0] && vc[1] < other[1]) ||
(vc[0] == other[0] && vc[1] == other[1] && vc[2] < other[2])
}
// IsZero returns true if the version is zero.
func (vc WAVersionContainer) IsZero() bool {
return vc == [3]uint32{0, 0, 0}
}
// String returns the version number as a dot-separated string.
func (vc WAVersionContainer) String() string {
parts := make([]string, len(vc))
for i, part := range vc {
parts[i] = strconv.Itoa(int(part))
}
return strings.Join(parts, ".")
}
// Hash returns the md5 hash of the String representation of this version.
func (vc WAVersionContainer) Hash() [16]byte {
return md5.Sum([]byte(vc.String()))
}
func (vc WAVersionContainer) ProtoAppVersion() *waProto.AppVersion {
return &waProto.AppVersion{
Primary: &vc[0],
Secondary: &vc[1],
Tertiary: &vc[2],
}
}
// waVersion is the WhatsApp web client version // waVersion is the WhatsApp web client version
var waVersion = []uint32{2, 2202, 9} var waVersion = WAVersionContainer{2, 2208, 7}
// waVersionHash is the md5 hash of a dot-separated waVersion // waVersionHash is the md5 hash of a dot-separated waVersion
var waVersionHash [16]byte var waVersionHash [16]byte
func init() { func init() {
waVersionParts := make([]string, len(waVersion)) waVersionHash = waVersion.Hash()
for i, part := range waVersion { }
waVersionParts[i] = strconv.Itoa(int(part))
// GetWAVersion gets the current WhatsApp web client version.
func GetWAVersion() WAVersionContainer {
return waVersion
}
// SetWAVersion sets the current WhatsApp web client version.
//
// In general, you should keep the library up-to-date instead of using this,
// as there may be code changes that are necessary too (like protobuf schema changes).
func SetWAVersion(version WAVersionContainer) {
if version.IsZero() {
return
} }
waVersionString := strings.Join(waVersionParts, ".") waVersion = version
waVersionHash = md5.Sum([]byte(waVersionString)) waVersionHash = version.Hash()
} }
var BaseClientPayload = &waProto.ClientPayload{ var BaseClientPayload = &waProto.ClientPayload{
UserAgent: &waProto.UserAgent{ UserAgent: &waProto.UserAgent{
Platform: waProto.UserAgent_WEB.Enum(), Platform: waProto.UserAgent_WEB.Enum(),
ReleaseChannel: waProto.UserAgent_RELEASE.Enum(), ReleaseChannel: waProto.UserAgent_RELEASE.Enum(),
AppVersion: &waProto.AppVersion{ AppVersion: waVersion.ProtoAppVersion(),
Primary: &waVersion[0],
Secondary: &waVersion[1],
Tertiary: &waVersion[2],
},
Mcc: proto.String("000"), Mcc: proto.String("000"),
Mnc: proto.String("000"), Mnc: proto.String("000"),
OsVersion: proto.String("0.1.0"), OsVersion: proto.String("0.1.0"),
Manufacturer: proto.String(""), Manufacturer: proto.String(""),
Device: proto.String("Desktop"), Device: proto.String("Desktop"),
OsBuildNumber: proto.String("0.1.0"), OsBuildNumber: proto.String("0.1.0"),
LocaleLanguageIso6391: proto.String("en"), LocaleLanguageIso6391: proto.String("en"),
LocaleCountryIso31661Alpha2: proto.String("en"), LocaleCountryIso31661Alpha2: proto.String("en"),
}, },

View File

@ -1,4 +1,4 @@
// Copyright (c) 2021 Tulir Asokan // Copyright (c) 2022 Tulir Asokan
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this // License, v. 2.0. If a copy of the MPL was not distributed with this
@ -349,15 +349,15 @@ func (s *SQLStore) putAppStateMutationMACs(tx execable, name string, version uin
values[0] = s.JID values[0] = s.JID
values[1] = name values[1] = name
values[2] = version values[2] = version
placeholderSyntax := "($1, $2, $3, $%d, $%d)"
if s.dialect == "sqlite3" {
placeholderSyntax = "(?1, ?2, ?3, ?%d, ?%d)"
}
for i, mutation := range mutations { for i, mutation := range mutations {
baseIndex := 3 + i*2 baseIndex := 3 + i*2
values[baseIndex] = mutation.IndexMAC values[baseIndex] = mutation.IndexMAC
values[baseIndex+1] = mutation.ValueMAC values[baseIndex+1] = mutation.ValueMAC
if s.dialect == "sqlite3" { queryParts[i] = fmt.Sprintf(placeholderSyntax, baseIndex+1, baseIndex+2)
queryParts[i] = fmt.Sprintf("(?1, ?2, ?3, ?%d, ?%d)", baseIndex+1, baseIndex+2)
} else {
queryParts[i] = fmt.Sprintf("($1, $2, $3, $%d, $%d)", baseIndex+1, baseIndex+2)
}
} }
_, err := tx.Exec(putAppStateMutationMACsQuery+strings.Join(queryParts, ","), values...) _, err := tx.Exec(putAppStateMutationMACsQuery+strings.Join(queryParts, ","), values...)
return err return err
@ -426,7 +426,12 @@ func (s *SQLStore) GetAppStateMutationMAC(name string, indexMAC []byte) (valueMA
const ( const (
putContactNameQuery = ` putContactNameQuery = `
INSERT INTO whatsmeow_contacts (our_jid, their_jid, first_name, full_name) VALUES ($1, $2, $3, $4) INSERT INTO whatsmeow_contacts (our_jid, their_jid, first_name, full_name) VALUES ($1, $2, $3, $4)
ON CONFLICT (our_jid, their_jid) DO UPDATE SET first_name=$3, full_name=$4 ON CONFLICT (our_jid, their_jid) DO UPDATE SET first_name=excluded.first_name, full_name=excluded.full_name
`
putManyContactNamesQuery = `
INSERT INTO whatsmeow_contacts (our_jid, their_jid, first_name, full_name)
VALUES %s
ON CONFLICT (our_jid, their_jid) DO UPDATE SET first_name=excluded.first_name, full_name=excluded.full_name
` `
putPushNameQuery = ` putPushNameQuery = `
INSERT INTO whatsmeow_contacts (our_jid, their_jid, push_name) VALUES ($1, $2, $3) INSERT INTO whatsmeow_contacts (our_jid, their_jid, push_name) VALUES ($1, $2, $3)
@ -504,6 +509,77 @@ func (s *SQLStore) PutContactName(user types.JID, firstName, fullName string) er
return nil return nil
} }
const contactBatchSize = 300
func (s *SQLStore) putContactNamesBatch(tx execable, contacts []store.ContactEntry) error {
values := make([]interface{}, 1, 1+len(contacts)*3)
queryParts := make([]string, 0, len(contacts))
values[0] = s.JID
placeholderSyntax := "($1, $%d, $%d, $%d)"
if s.dialect == "sqlite3" {
placeholderSyntax = "(?1, ?%d, ?%d, ?%d)"
}
i := 0
handledContacts := make(map[types.JID]struct{}, len(contacts))
for _, contact := range contacts {
if contact.JID.IsEmpty() {
s.log.Warnf("Empty contact info in mass insert: %+v", contact)
continue
}
// The whole query will break if there are duplicates, so make sure there aren't any duplicates
_, alreadyHandled := handledContacts[contact.JID]
if alreadyHandled {
s.log.Warnf("Duplicate contact info for %s in mass insert", contact.JID)
continue
}
handledContacts[contact.JID] = struct{}{}
baseIndex := i*3 + 1
values = append(values, contact.JID.String(), contact.FirstName, contact.FullName)
queryParts = append(queryParts, fmt.Sprintf(placeholderSyntax, baseIndex+1, baseIndex+2, baseIndex+3))
i++
}
_, err := tx.Exec(fmt.Sprintf(putManyContactNamesQuery, strings.Join(queryParts, ",")), values...)
return err
}
func (s *SQLStore) PutAllContactNames(contacts []store.ContactEntry) error {
if len(contacts) > contactBatchSize {
tx, err := s.db.Begin()
if err != nil {
return fmt.Errorf("failed to start transaction: %w", err)
}
for i := 0; i < len(contacts); i += contactBatchSize {
var contactSlice []store.ContactEntry
if len(contacts) > i+contactBatchSize {
contactSlice = contacts[i : i+contactBatchSize]
} else {
contactSlice = contacts[i:]
}
err = s.putContactNamesBatch(tx, contactSlice)
if err != nil {
_ = tx.Rollback()
return err
}
}
err = tx.Commit()
if err != nil {
return fmt.Errorf("failed to commit transaction: %w", err)
}
} else if len(contacts) > 0 {
err := s.putContactNamesBatch(s.db, contacts)
if err != nil {
return err
}
} else {
return nil
}
s.contactCacheLock.Lock()
// Just clear the cache, fetching pushnames and business names would be too much effort
s.contactCache = make(map[types.JID]*types.ContactInfo)
s.contactCacheLock.Unlock()
return nil
}
func (s *SQLStore) getContact(user types.JID) (*types.ContactInfo, error) { func (s *SQLStore) getContact(user types.JID) (*types.ContactInfo, error) {
cached, ok := s.contactCache[user] cached, ok := s.contactCache[user]
if ok { if ok {

View File

@ -1,4 +1,4 @@
// Copyright (c) 2021 Tulir Asokan // Copyright (c) 2022 Tulir Asokan
// //
// This Source Code Form is subject to the terms of the Mozilla Public // This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this // License, v. 2.0. If a copy of the MPL was not distributed with this
@ -71,10 +71,17 @@ type AppStateStore interface {
GetAppStateMutationMAC(name string, indexMAC []byte) (valueMAC []byte, err error) GetAppStateMutationMAC(name string, indexMAC []byte) (valueMAC []byte, err error)
} }
type ContactEntry struct {
JID types.JID
FirstName string
FullName string
}
type ContactStore interface { type ContactStore interface {
PutPushName(user types.JID, pushName string) (bool, string, error) PutPushName(user types.JID, pushName string) (bool, string, error)
PutBusinessName(user types.JID, businessName string) error PutBusinessName(user types.JID, businessName string) error
PutContactName(user types.JID, fullName, firstName string) error PutContactName(user types.JID, fullName, firstName string) error
PutAllContactNames(contacts []ContactEntry) error
GetContact(user types.JID) (types.ContactInfo, error) GetContact(user types.JID) (types.ContactInfo, error)
GetAllContacts() (map[types.JID]types.ContactInfo, error) GetAllContacts() (map[types.JID]types.ContactInfo, error)
} }

View File

@ -76,6 +76,14 @@ type Archive struct {
Action *waProto.ArchiveChatAction // The current archival status of the chat. Action *waProto.ArchiveChatAction // The current archival status of the chat.
} }
// MarkChatAsRead is emitted when a whole chat is marked as read or unread from another device.
type MarkChatAsRead struct {
JID types.JID // The chat which was marked as read or unread.
Timestamp time.Time // The time when the marking happened.
Action *waProto.MarkChatAsReadAction // Whether the chat was marked as read or unread, and info about the most recent messages.
}
// PushNameSetting is emitted when the user's push name is changed from another device. // PushNameSetting is emitted when the user's push name is changed from another device.
type PushNameSetting struct { type PushNameSetting struct {
Timestamp time.Time // The time when the push name was changed. Timestamp time.Time // The time when the push name was changed.

View File

@ -62,6 +62,8 @@ type LoggedOut struct {
// OnConnect is true if the event was triggered by a connect failure message. // OnConnect is true if the event was triggered by a connect failure message.
// If it's false, the event was triggered by a stream:error message. // If it's false, the event was triggered by a stream:error message.
OnConnect bool OnConnect bool
// If OnConnect is true, then this field contains the reason code.
Reason ConnectFailureReason
} }
// StreamReplaced is emitted when the client is disconnected by another client connecting with the same keys. // StreamReplaced is emitted when the client is disconnected by another client connecting with the same keys.
@ -70,14 +72,96 @@ type LoggedOut struct {
// or otherwise try to connect twice with the same session. // or otherwise try to connect twice with the same session.
type StreamReplaced struct{} type StreamReplaced struct{}
// TempBanReason is an error code included in temp ban error events.
type TempBanReason int
const (
TempBanBlockedByUsers TempBanReason = 101
TempBanSentToTooManyPeople TempBanReason = 102
TempBanCreatedTooManyGroups TempBanReason = 103
TempBanSentTooManySameMessage TempBanReason = 104
TempBanBroadcastList TempBanReason = 106
)
var tempBanReasonMessage = map[TempBanReason]string{
TempBanBlockedByUsers: "too many people blocked you",
TempBanSentToTooManyPeople: "you sent too many messages to people who don't have you in their address books",
TempBanCreatedTooManyGroups: "you created too many groups with people who don't have you in their address books",
TempBanSentTooManySameMessage: "you sent the same message to too many people",
TempBanBroadcastList: "you sent too many messages to a broadcast list",
}
// String returns the reason code and a human-readable description of the ban reason.
func (tbr TempBanReason) String() string {
msg, ok := tempBanReasonMessage[tbr]
if !ok {
msg = "you may have violated the terms of service (unknown error)"
}
return fmt.Sprintf("%d: %s", int(tbr), msg)
}
// TemporaryBan is emitted when there's a connection failure with the ConnectFailureTempBanned reason code.
type TemporaryBan struct {
Code TempBanReason
Expire time.Time
}
func (tb *TemporaryBan) String() string {
if tb.Expire.IsZero() {
return fmt.Sprintf("You've been temporarily banned: %v", tb.Code)
}
return fmt.Sprintf("You've been temporarily banned: %v. The ban expires at %v", tb.Code, tb.Expire)
}
// ConnectFailureReason is an error code included in connection failure events.
type ConnectFailureReason int
const (
ConnectFailureLoggedOut ConnectFailureReason = 401
ConnectFailureTempBanned ConnectFailureReason = 402
ConnectFailureBanned ConnectFailureReason = 403
ConnectFailureUnknownLogout ConnectFailureReason = 406
ConnectFailureClientOutdated ConnectFailureReason = 405
ConnectFailureBadUserAgent ConnectFailureReason = 409
// 400, 500 and 501 are also existing codes, but the meaning is unknown
)
var connectFailureReasonMessage = map[ConnectFailureReason]string{
ConnectFailureLoggedOut: "logged out from another device",
ConnectFailureTempBanned: "account temporarily banned",
ConnectFailureBanned: "account banned from WhatsApp",
ConnectFailureUnknownLogout: "logged out for unknown reason",
ConnectFailureClientOutdated: "client is out of date",
ConnectFailureBadUserAgent: "client user agent was rejected",
}
// IsLoggedOut returns true if the client should delete session data due to this connect failure.
func (cfr ConnectFailureReason) IsLoggedOut() bool {
return cfr == ConnectFailureLoggedOut || cfr == ConnectFailureBanned || cfr == ConnectFailureUnknownLogout
}
// String returns the reason code and a short human-readable description of the error.
func (cfr ConnectFailureReason) String() string {
msg, ok := connectFailureReasonMessage[cfr]
if !ok {
msg = "unknown error"
}
return fmt.Sprintf("%d: %s", int(cfr), msg)
}
// ConnectFailure is emitted when the WhatsApp server sends a <failure> node with an unknown reason. // ConnectFailure is emitted when the WhatsApp server sends a <failure> node with an unknown reason.
// //
// Known reasons are handled internally and emitted as different events (e.g. LoggedOut). // Known reasons are handled internally and emitted as different events (e.g. LoggedOut and TemporaryBan).
type ConnectFailure struct { type ConnectFailure struct {
Reason string Reason ConnectFailureReason
Raw *waBinary.Node Raw *waBinary.Node
} }
// ClientOutdated is emitted when the WhatsApp server rejects the connection with the ConnectFailureClientOutdated code.
type ClientOutdated struct{}
// StreamError is emitted when the WhatsApp server sends a <stream:error> node with an unknown code. // StreamError is emitted when the WhatsApp server sends a <stream:error> node with an unknown code.
// //
// Known codes are handled internally and emitted as different events (e.g. LoggedOut). // Known codes are handled internally and emitted as different events (e.g. LoggedOut).
@ -165,7 +249,8 @@ type Receipt struct {
// client.SendPresence(types.PresenceAvailable) // client.SendPresence(types.PresenceAvailable)
type ChatPresence struct { type ChatPresence struct {
types.MessageSource types.MessageSource
State types.ChatPresence State types.ChatPresence // The current state, either composing or paused
Media types.ChatPresenceMedia // When composing, the type of message
} }
// Presence is emitted when a presence update is received. // Presence is emitted when a presence update is received.
@ -261,3 +346,16 @@ type OfflineSyncPreview struct {
type OfflineSyncCompleted struct { type OfflineSyncCompleted struct {
Count int Count int
} }
// MediaRetry is emitted when the phone sends a response to a media retry request.
type MediaRetry struct {
Ciphertext []byte
IV []byte
Timestamp time.Time // The time of the response.
MessageID types.MessageID // The ID of the message.
ChatID types.JID // The chat ID where the message was sent.
SenderID types.JID // The user who sent the message. Only present in groups.
FromMe bool // Whether the message was sent by the current user or someone else.
}

View File

@ -155,6 +155,21 @@ func (jid JID) String() string {
} }
} }
// MarshalText implements encoding.TextMarshaler for JID
func (jid JID) MarshalText() ([]byte, error) {
return []byte(jid.String()), nil
}
// UnmarshalText implements encoding.TextUnmarshaler for JID
func (jid *JID) UnmarshalText(val []byte) error {
out, err := ParseJID(string(val))
if err != nil {
return err
}
*jid = out
return nil
}
// IsEmpty returns true if the JID has no server (which is required for all JIDs). // IsEmpty returns true if the JID has no server (which is required for all JIDs).
func (jid JID) IsEmpty() bool { func (jid JID) IsEmpty() bool {
return len(jid.Server) == 0 return len(jid.Server) == 0

View File

@ -17,6 +17,12 @@ type ChatPresence string
const ( const (
ChatPresenceComposing ChatPresence = "composing" ChatPresenceComposing ChatPresence = "composing"
ChatPresenceRecording ChatPresence = "recording"
ChatPresencePaused ChatPresence = "paused" ChatPresencePaused ChatPresence = "paused"
) )
type ChatPresenceMedia string
const (
ChatPresenceMediaText ChatPresenceMedia = ""
ChatPresenceMediaAudio ChatPresenceMedia = "audio"
)

81
vendor/go.mau.fi/whatsmeow/update.go vendored Normal file
View File

@ -0,0 +1,81 @@
// Copyright (c) 2022 Tulir Asokan
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package whatsmeow
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.mau.fi/whatsmeow/socket"
"go.mau.fi/whatsmeow/store"
)
// CheckUpdateResponse is the data returned by CheckUpdate.
type CheckUpdateResponse struct {
IsBroken bool
IsBelowSoft bool
IsBelowHard bool
CurrentVersion string
ParsedVersion store.WAVersionContainer `json:"-"`
}
// CheckUpdateURL is the base URL to check for WhatsApp web updates.
const CheckUpdateURL = "https://web.whatsapp.com/check-update"
// CheckUpdate asks the WhatsApp servers if there is an update available
// (using the HTTP client and proxy settings of this whatsmeow Client instance).
func (cli *Client) CheckUpdate() (respData CheckUpdateResponse, err error) {
return CheckUpdate(http.DefaultClient)
}
// CheckUpdate asks the WhatsApp servers if there is an update available.
func CheckUpdate(httpClient *http.Client) (respData CheckUpdateResponse, err error) {
var reqURL *url.URL
reqURL, err = url.Parse(CheckUpdateURL)
if err != nil {
err = fmt.Errorf("failed to parse check update URL: %w", err)
return
}
q := reqURL.Query()
q.Set("version", store.GetWAVersion().String())
q.Set("platform", "web")
reqURL.RawQuery = q.Encode()
var req *http.Request
req, err = http.NewRequest(http.MethodGet, reqURL.String(), nil)
if err != nil {
err = fmt.Errorf("failed to prepare request: %w", err)
return
}
req.Header.Set("Origin", socket.Origin)
req.Header.Set("Referer", socket.Origin+"/")
var resp *http.Response
resp, err = httpClient.Do(req)
if err != nil {
err = fmt.Errorf("failed to send request: %w", err)
return
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
body, _ := io.ReadAll(resp.Body)
err = fmt.Errorf("unexpected response with status %d: %s", resp.StatusCode, body)
return
}
err = json.NewDecoder(resp.Body).Decode(&respData)
if err != nil {
err = fmt.Errorf("failed to decode response body (status %d): %w", resp.StatusCode, err)
return
}
respData.ParsedVersion, err = store.ParseVersion(respData.CurrentVersion)
if err != nil {
err = fmt.Errorf("failed to parse version string: %w", err)
}
return
}

View File

@ -24,16 +24,41 @@ import (
// UploadResponse contains the data from the attachment upload, which can be put into a message to send the attachment. // UploadResponse contains the data from the attachment upload, which can be put into a message to send the attachment.
type UploadResponse struct { type UploadResponse struct {
URL string URL string `json:"url"`
DirectPath string DirectPath string `json:"direct_path"`
MediaKey []byte MediaKey []byte `json:"-"`
FileEncSHA256 []byte FileEncSHA256 []byte `json:"-"`
FileSHA256 []byte FileSHA256 []byte `json:"-"`
FileLength uint64 FileLength uint64 `json:"-"`
} }
// Upload uploads the given attachment to WhatsApp servers. // Upload uploads the given attachment to WhatsApp servers.
//
// You should copy the fields in the response to the corresponding fields in a protobuf message.
//
// For example, to send an image:
// resp, err := cli.Upload(context.Background(), yourImageBytes, whatsmeow.MediaImage)
// // handle error
//
// imageMsg := &waProto.ImageMessage{
// Caption: proto.String("Hello, world!"),
// Mimetype: proto.String("image/png"), // replace this with the actual mime type
// // you can also optionally add other fields like ContextInfo and JpegThumbnail here
//
// Url: &resp.URL,
// DirectPath: &uploaded.DirectPath,
// MediaKey: resp.MediaKey,
// FileEncSha256: resp.FileEncSHA256,
// FileSha256: resp.FileSha256,
// FileLength: &resp.FileLength,
// }
// _, err = cli.SendMessage(targetJID, "", &waProto.Message{
// ImageMessage: imageMsg,
// })
// // handle error again
//
// The same applies to the other message types like DocumentMessage, just replace the struct type and Message field name.
func (cli *Client) Upload(ctx context.Context, plaintext []byte, appInfo MediaType) (resp UploadResponse, err error) { func (cli *Client) Upload(ctx context.Context, plaintext []byte, appInfo MediaType) (resp UploadResponse, err error) {
resp.FileLength = uint64(len(plaintext)) resp.FileLength = uint64(len(plaintext))
resp.MediaKey = make([]byte, 32) resp.MediaKey = make([]byte, 32)
@ -92,7 +117,7 @@ func (cli *Client) Upload(ctx context.Context, plaintext []byte, appInfo MediaTy
req.Header.Set("Referer", socket.Origin+"/") req.Header.Set("Referer", socket.Origin+"/")
var httpResp *http.Response var httpResp *http.Response
httpResp, err = http.DefaultClient.Do(req) httpResp, err = cli.http.Do(req)
if err != nil { if err != nil {
err = fmt.Errorf("failed to execute request: %w", err) err = fmt.Errorf("failed to execute request: %w", err)
} else if httpResp.StatusCode != http.StatusOK { } else if httpResp.StatusCode != http.StatusOK {

View File

@ -3,17 +3,20 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Package acme provides an implementation of the // Package acme provides an implementation of the
// Automatic Certificate Management Environment (ACME) spec. // Automatic Certificate Management Environment (ACME) spec,
// The initial implementation was based on ACME draft-02 and // most famously used by Let's Encrypt.
// is now being extended to comply with RFC 8555. //
// See https://tools.ietf.org/html/draft-ietf-acme-acme-02 // The initial implementation of this package was based on an early version
// and https://tools.ietf.org/html/rfc8555 for details. // of the spec. The current implementation supports only the modern
// RFC 8555 but some of the old API surface remains for compatibility.
// While code using the old API will still compile, it will return an error.
// Note the deprecation comments to update your code.
//
// See https://tools.ietf.org/html/rfc8555 for the spec.
// //
// Most common scenarios will want to use autocert subdirectory instead, // Most common scenarios will want to use autocert subdirectory instead,
// which provides automatic access to certificates from Let's Encrypt // which provides automatic access to certificates from Let's Encrypt
// and any other ACME-based CA. // and any other ACME-based CA.
//
// This package is a work in progress and makes no API stability promises.
package acme package acme
import ( import (
@ -33,8 +36,6 @@ import (
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt" "fmt"
"io"
"io/ioutil"
"math/big" "math/big"
"net/http" "net/http"
"strings" "strings"
@ -72,6 +73,7 @@ const (
) )
// Client is an ACME client. // Client is an ACME client.
//
// The only required field is Key. An example of creating a client with a new key // The only required field is Key. An example of creating a client with a new key
// is as follows: // is as follows:
// //
@ -125,7 +127,9 @@ type Client struct {
cacheMu sync.Mutex cacheMu sync.Mutex
dir *Directory // cached result of Client's Discover method dir *Directory // cached result of Client's Discover method
kid keyID // cached Account.URI obtained from registerRFC or getAccountRFC // KID is the key identifier provided by the CA. If not provided it will be
// retrieved from the CA by making a call to the registration endpoint.
KID KeyID
noncesMu sync.Mutex noncesMu sync.Mutex
nonces map[string]struct{} // nonces collected from previous responses nonces map[string]struct{} // nonces collected from previous responses
@ -140,23 +144,22 @@ type Client struct {
// //
// When in pre-RFC mode or when c.getRegRFC responds with an error, accountKID // When in pre-RFC mode or when c.getRegRFC responds with an error, accountKID
// returns noKeyID. // returns noKeyID.
func (c *Client) accountKID(ctx context.Context) keyID { func (c *Client) accountKID(ctx context.Context) KeyID {
c.cacheMu.Lock() c.cacheMu.Lock()
defer c.cacheMu.Unlock() defer c.cacheMu.Unlock()
if !c.dir.rfcCompliant() { if c.KID != noKeyID {
return noKeyID return c.KID
}
if c.kid != noKeyID {
return c.kid
} }
a, err := c.getRegRFC(ctx) a, err := c.getRegRFC(ctx)
if err != nil { if err != nil {
return noKeyID return noKeyID
} }
c.kid = keyID(a.URI) c.KID = KeyID(a.URI)
return c.kid return c.KID
} }
var errPreRFC = errors.New("acme: server does not support the RFC 8555 version of ACME")
// Discover performs ACME server discovery using c.DirectoryURL. // Discover performs ACME server discovery using c.DirectoryURL.
// //
// It caches successful result. So, subsequent calls will not result in // It caches successful result. So, subsequent calls will not result in
@ -177,53 +180,36 @@ func (c *Client) Discover(ctx context.Context) (Directory, error) {
c.addNonce(res.Header) c.addNonce(res.Header)
var v struct { var v struct {
Reg string `json:"new-reg"` Reg string `json:"newAccount"`
RegRFC string `json:"newAccount"` Authz string `json:"newAuthz"`
Authz string `json:"new-authz"` Order string `json:"newOrder"`
AuthzRFC string `json:"newAuthz"` Revoke string `json:"revokeCert"`
OrderRFC string `json:"newOrder"` Nonce string `json:"newNonce"`
Cert string `json:"new-cert"` KeyChange string `json:"keyChange"`
Revoke string `json:"revoke-cert"`
RevokeRFC string `json:"revokeCert"`
NonceRFC string `json:"newNonce"`
KeyChangeRFC string `json:"keyChange"`
Meta struct { Meta struct {
Terms string `json:"terms-of-service"` Terms string `json:"termsOfService"`
TermsRFC string `json:"termsOfService"` Website string `json:"website"`
WebsiteRFC string `json:"website"` CAA []string `json:"caaIdentities"`
CAA []string `json:"caa-identities"` ExternalAcct bool `json:"externalAccountRequired"`
CAARFC []string `json:"caaIdentities"`
ExternalAcctRFC bool `json:"externalAccountRequired"`
} }
} }
if err := json.NewDecoder(res.Body).Decode(&v); err != nil { if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return Directory{}, err return Directory{}, err
} }
if v.OrderRFC == "" { if v.Order == "" {
// Non-RFC compliant ACME CA. return Directory{}, errPreRFC
}
c.dir = &Directory{ c.dir = &Directory{
RegURL: v.Reg, RegURL: v.Reg,
AuthzURL: v.Authz, AuthzURL: v.Authz,
CertURL: v.Cert, OrderURL: v.Order,
RevokeURL: v.Revoke, RevokeURL: v.Revoke,
NonceURL: v.Nonce,
KeyChangeURL: v.KeyChange,
Terms: v.Meta.Terms, Terms: v.Meta.Terms,
Website: v.Meta.WebsiteRFC, Website: v.Meta.Website,
CAA: v.Meta.CAA, CAA: v.Meta.CAA,
} ExternalAccountRequired: v.Meta.ExternalAcct,
return *c.dir, nil
}
// RFC compliant ACME CA.
c.dir = &Directory{
RegURL: v.RegRFC,
AuthzURL: v.AuthzRFC,
OrderURL: v.OrderRFC,
RevokeURL: v.RevokeRFC,
NonceURL: v.NonceRFC,
KeyChangeURL: v.KeyChangeRFC,
Terms: v.Meta.TermsRFC,
Website: v.Meta.WebsiteRFC,
CAA: v.Meta.CAARFC,
ExternalAccountRequired: v.Meta.ExternalAcctRFC,
} }
return *c.dir, nil return *c.dir, nil
} }
@ -235,55 +221,11 @@ func (c *Client) directoryURL() string {
return LetsEncryptURL return LetsEncryptURL
} }
// CreateCert requests a new certificate using the Certificate Signing Request csr encoded in DER format. // CreateCert was part of the old version of ACME. It is incompatible with RFC 8555.
// It is incompatible with RFC 8555. Callers should use CreateOrderCert when interfacing
// with an RFC-compliant CA.
// //
// The exp argument indicates the desired certificate validity duration. CA may issue a certificate // Deprecated: this was for the pre-RFC 8555 version of ACME. Callers should use CreateOrderCert.
// with a different duration.
// If the bundle argument is true, the returned value will also contain the CA (issuer) certificate chain.
//
// In the case where CA server does not provide the issued certificate in the response,
// CreateCert will poll certURL using c.FetchCert, which will result in additional round-trips.
// In such a scenario, the caller can cancel the polling with ctx.
//
// CreateCert returns an error if the CA's response or chain was unreasonably large.
// Callers are encouraged to parse the returned value to ensure the certificate is valid and has the expected features.
func (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration, bundle bool) (der [][]byte, certURL string, err error) { func (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration, bundle bool) (der [][]byte, certURL string, err error) {
if _, err := c.Discover(ctx); err != nil { return nil, "", errPreRFC
return nil, "", err
}
req := struct {
Resource string `json:"resource"`
CSR string `json:"csr"`
NotBefore string `json:"notBefore,omitempty"`
NotAfter string `json:"notAfter,omitempty"`
}{
Resource: "new-cert",
CSR: base64.RawURLEncoding.EncodeToString(csr),
}
now := timeNow()
req.NotBefore = now.Format(time.RFC3339)
if exp > 0 {
req.NotAfter = now.Add(exp).Format(time.RFC3339)
}
res, err := c.post(ctx, nil, c.dir.CertURL, req, wantStatus(http.StatusCreated))
if err != nil {
return nil, "", err
}
defer res.Body.Close()
curl := res.Header.Get("Location") // cert permanent URL
if res.ContentLength == 0 {
// no cert in the body; poll until we get it
cert, err := c.FetchCert(ctx, curl, bundle)
return cert, curl, err
}
// slurp issued cert and CA chain, if requested
cert, err := c.responseCert(ctx, res, bundle)
return cert, curl, err
} }
// FetchCert retrieves already issued certificate from the given url, in DER format. // FetchCert retrieves already issued certificate from the given url, in DER format.
@ -297,20 +239,10 @@ func (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration,
// Callers are encouraged to parse the returned value to ensure the certificate is valid // Callers are encouraged to parse the returned value to ensure the certificate is valid
// and has expected features. // and has expected features.
func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) { func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) {
dir, err := c.Discover(ctx) if _, err := c.Discover(ctx); err != nil {
if err != nil {
return nil, err return nil, err
} }
if dir.rfcCompliant() {
return c.fetchCertRFC(ctx, url, bundle) return c.fetchCertRFC(ctx, url, bundle)
}
// Legacy non-authenticated GET request.
res, err := c.get(ctx, url, wantStatus(http.StatusOK))
if err != nil {
return nil, err
}
return c.responseCert(ctx, res, bundle)
} }
// RevokeCert revokes a previously issued certificate cert, provided in DER format. // RevokeCert revokes a previously issued certificate cert, provided in DER format.
@ -320,30 +252,10 @@ func (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]by
// For instance, the key pair of the certificate may be authorized. // For instance, the key pair of the certificate may be authorized.
// If the key is nil, c.Key is used instead. // If the key is nil, c.Key is used instead.
func (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte, reason CRLReasonCode) error { func (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte, reason CRLReasonCode) error {
dir, err := c.Discover(ctx) if _, err := c.Discover(ctx); err != nil {
if err != nil {
return err return err
} }
if dir.rfcCompliant() {
return c.revokeCertRFC(ctx, key, cert, reason) return c.revokeCertRFC(ctx, key, cert, reason)
}
// Legacy CA.
body := &struct {
Resource string `json:"resource"`
Cert string `json:"certificate"`
Reason int `json:"reason"`
}{
Resource: "revoke-cert",
Cert: base64.RawURLEncoding.EncodeToString(cert),
Reason: int(reason),
}
res, err := c.post(ctx, key, dir.RevokeURL, body, wantStatus(http.StatusOK))
if err != nil {
return err
}
defer res.Body.Close()
return nil
} }
// AcceptTOS always returns true to indicate the acceptance of a CA's Terms of Service // AcceptTOS always returns true to indicate the acceptance of a CA's Terms of Service
@ -366,75 +278,33 @@ func (c *Client) Register(ctx context.Context, acct *Account, prompt func(tosURL
if c.Key == nil { if c.Key == nil {
return nil, errors.New("acme: client.Key must be set to Register") return nil, errors.New("acme: client.Key must be set to Register")
} }
if _, err := c.Discover(ctx); err != nil {
dir, err := c.Discover(ctx)
if err != nil {
return nil, err return nil, err
} }
if dir.rfcCompliant() {
return c.registerRFC(ctx, acct, prompt) return c.registerRFC(ctx, acct, prompt)
}
// Legacy ACME draft registration flow.
a, err := c.doReg(ctx, dir.RegURL, "new-reg", acct)
if err != nil {
return nil, err
}
var accept bool
if a.CurrentTerms != "" && a.CurrentTerms != a.AgreedTerms {
accept = prompt(a.CurrentTerms)
}
if accept {
a.AgreedTerms = a.CurrentTerms
a, err = c.UpdateReg(ctx, a)
}
return a, err
} }
// GetReg retrieves an existing account associated with c.Key. // GetReg retrieves an existing account associated with c.Key.
// //
// The url argument is an Account URI used with pre-RFC 8555 CAs. // The url argument is a legacy artifact of the pre-RFC 8555 API
// It is ignored when interfacing with an RFC-compliant CA. // and is ignored.
func (c *Client) GetReg(ctx context.Context, url string) (*Account, error) { func (c *Client) GetReg(ctx context.Context, url string) (*Account, error) {
dir, err := c.Discover(ctx) if _, err := c.Discover(ctx); err != nil {
if err != nil {
return nil, err return nil, err
} }
if dir.rfcCompliant() {
return c.getRegRFC(ctx) return c.getRegRFC(ctx)
}
// Legacy CA.
a, err := c.doReg(ctx, url, "reg", nil)
if err != nil {
return nil, err
}
a.URI = url
return a, nil
} }
// UpdateReg updates an existing registration. // UpdateReg updates an existing registration.
// It returns an updated account copy. The provided account is not modified. // It returns an updated account copy. The provided account is not modified.
// //
// When interfacing with RFC-compliant CAs, a.URI is ignored and the account URL // The account's URI is ignored and the account URL associated with
// associated with c.Key is used instead. // c.Key is used instead.
func (c *Client) UpdateReg(ctx context.Context, acct *Account) (*Account, error) { func (c *Client) UpdateReg(ctx context.Context, acct *Account) (*Account, error) {
dir, err := c.Discover(ctx) if _, err := c.Discover(ctx); err != nil {
if err != nil {
return nil, err return nil, err
} }
if dir.rfcCompliant() {
return c.updateRegRFC(ctx, acct) return c.updateRegRFC(ctx, acct)
}
// Legacy CA.
uri := acct.URI
a, err := c.doReg(ctx, uri, "reg", acct)
if err != nil {
return nil, err
}
a.URI = uri
return a, nil
} }
// Authorize performs the initial step in the pre-authorization flow, // Authorize performs the initial step in the pre-authorization flow,
@ -503,17 +373,11 @@ func (c *Client) authorize(ctx context.Context, typ, val string) (*Authorization
// If a caller needs to poll an authorization until its status is final, // If a caller needs to poll an authorization until its status is final,
// see the WaitAuthorization method. // see the WaitAuthorization method.
func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorization, error) { func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorization, error) {
dir, err := c.Discover(ctx) if _, err := c.Discover(ctx); err != nil {
if err != nil {
return nil, err return nil, err
} }
var res *http.Response res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))
if dir.rfcCompliant() {
res, err = c.postAsGet(ctx, url, wantStatus(http.StatusOK))
} else {
res, err = c.get(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -535,7 +399,6 @@ func (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorizati
// //
// It does not revoke existing certificates. // It does not revoke existing certificates.
func (c *Client) RevokeAuthorization(ctx context.Context, url string) error { func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
// Required for c.accountKID() when in RFC mode.
if _, err := c.Discover(ctx); err != nil { if _, err := c.Discover(ctx); err != nil {
return err return err
} }
@ -565,18 +428,11 @@ func (c *Client) RevokeAuthorization(ctx context.Context, url string) error {
// In all other cases WaitAuthorization returns an error. // In all other cases WaitAuthorization returns an error.
// If the Status is StatusInvalid, the returned error is of type *AuthorizationError. // If the Status is StatusInvalid, the returned error is of type *AuthorizationError.
func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorization, error) { func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorization, error) {
// Required for c.accountKID() when in RFC mode. if _, err := c.Discover(ctx); err != nil {
dir, err := c.Discover(ctx)
if err != nil {
return nil, err return nil, err
} }
getfn := c.postAsGet
if !dir.rfcCompliant() {
getfn = c.get
}
for { for {
res, err := getfn(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted)) res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -619,17 +475,11 @@ func (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorizat
// //
// A client typically polls a challenge status using this method. // A client typically polls a challenge status using this method.
func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, error) { func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, error) {
// Required for c.accountKID() when in RFC mode. if _, err := c.Discover(ctx); err != nil {
dir, err := c.Discover(ctx)
if err != nil {
return nil, err return nil, err
} }
getfn := c.postAsGet res, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
if !dir.rfcCompliant() {
getfn = c.get
}
res, err := getfn(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -647,29 +497,11 @@ func (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, erro
// //
// The server will then perform the validation asynchronously. // The server will then perform the validation asynchronously.
func (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error) { func (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error) {
// Required for c.accountKID() when in RFC mode. if _, err := c.Discover(ctx); err != nil {
dir, err := c.Discover(ctx)
if err != nil {
return nil, err return nil, err
} }
var req interface{} = json.RawMessage("{}") // RFC-compliant CA res, err := c.post(ctx, nil, chal.URI, json.RawMessage("{}"), wantStatus(
if !dir.rfcCompliant() {
auth, err := keyAuth(c.Key.Public(), chal.Token)
if err != nil {
return nil, err
}
req = struct {
Resource string `json:"resource"`
Type string `json:"type"`
Auth string `json:"keyAuthorization"`
}{
Resource: "challenge",
Type: chal.Type,
Auth: auth,
}
}
res, err := c.post(ctx, nil, chal.URI, req, wantStatus(
http.StatusOK, // according to the spec http.StatusOK, // according to the spec
http.StatusAccepted, // Let's Encrypt: see https://goo.gl/WsJ7VT (acme-divergences.md) http.StatusAccepted, // Let's Encrypt: see https://goo.gl/WsJ7VT (acme-divergences.md)
)) ))
@ -720,7 +552,7 @@ func (c *Client) HTTP01ChallengePath(token string) string {
// TLSSNI01ChallengeCert creates a certificate for TLS-SNI-01 challenge response. // TLSSNI01ChallengeCert creates a certificate for TLS-SNI-01 challenge response.
// //
// Deprecated: This challenge type is unused in both draft-02 and RFC versions of ACME spec. // Deprecated: This challenge type is unused in both draft-02 and RFC versions of the ACME spec.
func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) { func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
ka, err := keyAuth(c.Key.Public(), token) ka, err := keyAuth(c.Key.Public(), token)
if err != nil { if err != nil {
@ -738,7 +570,7 @@ func (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (cert tl
// TLSSNI02ChallengeCert creates a certificate for TLS-SNI-02 challenge response. // TLSSNI02ChallengeCert creates a certificate for TLS-SNI-02 challenge response.
// //
// Deprecated: This challenge type is unused in both draft-02 and RFC versions of ACME spec. // Deprecated: This challenge type is unused in both draft-02 and RFC versions of the ACME spec.
func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) { func (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (cert tls.Certificate, name string, err error) {
b := sha256.Sum256([]byte(token)) b := sha256.Sum256([]byte(token))
h := hex.EncodeToString(b[:]) h := hex.EncodeToString(b[:])
@ -805,63 +637,6 @@ func (c *Client) TLSALPN01ChallengeCert(token, domain string, opt ...CertOption)
return tlsChallengeCert([]string{domain}, newOpt) return tlsChallengeCert([]string{domain}, newOpt)
} }
// doReg sends all types of registration requests the old way (pre-RFC world).
// The type of request is identified by typ argument, which is a "resource"
// in the ACME spec terms.
//
// A non-nil acct argument indicates whether the intention is to mutate data
// of the Account. Only Contact and Agreement of its fields are used
// in such cases.
func (c *Client) doReg(ctx context.Context, url string, typ string, acct *Account) (*Account, error) {
req := struct {
Resource string `json:"resource"`
Contact []string `json:"contact,omitempty"`
Agreement string `json:"agreement,omitempty"`
}{
Resource: typ,
}
if acct != nil {
req.Contact = acct.Contact
req.Agreement = acct.AgreedTerms
}
res, err := c.post(ctx, nil, url, req, wantStatus(
http.StatusOK, // updates and deletes
http.StatusCreated, // new account creation
http.StatusAccepted, // Let's Encrypt divergent implementation
))
if err != nil {
return nil, err
}
defer res.Body.Close()
var v struct {
Contact []string
Agreement string
Authorizations string
Certificates string
}
if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
return nil, fmt.Errorf("acme: invalid response: %v", err)
}
var tos string
if v := linkHeader(res.Header, "terms-of-service"); len(v) > 0 {
tos = v[0]
}
var authz string
if v := linkHeader(res.Header, "next"); len(v) > 0 {
authz = v[0]
}
return &Account{
URI: res.Header.Get("Location"),
Contact: v.Contact,
AgreedTerms: v.Agreement,
CurrentTerms: tos,
Authz: authz,
Authorizations: v.Authorizations,
Certificates: v.Certificates,
}, nil
}
// popNonce returns a nonce value previously stored with c.addNonce // popNonce returns a nonce value previously stored with c.addNonce
// or fetches a fresh one from c.dir.NonceURL. // or fetches a fresh one from c.dir.NonceURL.
// If NonceURL is empty, it first tries c.directoryURL() and, failing that, // If NonceURL is empty, it first tries c.directoryURL() and, failing that,
@ -936,78 +711,6 @@ func nonceFromHeader(h http.Header) string {
return h.Get("Replay-Nonce") return h.Get("Replay-Nonce")
} }
func (c *Client) responseCert(ctx context.Context, res *http.Response, bundle bool) ([][]byte, error) {
b, err := ioutil.ReadAll(io.LimitReader(res.Body, maxCertSize+1))
if err != nil {
return nil, fmt.Errorf("acme: response stream: %v", err)
}
if len(b) > maxCertSize {
return nil, errors.New("acme: certificate is too big")
}
cert := [][]byte{b}
if !bundle {
return cert, nil
}
// Append CA chain cert(s).
// At least one is required according to the spec:
// https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-6.3.1
up := linkHeader(res.Header, "up")
if len(up) == 0 {
return nil, errors.New("acme: rel=up link not found")
}
if len(up) > maxChainLen {
return nil, errors.New("acme: rel=up link is too large")
}
for _, url := range up {
cc, err := c.chainCert(ctx, url, 0)
if err != nil {
return nil, err
}
cert = append(cert, cc...)
}
return cert, nil
}
// chainCert fetches CA certificate chain recursively by following "up" links.
// Each recursive call increments the depth by 1, resulting in an error
// if the recursion level reaches maxChainLen.
//
// First chainCert call starts with depth of 0.
func (c *Client) chainCert(ctx context.Context, url string, depth int) ([][]byte, error) {
if depth >= maxChainLen {
return nil, errors.New("acme: certificate chain is too deep")
}
res, err := c.get(ctx, url, wantStatus(http.StatusOK))
if err != nil {
return nil, err
}
defer res.Body.Close()
b, err := ioutil.ReadAll(io.LimitReader(res.Body, maxCertSize+1))
if err != nil {
return nil, err
}
if len(b) > maxCertSize {
return nil, errors.New("acme: certificate is too big")
}
chain := [][]byte{b}
uplink := linkHeader(res.Header, "up")
if len(uplink) > maxChainLen {
return nil, errors.New("acme: certificate chain is too large")
}
for _, up := range uplink {
cc, err := c.chainCert(ctx, up, depth+1)
if err != nil {
return nil, err
}
chain = append(chain, cc...)
}
return chain, nil
}
// linkHeader returns URI-Reference values of all Link headers // linkHeader returns URI-Reference values of all Link headers
// with relation-type rel. // with relation-type rel.
// See https://tools.ietf.org/html/rfc5988#section-5 for details. // See https://tools.ietf.org/html/rfc5988#section-5 for details.
@ -1098,5 +801,5 @@ func encodePEM(typ string, b []byte) []byte {
return pem.EncodeToMemory(pb) return pem.EncodeToMemory(pb)
} }
// timeNow is useful for testing for fixed current time. // timeNow is time.Now, except in tests which can mess with it.
var timeNow = time.Now var timeNow = time.Now

View File

@ -47,6 +47,8 @@ var createCertRetryAfter = time.Minute
// pseudoRand is safe for concurrent use. // pseudoRand is safe for concurrent use.
var pseudoRand *lockedMathRand var pseudoRand *lockedMathRand
var errPreRFC = errors.New("autocert: ACME server doesn't support RFC 8555")
func init() { func init() {
src := mathrand.NewSource(time.Now().UnixNano()) src := mathrand.NewSource(time.Now().UnixNano())
pseudoRand = &lockedMathRand{rnd: mathrand.New(src)} pseudoRand = &lockedMathRand{rnd: mathrand.New(src)}
@ -456,7 +458,7 @@ func (m *Manager) cert(ctx context.Context, ck certKey) (*tls.Certificate, error
leaf: cert.Leaf, leaf: cert.Leaf,
} }
m.state[ck] = s m.state[ck] = s
go m.renew(ck, s.key, s.leaf.NotAfter) go m.startRenew(ck, s.key, s.leaf.NotAfter)
return cert, nil return cert, nil
} }
@ -582,8 +584,9 @@ func (m *Manager) createCert(ctx context.Context, ck certKey) (*tls.Certificate,
if err != nil { if err != nil {
// Remove the failed state after some time, // Remove the failed state after some time,
// making the manager call createCert again on the following TLS hello. // making the manager call createCert again on the following TLS hello.
didRemove := testDidRemoveState // The lifetime of this timer is untracked, so copy mutable local state to avoid races.
time.AfterFunc(createCertRetryAfter, func() { time.AfterFunc(createCertRetryAfter, func() {
defer testDidRemoveState(ck) defer didRemove(ck)
m.stateMu.Lock() m.stateMu.Lock()
defer m.stateMu.Unlock() defer m.stateMu.Unlock()
// Verify the state hasn't changed and it's still invalid // Verify the state hasn't changed and it's still invalid
@ -601,7 +604,7 @@ func (m *Manager) createCert(ctx context.Context, ck certKey) (*tls.Certificate,
} }
state.cert = der state.cert = der
state.leaf = leaf state.leaf = leaf
go m.renew(ck, state.key, state.leaf.NotAfter) go m.startRenew(ck, state.key, state.leaf.NotAfter)
return state.tlscert() return state.tlscert()
} }
@ -658,31 +661,19 @@ func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, ck cert
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
if dir.OrderURL == "" {
return nil, nil, errPreRFC
}
var chain [][]byte
switch {
// Pre-RFC legacy CA.
case dir.OrderURL == "":
if err := m.verify(ctx, client, ck.domain); err != nil {
return nil, nil, err
}
der, _, err := client.CreateCert(ctx, csr, 0, true)
if err != nil {
return nil, nil, err
}
chain = der
// RFC 8555 compliant CA.
default:
o, err := m.verifyRFC(ctx, client, ck.domain) o, err := m.verifyRFC(ctx, client, ck.domain)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
der, _, err := client.CreateOrderCert(ctx, o.FinalizeURL, csr, true) chain, _, err := client.CreateOrderCert(ctx, o.FinalizeURL, csr, true)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
chain = der
}
leaf, err = validCert(ck, chain, key, m.now()) leaf, err = validCert(ck, chain, key, m.now())
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -690,69 +681,6 @@ func (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, ck cert
return chain, leaf, nil return chain, leaf, nil
} }
// verify runs the identifier (domain) pre-authorization flow for legacy CAs
// using each applicable ACME challenge type.
func (m *Manager) verify(ctx context.Context, client *acme.Client, domain string) error {
// Remove all hanging authorizations to reduce rate limit quotas
// after we're done.
var authzURLs []string
defer func() {
go m.deactivatePendingAuthz(authzURLs)
}()
// errs accumulates challenge failure errors, printed if all fail
errs := make(map[*acme.Challenge]error)
challengeTypes := m.supportedChallengeTypes()
var nextTyp int // challengeType index of the next challenge type to try
for {
// Start domain authorization and get the challenge.
authz, err := client.Authorize(ctx, domain)
if err != nil {
return err
}
authzURLs = append(authzURLs, authz.URI)
// No point in accepting challenges if the authorization status
// is in a final state.
switch authz.Status {
case acme.StatusValid:
return nil // already authorized
case acme.StatusInvalid:
return fmt.Errorf("acme/autocert: invalid authorization %q", authz.URI)
}
// Pick the next preferred challenge.
var chal *acme.Challenge
for chal == nil && nextTyp < len(challengeTypes) {
chal = pickChallenge(challengeTypes[nextTyp], authz.Challenges)
nextTyp++
}
if chal == nil {
errorMsg := fmt.Sprintf("acme/autocert: unable to authorize %q", domain)
for chal, err := range errs {
errorMsg += fmt.Sprintf("; challenge %q failed with error: %v", chal.Type, err)
}
return errors.New(errorMsg)
}
cleanup, err := m.fulfill(ctx, client, chal, domain)
if err != nil {
errs[chal] = err
continue
}
defer cleanup()
if _, err := client.Accept(ctx, chal); err != nil {
errs[chal] = err
continue
}
// A challenge is fulfilled and accepted: wait for the CA to validate.
if _, err := client.WaitAuthorization(ctx, authz.URI); err != nil {
errs[chal] = err
continue
}
return nil
}
}
// verifyRFC runs the identifier (domain) order-based authorization flow for RFC compliant CAs // verifyRFC runs the identifier (domain) order-based authorization flow for RFC compliant CAs
// using each applicable ACME challenge type. // using each applicable ACME challenge type.
func (m *Manager) verifyRFC(ctx context.Context, client *acme.Client, domain string) (*acme.Order, error) { func (m *Manager) verifyRFC(ctx context.Context, client *acme.Client, domain string) (*acme.Order, error) {
@ -966,7 +894,7 @@ func httpTokenCacheKey(tokenPath string) string {
return path.Base(tokenPath) + "+http-01" return path.Base(tokenPath) + "+http-01"
} }
// renew starts a cert renewal timer loop, one per domain. // startRenew starts a cert renewal timer loop, one per domain.
// //
// The loop is scheduled in two cases: // The loop is scheduled in two cases:
// - a cert was fetched from cache for the first time (wasn't in m.state) // - a cert was fetched from cache for the first time (wasn't in m.state)
@ -974,7 +902,7 @@ func httpTokenCacheKey(tokenPath string) string {
// //
// The key argument is a certificate private key. // The key argument is a certificate private key.
// The exp argument is the cert expiration time (NotAfter). // The exp argument is the cert expiration time (NotAfter).
func (m *Manager) renew(ck certKey, key crypto.Signer, exp time.Time) { func (m *Manager) startRenew(ck certKey, key crypto.Signer, exp time.Time) {
m.renewalMu.Lock() m.renewalMu.Lock()
defer m.renewalMu.Unlock() defer m.renewalMu.Unlock()
if m.renewal[ck] != nil { if m.renewal[ck] != nil {
@ -1200,6 +1128,10 @@ func validCert(ck certKey, der [][]byte, key crypto.Signer, now time.Time) (leaf
if err := leaf.VerifyHostname(ck.domain); err != nil { if err := leaf.VerifyHostname(ck.domain); err != nil {
return nil, err return nil, err
} }
// renew certificates revoked by Let's Encrypt in January 2022
if isRevokedLetsEncrypt(leaf) {
return nil, errors.New("acme/autocert: certificate was probably revoked by Let's Encrypt")
}
// ensure the leaf corresponds to the private key and matches the certKey type // ensure the leaf corresponds to the private key and matches the certKey type
switch pub := leaf.PublicKey.(type) { switch pub := leaf.PublicKey.(type) {
case *rsa.PublicKey: case *rsa.PublicKey:
@ -1230,6 +1162,18 @@ func validCert(ck certKey, der [][]byte, key crypto.Signer, now time.Time) (leaf
return leaf, nil return leaf, nil
} }
// https://community.letsencrypt.org/t/2022-01-25-issue-with-tls-alpn-01-validation-method/170450
var letsEncryptFixDeployTime = time.Date(2022, time.January, 26, 00, 48, 0, 0, time.UTC)
// isRevokedLetsEncrypt returns whether the certificate is likely to be part of
// a batch of certificates revoked by Let's Encrypt in January 2022. This check
// can be safely removed from May 2022.
func isRevokedLetsEncrypt(cert *x509.Certificate) bool {
O := cert.Issuer.Organization
return len(O) == 1 && O[0] == "Let's Encrypt" &&
cert.NotBefore.Before(letsEncryptFixDeployTime)
}
type lockedMathRand struct { type lockedMathRand struct {
sync.Mutex sync.Mutex
rnd *mathrand.Rand rnd *mathrand.Rand

View File

@ -23,6 +23,7 @@ type domainRenewal struct {
timerMu sync.Mutex timerMu sync.Mutex
timer *time.Timer timer *time.Timer
timerClose chan struct{} // if non-nil, renew closes this channel (and nils out the timer fields) instead of running
} }
// start starts a cert renewal timer at the time // start starts a cert renewal timer at the time
@ -38,16 +39,28 @@ func (dr *domainRenewal) start(exp time.Time) {
dr.timer = time.AfterFunc(dr.next(exp), dr.renew) dr.timer = time.AfterFunc(dr.next(exp), dr.renew)
} }
// stop stops the cert renewal timer. // stop stops the cert renewal timer and waits for any in-flight calls to renew
// If the timer is already stopped, calling stop is a noop. // to complete. If the timer is already stopped, calling stop is a noop.
func (dr *domainRenewal) stop() { func (dr *domainRenewal) stop() {
dr.timerMu.Lock() dr.timerMu.Lock()
defer dr.timerMu.Unlock() defer dr.timerMu.Unlock()
for {
if dr.timer == nil { if dr.timer == nil {
return return
} }
dr.timer.Stop() if dr.timer.Stop() {
dr.timer = nil dr.timer = nil
return
} else {
// dr.timer fired, and we acquired dr.timerMu before the renew callback did.
// (We know this because otherwise the renew callback would have reset dr.timer!)
timerClose := make(chan struct{})
dr.timerClose = timerClose
dr.timerMu.Unlock()
<-timerClose
dr.timerMu.Lock()
}
}
} }
// renew is called periodically by a timer. // renew is called periodically by a timer.
@ -55,7 +68,9 @@ func (dr *domainRenewal) stop() {
func (dr *domainRenewal) renew() { func (dr *domainRenewal) renew() {
dr.timerMu.Lock() dr.timerMu.Lock()
defer dr.timerMu.Unlock() defer dr.timerMu.Unlock()
if dr.timer == nil { if dr.timerClose != nil {
close(dr.timerClose)
dr.timer, dr.timerClose = nil, nil
return return
} }
@ -67,8 +82,8 @@ func (dr *domainRenewal) renew() {
next = renewJitter / 2 next = renewJitter / 2
next += time.Duration(pseudoRand.int63n(int64(next))) next += time.Duration(pseudoRand.int63n(int64(next)))
} }
dr.timer = time.AfterFunc(next, dr.renew)
testDidRenewLoop(next, err) testDidRenewLoop(next, err)
dr.timer = time.AfterFunc(next, dr.renew)
} }
// updateState locks and replaces the relevant Manager.state item with the given // updateState locks and replaces the relevant Manager.state item with the given

View File

@ -20,12 +20,12 @@ import (
"math/big" "math/big"
) )
// keyID is the account identity provided by a CA during registration. // KeyID is the account key identity provided by a CA during registration.
type keyID string type KeyID string
// noKeyID indicates that jwsEncodeJSON should compute and use JWK instead of a KID. // noKeyID indicates that jwsEncodeJSON should compute and use JWK instead of a KID.
// See jwsEncodeJSON for details. // See jwsEncodeJSON for details.
const noKeyID = keyID("") const noKeyID = KeyID("")
// noPayload indicates jwsEncodeJSON will encode zero-length octet string // noPayload indicates jwsEncodeJSON will encode zero-length octet string
// in a JWS request. This is called POST-as-GET in RFC 8555 and is used to make // in a JWS request. This is called POST-as-GET in RFC 8555 and is used to make
@ -43,14 +43,17 @@ type jsonWebSignature struct {
// jwsEncodeJSON signs claimset using provided key and a nonce. // jwsEncodeJSON signs claimset using provided key and a nonce.
// The result is serialized in JSON format containing either kid or jwk // The result is serialized in JSON format containing either kid or jwk
// fields based on the provided keyID value. // fields based on the provided KeyID value.
// //
// If kid is non-empty, its quoted value is inserted in the protected head // If kid is non-empty, its quoted value is inserted in the protected head
// as "kid" field value. Otherwise, JWK is computed using jwkEncode and inserted // as "kid" field value. Otherwise, JWK is computed using jwkEncode and inserted
// as "jwk" field value. The "jwk" and "kid" fields are mutually exclusive. // as "jwk" field value. The "jwk" and "kid" fields are mutually exclusive.
// //
// See https://tools.ietf.org/html/rfc7515#section-7. // See https://tools.ietf.org/html/rfc7515#section-7.
func jwsEncodeJSON(claimset interface{}, key crypto.Signer, kid keyID, nonce, url string) ([]byte, error) { func jwsEncodeJSON(claimset interface{}, key crypto.Signer, kid KeyID, nonce, url string) ([]byte, error) {
if key == nil {
return nil, errors.New("nil key")
}
alg, sha := jwsHasher(key.Public()) alg, sha := jwsHasher(key.Public())
if alg == "" || !sha.Available() { if alg == "" || !sha.Available() {
return nil, ErrUnsupportedKey return nil, ErrUnsupportedKey

View File

@ -78,7 +78,7 @@ func (c *Client) registerRFC(ctx context.Context, acct *Account, prompt func(tos
} }
// Cache Account URL even if we return an error to the caller. // Cache Account URL even if we return an error to the caller.
// It is by all means a valid and usable "kid" value for future requests. // It is by all means a valid and usable "kid" value for future requests.
c.kid = keyID(a.URI) c.KID = KeyID(a.URI)
if res.StatusCode == http.StatusOK { if res.StatusCode == http.StatusOK {
return nil, ErrAccountAlreadyExists return nil, ErrAccountAlreadyExists
} }

View File

@ -305,14 +305,6 @@ type Directory struct {
ExternalAccountRequired bool ExternalAccountRequired bool
} }
// rfcCompliant reports whether the ACME server implements RFC 8555.
// Note that some servers may have incomplete RFC implementation
// even if the returned value is true.
// If rfcCompliant reports false, the server most likely implements draft-02.
func (d *Directory) rfcCompliant() bool {
return d.OrderURL != ""
}
// Order represents a client's request for a certificate. // Order represents a client's request for a certificate.
// It tracks the request flow progress through to issuance. // It tracks the request flow progress through to issuance.
type Order struct { type Order struct {

View File

@ -1,13 +1,7 @@
// Copyright 2016 The Go Authors. All rights reserved. // Copyright 2019 The Go Authors. All rights reserved.
// 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.
// In Go 1.13, the ed25519 package was promoted to the standard library as
// crypto/ed25519, and this package became a wrapper for the standard library one.
//
//go:build !go1.13
// +build !go1.13
// Package ed25519 implements the Ed25519 signature algorithm. See // Package ed25519 implements the Ed25519 signature algorithm. See
// https://ed25519.cr.yp.to/. // https://ed25519.cr.yp.to/.
// //
@ -16,21 +10,15 @@
// representation includes a public key suffix to make multiple signing // representation includes a public key suffix to make multiple signing
// operations with the same key more efficient. This package refers to the RFC // operations with the same key more efficient. This package refers to the RFC
// 8032 private key as the “seed”. // 8032 private key as the “seed”.
//
// Beginning with Go 1.13, the functionality of this package was moved to the
// standard library as crypto/ed25519. This package only acts as a compatibility
// wrapper.
package ed25519 package ed25519
// This code is a port of the public domain, “ref10” implementation of ed25519
// from SUPERCOP.
import ( import (
"bytes" "crypto/ed25519"
"crypto"
cryptorand "crypto/rand"
"crypto/sha512"
"errors"
"io" "io"
"strconv"
"golang.org/x/crypto/ed25519/internal/edwards25519"
) )
const ( const (
@ -45,57 +33,21 @@ const (
) )
// PublicKey is the type of Ed25519 public keys. // PublicKey is the type of Ed25519 public keys.
type PublicKey []byte //
// This type is an alias for crypto/ed25519's PublicKey type.
// See the crypto/ed25519 package for the methods on this type.
type PublicKey = ed25519.PublicKey
// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer. // PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
type PrivateKey []byte //
// This type is an alias for crypto/ed25519's PrivateKey type.
// Public returns the PublicKey corresponding to priv. // See the crypto/ed25519 package for the methods on this type.
func (priv PrivateKey) Public() crypto.PublicKey { type PrivateKey = ed25519.PrivateKey
publicKey := make([]byte, PublicKeySize)
copy(publicKey, priv[32:])
return PublicKey(publicKey)
}
// Seed returns the private key seed corresponding to priv. It is provided for
// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
// in this package.
func (priv PrivateKey) Seed() []byte {
seed := make([]byte, SeedSize)
copy(seed, priv[:32])
return seed
}
// Sign signs the given message with priv.
// Ed25519 performs two passes over messages to be signed and therefore cannot
// handle pre-hashed messages. Thus opts.HashFunc() must return zero to
// indicate the message hasn't been hashed. This can be achieved by passing
// crypto.Hash(0) as the value for opts.
func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
if opts.HashFunc() != crypto.Hash(0) {
return nil, errors.New("ed25519: cannot sign hashed message")
}
return Sign(priv, message), nil
}
// GenerateKey generates a public/private key pair using entropy from rand. // GenerateKey generates a public/private key pair using entropy from rand.
// If rand is nil, crypto/rand.Reader will be used. // If rand is nil, crypto/rand.Reader will be used.
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) { func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
if rand == nil { return ed25519.GenerateKey(rand)
rand = cryptorand.Reader
}
seed := make([]byte, SeedSize)
if _, err := io.ReadFull(rand, seed); err != nil {
return nil, nil, err
}
privateKey := NewKeyFromSeed(seed)
publicKey := make([]byte, PublicKeySize)
copy(publicKey, privateKey[32:])
return publicKey, privateKey, nil
} }
// NewKeyFromSeed calculates a private key from a seed. It will panic if // NewKeyFromSeed calculates a private key from a seed. It will panic if
@ -103,121 +55,17 @@ func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
// with RFC 8032. RFC 8032's private keys correspond to seeds in this // with RFC 8032. RFC 8032's private keys correspond to seeds in this
// package. // package.
func NewKeyFromSeed(seed []byte) PrivateKey { func NewKeyFromSeed(seed []byte) PrivateKey {
if l := len(seed); l != SeedSize { return ed25519.NewKeyFromSeed(seed)
panic("ed25519: bad seed length: " + strconv.Itoa(l))
}
digest := sha512.Sum512(seed)
digest[0] &= 248
digest[31] &= 127
digest[31] |= 64
var A edwards25519.ExtendedGroupElement
var hBytes [32]byte
copy(hBytes[:], digest[:])
edwards25519.GeScalarMultBase(&A, &hBytes)
var publicKeyBytes [32]byte
A.ToBytes(&publicKeyBytes)
privateKey := make([]byte, PrivateKeySize)
copy(privateKey, seed)
copy(privateKey[32:], publicKeyBytes[:])
return privateKey
} }
// Sign signs the message with privateKey and returns a signature. It will // Sign signs the message with privateKey and returns a signature. It will
// panic if len(privateKey) is not PrivateKeySize. // panic if len(privateKey) is not PrivateKeySize.
func Sign(privateKey PrivateKey, message []byte) []byte { func Sign(privateKey PrivateKey, message []byte) []byte {
if l := len(privateKey); l != PrivateKeySize { return ed25519.Sign(privateKey, message)
panic("ed25519: bad private key length: " + strconv.Itoa(l))
}
h := sha512.New()
h.Write(privateKey[:32])
var digest1, messageDigest, hramDigest [64]byte
var expandedSecretKey [32]byte
h.Sum(digest1[:0])
copy(expandedSecretKey[:], digest1[:])
expandedSecretKey[0] &= 248
expandedSecretKey[31] &= 63
expandedSecretKey[31] |= 64
h.Reset()
h.Write(digest1[32:])
h.Write(message)
h.Sum(messageDigest[:0])
var messageDigestReduced [32]byte
edwards25519.ScReduce(&messageDigestReduced, &messageDigest)
var R edwards25519.ExtendedGroupElement
edwards25519.GeScalarMultBase(&R, &messageDigestReduced)
var encodedR [32]byte
R.ToBytes(&encodedR)
h.Reset()
h.Write(encodedR[:])
h.Write(privateKey[32:])
h.Write(message)
h.Sum(hramDigest[:0])
var hramDigestReduced [32]byte
edwards25519.ScReduce(&hramDigestReduced, &hramDigest)
var s [32]byte
edwards25519.ScMulAdd(&s, &hramDigestReduced, &expandedSecretKey, &messageDigestReduced)
signature := make([]byte, SignatureSize)
copy(signature[:], encodedR[:])
copy(signature[32:], s[:])
return signature
} }
// Verify reports whether sig is a valid signature of message by publicKey. It // Verify reports whether sig is a valid signature of message by publicKey. It
// will panic if len(publicKey) is not PublicKeySize. // will panic if len(publicKey) is not PublicKeySize.
func Verify(publicKey PublicKey, message, sig []byte) bool { func Verify(publicKey PublicKey, message, sig []byte) bool {
if l := len(publicKey); l != PublicKeySize { return ed25519.Verify(publicKey, message, sig)
panic("ed25519: bad public key length: " + strconv.Itoa(l))
}
if len(sig) != SignatureSize || sig[63]&224 != 0 {
return false
}
var A edwards25519.ExtendedGroupElement
var publicKeyBytes [32]byte
copy(publicKeyBytes[:], publicKey)
if !A.FromBytes(&publicKeyBytes) {
return false
}
edwards25519.FeNeg(&A.X, &A.X)
edwards25519.FeNeg(&A.T, &A.T)
h := sha512.New()
h.Write(sig[:32])
h.Write(publicKey[:])
h.Write(message)
var digest [64]byte
h.Sum(digest[:0])
var hReduced [32]byte
edwards25519.ScReduce(&hReduced, &digest)
var R edwards25519.ProjectiveGroupElement
var s [32]byte
copy(s[:], sig[32:])
// https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in
// the range [0, order) in order to prevent signature malleability.
if !edwards25519.ScMinimal(&s) {
return false
}
edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &s)
var checkR [32]byte
R.ToBytes(&checkR)
return bytes.Equal(sig[:32], checkR[:])
} }

View File

@ -1,74 +0,0 @@
// Copyright 2019 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.13
// +build go1.13
// Package ed25519 implements the Ed25519 signature algorithm. See
// https://ed25519.cr.yp.to/.
//
// These functions are also compatible with the “Ed25519” function defined in
// RFC 8032. However, unlike RFC 8032's formulation, this package's private key
// representation includes a public key suffix to make multiple signing
// operations with the same key more efficient. This package refers to the RFC
// 8032 private key as the “seed”.
//
// Beginning with Go 1.13, the functionality of this package was moved to the
// standard library as crypto/ed25519. This package only acts as a compatibility
// wrapper.
package ed25519
import (
"crypto/ed25519"
"io"
)
const (
// PublicKeySize is the size, in bytes, of public keys as used in this package.
PublicKeySize = 32
// PrivateKeySize is the size, in bytes, of private keys as used in this package.
PrivateKeySize = 64
// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
SignatureSize = 64
// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
SeedSize = 32
)
// PublicKey is the type of Ed25519 public keys.
//
// This type is an alias for crypto/ed25519's PublicKey type.
// See the crypto/ed25519 package for the methods on this type.
type PublicKey = ed25519.PublicKey
// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
//
// This type is an alias for crypto/ed25519's PrivateKey type.
// See the crypto/ed25519 package for the methods on this type.
type PrivateKey = ed25519.PrivateKey
// GenerateKey generates a public/private key pair using entropy from rand.
// If rand is nil, crypto/rand.Reader will be used.
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
return ed25519.GenerateKey(rand)
}
// NewKeyFromSeed calculates a private key from a seed. It will panic if
// len(seed) is not SeedSize. This function is provided for interoperability
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
// package.
func NewKeyFromSeed(seed []byte) PrivateKey {
return ed25519.NewKeyFromSeed(seed)
}
// Sign signs the message with privateKey and returns a signature. It will
// panic if len(privateKey) is not PrivateKeySize.
func Sign(privateKey PrivateKey, message []byte) []byte {
return ed25519.Sign(privateKey, message)
}
// Verify reports whether sig is a valid signature of message by publicKey. It
// will panic if len(publicKey) is not PublicKeySize.
func Verify(publicKey PublicKey, message, sig []byte) bool {
return ed25519.Verify(publicKey, message, sig)
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -394,6 +394,10 @@ func (c *gcmCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error)
} }
c.incIV() c.incIV()
if len(plain) == 0 {
return nil, errors.New("ssh: empty packet")
}
padding := plain[0] padding := plain[0]
if padding < 4 { if padding < 4 {
// padding is a byte, so it automatically satisfies // padding is a byte, so it automatically satisfies
@ -710,6 +714,10 @@ func (c *chacha20Poly1305Cipher) readCipherPacket(seqNum uint32, r io.Reader) ([
plain := c.buf[4:contentEnd] plain := c.buf[4:contentEnd]
s.XORKeyStream(plain, plain) s.XORKeyStream(plain, plain)
if len(plain) == 0 {
return nil, errors.New("ssh: empty packet")
}
padding := plain[0] padding := plain[0]
if padding < 4 { if padding < 4 {
// padding is a byte, so it automatically satisfies // padding is a byte, so it automatically satisfies

View File

@ -633,6 +633,30 @@ userAuthLoop:
} }
authFailures++ authFailures++
if config.MaxAuthTries > 0 && authFailures >= config.MaxAuthTries {
// If we have hit the max attempts, don't bother sending the
// final SSH_MSG_USERAUTH_FAILURE message, since there are
// no more authentication methods which can be attempted,
// and this message may cause the client to re-attempt
// authentication while we send the disconnect message.
// Continue, and trigger the disconnect at the start of
// the loop.
//
// The SSH specification is somewhat confusing about this,
// RFC 4252 Section 5.1 requires each authentication failure
// be responded to with a respective SSH_MSG_USERAUTH_FAILURE
// message, but Section 4 says the server should disconnect
// after some number of attempts, but it isn't explicit which
// message should take precedence (i.e. should there be a failure
// message than a disconnect message, or if we are going to
// disconnect, should we only send that message.)
//
// Either way, OpenSSH disconnects immediately after the last
// failed authnetication attempt, and given they are typically
// considered the golden implementation it seems reasonable
// to match that behavior.
continue
}
var failureMsg userAuthFailureMsg var failureMsg userAuthFailureMsg
if config.PasswordCallback != nil { if config.PasswordCallback != nil {

View File

@ -904,10 +904,10 @@ func (t *Task) Main() (err error) {
} }
abi, err := cc.NewABI(t.goos, t.goarch) abi, err := cc.NewABI(t.goos, t.goarch)
abi.Types[cc.LongDouble] = abi.Types[cc.Double]
if err != nil { if err != nil {
return err return err
} }
abi.Types[cc.LongDouble] = abi.Types[cc.Double]
var re *regexp.Regexp var re *regexp.Regexp
if t.ignoredIncludes != "" { if t.ignoredIncludes != "" {
@ -1474,7 +1474,7 @@ func (t *Task) createCompileDB(command []string) (rerr error) {
var parser func(s string) ([]string, error) var parser func(s string) ([]string, error)
out: out:
switch t.goos { switch t.goos {
case "darwin", "freebsd", "netbsd", "openbsd": case "darwin", "freebsd", "netbsd":
switch command[0] { switch command[0] {
case "make", "gmake": case "make", "gmake":
// ok // ok
@ -1490,6 +1490,22 @@ out:
command = append([]string{sh, "-c"}, join(" ", command[0], "SHELL='sh -x'", command[1:])) command = append([]string{sh, "-c"}, join(" ", command[0], "SHELL='sh -x'", command[1:]))
cmd = exec.Command(command[0], command[1:]...) cmd = exec.Command(command[0], command[1:]...)
parser = makeXParser parser = makeXParser
case "openbsd":
switch command[0] {
case "make", "gmake":
// ok
default:
return fmt.Errorf("usupported build command: %s", command[0])
}
sh, err := exec.LookPath("sh")
if err != nil {
return err
}
command = append([]string{sh, "-c"}, join(" ", command[0], "SHELL='sh -x'", command[1:]))
cmd = exec.Command(command[0], command[1:]...)
parser = makeXParser2
case "windows": case "windows":
if command[0] != "make" { if command[0] != "make" {
return fmt.Errorf("usupported build command: %s", command[0]) return fmt.Errorf("usupported build command: %s", command[0])
@ -1580,7 +1596,7 @@ func isCreateArchive(s string) bool {
b := []byte(s) b := []byte(s)
sort.Slice(b, func(i, j int) bool { return b[i] < b[j] }) sort.Slice(b, func(i, j int) bool { return b[i] < b[j] })
switch string(b) { switch string(b) {
case "cq", "cr", "crs", "cru": case "cq", "cr", "crs", "cru", "r":
return true return true
} }
return false return false
@ -1615,7 +1631,48 @@ func makeXParser(s string) (r []string, err error) {
} }
s = s[1:] s = s[1:]
if dmesgs {
dmesg("%v: source line `%s`, caller %v:", origin(1), s, origin(2))
}
r, err = shellquote.Split(s) r, err = shellquote.Split(s)
if dmesgs {
dmesg("%v: shellquote.Split -> %v %[2]q, %v", origin(1), r, err)
}
if err != nil {
if strings.Contains(err.Error(), "Unterminated single-quoted string") {
return nil, nil // ignore
}
}
if len(r) != 0 && filepath.Base(r[0]) == "libtool" {
r[0] = "libtool"
}
return r, err
}
func makeXParser2(s string) (r []string, err error) {
s = strings.TrimSpace(s)
switch {
case strings.HasPrefix(s, "libtool: link: ar "):
s = s[len("libtool: link:"):]
case strings.HasPrefix(s, "libtool: compile: "):
s = s[len("libtool: compile:"):]
for strings.HasPrefix(s, " ") {
s = s[1:]
}
default:
var n int
if n, s = hasPlusPrefix(s); n != 0 {
return nil, nil
}
}
if dmesgs {
dmesg("%v: source line `%s`, caller %v:", origin(1), s, origin(2))
}
r, err = shellquote.Split(s)
if dmesgs {
dmesg("%v: shellquote.Split -> %v %[2]q, %v", origin(1), r, err)
}
if err != nil { if err != nil {
if strings.Contains(err.Error(), "Unterminated single-quoted string") { if strings.Contains(err.Error(), "Unterminated single-quoted string") {
return nil, nil // ignore return nil, nil // ignore
@ -1809,26 +1866,29 @@ func (it *cdbItem) sources(cc, ar string) (r []string) {
} }
type cdbMakeWriter struct { type cdbMakeWriter struct {
b bytes.Buffer
cc string
ar string ar string
arBase string arBase string
b bytes.Buffer
cc string
dir string dir string
err error err error
it cdbItem it cdbItem
parser func(s string) ([]string, error) parser func(s string) ([]string, error)
prefix string
sc *bufio.Scanner sc *bufio.Scanner
t *Task
w *cdbWriter w *cdbWriter
} }
func (t *Task) newCdbMakeWriter(w *cdbWriter, dir string, parser func(s string) ([]string, error)) *cdbMakeWriter { func (t *Task) newCdbMakeWriter(w *cdbWriter, dir string, parser func(s string) ([]string, error)) *cdbMakeWriter {
const sz = 1 << 16 const sz = 1 << 16
r := &cdbMakeWriter{ r := &cdbMakeWriter{
cc: t.ccLookPath,
ar: t.arLookPath, ar: t.arLookPath,
arBase: filepath.Base(t.arLookPath), arBase: filepath.Base(t.arLookPath),
cc: t.ccLookPath,
dir: dir, dir: dir,
parser: parser, parser: parser,
t: t,
w: w, w: w,
} }
r.sc = bufio.NewScanner(&r.b) r.sc = bufio.NewScanner(&r.b)
@ -1849,7 +1909,15 @@ func (w *cdbMakeWriter) Write(b []byte) (int, error) {
panic(todo("internal error")) panic(todo("internal error"))
} }
s := strings.TrimSpace(w.sc.Text()) s := w.sc.Text()
if strings.HasSuffix(s, "\\") {
w.prefix += s[:len(s)-1]
continue
}
s = w.prefix + s
w.prefix = ""
s = strings.TrimSpace(s)
if edx := strings.Index(s, "Entering directory"); edx >= 0 { if edx := strings.Index(s, "Entering directory"); edx >= 0 {
s = s[edx+len("Entering directory"):] s = s[edx+len("Entering directory"):]
s = strings.TrimSpace(s) s = strings.TrimSpace(s)
@ -1882,7 +1950,13 @@ func (w *cdbMakeWriter) Write(b []byte) (int, error) {
continue continue
} }
if dmesgs {
dmesg("%v: source line `%s`", origin(1), s)
}
args, err := w.parser(s) args, err := w.parser(s)
if dmesgs {
dmesg("%v: parser -> %v %[2]q, %v", origin(1), args, err)
}
if err != nil { if err != nil {
w.fail(err) w.fail(err)
continue continue
@ -1899,16 +1973,25 @@ func (w *cdbMakeWriter) Write(b []byte) (int, error) {
err = nil err = nil
switch args[0] { switch args[0] {
case w.cc: case w.cc:
if w.t.verboseCompiledb {
fmt.Printf("source line: %q\n", s)
}
fmt.Printf("CCGO CC: %q\n", args) fmt.Printf("CCGO CC: %q\n", args)
err = w.handleGCC(args) err = w.handleGCC(args)
case w.ar: case w.ar:
fallthrough fallthrough
case w.arBase: case w.arBase:
if isCreateArchive(args[1]) { if isCreateArchive(args[1]) {
if w.t.verboseCompiledb {
fmt.Printf("source line: %q\n", s)
}
fmt.Printf("CCGO AR: %q\n", args) fmt.Printf("CCGO AR: %q\n", args)
err = w.handleAR(args) err = w.handleAR(args)
} }
case "libtool": case "libtool":
if w.t.verboseCompiledb {
fmt.Printf("source line: %q\n", s)
}
fmt.Printf("CCGO LIBTOOL: %q\n", args) fmt.Printf("CCGO LIBTOOL: %q\n", args)
err = w.handleLibtool(args) err = w.handleLibtool(args)
} }

View File

@ -32,7 +32,8 @@ func dmesg(s string, args ...interface{}) {
if s == "" { if s == "" {
s = strings.Repeat("%v ", len(args)) s = strings.Repeat("%v ", len(args))
} }
s = fmt.Sprintf(pid+s, args...) s = fmt.Sprintf(s, args...)
s = pid + s
switch { switch {
case len(s) != 0 && s[len(s)-1] == '\n': case len(s) != 0 && s[len(s)-1] == '\n':
fmt.Fprint(logf, s) fmt.Fprint(logf, s)

10
vendor/modernc.org/ccgo/v3/lib/go.go generated vendored
View File

@ -3117,6 +3117,9 @@ func (p *project) declaratorDecay(n cc.Node, f *function, d *cc.Declarator, t cc
return return
} }
if !local.isPinned {
p.err(n, "%v: %v: missed pinning", n.Position(), d.Position(), d.Name())
}
p.w("(%s%s)/* &%s[0] */", f.bpName, nonZeroUintptr(local.off), local.name) p.w("(%s%s)/* &%s[0] */", f.bpName, nonZeroUintptr(local.off), local.name)
return return
} }
@ -8135,6 +8138,11 @@ func (p *project) castExpressionValue(f *function, n *cc.CastExpression, t cc.Ty
case cc.CastExpressionUnary: // UnaryExpression case cc.CastExpressionUnary: // UnaryExpression
p.unaryExpression(f, n.UnaryExpression, t, mode, flags) p.unaryExpression(f, n.UnaryExpression, t, mode, flags)
case cc.CastExpressionCast: // '(' TypeName ')' CastExpression case cc.CastExpressionCast: // '(' TypeName ')' CastExpression
if f != nil && p.pass1 && n.TypeName.Type().IsIntegerType() && n.CastExpression.Operand.Type().Kind() == cc.Array {
if d := n.CastExpression.Declarator(); d != nil {
f.pin(n, d)
}
}
switch k := p.opKind(f, n.CastExpression, n.CastExpression.Operand.Type()); k { switch k := p.opKind(f, n.CastExpression, n.CastExpression.Operand.Type()); k {
case opNormal, opBitfield: case opNormal, opBitfield:
p.castExpressionValueNormal(f, n, t, mode, flags) p.castExpressionValueNormal(f, n, t, mode, flags)
@ -12561,7 +12569,7 @@ func (p *project) iterationStatement(f *function, n *cc.IterationStatement) {
break break
} }
v := "ok" v := "__ccgo"
if !p.pass1 { if !p.pass1 {
v = f.scope.take(cc.String(v)) v = f.scope.take(cc.String(v))
} }

1
vendor/modernc.org/libc/AUTHORS generated vendored
View File

@ -13,4 +13,5 @@ Dan Peterson <danp@danp.net>
Jan Mercl <0xjnml@gmail.com> Jan Mercl <0xjnml@gmail.com>
Jason DeBettencourt <jasond17@gmail.com> Jason DeBettencourt <jasond17@gmail.com>
Koichi Shiraishi <zchee.io@gmail.com> Koichi Shiraishi <zchee.io@gmail.com>
Marius Orcsik <marius@federated.id>
Steffen Butzer <steffen(dot)butzer@outlook.com> Steffen Butzer <steffen(dot)butzer@outlook.com>

View File

@ -12,4 +12,5 @@ Jaap Aarts <jaap.aarts1@gmail.com>
Jan Mercl <0xjnml@gmail.com> Jan Mercl <0xjnml@gmail.com>
Jason DeBettencourt <jasond17@gmail.com> Jason DeBettencourt <jasond17@gmail.com>
Koichi Shiraishi <zchee.io@gmail.com> Koichi Shiraishi <zchee.io@gmail.com>
Marius Orcsik <marius@federated.id>
Steffen Butzer <steffen(dot)butzer@outlook.com> Steffen Butzer <steffen(dot)butzer@outlook.com>

View File

@ -153,6 +153,7 @@ var CAPI = map[string]struct{}{
"atoi": {}, "atoi": {},
"atol": {}, "atol": {},
"bind": {}, "bind": {},
"bsearch": {},
"bzero": {}, "bzero": {},
"calloc": {}, "calloc": {},
"ceil": {}, "ceil": {},

View File

@ -82,6 +82,7 @@ var CAPI = map[string]struct{}{
"__ccgo_sqlite3_log": {}, "__ccgo_sqlite3_log": {},
"__cmsg_nxthdr": {}, "__cmsg_nxthdr": {},
"__ctype_get_mb_cur_max": {}, "__ctype_get_mb_cur_max": {},
"__darwin_check_fd_set_overflow": {},
"__darwin_fd_clr": {}, "__darwin_fd_clr": {},
"__darwin_fd_isset": {}, "__darwin_fd_isset": {},
"__darwin_fd_set": {}, "__darwin_fd_set": {},
@ -152,6 +153,7 @@ var CAPI = map[string]struct{}{
"atoi": {}, "atoi": {},
"atol": {}, "atol": {},
"bind": {}, "bind": {},
"bsearch": {},
"bzero": {}, "bzero": {},
"calloc": {}, "calloc": {},
"ceil": {}, "ceil": {},

View File

@ -39,6 +39,8 @@ var CAPI = map[string]struct{}{
"__builtin_exit": {}, "__builtin_exit": {},
"__builtin_expect": {}, "__builtin_expect": {},
"__builtin_fabs": {}, "__builtin_fabs": {},
"__builtin_fabsf": {},
"__builtin_fabsl": {},
"__builtin_free": {}, "__builtin_free": {},
"__builtin_getentropy": {}, "__builtin_getentropy": {},
"__builtin_huge_val": {}, "__builtin_huge_val": {},
@ -47,6 +49,7 @@ var CAPI = map[string]struct{}{
"__builtin_inff": {}, "__builtin_inff": {},
"__builtin_infl": {}, "__builtin_infl": {},
"__builtin_isnan": {}, "__builtin_isnan": {},
"__builtin_isunordered": {},
"__builtin_malloc": {}, "__builtin_malloc": {},
"__builtin_memcmp": {}, "__builtin_memcmp": {},
"__builtin_memcpy": {}, "__builtin_memcpy": {},
@ -90,11 +93,16 @@ var CAPI = map[string]struct{}{
"__isalnum_l": {}, "__isalnum_l": {},
"__isalpha_l": {}, "__isalpha_l": {},
"__isdigit_l": {}, "__isdigit_l": {},
"__islower_l": {},
"__isnan": {}, "__isnan": {},
"__isnanf": {}, "__isnanf": {},
"__isnanl": {}, "__isnanl": {},
"__isoc99_sscanf": {}, "__isoc99_sscanf": {},
"__isprint_l": {},
"__isspace_l": {},
"__isthreaded": {}, "__isthreaded": {},
"__isupper_l": {},
"__isxdigit_l": {},
"__lookup_ipliteral": {}, "__lookup_ipliteral": {},
"__lookup_name": {}, "__lookup_name": {},
"__lookup_serv": {}, "__lookup_serv": {},
@ -139,6 +147,7 @@ var CAPI = map[string]struct{}{
"backtrace": {}, "backtrace": {},
"backtrace_symbols_fd": {}, "backtrace_symbols_fd": {},
"bind": {}, "bind": {},
"bsearch": {},
"bzero": {}, "bzero": {},
"calloc": {}, "calloc": {},
"ceil": {}, "ceil": {},
@ -266,9 +275,14 @@ var CAPI = map[string]struct{}{
"isascii": {}, "isascii": {},
"isatty": {}, "isatty": {},
"isdigit": {}, "isdigit": {},
"islower": {},
"isnan": {}, "isnan": {},
"isnanf": {}, "isnanf": {},
"isnanl": {}, "isnanl": {},
"isprint": {},
"isspace": {},
"isupper": {},
"isxdigit": {},
"kill": {}, "kill": {},
"ldexp": {}, "ldexp": {},
"link": {}, "link": {},

View File

@ -34,6 +34,8 @@ var CAPI = map[string]struct{}{
"__builtin_exit": {}, "__builtin_exit": {},
"__builtin_expect": {}, "__builtin_expect": {},
"__builtin_fabs": {}, "__builtin_fabs": {},
"__builtin_fabsf": {},
"__builtin_fabsl": {},
"__builtin_free": {}, "__builtin_free": {},
"__builtin_getentropy": {}, "__builtin_getentropy": {},
"__builtin_huge_val": {}, "__builtin_huge_val": {},
@ -42,6 +44,7 @@ var CAPI = map[string]struct{}{
"__builtin_inff": {}, "__builtin_inff": {},
"__builtin_infl": {}, "__builtin_infl": {},
"__builtin_isnan": {}, "__builtin_isnan": {},
"__builtin_isunordered": {},
"__builtin_malloc": {}, "__builtin_malloc": {},
"__builtin_memcmp": {}, "__builtin_memcmp": {},
"__builtin_memcpy": {}, "__builtin_memcpy": {},
@ -136,6 +139,7 @@ var CAPI = map[string]struct{}{
"backtrace": {}, "backtrace": {},
"backtrace_symbols_fd": {}, "backtrace_symbols_fd": {},
"bind": {}, "bind": {},
"bsearch": {},
"bzero": {}, "bzero": {},
"calloc": {}, "calloc": {},
"ceil": {}, "ceil": {},
@ -258,6 +262,7 @@ var CAPI = map[string]struct{}{
"inet_ntoa": {}, "inet_ntoa": {},
"inet_ntop": {}, "inet_ntop": {},
"inet_pton": {}, "inet_pton": {},
"initstate": {},
"initstate_r": {}, "initstate_r": {},
"ioctl": {}, "ioctl": {},
"isalnum": {}, "isalnum": {},
@ -405,6 +410,7 @@ var CAPI = map[string]struct{}{
"setrlimit64": {}, "setrlimit64": {},
"setsid": {}, "setsid": {},
"setsockopt": {}, "setsockopt": {},
"setstate": {},
"setvbuf": {}, "setvbuf": {},
"shmat": {}, "shmat": {},
"shmctl": {}, "shmctl": {},

View File

@ -34,6 +34,8 @@ var CAPI = map[string]struct{}{
"__builtin_exit": {}, "__builtin_exit": {},
"__builtin_expect": {}, "__builtin_expect": {},
"__builtin_fabs": {}, "__builtin_fabs": {},
"__builtin_fabsf": {},
"__builtin_fabsl": {},
"__builtin_free": {}, "__builtin_free": {},
"__builtin_getentropy": {}, "__builtin_getentropy": {},
"__builtin_huge_val": {}, "__builtin_huge_val": {},
@ -42,6 +44,7 @@ var CAPI = map[string]struct{}{
"__builtin_inff": {}, "__builtin_inff": {},
"__builtin_infl": {}, "__builtin_infl": {},
"__builtin_isnan": {}, "__builtin_isnan": {},
"__builtin_isunordered": {},
"__builtin_malloc": {}, "__builtin_malloc": {},
"__builtin_memcmp": {}, "__builtin_memcmp": {},
"__builtin_memcpy": {}, "__builtin_memcpy": {},
@ -136,6 +139,7 @@ var CAPI = map[string]struct{}{
"backtrace": {}, "backtrace": {},
"backtrace_symbols_fd": {}, "backtrace_symbols_fd": {},
"bind": {}, "bind": {},
"bsearch": {},
"bzero": {}, "bzero": {},
"calloc": {}, "calloc": {},
"ceil": {}, "ceil": {},
@ -258,6 +262,7 @@ var CAPI = map[string]struct{}{
"inet_ntoa": {}, "inet_ntoa": {},
"inet_ntop": {}, "inet_ntop": {},
"inet_pton": {}, "inet_pton": {},
"initstate": {},
"initstate_r": {}, "initstate_r": {},
"ioctl": {}, "ioctl": {},
"isalnum": {}, "isalnum": {},
@ -407,6 +412,7 @@ var CAPI = map[string]struct{}{
"setrlimit64": {}, "setrlimit64": {},
"setsid": {}, "setsid": {},
"setsockopt": {}, "setsockopt": {},
"setstate": {},
"setvbuf": {}, "setvbuf": {},
"shmat": {}, "shmat": {},
"shmctl": {}, "shmctl": {},

View File

@ -34,6 +34,8 @@ var CAPI = map[string]struct{}{
"__builtin_exit": {}, "__builtin_exit": {},
"__builtin_expect": {}, "__builtin_expect": {},
"__builtin_fabs": {}, "__builtin_fabs": {},
"__builtin_fabsf": {},
"__builtin_fabsl": {},
"__builtin_free": {}, "__builtin_free": {},
"__builtin_getentropy": {}, "__builtin_getentropy": {},
"__builtin_huge_val": {}, "__builtin_huge_val": {},
@ -42,6 +44,7 @@ var CAPI = map[string]struct{}{
"__builtin_inff": {}, "__builtin_inff": {},
"__builtin_infl": {}, "__builtin_infl": {},
"__builtin_isnan": {}, "__builtin_isnan": {},
"__builtin_isunordered": {},
"__builtin_malloc": {}, "__builtin_malloc": {},
"__builtin_memcmp": {}, "__builtin_memcmp": {},
"__builtin_memcpy": {}, "__builtin_memcpy": {},
@ -136,6 +139,7 @@ var CAPI = map[string]struct{}{
"backtrace": {}, "backtrace": {},
"backtrace_symbols_fd": {}, "backtrace_symbols_fd": {},
"bind": {}, "bind": {},
"bsearch": {},
"bzero": {}, "bzero": {},
"calloc": {}, "calloc": {},
"ceil": {}, "ceil": {},
@ -258,6 +262,7 @@ var CAPI = map[string]struct{}{
"inet_ntoa": {}, "inet_ntoa": {},
"inet_ntop": {}, "inet_ntop": {},
"inet_pton": {}, "inet_pton": {},
"initstate": {},
"initstate_r": {}, "initstate_r": {},
"ioctl": {}, "ioctl": {},
"isalnum": {}, "isalnum": {},
@ -405,6 +410,7 @@ var CAPI = map[string]struct{}{
"setrlimit64": {}, "setrlimit64": {},
"setsid": {}, "setsid": {},
"setsockopt": {}, "setsockopt": {},
"setstate": {},
"setvbuf": {}, "setvbuf": {},
"shmat": {}, "shmat": {},
"shmctl": {}, "shmctl": {},

View File

@ -34,6 +34,8 @@ var CAPI = map[string]struct{}{
"__builtin_exit": {}, "__builtin_exit": {},
"__builtin_expect": {}, "__builtin_expect": {},
"__builtin_fabs": {}, "__builtin_fabs": {},
"__builtin_fabsf": {},
"__builtin_fabsl": {},
"__builtin_free": {}, "__builtin_free": {},
"__builtin_getentropy": {}, "__builtin_getentropy": {},
"__builtin_huge_val": {}, "__builtin_huge_val": {},
@ -42,6 +44,7 @@ var CAPI = map[string]struct{}{
"__builtin_inff": {}, "__builtin_inff": {},
"__builtin_infl": {}, "__builtin_infl": {},
"__builtin_isnan": {}, "__builtin_isnan": {},
"__builtin_isunordered": {},
"__builtin_malloc": {}, "__builtin_malloc": {},
"__builtin_memcmp": {}, "__builtin_memcmp": {},
"__builtin_memcpy": {}, "__builtin_memcpy": {},
@ -136,6 +139,7 @@ var CAPI = map[string]struct{}{
"backtrace": {}, "backtrace": {},
"backtrace_symbols_fd": {}, "backtrace_symbols_fd": {},
"bind": {}, "bind": {},
"bsearch": {},
"bzero": {}, "bzero": {},
"calloc": {}, "calloc": {},
"ceil": {}, "ceil": {},
@ -258,6 +262,7 @@ var CAPI = map[string]struct{}{
"inet_ntoa": {}, "inet_ntoa": {},
"inet_ntop": {}, "inet_ntop": {},
"inet_pton": {}, "inet_pton": {},
"initstate": {},
"initstate_r": {}, "initstate_r": {},
"ioctl": {}, "ioctl": {},
"isalnum": {}, "isalnum": {},
@ -405,6 +410,7 @@ var CAPI = map[string]struct{}{
"setrlimit64": {}, "setrlimit64": {},
"setsid": {}, "setsid": {},
"setsockopt": {}, "setsockopt": {},
"setstate": {},
"setvbuf": {}, "setvbuf": {},
"shmat": {}, "shmat": {},
"shmctl": {}, "shmctl": {},

View File

@ -34,6 +34,8 @@ var CAPI = map[string]struct{}{
"__builtin_exit": {}, "__builtin_exit": {},
"__builtin_expect": {}, "__builtin_expect": {},
"__builtin_fabs": {}, "__builtin_fabs": {},
"__builtin_fabsf": {},
"__builtin_fabsl": {},
"__builtin_free": {}, "__builtin_free": {},
"__builtin_getentropy": {}, "__builtin_getentropy": {},
"__builtin_huge_val": {}, "__builtin_huge_val": {},
@ -42,6 +44,7 @@ var CAPI = map[string]struct{}{
"__builtin_inff": {}, "__builtin_inff": {},
"__builtin_infl": {}, "__builtin_infl": {},
"__builtin_isnan": {}, "__builtin_isnan": {},
"__builtin_isunordered": {},
"__builtin_malloc": {}, "__builtin_malloc": {},
"__builtin_memcmp": {}, "__builtin_memcmp": {},
"__builtin_memcpy": {}, "__builtin_memcpy": {},
@ -136,6 +139,7 @@ var CAPI = map[string]struct{}{
"backtrace": {}, "backtrace": {},
"backtrace_symbols_fd": {}, "backtrace_symbols_fd": {},
"bind": {}, "bind": {},
"bsearch": {},
"bzero": {}, "bzero": {},
"calloc": {}, "calloc": {},
"ceil": {}, "ceil": {},
@ -258,6 +262,7 @@ var CAPI = map[string]struct{}{
"inet_ntoa": {}, "inet_ntoa": {},
"inet_ntop": {}, "inet_ntop": {},
"inet_pton": {}, "inet_pton": {},
"initstate": {},
"initstate_r": {}, "initstate_r": {},
"ioctl": {}, "ioctl": {},
"isalnum": {}, "isalnum": {},
@ -405,6 +410,7 @@ var CAPI = map[string]struct{}{
"setrlimit64": {}, "setrlimit64": {},
"setsid": {}, "setsid": {},
"setsockopt": {}, "setsockopt": {},
"setstate": {},
"setvbuf": {}, "setvbuf": {},
"shmat": {}, "shmat": {},
"shmctl": {}, "shmctl": {},

View File

@ -39,6 +39,8 @@ var CAPI = map[string]struct{}{
"__builtin_exit": {}, "__builtin_exit": {},
"__builtin_expect": {}, "__builtin_expect": {},
"__builtin_fabs": {}, "__builtin_fabs": {},
"__builtin_fabsf": {},
"__builtin_fabsl": {},
"__builtin_free": {}, "__builtin_free": {},
"__builtin_getentropy": {}, "__builtin_getentropy": {},
"__builtin_huge_val": {}, "__builtin_huge_val": {},
@ -47,6 +49,7 @@ var CAPI = map[string]struct{}{
"__builtin_inff": {}, "__builtin_inff": {},
"__builtin_infl": {}, "__builtin_infl": {},
"__builtin_isnan": {}, "__builtin_isnan": {},
"__builtin_isunordered": {},
"__builtin_malloc": {}, "__builtin_malloc": {},
"__builtin_memcmp": {}, "__builtin_memcmp": {},
"__builtin_memcpy": {}, "__builtin_memcpy": {},
@ -110,7 +113,6 @@ var CAPI = map[string]struct{}{
"__swbuf": {}, "__swbuf": {},
"__sync_add_and_fetch_uint32": {}, "__sync_add_and_fetch_uint32": {},
"__sync_sub_and_fetch_uint32": {}, "__sync_sub_and_fetch_uint32": {},
"__sync_synchronize": {},
"__syscall1": {}, "__syscall1": {},
"__syscall3": {}, "__syscall3": {},
"__syscall4": {}, "__syscall4": {},
@ -145,6 +147,7 @@ var CAPI = map[string]struct{}{
"backtrace": {}, "backtrace": {},
"backtrace_symbols_fd": {}, "backtrace_symbols_fd": {},
"bind": {}, "bind": {},
"bsearch": {},
"bzero": {}, "bzero": {},
"calloc": {}, "calloc": {},
"ceil": {}, "ceil": {},
@ -264,6 +267,8 @@ var CAPI = map[string]struct{}{
"inet_ntoa": {}, "inet_ntoa": {},
"inet_ntop": {}, "inet_ntop": {},
"inet_pton": {}, "inet_pton": {},
"initstate": {},
"initstate_r": {},
"ioctl": {}, "ioctl": {},
"isalnum": {}, "isalnum": {},
"isalpha": {}, "isalpha": {},
@ -299,6 +304,7 @@ var CAPI = map[string]struct{}{
"mkdir": {}, "mkdir": {},
"mkfifo": {}, "mkfifo": {},
"mknod": {}, "mknod": {},
"mkostemp": {},
"mkstemp": {}, "mkstemp": {},
"mkstemp64": {}, "mkstemp64": {},
"mkstemps": {}, "mkstemps": {},
@ -362,6 +368,7 @@ var CAPI = map[string]struct{}{
"raise": {}, "raise": {},
"rand": {}, "rand": {},
"random": {}, "random": {},
"random_r": {},
"read": {}, "read": {},
"readdir": {}, "readdir": {},
"readdir64": {}, "readdir64": {},
@ -395,6 +402,7 @@ var CAPI = map[string]struct{}{
"setrlimit64": {}, "setrlimit64": {},
"setsid": {}, "setsid": {},
"setsockopt": {}, "setsockopt": {},
"setstate": {},
"setvbuf": {}, "setvbuf": {},
"shmat": {}, "shmat": {},
"shmctl": {}, "shmctl": {},
@ -425,6 +433,7 @@ var CAPI = map[string]struct{}{
"strcspn": {}, "strcspn": {},
"strdup": {}, "strdup": {},
"strerror": {}, "strerror": {},
"strerror_r": {},
"strlen": {}, "strlen": {},
"strncmp": {}, "strncmp": {},
"strncpy": {}, "strncpy": {},
@ -464,6 +473,9 @@ var CAPI = map[string]struct{}{
"usleep": {}, "usleep": {},
"utime": {}, "utime": {},
"utimes": {}, "utimes": {},
"uuid_generate_random": {},
"uuid_parse": {},
"uuid_unparse": {},
"vasprintf": {}, "vasprintf": {},
"vfprintf": {}, "vfprintf": {},
"vprintf": {}, "vprintf": {},

View File

@ -96,6 +96,7 @@ var CAPI = map[string]struct{}{
"__isalnum_l": {}, "__isalnum_l": {},
"__isalpha_l": {}, "__isalpha_l": {},
"__isdigit_l": {}, "__isdigit_l": {},
"__islower_l": {},
"__isnan": {}, "__isnan": {},
"__isnanf": {}, "__isnanf": {},
"__isnanl": {}, "__isnanl": {},
@ -103,6 +104,8 @@ var CAPI = map[string]struct{}{
"__isprint_l": {}, "__isprint_l": {},
"__isspace_l": {}, "__isspace_l": {},
"__isthreaded": {}, "__isthreaded": {},
"__isupper_l": {},
"__isxdigit_l": {},
"__lookup_ipliteral": {}, "__lookup_ipliteral": {},
"__lookup_name": {}, "__lookup_name": {},
"__lookup_serv": {}, "__lookup_serv": {},
@ -151,6 +154,7 @@ var CAPI = map[string]struct{}{
"backtrace": {}, "backtrace": {},
"backtrace_symbols_fd": {}, "backtrace_symbols_fd": {},
"bind": {}, "bind": {},
"bsearch": {},
"bzero": {}, "bzero": {},
"calloc": {}, "calloc": {},
"ceil": {}, "ceil": {},
@ -279,11 +283,14 @@ var CAPI = map[string]struct{}{
"isascii": {}, "isascii": {},
"isatty": {}, "isatty": {},
"isdigit": {}, "isdigit": {},
"islower": {},
"isnan": {}, "isnan": {},
"isnanf": {}, "isnanf": {},
"isnanl": {}, "isnanl": {},
"isprint": {}, "isprint": {},
"isspace": {}, "isspace": {},
"isupper": {},
"isxdigit": {},
"kill": {}, "kill": {},
"ldexp": {}, "ldexp": {},
"link": {}, "link": {},

View File

@ -284,6 +284,8 @@ var CAPI = map[string]struct{}{
"__builtin_exit": {}, "__builtin_exit": {},
"__builtin_expect": {}, "__builtin_expect": {},
"__builtin_fabs": {}, "__builtin_fabs": {},
"__builtin_fabsf": {},
"__builtin_fabsl": {},
"__builtin_free": {}, "__builtin_free": {},
"__builtin_getentropy": {}, "__builtin_getentropy": {},
"__builtin_huge_val": {}, "__builtin_huge_val": {},
@ -292,6 +294,7 @@ var CAPI = map[string]struct{}{
"__builtin_inff": {}, "__builtin_inff": {},
"__builtin_infl": {}, "__builtin_infl": {},
"__builtin_isnan": {}, "__builtin_isnan": {},
"__builtin_isunordered": {},
"__builtin_malloc": {}, "__builtin_malloc": {},
"__builtin_memcmp": {}, "__builtin_memcmp": {},
"__builtin_memcpy": {}, "__builtin_memcpy": {},
@ -440,6 +443,7 @@ var CAPI = map[string]struct{}{
"backtrace": {}, "backtrace": {},
"backtrace_symbols_fd": {}, "backtrace_symbols_fd": {},
"bind": {}, "bind": {},
"bsearch": {},
"bzero": {}, "bzero": {},
"calloc": {}, "calloc": {},
"ceil": {}, "ceil": {},

View File

@ -282,6 +282,8 @@ var CAPI = map[string]struct{}{
"__builtin_exit": {}, "__builtin_exit": {},
"__builtin_expect": {}, "__builtin_expect": {},
"__builtin_fabs": {}, "__builtin_fabs": {},
"__builtin_fabsf": {},
"__builtin_fabsl": {},
"__builtin_free": {}, "__builtin_free": {},
"__builtin_getentropy": {}, "__builtin_getentropy": {},
"__builtin_huge_val": {}, "__builtin_huge_val": {},
@ -290,6 +292,7 @@ var CAPI = map[string]struct{}{
"__builtin_inff": {}, "__builtin_inff": {},
"__builtin_infl": {}, "__builtin_infl": {},
"__builtin_isnan": {}, "__builtin_isnan": {},
"__builtin_isunordered": {},
"__builtin_malloc": {}, "__builtin_malloc": {},
"__builtin_memcmp": {}, "__builtin_memcmp": {},
"__builtin_memcpy": {}, "__builtin_memcpy": {},
@ -436,6 +439,7 @@ var CAPI = map[string]struct{}{
"backtrace": {}, "backtrace": {},
"backtrace_symbols_fd": {}, "backtrace_symbols_fd": {},
"bind": {}, "bind": {},
"bsearch": {},
"bzero": {}, "bzero": {},
"calloc": {}, "calloc": {},
"ceil": {}, "ceil": {},

View File

@ -2,4 +2,6 @@
package errno package errno
var CAPI = map[string]struct{}{} var CAPI = map[string]struct{}{
"__darwin_check_fd_set_overflow": {},
}

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo errno/gen.c -crt-import-path -export-defines -export-enums -export-externs X -export-fields F -export-structs -export-typedefs -header -hide _OSSwapInt16,_OSSwapInt32,_OSSwapInt64 -o errno/errno_windows_386.go -pkgname errno', DO NOT EDIT. // Code generated by 'ccgo errno\gen.c -crt-import-path -export-defines -export-enums -export-externs X -export-fields F -export-structs -export-typedefs -header -hide _OSSwapInt16,_OSSwapInt32,_OSSwapInt64 -o errno\errno_windows_386.go -pkgname errno', DO NOT EDIT.
package errno package errno

View File

@ -314,6 +314,13 @@ var X__darwin_check_fd_set_overflow uintptr /* <builtin>:146:5: */
// in between its arguments. __CONCAT can also concatenate double-quoted // in between its arguments. __CONCAT can also concatenate double-quoted
// strings produced by the __STRING macro, but this only works with ANSI C. // strings produced by the __STRING macro, but this only works with ANSI C.
// In non-ANSI C environments, new programs will want ANSI-only C keywords
// deleted from the program and old programs will want them left alone.
// When using a compiler other than gcc, programs using the ANSI C keywords
// const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
// When using "gcc -traditional", we assume that this is the intent; if
// __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
// __unused denotes variables and functions that may not be used, preventing // __unused denotes variables and functions that may not be used, preventing
// the compiler from warning about it if not used. // the compiler from warning about it if not used.

View File

@ -156,6 +156,8 @@ type X__uint128_t = struct {
type X__builtin_va_list = uintptr /* <builtin>:46:14 */ type X__builtin_va_list = uintptr /* <builtin>:46:14 */
type X__float128 = float64 /* <builtin>:47:21 */ type X__float128 = float64 /* <builtin>:47:21 */
var X__darwin_check_fd_set_overflow uintptr /* <builtin>:146:5: */
// Copyright (c) 2000 Apple Computer, Inc. All rights reserved. // Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
// //
// @APPLE_LICENSE_HEADER_START@ // @APPLE_LICENSE_HEADER_START@
@ -314,6 +316,13 @@ type X__float128 = float64 /* <builtin>:47:21 */
// in between its arguments. __CONCAT can also concatenate double-quoted // in between its arguments. __CONCAT can also concatenate double-quoted
// strings produced by the __STRING macro, but this only works with ANSI C. // strings produced by the __STRING macro, but this only works with ANSI C.
// In non-ANSI C environments, new programs will want ANSI-only C keywords
// deleted from the program and old programs will want them left alone.
// When using a compiler other than gcc, programs using the ANSI C keywords
// const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
// When using "gcc -traditional", we assume that this is the intent; if
// __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
// __pure2 can be used for functions that are only a function of their scalar // __pure2 can be used for functions that are only a function of their scalar
// arguments (meaning they can't dereference pointers). // arguments (meaning they can't dereference pointers).
// //

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo errno/gen.c -crt-import-path "" -export-defines "" -export-enums "" -export-externs X -export-fields F -export-structs "" -export-typedefs "" -header -hide _OSSwapInt16,_OSSwapInt32,_OSSwapInt64 -o errno/errno_windows_386.go -pkgname errno', DO NOT EDIT. // Code generated by 'ccgo errno\gen.c -crt-import-path "" -export-defines "" -export-enums "" -export-externs X -export-fields F -export-structs "" -export-typedefs "" -header -hide _OSSwapInt16,_OSSwapInt32,_OSSwapInt64 -o errno\errno_windows_386.go -pkgname errno', DO NOT EDIT.
package errno package errno
@ -112,7 +112,9 @@ const (
EWOULDBLOCK = 140 EWOULDBLOCK = 140
EXDEV = 18 EXDEV = 18
MINGW_DDK_H = 0 MINGW_DDK_H = 0
MINGW_DDRAW_VERSION = 7
MINGW_HAS_DDK_H = 1 MINGW_HAS_DDK_H = 1
MINGW_HAS_DDRAW_H = 1
MINGW_HAS_SECURE_API = 1 MINGW_HAS_SECURE_API = 1
MINGW_SDK_INIT = 0 MINGW_SDK_INIT = 0
STRUNCATE = 80 STRUNCATE = 80
@ -136,12 +138,9 @@ const (
X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES = 0 X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES = 0
X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT = 0 X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT = 0
X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY = 0 X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY = 0
X_CRT_USE_WINAPI_FAMILY_DESKTOP_APP = 0
X_DLL = 0 X_DLL = 0
X_ERRCODE_DEFINED = 0 X_ERRCODE_DEFINED = 0
X_FILE_OFFSET_BITS = 64 X_FILE_OFFSET_BITS = 64
X_ILP32 = 1
X_INC_CORECRT = 0
X_INC_CRTDEFS = 0 X_INC_CRTDEFS = 0
X_INC_CRTDEFS_MACRO = 0 X_INC_CRTDEFS_MACRO = 0
X_INC_ERRNO = 0 X_INC_ERRNO = 0
@ -156,6 +155,7 @@ const (
X_PGLOBAL = 0 X_PGLOBAL = 0
X_PTRDIFF_T_ = 0 X_PTRDIFF_T_ = 0
X_PTRDIFF_T_DEFINED = 0 X_PTRDIFF_T_DEFINED = 0
X_REENTRANT = 1
X_RSIZE_T_DEFINED = 0 X_RSIZE_T_DEFINED = 0
X_SECURECRT_ERRCODE_VALUES_DEFINED = 0 X_SECURECRT_ERRCODE_VALUES_DEFINED = 0
X_SECURECRT_FILL_BUFFER_PATTERN = 0xFD X_SECURECRT_FILL_BUFFER_PATTERN = 0xFD
@ -210,11 +210,6 @@ type Va_list = X__builtin_va_list /* <builtin>:50:27 */
// This file is part of the mingw-w64 runtime package. // This file is part of the mingw-w64 runtime package.
// No warranty is given; refer to the file DISCLAIMER.PD within this package. // No warranty is given; refer to the file DISCLAIMER.PD within this package.
// *
// This file has no copyright assigned and is placed in the Public Domain.
// This file is part of the mingw-w64 runtime package.
// No warranty is given; refer to the file DISCLAIMER.PD within this package.
// This macro holds an monotonic increasing value, which indicates // This macro holds an monotonic increasing value, which indicates
// a specific fix/patch is present on trunk. This value isn't related to // a specific fix/patch is present on trunk. This value isn't related to
// minor/major version-macros. It is increased on demand, if a big // minor/major version-macros. It is increased on demand, if a big
@ -235,12 +230,6 @@ type Va_list = X__builtin_va_list /* <builtin>:50:27 */
// MinGW-w64 has some additional C99 printf/scanf feature support. // MinGW-w64 has some additional C99 printf/scanf feature support.
// So we add some helper macros to ease recognition of them. // So we add some helper macros to ease recognition of them.
// If _FORTIFY_SOURCE is enabled, some inline functions may use
// __builtin_va_arg_pack(). GCC may report an error if the address
// of such a function is used. Set _FORTIFY_VA_ARG=0 in this case.
// Enable workaround for ABI incompatibility on affected platforms
// * // *
// This file has no copyright assigned and is placed in the Public Domain. // This file has no copyright assigned and is placed in the Public Domain.
// This file is part of the mingw-w64 runtime package. // This file is part of the mingw-w64 runtime package.
@ -281,28 +270,26 @@ type Va_list = X__builtin_va_list /* <builtin>:50:27 */
// This file is part of the mingw-w64 runtime package. // This file is part of the mingw-w64 runtime package.
// No warranty is given; refer to the file DISCLAIMER.PD within this package. // No warranty is given; refer to the file DISCLAIMER.PD within this package.
// for backward compatibility
type X__gnuc_va_list = X__builtin_va_list /* vadefs.h:24:29 */ type X__gnuc_va_list = X__builtin_va_list /* vadefs.h:24:29 */
type Ssize_t = int32 /* corecrt.h:52:13 */ type Ssize_t = int32 /* crtdefs.h:47:13 */
type Rsize_t = Size_t /* corecrt.h:57:16 */ type Rsize_t = Size_t /* crtdefs.h:52:16 */
type Intptr_t = int32 /* corecrt.h:69:13 */ type Intptr_t = int32 /* crtdefs.h:64:13 */
type Uintptr_t = uint32 /* corecrt.h:82:22 */ type Uintptr_t = uint32 /* crtdefs.h:77:22 */
type Wint_t = uint16 /* corecrt.h:111:24 */ type Wint_t = uint16 /* crtdefs.h:106:24 */
type Wctype_t = uint16 /* corecrt.h:112:24 */ type Wctype_t = uint16 /* crtdefs.h:107:24 */
type Errno_t = int32 /* corecrt.h:118:13 */ type Errno_t = int32 /* crtdefs.h:113:13 */
type X__time32_t = int32 /* corecrt.h:123:14 */ type X__time32_t = int32 /* crtdefs.h:118:14 */
type X__time64_t = int64 /* corecrt.h:128:35 */ type X__time64_t = int64 /* crtdefs.h:123:35 */
type Time_t = X__time32_t /* corecrt.h:141:20 */ type Time_t = X__time32_t /* crtdefs.h:136:20 */
type Threadlocaleinfostruct = struct { type Threadlocaleinfostruct = struct {
Frefcount int32 Frefcount int32
@ -328,29 +315,29 @@ type Threadlocaleinfostruct = struct {
Fpclmap uintptr Fpclmap uintptr
Fpcumap uintptr Fpcumap uintptr
Flc_time_curr uintptr Flc_time_curr uintptr
} /* corecrt.h:435:1 */ } /* crtdefs.h:422:1 */
type Pthreadlocinfo = uintptr /* corecrt.h:437:39 */ type Pthreadlocinfo = uintptr /* crtdefs.h:424:39 */
type Pthreadmbcinfo = uintptr /* corecrt.h:438:36 */ type Pthreadmbcinfo = uintptr /* crtdefs.h:425:36 */
type Localeinfo_struct = struct { type Localeinfo_struct = struct {
Flocinfo Pthreadlocinfo Flocinfo Pthreadlocinfo
Fmbcinfo Pthreadmbcinfo Fmbcinfo Pthreadmbcinfo
} /* corecrt.h:441:9 */ } /* crtdefs.h:428:9 */
type X_locale_tstruct = Localeinfo_struct /* corecrt.h:444:3 */ type X_locale_tstruct = Localeinfo_struct /* crtdefs.h:431:3 */
type X_locale_t = uintptr /* corecrt.h:444:19 */ type X_locale_t = uintptr /* crtdefs.h:431:19 */
type TagLC_ID = struct { type TagLC_ID = struct {
FwLanguage uint16 FwLanguage uint16
FwCountry uint16 FwCountry uint16
FwCodePage uint16 FwCodePage uint16
} /* corecrt.h:435:1 */ } /* crtdefs.h:422:1 */
type LC_ID = TagLC_ID /* corecrt.h:452:3 */ type LC_ID = TagLC_ID /* crtdefs.h:439:3 */
type LPLC_ID = uintptr /* corecrt.h:452:9 */ type LPLC_ID = uintptr /* crtdefs.h:439:9 */
type Threadlocinfo = Threadlocaleinfostruct /* corecrt.h:487:3 */ type Threadlocinfo = Threadlocaleinfostruct /* crtdefs.h:468:3 */
// Posix thread extensions. // Posix thread extensions.

View File

@ -2,4 +2,6 @@
package fcntl package fcntl
var CAPI = map[string]struct{}{} var CAPI = map[string]struct{}{
"__darwin_check_fd_set_overflow": {},
}

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo fcntl/gen.c -crt-import-path -export-defines -export-enums -export-externs X -export-fields F -export-structs -export-typedefs -header -hide _OSSwapInt16,_OSSwapInt32,_OSSwapInt64 -o fcntl/fcntl_windows_386.go -pkgname fcntl', DO NOT EDIT. // Code generated by 'ccgo fcntl\gen.c -crt-import-path -export-defines -export-enums -export-externs X -export-fields F -export-structs -export-typedefs -header -hide _OSSwapInt16,_OSSwapInt32,_OSSwapInt64 -o fcntl\fcntl_windows_386.go -pkgname fcntl', DO NOT EDIT.
package fcntl package fcntl

View File

@ -409,6 +409,13 @@ var X__darwin_check_fd_set_overflow uintptr /* <builtin>:146:5: */
// in between its arguments. __CONCAT can also concatenate double-quoted // in between its arguments. __CONCAT can also concatenate double-quoted
// strings produced by the __STRING macro, but this only works with ANSI C. // strings produced by the __STRING macro, but this only works with ANSI C.
// In non-ANSI C environments, new programs will want ANSI-only C keywords
// deleted from the program and old programs will want them left alone.
// When using a compiler other than gcc, programs using the ANSI C keywords
// const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
// When using "gcc -traditional", we assume that this is the intent; if
// __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
// __unused denotes variables and functions that may not be used, preventing // __unused denotes variables and functions that may not be used, preventing
// the compiler from warning about it if not used. // the compiler from warning about it if not used.

View File

@ -262,6 +262,8 @@ type X__uint128_t = struct {
type X__builtin_va_list = uintptr /* <builtin>:46:14 */ type X__builtin_va_list = uintptr /* <builtin>:46:14 */
type X__float128 = float64 /* <builtin>:47:21 */ type X__float128 = float64 /* <builtin>:47:21 */
var X__darwin_check_fd_set_overflow uintptr /* <builtin>:146:5: */
// Copyright (c) 2000 Apple Computer, Inc. All rights reserved. // Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
// //
// @APPLE_LICENSE_HEADER_START@ // @APPLE_LICENSE_HEADER_START@
@ -450,6 +452,13 @@ type X__float128 = float64 /* <builtin>:47:21 */
// in between its arguments. __CONCAT can also concatenate double-quoted // in between its arguments. __CONCAT can also concatenate double-quoted
// strings produced by the __STRING macro, but this only works with ANSI C. // strings produced by the __STRING macro, but this only works with ANSI C.
// In non-ANSI C environments, new programs will want ANSI-only C keywords
// deleted from the program and old programs will want them left alone.
// When using a compiler other than gcc, programs using the ANSI C keywords
// const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
// When using "gcc -traditional", we assume that this is the intent; if
// __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
// __pure2 can be used for functions that are only a function of their scalar // __pure2 can be used for functions that are only a function of their scalar
// arguments (meaning they can't dereference pointers). // arguments (meaning they can't dereference pointers).
// //

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo fcntl/gen.c -crt-import-path "" -export-defines "" -export-enums "" -export-externs X -export-fields F -export-structs "" -export-typedefs "" -header -hide _OSSwapInt16,_OSSwapInt32,_OSSwapInt64 -o fcntl/fcntl_windows_386.go -pkgname fcntl', DO NOT EDIT. // Code generated by 'ccgo fcntl\gen.c -crt-import-path "" -export-defines "" -export-enums "" -export-externs X -export-fields F -export-structs "" -export-typedefs "" -header -hide _OSSwapInt16,_OSSwapInt32,_OSSwapInt64 -o fcntl\fcntl_windows_386.go -pkgname fcntl', DO NOT EDIT.
package fcntl package fcntl
@ -33,7 +33,9 @@ const (
DUMMYUNIONNAME9 = 0 DUMMYUNIONNAME9 = 0
F_OK = 0 F_OK = 0
MINGW_DDK_H = 0 MINGW_DDK_H = 0
MINGW_DDRAW_VERSION = 7
MINGW_HAS_DDK_H = 1 MINGW_HAS_DDK_H = 1
MINGW_HAS_DDRAW_H = 1
MINGW_HAS_SECURE_API = 1 MINGW_HAS_SECURE_API = 1
MINGW_SDK_INIT = 0 MINGW_SDK_INIT = 0
O_ACCMODE = 3 O_ACCMODE = 3
@ -81,7 +83,6 @@ const (
X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES = 0 X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES = 0
X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT = 0 X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT = 0
X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY = 0 X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY = 0
X_CRT_USE_WINAPI_FAMILY_DESKTOP_APP = 0
X_DLL = 0 X_DLL = 0
X_ERRCODE_DEFINED = 0 X_ERRCODE_DEFINED = 0
X_FILE_OFFSET_BITS = 64 X_FILE_OFFSET_BITS = 64
@ -89,8 +90,6 @@ const (
X_FILE_OFFSET_BITS_SET_OFFT = 0 X_FILE_OFFSET_BITS_SET_OFFT = 0
X_FINDDATA_T_DEFINED = 0 X_FINDDATA_T_DEFINED = 0
X_FSIZE_T_DEFINED = 0 X_FSIZE_T_DEFINED = 0
X_ILP32 = 1
X_INC_CORECRT = 0
X_INC_CRTDEFS = 0 X_INC_CRTDEFS = 0
X_INC_CRTDEFS_MACRO = 0 X_INC_CRTDEFS_MACRO = 0
X_INC_FCNTL = 0 X_INC_FCNTL = 0
@ -132,6 +131,7 @@ const (
X_PGLOBAL = 0 X_PGLOBAL = 0
X_PTRDIFF_T_ = 0 X_PTRDIFF_T_ = 0
X_PTRDIFF_T_DEFINED = 0 X_PTRDIFF_T_DEFINED = 0
X_REENTRANT = 1
X_RSIZE_T_DEFINED = 0 X_RSIZE_T_DEFINED = 0
X_SECURECRT_FILL_BUFFER_PATTERN = 0xFD X_SECURECRT_FILL_BUFFER_PATTERN = 0xFD
X_SIZE_T_DEFINED = 0 X_SIZE_T_DEFINED = 0
@ -189,11 +189,6 @@ type Va_list = X__builtin_va_list /* <builtin>:50:27 */
// This file is part of the mingw-w64 runtime package. // This file is part of the mingw-w64 runtime package.
// No warranty is given; refer to the file DISCLAIMER.PD within this package. // No warranty is given; refer to the file DISCLAIMER.PD within this package.
// *
// This file has no copyright assigned and is placed in the Public Domain.
// This file is part of the mingw-w64 runtime package.
// No warranty is given; refer to the file DISCLAIMER.PD within this package.
// This macro holds an monotonic increasing value, which indicates // This macro holds an monotonic increasing value, which indicates
// a specific fix/patch is present on trunk. This value isn't related to // a specific fix/patch is present on trunk. This value isn't related to
// minor/major version-macros. It is increased on demand, if a big // minor/major version-macros. It is increased on demand, if a big
@ -214,12 +209,6 @@ type Va_list = X__builtin_va_list /* <builtin>:50:27 */
// MinGW-w64 has some additional C99 printf/scanf feature support. // MinGW-w64 has some additional C99 printf/scanf feature support.
// So we add some helper macros to ease recognition of them. // So we add some helper macros to ease recognition of them.
// If _FORTIFY_SOURCE is enabled, some inline functions may use
// __builtin_va_arg_pack(). GCC may report an error if the address
// of such a function is used. Set _FORTIFY_VA_ARG=0 in this case.
// Enable workaround for ABI incompatibility on affected platforms
// * // *
// This file has no copyright assigned and is placed in the Public Domain. // This file has no copyright assigned and is placed in the Public Domain.
// This file is part of the mingw-w64 runtime package. // This file is part of the mingw-w64 runtime package.
@ -260,28 +249,26 @@ type Va_list = X__builtin_va_list /* <builtin>:50:27 */
// This file is part of the mingw-w64 runtime package. // This file is part of the mingw-w64 runtime package.
// No warranty is given; refer to the file DISCLAIMER.PD within this package. // No warranty is given; refer to the file DISCLAIMER.PD within this package.
// for backward compatibility
type X__gnuc_va_list = X__builtin_va_list /* vadefs.h:24:29 */ type X__gnuc_va_list = X__builtin_va_list /* vadefs.h:24:29 */
type Ssize_t = int32 /* corecrt.h:52:13 */ type Ssize_t = int32 /* crtdefs.h:47:13 */
type Rsize_t = Size_t /* corecrt.h:57:16 */ type Rsize_t = Size_t /* crtdefs.h:52:16 */
type Intptr_t = int32 /* corecrt.h:69:13 */ type Intptr_t = int32 /* crtdefs.h:64:13 */
type Uintptr_t = uint32 /* corecrt.h:82:22 */ type Uintptr_t = uint32 /* crtdefs.h:77:22 */
type Wint_t = uint16 /* corecrt.h:111:24 */ type Wint_t = uint16 /* crtdefs.h:106:24 */
type Wctype_t = uint16 /* corecrt.h:112:24 */ type Wctype_t = uint16 /* crtdefs.h:107:24 */
type Errno_t = int32 /* corecrt.h:118:13 */ type Errno_t = int32 /* crtdefs.h:113:13 */
type X__time32_t = int32 /* corecrt.h:123:14 */ type X__time32_t = int32 /* crtdefs.h:118:14 */
type X__time64_t = int64 /* corecrt.h:128:35 */ type X__time64_t = int64 /* crtdefs.h:123:35 */
type Time_t = X__time32_t /* corecrt.h:141:20 */ type Time_t = X__time32_t /* crtdefs.h:136:20 */
type Threadlocaleinfostruct = struct { type Threadlocaleinfostruct = struct {
Frefcount int32 Frefcount int32
@ -307,29 +294,29 @@ type Threadlocaleinfostruct = struct {
Fpclmap uintptr Fpclmap uintptr
Fpcumap uintptr Fpcumap uintptr
Flc_time_curr uintptr Flc_time_curr uintptr
} /* corecrt.h:435:1 */ } /* crtdefs.h:422:1 */
type Pthreadlocinfo = uintptr /* corecrt.h:437:39 */ type Pthreadlocinfo = uintptr /* crtdefs.h:424:39 */
type Pthreadmbcinfo = uintptr /* corecrt.h:438:36 */ type Pthreadmbcinfo = uintptr /* crtdefs.h:425:36 */
type Localeinfo_struct = struct { type Localeinfo_struct = struct {
Flocinfo Pthreadlocinfo Flocinfo Pthreadlocinfo
Fmbcinfo Pthreadmbcinfo Fmbcinfo Pthreadmbcinfo
} /* corecrt.h:441:9 */ } /* crtdefs.h:428:9 */
type X_locale_tstruct = Localeinfo_struct /* corecrt.h:444:3 */ type X_locale_tstruct = Localeinfo_struct /* crtdefs.h:431:3 */
type X_locale_t = uintptr /* corecrt.h:444:19 */ type X_locale_t = uintptr /* crtdefs.h:431:19 */
type TagLC_ID = struct { type TagLC_ID = struct {
FwLanguage uint16 FwLanguage uint16
FwCountry uint16 FwCountry uint16
FwCodePage uint16 FwCodePage uint16
} /* corecrt.h:435:1 */ } /* crtdefs.h:422:1 */
type LC_ID = TagLC_ID /* corecrt.h:452:3 */ type LC_ID = TagLC_ID /* crtdefs.h:439:3 */
type LPLC_ID = uintptr /* corecrt.h:452:9 */ type LPLC_ID = uintptr /* crtdefs.h:439:9 */
type Threadlocinfo = Threadlocaleinfostruct /* corecrt.h:487:3 */ type Threadlocinfo = Threadlocaleinfostruct /* crtdefs.h:468:3 */
type X_fsize_t = uint32 /* io.h:29:25 */ type X_fsize_t = uint32 /* io.h:29:25 */
type X_finddata32_t = struct { type X_finddata32_t = struct {

View File

@ -3,5 +3,9 @@
package fts package fts
var CAPI = map[string]struct{}{ var CAPI = map[string]struct{}{
"__darwin_check_fd_set": {},
"__darwin_check_fd_set_overflow": {}, "__darwin_check_fd_set_overflow": {},
"__darwin_fd_clr": {},
"__darwin_fd_isset": {},
"__darwin_fd_set": {},
} }

View File

@ -2,4 +2,10 @@
package fts package fts
var CAPI = map[string]struct{}{} var CAPI = map[string]struct{}{
"__darwin_check_fd_set": {},
"__darwin_check_fd_set_overflow": {},
"__darwin_fd_clr": {},
"__darwin_fd_isset": {},
"__darwin_fd_set": {},
}

View File

@ -27,6 +27,7 @@ const (
EF_NO_XATTRS = 0x00000002 EF_NO_XATTRS = 0x00000002
FD_SETSIZE = 1024 FD_SETSIZE = 1024
FTS_AGAIN = 1 FTS_AGAIN = 1
FTS_BLOCK_COMPAR = 0x80000000
FTS_COMFOLLOW = 0x001 FTS_COMFOLLOW = 0x001
FTS_COMFOLLOWDIR = 0x400 FTS_COMFOLLOWDIR = 0x400
FTS_D = 1 FTS_D = 1
@ -379,6 +380,13 @@ var X__darwin_check_fd_set_overflow uintptr /* <builtin>:146:5: */
// in between its arguments. __CONCAT can also concatenate double-quoted // in between its arguments. __CONCAT can also concatenate double-quoted
// strings produced by the __STRING macro, but this only works with ANSI C. // strings produced by the __STRING macro, but this only works with ANSI C.
// In non-ANSI C environments, new programs will want ANSI-only C keywords
// deleted from the program and old programs will want them left alone.
// When using a compiler other than gcc, programs using the ANSI C keywords
// const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
// When using "gcc -traditional", we assume that this is the intent; if
// __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
// __unused denotes variables and functions that may not be used, preventing // __unused denotes variables and functions that may not be used, preventing
// the compiler from warning about it if not used. // the compiler from warning about it if not used.
@ -2946,15 +2954,6 @@ type Errno_t = int32 /* _errno_t.h:30:32 */
// __IPHONE_NA is not defined to a value but is uses as a token by macros to indicate that the API is unavailable // __IPHONE_NA is not defined to a value but is uses as a token by macros to indicate that the API is unavailable
// DO NOT EDIT THIS FILE.
//
// It has been auto-edited by fixincludes from:
//
// "/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/AvailabilityInternal.h"
//
// This had to be done to correct non-standard usages in the
// original, manufacturer supplied header file.
// Copyright (c) 2007-2016 by Apple Inc.. All rights reserved. // Copyright (c) 2007-2016 by Apple Inc.. All rights reserved.
// //
// @APPLE_LICENSE_HEADER_START@ // @APPLE_LICENSE_HEADER_START@
@ -3225,15 +3224,6 @@ type Fd_set1 = struct{ Ffds_bits [32]X__int32_t } /* _fd_def.h:50:9 */
// __IPHONE_NA is not defined to a value but is uses as a token by macros to indicate that the API is unavailable // __IPHONE_NA is not defined to a value but is uses as a token by macros to indicate that the API is unavailable
// DO NOT EDIT THIS FILE.
//
// It has been auto-edited by fixincludes from:
//
// "/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/AvailabilityInternal.h"
//
// This had to be done to correct non-standard usages in the
// original, manufacturer supplied header file.
// Copyright (c) 2007-2016 by Apple Inc.. All rights reserved. // Copyright (c) 2007-2016 by Apple Inc.. All rights reserved.
// //
// @APPLE_LICENSE_HEADER_START@ // @APPLE_LICENSE_HEADER_START@
@ -5132,7 +5122,7 @@ type FTS = struct {
Ffts_pathlen int32 Ffts_pathlen int32
Ffts_nitems int32 Ffts_nitems int32
F__ccgo_pad2 [4]byte F__ccgo_pad2 [4]byte
Ffts_compar uintptr F__56 struct{ Ffts_compar uintptr }
Ffts_options int32 Ffts_options int32
F__ccgo_pad3 [4]byte F__ccgo_pad3 [4]byte
} /* fts.h:111:3 */ } /* fts.h:111:3 */

View File

@ -28,6 +28,7 @@ const (
EF_NO_XATTRS = 0x00000002 EF_NO_XATTRS = 0x00000002
FD_SETSIZE = 1024 FD_SETSIZE = 1024
FTS_AGAIN = 1 FTS_AGAIN = 1
FTS_BLOCK_COMPAR = 0x80000000
FTS_CHDIRFD = 0x08 FTS_CHDIRFD = 0x08
FTS_COMFOLLOW = 0x001 FTS_COMFOLLOW = 0x001
FTS_COMFOLLOWDIR = 0x400 FTS_COMFOLLOWDIR = 0x400
@ -229,7 +230,6 @@ const (
X_FSBLKCNT_T = 0 X_FSBLKCNT_T = 0
X_FSFILCNT_T = 0 X_FSFILCNT_T = 0
X_FTS_H_ = 0 X_FTS_H_ = 0
X_GCC_WRAP_STDINT_H = 0
X_GID_T = 0 X_GID_T = 0
X_ID_T = 0 X_ID_T = 0
X_INO64_T = 0 X_INO64_T = 0
@ -238,7 +238,6 @@ const (
X_INT32_T = 0 X_INT32_T = 0
X_INT64_T = 0 X_INT64_T = 0
X_INT8_T = 0 X_INT8_T = 0
X_INTMAX_T = 0
X_INTPTR_T = 0 X_INTPTR_T = 0
X_IN_ADDR_T = 0 X_IN_ADDR_T = 0
X_IN_PORT_T = 0 X_IN_PORT_T = 0
@ -269,7 +268,6 @@ const (
X_RSIZE_T = 0 X_RSIZE_T = 0
X_SIZE_T = 0 X_SIZE_T = 0
X_SSIZE_T = 0 X_SSIZE_T = 0
X_STDINT_H_ = 0
X_SUSECONDS_T = 0 X_SUSECONDS_T = 0
X_SYS_STAT_H_ = 0 X_SYS_STAT_H_ = 0
X_SYS_TYPES_H_ = 0 X_SYS_TYPES_H_ = 0
@ -278,11 +276,6 @@ const (
X_SYS__TYPES_H_ = 0 X_SYS__TYPES_H_ = 0
X_TIME_T = 0 X_TIME_T = 0
X_UID_T = 0 X_UID_T = 0
X_UINT16_T = 0
X_UINT32_T = 0
X_UINT64_T = 0
X_UINT8_T = 0
X_UINTMAX_T = 0
X_UINTPTR_T = 0 X_UINTPTR_T = 0
X_USECONDS_T = 0 X_USECONDS_T = 0
X_U_CHAR = 0 X_U_CHAR = 0
@ -313,6 +306,8 @@ type X__uint128_t = struct {
type X__builtin_va_list = uintptr /* <builtin>:46:14 */ type X__builtin_va_list = uintptr /* <builtin>:46:14 */
type X__float128 = float64 /* <builtin>:47:21 */ type X__float128 = float64 /* <builtin>:47:21 */
var X__darwin_check_fd_set_overflow uintptr /* <builtin>:146:5: */
// Copyright (c) 2000-2008 Apple Inc. All rights reserved. // Copyright (c) 2000-2008 Apple Inc. All rights reserved.
// //
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@ // @APPLE_OSREFERENCE_LICENSE_HEADER_START@
@ -477,6 +472,13 @@ type X__float128 = float64 /* <builtin>:47:21 */
// in between its arguments. __CONCAT can also concatenate double-quoted // in between its arguments. __CONCAT can also concatenate double-quoted
// strings produced by the __STRING macro, but this only works with ANSI C. // strings produced by the __STRING macro, but this only works with ANSI C.
// In non-ANSI C environments, new programs will want ANSI-only C keywords
// deleted from the program and old programs will want them left alone.
// When using a compiler other than gcc, programs using the ANSI C keywords
// const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
// When using "gcc -traditional", we assume that this is the intent; if
// __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
// __pure2 can be used for functions that are only a function of their scalar // __pure2 can be used for functions that are only a function of their scalar
// arguments (meaning they can't dereference pointers). // arguments (meaning they can't dereference pointers).
// //
@ -1552,727 +1554,39 @@ type X__darwin_pthread_once_t = X_opaque_pthread_once_t /* _pthread_
type X__darwin_pthread_rwlock_t = X_opaque_pthread_rwlock_t /* _pthread_types.h:116:41 */ type X__darwin_pthread_rwlock_t = X_opaque_pthread_rwlock_t /* _pthread_types.h:116:41 */
type X__darwin_pthread_rwlockattr_t = X_opaque_pthread_rwlockattr_t /* _pthread_types.h:117:45 */ type X__darwin_pthread_rwlockattr_t = X_opaque_pthread_rwlockattr_t /* _pthread_types.h:117:45 */
type X__darwin_pthread_t = uintptr /* _pthread_types.h:118:34 */ type X__darwin_pthread_t = uintptr /* _pthread_types.h:118:34 */
type Uint64_t = uint64 /* stdint.h:98:25 */
// Copyright (c) 2000-2007 Apple Inc. All rights reserved. type Int_least64_t = Int64_t /* stdint.h:110:25 */
// type Uint_least64_t = Uint64_t /* stdint.h:111:26 */
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@ type Int_fast64_t = Int64_t /* stdint.h:112:25 */
// type Uint_fast64_t = Uint64_t /* stdint.h:113:26 */
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// Copyright 1995 NeXT Computer, Inc. All rights reserved.
// Copyright (c) 2000-2007 Apple Inc. All rights reserved. type Uint32_t = uint32 /* stdint.h:172:25 */
// Copyright 1995 NeXT Computer, Inc. All rights reserved.
// Copyright (c) 1987, 1991, 1993
// The Regents of the University of California. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by the University of
// California, Berkeley and its contributors.
// 4. Neither the name of the University nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// @(#)endian.h 8.1 (Berkeley) 6/11/93
// Copyright (c) 2000-2018 Apple Inc. All rights reserved. type Int_least32_t = Int32_t /* stdint.h:184:25 */
// type Uint_least32_t = Uint32_t /* stdint.h:185:26 */
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@ type Int_fast32_t = Int32_t /* stdint.h:186:25 */
// type Uint_fast32_t = Uint32_t /* stdint.h:187:26 */
// This file contains Original Code and/or Modifications of Original Code type Uint16_t = uint16 /* stdint.h:207:25 */
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// Copyright 1995 NeXT Computer, Inc. All rights reserved.
// Copyright (c) 1991, 1993
// The Regents of the University of California. All rights reserved.
//
// This code is derived from software contributed to Berkeley by
// Berkeley Software Design, Inc.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by the University of
// California, Berkeley and its contributors.
// 4. Neither the name of the University nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// @(#)cdefs.h 8.8 (Berkeley) 1/9/95
// Define _NOQUAD if the compiler does NOT support 64-bit integers. type Int_least16_t = Int16_t /* stdint.h:215:25 */
// #define _NOQUAD type Uint_least16_t = Uint16_t /* stdint.h:216:26 */
type Int_fast16_t = Int16_t /* stdint.h:217:25 */
type Uint_fast16_t = Uint16_t /* stdint.h:218:26 */
type Uint8_t = uint8 /* stdint.h:226:24 */
// Define the order of 32-bit words in 64-bit words. type Int_least8_t = Int8_t /* stdint.h:232:24 */
type Uint_least8_t = Uint8_t /* stdint.h:233:25 */
type Int_fast8_t = Int8_t /* stdint.h:234:24 */
type Uint_fast8_t = Uint8_t /* stdint.h:235:25 */
// Definitions for byte order, according to byte significance from low // prevent glibc sys/types.h from defining conflicting types
// address to high.
// Copyright (c) 2004, 2006 Apple Computer, Inc. All rights reserved. // C99 7.18.1.4 Integer types capable of holding object pointers.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// Copyright (c) 1995 NeXT Computer, Inc. All rights reserved. // C99 7.18.1.5 Greatest-width integer types.
// Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. type Intmax_t = int64 /* stdint.h:262:26 */
// type Uintmax_t = uint64 /* stdint.h:263:26 */
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// Copyright (c) 1987, 1991, 1993
// The Regents of the University of California. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by the University of
// California, Berkeley and its contributors.
// 4. Neither the name of the University nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
// Copyright (c) 2000-2018 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// Copyright 1995 NeXT Computer, Inc. All rights reserved.
// Copyright (c) 1991, 1993
// The Regents of the University of California. All rights reserved.
//
// This code is derived from software contributed to Berkeley by
// Berkeley Software Design, Inc.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by the University of
// California, Berkeley and its contributors.
// 4. Neither the name of the University nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// @(#)cdefs.h 8.8 (Berkeley) 1/9/95
// Macros for network/external number representation conversion.
// Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// This header is normally included from <libkern/OSByteOrder.h>. However,
// <sys/_endian.h> also includes this in the case of little-endian
// architectures, so that we can map OSByteOrder routines to the hton* and ntoh*
// macros. This results in the asymmetry below; we only include
// <libkern/arch/_OSByteOrder.h> for little-endian architectures.
// Copyright (c) 2003-2007 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// Macros for swapping constant values in the preprocessing stage.
// Copyright (c) 1999-2007 Apple Inc. All rights reserved.
// DO NOT EDIT THIS FILE.
//
// It has been auto-edited by fixincludes from:
//
// "/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk/usr/include/stdint.h"
//
// This had to be done to correct non-standard usages in the
// original, manufacturer supplied header file.
// Copyright (c) 2000-2010 Apple Inc.
// All rights reserved.
// from ISO/IEC 988:1999 spec
// 7.18.1.1 Exact-width integer types
// Copyright (c) 2012 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// Copyright (c) 2012 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// Copyright (c) 2012 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// Copyright (c) 2012 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// Copyright (c) 2012 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
type Uint8_t = uint8 /* _uint8_t.h:31:23 */
// Copyright (c) 2012 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
type Uint16_t = uint16 /* _uint16_t.h:31:24 */
// Copyright (c) 2012 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
type Uint32_t = uint32 /* _uint32_t.h:31:22 */
// Copyright (c) 2012 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
type Uint64_t = uint64 /* _uint64_t.h:31:28 */
// 7.18.1.2 Minimum-width integer types
type Int_least8_t = Int8_t /* stdint.h:38:26 */
type Int_least16_t = Int16_t /* stdint.h:39:25 */
type Int_least32_t = Int32_t /* stdint.h:40:25 */
type Int_least64_t = Int64_t /* stdint.h:41:25 */
type Uint_least8_t = Uint8_t /* stdint.h:42:25 */
type Uint_least16_t = Uint16_t /* stdint.h:43:24 */
type Uint_least32_t = Uint32_t /* stdint.h:44:24 */
type Uint_least64_t = Uint64_t /* stdint.h:45:24 */
// 7.18.1.3 Fastest-width integer types
type Int_fast8_t = Int8_t /* stdint.h:49:27 */
type Int_fast16_t = Int16_t /* stdint.h:50:26 */
type Int_fast32_t = Int32_t /* stdint.h:51:26 */
type Int_fast64_t = Int64_t /* stdint.h:52:26 */
type Uint_fast8_t = Uint8_t /* stdint.h:53:26 */
type Uint_fast16_t = Uint16_t /* stdint.h:54:25 */
type Uint_fast32_t = Uint32_t /* stdint.h:55:25 */
type Uint_fast64_t = Uint64_t /* stdint.h:56:25 */
// 7.18.1.4 Integer types capable of holding object pointers
// Copyright (c) 2003-2007 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// Copyright (c) 2003-2012 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// Copyright (c) 2003-2012 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
// 7.18.1.5 Greatest-width integer types
// Copyright (c) 2012 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
type Intmax_t = int64 /* _intmax_t.h:32:25 */
// Copyright (c) 2012 Apple Inc. All rights reserved.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_START@
//
// This file contains Original Code and/or Modifications of Original Code
// as defined in and that are subject to the Apple Public Source License
// Version 2.0 (the 'License'). You may not use this file except in
// compliance with the License. The rights granted to you under the License
// may not be used to create, or enable the creation or redistribution of,
// unlawful or unlicensed copies of an Apple operating system, or to
// circumvent, violate, or enable the circumvention or violation of, any
// terms of an Apple operating system software license agreement.
//
// Please obtain a copy of the License at
// http://www.opensource.apple.com/apsl/ and read it before using this file.
//
// The Original Code and all software distributed under the License are
// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
// Please see the License for the specific language governing rights and
// limitations under the License.
//
// @APPLE_OSREFERENCE_LICENSE_HEADER_END@
type Uintmax_t = uint64 /* _uintmax_t.h:32:26 */
// Functions for byte reversed loads. // Functions for byte reversed loads.
@ -3735,15 +3049,6 @@ type Errno_t = int32 /* _errno_t.h:30:32 */
// Set up standard Mac OS X versions // Set up standard Mac OS X versions
// DO NOT EDIT THIS FILE.
//
// It has been auto-edited by fixincludes from:
//
// "/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk/usr/include/AvailabilityInternal.h"
//
// This had to be done to correct non-standard usages in the
// original, manufacturer supplied header file.
// Copyright (c) 2007-2016 by Apple Inc.. All rights reserved. // Copyright (c) 2007-2016 by Apple Inc.. All rights reserved.
// //
// @APPLE_LICENSE_HEADER_START@ // @APPLE_LICENSE_HEADER_START@
@ -4037,15 +3342,6 @@ type Fd_set1 = struct{ Ffds_bits [32]X__int32_t } /* _fd_def.h:50:9 */
// Set up standard Mac OS X versions // Set up standard Mac OS X versions
// DO NOT EDIT THIS FILE.
//
// It has been auto-edited by fixincludes from:
//
// "/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk/usr/include/AvailabilityInternal.h"
//
// This had to be done to correct non-standard usages in the
// original, manufacturer supplied header file.
// Copyright (c) 2007-2016 by Apple Inc.. All rights reserved. // Copyright (c) 2007-2016 by Apple Inc.. All rights reserved.
// //
// @APPLE_LICENSE_HEADER_START@ // @APPLE_LICENSE_HEADER_START@
@ -5910,7 +5206,7 @@ type FTS = struct {
Ffts_pathlen int32 Ffts_pathlen int32
Ffts_nitems int32 Ffts_nitems int32
F__ccgo_pad2 [4]byte F__ccgo_pad2 [4]byte
Ffts_compar uintptr F__56 struct{ Ffts_compar uintptr }
Ffts_options int32 Ffts_options int32
F__ccgo_pad3 [4]byte F__ccgo_pad3 [4]byte
} /* fts.h:111:3 */ } /* fts.h:111:3 */

View File

@ -2,4 +2,6 @@
package grp package grp
var CAPI = map[string]struct{}{} var CAPI = map[string]struct{}{
"__darwin_check_fd_set_overflow": {},
}

View File

@ -219,6 +219,13 @@ var X__darwin_check_fd_set_overflow uintptr /* <builtin>:146:5: */
// in between its arguments. __CONCAT can also concatenate double-quoted // in between its arguments. __CONCAT can also concatenate double-quoted
// strings produced by the __STRING macro, but this only works with ANSI C. // strings produced by the __STRING macro, but this only works with ANSI C.
// In non-ANSI C environments, new programs will want ANSI-only C keywords
// deleted from the program and old programs will want them left alone.
// When using a compiler other than gcc, programs using the ANSI C keywords
// const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
// When using "gcc -traditional", we assume that this is the intent; if
// __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
// __unused denotes variables and functions that may not be used, preventing // __unused denotes variables and functions that may not be used, preventing
// the compiler from warning about it if not used. // the compiler from warning about it if not used.

View File

@ -58,6 +58,8 @@ type X__uint128_t = struct {
type X__builtin_va_list = uintptr /* <builtin>:46:14 */ type X__builtin_va_list = uintptr /* <builtin>:46:14 */
type X__float128 = float64 /* <builtin>:47:21 */ type X__float128 = float64 /* <builtin>:47:21 */
var X__darwin_check_fd_set_overflow uintptr /* <builtin>:146:5: */
// - // -
// Copyright (c) 1989, 1993 // Copyright (c) 1989, 1993
// The Regents of the University of California. All rights reserved. // The Regents of the University of California. All rights reserved.
@ -219,6 +221,13 @@ type X__float128 = float64 /* <builtin>:47:21 */
// in between its arguments. __CONCAT can also concatenate double-quoted // in between its arguments. __CONCAT can also concatenate double-quoted
// strings produced by the __STRING macro, but this only works with ANSI C. // strings produced by the __STRING macro, but this only works with ANSI C.
// In non-ANSI C environments, new programs will want ANSI-only C keywords
// deleted from the program and old programs will want them left alone.
// When using a compiler other than gcc, programs using the ANSI C keywords
// const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
// When using "gcc -traditional", we assume that this is the intent; if
// __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
// __pure2 can be used for functions that are only a function of their scalar // __pure2 can be used for functions that are only a function of their scalar
// arguments (meaning they can't dereference pointers). // arguments (meaning they can't dereference pointers).
// //

View File

@ -713,7 +713,10 @@ func init() {
num, err := strconv.ParseInt(fields[1], 10, 32) num, err := strconv.ParseInt(fields[1], 10, 32)
if err != nil { if err != nil {
panic(err) // If we find lines that don't match the expected format we skip over them.
// The expected format is <protocol> <number> <aliases> ...
// As we're using strings.Fields for splitting the line, failures can happen if the protocol field contains white spaces.
continue
} }
protoent := &Protoent{ protoent := &Protoent{

View File

@ -2,4 +2,6 @@
package langinfo package langinfo
var CAPI = map[string]struct{}{} var CAPI = map[string]struct{}{
"__darwin_check_fd_set_overflow": {},
}

View File

@ -259,6 +259,13 @@ var X__darwin_check_fd_set_overflow uintptr /* <builtin>:146:5: */
// in between its arguments. __CONCAT can also concatenate double-quoted // in between its arguments. __CONCAT can also concatenate double-quoted
// strings produced by the __STRING macro, but this only works with ANSI C. // strings produced by the __STRING macro, but this only works with ANSI C.
// In non-ANSI C environments, new programs will want ANSI-only C keywords
// deleted from the program and old programs will want them left alone.
// When using a compiler other than gcc, programs using the ANSI C keywords
// const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
// When using "gcc -traditional", we assume that this is the intent; if
// __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
// __unused denotes variables and functions that may not be used, preventing // __unused denotes variables and functions that may not be used, preventing
// the compiler from warning about it if not used. // the compiler from warning about it if not used.

View File

@ -111,6 +111,8 @@ type X__uint128_t = struct {
type X__builtin_va_list = uintptr /* <builtin>:46:14 */ type X__builtin_va_list = uintptr /* <builtin>:46:14 */
type X__float128 = float64 /* <builtin>:47:21 */ type X__float128 = float64 /* <builtin>:47:21 */
var X__darwin_check_fd_set_overflow uintptr /* <builtin>:146:5: */
// - // -
// Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org> // Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
// All rights reserved. // All rights reserved.
@ -259,6 +261,13 @@ type X__float128 = float64 /* <builtin>:47:21 */
// in between its arguments. __CONCAT can also concatenate double-quoted // in between its arguments. __CONCAT can also concatenate double-quoted
// strings produced by the __STRING macro, but this only works with ANSI C. // strings produced by the __STRING macro, but this only works with ANSI C.
// In non-ANSI C environments, new programs will want ANSI-only C keywords
// deleted from the program and old programs will want them left alone.
// When using a compiler other than gcc, programs using the ANSI C keywords
// const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
// When using "gcc -traditional", we assume that this is the intent; if
// __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
// __pure2 can be used for functions that are only a function of their scalar // __pure2 can be used for functions that are only a function of their scalar
// arguments (meaning they can't dereference pointers). // arguments (meaning they can't dereference pointers).
// //

4
vendor/modernc.org/libc/libc.go generated vendored
View File

@ -161,6 +161,10 @@ func X_exit(_ *TLS, status int32) {
} }
func SetEnviron(t *TLS, env []string) { func SetEnviron(t *TLS, env []string) {
if environInitialized {
return
}
environInitialized = true environInitialized = true
p := Xcalloc(t, 1, types.Size_t((len(env)+1)*(int(uintptrSize)))) p := Xcalloc(t, 1, types.Size_t((len(env)+1)*(int(uintptrSize))))
if p == 0 { if p == 0 {

View File

@ -1481,7 +1481,7 @@ func X__xuname(t *TLS, namesize int32, namebuf uintptr) int32 {
} }
// int chflags(const char *path, u_int flags); // int chflags(const char *path, u_int flags);
func Xchflags(t *TLS, path uintptr, flags uint64) int32 { func Xchflags(t *TLS, path uintptr, flags uint32) int32 {
if err := unix.Chflags(GoString(path), int(flags)); err != nil { if err := unix.Chflags(GoString(path), int(flags)); err != nil {
if dmesgs { if dmesgs {
dmesg("%v: %v FAIL", origin(1), err) dmesg("%v: %v FAIL", origin(1), err)
@ -1605,3 +1605,29 @@ func X__assert2(t *TLS, file uintptr, line int32, fn, expr uintptr) {
func Xgetpagesize(t *TLS) int32 { func Xgetpagesize(t *TLS) int32 {
return int32(unix.Getpagesize()) return int32(unix.Getpagesize())
} }
const PTHREAD_MUTEX_DEFAULT = 0
// The pthread_mutex_init() function shall initialize the mutex referenced by
// mutex with attributes specified by attr. If attr is NULL, the default mutex
// attributes are used; the effect shall be the same as passing the address of
// a default mutex attributes object. Upon successful initialization, the state
// of the mutex becomes initialized and unlocked.
//
// If successful, the pthread_mutex_destroy() and pthread_mutex_init()
// functions shall return zero; otherwise, an error number shall be returned to
// indicate the error.
//
// int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
func Xpthread_mutex_init(t *TLS, pMutex, pAttr uintptr) int32 {
typ := PTHREAD_MUTEX_DEFAULT
if pAttr != 0 {
typ = int(X__ccgo_pthreadMutexattrGettype(t, pAttr))
}
mutexesMu.Lock()
defer mutexesMu.Unlock()
mutexes[pMutex] = newMutex(typ)
return 0
}

View File

@ -380,7 +380,7 @@ func Xalarm(t *TLS, seconds uint32) uint32 {
} }
// int getnameinfo(const struct sockaddr * restrict sa, socklen_t salen, char * restrict host, socklen_t hostlen, char * restrict serv, socklen_t servlen, int flags); // int getnameinfo(const struct sockaddr * restrict sa, socklen_t salen, char * restrict host, socklen_t hostlen, char * restrict serv, socklen_t servlen, int flags);
func Xgetnameinfo(tls *TLS, sa1 uintptr, sl socklen_t, node uintptr, nodelen socklen_t, serv uintptr, servlen socklen_t, flags int32) int32 { /* getnameinfo.c:125:5: */ func Xgetnameinfo(tls *TLS, sa1 uintptr, sl socklen_t, node uintptr, nodelen size_t, serv uintptr, servlen size_t, flags int32) int32 { /* getnameinfo.c:125:5: */
panic(todo("")) panic(todo(""))
//TODO bp := tls.Alloc(347) //TODO bp := tls.Alloc(347)
//TODO defer tls.Free(347) //TODO defer tls.Free(347)

View File

@ -2,4 +2,6 @@
package limits package limits
var CAPI = map[string]struct{}{} var CAPI = map[string]struct{}{
"__darwin_check_fd_set_overflow": {},
}

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo limits/gen.c -crt-import-path -export-defines -export-enums -export-externs X -export-fields F -export-structs -export-typedefs -header -hide _OSSwapInt16,_OSSwapInt32,_OSSwapInt64 -o limits/limits_windows_386.go -pkgname limits', DO NOT EDIT. // Code generated by 'ccgo limits\gen.c -crt-import-path -export-defines -export-enums -export-externs X -export-fields F -export-structs -export-typedefs -header -hide _OSSwapInt16,_OSSwapInt32,_OSSwapInt64 -o limits\limits_windows_386.go -pkgname limits', DO NOT EDIT.
package limits package limits

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo limits/gen.c -crt-import-path "" -export-defines "" -export-enums "" -export-externs X -export-fields F -export-structs "" -export-typedefs "" -header -hide _OSSwapInt16,_OSSwapInt32,_OSSwapInt64 -o limits/limits_windows_386.go -pkgname limits', DO NOT EDIT. // Code generated by 'ccgo limits\gen.c -crt-import-path "" -export-defines "" -export-enums "" -export-externs X -export-fields F -export-structs "" -export-typedefs "" -header -hide _OSSwapInt16,_OSSwapInt32,_OSSwapInt64 -o limits\limits_windows_386.go -pkgname limits', DO NOT EDIT.
package limits package limits
@ -44,7 +44,9 @@ const (
LONG_MIN = -2147483648 LONG_MIN = -2147483648
MB_LEN_MAX = 5 MB_LEN_MAX = 5
MINGW_DDK_H = 0 MINGW_DDK_H = 0
MINGW_DDRAW_VERSION = 7
MINGW_HAS_DDK_H = 1 MINGW_HAS_DDK_H = 1
MINGW_HAS_DDRAW_H = 1
MINGW_HAS_SECURE_API = 1 MINGW_HAS_SECURE_API = 1
MINGW_SDK_INIT = 0 MINGW_SDK_INIT = 0
PATH_MAX = 260 PATH_MAX = 260
@ -79,7 +81,6 @@ const (
X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES = 0 X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES = 0
X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT = 0 X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT = 0
X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY = 0 X_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY = 0
X_CRT_USE_WINAPI_FAMILY_DESKTOP_APP = 0
X_DLL = 0 X_DLL = 0
X_ERRCODE_DEFINED = 0 X_ERRCODE_DEFINED = 0
X_FILE_OFFSET_BITS = 64 X_FILE_OFFSET_BITS = 64
@ -92,8 +93,6 @@ const (
X_I64_MIN = -9223372036854775808 X_I64_MIN = -9223372036854775808
X_I8_MAX = 127 X_I8_MAX = 127
X_I8_MIN = -128 X_I8_MIN = -128
X_ILP32 = 1
X_INC_CORECRT = 0
X_INC_CRTDEFS = 0 X_INC_CRTDEFS = 0
X_INC_CRTDEFS_MACRO = 0 X_INC_CRTDEFS_MACRO = 0
X_INC_LIMITS = 0 X_INC_LIMITS = 0
@ -109,6 +108,7 @@ const (
X_PGLOBAL = 0 X_PGLOBAL = 0
X_PTRDIFF_T_ = 0 X_PTRDIFF_T_ = 0
X_PTRDIFF_T_DEFINED = 0 X_PTRDIFF_T_DEFINED = 0
X_REENTRANT = 1
X_RSIZE_T_DEFINED = 0 X_RSIZE_T_DEFINED = 0
X_SECURECRT_FILL_BUFFER_PATTERN = 0xFD X_SECURECRT_FILL_BUFFER_PATTERN = 0xFD
X_SIZE_T_DEFINED = 0 X_SIZE_T_DEFINED = 0
@ -146,7 +146,7 @@ type X__float128 = float64 /* <builtin>:47:21 */
type Va_list = X__builtin_va_list /* <builtin>:50:27 */ type Va_list = X__builtin_va_list /* <builtin>:50:27 */
// Copyright (C) 1992-2020 Free Software Foundation, Inc. // Copyright (C) 1992-2018 Free Software Foundation, Inc.
// //
// This file is part of GCC. // This file is part of GCC.
// //
@ -200,11 +200,6 @@ type Va_list = X__builtin_va_list /* <builtin>:50:27 */
// This file is part of the mingw-w64 runtime package. // This file is part of the mingw-w64 runtime package.
// No warranty is given; refer to the file DISCLAIMER.PD within this package. // No warranty is given; refer to the file DISCLAIMER.PD within this package.
// *
// This file has no copyright assigned and is placed in the Public Domain.
// This file is part of the mingw-w64 runtime package.
// No warranty is given; refer to the file DISCLAIMER.PD within this package.
// This macro holds an monotonic increasing value, which indicates // This macro holds an monotonic increasing value, which indicates
// a specific fix/patch is present on trunk. This value isn't related to // a specific fix/patch is present on trunk. This value isn't related to
// minor/major version-macros. It is increased on demand, if a big // minor/major version-macros. It is increased on demand, if a big
@ -225,12 +220,6 @@ type Va_list = X__builtin_va_list /* <builtin>:50:27 */
// MinGW-w64 has some additional C99 printf/scanf feature support. // MinGW-w64 has some additional C99 printf/scanf feature support.
// So we add some helper macros to ease recognition of them. // So we add some helper macros to ease recognition of them.
// If _FORTIFY_SOURCE is enabled, some inline functions may use
// __builtin_va_arg_pack(). GCC may report an error if the address
// of such a function is used. Set _FORTIFY_VA_ARG=0 in this case.
// Enable workaround for ABI incompatibility on affected platforms
// * // *
// This file has no copyright assigned and is placed in the Public Domain. // This file has no copyright assigned and is placed in the Public Domain.
// This file is part of the mingw-w64 runtime package. // This file is part of the mingw-w64 runtime package.
@ -271,28 +260,26 @@ type Va_list = X__builtin_va_list /* <builtin>:50:27 */
// This file is part of the mingw-w64 runtime package. // This file is part of the mingw-w64 runtime package.
// No warranty is given; refer to the file DISCLAIMER.PD within this package. // No warranty is given; refer to the file DISCLAIMER.PD within this package.
// for backward compatibility
type X__gnuc_va_list = X__builtin_va_list /* vadefs.h:24:29 */ type X__gnuc_va_list = X__builtin_va_list /* vadefs.h:24:29 */
type Ssize_t = int32 /* corecrt.h:52:13 */ type Ssize_t = int32 /* crtdefs.h:47:13 */
type Rsize_t = Size_t /* corecrt.h:57:16 */ type Rsize_t = Size_t /* crtdefs.h:52:16 */
type Intptr_t = int32 /* corecrt.h:69:13 */ type Intptr_t = int32 /* crtdefs.h:64:13 */
type Uintptr_t = uint32 /* corecrt.h:82:22 */ type Uintptr_t = uint32 /* crtdefs.h:77:22 */
type Wint_t = uint16 /* corecrt.h:111:24 */ type Wint_t = uint16 /* crtdefs.h:106:24 */
type Wctype_t = uint16 /* corecrt.h:112:24 */ type Wctype_t = uint16 /* crtdefs.h:107:24 */
type Errno_t = int32 /* corecrt.h:118:13 */ type Errno_t = int32 /* crtdefs.h:113:13 */
type X__time32_t = int32 /* corecrt.h:123:14 */ type X__time32_t = int32 /* crtdefs.h:118:14 */
type X__time64_t = int64 /* corecrt.h:128:35 */ type X__time64_t = int64 /* crtdefs.h:123:35 */
type Time_t = X__time32_t /* corecrt.h:141:20 */ type Time_t = X__time32_t /* crtdefs.h:136:20 */
type Threadlocaleinfostruct = struct { type Threadlocaleinfostruct = struct {
Frefcount int32 Frefcount int32
@ -318,29 +305,29 @@ type Threadlocaleinfostruct = struct {
Fpclmap uintptr Fpclmap uintptr
Fpcumap uintptr Fpcumap uintptr
Flc_time_curr uintptr Flc_time_curr uintptr
} /* corecrt.h:435:1 */ } /* crtdefs.h:422:1 */
type Pthreadlocinfo = uintptr /* corecrt.h:437:39 */ type Pthreadlocinfo = uintptr /* crtdefs.h:424:39 */
type Pthreadmbcinfo = uintptr /* corecrt.h:438:36 */ type Pthreadmbcinfo = uintptr /* crtdefs.h:425:36 */
type Localeinfo_struct = struct { type Localeinfo_struct = struct {
Flocinfo Pthreadlocinfo Flocinfo Pthreadlocinfo
Fmbcinfo Pthreadmbcinfo Fmbcinfo Pthreadmbcinfo
} /* corecrt.h:441:9 */ } /* crtdefs.h:428:9 */
type X_locale_tstruct = Localeinfo_struct /* corecrt.h:444:3 */ type X_locale_tstruct = Localeinfo_struct /* crtdefs.h:431:3 */
type X_locale_t = uintptr /* corecrt.h:444:19 */ type X_locale_t = uintptr /* crtdefs.h:431:19 */
type TagLC_ID = struct { type TagLC_ID = struct {
FwLanguage uint16 FwLanguage uint16
FwCountry uint16 FwCountry uint16
FwCodePage uint16 FwCodePage uint16
} /* corecrt.h:435:1 */ } /* crtdefs.h:422:1 */
type LC_ID = TagLC_ID /* corecrt.h:452:3 */ type LC_ID = TagLC_ID /* crtdefs.h:439:3 */
type LPLC_ID = uintptr /* corecrt.h:452:9 */ type LPLC_ID = uintptr /* crtdefs.h:439:9 */
type Threadlocinfo = Threadlocaleinfostruct /* corecrt.h:487:3 */ type Threadlocinfo = Threadlocaleinfostruct /* crtdefs.h:468:3 */
// File system limits // File system limits
// //
@ -350,7 +337,7 @@ type Threadlocinfo = Threadlocaleinfostruct /* corecrt.h:487:3 */
// are semantically identical, with a limit of 259 characters for the // are semantically identical, with a limit of 259 characters for the
// path name, plus one for a terminating NUL, for a total of 260. // path name, plus one for a terminating NUL, for a total of 260.
// Copyright (C) 1991-2020 Free Software Foundation, Inc. // Copyright (C) 1991-2018 Free Software Foundation, Inc.
// //
// This file is part of GCC. // This file is part of GCC.
// //

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo -D__environ=environ -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -hide isascii,isspace,tolower,toupper -nostdinc -nostdlib -o ../musl_darwin_amd64.go -pkgname libc -static-locals-prefix _s -Iarch/x86_64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c ../darwin/table.c src/env/putenv.c src/env/setenv.c src/env/unsetenv.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__toread.c src/stdio/__uflow.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strchrnul.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c', DO NOT EDIT. // Code generated by 'ccgo -D__environ=environ -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -hide isascii,isspace,tolower,toupper -nostdinc -nostdlib -o ../musl_darwin_amd64.go -pkgname libc -static-locals-prefix _s -Iarch/x86_64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c ../darwin/table.c src/env/putenv.c src/env/setenv.c src/env/unsetenv.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__toread.c src/stdio/__uflow.c src/stdlib/bsearch.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strchrnul.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c', DO NOT EDIT.
package libc package libc
@ -4415,6 +4415,26 @@ func X__uflow(tls *TLS, f uintptr) int32 { /* __uflow.c:6:5: */
return -1 return -1
} }
func Xbsearch(tls *TLS, key uintptr, base uintptr, nel size_t, width size_t, cmp uintptr) uintptr { /* bsearch.c:3:6: */
var try uintptr
var sign int32
for nel > uint64(0) {
try = base + uintptr(width*(nel/uint64(2)))
sign = (*struct {
f func(*TLS, uintptr, uintptr) int32
})(unsafe.Pointer(&struct{ uintptr }{cmp})).f(tls, key, try)
if sign < 0 {
nel = nel / uint64(2)
} else if sign > 0 {
base = try + uintptr(width)
nel = nel - (nel/uint64(2) + uint64(1))
} else {
return try
}
}
return uintptr(0)
}
func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */ func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */
bp := tls.Alloc(232) bp := tls.Alloc(232)
defer tls.Free(232) defer tls.Free(232)

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo -D__environ=environ -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -hide isascii,isspace,tolower,toupper -nostdinc -nostdlib -o ../musl_darwin_arm64.go -pkgname libc -static-locals-prefix _s -Iarch/aarch64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c ../darwin/table.c src/env/putenv.c src/env/setenv.c src/env/unsetenv.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__toread.c src/stdio/__uflow.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strchrnul.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c', DO NOT EDIT. // Code generated by 'ccgo -D__environ=environ -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -hide isascii,isspace,tolower,toupper -nostdinc -nostdlib -o ../musl_darwin_arm64.go -pkgname libc -static-locals-prefix _s -Iarch/aarch64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c ../darwin/table.c src/env/putenv.c src/env/setenv.c src/env/unsetenv.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__toread.c src/stdio/__uflow.c src/stdlib/bsearch.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strchrnul.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c', DO NOT EDIT.
package libc package libc
@ -357,6 +357,8 @@ type size_t = uint64 /* <builtin>:9:23 */
type wchar_t = int32 /* <builtin>:15:24 */ type wchar_t = int32 /* <builtin>:15:24 */
var X__darwin_check_fd_set_overflow uintptr /* <builtin>:146:5: */
// pthread opaque structures // pthread opaque structures
type __darwin_pthread_handler_rec = struct { type __darwin_pthread_handler_rec = struct {
@ -4413,6 +4415,26 @@ func X__uflow(tls *TLS, f uintptr) int32 { /* __uflow.c:6:5: */
return -1 return -1
} }
func Xbsearch(tls *TLS, key uintptr, base uintptr, nel size_t, width size_t, cmp uintptr) uintptr { /* bsearch.c:3:6: */
var try uintptr
var sign int32
for nel > uint64(0) {
try = base + uintptr(width*(nel/uint64(2)))
sign = (*struct {
f func(*TLS, uintptr, uintptr) int32
})(unsafe.Pointer(&struct{ uintptr }{cmp})).f(tls, key, try)
if sign < 0 {
nel = nel / uint64(2)
} else if sign > 0 {
base = try + uintptr(width)
nel = nel - (nel/uint64(2) + uint64(1))
} else {
return try
}
}
return uintptr(0)
}
func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */ func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */
bp := tls.Alloc(232) bp := tls.Alloc(232)
defer tls.Free(232) defer tls.Free(232)

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6,getnameinfo,gethostbyaddr_r, -nostdinc -nostdlib -o ../musl_freebsd_amd64.go -pkgname libc -static-locals-prefix _s -Iarch/x86_64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c ../freebsd/table.cpp.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/stdio/__toread.c src/stdio/__uflow.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strnlen.c src/string/strspn.c', DO NOT EDIT. // Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6,getnameinfo,gethostbyaddr_r, -nostdinc -nostdlib -o ../musl_freebsd_amd64.go -pkgname libc -static-locals-prefix _s -Iarch/x86_64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c ../freebsd/table.cpp.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isspace.c src/ctype/isupper.c src/ctype/isxdigit.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/stdio/__toread.c src/stdio/__uflow.c src/stdlib/bsearch.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strnlen.c src/string/strspn.c', DO NOT EDIT.
package libc package libc
@ -3356,6 +3356,51 @@ func X__isdigit_l(tls *TLS, c int32, l locale_t) int32 { /* isdigit.c:9:5: */
return Xisdigit(tls, c) return Xisdigit(tls, c)
} }
func Xislower(tls *TLS, c int32) int32 { /* islower.c:4:5: */
return Bool32(uint32(c)-uint32('a') < uint32(26))
}
func X__islower_l(tls *TLS, c int32, l locale_t) int32 { /* islower.c:9:5: */
return Xislower(tls, c)
}
func Xisprint(tls *TLS, c int32) int32 { /* isprint.c:4:5: */
return Bool32(uint32(c)-uint32(0x20) < uint32(0x5f))
}
func X__isprint_l(tls *TLS, c int32, l locale_t) int32 { /* isprint.c:9:5: */
return Xisprint(tls, c)
}
func Xisspace(tls *TLS, c int32) int32 { /* isspace.c:4:5: */
return Bool32(c == ' ' || uint32(c)-uint32('\t') < uint32(5))
}
func X__isspace_l(tls *TLS, c int32, l locale_t) int32 { /* isspace.c:9:5: */
return Xisspace(tls, c)
}
func Xisupper(tls *TLS, c int32) int32 { /* isupper.c:4:5: */
return Bool32(uint32(c)-uint32('A') < uint32(26))
}
func X__isupper_l(tls *TLS, c int32, l locale_t) int32 { /* isupper.c:9:5: */
return Xisupper(tls, c)
}
func Xisxdigit(tls *TLS, c int32) int32 { /* isxdigit.c:3:5: */
return Bool32(func() int32 {
if 0 != 0 {
return Xisdigit(tls, c)
}
return Bool32(uint32(c)-uint32('0') < uint32(10))
}() != 0 || uint32(c)|uint32(32)-uint32('a') < uint32(6))
}
func X__isxdigit_l(tls *TLS, c int32, l locale_t) int32 { /* isxdigit.c:8:5: */
return Xisxdigit(tls, c)
}
type uintptr_t = uint64 /* alltypes.h:55:24 */ type uintptr_t = uint64 /* alltypes.h:55:24 */
type intptr_t = int64 /* alltypes.h:70:15 */ type intptr_t = int64 /* alltypes.h:70:15 */
@ -6667,6 +6712,26 @@ func X__uflow(tls *TLS, f uintptr) int32 { /* __uflow.c:6:5: */
return -1 return -1
} }
func Xbsearch(tls *TLS, key uintptr, base uintptr, nel size_t, width size_t, cmp uintptr) uintptr { /* bsearch.c:3:6: */
var try uintptr
var sign int32
for nel > uint64(0) {
try = base + uintptr(width*(nel/uint64(2)))
sign = (*struct {
f func(*TLS, uintptr, uintptr) int32
})(unsafe.Pointer(&struct{ uintptr }{cmp})).f(tls, key, try)
if sign < 0 {
nel = nel / uint64(2)
} else if sign > 0 {
base = try + uintptr(width)
nel = nel - (nel/uint64(2) + uint64(1))
} else {
return try
}
}
return uintptr(0)
}
func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */ func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */
bp := tls.Alloc(232) bp := tls.Alloc(232)
defer tls.Free(232) defer tls.Free(232)

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_linux_386.go -pkgname libc -static-locals-prefix _s -Iarch/i386 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/__ctype_b_loc.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isupper.c src/ctype/isxdigit.c src/dirent/closedir.c src/dirent/opendir.c src/dirent/readdir.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/multibyte/internal.c src/multibyte/mbrtowc.c src/multibyte/mbsinit.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/gethostbyname_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__lockfile.c src/stdio/__toread.c src/stdio/__uflow.c src/stdio/sscanf.c src/stdio/vfscanf.c src/stdio/vsscanf.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c src/thread/pthread_attr_get.c src/thread/pthread_attr_setdetachstate.c src/thread/pthread_mutex_lock.c src/thread/pthread_mutexattr_destroy.c src/thread/pthread_mutexattr_init.c src/thread/pthread_mutexattr_settype.c', DO NOT EDIT. // Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_linux_386.go -pkgname libc -static-locals-prefix _s -Iarch/i386 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/__ctype_b_loc.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isupper.c src/ctype/isxdigit.c src/dirent/closedir.c src/dirent/opendir.c src/dirent/readdir.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/multibyte/internal.c src/multibyte/mbrtowc.c src/multibyte/mbsinit.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/gethostbyname_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__lockfile.c src/stdio/__toread.c src/stdio/__uflow.c src/stdio/sscanf.c src/stdio/vfscanf.c src/stdio/vsscanf.c src/stdlib/bsearch.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c src/thread/pthread_attr_get.c src/thread/pthread_attr_setdetachstate.c src/thread/pthread_mutex_lock.c src/thread/pthread_mutexattr_destroy.c src/thread/pthread_mutexattr_init.c src/thread/pthread_mutexattr_settype.c', DO NOT EDIT.
package libc package libc
@ -6452,6 +6452,26 @@ func Xvsscanf(tls *TLS, s uintptr, fmt uintptr, ap va_list) int32 { /* vsscanf.c
return Xvfscanf(tls, bp, fmt, ap) return Xvfscanf(tls, bp, fmt, ap)
} }
func Xbsearch(tls *TLS, key uintptr, base uintptr, nel size_t, width size_t, cmp uintptr) uintptr { /* bsearch.c:3:6: */
var try uintptr
var sign int32
for nel > size_t(0) {
try = base + uintptr(width*(nel/size_t(2)))
sign = (*struct {
f func(*TLS, uintptr, uintptr) int32
})(unsafe.Pointer(&struct{ uintptr }{cmp})).f(tls, key, try)
if sign < 0 {
nel = nel / size_t(2)
} else if sign > 0 {
base = try + uintptr(width)
nel = nel - (nel/size_t(2) + size_t(1))
} else {
return try
}
}
return uintptr(0)
}
func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */ func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */
bp := tls.Alloc(136) bp := tls.Alloc(136)
defer tls.Free(136) defer tls.Free(136)

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_linux_amd64.go -pkgname libc -static-locals-prefix _s -Iarch/x86_64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/__ctype_b_loc.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isupper.c src/ctype/isxdigit.c src/dirent/closedir.c src/dirent/opendir.c src/dirent/readdir.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/multibyte/internal.c src/multibyte/mbrtowc.c src/multibyte/mbsinit.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/gethostbyname_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__lockfile.c src/stdio/__toread.c src/stdio/__uflow.c src/stdio/sscanf.c src/stdio/vfscanf.c src/stdio/vsscanf.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c src/thread/pthread_attr_get.c src/thread/pthread_attr_setdetachstate.c src/thread/pthread_mutex_lock.c src/thread/pthread_mutexattr_destroy.c src/thread/pthread_mutexattr_init.c src/thread/pthread_mutexattr_settype.c', DO NOT EDIT. // Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_linux_amd64.go -pkgname libc -static-locals-prefix _s -Iarch/x86_64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/__ctype_b_loc.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isupper.c src/ctype/isxdigit.c src/dirent/closedir.c src/dirent/opendir.c src/dirent/readdir.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/multibyte/internal.c src/multibyte/mbrtowc.c src/multibyte/mbsinit.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/gethostbyname_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__lockfile.c src/stdio/__toread.c src/stdio/__uflow.c src/stdio/sscanf.c src/stdio/vfscanf.c src/stdio/vsscanf.c src/stdlib/bsearch.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c src/thread/pthread_attr_get.c src/thread/pthread_attr_setdetachstate.c src/thread/pthread_mutex_lock.c src/thread/pthread_mutexattr_destroy.c src/thread/pthread_mutexattr_init.c src/thread/pthread_mutexattr_settype.c', DO NOT EDIT.
package libc package libc
@ -6507,6 +6507,26 @@ func Xvsscanf(tls *TLS, s uintptr, fmt uintptr, ap va_list) int32 { /* vsscanf.c
return Xvfscanf(tls, bp, fmt, ap) return Xvfscanf(tls, bp, fmt, ap)
} }
func Xbsearch(tls *TLS, key uintptr, base uintptr, nel size_t, width size_t, cmp uintptr) uintptr { /* bsearch.c:3:6: */
var try uintptr
var sign int32
for nel > uint64(0) {
try = base + uintptr(width*(nel/uint64(2)))
sign = (*struct {
f func(*TLS, uintptr, uintptr) int32
})(unsafe.Pointer(&struct{ uintptr }{cmp})).f(tls, key, try)
if sign < 0 {
nel = nel / uint64(2)
} else if sign > 0 {
base = try + uintptr(width)
nel = nel - (nel/uint64(2) + uint64(1))
} else {
return try
}
}
return uintptr(0)
}
func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */ func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */
bp := tls.Alloc(232) bp := tls.Alloc(232)
defer tls.Free(232) defer tls.Free(232)

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_linux_arm.go -pkgname libc -static-locals-prefix _s -Iarch/arm -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/__ctype_b_loc.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isupper.c src/ctype/isxdigit.c src/dirent/closedir.c src/dirent/opendir.c src/dirent/readdir.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/multibyte/internal.c src/multibyte/mbrtowc.c src/multibyte/mbsinit.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/gethostbyname_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__lockfile.c src/stdio/__toread.c src/stdio/__uflow.c src/stdio/sscanf.c src/stdio/vfscanf.c src/stdio/vsscanf.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c src/thread/pthread_attr_get.c src/thread/pthread_attr_setdetachstate.c src/thread/pthread_mutex_lock.c src/thread/pthread_mutexattr_destroy.c src/thread/pthread_mutexattr_init.c src/thread/pthread_mutexattr_settype.c', DO NOT EDIT. // Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_linux_arm.go -pkgname libc -static-locals-prefix _s -Iarch/arm -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/__ctype_b_loc.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isupper.c src/ctype/isxdigit.c src/dirent/closedir.c src/dirent/opendir.c src/dirent/readdir.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/multibyte/internal.c src/multibyte/mbrtowc.c src/multibyte/mbsinit.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/gethostbyname_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__lockfile.c src/stdio/__toread.c src/stdio/__uflow.c src/stdio/sscanf.c src/stdio/vfscanf.c src/stdio/vsscanf.c src/stdlib/bsearch.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c src/thread/pthread_attr_get.c src/thread/pthread_attr_setdetachstate.c src/thread/pthread_mutex_lock.c src/thread/pthread_mutexattr_destroy.c src/thread/pthread_mutexattr_init.c src/thread/pthread_mutexattr_settype.c', DO NOT EDIT.
package libc package libc
@ -6485,6 +6485,26 @@ func Xvsscanf(tls *TLS, s uintptr, fmt uintptr, ap va_list) int32 { /* vsscanf.c
return Xvfscanf(tls, bp, fmt, ap) return Xvfscanf(tls, bp, fmt, ap)
} }
func Xbsearch(tls *TLS, key uintptr, base uintptr, nel size_t, width size_t, cmp uintptr) uintptr { /* bsearch.c:3:6: */
var try uintptr
var sign int32
for nel > size_t(0) {
try = base + uintptr(width*(nel/size_t(2)))
sign = (*struct {
f func(*TLS, uintptr, uintptr) int32
})(unsafe.Pointer(&struct{ uintptr }{cmp})).f(tls, key, try)
if sign < 0 {
nel = nel / size_t(2)
} else if sign > 0 {
base = try + uintptr(width)
nel = nel - (nel/size_t(2) + size_t(1))
} else {
return try
}
}
return uintptr(0)
}
func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */ func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */
bp := tls.Alloc(144) bp := tls.Alloc(144)
defer tls.Free(144) defer tls.Free(144)

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_linux_arm64.go -pkgname libc -static-locals-prefix _s -Iarch/aarch64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/__ctype_b_loc.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isupper.c src/ctype/isxdigit.c src/dirent/closedir.c src/dirent/opendir.c src/dirent/readdir.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/multibyte/internal.c src/multibyte/mbrtowc.c src/multibyte/mbsinit.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/gethostbyname_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__lockfile.c src/stdio/__toread.c src/stdio/__uflow.c src/stdio/sscanf.c src/stdio/vfscanf.c src/stdio/vsscanf.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c src/thread/pthread_attr_get.c src/thread/pthread_attr_setdetachstate.c src/thread/pthread_mutex_lock.c src/thread/pthread_mutexattr_destroy.c src/thread/pthread_mutexattr_init.c src/thread/pthread_mutexattr_settype.c', DO NOT EDIT. // Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_linux_arm64.go -pkgname libc -static-locals-prefix _s -Iarch/aarch64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/__ctype_b_loc.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isupper.c src/ctype/isxdigit.c src/dirent/closedir.c src/dirent/opendir.c src/dirent/readdir.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/multibyte/internal.c src/multibyte/mbrtowc.c src/multibyte/mbsinit.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/gethostbyname_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__lockfile.c src/stdio/__toread.c src/stdio/__uflow.c src/stdio/sscanf.c src/stdio/vfscanf.c src/stdio/vsscanf.c src/stdlib/bsearch.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c src/thread/pthread_attr_get.c src/thread/pthread_attr_setdetachstate.c src/thread/pthread_mutex_lock.c src/thread/pthread_mutexattr_destroy.c src/thread/pthread_mutexattr_init.c src/thread/pthread_mutexattr_settype.c', DO NOT EDIT.
package libc package libc
@ -6595,6 +6595,26 @@ func Xvsscanf(tls *TLS, s uintptr, fmt uintptr, ap va_list) int32 { /* vsscanf.c
return Xvfscanf(tls, bp, fmt, ap) return Xvfscanf(tls, bp, fmt, ap)
} }
func Xbsearch(tls *TLS, key uintptr, base uintptr, nel size_t, width size_t, cmp uintptr) uintptr { /* bsearch.c:3:6: */
var try uintptr
var sign int32
for nel > uint64(0) {
try = base + uintptr(width*(nel/uint64(2)))
sign = (*struct {
f func(*TLS, uintptr, uintptr) int32
})(unsafe.Pointer(&struct{ uintptr }{cmp})).f(tls, key, try)
if sign < 0 {
nel = nel / uint64(2)
} else if sign > 0 {
base = try + uintptr(width)
nel = nel - (nel/uint64(2) + uint64(1))
} else {
return try
}
}
return uintptr(0)
}
func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */ func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */
bp := tls.Alloc(232) bp := tls.Alloc(232)
defer tls.Free(232) defer tls.Free(232)

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_linux_s390x.go -pkgname libc -static-locals-prefix _s -Iarch/s390x -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/__ctype_b_loc.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isupper.c src/ctype/isxdigit.c src/dirent/closedir.c src/dirent/opendir.c src/dirent/readdir.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/multibyte/internal.c src/multibyte/mbrtowc.c src/multibyte/mbsinit.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/gethostbyname_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__lockfile.c src/stdio/__toread.c src/stdio/__uflow.c src/stdio/sscanf.c src/stdio/vfscanf.c src/stdio/vsscanf.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c src/thread/pthread_attr_get.c src/thread/pthread_attr_setdetachstate.c src/thread/pthread_mutex_lock.c src/thread/pthread_mutexattr_destroy.c src/thread/pthread_mutexattr_init.c src/thread/pthread_mutexattr_settype.c', DO NOT EDIT. // Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_linux_s390x.go -pkgname libc -static-locals-prefix _s -Iarch/s390x -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/__ctype_b_loc.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isupper.c src/ctype/isxdigit.c src/dirent/closedir.c src/dirent/opendir.c src/dirent/readdir.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/locale/localeconv.c src/math/__fpclassify.c src/math/__fpclassifyf.c src/math/__fpclassifyl.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/nanf.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/multibyte/internal.c src/multibyte/mbrtowc.c src/multibyte/mbsinit.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/gethostbyname_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/prng/rand_r.c src/stdio/__lockfile.c src/stdio/__toread.c src/stdio/__uflow.c src/stdio/sscanf.c src/stdio/vfscanf.c src/stdio/vsscanf.c src/stdlib/bsearch.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strlcat.c src/string/strlcpy.c src/string/strncasecmp.c src/string/strncat.c src/string/strnlen.c src/string/strspn.c src/string/strtok.c src/thread/pthread_attr_get.c src/thread/pthread_attr_setdetachstate.c src/thread/pthread_mutex_lock.c src/thread/pthread_mutexattr_destroy.c src/thread/pthread_mutexattr_init.c src/thread/pthread_mutexattr_settype.c', DO NOT EDIT.
package libc package libc
@ -6535,6 +6535,26 @@ func Xvsscanf(tls *TLS, s uintptr, fmt uintptr, ap va_list) int32 { /* vsscanf.c
return Xvfscanf(tls, bp, fmt, ap) return Xvfscanf(tls, bp, fmt, ap)
} }
func Xbsearch(tls *TLS, key uintptr, base uintptr, nel size_t, width size_t, cmp uintptr) uintptr { /* bsearch.c:3:6: */
var try uintptr
var sign int32
for nel > uint64(0) {
try = base + uintptr(width*(nel/uint64(2)))
sign = (*struct {
f func(*TLS, uintptr, uintptr) int32
})(unsafe.Pointer(&struct{ uintptr }{cmp})).f(tls, key, try)
if sign < 0 {
nel = nel / uint64(2)
} else if sign > 0 {
base = try + uintptr(width)
nel = nel - (nel/uint64(2) + uint64(1))
} else {
return try
}
}
return uintptr(0)
}
func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */ func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */
bp := tls.Alloc(232) bp := tls.Alloc(232)
defer tls.Free(232) defer tls.Free(232)

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6,getnameinfo,gethostbyaddr_r, -nostdinc -nostdlib -o ../musl_openbsd_amd64.go -pkgname libc -static-locals-prefix _s -Iarch/x86_64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c ../freebsd/table.cpp.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/isprint.c src/ctype/isspace.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/stdio/__toread.c src/stdio/__uflow.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strnlen.c src/string/strspn.c', DO NOT EDIT. // Code generated by 'ccgo -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6,getnameinfo,gethostbyaddr_r, -nostdinc -nostdlib -o ../musl_openbsd_amd64.go -pkgname libc -static-locals-prefix _s -Iarch/x86_64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c ../freebsd/table.cpp.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isspace.c src/ctype/isupper.c src/ctype/isxdigit.c src/internal/floatscan.c src/internal/intscan.c src/internal/shgetc.c src/math/copysignl.c src/math/fabsl.c src/math/fmodl.c src/math/rint.c src/math/scalbn.c src/math/scalbnl.c src/network/freeaddrinfo.c src/network/getaddrinfo.c src/network/gethostbyaddr.c src/network/gethostbyaddr_r.c src/network/gethostbyname.c src/network/gethostbyname2.c src/network/gethostbyname2_r.c src/network/getnameinfo.c src/network/h_errno.c src/network/inet_aton.c src/network/inet_ntop.c src/network/inet_pton.c src/network/lookup_ipliteral.c src/network/lookup_name.c src/network/lookup_serv.c src/stdio/__toread.c src/stdio/__uflow.c src/stdlib/bsearch.c src/stdlib/strtod.c src/stdlib/strtol.c src/string/strdup.c src/string/strnlen.c src/string/strspn.c', DO NOT EDIT.
package libc package libc
@ -3356,6 +3356,14 @@ func X__isdigit_l(tls *TLS, c int32, l locale_t) int32 { /* isdigit.c:9:5: */
return Xisdigit(tls, c) return Xisdigit(tls, c)
} }
func Xislower(tls *TLS, c int32) int32 { /* islower.c:4:5: */
return Bool32(uint32(c)-uint32('a') < uint32(26))
}
func X__islower_l(tls *TLS, c int32, l locale_t) int32 { /* islower.c:9:5: */
return Xislower(tls, c)
}
func Xisprint(tls *TLS, c int32) int32 { /* isprint.c:4:5: */ func Xisprint(tls *TLS, c int32) int32 { /* isprint.c:4:5: */
return Bool32(uint32(c)-uint32(0x20) < uint32(0x5f)) return Bool32(uint32(c)-uint32(0x20) < uint32(0x5f))
} }
@ -3372,6 +3380,27 @@ func X__isspace_l(tls *TLS, c int32, l locale_t) int32 { /* isspace.c:9:5: */
return Xisspace(tls, c) return Xisspace(tls, c)
} }
func Xisupper(tls *TLS, c int32) int32 { /* isupper.c:4:5: */
return Bool32(uint32(c)-uint32('A') < uint32(26))
}
func X__isupper_l(tls *TLS, c int32, l locale_t) int32 { /* isupper.c:9:5: */
return Xisupper(tls, c)
}
func Xisxdigit(tls *TLS, c int32) int32 { /* isxdigit.c:3:5: */
return Bool32(func() int32 {
if 0 != 0 {
return Xisdigit(tls, c)
}
return Bool32(uint32(c)-uint32('0') < uint32(10))
}() != 0 || uint32(c)|uint32(32)-uint32('a') < uint32(6))
}
func X__isxdigit_l(tls *TLS, c int32, l locale_t) int32 { /* isxdigit.c:8:5: */
return Xisxdigit(tls, c)
}
type uintptr_t = uint64 /* alltypes.h:55:24 */ type uintptr_t = uint64 /* alltypes.h:55:24 */
type intptr_t = int64 /* alltypes.h:70:15 */ type intptr_t = int64 /* alltypes.h:70:15 */
@ -6683,6 +6712,26 @@ func X__uflow(tls *TLS, f uintptr) int32 { /* __uflow.c:6:5: */
return -1 return -1
} }
func Xbsearch(tls *TLS, key uintptr, base uintptr, nel size_t, width size_t, cmp uintptr) uintptr { /* bsearch.c:3:6: */
var try uintptr
var sign int32
for nel > uint64(0) {
try = base + uintptr(width*(nel/uint64(2)))
sign = (*struct {
f func(*TLS, uintptr, uintptr) int32
})(unsafe.Pointer(&struct{ uintptr }{cmp})).f(tls, key, try)
if sign < 0 {
nel = nel / uint64(2)
} else if sign > 0 {
base = try + uintptr(width)
nel = nel - (nel/uint64(2) + uint64(1))
} else {
return try
}
}
return uintptr(0)
}
func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */ func strtox(tls *TLS, s uintptr, p uintptr, prec int32) float64 { /* strtod.c:6:20: */
bp := tls.Alloc(232) bp := tls.Alloc(232)
defer tls.Free(232) defer tls.Free(232)

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo -D__environ=environ -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_windows_386.go -pkgname libc -static-locals-prefix _s -Iarch/i386 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isspace.c src/ctype/isxdigit.c src/env/putenv.c src/env/setenv.c src/env/unsetenv.c src/multibyte/wcrtomb.c src/multibyte/wcsrtombs.c src/multibyte/wcstombs.c src/string/strchrnul.c src/string/strdup.c', DO NOT EDIT. // Code generated by 'ccgo -D__environ=environ -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_windows_386.go -pkgname libc -static-locals-prefix _s -Iarch\i386 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isspace.c src/ctype/isxdigit.c src/env/putenv.c src/env/setenv.c src/env/unsetenv.c src/multibyte/wcrtomb.c src/multibyte/wcsrtombs.c src/multibyte/wcstombs.c src/stdlib/bsearch.c src/string/strchrnul.c src/string/strdup.c', DO NOT EDIT.
package libc package libc
@ -863,32 +863,32 @@ type mode_t = uint32 /* alltypes.h:175:18 */
type syscall_arg_t = int32 /* syscall.h:22:14 */ type syscall_arg_t = int32 /* syscall.h:22:14 */
func a_cas(tls *TLS, p uintptr, t int32, s int32) int32 { /* atomic_arch.h:2:19: */ func a_cas(tls *TLS, p uintptr, t int32, s int32) int32 { /* atomic_arch.h:2:19: */
panic(`arch/i386/atomic_arch.h:4:2: assembler statements not supported`) panic(`arch\i386\atomic_arch.h:4:2: assembler statements not supported`)
return t return t
} }
func a_and(tls *TLS, p uintptr, v int32) { /* atomic_arch.h:29:20: */ func a_and(tls *TLS, p uintptr, v int32) { /* atomic_arch.h:29:20: */
panic(`arch/i386/atomic_arch.h:31:2: assembler statements not supported`) panic(`arch\i386\atomic_arch.h:31:2: assembler statements not supported`)
} }
func a_or(tls *TLS, p uintptr, v int32) { /* atomic_arch.h:37:20: */ func a_or(tls *TLS, p uintptr, v int32) { /* atomic_arch.h:37:20: */
panic(`arch/i386/atomic_arch.h:39:2: assembler statements not supported`) panic(`arch\i386\atomic_arch.h:39:2: assembler statements not supported`)
} }
func a_ctz_64(tls *TLS, x uint64_t) int32 { /* atomic_arch.h:87:19: */ func a_ctz_64(tls *TLS, x uint64_t) int32 { /* atomic_arch.h:87:19: */
var r int32 var r int32
panic(`arch/i386/atomic_arch.h:90:2: assembler statements not supported`) panic(`arch\i386\atomic_arch.h:90:2: assembler statements not supported`)
return r return r
} }
func a_ctz_32(tls *TLS, x uint32_t) int32 { /* atomic_arch.h:96:19: */ func a_ctz_32(tls *TLS, x uint32_t) int32 { /* atomic_arch.h:96:19: */
var r int32 var r int32
panic(`arch/i386/atomic_arch.h:99:2: assembler statements not supported`) panic(`arch\i386\atomic_arch.h:99:2: assembler statements not supported`)
return r return r
} }
func a_clz_32(tls *TLS, x uint32_t) int32 { /* atomic_arch.h:104:19: */ func a_clz_32(tls *TLS, x uint32_t) int32 { /* atomic_arch.h:104:19: */
panic(`arch/i386/atomic_arch.h:106:2: assembler statements not supported`) panic(`arch\i386\atomic_arch.h:106:2: assembler statements not supported`)
return int32(x) return int32(x)
} }
@ -917,7 +917,7 @@ type __timer = struct {
func __pthread_self(tls *TLS) uintptr { /* pthread_arch.h:1:30: */ func __pthread_self(tls *TLS) uintptr { /* pthread_arch.h:1:30: */
var self uintptr var self uintptr
panic(`arch/i386/pthread_arch.h:4:2: assembler statements not supported`) panic(`arch\i386\pthread_arch.h:4:2: assembler statements not supported`)
return self return self
} }
@ -1039,6 +1039,26 @@ func Xwcstombs(tls *TLS, s uintptr, ws uintptr, n size_t) size_t { /* wcstombs.c
return Xwcsrtombs(tls, s, bp, n, uintptr(0)) return Xwcsrtombs(tls, s, bp, n, uintptr(0))
} }
func Xbsearch(tls *TLS, key uintptr, base uintptr, nel size_t, width size_t, cmp uintptr) uintptr { /* bsearch.c:3:6: */
var try uintptr
var sign int32
for nel > size_t(0) {
try = base + uintptr(width*(nel/size_t(2)))
sign = (*struct {
f func(*TLS, uintptr, uintptr) int32
})(unsafe.Pointer(&struct{ uintptr }{cmp})).f(tls, key, try)
if sign < 0 {
nel = nel / size_t(2)
} else if sign > 0 {
base = try + uintptr(width)
nel = nel - (nel/size_t(2) + size_t(1))
} else {
return try
}
}
return uintptr(0)
}
// Support signed or unsigned plain-char // Support signed or unsigned plain-char
// Implementation choices... // Implementation choices...

View File

@ -1,4 +1,4 @@
// Code generated by 'ccgo -D__environ=environ -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_windows_amd64.go -pkgname libc -static-locals-prefix _s -Iarch\x86_64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isspace.c src/ctype/isxdigit.c src/env/putenv.c src/env/setenv.c src/env/unsetenv.c src/multibyte/wcrtomb.c src/multibyte/wcsrtombs.c src/multibyte/wcstombs.c src/string/strchrnul.c src/string/strdup.c', DO NOT EDIT. // Code generated by 'ccgo -D__environ=environ -export-externs X -hide __syscall0,__syscall1,__syscall2,__syscall3,__syscall4,__syscall5,__syscall6 -nostdinc -nostdlib -o ../musl_windows_amd64.go -pkgname libc -static-locals-prefix _s -Iarch\x86_64 -Iarch/generic -Iobj/src/internal -Isrc/include -Isrc/internal -Iobj/include -Iinclude copyright.c src/ctype/isalnum.c src/ctype/isalpha.c src/ctype/isdigit.c src/ctype/islower.c src/ctype/isprint.c src/ctype/isspace.c src/ctype/isxdigit.c src/env/putenv.c src/env/setenv.c src/env/unsetenv.c src/multibyte/wcrtomb.c src/multibyte/wcsrtombs.c src/multibyte/wcstombs.c src/stdlib/bsearch.c src/string/strchrnul.c src/string/strdup.c', DO NOT EDIT.
package libc package libc
@ -1062,6 +1062,26 @@ func Xwcstombs(tls *TLS, s uintptr, ws uintptr, n size_t) size_t { /* wcstombs.c
return Xwcsrtombs(tls, s, bp, n, uintptr(0)) return Xwcsrtombs(tls, s, bp, n, uintptr(0))
} }
func Xbsearch(tls *TLS, key uintptr, base uintptr, nel size_t, width size_t, cmp uintptr) uintptr { /* bsearch.c:3:6: */
var try uintptr
var sign int32
for nel > uint64(0) {
try = base + uintptr(width*(nel/uint64(2)))
sign = (*struct {
f func(*TLS, uintptr, uintptr) int32
})(unsafe.Pointer(&struct{ uintptr }{cmp})).f(tls, key, try)
if sign < 0 {
nel = nel / uint64(2)
} else if sign > 0 {
base = try + uintptr(width)
nel = nel - (nel/uint64(2) + uint64(1))
} else {
return try
}
}
return uintptr(0)
}
// Support signed or unsigned plain-char // Support signed or unsigned plain-char
// Implementation choices... // Implementation choices...

Some files were not shown because too many files have changed in this diff Show More