<commit_before>// Copyright 2016-2017 Authors of Cilium
//
// Licensed 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 mac

import (
	"bytes"
	"encoding/hex"
	"fmt"
	"net"
)

// MAC address is an net.HardwareAddr encapsulation to force cilium to only use MAC-48.
type MAC net.HardwareAddr

// String returns the string representation of m.
func (m MAC) String() string {
	return net.HardwareAddr(m).String()
}

// ParseMAC parses s only as an IEEE 802 MAC-48.
func ParseMAC(s string) (MAC, error) {
	ha, err := net.ParseMAC(s)
	if err != nil {
		return MAC{}, err
	}
	if len(ha) != 6 {
		return MAC{}, fmt.Errorf("invalid MAC address %s", s)
	}

	return MAC(ha), nil
}

// Uint64 returns the MAC in uint64 format. The MAC is represented as little-endian in
// the returned value.
// Example:
//  m := MAC([]{0x11, 0x12, 0x23, 0x34, 0x45, 0x56})
//  v, err := m.Uint64()
//  fmt.Printf("0x%X", v) // 0x564534231211
func (m MAC) Uint64() (uint64, error) {
	if len(m) != 6 {
		return 0, fmt.Errorf("invalid MAC address %s", m.String())
	}

	return uint64(m[5])<<40 | uint64(m[4])<<32 | uint64(m[3])<<24 |
		uint64(m[2])<<16 | uint64(m[1])<<8 | uint64(m[0]), nil
}

func (m MAC) MarshalJSON() ([]byte, error) {
	if len(m) == 0 {
		return []byte(`""`), nil
	}
	if len(m) != 6 {
		return nil, fmt.Errorf("invalid MAC address length %s", string(m))
	}
	return []byte(fmt.Sprintf("\"%02x:%02x:%02x:%02x:%02x:%02x\"", m[0], m[1], m[2], m[3], m[4], m[5])), nil
}

func (m MAC) MarshalIndentJSON(prefix, indent string) ([]byte, error) {
	return m.MarshalJSON()
}

func (m *MAC) UnmarshalJSON(data []byte) error {
	if len(data) == len([]byte(`""`)) {
		if m == nil {
			m = new(MAC)
		}
		*m = MAC{}
		return nil
	}
	if len(data) != 19 {
		return fmt.Errorf("invalid MAC address length %s", string(data))
	}
	data = data[1 : len(data)-1]
	macStr := bytes.Replace(data, []byte(`:`), []byte(``), -1)
	if len(macStr) != 12 {
		return fmt.Errorf("invalid MAC address format")
	}
	macByte := make([]byte, len(macStr))
	hex.Decode(macByte, macStr)
	*m = MAC{macByte[0], macByte[1], macByte[2], macByte[3], macByte[4], macByte[5]}
	return nil
}
<commit_msg>mac: Add function to generate a random MAC addr<commit_after>// Copyright 2016-2017 Authors of Cilium
//
// Licensed 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 mac

import (
	"bytes"
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"net"
)

// MAC address is an net.HardwareAddr encapsulation to force cilium to only use MAC-48.
type MAC net.HardwareAddr

// String returns the string representation of m.
func (m MAC) String() string {
	return net.HardwareAddr(m).String()
}

// ParseMAC parses s only as an IEEE 802 MAC-48.
func ParseMAC(s string) (MAC, error) {
	ha, err := net.ParseMAC(s)
	if err != nil {
		return MAC{}, err
	}
	if len(ha) != 6 {
		return MAC{}, fmt.Errorf("invalid MAC address %s", s)
	}

	return MAC(ha), nil
}

// Uint64 returns the MAC in uint64 format. The MAC is represented as little-endian in
// the returned value.
// Example:
//  m := MAC([]{0x11, 0x12, 0x23, 0x34, 0x45, 0x56})
//  v, err := m.Uint64()
//  fmt.Printf("0x%X", v) // 0x564534231211
func (m MAC) Uint64() (uint64, error) {
	if len(m) != 6 {
		return 0, fmt.Errorf("invalid MAC address %s", m.String())
	}

	return uint64(m[5])<<40 | uint64(m[4])<<32 | uint64(m[3])<<24 |
		uint64(m[2])<<16 | uint64(m[1])<<8 | uint64(m[0]), nil
}

func (m MAC) MarshalJSON() ([]byte, error) {
	if len(m) == 0 {
		return []byte(`""`), nil
	}
	if len(m) != 6 {
		return nil, fmt.Errorf("invalid MAC address length %s", string(m))
	}
	return []byte(fmt.Sprintf("\"%02x:%02x:%02x:%02x:%02x:%02x\"", m[0], m[1], m[2], m[3], m[4], m[5])), nil
}

func (m MAC) MarshalIndentJSON(prefix, indent string) ([]byte, error) {
	return m.MarshalJSON()
}

func (m *MAC) UnmarshalJSON(data []byte) error {
	if len(data) == len([]byte(`""`)) {
		if m == nil {
			m = new(MAC)
		}
		*m = MAC{}
		return nil
	}
	if len(data) != 19 {
		return fmt.Errorf("invalid MAC address length %s", string(data))
	}
	data = data[1 : len(data)-1]
	macStr := bytes.Replace(data, []byte(`:`), []byte(``), -1)
	if len(macStr) != 12 {
		return fmt.Errorf("invalid MAC address format")
	}
	macByte := make([]byte, len(macStr))
	hex.Decode(macByte, macStr)
	*m = MAC{macByte[0], macByte[1], macByte[2], macByte[3], macByte[4], macByte[5]}
	return nil
}

// GenerateRandMAC generates a random unicast and locally administered MAC address.
func GenerateRandMAC() (MAC, error) {
	buf := make([]byte, 6)
	if _, err := rand.Read(buf); err != nil {
		return nil, fmt.Errorf("Unable to retrieve 6 rnd bytes: %s", err)
	}

	// Set locally administered addresses bit and reset multicast bit
	buf[0] = (buf[0] | 0x02) & 0xfe

	return MAC(buf), nil
}
<|endoftext|>


<commit_before>package plugins

import (
	"encoding/json"
	"io"
	"net/http"
	"regexp"
	"strings"

	"crypto/tls"

	"code.google.com/p/go.net/html"
	irc "github.com/thoj/go-ircevent"

	seabird ".."
)

func init() {
	seabird.RegisterPlugin("url", NewURLPlugin)
}

type URLPlugin struct {
	Bot *seabird.Bot
}

// NOTE: This isn't perfect in any sense of the word, but it's pretty close
// and I don't know if it's worth the time to make it better.
var urlRegex = regexp.MustCompile(`https?://[^ ]+`)

func NewURLPlugin(b *seabird.Bot, c json.RawMessage) {
	p := &URLPlugin{b}
	b.RegisterCallback("PRIVMSG", p.Msg)
}

func (p *URLPlugin) Msg(e *irc.Event) {
	for _, url := range urlRegex.FindAllString(e.Message(), -1) {
		go func() {
			// NOTE: This nasty work is done so we ignore invalid ssl certs
			tr := &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
			}
			client := &http.Client{Transport: tr}

			r, err := client.Get(url)
			if err != nil {
				return
			}
			defer r.Body.Close()

			if r.StatusCode != 200 {
				return
			}

			// We search the first 1K and if a title isn't in there, we deal with it
			z, err := html.Parse(io.LimitReader(r.Body, 1024*1024))
			if err != nil {
				return
			}

			// DFS that searches the tree for any node named title then
			// returns the data of that node's first child
			var f func(*html.Node) (string, bool)
			f = func(n *html.Node) (string, bool) {
				// If it's an element and it's a title node, look for a child
				if n.Type == html.ElementNode && n.Data == "title" {
					if n.FirstChild != nil {
						t := strings.TrimSpace(n.FirstChild.Data)
						t = strings.Map(func(r rune) rune {
							if r == '\r' || r == '\n' {
								return -1
							}
							return r
						}, t)

						if t != "" {
							return t, true
						} else {
							return "", false
						}
					}
				}

				// Loop through all nodes and try recursing
				for c := n.FirstChild; c != nil; c = c.NextSibling {
					if str, ok := f(c); ok {
						return str, true
					}
				}

				return "", false
			}

			if str, ok := f(z); ok {
				p.Bot.Reply(e, "Title: %s", str)
			}
		}()
	}
}
<commit_msg>replace newplines with a space before trimming<commit_after>package plugins

import (
	"encoding/json"
	"io"
	"net/http"
	"regexp"
	"strings"

	"crypto/tls"

	"code.google.com/p/go.net/html"
	irc "github.com/thoj/go-ircevent"

	seabird ".."
)

func init() {
	seabird.RegisterPlugin("url", NewURLPlugin)
}

type URLPlugin struct {
	Bot *seabird.Bot
}

// NOTE: This isn't perfect in any sense of the word, but it's pretty close
// and I don't know if it's worth the time to make it better.
var urlRegex = regexp.MustCompile(`https?://[^ ]+`)
var titleRegex = regexp.MustCompile(`(?:\s*[\r\n]+\s*)+`)

func NewURLPlugin(b *seabird.Bot, c json.RawMessage) {
	p := &URLPlugin{b}
	b.RegisterCallback("PRIVMSG", p.Msg)
}

func (p *URLPlugin) Msg(e *irc.Event) {
	for _, url := range urlRegex.FindAllString(e.Message(), -1) {
		go func() {
			// NOTE: This nasty work is done so we ignore invalid ssl certs
			tr := &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
			}
			client := &http.Client{Transport: tr}

			r, err := client.Get(url)
			if err != nil {
				return
			}
			defer r.Body.Close()

			if r.StatusCode != 200 {
				return
			}

			// We search the first 1K and if a title isn't in there, we deal with it
			z, err := html.Parse(io.LimitReader(r.Body, 1024*1024))
			if err != nil {
				return
			}

			// DFS that searches the tree for any node named title then
			// returns the data of that node's first child
			var f func(*html.Node) (string, bool)
			f = func(n *html.Node) (string, bool) {
				// If it's an element and it's a title node, look for a child
				if n.Type == html.ElementNode && n.Data == "title" {
					if n.FirstChild != nil {
						t := n.FirstChild.Data
						t = string(titleRegex.ReplaceAll([]byte(t), []byte(" ")))
						t = strings.TrimSpace(t)

						if t != "" {
							return t, true
						} else {
							return "", false
						}
					}
				}

				// Loop through all nodes and try recursing
				for c := n.FirstChild; c != nil; c = c.NextSibling {
					if str, ok := f(c); ok {
						return str, true
					}
				}

				return "", false
			}

			if str, ok := f(z); ok {
				p.Bot.Reply(e, "Title: %s", str)
			}
		}()
	}
}
<|endoftext|>


<commit_before>package zmq

import (
	"testing"
	"time"
)

func TestPollSocket(t *testing.T) {
	env := &Env{Tester: t, serverType: PULL, endpoint: TCP_ENDPOINT, clientType: PUSH}
	env.setupEnv()
	defer env.destroyEnv()

	data := []byte("test")
	err := env.client.Send(data, 0)
	if err != nil {
		t.Fatal("Error on send", err)
	}

	item := PollItem{env.server, []PollEvent{POLLIN}}
	items := &PollItems{ item  }
	rc, err := items.Poll(-1 * time.Millisecond)
	if rc != 1 {
		t.Fatalf("Expected pollin to return 1, was %d, err is %q", rc, err)
	}
}
<commit_msg>Added poll benchmark<commit_after>package zmq

