mirror of
https://github.com/go-i2p/sam3.git
synced 2025-06-09 18:53:50 -04:00
purge ramp
This commit is contained in:
10
Makefile
10
Makefile
@ -1,10 +1,16 @@
|
|||||||
|
|
||||||
USER_GH=eyedeekay
|
USER_GH=eyedeekay
|
||||||
VERSION=0.32.1
|
VERSION=0.32.2
|
||||||
|
packagename=sam3
|
||||||
|
|
||||||
echo:
|
echo:
|
||||||
@echo "type make version to do release $(VERSION)"
|
@echo "type make version to do release $(VERSION)"
|
||||||
|
|
||||||
version:
|
version:
|
||||||
gothub release -s $(GITHUB_TOKEN) -u $(USER_GH) -r sam3 -t v$(VERSION) -d "version $(VERSION)"
|
gothub release -s $(GITHUB_TOKEN) -u $(USER_GH) -r $(packagename) -t v$(VERSION) -d "version $(VERSION)"
|
||||||
|
|
||||||
|
tar:
|
||||||
|
tar --exclude .git \
|
||||||
|
--exclude .go \
|
||||||
|
--exclude bin \
|
||||||
|
-cJvf ../$(packagename)_$(VERSION).orig.tar.xz .
|
||||||
|
8
debian/changelog
vendored
8
debian/changelog
vendored
@ -1,3 +1,11 @@
|
|||||||
|
golang-github-eyedeekay-sam3 (0.3.2.2) bionic; urgency=medium
|
||||||
|
|
||||||
|
[ idk ]
|
||||||
|
* Purge ramp
|
||||||
|
|
||||||
|
-- idk <hankhill19580@gmail.com> Sat, 7 Dec 2019 22:05:34 -0500
|
||||||
|
|
||||||
|
|
||||||
golang-github-eyedeekay-sam3 (0.3.2.1) bionic; urgency=medium
|
golang-github-eyedeekay-sam3 (0.3.2.1) bionic; urgency=medium
|
||||||
|
|
||||||
[ idk ]
|
[ idk ]
|
||||||
|
1
debian/files
vendored
1
debian/files
vendored
@ -1 +0,0 @@
|
|||||||
golang-github-eyedeekay-sam3_0.3.2.01_source.buildinfo devel optional
|
|
369
emit-options.go
Normal file
369
emit-options.go
Normal file
@ -0,0 +1,369 @@
|
|||||||
|
package sam3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
//Option is a SAMEmit Option
|
||||||
|
type Option func(*SAMEmit) error
|
||||||
|
|
||||||
|
//SetType sets the type of the forwarder server
|
||||||
|
func SetType(s string) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if s == "STREAM" {
|
||||||
|
c.Style = s
|
||||||
|
return nil
|
||||||
|
} else if s == "DATAGRAM" {
|
||||||
|
c.Style = s
|
||||||
|
return nil
|
||||||
|
}else if s == "RAW" {
|
||||||
|
c.Style = s
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid session STYLE=%s, must be STREAM, DATAGRAM, or RAW")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSAMAddress sets the SAM address all-at-once
|
||||||
|
func SetSAMAddress(s string) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
sp := strings.Split(s, ":")
|
||||||
|
if len(sp) > 2 {
|
||||||
|
return fmt.Errorf("Invalid address string: %s", sp)
|
||||||
|
}
|
||||||
|
if len(sp) == 2 {
|
||||||
|
c.I2PConfig.SamPort = sp[1]
|
||||||
|
}
|
||||||
|
c.I2PConfig.SamHost = sp[0]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetSAMHost sets the host of the SAMEmit's SAM bridge
|
||||||
|
func SetSAMHost(s string) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
c.I2PConfig.SamHost = s
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetSAMPort sets the port of the SAMEmit's SAM bridge using a string
|
||||||
|
func SetSAMPort(s string) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
port, err := strconv.Atoi(s)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Invalid SAM Port %s; non-number", s)
|
||||||
|
}
|
||||||
|
if port < 65536 && port > -1 {
|
||||||
|
c.I2PConfig.SamPort = s
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid port")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetName sets the host of the SAMEmit's SAM bridge
|
||||||
|
func SetName(s string) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
c.I2PConfig.TunName = s
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetInLength sets the number of hops inbound
|
||||||
|
func SetInLength(u int) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if u < 7 && u >= 0 {
|
||||||
|
c.I2PConfig.InLength = strconv.Itoa(u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid inbound tunnel length")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetOutLength sets the number of hops outbound
|
||||||
|
func SetOutLength(u int) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if u < 7 && u >= 0 {
|
||||||
|
c.I2PConfig.OutLength = strconv.Itoa(u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid outbound tunnel length")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetInVariance sets the variance of a number of hops inbound
|
||||||
|
func SetInVariance(i int) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if i < 7 && i > -7 {
|
||||||
|
c.I2PConfig.InVariance = strconv.Itoa(i)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid inbound tunnel length")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetOutVariance sets the variance of a number of hops outbound
|
||||||
|
func SetOutVariance(i int) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if i < 7 && i > -7 {
|
||||||
|
c.I2PConfig.OutVariance = strconv.Itoa(i)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid outbound tunnel variance")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetInQuantity sets the inbound tunnel quantity
|
||||||
|
func SetInQuantity(u int) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if u <= 16 && u > 0 {
|
||||||
|
c.I2PConfig.InQuantity = strconv.Itoa(u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid inbound tunnel quantity")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetOutQuantity sets the outbound tunnel quantity
|
||||||
|
func SetOutQuantity(u int) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if u <= 16 && u > 0 {
|
||||||
|
c.I2PConfig.OutQuantity = strconv.Itoa(u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid outbound tunnel quantity")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetInBackups sets the inbound tunnel backups
|
||||||
|
func SetInBackups(u int) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if u < 6 && u >= 0 {
|
||||||
|
c.I2PConfig.InBackupQuantity = strconv.Itoa(u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid inbound tunnel backup quantity")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetOutBackups sets the inbound tunnel backups
|
||||||
|
func SetOutBackups(u int) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if u < 6 && u >= 0 {
|
||||||
|
c.I2PConfig.OutBackupQuantity = strconv.Itoa(u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid outbound tunnel backup quantity")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetEncrypt tells the router to use an encrypted leaseset
|
||||||
|
func SetEncrypt(b bool) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if b {
|
||||||
|
c.I2PConfig.EncryptLeaseSet = "true"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
c.I2PConfig.EncryptLeaseSet = "false"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetLeaseSetKey sets the host of the SAMEmit's SAM bridge
|
||||||
|
func SetLeaseSetKey(s string) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
c.I2PConfig.LeaseSetKey = s
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetLeaseSetPrivateKey sets the host of the SAMEmit's SAM bridge
|
||||||
|
func SetLeaseSetPrivateKey(s string) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
c.I2PConfig.LeaseSetPrivateKey = s
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetLeaseSetPrivateSigningKey sets the host of the SAMEmit's SAM bridge
|
||||||
|
func SetLeaseSetPrivateSigningKey(s string) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
c.I2PConfig.LeaseSetPrivateSigningKey = s
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetMessageReliability sets the host of the SAMEmit's SAM bridge
|
||||||
|
func SetMessageReliability(s string) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
c.I2PConfig.MessageReliability = s
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetAllowZeroIn tells the tunnel to accept zero-hop peers
|
||||||
|
func SetAllowZeroIn(b bool) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if b {
|
||||||
|
c.I2PConfig.InAllowZeroHop = "true"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
c.I2PConfig.InAllowZeroHop = "false"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetAllowZeroOut tells the tunnel to accept zero-hop peers
|
||||||
|
func SetAllowZeroOut(b bool) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if b {
|
||||||
|
c.I2PConfig.OutAllowZeroHop = "true"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
c.I2PConfig.OutAllowZeroHop = "false"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetCompress tells clients to use compression
|
||||||
|
func SetCompress(b bool) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if b {
|
||||||
|
c.I2PConfig.UseCompression = "true"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
c.I2PConfig.UseCompression = "false"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetFastRecieve tells clients to use compression
|
||||||
|
func SetFastRecieve(b bool) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if b {
|
||||||
|
c.I2PConfig.FastRecieve = "true"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
c.I2PConfig.FastRecieve = "false"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetReduceIdle tells the connection to reduce it's tunnels during extended idle time.
|
||||||
|
func SetReduceIdle(b bool) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if b {
|
||||||
|
c.I2PConfig.ReduceIdle = "true"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
c.I2PConfig.ReduceIdle = "false"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetReduceIdleTime sets the time to wait before reducing tunnels to idle levels
|
||||||
|
func SetReduceIdleTime(u int) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
c.I2PConfig.ReduceIdleTime = "300000"
|
||||||
|
if u >= 6 {
|
||||||
|
c.I2PConfig.ReduceIdleTime = strconv.Itoa((u * 60) * 1000)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid reduce idle timeout(Measured in minutes) %v", u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetReduceIdleTimeMs sets the time to wait before reducing tunnels to idle levels in milliseconds
|
||||||
|
func SetReduceIdleTimeMs(u int) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
c.I2PConfig.ReduceIdleTime = "300000"
|
||||||
|
if u >= 300000 {
|
||||||
|
c.I2PConfig.ReduceIdleTime = strconv.Itoa(u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid reduce idle timeout(Measured in milliseconds) %v", u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetReduceIdleQuantity sets minimum number of tunnels to reduce to during idle time
|
||||||
|
func SetReduceIdleQuantity(u int) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if u < 5 {
|
||||||
|
c.I2PConfig.ReduceIdleQuantity = strconv.Itoa(u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid reduce tunnel quantity")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetCloseIdle tells the connection to close it's tunnels during extended idle time.
|
||||||
|
func SetCloseIdle(b bool) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if b {
|
||||||
|
c.I2PConfig.CloseIdle = "true"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
c.I2PConfig.CloseIdle = "false"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetCloseIdleTime sets the time to wait before closing tunnels to idle levels
|
||||||
|
func SetCloseIdleTime(u int) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
c.I2PConfig.CloseIdleTime = "300000"
|
||||||
|
if u >= 6 {
|
||||||
|
c.I2PConfig.CloseIdleTime = strconv.Itoa((u * 60) * 1000)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid close idle timeout(Measured in minutes) %v", u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetCloseIdleTimeMs sets the time to wait before closing tunnels to idle levels in milliseconds
|
||||||
|
func SetCloseIdleTimeMs(u int) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
c.I2PConfig.CloseIdleTime = "300000"
|
||||||
|
if u >= 300000 {
|
||||||
|
c.I2PConfig.CloseIdleTime = strconv.Itoa(u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid close idle timeout(Measured in milliseconds) %v", u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetAccessListType tells the system to treat the AccessList as a whitelist
|
||||||
|
func SetAccessListType(s string) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if s == "whitelist" {
|
||||||
|
c.I2PConfig.AccessListType = "whitelist"
|
||||||
|
return nil
|
||||||
|
} else if s == "blacklist" {
|
||||||
|
c.I2PConfig.AccessListType = "blacklist"
|
||||||
|
return nil
|
||||||
|
} else if s == "none" {
|
||||||
|
c.I2PConfig.AccessListType = ""
|
||||||
|
return nil
|
||||||
|
} else if s == "" {
|
||||||
|
c.I2PConfig.AccessListType = ""
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Invalid Access list type(whitelist, blacklist, none)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SetAccessList tells the system to treat the AccessList as a whitelist
|
||||||
|
func SetAccessList(s []string) func(*SAMEmit) error {
|
||||||
|
return func(c *SAMEmit) error {
|
||||||
|
if len(s) > 0 {
|
||||||
|
for _, a := range s {
|
||||||
|
c.I2PConfig.AccessList = append(c.I2PConfig.AccessList, a)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
102
emit.go
Normal file
102
emit.go
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package sam3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/eyedeekay/ramp/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SAMEmit struct {
|
||||||
|
i2pconfig.I2PConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SAMEmit) OptStr() string {
|
||||||
|
optStr := ""
|
||||||
|
for _, opt := range e.I2PConfig.Print() {
|
||||||
|
optStr += opt + " "
|
||||||
|
}
|
||||||
|
return optStr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SAMEmit) Hello() string {
|
||||||
|
return fmt.Sprintf("HELLO VERSION MIN=%s MAX=%s \n", e.I2PConfig.MinSAM(), e.I2PConfig.MaxSAM())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SAMEmit) HelloBytes() []byte {
|
||||||
|
return []byte(e.Hello())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SAMEmit) GenerateDestination() string {
|
||||||
|
return fmt.Sprintf("DEST GENERATE %s \n", e.I2PConfig.SignatureType())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SAMEmit) GenerateDestinationBytes() []byte {
|
||||||
|
return []byte(e.GenerateDestination())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SAMEmit) Lookup(name string) string {
|
||||||
|
return fmt.Sprintf("NAMING LOOKUP NAME=%s \n", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SAMEmit) LookupBytes(name string) []byte {
|
||||||
|
return []byte(e.Lookup(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SAMEmit) Create() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
// //1 2 3 4 5 6 7
|
||||||
|
"SESSION CREATE %s%s%s%s%s%s%s \n",
|
||||||
|
e.I2PConfig.SessionStyle(), //1
|
||||||
|
e.I2PConfig.FromPort(), //2
|
||||||
|
e.I2PConfig.ToPort(), //3
|
||||||
|
e.I2PConfig.ID(), //4
|
||||||
|
e.I2PConfig.DestinationKey(), // 5
|
||||||
|
e.I2PConfig.SignatureType(), // 6
|
||||||
|
e.OptStr(), // 7
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SAMEmit) CreateBytes() []byte {
|
||||||
|
log.Println("sam command: " + e.Create())
|
||||||
|
return []byte(e.Create())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SAMEmit) Connect(dest string) string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"STREAM CONNECT ID=%s %s %s DESTINATION=%s \n",
|
||||||
|
e.I2PConfig.ID(),
|
||||||
|
e.I2PConfig.FromPort(),
|
||||||
|
e.I2PConfig.ToPort(),
|
||||||
|
dest,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SAMEmit) ConnectBytes(dest string) []byte {
|
||||||
|
return []byte(e.Connect(dest))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SAMEmit) Accept() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"STREAM ACCEPT ID=%s",
|
||||||
|
e.I2PConfig.ID(),
|
||||||
|
e.I2PConfig.FromPort(),
|
||||||
|
e.I2PConfig.ToPort(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SAMEmit) AcceptBytes() []byte {
|
||||||
|
return []byte(e.Accept())
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEmit(opts ...func(*SAMEmit) error) (*SAMEmit, error) {
|
||||||
|
var emit SAMEmit
|
||||||
|
for _, o := range opts {
|
||||||
|
if err := o(&emit); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &emit, nil
|
||||||
|
}
|
Reference in New Issue
Block a user