<commit_before>package quickpgp

import (
	"fmt"
	"os"

	"golang.org/x/crypto/openpgp"
	"golang.org/x/crypto/openpgp/armor"
)

type readPasswordCallback func(filename string) (pass []byte, err error)

func readPrivateKeyFile(filename string, passPrompt readPasswordCallback) (e *openpgp.Entity, err error) {
	var krpriv *os.File

	if krpriv, err = os.Open(filename); err != nil {
		return nil, err
	}
	defer krpriv.Close()

	var entityList openpgp.EntityList

	keyFileReader := openpgp.ReadKeyRing
	if _, err = armor.Decode(krpriv); err == nil {
		keyFileReader = openpgp.ReadArmoredKeyRing
	}

	krpriv.Seek(0, 0)
	if entityList, err = keyFileReader(krpriv); err != nil {
		return nil, fmt.Errorf("reading %s: %s", filename, err)
	}
	if len(entityList) != 1 {
		return nil, fmt.Errorf("%s must contain only one key", filename)
	}
	e = entityList[0]
	if e.PrivateKey == nil {
		return nil, fmt.Errorf("%s does not contain a private key", filename)
	}
	if e.PrivateKey.Encrypted {
		if passPrompt != nil {
			var pass []byte
			if pass, err = passPrompt(filename); err == nil {
				err = e.PrivateKey.Decrypt(pass)
			}
		} else {
			return nil, fmt.Errorf("%s is encrypted", filename)
		}
	}
	return e, err
}

func readPublicKeyFile(filename string) (entityList openpgp.EntityList, err error) {
	var krpub *os.File

	if krpub, err = os.Open(filename); err != nil {
		return nil, err
	}
	defer krpub.Close()

	keyFileReader := openpgp.ReadKeyRing
	if _, err = armor.Decode(krpub); err == nil {
		keyFileReader = openpgp.ReadArmoredKeyRing
	}

	krpub.Seek(0, 0)
	if entityList, err = keyFileReader(krpub); err != nil {
		return nil, fmt.Errorf("reading %s: %s", filename, err)
	}
	return entityList, nil
}
<commit_msg>catch errs on Seek, we only process regular files<commit_after>package quickpgp

import (
	"fmt"
	"os"

	"golang.org/x/crypto/openpgp"
	"golang.org/x/crypto/openpgp/armor"
)

type readPasswordCallback func(filename string) (pass []byte, err error)

func readPrivateKeyFile(filename string, passPrompt readPasswordCallback) (e *openpgp.Entity, err error) {
	var krpriv *os.File

	if krpriv, err = os.Open(filename); err != nil {
		return nil, err
	}
	defer krpriv.Close()

	var entityList openpgp.EntityList

	keyFileReader := openpgp.ReadKeyRing
	if _, err = armor.Decode(krpriv); err == nil {
		keyFileReader = openpgp.ReadArmoredKeyRing
	}

	if _, err = krpriv.Seek(0, 0); err != nil {
		return nil, err
	}
	if entityList, err = keyFileReader(krpriv); err != nil {
		return nil, fmt.Errorf("reading %s: %s", filename, err)
	}
	if len(entityList) != 1 {
		return nil, fmt.Errorf("%s must contain only one key", filename)
	}
	e = entityList[0]
	if e.PrivateKey == nil {
		return nil, fmt.Errorf("%s does not contain a private key", filename)
	}
	if e.PrivateKey.Encrypted {
		if passPrompt != nil {
			var pass []byte
			if pass, err = passPrompt(filename); err == nil {
				err = e.PrivateKey.Decrypt(pass)
			}
		} else {
			return nil, fmt.Errorf("%s is encrypted", filename)
		}
	}
	return e, err
}

func readPublicKeyFile(filename string) (entityList openpgp.EntityList, err error) {
	var krpub *os.File

	if krpub, err = os.Open(filename); err != nil {
		return nil, err
	}
	defer krpub.Close()

	keyFileReader := openpgp.ReadKeyRing
	if _, err = armor.Decode(krpub); err == nil {
		keyFileReader = openpgp.ReadArmoredKeyRing
	}

	if _, err = krpub.Seek(0, 0); err != nil {
		return nil, err
	}
	if entityList, err = keyFileReader(krpub); err != nil {
		return nil, fmt.Errorf("reading %s: %s", filename, err)
	}
	return entityList, nil
}
<|endoftext|>


<commit_before>package fetch

import (
	"encoding/json"
	"fmt"
	"strings"
)

// Default implied values regarding docker registry interactions
var (
	DefaultRegistryHost = "index.docker.io"
	DefaultHubNamespace = "docker.io"
	DefaultTag          = "latest"
)

// Hoster is returns a hostname for the structure
type Hoster interface {
	Host() string
}

// RegistryEndpoint are the interactions of a docker registry
type RegistryEndpoint interface {
	Hoster
	Token(ImageRef) (Token, error)
	ImageID(ImageRef) (string, error)
	Ancestry(ImageRef) ([]string, error)
	FetchLayers(ImageRef, string) ([]string, error)
}

// NewRegistry sets up a RegistryEndpoint from a host string
func NewRegistry(host string) RegistryEndpoint {
	if host == "docker.io" {
		host = DefaultRegistryHost
	}
	return &registryV1Endpoint{
		host:      host,
		tokens:    map[string]Token{},
		endpoints: []string{},
	}
}

// FormatRepositories returns the `repositories` file format data for the
// referenced image as it conforms to the output of `docker save ...`
func FormatRepositories(refs ...ImageRef) ([]byte, error) {
	// new Registry, ref.host function
	for _, ref := range refs {
		if ref.ID() == "" {
			re := NewRegistry(ref.Host())
			if _, err := re.ImageID(ref); err != nil {
				return nil, err
			}
		}
	}
	// {"busybox":{"latest":"4986bf8c15363d1c5d15512d5266f8777bfba4974ac56e3270e7760f6f0a8125"}}
	repoInfo := map[string]map[string]string{}
	for _, ref := range refs {
		if repoInfo[ref.Name()] == nil {
			repoInfo[ref.Name()] = map[string]string{ref.Tag(): ref.ID()}
		} else {
			repoInfo[ref.Name()][ref.Tag()] = ref.ID()
		}
	}
	return json.Marshal(repoInfo)
}

var (
	// ErrTokenHeaderEmpty if the response from the registry did not provide a Token
	ErrTokenHeaderEmpty = fmt.Errorf("HTTP Header x-docker-token is empty")

	emptyToken = Token("")
)

// Token is access token from a docker registry
type Token string

// Signature value of the registry Token
func (t Token) Signature() string {
	return t.getFieldValue("Signature")
}

// Repository value of the registry Token
func (t Token) Repository() string {
	return t.getFieldValue("Repository")
}

// Access value of the registry Token
func (t Token) Access() string {
	return t.getFieldValue("Access")
}

func (t Token) getFieldValue(key string) string {
	for _, part := range strings.Split(t.String(), ",") {
		if strings.HasPrefix(strings.ToLower(part), strings.ToLower(key)) {
			chunks := strings.SplitN(part, "=", 2)
			if len(chunks) > 2 {
				continue
			}
			return chunks[1]
		}
	}
	return ""
}

// String to satisfy the fmt.Stringer interface
func (t Token) String() string {
	return string(t)
}
<commit_msg>registry/fetch: comment and URI<commit_after>package fetch

import (
	"encoding/json"
	"fmt"
	"strings"
)

// Default implied values regarding docker registry interactions
var (
	DefaultRegistryHost = "index.docker.io"
	DockerURIScheme     = "docker://"
	DefaultHubNamespace = "docker.io"
	DefaultTag          = "latest"
)

// Hoster is returns a hostname for the structure
type Hoster interface {
	Host() string
}

// RegistryEndpoint are the interactions of a docker registry
type RegistryEndpoint interface {
	Hoster
	Token(ImageRef) (Token, error)
	ImageID(ImageRef) (string, error)
	Ancestry(ImageRef) ([]string, error)
	FetchLayers(ImageRef, string) ([]string, error)
}

// NewRegistry sets up a RegistryEndpoint from a host string
func NewRegistry(host string) RegistryEndpoint {
	if host == "docker.io" {
		host = DefaultRegistryHost
	}

	// FIXME somewhere around here either we test for v2 functionality, or return
	// something that suffices the RegistryEndpoint, but can lazily determine v1
	// or v2 registry

	return &registryV1Endpoint{
		host:      host,
		tokens:    map[string]Token{},
		endpoints: []string{},
	}
}

// FormatRepositories returns the `repositories` file format data for the
// referenced image as it conforms to the output of `docker save ...`
func FormatRepositories(refs ...ImageRef) ([]byte, error) {
	// new Registry, ref.host function
	for _, ref := range refs {
		if ref.ID() == "" {
			re := NewRegistry(ref.Host())
			if _, err := re.ImageID(ref); err != nil {
				return nil, err
			}
		}
	}
	// {"busybox":{"latest":"4986bf8c15363d1c5d15512d5266f8777bfba4974ac56e3270e7760f6f0a8125"}}
	repoInfo := map[string]map[string]string{}
	for _, ref := range refs {
		if repoInfo[ref.Name()] == nil {
			repoInfo[ref.Name()] = map[string]string{ref.Tag(): ref.ID()}
		} else {
			repoInfo[ref.Name()][ref.Tag()] = ref.ID()
		}
	}
	return json.Marshal(repoInfo)
}

var (
	// ErrTokenHeaderEmpty if the response from the registry did not provide a Token
	ErrTokenHeaderEmpty = fmt.Errorf("HTTP Header x-docker-token is empty")

	emptyToken = Token("")
)

// Token is access token from a docker registry
type Token string

// Signature value of the registry Token
func (t Token) Signature() string {
	return t.getFieldValue("Signature")
}

// Repository value of the registry Token
func (t Token) Repository() string {
	return t.getFieldValue("Repository")
}

// Access value of the registry Token
func (t Token) Access() string {
	return t.getFieldValue("Access")
}

func (t Token) getFieldValue(key string) string {
	for _, part := range strings.Split(t.String(), ",") {
		if strings.HasPrefix(strings.ToLower(part), strings.ToLower(key)) {
			chunks := strings.SplitN(part, "=", 2)
			if len(chunks) > 2 {
				continue
			}
			return chunks[1]
		}
	}
	return ""
}

// String to satisfy the fmt.Stringer interface
func (t Token) String() string {
	return string(t)
}
<|endoftext|>


<commit_before>package core

import (
	"bytes"
	"fmt"
	"os/exec"
	"strings"

	"github.com/cactus/gologit"
)

type ZFSProperties map[string]string

func (prop ZFSProperties) Get(property string) string {
	return prop[property]
}

func (prop ZFSProperties) GetIOC(property string) string {
	return prop[fmt.Sprintf("org.freebsd.iocage:%s", property)]
}

func ZFS(arg ...string) (string, error) {
	return Cmd("/sbin/zfs", arg...)
}

func ZFSMust(errmsg error, arg ...string) string {
	return CmdMust(errmsg, "/sbin/zfs", arg...)
}

func Jls(arg ...string) (string, error) {
	return Cmd("/usr/sbin/jls", arg...)
}

func JlsMust(errmsg error, arg ...string) string {
	return CmdMust(errmsg, "/usr/sbin/jls", arg...)
}

func Cmd(name string, arg ...string) (string, error) {
	cmd := exec.Command(name, arg...)
	stdout := &bytes.Buffer{}
	stderr := &bytes.Buffer{}
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	err := cmd.Run()
	gologit.Debugf("cmd: %s\nstdout: %s\nstderr: %s", cmd.Args, stdout, stderr)
	return strings.TrimSpace(stdout.String()), err
}

func CmdMust(errmsg error, name string, arg ...string) string {
	out, err := Cmd(name, arg...)
	if err != nil {
		gologit.Fatalf("Error: %s\n", errmsg)
	}
	return out
}
<commit_msg>add comment<commit_after>package core

import (
	"bytes"
	"fmt"
	"os/exec"
	"strings"

	"github.com/cactus/gologit"
)

type ZFSProperties map[string]string

func (prop ZFSProperties) Get(property string) string {
	return prop[property]
}

func (prop ZFSProperties) GetIOC(property string) string {
	return prop[fmt.Sprintf("org.freebsd.iocage:%s", property)]
}

// Misc command helpers
func ZFS(arg ...string) (string, error) {
	return Cmd("/sbin/zfs", arg...)
}

func ZFSMust(errmsg error, arg ...string) string {
	return CmdMust(errmsg, "/sbin/zfs", arg...)
}

func Jls(arg ...string) (string, error) {
	return Cmd("/usr/sbin/jls", arg...)
}

func JlsMust(errmsg error, arg ...string) string {
	return CmdMust(errmsg, "/usr/sbin/jls", arg...)
}

func Cmd(name string, arg ...string) (string, error) {
	cmd := exec.Command(name, arg...)
	stdout := &bytes.Buffer{}
	stderr := &bytes.Buffer{}
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	err := cmd.Run()
	gologit.Debugf("cmd: %s\nstdout: %s\nstderr: %s", cmd.Args, stdout, stderr)
	return strings.TrimSpace(stdout.String()), err
}