import (
	"testing"
	"time"
)

func TestPollSocket(t *testing.T) {
	env := &Env{Tester: t, serverType: PULL, endpoint: TCP_ENDPOINT, clientType: PUSH}
	env.setupEnv()
	defer env.destroyEnv()

	data := []byte("test")
	err := env.client.Send(data, 0)
	if err != nil {
		t.Fatal("Error on send", err)
	}

	item := &PollItem{Socket:env.server, Events:POLLIN}
	items := PollItems{ item  }
	rc, err := items.Poll(-1 * time.Millisecond)
	if rc != 1 {
		t.Fatalf("Expected pollin to return 1, was %d, err is %q", rc, err)
	}
	if item.REvents != POLLIN {
		t.Fatalf("Expected poll item to be filled with POLLIN, got %+v", item)
	}
}

func BenchmarkPollSocket(b *testing.B) {
	env := &Env{Tester: b, serverType: PULL, endpoint: TCP_ENDPOINT, clientType: PUSH}
	env.setupEnv()
	defer env.destroyEnv()

	data := make([]byte, 1e3)
	item := &PollItem{Socket:env.server, Events:POLLIN}
	items := PollItems{ item  }
	var resp *MessagePart
	for i :=0; i < b.N; i++ {
		env.client.Send(data, 0)
		items.Poll(-1 * time.Millisecond)
		resp, _ = env.server.Recv(0)
		_ = resp.Close()
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 SteelSeries ApS.  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 implements a basic LISP interpretor for embedding in a go program for scripting.
// This file contains the system primitive functions.

package golisp

import (
	"fmt"
	"os"
	"strings"
	"time"
)

var symbolCounts map[string]int = make(map[string]int)

func RegisterSystemPrimitives() {
	MakePrimitiveFunction("load", 1, LoadFileImpl)
	MakePrimitiveFunction("sleep", 1, SleepImpl)
	MakePrimitiveFunction("millis", 0, MillisImpl)
	MakePrimitiveFunction("write-line", 1, WriteLineImpl)
	MakePrimitiveFunction("str", -1, MakeStringImpl)
	MakePrimitiveFunction("intern", 1, InternImpl)
	MakeSpecialForm("time", 1, TimeImpl)
	MakePrimitiveFunction("quit", 0, QuitImpl)
	MakePrimitiveFunction("gensym", -1, GensymImpl)
	MakePrimitiveFunction("eval", -1, EvalImpl)
	MakePrimitiveFunction("global-eval", 1, GlobalEvalImpl)
}

func LoadFileImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	filename := Car(args)
	if !StringP(filename) {
		err = ProcessError("Filename must be a string", env)
		return
	}

	return ProcessFile(StringValue(filename))
}

func QuitImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	WriteHistoryToFile(".golisp_history")
	fmt.Printf("\n\nGoodbye.\n\n")
	os.Exit(0)
	return
}

func SleepImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	n := Car(args)
	if !IntegerP(n) {
		err = ProcessError(fmt.Sprintf("Number expected, received %s", String(n)), env)
		return
	}
	millis := IntegerValue(n)
	time.Sleep(time.Duration(millis) * time.Millisecond)
	return
}

func MillisImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	result = IntegerWithValue(int64(time.Now().UnixNano() / 1e6))
	return
}

// TODO: make this take multiple args and act like MakeStrImpl (write
// the concatenation of the printstrings of the args
func WriteLineImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	data := Car(args)
	println(PrintString(data))
	return
}

func MakeStringImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	if NilP(args) || Length(args) == 0 {
		return StringWithValue("()"), nil
	}

	pieces := make([]string, 2)
	for cell := args; NotNilP(cell); cell = Cdr(cell) {
		pieces = append(pieces, PrintString(Car(cell)))
	}
	return StringWithValue(strings.Join(pieces, "")), nil
}

func TimeImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	fmt.Printf("Starting timer.\n")
	startTime := time.Now()

	for cell := args; NotNilP(cell); cell = Cdr(cell) {
		sexpr := Car(cell)
		result, err = Eval(sexpr, env)
		if err != nil {
			break
		}
	}

	d := time.Since(startTime)
	fmt.Printf("Stopped timer.\nTook %v to run.\n", d)
	result = IntegerWithValue(int64(d.Nanoseconds() / 1000000))
	return
}

func InternImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	sym := Car(args)
	if !StringP(sym) {
		err = ProcessError(fmt.Sprintf("intern expects a string, but received %s.", String(sym)), env)
		return
	}

	return Intern(StringValue(sym)), nil
}

func GensymImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	var prefix string
	if Length(args) > 1 {
		err = ProcessError(fmt.Sprintf("gensym expects 0 or 1 argument, but received %d.", Length(args)), env)
		return
	}

	if Length(args) == 0 {
		prefix = "GENSYM"
	} else {
		arg := Car(args)
		if !StringP(arg) && !SymbolP(arg) {
			err = ProcessError(fmt.Sprintf("gensym expects a string or symbol, but recieved %s.", String(arg)), env)
			return
		}
		prefix = StringValue(arg)
	}

	count := symbolCounts[prefix]
	if count == 0 {
		count = 1
	} else {
		count += 1
	}
	symbolCounts[prefix] = count
	result = Intern(fmt.Sprintf("%s-%d", prefix, count))
	return
}

func EvalImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	var evalEnv *SymbolTableFrame
	sexpr := Car(args)
	if Length(args) != 1 && Length(args) != 2 {
		err = ProcessError(fmt.Sprintf("eval expects 1 or 2 arguments, but recieved %d.", Length(args)), env)
		return
	}
	if Length(args) == 2 {
		if !EnvironmentP(Cadr(args)) {
			err = ProcessError(fmt.Sprintf("eval expects an environment as it's second argument, but recieved %s.", String(Cadr(args))), env)
			return
		}
		evalEnv = EnvironmentValue(Cadr(args))
	} else {
		evalEnv = env
	}
	return Eval(sexpr, evalEnv)
}

func GlobalEvalImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return Eval(Car(args), Global)
}
<commit_msg>Added write & newline<commit_after>// Copyright 2014 SteelSeries ApS.  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 implements a basic LISP interpretor for embedding in a go program for scripting.
// This file contains the system primitive functions.

package golisp

import (
	"fmt"
	"os"
	"strings"
	"time"
)

var symbolCounts map[string]int = make(map[string]int)

func RegisterSystemPrimitives() {
	MakePrimitiveFunction("load", 1, LoadFileImpl)
	MakePrimitiveFunction("sleep", 1, SleepImpl)
	MakePrimitiveFunction("millis", 0, MillisImpl)
	MakePrimitiveFunction("newline", 0, NewlineImpl)
	MakePrimitiveFunction("write", 1, WriteImpl)
	MakePrimitiveFunction("write-line", 1, WriteLineImpl)
	MakePrimitiveFunction("str", -1, MakeStringImpl)
	MakePrimitiveFunction("intern", 1, InternImpl)
	MakePrimitiveFunction("quit", 0, QuitImpl)
	MakePrimitiveFunction("gensym", -1, GensymImpl)
	MakePrimitiveFunction("eval", -1, EvalImpl)
	MakePrimitiveFunction("global-eval", 1, GlobalEvalImpl)
	MakeSpecialForm("time", 1, TimeImpl)
}

func LoadFileImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	filename := Car(args)
	if !StringP(filename) {
		err = ProcessError("Filename must be a string", env)
		return
	}

	return ProcessFile(StringValue(filename))
}

func QuitImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	WriteHistoryToFile(".golisp_history")
	fmt.Printf("\n\nGoodbye.\n\n")
	os.Exit(0)
	return
}

func SleepImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	n := Car(args)
	if !IntegerP(n) {
		err = ProcessError(fmt.Sprintf("Number expected, received %s", String(n)), env)
		return
	}
	millis := IntegerValue(n)
	time.Sleep(time.Duration(millis) * time.Millisecond)
	return
}

func MillisImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	result = IntegerWithValue(int64(time.Now().UnixNano() / 1e6))
	return
}

func NewlineImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	fmt.Printf("\n")
	return
}

func WriteImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	fmt.Printf(PrintString(Car(args)))
	return
}

func WriteLineImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	fmt.Printf("%s\n", PrintString(Car(args)))
	return
}

func MakeStringImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	if NilP(args) || Length(args) == 0 {
		return StringWithValue("()"), nil
	}

	pieces := make([]string, 2)
	for cell := args; NotNilP(cell); cell = Cdr(cell) {
		pieces = append(pieces, PrintString(Car(cell)))
	}
	return StringWithValue(strings.Join(pieces, "")), nil
}

func TimeImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	fmt.Printf("Starting timer.\n")
	startTime := time.Now()

	for cell := args; NotNilP(cell); cell = Cdr(cell) {
		sexpr := Car(cell)
		result, err = Eval(sexpr, env)
		if err != nil {
			break
		}
	}

	d := time.Since(startTime)
	fmt.Printf("Stopped timer.\nTook %v to run.\n", d)
	result = IntegerWithValue(int64(d.Nanoseconds() / 1000000))
	return
}

func InternImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	sym := Car(args)
	if !StringP(sym) {
		err = ProcessError(fmt.Sprintf("intern expects a string, but received %s.", String(sym)), env)
		return
	}

	return Intern(StringValue(sym)), nil
}

func GensymImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	var prefix string
	if Length(args) > 1 {
		err = ProcessError(fmt.Sprintf("gensym expects 0 or 1 argument, but received %d.", Length(args)), env)
		return
	}

	if Length(args) == 0 {
		prefix = "GENSYM"
	} else {
		arg := Car(args)
		if !StringP(arg) && !SymbolP(arg) {
			err = ProcessError(fmt.Sprintf("gensym expects a string or symbol, but recieved %s.", String(arg)), env)
			return
		}
		prefix = StringValue(arg)
	}

	count := symbolCounts[prefix]
	if count == 0 {
		count = 1
	} else {
		count += 1
	}
	symbolCounts[prefix] = count
	result = Intern(fmt.Sprintf("%s-%d", prefix, count))
	return
}

func EvalImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	var evalEnv *SymbolTableFrame
	sexpr := Car(args)
	if Length(args) != 1 && Length(args) != 2 {
		err = ProcessError(fmt.Sprintf("eval expects 1 or 2 arguments, but recieved %d.", Length(args)), env)
		return
	}
	if Length(args) == 2 {
		if !EnvironmentP(Cadr(args)) {
			err = ProcessError(fmt.Sprintf("eval expects an environment as it's second argument, but recieved %s.", String(Cadr(args))), env)
			return
		}
		evalEnv = EnvironmentValue(Cadr(args))
	} else {
		evalEnv = env
	}
	return Eval(sexpr, evalEnv)
}

func GlobalEvalImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	return Eval(Car(args), Global)
}
<|endoftext|>


<commit_before>// Copyright 2014 SteelSeries ApS.  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 implements a basic LISP interpretor for embedding in a go program for scripting.
// This file contains the system primitive functions.

package golisp

import (
	"fmt"
	"os"
	"strings"
	"time"
)

func RegisterSystemPrimitives() {
	MakePrimitiveFunction("load", 1, LoadFileImpl)
	MakePrimitiveFunction("sleep", 1, SleepImpl)
	MakePrimitiveFunction("write-line", 1, WriteLineImpl)
	MakePrimitiveFunction("str", -1, MakeStringImpl)
	MakePrimitiveFunction("intern", 1, InternImpl)
	MakePrimitiveFunction("time", 1, TimeImpl)
	MakePrimitiveFunction("quit", 0, QuitImpl)
}

func LoadFileImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	filename := Car(args)
	if !StringP(filename) {
		err = ProcessError("Filename must be a string", env)
		return
	}

	return ProcessFile(StringValue(filename))
}

func QuitImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	WriteHistoryToFile(".golisp_history")
	os.Exit(0)
	return
}

func SleepImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	n, err := Eval(Car(args), env)
	if err != nil {
		return
	}
	if !IntegerP(n) {
		err = ProcessError(fmt.Sprintf("Number expected, received %s", String(n)), env)
		return
	}
	millis := IntegerValue(n)
	time.Sleep(time.Duration(millis) * time.Millisecond)
	return
}

func WriteLineImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	data, err := Eval(Car(args), env)
	if err != nil {
		return
	}
	println(PrintString(data))
	return
}

func MakeStringImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	pieces := make([]string, 2)
	for cell := args; NotNilP(cell); cell = Cdr(cell) {
		sexpr := Car(cell)
		s, err := Eval(sexpr, env)
		if err != nil {
			break
		}
		pieces = append(pieces, PrintString(s))
	}
	return StringWithValue(strings.Join(pieces, "")), nil
}

func TimeImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	fmt.Printf("Starting timer.\n")
	startTime := time.Now()

	for cell := args; NotNilP(cell); cell = Cdr(cell) {
		sexpr := Car(cell)
		result, err = Eval(sexpr, env)
		if err != nil {
			break
		}
	}

	d := time.Since(startTime)
	fmt.Printf("Stopped timer.\nTook %v to run.\n", d)
	result = IntegerWithValue(int64(d.Nanoseconds() / 1000000))
	return
}

func InternImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	sym, err := Eval(Car(args), env)
	if err != nil {
		return
	}
	if !StringP(sym) {
		err = ProcessError(fmt.Sprintf("intern expects a string, but received %s.", String(sym)), env)
		return
	}

	return SymbolWithName(StringValue(sym)), nil
}
<commit_msg>Add mills function to get the number of milliseconds since Jan 1 1970.<commit_after>// Copyright 2014 SteelSeries ApS.  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 implements a basic LISP interpretor for embedding in a go program for scripting.
// This file contains the system primitive functions.

package golisp

import (
	"fmt"
	"os"
	"strings"
	"time"
)

func RegisterSystemPrimitives() {
	MakePrimitiveFunction("load", 1, LoadFileImpl)
	MakePrimitiveFunction("sleep", 1, SleepImpl)
	MakePrimitiveFunction("millis", 0, MillisImpl)
	MakePrimitiveFunction("write-line", 1, WriteLineImpl)
	MakePrimitiveFunction("str", -1, MakeStringImpl)
	MakePrimitiveFunction("intern", 1, InternImpl)
	MakePrimitiveFunction("time", 1, TimeImpl)
	MakePrimitiveFunction("quit", 0, QuitImpl)
}

func LoadFileImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	filename := Car(args)
	if !StringP(filename) {
		err = ProcessError("Filename must be a string", env)
		return
	}

	return ProcessFile(StringValue(filename))
}

func QuitImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	WriteHistoryToFile(".golisp_history")
	os.Exit(0)
	return
}

func SleepImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	n, err := Eval(Car(args), env)
	if err != nil {
		return
	}
	if !IntegerP(n) {
		err = ProcessError(fmt.Sprintf("Number expected, received %s", String(n)), env)
		return
	}
	millis := IntegerValue(n)
	time.Sleep(time.Duration(millis) * time.Millisecond)
	return
}

func MillisImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	result = IntegerWithValue(int64(time.Now().UnixNano() / 1e3))
	return
}

func WriteLineImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	data, err := Eval(Car(args), env)
	if err != nil {
		return
	}
	println(PrintString(data))
	return
}

func MakeStringImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	pieces := make([]string, 2)
	for cell := args; NotNilP(cell); cell = Cdr(cell) {
		sexpr := Car(cell)
		s, err := Eval(sexpr, env)
		if err != nil {
			break
		}
		pieces = append(pieces, PrintString(s))
	}
	return StringWithValue(strings.Join(pieces, "")), nil
}

func TimeImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	fmt.Printf("Starting timer.\n")
	startTime := time.Now()

	for cell := args; NotNilP(cell); cell = Cdr(cell) {
		sexpr := Car(cell)
		result, err = Eval(sexpr, env)
		if err != nil {
			break
		}
	}

	d := time.Since(startTime)
	fmt.Printf("Stopped timer.\nTook %v to run.\n", d)
	result = IntegerWithValue(int64(d.Nanoseconds() / 1000000))
	return
}

func InternImpl(args *Data, env *SymbolTableFrame) (result *Data, err error) {
	sym, err := Eval(Car(args), env)
	if err != nil {
		return
	}
	if !StringP(sym) {
		err = ProcessError(fmt.Sprintf("intern expects a string, but received %s.", String(sym)), env)
		return
	}

	return SymbolWithName(StringValue(sym)), nil
}
<|endoftext|>


<commit_before>// SPDX-License-Identifier: ISC
// Copyright (c) 2014-2020 Bitmark Inc.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package proof

import (
	"encoding/binary"
	"fmt"
	"sync"

	"github.com/bitmark-inc/bitmarkd/blockrecord"
	"github.com/bitmark-inc/bitmarkd/merkle"
	"github.com/bitmark-inc/bitmarkd/messagebus"
	"github.com/bitmark-inc/bitmarkd/mode"
	"github.com/bitmark-inc/logger"
)

// PublishedItem - to send to proofer
type PublishedItem struct {
	Job    string             `json:"job"`
	Header blockrecord.Header `json:"header"`
	TxZero []byte             `json:"txZero"`
	TxIds  []merkle.Digest    `json:"txIds"`
}

// SubmittedItem - received from the proofer
type SubmittedItem struct {
	Request string `json:"request"`
	Job     string `json:"job"`
	Packed  []byte `json:"packed"`
	//***** FIX THIS: add for miner generated TxZero  []byte `json:"txZero"`
}

type entryType struct {
	item         *PublishedItem
	transactions []byte
}

// size of queue
const (
	queueSize = 32
)

// the queue
type jobQueueType struct {
	sync.RWMutex // to allow locking

	entries [queueSize]*entryType
	count   uint16
	clear   bool
}

// the queue storage
var jobQueue jobQueueType

// add job to the queue
func initialiseJobQueue() {
	jobQueue.Lock()
	defer jobQueue.Unlock()
	for i := range jobQueue.entries {
		jobQueue.entries[i] = nil
	}
	jobQueue.clear = false
}

// create a job number
func enqueueToJobQueue(item *PublishedItem, txdata []byte) {
	jobQueue.Lock()
	jobQueue.count += 1 // wraps (uint16)
	item.Job = fmt.Sprintf("%04x", jobQueue.count)
	n := jobQueue.count % queueSize
	if nil != jobQueue.entries[n] {
		jobQueue.entries[n].transactions = nil
		jobQueue.entries[n] = nil
	}
	jobQueue.entries[n] = &entryType{
		item:         item,
		transactions: txdata,
	}
	jobQueue.Unlock()
}

func matchToJobQueue(received *SubmittedItem, log *logger.L) (success bool) {
	jobQueue.Lock()
	defer jobQueue.Unlock()

	job := received.Job

	var entry *entryType
search:
	for _, e := range jobQueue.entries {
		if nil != e && nil != e.item && e.item.Job == job {
			entry = e
			break search
		}
	}

	if nil == entry {
		return
	}

	// if not normal abandon the queue and the submission
	if !mode.Is(mode.Normal) {
		goto cleanup
	}

	switch received.Request {

	case "block.nonce":
		if len(received.Packed) != blockrecord.NonceSize {
			return
		}
		entry.item.Header.Nonce = blockrecord.NonceType(binary.LittleEndian.Uint64(received.Packed))
		ph := entry.item.Header.Pack()
		digest := ph.Digest()

		diff := entry.item.Header.Difficulty
		log.Debugf("incoming block difficulty: %f", diff.Value())

		if !digest.IsValidByDifficulty(diff, mode.ChainName()) {
			log.Infof("digest %s, difficulty %064x, digest not match difficulty criteria", digest.String(), diff.BigInt())
			return
		}

		packedBlock := ph[:] //make([]byte,len(ph)+len(entry.item.Base)+len(entry.transactions))
		packedBlock = append(packedBlock, entry.item.TxZero...)
		packedBlock = append(packedBlock, entry.transactions...)

		// broadcast this packedBlock for processing
		messagebus.Bus.Blockstore.Send("local", packedBlock)
		success = true
	}

cleanup:
	// erase the queue
	for i := range jobQueue.entries {
		if nil != jobQueue.entries[i] {
			jobQueue.entries[i].transactions = nil
			jobQueue.entries[i] = nil
		}
	}
	jobQueue.clear = true

	return
}
<commit_msg>[proof] completely clean queue structures<commit_after>// SPDX-License-Identifier: ISC
// Copyright (c) 2014-2020 Bitmark Inc.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package proof

import (
	"encoding/binary"
	"fmt"
	"sync"

	"github.com/bitmark-inc/bitmarkd/blockrecord"
	"github.com/bitmark-inc/bitmarkd/merkle"
	"github.com/bitmark-inc/bitmarkd/messagebus"
	"github.com/bitmark-inc/bitmarkd/mode"
	"github.com/bitmark-inc/logger"
)

// PublishedItem - to send to proofer
type PublishedItem struct {
	Job    string             `json:"job"`
	Header blockrecord.Header `json:"header"`
	TxZero []byte             `json:"txZero"`
	TxIds  []merkle.Digest    `json:"txIds"`
}

// SubmittedItem - received from the proofer
type SubmittedItem struct {
	Request string `json:"request"`
	Job     string `json:"job"`
	Packed  []byte `json:"packed"`
	//***** FIX THIS: add for miner generated TxZero  []byte `json:"txZero"`
}

type entryType struct {
	item         *PublishedItem
	transactions []byte
}

// size of queue
const (
	queueSize = 32
)

// the queue
type jobQueueType struct {
	sync.RWMutex // to allow locking

	entries [queueSize]*entryType
	count   uint16
	clear   bool
}

// the queue storage
var jobQueue jobQueueType

// add job to the queue
func initialiseJobQueue() {
	jobQueue.Lock()
	defer jobQueue.Unlock()
	for i := range jobQueue.entries {
		jobQueue.entries[i] = nil
	}
	jobQueue.clear = false
}

// remove all data links to help GC recover memory
func clearEntry(entry *entryType) {
	entry.item.TxZero = nil
	entry.item.TxIds = nil
	entry.item = nil
	entry.transactions = nil
}