func CmdMust(errmsg error, name string, arg ...string) string {
	out, err := Cmd(name, arg...)
	if err != nil {
		gologit.Fatalf("Error: %s\n", errmsg)
	}
	return out
}
<|endoftext|>


<commit_before>/*
   Copyright (C) 2017 Enrico Bianchi (enrico.bianchi@gmail.com)
   Project       Syncimap
   Description   A rsync like IMAP syncronization tool
   License       Apache License 2.0 (see LICENSE for details)
*/

package main

import (
	"gopkg.in/alecthomas/kingpin.v2"
	"syncimap/imap"
	"log"
	"net/url"
)

type Data struct {
	Source      *url.URL
	Destination *url.URL
}

func parse(data *Data) {
	var err error

	source := kingpin.Arg("source", "Set source URI").Required().String()
	destination := kingpin.Arg("destination", "Set destination URI").Required().String()

	kingpin.CommandLine.HelpFlag.Short('h')
	kingpin.Parse()

	data.Source, err = url.Parse(*source)
	if err != nil {
		log.Fatalf("Source URI is not valid")
	}

	data.Destination, err = url.Parse(*destination)
	if err != nil {
		log.Fatalf("Destination URI is not valid")
	}
}

func main() {
	var data Data
	var srcconn, dstconn imap.Connection

	parse(&data)

	if err := srcconn.Dial(data.Source); err != nil {
		log.Fatalf(err.Error())
	}
	defer srcconn.Client.Close()
	defer srcconn.Client.Logout()

	if err := dstconn.Dial(data.Destination); err != nil {
		log.Fatalf(err.Error())
	}
	defer dstconn.Client.Close()
	defer dstconn.Client.Logout()
}
<commit_msg>Rearranged code<commit_after>/*
   Copyright (C) 2017 Enrico Bianchi (enrico.bianchi@gmail.com)
   Project       Syncimap
   Description   A rsync like IMAP syncronization tool
   License       Apache License 2.0 (see LICENSE for details)
*/

package main

import (
	"gopkg.in/alecthomas/kingpin.v2"
	"syncimap/imap"
	"log"
	"net/url"
)

type Data struct {
	Source      *url.URL
	Destination *url.URL
}

func parse(data *Data) {
	var err error

	source := kingpin.Arg("source", "Set source URI").Required().String()
	destination := kingpin.Arg("destination", "Set destination URI").Required().String()

	kingpin.CommandLine.HelpFlag.Short('h')
	kingpin.Parse()

	data.Source, err = url.Parse(*source)
	if err != nil {
		log.Fatalf("Source URI is not valid")
	}

	data.Destination, err = url.Parse(*destination)
	if err != nil {
		log.Fatalf("Destination URI is not valid")
	}
}

func main() {
	var data Data
	var srcconn, dstconn imap.Connection
	var err error

	parse(&data)

	err = srcconn.Dial(data.Source)
	if  err != nil {
		log.Fatalf(err.Error())
	}
	defer srcconn.Client.Close()
	defer srcconn.Client.Logout()

	err = dstconn.Dial(data.Destination)
	if err != nil {
		log.Fatalf(err.Error())
	}
	defer dstconn.Client.Close()
	defer dstconn.Client.Logout()
}
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package transport

import (
	"fmt"
	"net"
	"time"

	"mynewt.apache.org/newt/newtmgr/config"
	"mynewt.apache.org/newt/util"
)

type ConnUDP struct {
	connProfile config.NewtmgrConnProfile
	conn        *net.UDPConn
	dst         *net.UDPAddr
	isOIC       bool
}

func (cs *ConnUDP) Open(cp config.NewtmgrConnProfile, readTimeout time.Duration) error {
	addr, err := net.ResolveUDPAddr("udp", cp.ConnString())
	if err != nil {
		return util.NewNewtError(fmt.Sprintf("Name not resolving: %s",
			err.Error()))
	}
	cs.dst = addr

	// bind local endpoint to wait for response afterwards
	s, err := net.ListenUDP("udp", nil)
	if err != nil {
		return util.NewNewtError(fmt.Sprintf("UDP conn failed: %s\n",
			err.Error()))
	}
	cs.conn = s
	return nil
}

func (cs *ConnUDP) Close() error {
	cs.conn.Close()
	cs.conn = nil
	return nil
}

func (cs *ConnUDP) SetOICEncoded(b bool) {
	cs.isOIC = b
}

func (cs *ConnUDP) GetOICEncoded() bool {
	return cs.isOIC
}

func (cs *ConnUDP) WritePacket(pkt *Packet) error {
	if cs.conn == nil {
		return util.NewNewtError("Connection not open")
	}

	_, err := cs.conn.WriteTo(pkt.GetBytes(), cs.dst)
	if err != nil {
		return util.NewNewtError(fmt.Sprintf("failed to write: %s",
			err.Error()))
	}
	return nil
}

func (cs *ConnUDP) ReadPacket() (*Packet, error) {
	// cs.conn.SetDeadline(time.Now().Add(time.Second * 4))

	data := make([]byte, 2048)
	nr, srcAddr, err := cs.conn.ReadFromUDP(data)
	if err != nil {
		return nil, util.NewNewtError(fmt.Sprintf("failed to read: %s",
			err.Error()))
	}
	data = data[0:nr]
	fmt.Printf("Received message from %v %d\n", srcAddr, nr)
	pkt, err := NewPacket(uint16(nr))
	if err != nil {
		return nil, err
	}
	pkt.AddBytes(data)
	return pkt, nil
}
<commit_msg>newtmgr connudp; remove accidentally left in debug message.<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package transport

import (
	"fmt"
	"net"
	"time"

	"mynewt.apache.org/newt/newtmgr/config"
	"mynewt.apache.org/newt/util"
)

type ConnUDP struct {
	connProfile config.NewtmgrConnProfile
	conn        *net.UDPConn
	dst         *net.UDPAddr
	isOIC       bool
}

func (cs *ConnUDP) Open(cp config.NewtmgrConnProfile, readTimeout time.Duration) error {
	addr, err := net.ResolveUDPAddr("udp", cp.ConnString())
	if err != nil {
		return util.NewNewtError(fmt.Sprintf("Name not resolving: %s",
			err.Error()))
	}
	cs.dst = addr

	// bind local endpoint to wait for response afterwards
	s, err := net.ListenUDP("udp", nil)
	if err != nil {
		return util.NewNewtError(fmt.Sprintf("UDP conn failed: %s\n",
			err.Error()))
	}
	cs.conn = s
	return nil
}

func (cs *ConnUDP) Close() error {
	cs.conn.Close()
	cs.conn = nil
	return nil
}

func (cs *ConnUDP) SetOICEncoded(b bool) {
	cs.isOIC = b
}

func (cs *ConnUDP) GetOICEncoded() bool {
	return cs.isOIC
}

func (cs *ConnUDP) WritePacket(pkt *Packet) error {
	if cs.conn == nil {
		return util.NewNewtError("Connection not open")
	}

	_, err := cs.conn.WriteTo(pkt.GetBytes(), cs.dst)
	if err != nil {
		return util.NewNewtError(fmt.Sprintf("failed to write: %s",
			err.Error()))
	}
	return nil
}

func (cs *ConnUDP) ReadPacket() (*Packet, error) {
	// cs.conn.SetDeadline(time.Now().Add(time.Second * 4))

	data := make([]byte, 2048)
	nr, srcAddr, err := cs.conn.ReadFromUDP(data)
	if err != nil {
		return nil, util.NewNewtError(fmt.Sprintf("failed to read: %s",
			err.Error()))
	}
	data = data[0:nr]

	pkt, err := NewPacket(uint16(nr))
	if err != nil {
		return nil, err
	}
	pkt.AddBytes(data)
	return pkt, nil
}
<|endoftext|>


<commit_before>package statsd

import (
	"bytes"
	"errors"
	"fmt"
	"github.com/mono83/slf"
	"github.com/mono83/udpwriter"
	"io"
)

// Config holds configuration for StatsD client
type Config struct {
	Address      string `json:"address" yaml:"address"`
	Microseconds bool   `json:"microseconds" yaml:"microseconds"`
	Buffered     bool   `json:"buffered" yaml:"buffered"`
	Dogstats     bool   `json:"dogstats" yaml:"dogstats"`
	Prefix       string `json:"prefix" yaml:"prefix"`
}

// NewReceiver builds new StatsD receiver
func NewReceiver(c Config) (slf.Receiver, error) {
	uw, err := udpwriter.NewS(c.Address)
	if err != nil {
		return nil, err
	}

	if c.Buffered {
		return nil, errors.New("Buffered output not supported yet")
	}

	return &sdr{target: uw, config: c}, nil
}

type sdr struct {
	target io.Writer
	config Config
}

func (s *sdr) Receive(p slf.Event) {
	switch p.Type {
	case slf.TypeInc:
		s.target.Write([]byte(fmt.Sprintf(
			"%s%s:%d|c%s",
			s.config.Prefix,
			p.Content,
			p.I64,
			s.appendTags(p.Params),
		)))
	case slf.TypeGauge:
		s.target.Write([]byte(fmt.Sprintf(
			"%s%s:%d|g%s",
			s.config.Prefix,
			p.Content,
			p.I64,
			s.appendTags(p.Params),
		)))
	case slf.TypeDuration:
		var d int64
		if s.config.Microseconds {
			// Microseconds precision
			d = p.I64 / 1000
		} else {
			// Milliseconds precision
			d = p.I64 / 1000000
		}

		s.target.Write([]byte(fmt.Sprintf(
			"%s%s:%d|ms%s",
			s.config.Prefix,
			p.Content,
			d,
			s.appendTags(p.Params),
		)))
	}
}

func (s sdr) appendTags(tags []slf.Param) string {
	if len(tags) == 0 || !s.config.Dogstats {
		return ""
	}

	sb := bytes.NewBufferString("|@1.0|#")
	for i, tag := range tags {
		if i > 0 {
			sb.WriteString(",")
		}
		sb.WriteString(fmt.Sprintf("%s:%v", tag.GetKey(), tag.GetRaw()))
	}

	return sb.String()
}
<commit_msg>buffered statsd client<commit_after>package statsd

import (
	"bytes"
	"fmt"
	"github.com/mono83/slf"
	"github.com/mono83/slf/recievers"
	"github.com/mono83/udpwriter"
	"io"
	"time"
)

// Config holds configuration for StatsD client
type Config struct {
	Address      string `json:"address" yaml:"address"`
	Microseconds bool   `json:"microseconds" yaml:"microseconds"`
	Dogstats     bool   `json:"dogstats" yaml:"dogstats"`
	Prefix       string `json:"prefix" yaml:"prefix"`
	FlushEvery   int    `json:"flushEvery" yaml:"flushEvery"`
	PacketLines  int    `json:"packetLines" yaml:"packetLines"`
}

// NewReceiver builds new StatsD receiver
func NewReceiver(c Config) (slf.Receiver, error) {
	uw, err := udpwriter.NewS(c.Address)
	if err != nil {
		return nil, err
	}

	if c.PacketLines < 5 {
		c.PacketLines = 5
	}

	if c.FlushEvery < 1 {
		c.FlushEvery = 1
	}

	s := &sdr{target: uw, config: c}
	s.Receiver = recievers.NewMetricsBuffer(time.Duration(int64(c.FlushEvery)*int64(time.Second)), s.sendToWriter)

	return s, nil
}

type sdr struct {
	slf.Receiver
	target io.Writer
	config Config
}

func (s *sdr) sendToWriter(list []slf.Event) {
	if len(list) == 0 {
		return
	}

	startIndex := 0
	for startIndex+1 <= len(list) {
		endIndex := startIndex + s.config.PacketLines
		if endIndex >= len(list) {
			endIndex = len(list)
		}

		part := list[startIndex:endIndex]
		buf := bytes.NewBuffer(nil)

		for _, p := range part {
			switch p.Type {
			case slf.TypeInc:
				buf.Write([]byte(fmt.Sprintf(
					"%s%s:%d|c%s\n",
					s.config.Prefix,
					p.Content,
					p.I64,
					s.appendTags(p.Params),
				)))
			case slf.TypeGauge:
				buf.Write([]byte(fmt.Sprintf(
					"%s%s:%d|g%s\n",
					s.config.Prefix,
					p.Content,
					p.I64,
					s.appendTags(p.Params),
				)))
			case slf.TypeDuration:
				var d int64
				if s.config.Microseconds {
					// Microseconds precision
					d = p.I64 / 1000
				} else {
					// Milliseconds precision
					d = p.I64 / 1000000
				}

				buf.Write([]byte(fmt.Sprintf(
					"%s%s:%d|ms%s\n",
					s.config.Prefix,
					p.Content,
					d,
					s.appendTags(p.Params),
				)))
			}
		}

		s.target.Write(buf.Bytes())
		startIndex = endIndex
	}
}

func (s sdr) appendTags(tags []slf.Param) string {
	if len(tags) == 0 || !s.config.Dogstats {
		return ""
	}

	sb := bytes.NewBufferString("|@1.0|#")
	for i, tag := range tags {
		if i > 0 {
			sb.WriteString(",")
		}
		sb.WriteString(tag.GetKey())
		sb.WriteString(":")
		sb.WriteString(tag.String())
	}

	return sb.String()
}
<|endoftext|>