// create a job number
func enqueueToJobQueue(item *PublishedItem, txdata []byte) {
	jobQueue.Lock()
	jobQueue.count += 1 // wraps (uint16)
	item.Job = fmt.Sprintf("%04x", jobQueue.count)
	n := jobQueue.count % queueSize
	if nil != jobQueue.entries[n] {
		clearEntry(jobQueue.entries[n])
		jobQueue.entries[n] = nil
	}
	jobQueue.entries[n] = &entryType{
		item:         item,
		transactions: txdata,
	}
	jobQueue.Unlock()
}

func matchToJobQueue(received *SubmittedItem, log *logger.L) (success bool) {
	jobQueue.Lock()
	defer jobQueue.Unlock()

	job := received.Job

	var entry *entryType
search:
	for _, e := range jobQueue.entries {
		if nil != e && nil != e.item && e.item.Job == job {
			entry = e
			break search
		}
	}

	if nil == entry {
		return
	}

	// if not normal abandon the queue and the submission
	if !mode.Is(mode.Normal) {
		goto cleanup
	}

	switch received.Request {

	case "block.nonce":
		if len(received.Packed) != blockrecord.NonceSize {
			return
		}
		entry.item.Header.Nonce = blockrecord.NonceType(binary.LittleEndian.Uint64(received.Packed))
		ph := entry.item.Header.Pack()
		digest := ph.Digest()

		diff := entry.item.Header.Difficulty
		log.Debugf("incoming block difficulty: %f", diff.Value())

		if !digest.IsValidByDifficulty(diff, mode.ChainName()) {
			log.Infof("digest %s, difficulty %064x, digest not match difficulty criteria", digest.String(), diff.BigInt())
			return
		}

		packedBlock := ph[:] //make([]byte,len(ph)+len(entry.item.Base)+len(entry.transactions))
		packedBlock = append(packedBlock, entry.item.TxZero...)
		packedBlock = append(packedBlock, entry.transactions...)

		// broadcast this packedBlock for processing
		messagebus.Bus.Blockstore.Send("local", packedBlock)
		success = true
	}

cleanup:
	// erase the queue
	for i := range jobQueue.entries {
		if nil != jobQueue.entries[i] {
			clearEntry(jobQueue.entries[i])
			jobQueue.entries[i] = nil
		}
	}
	jobQueue.clear = true

	return
}
<|endoftext|>


<commit_before>package opentracing

import "errors"

///////////////////////////////////////////////////////////////////////////////
// CORE PROPAGATION INTERFACES:
///////////////////////////////////////////////////////////////////////////////

var (
	// ErrUnsupportedFormat occurs when the `format` passed to Tracer.Inject() or
	// Tracer.Join() is not recognized by the Tracer implementation.
	ErrUnsupportedFormat = errors.New("opentracing: Unknown or unsupported Inject/Join format")

	// ErrTraceNotFound occurs when the `carrier` passed to Tracer.Join() is
	// valid and uncorrupted but has insufficient information to join or resume
	// a trace.
	ErrTraceNotFound = errors.New("opentracing: Trace not found in Join carrier")

	// ErrInvalidSpan errors occur when Tracer.Inject() is asked to operate on
	// a Span which it is not prepared to handle (for example, since it was
	// created by a different tracer implementation).
	ErrInvalidSpan = errors.New("opentracing: Span type incompatible with tracer")

	// ErrInvalidCarrier errors occur when Tracer.Inject() or Tracer.Join()
	// implementations expect a different type of `carrier` than they are
	// given.
	ErrInvalidCarrier = errors.New("opentracing: Invalid Inject/Join carrier")

	// ErrTraceCorrupted occurs when the `carrier` passed to Tracer.Join() is
	// of the expected type but is corrupted.
	ErrTraceCorrupted = errors.New("opentracing: Trace data corrupted in Join carrier")
)

///////////////////////////////////////////////////////////////////////////////
// BUILTIN PROPAGATION FORMATS:
///////////////////////////////////////////////////////////////////////////////

// BuiltinFormat is used to demarcate the values within package `opentracing`
// that are intended for use with the Tracer.Inject() and Tracer.Join()
// methods.
type BuiltinFormat byte

const (
	// Binary encodes the Span in a BinaryCarrier instance.
	//
	// The `carrier` for injection and extraction must be a `BinaryCarrier`
	// instance (not a pointer to a BinaryCarrier instance).
	Binary BuiltinFormat = iota

	// TextMap encodes the Span in a TextMapCarrier instance.
	//
	// The `carrier` for injection and extraction must be a `TextMapCarrier`
	// instance (not a pointer to a TextMapCarrier instance).
	TextMap

	// GoHTTPHeader encodes the Span into a Go http.Header instance (both the
	// tracer state and any baggage).
	//
	// The `carrier` for both injection and extraction must be an http.Header
	// instance (not a pointer to an http.Header instance).
	//
	// If there are entries in the http.Header map prior to a call to Inject(),
	// they are left alone (i.e., the map is not cleared). Similarly, in calls
	// to Join() it is fine (and expected in some cases) for the http.Header
	// map to contain other unrelated data (i.e., non-OpenTracing headers).
	GoHTTPHeader
)

// TextMapCarrier represents a Span for propagation as a key:value map of
// unicode strings.
//
// If there are entries in the TextMapCarrier prior to a call to Inject(), they
// are left alone (i.e., the map is not cleared). Similarly, in calls to Join()
// it is fine (and expected in some cases) for the TextMapCarrier to contain
// other unrelated data (e.g., arbitrary HTTP header pairs).
type TextMapCarrier map[string]string

// BinaryCarrier represents a Span for propagation as an opaque byte array.
//
// It is fine to pass `nil` to Inject(); in that case, it will allocate a
// []byte for the caller.
type BinaryCarrier *[]byte
<commit_msg>Deprecate old API to keep basictracer-go compiling<commit_after>package opentracing

import "errors"

///////////////////////////////////////////////////////////////////////////////
// CORE PROPAGATION INTERFACES:
///////////////////////////////////////////////////////////////////////////////

var (
	// ErrUnsupportedFormat occurs when the `format` passed to Tracer.Inject() or
	// Tracer.Join() is not recognized by the Tracer implementation.
	ErrUnsupportedFormat = errors.New("opentracing: Unknown or unsupported Inject/Join format")

	// ErrTraceNotFound occurs when the `carrier` passed to Tracer.Join() is
	// valid and uncorrupted but has insufficient information to join or resume
	// a trace.
	ErrTraceNotFound = errors.New("opentracing: Trace not found in Join carrier")

	// ErrInvalidSpan errors occur when Tracer.Inject() is asked to operate on
	// a Span which it is not prepared to handle (for example, since it was
	// created by a different tracer implementation).
	ErrInvalidSpan = errors.New("opentracing: Span type incompatible with tracer")

	// ErrInvalidCarrier errors occur when Tracer.Inject() or Tracer.Join()
	// implementations expect a different type of `carrier` than they are
	// given.
	ErrInvalidCarrier = errors.New("opentracing: Invalid Inject/Join carrier")

	// ErrTraceCorrupted occurs when the `carrier` passed to Tracer.Join() is
	// of the expected type but is corrupted.
	ErrTraceCorrupted = errors.New("opentracing: Trace data corrupted in Join carrier")
)

///////////////////////////////////////////////////////////////////////////////
// BUILTIN PROPAGATION FORMATS:
///////////////////////////////////////////////////////////////////////////////

// BuiltinFormat is used to demarcate the values within package `opentracing`
// that are intended for use with the Tracer.Inject() and Tracer.Join()
// methods.
type BuiltinFormat byte

const (
	// Binary encodes the Span in a BinaryCarrier instance.
	//
	// The `carrier` for injection and extraction must be a `BinaryCarrier`
	// instance (not a pointer to a BinaryCarrier instance).
	Binary BuiltinFormat = iota

	// TextMap encodes the Span in a TextMapCarrier instance.
	//
	// The `carrier` for injection and extraction must be a `TextMapCarrier`
	// instance (not a pointer to a TextMapCarrier instance).
	TextMap

	// GoHTTPHeader encodes the Span into a Go http.Header instance (both the
	// tracer state and any baggage).
	//
	// The `carrier` for both injection and extraction must be an http.Header
	// instance (not a pointer to an http.Header instance).
	//
	// If there are entries in the http.Header map prior to a call to Inject(),
	// they are left alone (i.e., the map is not cleared). Similarly, in calls
	// to Join() it is fine (and expected in some cases) for the http.Header
	// map to contain other unrelated data (i.e., non-OpenTracing headers).
	GoHTTPHeader

	// SplitBinary is DEPRECATED
	SplitBinary
	// SplitText is DEPRECATED
	SplitText
)

// TextMapCarrier represents a Span for propagation as a key:value map of
// unicode strings.
//
// If there are entries in the TextMapCarrier prior to a call to Inject(), they
// are left alone (i.e., the map is not cleared). Similarly, in calls to Join()
// it is fine (and expected in some cases) for the TextMapCarrier to contain
// other unrelated data (e.g., arbitrary HTTP header pairs).
type TextMapCarrier map[string]string

// BinaryCarrier represents a Span for propagation as an opaque byte array.
//
// It is fine to pass `nil` to Inject(); in that case, it will allocate a
// []byte for the caller.
type BinaryCarrier *[]byte

// SplitTextCarrier is DEPRECATED
type SplitTextCarrier struct {
	TracerState map[string]string
	Baggage     map[string]string
}

// NewSplitTextCarrier is DEPRECATED
func NewSplitTextCarrier() *SplitTextCarrier {
	return &SplitTextCarrier{}
}

// SplitBinaryCarrier is DEPRECATED
type SplitBinaryCarrier struct {
	TracerState []byte
	Baggage     []byte
}

// NewSplitBinaryCarrier is DEPRECATED
func NewSplitBinaryCarrier() *SplitBinaryCarrier {
	return &SplitBinaryCarrier{}
}
<|endoftext|>


<commit_before>package proxy

import (
	"encoding/binary"
	"fmt"
	"io"
	"net"
	"os"

	"github.com/DimShadoWWW/power-pg/common"
)

var (
	connid = uint64(0)
)

// Start function
func Start(localHost, remoteHost *string, powerCallback common.Callback) {
	fmt.Printf("Proxying from %v to %v\n", localHost, remoteHost)

	localAddr, remoteAddr := getResolvedAddresses(localHost, remoteHost)
	listener := getListener(localAddr)

	for {
		conn, err := listener.AcceptTCP()
		if err != nil {
			fmt.Printf("Failed to accept connection '%s'\n", err)
			continue
		}
		connid++

		p := &proxy{
			lconn:  *conn,
			laddr:  localAddr,
			raddr:  remoteAddr,
			erred:  false,
			errsig: make(chan bool),
			prefix: fmt.Sprintf("Connection #%03d ", connid),
		}
		go p.start(powerCallback)
	}
}

func getResolvedAddresses(localHost, remoteHost *string) (*net.TCPAddr, *net.TCPAddr) {
	laddr, err := net.ResolveTCPAddr("tcp", *localHost)
	check(err)
	raddr, err := net.ResolveTCPAddr("tcp", *remoteHost)
	check(err)
	return laddr, raddr
}

func getListener(addr *net.TCPAddr) *net.TCPListener {
	listener, err := net.ListenTCP("tcp", addr)
	check(err)
	return listener
}

type proxy struct {
	sentBytes     uint64
	receivedBytes uint64
	laddr, raddr  *net.TCPAddr
	lconn, rconn  net.TCPConn
	erred         bool
	errsig        chan bool
	prefix        string
}

func (p *proxy) err(s string, err error) {
	if p.erred {
		return
	}
	if err != io.EOF {
		warn(p.prefix+s, err)
	}
	p.errsig <- true
	p.erred = true
}

func (p *proxy) start(powerCallback common.Callback) {
	// defer p.lconn.conn.Close()
	//connect to remote
	rconn, err := net.DialTCP("tcp", nil, p.raddr)
	if err != nil {
		p.err("Remote connection failed: %s", err)
		return
	}
	p.rconn = *rconn
	// p.rconn.alive = true
	// defer p.rconn.conn.Close()
	//bidirectional copy
	go p.pipe(p.lconn, p.rconn, powerCallback)
	go p.pipe(p.rconn, p.lconn, nil)
	//wait for close...
	<-p.errsig
}

func (p *proxy) pipe(src, dst net.TCPConn, powerCallback common.Callback) {
	//data direction
	islocal := src == p.lconn
	//directional copy (64k buffer)
	buff := make(readBuf, 0xffff)
	newPacket := true
	var msg string
	var remainingBytes int
	var r readBuf
	if islocal {
		for {
			n, err := src.Read(buff)
			if err != nil {
				p.err("Read failed '%s'\n", err)
				return
			}
			b := buff[:n]
			r = append(readBuf{}, buff[:n]...)
			if remainingBytes > 0 && remainingBytes <= 0xffff {
				newPacket = true
				msg = msg + string(r.next(remainingBytes))
				remainingBytes = 0xffff - remainingBytes
				fmt.Println(msg)
			} else {
				newPacket = false
				msg = msg + string(r.next(remainingBytes))
				remainingBytes = remainingBytes - 0xffff
			}
		NewP:
			if newPacket {
				remainingBytes = 0
				newPacket = false
				msg = ""
				t := r.byte()
				switch t {
				case query:
					// c.rxReadyForQuery(r)
					remainingBytes = r.int32()
					fmt.Printf("Remaining bytes: %d\n", remainingBytes)
					if remainingBytes <= 0xffff {
						newPacket = true
						msg = msg + string(r.next(remainingBytes))
						remainingBytes = 0xffff - remainingBytes
						fmt.Println(msg)
						goto NewP
					} else {
						newPacket = false
						msg = msg + string(r.next(remainingBytes))
						remainingBytes = remainingBytes - 0xffff
					}
				// case rowDescription:
				// case dataRow:
				// case bindComplete:
				// case commandComplete:
				// 	commandTag = CommandTag(r.readCString())
				default:
					// if e := c.processContextFreeMsg(t, r); e != nil && softErr == nil {
					// 	softErr = e
					// }
				}
			}
			r = append(r, buff[:]...)

			// fmt.Println("a")
			// c := src
			// c.reader = bufio.NewReader(src.conn)
			// c.mr.reader = c.reader
			//
			// var t byte
			// var r *msgReader
			// fmt.Println("b")
			// t, r, err := c.rxMsg()
			// fmt.Println("c")
			// if err != nil {
			// 	fmt.Println(err)
			// 	return
			// }
			// fmt.Println("d")
			//
			// fmt.Printf("t: %#v\n", t)

			// n, err := src.Read(buff)
			// if err != nil {
			// 	p.err("Read failed '%s'\n", err)
			// 	return
			// }
			// b := buff[:n]
			// //show output
			//
			//
			// b = getModifiedBuffer(b, powerCallback)
			// n, err = dst.Write(b)
			//
			//write out result
			n, err = dst.Write(b)
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
		}
	} else {
		for {
			n, err := src.Read(buff)
			if err != nil {
				p.err("Read failed '%s'\n", err)
				return
			}
			b := buff[:n]
			//write out result
			n, err = dst.Write(b)
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
		}
	}
}

func getModifiedBuffer(buffer []byte, powerCallback common.Callback) []byte {
	if powerCallback == nil || len(buffer) < 1 || string(buffer[0]) != "Q" || string(buffer[5:11]) != "power:" {
		return buffer
	}
	query := powerCallback(string(buffer[5:]))
	return makeMessage(query)
}

func makeMessage(query string) []byte {
	queryArray := make([]byte, 0, 6+len(query))
	queryArray = append(queryArray, 'Q', 0, 0, 0, 0)
	queryArray = append(queryArray, query...)
	queryArray = append(queryArray, 0)
	binary.BigEndian.PutUint32(queryArray[1:], uint32(len(queryArray)-1))
	return queryArray

}

func check(err error) {
	if err != nil {
		warn(err.Error())
		os.Exit(1)
	}
}

func warn(f string, args ...interface{}) {
	fmt.Printf(f+"\n", args...)
}
<commit_msg>Update<commit_after>package proxy

import (
	"encoding/binary"
	"fmt"
	"io"
	"net"
	"os"

	"github.com/DimShadoWWW/power-pg/common"
)

var (
	connid = uint64(0)
)

// Start function
func Start(localHost, remoteHost *string, powerCallback common.Callback) {
	fmt.Printf("Proxying from %v to %v\n", localHost, remoteHost)

	localAddr, remoteAddr := getResolvedAddresses(localHost, remoteHost)
	listener := getListener(localAddr)

	for {
		conn, err := listener.AcceptTCP()
		if err != nil {
			fmt.Printf("Failed to accept connection '%s'\n", err)
			continue
		}
		connid++

		p := &proxy{
			lconn:  *conn,
			laddr:  localAddr,
			raddr:  remoteAddr,
			erred:  false,
			errsig: make(chan bool),
			prefix: fmt.Sprintf("Connection #%03d ", connid),
		}
		go p.start(powerCallback)
	}
}

func getResolvedAddresses(localHost, remoteHost *string) (*net.TCPAddr, *net.TCPAddr) {
	laddr, err := net.ResolveTCPAddr("tcp", *localHost)
	check(err)
	raddr, err := net.ResolveTCPAddr("tcp", *remoteHost)
	check(err)
	return laddr, raddr
}

func getListener(addr *net.TCPAddr) *net.TCPListener {
	listener, err := net.ListenTCP("tcp", addr)
	check(err)
	return listener
}

type proxy struct {
	sentBytes     uint64
	receivedBytes uint64
	laddr, raddr  *net.TCPAddr
	lconn, rconn  net.TCPConn
	erred         bool
	errsig        chan bool
	prefix        string
}

func (p *proxy) err(s string, err error) {
	if p.erred {
		return
	}
	if err != io.EOF {
		warn(p.prefix+s, err)
	}
	p.errsig <- true
	p.erred = true
}

func (p *proxy) start(powerCallback common.Callback) {
	// defer p.lconn.conn.Close()
	//connect to remote
	rconn, err := net.DialTCP("tcp", nil, p.raddr)
	if err != nil {
		p.err("Remote connection failed: %s", err)
		return
	}
	p.rconn = *rconn
	// p.rconn.alive = true
	// defer p.rconn.conn.Close()
	//bidirectional copy
	go p.pipe(p.lconn, p.rconn, powerCallback)
	go p.pipe(p.rconn, p.lconn, nil)
	//wait for close...
	<-p.errsig
}

func (p *proxy) pipe(src, dst net.TCPConn, powerCallback common.Callback) {
	//data direction
	islocal := src == p.lconn
	//directional copy (64k buffer)
	buff := make(readBuf, 0xffff)
	newPacket := true
	var msg string
	remainingBytes := 0
	var r readBuf
	if islocal {
		for {
			n, err := src.Read(buff)
			if err != nil {
				p.err("Read failed '%s'\n", err)
				return
			}
			b := buff[:n]
			r = append(readBuf{}, buff[:n]...)
			fmt.Printf("Remaining bytes: %d\n", remainingBytes)
			if remainingBytes > 0 && remainingBytes <= 0xffff {
				newPacket = true
				msg = msg + string(r.next(remainingBytes))
				remainingBytes = 0xffff - remainingBytes
				fmt.Println(msg)
			} else {
				if remainingBytes > 0 {
					newPacket = false
					msg = msg + string(r.next(remainingBytes))
					remainingBytes = remainingBytes - 0xffff
				}
			}
		NewP:
			if newPacket {
				remainingBytes = 0
				newPacket = false
				msg = ""
				t := r.byte()
				switch t {
				case query:
					// c.rxReadyForQuery(r)
					remainingBytes = r.int32()
					if remainingBytes <= 0xffff {
						newPacket = true
						msg = msg + string(r.next(remainingBytes))
						remainingBytes = 0xffff - remainingBytes
						fmt.Println(msg)
						goto NewP
					} else {
						newPacket = false
						msg = msg + string(r.next(remainingBytes))
						remainingBytes = remainingBytes - 0xffff
					}
				// case rowDescription:
				// case dataRow:
				// case bindComplete:
				// case commandComplete:
				// 	commandTag = CommandTag(r.readCString())
				default:
					// if e := c.processContextFreeMsg(t, r); e != nil && softErr == nil {
					// 	softErr = e
					// }
				}
			}
			r = append(r, buff[:]...)

			// fmt.Println("a")
			// c := src
			// c.reader = bufio.NewReader(src.conn)
			// c.mr.reader = c.reader
			//
			// var t byte
			// var r *msgReader
			// fmt.Println("b")
			// t, r, err := c.rxMsg()
			// fmt.Println("c")
			// if err != nil {
			// 	fmt.Println(err)
			// 	return
			// }
			// fmt.Println("d")
			//
			// fmt.Printf("t: %#v\n", t)

			// n, err := src.Read(buff)
			// if err != nil {
			// 	p.err("Read failed '%s'\n", err)
			// 	return
			// }
			// b := buff[:n]
			// //show output
			//
			//
			// b = getModifiedBuffer(b, powerCallback)
			// n, err = dst.Write(b)
			//
			//write out result
			n, err = dst.Write(b)
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
		}
	} else {
		for {
			n, err := src.Read(buff)
			if err != nil {
				p.err("Read failed '%s'\n", err)
				return
			}
			b := buff[:n]
			//write out result
			n, err = dst.Write(b)
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
		}
	}
}

func getModifiedBuffer(buffer []byte, powerCallback common.Callback) []byte {
	if powerCallback == nil || len(buffer) < 1 || string(buffer[0]) != "Q" || string(buffer[5:11]) != "power:" {
		return buffer
	}
	query := powerCallback(string(buffer[5:]))
	return makeMessage(query)
}

func makeMessage(query string) []byte {
	queryArray := make([]byte, 0, 6+len(query))
	queryArray = append(queryArray, 'Q', 0, 0, 0, 0)
	queryArray = append(queryArray, query...)
	queryArray = append(queryArray, 0)
	binary.BigEndian.PutUint32(queryArray[1:], uint32(len(queryArray)-1))
	return queryArray

}

func check(err error) {
	if err != nil {
		warn(err.Error())
		os.Exit(1)
	}
}

func warn(f string, args ...interface{}) {
	fmt.Printf(f+"\n", args...)
}
<|endoftext|>