<commit_before><commit_msg>Simplify executeOSAScript method<commit_after><|endoftext|>


<commit_before>// Copyright 2013 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package authtest

import (
	"net"
	"net/smtp"
	"strings"
	"testing"

	"gopkg.in/check.v1"
)

func Test(t *testing.T) {
	check.TestingT(t)
}

type S struct{}

var _ = check.Suite(&S{})

func (s *S) TestFakeMailAddress(c *check.C) {
	fake := fakeMailAddress("gopher@tsuru.io")
	c.Assert(fake.Email(), check.Equals, "gopher@tsuru.io")
	c.Assert(fake.Hostname(), check.Equals, "tsuru.io")
	fake = fakeMailAddress("gopher")
	c.Assert(fake.Email(), check.Equals, "gopher")
	c.Assert(fake.Hostname(), check.Equals, "")
}

func (s *S) TestFakeEnvelope(c *check.C) {
	server := SMTPServer{}
	fake := newFakeEnvelope("tsuru@globo.com", &server)
	err := fake.BeginData()
	c.Assert(err, check.NotNil)
	fake.AddRecipient(fakeMailAddress("gandalf@globo.com"))
	err = fake.BeginData()
	c.Assert(err, check.IsNil)
	fake.Write([]byte("Hello world!"))
	fake.Write([]byte("Hello again!"))
	fake.Close()
	c.Assert(server.MailBox, check.HasLen, 1)
	c.Assert(server.MailBox[0], check.DeepEquals, fake.m)
}

func (s *S) TestSMTPServerStart(c *check.C) {
	server, err := NewSMTPServer()
	c.Assert(err, check.IsNil)
	conn, err := net.Dial("tcp", server.Addr())
	c.Assert(err, check.IsNil)
	conn.Close()
}

func (s *S) TestSMTPServerStop(c *check.C) {
	server, err := NewSMTPServer()
	c.Assert(err, check.IsNil)
	server.Stop()
	_, err = net.Dial("tcp", server.Addr())
	c.Assert(err, check.NotNil)
}

func (s *S) TestSMTPServerRecordsMailMessages(c *check.C) {
	server, err := NewSMTPServer()
	c.Assert(err, check.IsNil)
	defer server.Stop()
	to := []string{"gopher1@tsuru.io", "gopher2@tsuru.io"}
	err = smtp.SendMail(server.Addr(), nil, "gopher@tsuru.io", to, []byte("Hello world!"))
	c.Assert(err, check.IsNil)
	c.Assert(server.MailBox, check.HasLen, 1)
	want := Mail{
		From: "gopher@tsuru.io",
		To:   to,
		Data: []byte("Hello world!\r\n"),
	}
	c.Assert(server.MailBox[0], check.DeepEquals, want)
}

func (s *S) TestSMTPServerReset(c *check.C) {
	server, err := NewSMTPServer()
	c.Assert(err, check.IsNil)
	defer server.Stop()
	to := []string{"gopher1@tsuru.io", "gopher2@tsuru.io"}
	err = smtp.SendMail(server.Addr(), nil, "gopher@tsuru.io", to, []byte("Hello world!"))
	c.Assert(err, check.IsNil)
	c.Assert(server.MailBox, check.HasLen, 1)
	server.Reset()
	c.Assert(server.MailBox, check.HasLen, 0)
}

type fakeMailAddress string

func (m fakeMailAddress) Email() string {
	return string(m)
}

func (m fakeMailAddress) Hostname() string {
	s := string(m)
	if p := strings.Index(s, "@"); p > -1 {
		return s[p+1:]
	}
	return ""
}
<commit_msg>auth/authtest: fix flaky test by waiting for listener to close<commit_after>// Copyright 2013 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package authtest

import (
	"net"
	"net/smtp"
	"strings"
	"testing"
	"time"

	"gopkg.in/check.v1"
)

func Test(t *testing.T) {
	check.TestingT(t)
}

type S struct{}

var _ = check.Suite(&S{})

func (s *S) TestFakeMailAddress(c *check.C) {
	fake := fakeMailAddress("gopher@tsuru.io")
	c.Assert(fake.Email(), check.Equals, "gopher@tsuru.io")
	c.Assert(fake.Hostname(), check.Equals, "tsuru.io")
	fake = fakeMailAddress("gopher")
	c.Assert(fake.Email(), check.Equals, "gopher")
	c.Assert(fake.Hostname(), check.Equals, "")
}

func (s *S) TestFakeEnvelope(c *check.C) {
	server := SMTPServer{}
	fake := newFakeEnvelope("tsuru@globo.com", &server)
	err := fake.BeginData()
	c.Assert(err, check.NotNil)
	fake.AddRecipient(fakeMailAddress("gandalf@globo.com"))
	err = fake.BeginData()
	c.Assert(err, check.IsNil)
	fake.Write([]byte("Hello world!"))
	fake.Write([]byte("Hello again!"))
	fake.Close()
	c.Assert(server.MailBox, check.HasLen, 1)
	c.Assert(server.MailBox[0], check.DeepEquals, fake.m)
}

func (s *S) TestSMTPServerStart(c *check.C) {
	server, err := NewSMTPServer()
	c.Assert(err, check.IsNil)
	conn, err := net.Dial("tcp", server.Addr())
	c.Assert(err, check.IsNil)
	conn.Close()
}

func (s *S) TestSMTPServerStop(c *check.C) {
	server, err := NewSMTPServer()
	c.Assert(err, check.IsNil)
	server.Stop()
	timeout := time.After(5 * time.Second)
	for {
		_, err = net.Dial("tcp", server.Addr())
		if err != nil {
			break
		}
		select {
		case <-time.After(100 * time.Millisecond):
		case <-timeout:
			c.Fatal("timeout waiting for listener to close")
		}
	}
	c.Assert(err, check.NotNil)
}

func (s *S) TestSMTPServerRecordsMailMessages(c *check.C) {
	server, err := NewSMTPServer()
	c.Assert(err, check.IsNil)
	defer server.Stop()
	to := []string{"gopher1@tsuru.io", "gopher2@tsuru.io"}
	err = smtp.SendMail(server.Addr(), nil, "gopher@tsuru.io", to, []byte("Hello world!"))
	c.Assert(err, check.IsNil)
	c.Assert(server.MailBox, check.HasLen, 1)
	want := Mail{
		From: "gopher@tsuru.io",
		To:   to,
		Data: []byte("Hello world!\r\n"),
	}
	c.Assert(server.MailBox[0], check.DeepEquals, want)
}

func (s *S) TestSMTPServerReset(c *check.C) {
	server, err := NewSMTPServer()
	c.Assert(err, check.IsNil)
	defer server.Stop()
	to := []string{"gopher1@tsuru.io", "gopher2@tsuru.io"}
	err = smtp.SendMail(server.Addr(), nil, "gopher@tsuru.io", to, []byte("Hello world!"))
	c.Assert(err, check.IsNil)
	c.Assert(server.MailBox, check.HasLen, 1)
	server.Reset()
	c.Assert(server.MailBox, check.HasLen, 0)
}

type fakeMailAddress string

func (m fakeMailAddress) Email() string {
	return string(m)
}

func (m fakeMailAddress) Hostname() string {
	s := string(m)
	if p := strings.Index(s, "@"); p > -1 {
		return s[p+1:]
	}
	return ""
}
<|endoftext|>


<commit_before>// Copyright 2009 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.

// This package provides basic interfaces to I/O primitives.
// Its primary job is to wrap existing implementations of such primitives,
// such as those in package os, into shared public interfaces that
// abstract the functionality.
// It also provides buffering primitives and some other basic operations.
package io

import (
	"bytes";
	"os";
)

// Error represents an unexpected I/O behavior.
type Error struct {
	os.ErrorString
}

// ErrShortWrite means that a write accepted fewer bytes than requested
// but failed to return an explicit error.
var ErrShortWrite os.Error = &Error{"short write"}

// ErrUnexpectedEOF means that os.EOF was encountered in the
// middle of reading a fixed-size block or data structure.
var ErrUnexpectedEOF os.Error = &Error{"unexpected EOF"}

// Reader is the interface that wraps the basic Read method.
//
// Read reads up to len(p) bytes into p.  It returns the number of bytes
// read and any error encountered.  Even if Read returns n < len(p),
// it may use all of p as scratch space during the call.
// If some data is available but not len(p) bytes, Read conventionally
// returns what is available rather than block waiting for more.
//
// At the end of the input stream, Read returns 0, os.EOF.
// Read may return a non-zero number of bytes with a non-nil err.
// In particular, a Read that exhausts the input may return n > 0, os.EOF.
type Reader interface {
	Read(p []byte) (n int, err os.Error);
}

// Writer is the interface that wraps the basic Write method.
type Writer interface {
	Write(p []byte) (n int, err os.Error);
}

// Closer is the interface that wraps the basic Close method.
type Closer interface {
	Close() os.Error;
}

// ReadWrite is the interface that groups the basic Read and Write methods.
type ReadWriter interface {
	Reader;
	Writer;
}

// ReadCloser is the interface that groups the basic Read and Close methods.
type ReadCloser interface {
	Reader;
	Closer;
}

// WriteCloser is the interface that groups the basic Write and Close methods.
type WriteCloser interface {
	Writer;
	Closer;
}

// ReadWriteCloser is the interface that groups the basic Read, Write and Close methods.
type ReadWriteCloser interface {
	Reader;
	Writer;
	Closer;
}

// Convert a string to an array of bytes for easy marshaling.
func StringBytes(s string) []byte {
	b := make([]byte, len(s));
	for i := 0; i < len(s); i++ {
		b[i] = s[i];
	}
	return b;
}

// WriteString writes the contents of the string s to w, which accepts an array of bytes.
func WriteString(w Writer, s string) (n int, err os.Error) {
	return w.Write(StringBytes(s))
}

// ReadAtLeast reads from r into buf until it has read at least min bytes.
// It returns the number of bytes copied and an error if fewer bytes were read.
// The error is os.EOF only if no bytes were read.
// If an EOF happens after reading fewer than min bytes,
// ReadAtLeast returns ErrUnexpectedEOF.
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err os.Error) {
	n = 0;
	for n < min {
		nn, e := r.Read(buf[n:len(buf)]);
		if nn > 0 {
			n += nn
		}
		if e != nil {
			if e == os.EOF && n > 0 {
				e = ErrUnexpectedEOF;
			}
			return n, e
		}
	}
	return n, nil
}

// ReadFull reads exactly len(buf) bytes from r into buf.
// It returns the number of bytes copied and an error if fewer bytes were read.
// The error is os.EOF only if no bytes were read.
// If an EOF happens after reading some but not all the bytes,
// ReadFull returns ErrUnexpectedEOF.
func ReadFull(r Reader, buf []byte) (n int, err os.Error) {
	// TODO(rsc): 6g bug keeps us from writing the obvious 1-liner
	n, err = ReadAtLeast(r, buf, len(buf));
	return;
}

// Copyn copies n bytes (or until an error) from src to dst.
// It returns the number of bytes copied and the error, if any.
func Copyn(src Reader, dst Writer, n int64) (written int64, err os.Error) {
	buf := make([]byte, 32*1024);
	for written < n {
		l := len(buf);
		if d := n - written; d < int64(l) {
			l = int(d);
		}
		nr, er := src.Read(buf[0 : l]);
		if nr > 0 {
			nw, ew := dst.Write(buf[0 : nr]);
			if nw > 0 {
				written += int64(nw);
			}
			if ew != nil {
				err = ew;
				break;
			}
			if nr != nw {
				err = ErrShortWrite;
				break;
			}
		}
		if er != nil {
			err = er;
			break;
		}
	}
	return written, err
}

// Copy copies from src to dst until either EOF is reached
// on src or an error occurs.  It returns the number of bytes
// copied and the error, if any.
func Copy(src Reader, dst Writer) (written int64, err os.Error) {
	buf := make([]byte, 32*1024);
	for {
		nr, er := src.Read(buf);
		if nr > 0 {
			nw, ew := dst.Write(buf[0:nr]);
			if nw > 0 {
				written += int64(nw);
			}
			if ew != nil {
				err = ew;
				break;
			}
			if nr != nw {
				err = ErrShortWrite;
				break;
			}
		}
		if er == os.EOF {
			break;
		}
		if er != nil {
			err = er;
			break;
		}
	}
	return written, err
}

// A ByteReader satisfies Reads by consuming data from a slice of bytes.
// Clients can call NewByteReader to create one or wrap pointers
// to their own slices: r := ByteReader{&data}.
type ByteReader struct {
	Data *[]byte
}

func (r ByteReader) Read(p []byte) (int, os.Error) {
	n := len(p);
	b := *r.Data;
	if len(b) == 0 {
		return 0, os.EOF;
	}
	if n > len(b) {
		n = len(b);
	}
	bytes.Copy(p, b[0:n]);
	*r.Data = b[n:len(b)];
	return n, nil;
}

// NewByteReader returns a new ByteReader reading from data.
func NewByteReader(data []byte) ByteReader {
	return ByteReader{ &data };
}