<commit_before>package main

import (
	"fullerite/collector"
	"fullerite/config"
	"fullerite/handler"
	"fullerite/metric"
	"sync"

	"io/ioutil"
	"os"
	"testing"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/stretchr/testify/assert"
)

var testFakeConfiguration = `{
    "prefix": "test.",
    "interval": 10,
    "defaultDimensions": {
    },

	"collectorsConfigPath": "/tmp",
    "diamondCollectorsPath": "src/diamond/collectors",
    "diamondCollectors": [],

    "collectors": ["FakeCollector","Test"],

    "handlers": {
    }
}
`

var testCollectorConfiguration = `{
	"metricName": "TestMetric",
	"interval": 10
}
`

var (
	tmpTestFakeFile, tempTestCollectorConfig string
)

func TestMain(m *testing.M) {
	logrus.SetLevel(logrus.ErrorLevel)
	if f, err := ioutil.TempFile("/tmp", "fullerite"); err == nil {
		f.WriteString(testFakeConfiguration)
		tmpTestFakeFile = f.Name()
		f.Close()
		defer os.Remove(tmpTestFakeFile)
	}
	if f, err := ioutil.TempFile("/tmp", "fullerite"); err == nil {
		f.WriteString(testCollectorConfiguration)
		tempTestCollectorConfig = f.Name() + ".conf"
		f.Close()
		defer os.Remove(tempTestCollectorConfig)
	}
	os.Exit(m.Run())
}

func TestStartCollectorsEmptyConfig(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)
	collectors := startCollectors(config.Config{})

	assert.NotEqual(t, len(collectors), 1, "should create a Collector")
}

func TestStartCollectorUnknownCollector(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)
	c := make(map[string]interface{})
	collector := startCollector("unknown collector", config.Config{}, c)

	assert.Nil(t, collector, "should NOT create a Collector")
}

func TestStartCollectorsMixedConfig(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)
	conf, _ := config.ReadConfig(tmpTestFakeFile)
	collectors := startCollectors(conf)

	for _, c := range collectors {
		assert.Equal(t, c.Name(), "Test", "Only create valid collectors")
	}
}

func TestStartCollectorTooLong(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)
	c := make(map[string]interface{})
	c["interval"] = 1
	collector := startCollector("Test", config.Config{}, c)

	select {
	case m := <-collector.Channel():
		assert.Equal(t, 1.0, m.Value)
		assert.Equal(t, "fullerite.collection_time_exceeded", m.Name)
		assert.Equal(t, "1", m.Dimensions["interval"])
		return
	case <-time.After(5 * time.Second):
		t.Fail()
	}
}

func TestReadFromCollector(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)
	c := make(map[string]interface{})
	c["interval"] = 1
	collector := collector.New("Test")
	collector.SetInterval(1)
	collector.Configure(c)

	var wg sync.WaitGroup
	wg.Add(2)
	collectorStatChannel := make(chan metric.CollectorEmission)
	go func() {
		defer wg.Done()
		collector.Channel() <- metric.New("hello")
		time.Sleep(time.Duration(2) * time.Second)
		m2 := metric.New("world")
		m2.AddDimension("collectorCanonicalName", "Foobar")
		collector.Channel() <- m2
		time.Sleep(time.Duration(2) * time.Second)
		m2.AddDimension("collectorCanonicalName", "Foobar")
		collector.Channel() <- m2
		close(collector.Channel())
	}()
	collectorMetrics := map[string]uint64{}
	go func() {
		defer wg.Done()
		for collectorMetric := range collectorStatChannel {
			collectorMetrics[collectorMetric.Name] = collectorMetric.EmissionCount
		}
	}()
	readFromCollector(collector, []handler.Handler{}, collectorStatChannel)
	wg.Wait()
	assert.Equal(t, uint64(1), collectorMetrics["Test"])
	assert.Equal(t, uint64(2), collectorMetrics["Foobar"])
}
<commit_msg>Add test for checking with metric prefix<commit_after>package main

import (
	"fullerite/collector"
	"fullerite/config"
	"fullerite/handler"
	"fullerite/metric"
	"sync"

	"io/ioutil"
	"os"
	"testing"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/stretchr/testify/assert"
)

var testFakeConfiguration = `{
    "prefix": "test.",
    "interval": 10,
    "defaultDimensions": {
    },

	"collectorsConfigPath": "/tmp",
    "diamondCollectorsPath": "src/diamond/collectors",
    "diamondCollectors": [],

    "collectors": ["FakeCollector","Test"],

    "handlers": {
    }
}
`

var testCollectorConfiguration = `{
	"metricName": "TestMetric",
	"interval": 10
}
`

var (
	tmpTestFakeFile, tempTestCollectorConfig string
)

func TestMain(m *testing.M) {
	logrus.SetLevel(logrus.ErrorLevel)
	if f, err := ioutil.TempFile("/tmp", "fullerite"); err == nil {
		f.WriteString(testFakeConfiguration)
		tmpTestFakeFile = f.Name()
		f.Close()
		defer os.Remove(tmpTestFakeFile)
	}
	if f, err := ioutil.TempFile("/tmp", "fullerite"); err == nil {
		f.WriteString(testCollectorConfiguration)
		tempTestCollectorConfig = f.Name() + ".conf"
		f.Close()
		defer os.Remove(tempTestCollectorConfig)
	}
	os.Exit(m.Run())
}

func TestStartCollectorsEmptyConfig(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)
	collectors := startCollectors(config.Config{})

	assert.NotEqual(t, len(collectors), 1, "should create a Collector")
}

func TestStartCollectorUnknownCollector(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)
	c := make(map[string]interface{})
	collector := startCollector("unknown collector", config.Config{}, c)

	assert.Nil(t, collector, "should NOT create a Collector")
}

func TestStartCollectorsMixedConfig(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)
	conf, _ := config.ReadConfig(tmpTestFakeFile)
	collectors := startCollectors(conf)

	for _, c := range collectors {
		assert.Equal(t, c.Name(), "Test", "Only create valid collectors")
	}
}

func TestStartCollectorTooLong(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)
	c := make(map[string]interface{})
	c["interval"] = 1
	collector := startCollector("Test", config.Config{}, c)

	select {
	case m := <-collector.Channel():
		assert.Equal(t, 1.0, m.Value)
		assert.Equal(t, "fullerite.collection_time_exceeded", m.Name)
		assert.Equal(t, "1", m.Dimensions["interval"])
		return
	case <-time.After(5 * time.Second):
		t.Fail()
	}
}

func TestReadFromCollector(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)
	c := make(map[string]interface{})
	c["interval"] = 1
	collector := collector.New("Test")
	collector.SetInterval(1)
	collector.Configure(c)

	var wg sync.WaitGroup
	wg.Add(2)
	collectorStatChannel := make(chan metric.CollectorEmission)
	go func() {
		defer wg.Done()
		collector.Channel() <- metric.New("hello")
		time.Sleep(time.Duration(2) * time.Second)
		m2 := metric.New("world")
		m2.AddDimension("collectorCanonicalName", "Foobar")
		collector.Channel() <- m2
		time.Sleep(time.Duration(2) * time.Second)
		m2.AddDimension("collectorCanonicalName", "Foobar")
		collector.Channel() <- m2
		close(collector.Channel())
	}()
	collectorMetrics := map[string]uint64{}
	go func() {
		defer wg.Done()
		for collectorMetric := range collectorStatChannel {
			collectorMetrics[collectorMetric.Name] = collectorMetric.EmissionCount
		}
	}()
	readFromCollector(collector, []handler.Handler{}, collectorStatChannel)
	wg.Wait()
	assert.Equal(t, uint64(1), collectorMetrics["Test"])
	assert.Equal(t, uint64(2), collectorMetrics["Foobar"])
}

func TestCollectorPrefix(t *testing.T) {
	logrus.SetLevel(logrus.ErrorLevel)
	c := make(map[string]interface{})
	c["interval"] = 1
	c["prefix"] = "px."
	collector := collector.New("Test")
	collector.SetInterval(1)
	collector.Configure(c)

	collectorChannel := map[string]chan metric.Metric{
		"Test": make(chan metric.Metric),
	}

	testHandler := handler.New("Log")
	testHandler.SetCollectorChannels(collectorChannel)

	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		defer wg.Done()
		collector.Channel() <- metric.New("hello")
		close(collector.Channel())
	}()
	go func() {
		defer wg.Done()
		testMetric := <-collectorChannel["Test"]
		assert.Equal(t, "px.hello", testMetric.Name)
	}()
	readFromCollector(collector, []handler.Handler{testHandler})
	wg.Wait()
}
<|endoftext|>


<commit_before>// Package watcher is used for watching files and directories
// for automatic recompilation and restart of app on change
// when in development mode.
package watcher

import (
	"errors"
	"os"
	"path/filepath"
	"sync"

	"github.com/anonx/sunplate/log"

	"gopkg.in/fsnotify.v1"
)

// Type is a watcher type that allows registering new
// pattern - actions pairs.
type Type struct {
	mu sync.Mutex
}

// NewType allocates and returns a new instance of watcher Type.
func NewType() *Type {
	return &Type{}
}

// Listen gets a pattern and a function. The function will be executed
// when files matching the pattern will be modified.
func (t *Type) Listen(pattern string, fn func()) {
	// Create a new watcher.
	w, err := fsnotify.NewWatcher()
	log.AssertNil(err)

	// Find directories matching the pattern.
	ds := glob(pattern)
	if err != nil {
		log.Error.Panicf("Pattern `%s` is malformed. Error: %v.", pattern, err)
	}

	// Add the files to the watcher.
	for i := range ds {
		log.Trace.Printf(`Adding "%s" to the list of watched directories...`, ds[i])
		err := w.Add(ds[i])
		if err != nil {
			log.Warn.Println(err)
		}
	}

	// Start watching process.
	go t.NotifyOnUpdate(w, fn)
}

// NotifyOnUpdate starts the function every time a file change
// event is received. Start it as a goroutine.
func (t *Type) NotifyOnUpdate(watcher *fsnotify.Watcher, fn func()) {
	for {
		select {
		case ev := <-watcher.Events:
			if restartRequired(ev) {
				t.mu.Lock()
				fn()
				t.mu.Unlock()
			}
		case err := <-watcher.Errors:
			log.Warn.Println(err)
		}
	}
}

// restartRequired checks whether event indicates a file
// has been modified. If so, it returns true.
func restartRequired(event fsnotify.Event) bool {
	if event.Op&fsnotify.Chmod == fsnotify.Chmod {
		return true
	}
	return false
}

// glob returns names of all directories matching pattern or nil.
// The only supported special character is an asterisk at the end.
// It means that the directory is expected to be scanned recursively.
// There is no way for fsnotify to watch individual files (see #17),
// do we support only directories.
// File system errors such as I/O reading are ignored.
func glob(pattern string) (ds []string) {
	// Check whether recursive scan is expected.
	l := len(pattern)
	if l == 0 || pattern[l-1] != '*' {
		ds = append(ds, pattern)
		return // Return as is.
	}

	// Otherwise, trim the asterisk at the end.
	pattern = pattern[:l-1]

	// Start searching directories recursively.
	filepath.Walk(pattern, func(path string, info os.FileInfo, err error) error {
		// Make sure there are no any errors.
		if err != nil {
			return err
		}

		// Make sure the path represents a directory.
		if info.IsDir() {
			ds = append(ds, path) // Add current path to the list.
			return nil
		}

		// Otherwise, return an error.
		return errors.New("not a directory")
	})
	return
}
<commit_msg>watcher: Restart on Write event rather than Chmod<commit_after>// Package watcher is used for watching files and directories
// for automatic recompilation and restart of app on change
// when in development mode.
package watcher

import (
	"errors"
	"os"
	"path/filepath"
	"sync"

	"github.com/anonx/sunplate/log"

	"gopkg.in/fsnotify.v1"
)

// Type is a watcher type that allows registering new
// pattern - actions pairs.
type Type struct {
	mu sync.Mutex
}

// NewType allocates and returns a new instance of watcher Type.
func NewType() *Type {
	return &Type{}
}

// Listen gets a pattern and a function. The function will be executed
// when files matching the pattern will be modified.
func (t *Type) Listen(pattern string, fn func()) {
	// Create a new watcher.
	w, err := fsnotify.NewWatcher()
	log.AssertNil(err)

	// Find directories matching the pattern.
	ds := glob(pattern)
	if err != nil {
		log.Error.Panicf("Pattern `%s` is malformed. Error: %v.", pattern, err)
	}

	// Add the files to the watcher.
	for i := range ds {
		log.Trace.Printf(`Adding "%s" to the list of watched directories...`, ds[i])
		err := w.Add(ds[i])
		if err != nil {
			log.Warn.Println(err)
		}
	}

	// Start watching process.
	go t.NotifyOnUpdate(w, fn)
}

// NotifyOnUpdate starts the function every time a file change
// event is received. Start it as a goroutine.
func (t *Type) NotifyOnUpdate(watcher *fsnotify.Watcher, fn func()) {
	for {
		select {
		case ev := <-watcher.Events:
			if restartRequired(ev) {
				t.mu.Lock()
				fn()
				t.mu.Unlock()
			}
		case err := <-watcher.Errors:
			log.Warn.Println(err)
		}
	}
}

// restartRequired checks whether event indicates a file
// has been modified. If so, it returns true.
func restartRequired(event fsnotify.Event) bool {
	if event.Op&fsnotify.Write == fsnotify.Write {
		return true
	}
	return false
}

// glob returns names of all directories matching pattern or nil.
// The only supported special character is an asterisk at the end.
// It means that the directory is expected to be scanned recursively.
// There is no way for fsnotify to watch individual files (see #17),
// do we support only directories.
// File system errors such as I/O reading are ignored.
func glob(pattern string) (ds []string) {
	// Check whether recursive scan is expected.
	l := len(pattern)
	if l == 0 || pattern[l-1] != '*' {
		ds = append(ds, pattern)
		return // Return as is.
	}

	// Otherwise, trim the asterisk at the end.
	pattern = pattern[:l-1]

	// Start searching directories recursively.
	filepath.Walk(pattern, func(path string, info os.FileInfo, err error) error {
		// Make sure there are no any errors.
		if err != nil {
			return err
		}

		// Make sure the path represents a directory.
		if info.IsDir() {
			ds = append(ds, path) // Add current path to the list.
			return nil
		}

		// Otherwise, return an error.
		return errors.New("not a directory")
	})
	return
}
<|endoftext|>


<commit_before>package plugin

import (
	"crypto/rand"
	"encoding/json"
	"fmt"
	"net"
	"os"

	"github.com/containernetworking/cni/pkg/ipam"
	"github.com/containernetworking/cni/pkg/skel"
	"github.com/containernetworking/cni/pkg/types"
	"github.com/containernetworking/cni/pkg/types/current"
	"github.com/vishvananda/netlink"
	"github.com/vishvananda/netns"
	weaveapi "github.com/weaveworks/weave/api"
	weavenet "github.com/weaveworks/weave/net"
	ipamplugin "github.com/weaveworks/weave/plugin/ipam"
)

var (
	zeroNetwork = net.IPNet{IP: net.IPv4zero, Mask: net.IPv4Mask(0, 0, 0, 0)}
	mask32      = net.IPv4Mask(0xff, 0xff, 0xff, 0xff)
)

type CNIPlugin struct {
	weave *weaveapi.Client
}

func NewCNIPlugin(weave *weaveapi.Client) *CNIPlugin {
	return &CNIPlugin{weave: weave}
}

func loadNetConf(bytes []byte) (*NetConf, error) {
	n := &NetConf{
		BrName:      weavenet.WeaveBridgeName,
		HairpinMode: true,
	}
	if err := json.Unmarshal(bytes, n); err != nil {
		return nil, fmt.Errorf("failed to load netconf: %v", err)
	}
	return n, nil
}

func (c *CNIPlugin) getIP(ipamType string, args *skel.CmdArgs) (newResult *current.Result, err error) {
	var result types.Result
	// Default IPAM is Weave's own
	if ipamType == "" {
		result, err = ipamplugin.NewIpam(c.weave).Allocate(args)
	} else {
		result, err = ipam.ExecAdd(ipamType, args.StdinData)
	}
	if err != nil {
		return nil, err
	}
	if result == nil {
		return nil, fmt.Errorf("Received no usable result from IPAM plugin")
	}
	newResult, err = current.NewResultFromResult(result)
	// Check if ipam returned no results without error
	if err == nil && len(newResult.IPs) == 0 {
		return nil, fmt.Errorf("IPAM plugin failed to allocate IP address")
	}
	return newResult, err
}

func (c *CNIPlugin) CmdAdd(args *skel.CmdArgs) error {
	conf, err := loadNetConf(args.StdinData)
	if err != nil {
		return err
	}

	if conf.IsGW {
		return fmt.Errorf("Gateway functionality not supported")
	}
	if conf.IPMasq {
		return fmt.Errorf("IP Masquerading functionality not supported")
	}

	result, err := c.getIP(conf.IPAM.Type, args)
	if err != nil {
		return fmt.Errorf("unable to allocate IP address: %s", err)
	}
	// Only expecting one address
	ip := result.IPs[0]

	// If config says nothing about routes or gateway, default one will be via the bridge
	if len(result.Routes) == 0 && ip.Gateway == nil {
		bridgeIP, err := weavenet.FindBridgeIP(conf.BrName, &ip.Address)
		if err == weavenet.ErrBridgeNoIP {
			bridgeArgs := *args
			bridgeArgs.ContainerID = "weave:expose"
			// It would be better if libcni let us send just the desired parameters,
			// but there is a bug: https://github.com/containernetworking/cni/issues/410
			// so just blank out the one we want to change
			os.Setenv("CNI_CONTAINERID", bridgeArgs.ContainerID)
			bridgeIPResult, err := c.getIP(conf.IPAM.Type, &bridgeArgs)
			if err != nil {
				return fmt.Errorf("unable to allocate IP address for bridge: %s", err)
			}
			bridgeCIDR := bridgeIPResult.IPs[0].Address

			if err := c.weave.Expose(&bridgeCIDR); err != nil {
				return fmt.Errorf("unable to expose bridge %q: %s", conf.BrName, err)
			}

			bridgeIP = bridgeCIDR.IP
		} else if err != nil {
			return err
		}
		result.IPs[0].Gateway = bridgeIP
	}

	ns, err := netns.GetFromPath(args.Netns)
	if err != nil {
		return fmt.Errorf("error accessing namespace %q: %s", args.Netns, err)
	}
	defer ns.Close()

	id := args.ContainerID
	if len(id) < 5 {
		data := make([]byte, 5)
		_, err := rand.Reader.Read(data)
		if err != nil {
			return err
		}
		id = fmt.Sprintf("%x", data)
	}

	if err := weavenet.AttachContainer(args.Netns, id, args.IfName, conf.BrName, conf.MTU, false, []*net.IPNet{&ip.Address}, false, conf.HairpinMode); err != nil {
		return err
	}
	if err := weavenet.WithNetNSLink(ns, args.IfName, func(link netlink.Link) error {
		return setupRoutes(link, args.IfName, ip.Address, ip.Gateway, result.Routes)
	}); err != nil {
		return fmt.Errorf("error setting up routes: %s", err)
	}

	result.DNS = conf.DNS
	return types.PrintResult(result, conf.CNIVersion)
}

func setupRoutes(link netlink.Link, name string, ipnet net.IPNet, gw net.IP, routes []*types.Route) error {
	var err error
	if routes == nil { // If config says nothing about routes, add a default one
		if !ipnet.Contains(gw) {
			// The bridge IP is not on the same subnet; add a specific route to it
			gw32 := &net.IPNet{IP: gw, Mask: mask32}
			if err = weavenet.AddRoute(link, netlink.SCOPE_LINK, gw32, nil); err != nil {
				return err
			}
		}
		routes = []*types.Route{{Dst: zeroNetwork}}
	}
	for _, r := range routes {
		if r.GW != nil {
			err = weavenet.AddRoute(link, netlink.SCOPE_UNIVERSE, &r.Dst, r.GW)
		} else {
			err = weavenet.AddRoute(link, netlink.SCOPE_UNIVERSE, &r.Dst, gw)
		}
		if err != nil {
			return fmt.Errorf("failed to add route '%v via %v dev %v': %v", r.Dst, gw, name, err)
		}
	}
	return nil
}

// As of CNI 0.5 spec:
//   "Plugins should generally complete a DEL action without error even if some resources are missing"
// this method should therefore return nil in most, if not all, cases.
func (c *CNIPlugin) CmdDel(args *skel.CmdArgs) error {
	conf, err := loadNetConf(args.StdinData)
	if err != nil {
		logOnStderr(err)
		return nil
	}

	// As of CNI 0.3 spec, runtimes can send blank if they just want the address deallocated
	if args.Netns != "" {
		if err = weavenet.WithNetNSByPath(args.Netns, func() error {
			link, err := netlink.LinkByName(args.IfName)
			if err != nil {
				return err
			}
			return netlink.LinkDel(link)
		}); err != nil {
			// We log the error and carry on instead of returning nil, as there may still be resources to free in IPAM.
			logOnStderr(fmt.Errorf("error removing interface %q: %s", args.IfName, err))
		}
	}

	// Default IPAM is Weave's own
	if conf.IPAM.Type == "" {
		err = ipamplugin.NewIpam(c.weave).Release(args)
	} else {
		err = ipam.ExecDel(conf.IPAM.Type, args.StdinData)
	}
	if err != nil {
		logOnStderr(fmt.Errorf("unable to release IP address: %s", err))
	}
	return nil
}

// Standard error is inherited from the caller (e.g. Kubelet, when running Weave Net's CNI plugin
// under Kubernetes) hence provided errors should eventually appear in the caller's log files.
func logOnStderr(err error) {
	fmt.Fprintln(os.Stderr, "weave-cni:", err)
}

type NetConf struct {
	types.NetConf
	BrName      string `json:"bridge"`
	IsGW        bool   `json:"isGateway"`
	IPMasq      bool   `json:"ipMasq"`
	MTU         int    `json:"mtu"`
	HairpinMode bool   `json:"hairpinMode"`
}
<commit_msg>3206: Protect against CNI plugin being called with the host namespace<commit_after>package plugin