<commit_msg>document requirements on Write method<commit_after>// Copyright 2009 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.

// This package provides basic interfaces to I/O primitives.
// Its primary job is to wrap existing implementations of such primitives,
// such as those in package os, into shared public interfaces that
// abstract the functionality.
// It also provides buffering primitives and some other basic operations.
package io

import (
	"bytes";
	"os";
)

// Error represents an unexpected I/O behavior.
type Error struct {
	os.ErrorString
}

// ErrShortWrite means that a write accepted fewer bytes than requested
// but failed to return an explicit error.
var ErrShortWrite os.Error = &Error{"short write"}

// ErrUnexpectedEOF means that os.EOF was encountered in the
// middle of reading a fixed-size block or data structure.
var ErrUnexpectedEOF os.Error = &Error{"unexpected EOF"}

// Reader is the interface that wraps the basic Read method.
//
// Read reads up to len(p) bytes into p.  It returns the number of bytes
// read (0 <= n <= len(p)) and any error encountered.
// Even if Read returns n < len(p),
// it may use all of p as scratch space during the call.
// If some data is available but not len(p) bytes, Read conventionally
// returns what is available rather than block waiting for more.
//
// At the end of the input stream, Read returns 0, os.EOF.
// Read may return a non-zero number of bytes with a non-nil err.
// In particular, a Read that exhausts the input may return n > 0, os.EOF.
type Reader interface {
	Read(p []byte) (n int, err os.Error);
}

// Writer is the interface that wraps the basic Write method.
//
// Write writes len(p) bytes from p to the underlying data stream.
// It returns the number of bytes written from p (0 <= n <= len(p))
// and any error encountered that caused the write to stop early.
// Write must return a non-nil error if it returns n < len(p).
type Writer interface {
	Write(p []byte) (n int, err os.Error);
}

// Closer is the interface that wraps the basic Close method.
type Closer interface {
	Close() os.Error;
}

// ReadWrite is the interface that groups the basic Read and Write methods.
type ReadWriter interface {
	Reader;
	Writer;
}

// ReadCloser is the interface that groups the basic Read and Close methods.
type ReadCloser interface {
	Reader;
	Closer;
}

// WriteCloser is the interface that groups the basic Write and Close methods.
type WriteCloser interface {
	Writer;
	Closer;
}

// ReadWriteCloser is the interface that groups the basic Read, Write and Close methods.
type ReadWriteCloser interface {
	Reader;
	Writer;
	Closer;
}

// Convert a string to an array of bytes for easy marshaling.
func StringBytes(s string) []byte {
	b := make([]byte, len(s));
	for i := 0; i < len(s); i++ {
		b[i] = s[i];
	}
	return b;
}

// WriteString writes the contents of the string s to w, which accepts an array of bytes.
func WriteString(w Writer, s string) (n int, err os.Error) {
	return w.Write(StringBytes(s))
}

// ReadAtLeast reads from r into buf until it has read at least min bytes.
// It returns the number of bytes copied and an error if fewer bytes were read.
// The error is os.EOF only if no bytes were read.
// If an EOF happens after reading fewer than min bytes,
// ReadAtLeast returns ErrUnexpectedEOF.
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err os.Error) {
	n = 0;
	for n < min {
		nn, e := r.Read(buf[n:len(buf)]);
		if nn > 0 {
			n += nn
		}
		if e != nil {
			if e == os.EOF && n > 0 {
				e = ErrUnexpectedEOF;
			}
			return n, e
		}
	}
	return n, nil
}

// ReadFull reads exactly len(buf) bytes from r into buf.
// It returns the number of bytes copied and an error if fewer bytes were read.
// The error is os.EOF only if no bytes were read.
// If an EOF happens after reading some but not all the bytes,
// ReadFull returns ErrUnexpectedEOF.
func ReadFull(r Reader, buf []byte) (n int, err os.Error) {
	// TODO(rsc): 6g bug keeps us from writing the obvious 1-liner
	n, err = ReadAtLeast(r, buf, len(buf));
	return;
}

// Copyn copies n bytes (or until an error) from src to dst.
// It returns the number of bytes copied and the error, if any.
func Copyn(src Reader, dst Writer, n int64) (written int64, err os.Error) {
	buf := make([]byte, 32*1024);
	for written < n {
		l := len(buf);
		if d := n - written; d < int64(l) {
			l = int(d);
		}
		nr, er := src.Read(buf[0 : l]);
		if nr > 0 {
			nw, ew := dst.Write(buf[0 : nr]);
			if nw > 0 {
				written += int64(nw);
			}
			if ew != nil {
				err = ew;
				break;
			}
			if nr != nw {
				err = ErrShortWrite;
				break;
			}
		}
		if er != nil {
			err = er;
			break;
		}
	}
	return written, err
}

// Copy copies from src to dst until either EOF is reached
// on src or an error occurs.  It returns the number of bytes
// copied and the error, if any.
func Copy(src Reader, dst Writer) (written int64, err os.Error) {
	buf := make([]byte, 32*1024);
	for {
		nr, er := src.Read(buf);
		if nr > 0 {
			nw, ew := dst.Write(buf[0:nr]);
			if nw > 0 {
				written += int64(nw);
			}
			if ew != nil {
				err = ew;
				break;
			}
			if nr != nw {
				err = ErrShortWrite;
				break;
			}
		}
		if er == os.EOF {
			break;
		}
		if er != nil {
			err = er;
			break;
		}
	}
	return written, err
}

// A ByteReader satisfies Reads by consuming data from a slice of bytes.
// Clients can call NewByteReader to create one or wrap pointers
// to their own slices: r := ByteReader{&data}.
type ByteReader struct {
	Data *[]byte
}

func (r ByteReader) Read(p []byte) (int, os.Error) {
	n := len(p);
	b := *r.Data;
	if len(b) == 0 {
		return 0, os.EOF;
	}
	if n > len(b) {
		n = len(b);
	}
	bytes.Copy(p, b[0:n]);
	*r.Data = b[n:len(b)];
	return n, nil;
}

// NewByteReader returns a new ByteReader reading from data.
func NewByteReader(data []byte) ByteReader {
	return ByteReader{ &data };
}

<|endoftext|>


<commit_before>//
// nntp.go -- nntp interface for peering
//
package srnd

import (
  "bufio"
  "io"
  "log"
  "net/textproto"
  "os"
  "strings"
  "sync"
  "time"
)

// nntp connection state
type nntpConnection struct {
  // the name of this feed
  name string
  // the mode we are in now
  mode string
  // the policy for federation
  policy FeedPolicy
  // lock help when expecting non pipelined activity
  access sync.Mutex

  // CHECK <message-id>
  check chan string
  // ARTICLE <message-id>
  article chan string
  // TAKETHIS <message-id>
  take chan string
}

func createNNTPConnection() nntpConnection {
  return nntpConnection{
    check: make(chan string, 32),
    article: make(chan string, 32),
    take: make(chan string, 32),
  }
}

// switch modes
func (self nntpConnection) modeSwitch(mode string, conn *textproto.Conn) (success bool, err error) {
  self.access.Lock()
  mode = strings.ToUpper(mode)
  conn.PrintfLine("MODE %s", mode)
  var code int
  code, _, err = conn.ReadCodeLine(-1)
  if code > 200 && code < 300 {
    // accepted mode change
    if len(self.mode) > 0 {
      log.Printf("mode switch %s -> %s", self.mode, mode)
    } else {
      log.Println("switched to mode", mode)
    }
    self.mode = mode
    success = len(self.mode) > 0
  }
  self.access.Unlock()
  return
}

// send a banner for inbound connections
func (self nntpConnection) inboundHandshake(conn *textproto.Conn) (err error) {
  err = conn.PrintfLine("200 Posting Allowed")
  return err
}

// outbound setup, check capabilities and set mode
// returns (supports stream, supports reader) + error
func (self nntpConnection) outboundHandshake(conn *textproto.Conn) (stream, reader bool, err error) {
  var code int
  var line string
  for err == nil {
    code, line, err = conn.ReadCodeLine(-1)
    if err == nil {
      if code == 200 {
        // send capabilities
        err = conn.PrintfLine("CAPABILITIES")
        if err == nil {
          // read response
          dr := conn.DotReader()
          r := bufio.NewReader(dr)
          for {
            line, err = r.ReadString('\n')
            if err == io.EOF {
              // we are at the end of the dotreader
              // set err back to nil and break out
              err = nil
              break
            } else if err == nil {
              // we got a line
              if line == "MODE-READER\n" {
                log.Println(self.name, "supports READER")
                reader = true
              } else if line == "STREAMING\n" {
                stream = true
                log.Println(self.name, "supports STREAMING")
              }
            } else {
              // we got an error
              log.Println("error reading capabilities", err)
              break
            }
          }
          // return after reading
          return
        }
      } else if code == 201 {
        log.Println("feed", self.name,"does not allow posting")
        // we don't do auth yet
        break
      } else {
        continue
      }
    }
  }
  return
}

// run the mainloop for this connection
// stream if true means they support streaming mode
// reader if true means they support reader mode
func (self nntpConnection) runConnection(daemon NNTPDaemon, inbound, stream, reader bool, conn *textproto.Conn) {

  var err error
  var code int
  var line string
  var success bool

  for err == nil {
    if self.mode == "" {
      if inbound  {
        // no mode set and inbound
        line, err = conn.ReadLine()
      } else {
        // set out mode we are outbound
        if stream {
          success, err = self.modeSwitch("STREAM", conn)
        } else if reader {
          success, err = self.modeSwitch("READER", conn)
        }
        if success {
          log.Println("mode set to", self.mode)
        } else {
          // bullshit
          // we can't do anything so we quit
          log.Println(self.name, "can't stream or read, wtf?")
          conn.PrintfLine("QUIT")
          conn.Close()
          return
        }
      }
    } else if self.mode == "STREAM" {
      // we're in streaming mode
      // let's pipeline this shit
      select {
        // we've are going to ask for an article in READER mode
      case msgid := <- self.article:
        if reader && ValidMessageID(msgid) {
          // switch to reader mode
          success, err = self.modeSwitch("READER", conn)
          if success {
            // send the request
            conn.PrintfLine("ARTICLE %s", msgid)
            code, line, err = conn.ReadCodeLine(-1)
            if code == 220 {
              // awwww yeh we got it
              f := daemon.store.CreateTempFile(msgid)
              if f == nil {
                // already being loaded elsewhere
              } else {
                // read in the article
                dr := conn.DotReader()
                _, err = io.Copy(f, dr)
                f.Close()
                log.Println(msgid, "got from", self.name)
                // tell daemon to load infeed
                daemon.infeed_load <- msgid
              }
            } else if code == 430 {
              // they don't know it D:
              log.Println(msgid, "not known by", self.name)
            } else {
              // invalid response
              log.Println(self.name, "invald response to ARTICLE:", code, line)
            }
            // now switch back to streaming mode
            log.Println(self.name, "switch back to streaming mode")
            success, err = self.modeSwitch("STREAM", conn)
            if ! success {
              log.Println(self.name, "failed to switch back to streaming mode? wtf!")
            }
          } else {
            log.Println(self.name, "failed to set reader mode")
          }
        }
      case msgid := <- self.check:
        conn.PrintfLine("CHECK %s", msgid)
      case msgid := <- self.take:
        // send a file via TAKETHIS
        if ValidMessageID(msgid) {
          fname := daemon.store.GetFilename(line)
          if CheckFile(fname) {
            f, err := os.Open(fname)
            if err == nil {
              // time to send
              err = conn.PrintfLine("TAKETHIS %s", msgid)
              dw := conn.DotWriter()
              _ , err = io.Copy(dw, f)
              err = dw.Close()
              f.Close()
            }
          } else {
            log.Println(self.name, "didn't send", msgid, "we don't have it locally")
          }
        }
      default:
        code, line, err = conn.ReadCodeLine(-1)
        if code == 238 {
          if ValidMessageID(line) {
            log.Println("sending", line, "to", self.name)
            // send the article to us
            self.take <- line
          }
        } else if code == 239 {
          // successful TAKETHIS
          log.Println(line, "sent via", self.name)
          // TODO: remember success
        } else if code == 431 {
          // CHECK said we would like this article later
          log.Println("defer sending", line, "to", self.name)
          go self.articleDefer(line)
        } else if code == 439 {
          // TAKETHIS failed
          log.Println(line, "was not sent to", self.name, "denied")
          // TODO: remember denial
        } else if code == 438 {
          // they don't want the article
          // TODO: remeber rejection
        } else {
          // handle command
          parts := strings.Split(line, " ")
          if len(parts) == 2 {
            cmd := parts[0]
            if cmd == "MODE" {
              if parts[1] == "READER" {
                self.mode = "READER"
                log.Println(self.name, "switched to reader mode")
              } else if parts[1] == "STREAM" {
                // wut? we're already in streaming mode
                log.Println(self.name, "already in streaming mode")
                conn.PrintfLine("203 Streaming enabled brah")
              } else {
                log.Println(self.name, "got invalid mode request", parts[1])
                conn.PrintfLine("501 invalid mode variant:", parts[1])
              }
            } else if cmd == "CHECK" {
              // handle check command
              msgid := parts[1]
              // have we seen this article?
              if daemon.database.HasArticle(msgid) {
                // yeh don't want it
                conn.PrintfLine("438 %s", msgid)
              } else {
                // yes we do want it and we don't have it
                conn.PrintfLine("238 %s", msgid)
              }
            } else if cmd == "TAKETHIS" {
              // read the article headers
              var hdr textproto.MIMEHeader
              hdr, err = conn.ReadMIMEHeader()
              // check the headers and see if we want this article
              newsgroup := hdr.Get("Newsgroups")
              reference := hdr.Get("References")
              msgid := hdr.Get("Message-Id")
              encaddr := hdr.Get("X-Encrypted-Ip")
              torposter := hdr.Get("X-Tor-Poster")
              i2paddr := hdr.Get("X-I2p-Desthash")
              content_type := hdr.Get("Content-Type")
              has_attachment := strings.HasPrefix(content_type, "multipart/mixed")
              pubkey := hdr.Get("X-Pubkey-Ed25519")
              // TODO: allow certain pubkeys?
              is_signed := pubkey != ""
              is_ctl := newsgroup == "ctl" && is_signed
              anon_poster := torposter != "" || i2paddr != "" || encaddr == ""

              if ! newsgroupValidFormat(newsgroup) {
                // invalid newsgroup format
                code = 439
              } else if ! ( ValidMessageID(msgid) && ( reference != "" && ValidMessageID(reference) ) ) {
                // invalid message id or reference
                code = 439
              } else if daemon.store.HasArticle(msgid) {
                // we already have this article locally
                code = 439
              } else if daemon.database.HasArticle(msgid) {
                // we have already seen this article
                log.Println(self.name, "already seen", msgid)
                code = 439
              } else if reference != "" && daemon.database.IsExpired(reference) {
                // this belongs to a root post that is expired or banned
                code = 439
              } else if is_ctl {
                // we always allow control messages
                code = 239
              } else if anon_poster {
                // this was posted anonymously
                if daemon.allow_anon {
                  if has_attachment || is_signed {
                    // this is a signed message or has attachment
                    if daemon.allow_anon_attachments {
                      // we'll allow anon attachments
                      code = 239
                    } else {
                      // we don't take signed messages or attachments posted anonymously
                      code = 439
                    }
                  } else {
                    // we allow anon posts that are plain
                    code = 239
                  }
                } else {
                  // we don't allow anon posts of any kind
                  code = 439
                }
              } else {
                // check for banned address
                banned, err := daemon.database.CheckEncIPBanned(encaddr)
                if err == nil {
                  if banned {
                    // this address is banned
                    code = 439
                  } else {
                    // not banned
                    code = 239
                  }
                } else {
                  // an error occured
                  log.Println(self.name, "failed to check ban for", encaddr, err)
                  // do a 400
                  conn.PrintfLine("400 Service temporarily unavailable")
                  conn.Close()
                  return
                }
              }
            }
          }
        }
      }
    } else if self.mode == "READER" {

    }
  }
  log.Println("run connection got error", err)
  conn.Close()
}

func (self nntpConnection) articleDefer(msgid string) {
  time.Sleep(time.Second * 90)
  self.check <- msgid
}
<commit_msg>detect srnd<commit_after>//
// nntp.go -- nntp interface for peering
//
package srnd

import (
  "bufio"
  "io"
  "log"
  "net/textproto"
  "os"
  "strings"
  "sync"
  "time"
)

// nntp connection state
type nntpConnection struct {
  // the name of this feed
  name string
  // the mode we are in now
  mode string
  // the policy for federation
  policy FeedPolicy
  // lock help when expecting non pipelined activity
  access sync.Mutex

  // CHECK <message-id>
  check chan string
  // ARTICLE <message-id>
  article chan string
  // TAKETHIS <message-id>
  take chan string
}

func createNNTPConnection() nntpConnection {
  return nntpConnection{
    check: make(chan string, 32),
    article: make(chan string, 32),
    take: make(chan string, 32),
  }
}

// switch modes
func (self *nntpConnection) modeSwitch(mode string, conn *textproto.Conn) (success bool, err error) {
  self.access.Lock()
  mode = strings.ToUpper(mode)
  conn.PrintfLine("MODE %s", mode)
  log.Println("MODE", mode)
  var code int
  code, _, err = conn.ReadCodeLine(-1)
  if code > 200 && code < 300 {
    // accepted mode change
    if len(self.mode) > 0 {
      log.Printf("mode switch %s -> %s", self.mode, mode)
    } else {
      log.Println("switched to mode", mode)
    }
    self.mode = mode
    success = len(self.mode) > 0
  }
  self.access.Unlock()
  return
}

// send a banner for inbound connections
func (self nntpConnection) inboundHandshake(conn *textproto.Conn) (err error) {
  err = conn.PrintfLine("200 Posting Allowed")
  return err
}

// outbound setup, check capabilities and set mode
// returns (supports stream, supports reader) + error
func (self nntpConnection) outboundHandshake(conn *textproto.Conn) (stream, reader bool, err error) {
  log.Println(self.name, "outbound handshake")
  var code int
  var line string
  for err == nil {
    code, line, err = conn.ReadCodeLine(-1)
    if err == nil {
      if code == 200 {
        // send capabilities
        err = conn.PrintfLine("CAPABILITIES")
        if err == nil {
          // read response
          dr := conn.DotReader()
          r := bufio.NewReader(dr)
          for {
            line, err = r.ReadString('\n')
            if err == io.EOF {
              // we are at the end of the dotreader
              // set err back to nil and break out
              err = nil
              break
            } else if err == nil {
              // we got a line
              if line == "MODE-READER\n" {
                log.Println(self.name, "supports READER")
                reader = true
              } else if line == "STREAMING\n" {
                stream = true
                log.Println(self.name, "supports STREAMING")
              } else if line == "POSTIHAVESTREAMING\n" {
                stream = true
                reader = false
                log.Println(self.name, "is SRNd")
              }
            } else {
              // we got an error
              log.Println("error reading capabilities", err)
              break
            }
          }
          // return after reading
          return
        }
      } else if code == 201 {
        log.Println("feed", self.name,"does not allow posting")
        // we don't do auth yet
        break
      } else {
        continue
      }
    }
  }
  return
}

// run the mainloop for this connection
// stream if true means they support streaming mode
// reader if true means they support reader mode
func (self nntpConnection) runConnection(daemon NNTPDaemon, inbound, stream, reader bool, conn *textproto.Conn) {

  var err error
  var code int
  var line string
  var success bool

  for err == nil {
    if self.mode == "" {
      if inbound  {
        // no mode set and inbound
        line, err = conn.ReadLine()
      } else {
        // set out mode we are outbound
        if stream {
          success, err = self.modeSwitch("STREAM", conn)
        } else if reader {
          success, err = self.modeSwitch("READER", conn)
        }
        if success {
          log.Println("mode set to", self.mode)
        } else {
          // bullshit
          // we can't do anything so we quit
          log.Println(self.name, "can't stream or read, wtf?")
          conn.PrintfLine("QUIT")
          conn.Close()
          return
        }
      }
    } else if self.mode == "STREAM" {
      // we're in streaming mode
      // let's pipeline this shit
      select {
        // we've are going to ask for an article in READER mode
      case msgid := <- self.article:
        if reader && ValidMessageID(msgid) {
          // switch to reader mode
          success, err = self.modeSwitch("READER", conn)
          if success {
            // send the request
            conn.PrintfLine("ARTICLE %s", msgid)
            code, line, err = conn.ReadCodeLine(-1)
            if code == 220 {
              // awwww yeh we got it
              f := daemon.store.CreateTempFile(msgid)
              if f == nil {
                // already being loaded elsewhere
              } else {
                // read in the article
                dr := conn.DotReader()
                _, err = io.Copy(f, dr)
                f.Close()
                log.Println(msgid, "got from", self.name)
                // tell daemon to load infeed
                daemon.infeed_load <- msgid
              }
            } else if code == 430 {
              // they don't know it D:
              log.Println(msgid, "not known by", self.name)
            } else {
              // invalid response
              log.Println(self.name, "invald response to ARTICLE:", code, line)
            }
            // now switch back to streaming mode
            log.Println(self.name, "switch back to streaming mode")
            success, err = self.modeSwitch("STREAM", conn)
            if ! success {
              log.Println(self.name, "failed to switch back to streaming mode? wtf!")
            }
          } else {
            log.Println(self.name, "failed to set reader mode")
          }
        }
      case msgid := <- self.check:
        conn.PrintfLine("CHECK %s", msgid)
      case msgid := <- self.take:
        // send a file via TAKETHIS
        if ValidMessageID(msgid) {
          fname := daemon.store.GetFilename(line)
          if CheckFile(fname) {
            f, err := os.Open(fname)
            if err == nil {
              // time to send
              err = conn.PrintfLine("TAKETHIS %s", msgid)
              dw := conn.DotWriter()
              _ , err = io.Copy(dw, f)
              err = dw.Close()
              f.Close()
            }
          } else {
            log.Println(self.name, "didn't send", msgid, "we don't have it locally")
          }
        }
      default:
        code, line, err = conn.ReadCodeLine(-1)
        if code == 238 {
          if ValidMessageID(line) {
            log.Println("sending", line, "to", self.name)
            // send the article to us
            self.take <- line
          }
        } else if code == 239 {
          // successful TAKETHIS
          log.Println(line, "sent via", self.name)
          // TODO: remember success
        } else if code == 431 {
          // CHECK said we would like this article later
          log.Println("defer sending", line, "to", self.name)
          go self.articleDefer(line)
        } else if code == 439 {
          // TAKETHIS failed
          log.Println(line, "was not sent to", self.name, "denied")
          // TODO: remember denial
        } else if code == 438 {
          // they don't want the article
          // TODO: remeber rejection
        } else {
          // handle command
          parts := strings.Split(line, " ")
          if len(parts) == 2 {
            cmd := parts[0]
            if cmd == "MODE" {
              if parts[1] == "READER" {
                self.mode = "READER"
                log.Println(self.name, "switched to reader mode")
              } else if parts[1] == "STREAM" {
                // wut? we're already in streaming mode
                log.Println(self.name, "already in streaming mode")
                conn.PrintfLine("203 Streaming enabled brah")
              } else {
                log.Println(self.name, "got invalid mode request", parts[1])
                conn.PrintfLine("501 invalid mode variant:", parts[1])
              }
            } else if cmd == "CHECK" {
              // handle check command
              msgid := parts[1]
              // have we seen this article?
              if daemon.database.HasArticle(msgid) {
                // yeh don't want it
                conn.PrintfLine("438 %s", msgid)
              } else {
                // yes we do want it and we don't have it
                conn.PrintfLine("238 %s", msgid)
              }
            } else if cmd == "TAKETHIS" {
              // read the article headers
              var hdr textproto.MIMEHeader
              hdr, err = conn.ReadMIMEHeader()
              // check the headers and see if we want this article
              newsgroup := hdr.Get("Newsgroups")
              reference := hdr.Get("References")
              msgid := hdr.Get("Message-Id")
              encaddr := hdr.Get("X-Encrypted-Ip")
              torposter := hdr.Get("X-Tor-Poster")
              i2paddr := hdr.Get("X-I2p-Desthash")
              content_type := hdr.Get("Content-Type")
              has_attachment := strings.HasPrefix(content_type, "multipart/mixed")
              pubkey := hdr.Get("X-Pubkey-Ed25519")
              // TODO: allow certain pubkeys?
              is_signed := pubkey != ""
              is_ctl := newsgroup == "ctl" && is_signed
              anon_poster := torposter != "" || i2paddr != "" || encaddr == ""

              if ! newsgroupValidFormat(newsgroup) {
                // invalid newsgroup format
                code = 439
              } else if ! ( ValidMessageID(msgid) && ( reference != "" && ValidMessageID(reference) ) ) {
                // invalid message id or reference
                code = 439
              } else if daemon.store.HasArticle(msgid) {
                // we already have this article locally
                code = 439
              } else if daemon.database.HasArticle(msgid) {
                // we have already seen this article
                log.Println(self.name, "already seen", msgid)
                code = 439
              } else if reference != "" && daemon.database.IsExpired(reference) {
                // this belongs to a root post that is expired or banned
                code = 439
              } else if is_ctl {
                // we always allow control messages
                code = 239
              } else if anon_poster {
                // this was posted anonymously
                if daemon.allow_anon {
                  if has_attachment || is_signed {
                    // this is a signed message or has attachment
                    if daemon.allow_anon_attachments {
                      // we'll allow anon attachments
                      code = 239
                    } else {
                      // we don't take signed messages or attachments posted anonymously
                      code = 439
                    }
                  } else {
                    // we allow anon posts that are plain
                    code = 239
                  }
                } else {
                  // we don't allow anon posts of any kind
                  code = 439
                }
              } else {
                // check for banned address
                banned, err := daemon.database.CheckEncIPBanned(encaddr)
                if err == nil {
                  if banned {
                    // this address is banned
                    code = 439
                  } else {
                    // not banned
                    code = 239
                  }
                } else {
                  // an error occured
                  log.Println(self.name, "failed to check ban for", encaddr, err)
                  // do a 400
                  conn.PrintfLine("400 Service temporarily unavailable")
                  conn.Close()
                  return
                }
              }
            }
          }
        }
      }
    } else if self.mode == "READER" {

    }
  }
  log.Println("run connection got error", err)
  conn.Close()
}