import (
	"crypto/rand"
	"encoding/json"
	"fmt"
	"net"
	"os"

	"github.com/containernetworking/cni/pkg/ipam"
	"github.com/containernetworking/cni/pkg/skel"
	"github.com/containernetworking/cni/pkg/types"
	"github.com/containernetworking/cni/pkg/types/current"
	"github.com/vishvananda/netlink"
	"github.com/vishvananda/netns"
	weaveapi "github.com/weaveworks/weave/api"
	weavenet "github.com/weaveworks/weave/net"
	ipamplugin "github.com/weaveworks/weave/plugin/ipam"
)

var (
	zeroNetwork = net.IPNet{IP: net.IPv4zero, Mask: net.IPv4Mask(0, 0, 0, 0)}
	mask32      = net.IPv4Mask(0xff, 0xff, 0xff, 0xff)
)

type CNIPlugin struct {
	weave *weaveapi.Client
}

func NewCNIPlugin(weave *weaveapi.Client) *CNIPlugin {
	return &CNIPlugin{weave: weave}
}

func loadNetConf(bytes []byte) (*NetConf, error) {
	n := &NetConf{
		BrName:      weavenet.WeaveBridgeName,
		HairpinMode: true,
	}
	if err := json.Unmarshal(bytes, n); err != nil {
		return nil, fmt.Errorf("failed to load netconf: %v", err)
	}
	return n, nil
}

func (c *CNIPlugin) getIP(ipamType string, args *skel.CmdArgs) (newResult *current.Result, err error) {
	var result types.Result
	// Default IPAM is Weave's own
	if ipamType == "" {
		result, err = ipamplugin.NewIpam(c.weave).Allocate(args)
	} else {
		result, err = ipam.ExecAdd(ipamType, args.StdinData)
	}
	if err != nil {
		return nil, err
	}
	if result == nil {
		return nil, fmt.Errorf("Received no usable result from IPAM plugin")
	}
	newResult, err = current.NewResultFromResult(result)
	// Check if ipam returned no results without error
	if err == nil && len(newResult.IPs) == 0 {
		return nil, fmt.Errorf("IPAM plugin failed to allocate IP address")
	}
	return newResult, err
}

func (c *CNIPlugin) CmdAdd(args *skel.CmdArgs) error {
	conf, err := loadNetConf(args.StdinData)
	if err != nil {
		return err
	}

	if conf.IsGW {
		return fmt.Errorf("Gateway functionality not supported")
	}
	if conf.IPMasq {
		return fmt.Errorf("IP Masquerading functionality not supported")
	}

	result, err := c.getIP(conf.IPAM.Type, args)
	if err != nil {
		return fmt.Errorf("unable to allocate IP address: %s", err)
	}
	// Only expecting one address
	ip := result.IPs[0]

	// If config says nothing about routes or gateway, default one will be via the bridge
	if len(result.Routes) == 0 && ip.Gateway == nil {
		bridgeIP, err := weavenet.FindBridgeIP(conf.BrName, &ip.Address)
		if err == weavenet.ErrBridgeNoIP {
			bridgeArgs := *args
			bridgeArgs.ContainerID = "weave:expose"
			// It would be better if libcni let us send just the desired parameters,
			// but there is a bug: https://github.com/containernetworking/cni/issues/410
			// so just blank out the one we want to change
			os.Setenv("CNI_CONTAINERID", bridgeArgs.ContainerID)
			bridgeIPResult, err := c.getIP(conf.IPAM.Type, &bridgeArgs)
			if err != nil {
				return fmt.Errorf("unable to allocate IP address for bridge: %s", err)
			}
			bridgeCIDR := bridgeIPResult.IPs[0].Address

			if err := c.weave.Expose(&bridgeCIDR); err != nil {
				return fmt.Errorf("unable to expose bridge %q: %s", conf.BrName, err)
			}

			bridgeIP = bridgeCIDR.IP
		} else if err != nil {
			return err
		}
		result.IPs[0].Gateway = bridgeIP
	}

	ns, err := netns.GetFromPath(args.Netns)
	if err != nil {
		return fmt.Errorf("error accessing namespace %q: %s", args.Netns, err)
	}
	defer ns.Close()

	hostNs, err := netns.Get()
	if err != nil {
		return fmt.Errorf("error accessing host network namespace: %s", err)
	}
	defer hostNs.Close()

	if ns.Equal(hostNs) {
		return fmt.Errorf("can not specify host network namespace as network namespace to which container should be added")
	}

	id := args.ContainerID
	if len(id) < 5 {
		data := make([]byte, 5)
		_, err := rand.Reader.Read(data)
		if err != nil {
			return err
		}
		id = fmt.Sprintf("%x", data)
	}

	if err := weavenet.AttachContainer(args.Netns, id, args.IfName, conf.BrName, conf.MTU, false, []*net.IPNet{&ip.Address}, false, conf.HairpinMode); err != nil {
		return err
	}
	if err := weavenet.WithNetNSLink(ns, args.IfName, func(link netlink.Link) error {
		return setupRoutes(link, args.IfName, ip.Address, ip.Gateway, result.Routes)
	}); err != nil {
		return fmt.Errorf("error setting up routes: %s", err)
	}

	result.DNS = conf.DNS
	return types.PrintResult(result, conf.CNIVersion)
}

func setupRoutes(link netlink.Link, name string, ipnet net.IPNet, gw net.IP, routes []*types.Route) error {
	var err error
	if routes == nil { // If config says nothing about routes, add a default one
		if !ipnet.Contains(gw) {
			// The bridge IP is not on the same subnet; add a specific route to it
			gw32 := &net.IPNet{IP: gw, Mask: mask32}
			if err = weavenet.AddRoute(link, netlink.SCOPE_LINK, gw32, nil); err != nil {
				return err
			}
		}
		routes = []*types.Route{{Dst: zeroNetwork}}
	}
	for _, r := range routes {
		if r.GW != nil {
			err = weavenet.AddRoute(link, netlink.SCOPE_UNIVERSE, &r.Dst, r.GW)
		} else {
			err = weavenet.AddRoute(link, netlink.SCOPE_UNIVERSE, &r.Dst, gw)
		}
		if err != nil {
			return fmt.Errorf("failed to add route '%v via %v dev %v': %v", r.Dst, gw, name, err)
		}
	}
	return nil
}

// As of CNI 0.5 spec:
//   "Plugins should generally complete a DEL action without error even if some resources are missing"
// this method should therefore return nil in most, if not all, cases.
func (c *CNIPlugin) CmdDel(args *skel.CmdArgs) error {
	conf, err := loadNetConf(args.StdinData)
	if err != nil {
		logOnStderr(err)
		return nil
	}

	// As of CNI 0.3 spec, runtimes can send blank if they just want the address deallocated
	if args.Netns != "" {
		if err = weavenet.WithNetNSByPath(args.Netns, func() error {
			link, err := netlink.LinkByName(args.IfName)
			if err != nil {
				return err
			}
			return netlink.LinkDel(link)
		}); err != nil {
			// We log the error and carry on instead of returning nil, as there may still be resources to free in IPAM.
			logOnStderr(fmt.Errorf("error removing interface %q: %s", args.IfName, err))
		}
	}

	// Default IPAM is Weave's own
	if conf.IPAM.Type == "" {
		err = ipamplugin.NewIpam(c.weave).Release(args)
	} else {
		err = ipam.ExecDel(conf.IPAM.Type, args.StdinData)
	}
	if err != nil {
		logOnStderr(fmt.Errorf("unable to release IP address: %s", err))
	}
	return nil
}

// Standard error is inherited from the caller (e.g. Kubelet, when running Weave Net's CNI plugin
// under Kubernetes) hence provided errors should eventually appear in the caller's log files.
func logOnStderr(err error) {
	fmt.Fprintln(os.Stderr, "weave-cni:", err)
}

type NetConf struct {
	types.NetConf
	BrName      string `json:"bridge"`
	IsGW        bool   `json:"isGateway"`
	IPMasq      bool   `json:"ipMasq"`
	MTU         int    `json:"mtu"`
	HairpinMode bool   `json:"hairpinMode"`
}
<|endoftext|>


<commit_before>package pipoint

import (
	"math"
)

// Parameters for a servo including limits.
type ServoParams struct {
	Pin string
	Min float64
	Max float64
	Mid float64
}

// A servo on a pin with limits, demand, and actual position.
type Servo struct {
	params *Param
	sp     *Param
	pv     *Param
}

func NewServo(name string, params *Params) *Servo {
	s := &Servo{
		params: params.NewWith(name, &ServoParams{
			"",
			-math.Pi / 2,
			math.Pi / 2,
			0,
		}),
		sp: params.New(name + ".sp"),
		pv: params.New(name + ".pv"),
	}

	return s
}

func (s *Servo) Set(angle float64) {
	params := s.params.Get().(*ServoParams)

	s.sp.SetFloat64(angle)

	angle += params.Mid
	angle = math.Min(angle, params.Max)
	angle = math.Max(angle, params.Min)

	// Move from -pi/2..pi/2 to the gobot format.
	demand := int(AsDeg(angle) + 90 + 0.5)

	if demand < 0 {
		demand = 0
	}
	if demand > 250 {
		demand = 250
	}
	s.pv.SetFloat64(AsRad(float64(demand - 90)))
}
<commit_msg>pipoint: actually implement the Servo class.<commit_after>package pipoint

import (
	"math"
	"log"
)

// Parameters for a servo including limits.
type ServoParams struct {
	Pin int
	Span float64

	Min float64
	Max float64
}

// A servo on a pin with limits, demand, and actual position.
type Servo struct {
	params *Param
	sp     *Param
	pv     *Param
	pwm *PwmPin
}

func NewServo(name string, params *Params) *Servo {
	s := &Servo{
		params: params.NewWith(name, &ServoParams{
			Pin: -1,
			Min: 1.1,
			Max: 1.9,
			Span: math.Pi,
		}),
		sp: params.New(name + ".sp"),
		pv: params.New(name + ".pv"),
	}

	return s
}

func (s *Servo) Set(angle float64) {
	params := s.params.Get().(*ServoParams)

	s.sp.SetFloat64(angle)

	// Convert to pulse width.
	angle += math.Pi/2
	angle /= math.Pi

	ms := params.Min + angle*(params.Max - params.Min)
	if ms < 1 {
		ms = 1
	}
	if ms > 2 {
		ms = 2
	}
	s.pv.SetFloat64(ms)

	if params.Pin < 0 {
		return
	}
	if s.pwm == nil || params.Pin != s.pwm.Pin {
		if s.pwm != nil {
			s.pwm.SetEnable(0)
			s.pwm.UnExport()
		}
		s.pwm = &PwmPin{Chip: 0, Pin: params.Pin}

		var err error
		s.pwm.Export()
		err = s.pwm.SetEnable(0)
		if err == nil {
			err = s.pwm.SetPeriod(20e6)
		}
		if err == nil {
			s.pwm.SetDuty(int(ms*1e6))
		}
		if err == nil {
			err = s.pwm.SetEnable(1)
		}
		if err != nil {
			log.Printf("error: %v\n", err)
		}
	}
	if s.pwm != nil {
		s.pwm.SetDuty(int(ms*1e6))
	}
}
<|endoftext|>