func (self nntpConnection) articleDefer(msgid string) {
  time.Sleep(time.Second * 90)
  self.check <- msgid
}
<|endoftext|>


<commit_before>package terp

import (
	. "fmt"
	"log"
	"net/http"
	"strconv"
)

var Builtins map[string]Command = make(map[string]Command, 0)
var TBuiltins map[string]TCommand = make(map[string]TCommand, 0)

func (fr *Frame) initBuiltins() {
	Builtins["+"] = MkChainingBinaryFlopCmd(fr, 0.0, func(a, b float64) float64 { return a + b })
	Builtins["*"] = MkChainingBinaryFlopCmd(fr, 1.0, func(a, b float64) float64 { return a * b })
	Builtins["-"] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return a - b })
	Builtins["/"] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return a / b })

	Builtins["=="] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return ToFloat(a == b) })
	Builtins["!="] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return ToFloat(a != b) })
	Builtins["<"] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return ToFloat(a < b) })
	Builtins["<="] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return ToFloat(a <= b) })
	Builtins[">"] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return ToFloat(a > b) })
	Builtins[">="] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return ToFloat(a >= b) })

	Builtins["must"] = cmdMust
	Builtins["if"] = cmdIf
	Builtins["get"] = cmdGet
	Builtins["set"] = cmdSet
	Builtins["proc"] = cmdProc
	Builtins["ls"] = cmdLs
	Builtins["slen"] = cmdSLen
	Builtins["llen"] = cmdLLen
	Builtins["list"] = cmdList
	Builtins["sat"] = cmdSAt
	Builtins["lat"] = cmdLAt
	Builtins["nil"] = cmdNil
	Builtins["http_handler"] = cmdHttpHandler
}

func (fr *Frame) initTBuiltins() {
	TBuiltins["+"] = MkChainingBinaryFlopTCmd(fr, 0.0, func(a, b float64) float64 { return a + b })
	TBuiltins["*"] = MkChainingBinaryFlopTCmd(fr, 1.0, func(a, b float64) float64 { return a * b })
	TBuiltins["-"] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return a - b })
	TBuiltins["/"] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return a / b })

	TBuiltins["=="] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return ToFloat(a == b) })
	TBuiltins["!="] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return ToFloat(a != b) })
	TBuiltins["<"] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return ToFloat(a < b) })
	TBuiltins["<="] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return ToFloat(a <= b) })
	TBuiltins[">"] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return ToFloat(a > b) })
	TBuiltins[">="] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return ToFloat(a >= b) })
	TBuiltins["must"] = tcmdMust

	TBuiltins["if"] = newcmd(cmdIf)
	TBuiltins["get"] = newcmd(cmdGet)
	TBuiltins["set"] = newcmd(cmdSet)
	TBuiltins["proc"] = newcmd(cmdProc)
	TBuiltins["ls"] = newcmd(cmdLs)
	TBuiltins["slen"] = newcmd(cmdSLen)
	TBuiltins["llen"] = newcmd(cmdLLen)
	TBuiltins["list"] = newcmd(cmdList)
	TBuiltins["sat"] = newcmd(cmdSAt)
	TBuiltins["lat"] = newcmd(cmdLAt)
	TBuiltins["nil"] = newcmd(cmdNil)
	TBuiltins["http_handler"] = newcmd(cmdHttpHandler)
/*
	TBuiltins["if"] = tcmdIf
	TBuiltins["get"] = tcmdGet
	TBuiltins["set"] = tcmdSet
	TBuiltins["proc"] = tcmdProc
	TBuiltins["ls"] = tcmdLs
	TBuiltins["slen"] = tcmdSLen
	TBuiltins["llen"] = tcmdLLen
	TBuiltins["list"] = tcmdList
	TBuiltins["sat"] = tcmdSAt
	TBuiltins["lat"] = tcmdLAt
	TBuiltins["nil"] = tcmdNil
	TBuiltins["http_handler"] = tcmdHttpHandler
*/
}
type BinaryFlop func(a, b float64) float64

func MkBinaryFlopCmd(fr *Frame, flop BinaryFlop) Command {
	return func(fr *Frame, argv List) Any {
		a, b := Argv2(argv)
		return flop(ToFloat(a), ToFloat(b))
	}
}

func MkBinaryFlopTCmd(fr *Frame, flop BinaryFlop) TCommand {
	return func(fr *Frame, argv []T) T {
		a, b := TArgv2(argv)
		return MkTf(flop(a.Float(), b.Float()))
	}
}

func MkChainingBinaryFlopCmd(fr *Frame, starter float64, flop BinaryFlop) Command {
	return func(fr *Frame, argv List) Any {
		z := starter // Be sure not to modify starter!  It is captured.
		for _, a := range argv[1:] {
			z = flop(z, ToFloat(a))
		}
		return z
	}
}

func MkChainingBinaryFlopTCmd(fr *Frame, starter float64, flop BinaryFlop) TCommand {
	return func(fr *Frame, argv []T) T {
		z := starter // Be sure not to modify starter!  It is captured.
		for _, a := range argv[1:] {
			z = flop(z, a.Float())
		}
		return MkTf(z)
	}
}

func TTruth(a T) bool {
	switch x := a.(type) {
	case Tf:
		return x.f != 0
	case Ts:
		return len(x.s) > 0
	case Tl:
		return len(x.l) > 0
	}
	// To Do: Value(nil) Value(false) are false.
	return true
}
func Truth(a Any) bool {
	switch x := a.(type) {
	case float64:
		return x != 0
	case float32:
		return x != 0
	case uint64:
		return x != 0
	case int64:
		return x != 0
	case int:
		return x != 0
	case uint:
		return x != 0
	case byte:
		return x != 0
	case rune:
		return x != 0
	case bool:
		return x
	case string:
		return len(x) != 0
	case List:
		return len(x) != 0
	case Dict:
		return len(x) != 0
	}
	panic(Sprintf("Case not supported in Truth(): %#v", a))
}

func ToFloat(a Any) float64 {
	switch x := a.(type) {
	case float64:
		return x
	case float32:
		return float64(x)
	case uint64:
		return float64(x)
	case int64:
		return float64(x)
	case int:
		return float64(x)
	case uint:
		return float64(x)
	case byte:
		return float64(x)
	case rune:
		return float64(x)
	case bool:
		log.Printf("BOOL %v", x)
		if x {
			return 1.0
		}
		return 0.0
	}
	f, err := strconv.ParseFloat(Str(a), 64)
	if err != nil {
		panic(Sprintf("Cannot Parse Float: %q", a))
	}
	return f
}

func Argv1(argv List) Any {
	if len(argv) != 1+1 {
		panic(Sprintf("Expected 1 arguments, but got %#v", argv))
	}
	return argv[1]
}

func Argv2(argv List) (Any, Any) {
	if len(argv) != 2+1 {
		panic(Sprintf("Expected 2 arguments, but got %#v", argv))
	}
	return argv[1], argv[2]
}

func Argv3(argv List) (Any, Any, Any) {
	if len(argv) != 3+1 {
		panic(Sprintf("Expected 3 arguments, but got %#v", argv))
	}
	return argv[1], argv[2], argv[3]
}

func TArgv1(argv []T) T {
	if len(argv) != 1+1 {
		panic(Sprintf("Expected 1 arguments, but got argv=%#v", argv))
	}
	return argv[1]
}

func TArgv2(argv []T) (T, T) {
	if len(argv) != 2+1 {
		panic(Sprintf("Expected 2 arguments, but got argv=%#v", argv))
	}
	return argv[1], argv[2]
}

func TArgv3(argv []T) (T, T, T) {
	if len(argv) != 3+1 {
		panic(Sprintf("Expected 3 arguments, but got argv=%#v", argv))
	}
	return argv[1], argv[2], argv[3]
}

func cmdMust(fr *Frame, argv List) Any {
	x := Str(argv[1])
	y := Str(argv[2])

	if x == y {
		return argv[2]
	}

	panic("FAILED: must: " + Repr(argv) + " -- x: " + x + " -- y: " + y)
}
func tcmdMust(fr *Frame, argv []T) T {
	xx, yy := TArgv2(argv)
	x := xx.String()
	y := yy.String()

	if x == y {
		return argv[2]
	}

	panic("FAILED: must: " + Repr(argv) + " -- x: " + x + " -- y: " + y)
}

func cmdIf(fr *Frame, argv List) Any {
	if len(argv) < 3+1 {
		panic(Sprintf("Too few arguments for if: %#v", argv))
	}
	var cond, yes, no Any

	switch len(argv) {
	case 5:
		if argv[3] != "else" {
			panic(Sprintf("Expected 'else' at argv[3]: %#v", argv))
		}
		cond, yes, no = argv[1], argv[2], argv[4]
	case 3:
		cond, yes = argv[1], argv[2]
	default:
		panic(Sprintf("Wrong len(argv) for if: %#v", argv))
	}

	if Truth(fr.Eval(cond)) {
		return fr.Eval(yes)
	}

	if no != nil {
		return fr.Eval(no)
	}

	return nil
}

func cmdGet(fr *Frame, argv List) Any {
	name := Argv1(argv)
	return fr.GetVar(Str(name))
}

func cmdSet(fr *Frame, argv List) Any {
	name, x := Argv2(argv)
	fr.SetVar(Str(name), x)
	return x
}

func cmdProc(fr *Frame, argv List) Any {
	name, aa, body := Argv3(argv)
	alist := ParseList(aa)
	astrs := make([]string, len(alist))
	for i, arg := range alist {
		astr := Str(arg)
		if !IsLocal(astr) {
			panic(Sprintf("Cannot use nonlocal name %q for argument in proc", arg))
		}
		astrs[i] = astr
	}
	n := len(alist) + 1
	cmd := func(fr2 *Frame, argv2 List) Any {
		if argv2 == nil {
			// Debug Data, if invoked with nil argv2.
			return argv
		}
		if len(argv2) != n {
			panic(Sprintf("Proc %q expects args %#v but got %#v", name, aa, argv2))
		}
		fr3 := fr2.NewFrame()
		for i, arg := range astrs {
			fr3.SetVar(arg, argv2[i+1])
		}
		return fr3.Eval(body)
	}
	fr.G.Cmds[Str(name)] = cmd
	return nil
}

func cmdLs(fr *Frame, argv List) Any {
	name := Argv1(argv)
	fn := fr.G.Cmds[Str(name)]
	return fn(fr, nil)
}

func cmdSLen(fr *Frame, argv List) Any {
	a := Argv1(argv)
	return float64(len(Str(a)))
}

func cmdLLen(fr *Frame, argv List) Any {
	a := Argv1(argv)
	return float64(len(ParseList(a)))
}

func cmdList(fr *Frame, argv List) Any {
	return argv[1:]
}

func cmdLAt(fr *Frame, argv List) Any {
	v, j := Argv2(argv)
	f := ToFloat(j)
	i := int(f)
	return ParseList(v)[i]
}

func cmdSAt(fr *Frame, argv List) Any {
	s, j := Argv2(argv)
	f := ToFloat(j)
	i := int(f)
	return Str(s)[i : i+1]
}

func cmdNil(fr *Frame, argv List) Any { // TODO
	return http.Handler(nil)
}

func cmdHttpHandler(fr *Frame, argv List) Any {
	return func (w http.ResponseWriter, r *http.Request) {
		v := make(List, len(argv)-1)
		copy(v, argv[1:])
		v = LAppend(v, w)
		v = LAppend(v, r)
		_ = fr.Apply(v)
	}
}

<commit_msg>convert cmdIf to xcmdIf<commit_after>package terp

import (
	. "fmt"
	"log"
	"net/http"
	"strconv"
)

var Builtins map[string]Command = make(map[string]Command, 0)
var TBuiltins map[string]TCommand = make(map[string]TCommand, 0)

func (fr *Frame) initBuiltins() {
	Builtins["+"] = MkChainingBinaryFlopCmd(fr, 0.0, func(a, b float64) float64 { return a + b })
	Builtins["*"] = MkChainingBinaryFlopCmd(fr, 1.0, func(a, b float64) float64 { return a * b })
	Builtins["-"] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return a - b })
	Builtins["/"] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return a / b })

	Builtins["=="] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return ToFloat(a == b) })
	Builtins["!="] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return ToFloat(a != b) })
	Builtins["<"] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return ToFloat(a < b) })
	Builtins["<="] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return ToFloat(a <= b) })
	Builtins[">"] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return ToFloat(a > b) })
	Builtins[">="] = MkBinaryFlopCmd(fr, func(a, b float64) float64 { return ToFloat(a >= b) })

	Builtins["must"] = cmdMust
	Builtins["if"] = cmdIf
	Builtins["get"] = cmdGet
	Builtins["set"] = cmdSet
	Builtins["proc"] = cmdProc
	Builtins["ls"] = cmdLs
	Builtins["slen"] = cmdSLen
	Builtins["llen"] = cmdLLen
	Builtins["list"] = cmdList
	Builtins["sat"] = cmdSAt
	Builtins["lat"] = cmdLAt
	Builtins["nil"] = cmdNil
	Builtins["http_handler"] = cmdHttpHandler
}

func (fr *Frame) initTBuiltins() {
	TBuiltins["+"] = MkChainingBinaryFlopTCmd(fr, 0.0, func(a, b float64) float64 { return a + b })
	TBuiltins["*"] = MkChainingBinaryFlopTCmd(fr, 1.0, func(a, b float64) float64 { return a * b })
	TBuiltins["-"] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return a - b })
	TBuiltins["/"] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return a / b })

	TBuiltins["=="] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return ToFloat(a == b) })
	TBuiltins["!="] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return ToFloat(a != b) })
	TBuiltins["<"] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return ToFloat(a < b) })
	TBuiltins["<="] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return ToFloat(a <= b) })
	TBuiltins[">"] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return ToFloat(a > b) })
	TBuiltins[">="] = MkBinaryFlopTCmd(fr, func(a, b float64) float64 { return ToFloat(a >= b) })
	TBuiltins["must"] = tcmdMust

	TBuiltins["if"] = tcmdIf
	TBuiltins["get"] = newcmd(cmdGet)
	TBuiltins["set"] = newcmd(cmdSet)
	TBuiltins["proc"] = newcmd(cmdProc)
	TBuiltins["ls"] = newcmd(cmdLs)
	TBuiltins["slen"] = newcmd(cmdSLen)
	TBuiltins["llen"] = newcmd(cmdLLen)
	TBuiltins["list"] = newcmd(cmdList)
	TBuiltins["sat"] = newcmd(cmdSAt)
	TBuiltins["lat"] = newcmd(cmdLAt)
	TBuiltins["nil"] = newcmd(cmdNil)
	TBuiltins["http_handler"] = newcmd(cmdHttpHandler)
/*
	TBuiltins["if"] = tcmdIf
	TBuiltins["get"] = tcmdGet
	TBuiltins["set"] = tcmdSet
	TBuiltins["proc"] = tcmdProc
	TBuiltins["ls"] = tcmdLs
	TBuiltins["slen"] = tcmdSLen
	TBuiltins["llen"] = tcmdLLen
	TBuiltins["list"] = tcmdList
	TBuiltins["sat"] = tcmdSAt
	TBuiltins["lat"] = tcmdLAt
	TBuiltins["nil"] = tcmdNil
	TBuiltins["http_handler"] = tcmdHttpHandler
*/
}
type BinaryFlop func(a, b float64) float64

func MkBinaryFlopCmd(fr *Frame, flop BinaryFlop) Command {
	return func(fr *Frame, argv List) Any {
		a, b := Argv2(argv)
		return flop(ToFloat(a), ToFloat(b))
	}
}

func MkBinaryFlopTCmd(fr *Frame, flop BinaryFlop) TCommand {
	return func(fr *Frame, argv []T) T {
		a, b := TArgv2(argv)
		return MkTf(flop(a.Float(), b.Float()))
	}
}

func MkChainingBinaryFlopCmd(fr *Frame, starter float64, flop BinaryFlop) Command {
	return func(fr *Frame, argv List) Any {
		z := starter // Be sure not to modify starter!  It is captured.
		for _, a := range argv[1:] {
			z = flop(z, ToFloat(a))
		}
		return z
	}
}

func MkChainingBinaryFlopTCmd(fr *Frame, starter float64, flop BinaryFlop) TCommand {
	return func(fr *Frame, argv []T) T {
		z := starter // Be sure not to modify starter!  It is captured.
		for _, a := range argv[1:] {
			z = flop(z, a.Float())
		}
		return MkTf(z)
	}
}

func TTruth(a T) bool {
	switch x := a.(type) {
	case Tf:
		return x.f != 0
	case Ts:
		return len(x.s) > 0
	case Tl:
		return len(x.l) > 0
	}
	// To Do: Value(nil) Value(false) are false.
	return true
}
func Truth(a Any) bool {
	switch x := a.(type) {
	case float64:
		return x != 0
	case float32:
		return x != 0
	case uint64:
		return x != 0
	case int64:
		return x != 0
	case int:
		return x != 0
	case uint:
		return x != 0
	case byte:
		return x != 0
	case rune:
		return x != 0
	case bool:
		return x
	case string:
		return len(x) != 0
	case List:
		return len(x) != 0
	case Dict:
		return len(x) != 0
	}
	panic(Sprintf("Case not supported in Truth(): %#v", a))
}

func ToFloat(a Any) float64 {
	switch x := a.(type) {
	case float64:
		return x
	case float32:
		return float64(x)
	case uint64:
		return float64(x)
	case int64:
		return float64(x)
	case int:
		return float64(x)
	case uint:
		return float64(x)
	case byte:
		return float64(x)
	case rune:
		return float64(x)
	case bool:
		log.Printf("BOOL %v", x)
		if x {
			return 1.0
		}
		return 0.0
	}
	f, err := strconv.ParseFloat(Str(a), 64)
	if err != nil {
		panic(Sprintf("Cannot Parse Float: %q", a))
	}
	return f
}

func Argv1(argv List) Any {
	if len(argv) != 1+1 {
		panic(Sprintf("Expected 1 arguments, but got %#v", argv))
	}
	return argv[1]
}

func Argv2(argv List) (Any, Any) {
	if len(argv) != 2+1 {
		panic(Sprintf("Expected 2 arguments, but got %#v", argv))
	}
	return argv[1], argv[2]
}

func Argv3(argv List) (Any, Any, Any) {
	if len(argv) != 3+1 {
		panic(Sprintf("Expected 3 arguments, but got %#v", argv))
	}
	return argv[1], argv[2], argv[3]
}

func TArgv1(argv []T) T {
	if len(argv) != 1+1 {
		panic(Sprintf("Expected 1 arguments, but got argv=%#v", argv))
	}
	return argv[1]
}

func TArgv2(argv []T) (T, T) {
	if len(argv) != 2+1 {
		panic(Sprintf("Expected 2 arguments, but got argv=%#v", argv))
	}
	return argv[1], argv[2]
}

func TArgv3(argv []T) (T, T, T) {
	if len(argv) != 3+1 {
		panic(Sprintf("Expected 3 arguments, but got argv=%#v", argv))
	}
	return argv[1], argv[2], argv[3]
}

func cmdMust(fr *Frame, argv List) Any {
	x := Str(argv[1])
	y := Str(argv[2])

	if x == y {
		return argv[2]
	}

	panic("FAILED: must: " + Repr(argv) + " -- x: " + x + " -- y: " + y)
}
func tcmdMust(fr *Frame, argv []T) T {
	xx, yy := TArgv2(argv)
	x := xx.String()
	y := yy.String()

	if x == y {
		return argv[2]
	}

	panic("FAILED: must: " + Repr(argv) + " -- x: " + x + " -- y: " + y)
}

func tcmdIf(fr *Frame, argv []T) T {
	if len(argv) < 3+1 {
		panic(Sprintf("Too few arguments for if: %#v", argv))
	}
	var cond, yes, no T

	switch len(argv) {
	case 5:
		if argv[3].String() != "else" {
			panic(Sprintf("Expected 'else' at argv[3]: %#v", argv))
		}
		cond, yes, no = argv[1], argv[2], argv[4]
	case 3:
		cond, yes = argv[1], argv[2]
	default:
		panic(Sprintf("Wrong len(argv) for if: %#v", argv))
	}

	if TTruth(fr.TEval(cond)) {
		return fr.TEval(yes)
	}

	if no != nil {
		return fr.TEval(no)
	}

	return MkTs("")
}

func cmdIf(fr *Frame, argv List) Any {
	if len(argv) < 3+1 {
		panic(Sprintf("Too few arguments for if: %#v", argv))
	}
	var cond, yes, no Any

	switch len(argv) {
	case 5:
		if argv[3] != "else" {
			panic(Sprintf("Expected 'else' at argv[3]: %#v", argv))
		}
		cond, yes, no = argv[1], argv[2], argv[4]
	case 3:
		cond, yes = argv[1], argv[2]
	default:
		panic(Sprintf("Wrong len(argv) for if: %#v", argv))
	}

	if Truth(fr.Eval(cond)) {
		return fr.Eval(yes)
	}

	if no != nil {
		return fr.Eval(no)
	}

	return nil
}

func cmdGet(fr *Frame, argv List) Any {
	name := Argv1(argv)
	return fr.GetVar(Str(name))
}

func cmdSet(fr *Frame, argv List) Any {
	name, x := Argv2(argv)
	fr.SetVar(Str(name), x)
	return x
}

func cmdProc(fr *Frame, argv List) Any {
	name, aa, body := Argv3(argv)
	alist := ParseList(aa)
	astrs := make([]string, len(alist))
	for i, arg := range alist {
		astr := Str(arg)
		if !IsLocal(astr) {
			panic(Sprintf("Cannot use nonlocal name %q for argument in proc", arg))
		}
		astrs[i] = astr
	}
	n := len(alist) + 1
	cmd := func(fr2 *Frame, argv2 List) Any {
		if argv2 == nil {
			// Debug Data, if invoked with nil argv2.
			return argv
		}
		if len(argv2) != n {
			panic(Sprintf("Proc %q expects args %#v but got %#v", name, aa, argv2))
		}
		fr3 := fr2.NewFrame()
		for i, arg := range astrs {
			fr3.SetVar(arg, argv2[i+1])
		}
		return fr3.Eval(body)
	}
	fr.G.Cmds[Str(name)] = cmd
	return nil
}

func cmdLs(fr *Frame, argv List) Any {
	name := Argv1(argv)
	fn := fr.G.Cmds[Str(name)]
	return fn(fr, nil)
}

func cmdSLen(fr *Frame, argv List) Any {
	a := Argv1(argv)
	return float64(len(Str(a)))
}

func cmdLLen(fr *Frame, argv List) Any {
	a := Argv1(argv)
	return float64(len(ParseList(a)))
}

func cmdList(fr *Frame, argv List) Any {
	return argv[1:]
}

func cmdLAt(fr *Frame, argv List) Any {
	v, j := Argv2(argv)
	f := ToFloat(j)
	i := int(f)
	return ParseList(v)[i]
}

func cmdSAt(fr *Frame, argv List) Any {
	s, j := Argv2(argv)
	f := ToFloat(j)
	i := int(f)
	return Str(s)[i : i+1]
}

func cmdNil(fr *Frame, argv List) Any { // TODO
	return http.Handler(nil)
}

func cmdHttpHandler(fr *Frame, argv List) Any {
	return func (w http.ResponseWriter, r *http.Request) {
		v := make(List, len(argv)-1)
		copy(v, argv[1:])
		v = LAppend(v, w)
		v = LAppend(v, r)
		_ = fr.Apply(v)
	}
}

<|endoftext|>


<commit_before>// Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.

package provider

import (
	"fmt"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"

	"github.com/terraform-providers/terraform-provider-oci/httpreplay"
)

var (
	auditEventDataSourceRepresentation = map[string]interface{}{
		"compartment_id": Representation{repType: Required, create: `${var.compartment_id}`},
		"end_time":       Representation{repType: Required, create: `${timestamp()}`},
		"start_time":     Representation{repType: Required, create: `${timeadd(timestamp(), "-1m")}`},
		"limit":          Representation{repType: Required, create: `1`},
	}

	AuditEventResourceConfig = ""
)

func TestAuditAuditEventResource_basic(t *testing.T) {
	httpreplay.SetScenario("TestAuditAuditEventResource_basic")
	defer httpreplay.SaveScenario()

	provider := testAccProvider
	config := testProviderConfig()

	compartmentId := getEnvSettingWithBlankDefault("compartment_ocid")
	compartmentIdVariableStr := fmt.Sprintf("variable \"compartment_id\" { default = \"%s\" }\n", compartmentId)

	datasourceName := "data.oci_audit_events.test_audit_events"

	resource.Test(t, resource.TestCase{
		PreCheck: func() { testAccPreCheck(t) },
		Providers: map[string]terraform.ResourceProvider{
			"oci": provider,
		},
		Steps: []resource.TestStep{
			// verify datasource
			{
				Config: config +
					generateDataSourceFromRepresentationMap("oci_audit_events", "test_audit_events", Required, Create, auditEventDataSourceRepresentation) +
					compartmentIdVariableStr + AuditEventResourceConfig,
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttr(datasourceName, "compartment_id", compartmentId),
					resource.TestCheckResourceAttrSet(datasourceName, "end_time"),
					resource.TestCheckResourceAttrSet(datasourceName, "start_time"),

					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.#"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.compartment_id"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.event_id"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.event_name"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.event_source"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.event_time"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.event_type"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.principal_id"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.request_action"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.request_agent"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.request_id"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.request_origin"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.request_resource"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.response_status"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.response_time"),
					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.0.tenant_id"),
				),
			},
		},
	})
}
<commit_msg>fix TER-1410 TestAuditAuditEventResource_basic fail in validation.<commit_after>// Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.

package provider

import (
	"fmt"
	"testing"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"

	"github.com/terraform-providers/terraform-provider-oci/httpreplay"
)

var (
	auditEventDataSourceRepresentation = map[string]interface{}{
		"compartment_id": Representation{repType: Required, create: `${var.compartment_id}`},
		"end_time":       Representation{repType: Required, create: `${timestamp()}`},
		"start_time":     Representation{repType: Required, create: `${timeadd(timestamp(), "-1m")}`},
		"limit":          Representation{repType: Required, create: `1`},
	}

	AuditEventResourceConfig = ""
)

func TestAuditAuditEventResource_basic(t *testing.T) {
	httpreplay.SetScenario("TestAuditAuditEventResource_basic")
	defer httpreplay.SaveScenario()

	provider := testAccProvider
	config := testProviderConfig()

	compartmentId := getEnvSettingWithBlankDefault("compartment_ocid")
	compartmentIdVariableStr := fmt.Sprintf("variable \"compartment_id\" { default = \"%s\" }\n", compartmentId)

	datasourceName := "data.oci_audit_events.test_audit_events"

	resource.Test(t, resource.TestCase{
		PreCheck: func() { testAccPreCheck(t) },
		Providers: map[string]terraform.ResourceProvider{
			"oci": provider,
		},
		Steps: []resource.TestStep{
			// verify datasource
			{
				Config: config +
					generateDataSourceFromRepresentationMap("oci_audit_events", "test_audit_events", Required, Create, auditEventDataSourceRepresentation) +
					compartmentIdVariableStr + AuditEventResourceConfig,
				Check: resource.ComposeAggregateTestCheckFunc(
					resource.TestCheckResourceAttr(datasourceName, "compartment_id", compartmentId),
					resource.TestCheckResourceAttrSet(datasourceName, "end_time"),
					resource.TestCheckResourceAttrSet(datasourceName, "start_time"),

					resource.TestCheckResourceAttrSet(datasourceName, "audit_events.#"),
				),
			},
		},
	})
}
<|endoftext|>


<commit_before>// get sqrt by Newton's method
// https://zh.wikipedia.org/wiki/%E7%89%9B%E9%A1%BF%E6%B3%95
// http://blog.punkid.org/2008/02/28/compute-the-square-root-via-newtons-iteration
// http://jashawn.iteye.com/blog/1659680
// x[k+1] = 1/2(x[k] + N/x[k])

package main

import (
	"fmt"
	"math"
	"os"
	"strconv"
)

func newtonIterator(start float64) func(value float64) float64 {
	sqr := start
	return func(value float64) float64 {
		sqr = (sqr + value/sqr) / 2.0
		return sqr
	}
}

// Can be run as follow:
// go run sqrt.go 9
func main() {
	if len(os.Args) != 2 {
		fmt.Println("see usage comments in file")
		return
	}

	num, err := strconv.ParseFloat(os.Args[1], 64)
	if err != nil {
		fmt.Println(err)
		return
	}
	if num < 0 {
		fmt.Println("arg should be a Positive integer")
		return
	}

	sqr := math.Sqrt(num)
	f := newtonIterator(num)
	for i := 0; i < 40; i++ {
		fmt.Println(i, ". ", f(num), ":", sqr)
	}
}
<commit_msg>optmize sqrt algorithm<commit_after>// get sqrt by Newton's method
// https://zh.wikipedia.org/wiki/%E7%89%9B%E9%A1%BF%E6%B3%95
// http://blog.punkid.org/2008/02/28/compute-the-square-root-via-newtons-iteration
// http://jashawn.iteye.com/blog/1659680
// x[k+1] = 1/2(x[k] + N/x[k])

package main

import (
	"fmt"
	"math"
	"os"
	"strconv"
)

func newtonIterator(start float64) func(n float64) float64 {
	sqr := start
	return func(n float64) float64 {
		sqr = (sqr + n/sqr) / 2.0
		return sqr
	}
}

// Can be run as follow:
// go run sqrt.go 9
func main() {
	if len(os.Args) != 2 {
		fmt.Println("see usage comments in file")
		return
	}

	n, err := strconv.ParseFloat(os.Args[1], 64)
	if err != nil {
		fmt.Println(err)
		return
	}
	if n < 0.0 {
		fmt.Println("arg should be a Positive integer")
		return
	}

	start := 1.0
	f := newtonIterator(start)

	rightSqrt, lastSqrt, sqrt := math.Sqrt(n), start, 0.0
	for ; math.Abs(lastSqrt-sqrt) > 1.0e-10; sqrt = f(n) {
		fmt.Println(rightSqrt, sqrt, lastSqrt, math.Abs(lastSqrt-sqrt))
		lastSqrt = sqrt
	}
	fmt.Println("last: ", rightSqrt, sqrt)
}
<|endoftext|>


<commit_before>package eval

import (
	"reflect"
	"testing"

	"github.com/johnny-morrice/godless/crdt"
	"github.com/johnny-morrice/godless/internal/crypto"
	"github.com/johnny-morrice/godless/internal/testutil"
	"github.com/johnny-morrice/godless/query"
)

// TODO implement test.
// func TestRowCriteria_selectMatching(t *testing.T) {
// 	t.Fail()
// }

// The various where predicates are tested elsewhere.  This test focusses
// on whether the correct rows will be discovered for any predicate.
func TestRowCriteria_findRows(t *testing.T) {
	pointA := crdt.UnsignedPoint("hello")
	pointB := crdt.UnsignedPoint("world")

	rowA := crdt.MakeRow(map[crdt.EntryName]crdt.Entry{
		"foo": crdt.MakeEntry([]crdt.Point{pointA}),
	})
	rowB := crdt.MakeRow(map[crdt.EntryName]crdt.Entry{
		"bar": crdt.MakeEntry([]crdt.Point{pointB}),
	})

	streamPointA := makeStreamPoint(pointA.Text, crypto.Signature{})
	streamPointB := makeStreamPoint(pointB.Text, crypto.Signature{})

	namespace := crdt.MakeNamespace(map[crdt.TableName]crdt.Table{
		TABLE_KEY: crdt.MakeTable(map[crdt.RowName]crdt.Row{
			"a": rowA,
			"b": rowB,
			"c": rowB,
		}),
	})

	streamEntryA := crdt.NamespaceStreamEntry{
		Table: TABLE_KEY,
		Row:   "a",
		Entry: "foo",
		Point: streamPointA,
	}

	streamEntryB := crdt.NamespaceStreamEntry{
		Table: TABLE_KEY,
		Row:   "b",
		Entry: "bar",
		Point: streamPointB,
	}

	streamEntryC := crdt.NamespaceStreamEntry{
		Table: TABLE_KEY,
		Row:   "c",
		Entry: "bar",
		Point: streamPointB,
	}

	expected := [][]crdt.NamespaceStreamEntry{
		[]crdt.NamespaceStreamEntry{
			streamEntryA,
		},
		[]crdt.NamespaceStreamEntry{
			streamEntryB, streamEntryC,
		},
	}

	where := []query.QueryWhere{
		query.QueryWhere{
			OpCode: query.PREDICATE,
			Predicate: query.QueryPredicate{
				OpCode:        query.STR_EQ,
				Literals:      []string{"a"},
				IncludeRowKey: true,
			},
		},
		query.QueryWhere{
			OpCode: query.PREDICATE,
			Predicate: query.QueryPredicate{
				OpCode:   query.STR_EQ,
				Literals: []string{"world"},
				Keys:     []crdt.EntryName{"bar"},
			},
		},
	}

	for i, e := range expected {
		w := where[i]
		rc := &rowCriteria{
			tableKey:  TABLE_KEY,
			limit:     10,
			rootWhere: &w,
		}

		actual, invalid := rc.findRows(namespace)

		testutil.AssertLenEquals(t, 0, invalid)

		crdt.SortNamespaceStream(actual)

		if !reflect.DeepEqual(e, actual) {
			t.Error(i, "Expected", e, "but was", actual)
		}
	}
}

func TestRowCriteria_isReady(t *testing.T) {
	bad := []*rowCriteria{
		&rowCriteria{},
		&rowCriteria{limit: 10},
		&rowCriteria{rootWhere: &query.QueryWhere{}},
		&rowCriteria{tableKey: TABLE_KEY},
		&rowCriteria{limit: 10, rootWhere: &query.QueryWhere{}},
		&rowCriteria{limit: 10, tableKey: TABLE_KEY},
		&rowCriteria{rootWhere: &query.QueryWhere{}, tableKey: TABLE_KEY},
	}

	for _, b := range bad {
		if b.isReady() {
			t.Error("Unexpected rowCriteria isReady()")
		}
	}

	okay := &rowCriteria{}
	okay.limit = 10
	okay.rootWhere = &query.QueryWhere{}
	okay.tableKey = TABLE_KEY

	if !okay.isReady() {
		t.Error("Expected rowCriteria isReady()")
	}
}

func makeStreamPoint(text crdt.PointText, sig crypto.Signature) crdt.StreamPoint {
	streamPoint, err := crdt.MakeStreamPoint(text, sig)
	setupPanic(err)
	return streamPoint
}

func setupPanic(err error) {
	if err != nil {
		panic(err)
	}
}

const TABLE_KEY = "The Table"
<commit_msg>Test reflects optional limits.<commit_after>package eval

import (
	"reflect"
	"testing"

	"github.com/johnny-morrice/godless/crdt"
	"github.com/johnny-morrice/godless/internal/crypto"
	"github.com/johnny-morrice/godless/internal/testutil"
	"github.com/johnny-morrice/godless/query"
)

// TODO implement test.
// func TestRowCriteria_selectMatching(t *testing.T) {
// 	t.Fail()
// }

// The various where predicates are tested elsewhere.  This test focusses
// on whether the correct rows will be discovered for any predicate.
func TestRowCriteria_findRows(t *testing.T) {
	pointA := crdt.UnsignedPoint("hello")
	pointB := crdt.UnsignedPoint("world")

	rowA := crdt.MakeRow(map[crdt.EntryName]crdt.Entry{
		"foo": crdt.MakeEntry([]crdt.Point{pointA}),
	})
	rowB := crdt.MakeRow(map[crdt.EntryName]crdt.Entry{
		"bar": crdt.MakeEntry([]crdt.Point{pointB}),
	})

	streamPointA := makeStreamPoint(pointA.Text, crypto.Signature{})
	streamPointB := makeStreamPoint(pointB.Text, crypto.Signature{})

	namespace := crdt.MakeNamespace(map[crdt.TableName]crdt.Table{
		TABLE_KEY: crdt.MakeTable(map[crdt.RowName]crdt.Row{
			"a": rowA,
			"b": rowB,
			"c": rowB,
		}),
	})

	streamEntryA := crdt.NamespaceStreamEntry{
		Table: TABLE_KEY,
		Row:   "a",
		Entry: "foo",
		Point: streamPointA,
	}

	streamEntryB := crdt.NamespaceStreamEntry{
		Table: TABLE_KEY,
		Row:   "b",
		Entry: "bar",
		Point: streamPointB,
	}

	streamEntryC := crdt.NamespaceStreamEntry{
		Table: TABLE_KEY,
		Row:   "c",
		Entry: "bar",
		Point: streamPointB,
	}

	expected := [][]crdt.NamespaceStreamEntry{
		[]crdt.NamespaceStreamEntry{
			streamEntryA,
		},
		[]crdt.NamespaceStreamEntry{
			streamEntryB, streamEntryC,
		},
	}

	where := []query.QueryWhere{
		query.QueryWhere{
			OpCode: query.PREDICATE,
			Predicate: query.QueryPredicate{
				OpCode:        query.STR_EQ,
				Literals:      []string{"a"},
				IncludeRowKey: true,
			},
		},
		query.QueryWhere{
			OpCode: query.PREDICATE,
			Predicate: query.QueryPredicate{
				OpCode:   query.STR_EQ,
				Literals: []string{"world"},
				Keys:     []crdt.EntryName{"bar"},
			},
		},
	}

	for i, e := range expected {
		w := where[i]
		rc := &rowCriteria{
			tableKey:  TABLE_KEY,
			limit:     10,
			rootWhere: &w,
		}

		actual, invalid := rc.findRows(namespace)

		testutil.AssertLenEquals(t, 0, invalid)

		crdt.SortNamespaceStream(actual)

		if !reflect.DeepEqual(e, actual) {
			t.Error(i, "Expected", e, "but was", actual)
		}
	}
}

func TestRowCriteria_isReady(t *testing.T) {
	bad := []*rowCriteria{
		&rowCriteria{},
		&rowCriteria{rootWhere: &query.QueryWhere{}},
		&rowCriteria{tableKey: TABLE_KEY},
	}

	for i, b := range bad {
		if b.isReady() {
			t.Error("Unexpected rowCriteria isReady() at", i)
		}
	}

	okay := &rowCriteria{}
	okay.limit = 10
	okay.rootWhere = &query.QueryWhere{}
	okay.tableKey = TABLE_KEY

	if !okay.isReady() {
		t.Error("Expected rowCriteria isReady()")
	}
}

func makeStreamPoint(text crdt.PointText, sig crypto.Signature) crdt.StreamPoint {
	streamPoint, err := crdt.MakeStreamPoint(text, sig)
	setupPanic(err)
	return streamPoint
}

func setupPanic(err error) {
	if err != nil {
		panic(err)
	}
}

const TABLE_KEY = "The Table"
<|endoftext|>