<commit_before>package main

import (
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"strings"
	"time"

	stress "github.com/buaazp/stress/lib"
)

func attackCmd() command {
	fs := flag.NewFlagSet("stress attack", flag.ExitOnError)
	opts := &attackOpts{
		headers: headers{http.Header{}},
		laddr:   localAddr{&stress.DefaultLocalAddr},
	}

	fs.StringVar(&opts.targetsf, "targets", "stdin", "Targets file")
	fs.StringVar(&opts.outputf, "output", "result.json", "Output file")
	fs.StringVar(&opts.bodyf, "body", "", "Requests body file")
	fs.StringVar(&opts.ordering, "ordering", "random", "Attack ordering [sequential, random]")
	fs.DurationVar(&opts.duration, "duration", 10*time.Second, "Duration of the test")
	fs.DurationVar(&opts.timeout, "timeout", 0, "Requests timeout")
	fs.Uint64Var(&opts.rate, "rate", 0, "Requests per second")
	fs.Uint64Var(&opts.concurrency, "c", 0, "Concurrency level")
	fs.Uint64Var(&opts.number, "n", 1000, "Requests number")
	fs.IntVar(&opts.redirects, "redirects", 10, "Number of redirects to follow")
	fs.Var(&opts.headers, "header", "Request header")
	fs.Var(&opts.laddr, "laddr", "Local IP address")

	return command{fs, func(args []string) error {
		fs.Parse(args)
		return attack(opts)
	}}
}

// attackOpts aggregates the attack function command options
type attackOpts struct {
	targetsf    string
	outputf     string
	bodyf       string
	ordering    string
	timeout     time.Duration
	rate        uint64
	duration    time.Duration
	concurrency uint64
	number      uint64
	redirects   int
	headers     headers
	laddr       localAddr
}

// attack validates the attack arguments, sets up the
// required resources, launches the attack and writes the results
func attack(opts *attackOpts) error {
	if opts.rate == 0 && opts.concurrency == 0 {
		return fmt.Errorf(errRatePrefix + "or " + errConcurrencyPrefix + "can't be zero")
	} else if opts.rate != 0 && opts.concurrency != 0 {
		return fmt.Errorf(errRatePrefix + "is conflict with " + errConcurrencyPrefix)
	}

	if opts.rate != 0 && opts.duration == 0 {
		return fmt.Errorf(errDurationPrefix + "can't be zero")
	}

	if opts.concurrency != 0 && opts.number == 0 {
		return fmt.Errorf(errNumberPrefix + "can't be zero")
	}

	in, err := file(opts.targetsf, false)
	if err != nil {
		return fmt.Errorf(errTargetsFilePrefix+"(%s): %s", opts.targetsf, err)
	}
	defer in.Close()

	var body []byte
	if opts.bodyf != "" {
		bodyr, err := file(opts.bodyf, false)
		if err != nil {
			return fmt.Errorf(errBodyFilePrefix+"(%s): %s", opts.bodyf, err)
		}
		defer bodyr.Close()

		if body, err = ioutil.ReadAll(bodyr); err != nil {
			return fmt.Errorf(errBodyFilePrefix+"(%s): %s", opts.bodyf, err)
		}
	}

	targets, err := stress.NewTargetsFrom(in, body, opts.headers.Header)
	if err != nil {
		return fmt.Errorf(errTargetsFilePrefix+"(%s): %s", opts.targetsf, err)
	}

	switch opts.ordering {
	case "random":
		targets.Shuffle(time.Now().UnixNano())
	case "sequential":
		break
	default:
		return fmt.Errorf(errOrderingPrefix+"`%s` is invalid", opts.ordering)
	}

	out, err := file(opts.outputf, true)
	if err != nil {
		return fmt.Errorf(errOutputFilePrefix+"(%s): %s", opts.outputf, err)
	}
	defer out.Close()

	attacker := stress.NewAttacker(opts.redirects, opts.timeout, *opts.laddr.IPAddr)

	var results stress.Results
	if opts.rate != 0 {
		log.Printf(
			"Stress is attacking %d targets in %s order and %d rate for %s...\n",
			len(targets),
			opts.ordering,
			opts.rate,
			opts.duration,
		)
		results = attacker.AttackRate(targets, opts.rate, opts.duration)
	} else if opts.concurrency != 0 {
		concurrency := opts.concurrency
		if opts.concurrency > opts.number {
			concurrency = opts.number
		}
		log.Printf(
			"Stress is attacking %d targets in %s order and %d concurrency level for %d times...\n",
			len(targets),
			opts.ordering,
			concurrency,
			opts.number,
		)
		results = attacker.AttackConcy(targets, opts.concurrency, opts.number)
	}

	log.Printf("Done! Writing results to '%s'...", opts.outputf)
	err = results.Encode(out)
	if err != nil {
		return err
	}

	data, err := stress.ReportText(results)
	if err != nil {
		return err
	}

	_, err = os.Stdout.Write(data)

	return err
}

const (
	errRatePrefix        = "Rate: "
	errDurationPrefix    = "Duration: "
	errConcurrencyPrefix = "Concurrency Level: "
	errNumberPrefix      = "Number: "
	errOutputFilePrefix  = "Output file: "
	errTargetsFilePrefix = "Targets file: "
	errBodyFilePrefix    = "Body file: "
	errOrderingPrefix    = "Ordering: "
	errReportingPrefix   = "Reporting: "
)

// headers is the http.Header used in each target request
// it is defined here to implement the flag.Value interface
// in order to support multiple identical flags for request header
// specification
type headers struct{ http.Header }

func (h headers) String() string {
	buf := &bytes.Buffer{}
	if err := h.Write(buf); err != nil {
		return ""
	}
	return buf.String()
}

func (h headers) Set(value string) error {
	parts := strings.SplitN(value, ":", 2)
	if len(parts) != 2 {
		return fmt.Errorf("Header '%s' has a wrong format", value)
	}
	key, val := strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])
	if key == "" || val == "" {
		return fmt.Errorf("Header '%s' has a wrong format", value)
	}
	h.Add(key, val)
	return nil
}

// localAddr implements the Flag interface for parsing net.IPAddr
type localAddr struct{ *net.IPAddr }

func (ip *localAddr) Set(value string) (err error) {
	ip.IPAddr, err = net.ResolveIPAddr("ip", value)
	return
}
<commit_msg>Update attack.go<commit_after>package main

import (
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"strings"
	"time"

	stress "github.com/buaazp/stress/lib"
)

func attackCmd() command {
	fs := flag.NewFlagSet("stress attack", flag.ExitOnError)
	opts := &attackOpts{
		headers: headers{http.Header{}},
		laddr:   localAddr{&stress.DefaultLocalAddr},
	}

	fs.StringVar(&opts.targetsf, "targets", "stdin", "Targets file")
	fs.StringVar(&opts.outputf, "output", "result.json", "Output file")
	fs.StringVar(&opts.bodyf, "body", "", "Requests body file")
	fs.StringVar(&opts.ordering, "ordering", "random", "Attack ordering [sequential, random]")
	fs.DurationVar(&opts.duration, "duration", 10*time.Second, "Duration of the test")
	fs.DurationVar(&opts.timeout, "timeout", 0, "Requests timeout")
	fs.Uint64Var(&opts.rate, "rate", 0, "Requests per second")
	fs.Uint64Var(&opts.concurrency, "c", 0, "Concurrency level")
	fs.Uint64Var(&opts.number, "n", 1000, "Requests number")
	fs.IntVar(&opts.redirects, "redirects", 10, "Number of redirects to follow")
	fs.Var(&opts.headers, "header", "Request header")
	fs.Var(&opts.laddr, "laddr", "Local IP address")

	return command{fs, func(args []string) error {
		fs.Parse(args)
		return attack(opts)
	}}
}

// attackOpts aggregates the attack function command options
type attackOpts struct {
	targetsf    string
	outputf     string
	bodyf       string
	ordering    string
	timeout     time.Duration
	rate        uint64
	duration    time.Duration
	concurrency uint64
	number      uint64
	redirects   int
	headers     headers
	laddr       localAddr
}

// attack validates the attack arguments, sets up the
// required resources, launches the attack and writes the results
func attack(opts *attackOpts) error {
	if opts.rate == 0 && opts.concurrency == 0 {
		return fmt.Errorf(errRatePrefix + "or " + errConcurrencyPrefix + "can't be zero")
	} else if opts.rate != 0 && opts.concurrency != 0 {
		return fmt.Errorf(errRatePrefix + "is conflict with " + errConcurrencyPrefix)
	}

	if opts.rate != 0 && opts.duration == 0 {
		return fmt.Errorf(errDurationPrefix + "can't be zero")
	}

	if opts.concurrency != 0 && opts.number == 0 {
		return fmt.Errorf(errNumberPrefix + "can't be zero")
	}

	in, err := file(opts.targetsf, false)
	if err != nil {
		return fmt.Errorf(errTargetsFilePrefix+"(%s): %s", opts.targetsf, err)
	}
	defer in.Close()

	var body []byte
	if opts.bodyf != "" {
		bodyr, err := file(opts.bodyf, false)
		if err != nil {
			return fmt.Errorf(errBodyFilePrefix+"(%s): %s", opts.bodyf, err)
		}
		defer bodyr.Close()

		if body, err = ioutil.ReadAll(bodyr); err != nil {
			return fmt.Errorf(errBodyFilePrefix+"(%s): %s", opts.bodyf, err)
		}
	}

	targets, err := stress.NewTargetsFrom(in, body, opts.headers.Header)
	if err != nil {
		return fmt.Errorf(errTargetsFilePrefix+"(%s): %s", opts.targetsf, err)
	}
	if len(targets) == 0 {
		return fmt.Errorf(errTargetsFilePrefix+" : is empty")
	}

	switch opts.ordering {
	case "random":
		targets.Shuffle(time.Now().UnixNano())
	case "sequential":
		break
	default:
		return fmt.Errorf(errOrderingPrefix+"`%s` is invalid", opts.ordering)
	}

	out, err := file(opts.outputf, true)
	if err != nil {
		return fmt.Errorf(errOutputFilePrefix+"(%s): %s", opts.outputf, err)
	}
	defer out.Close()

	attacker := stress.NewAttacker(opts.redirects, opts.timeout, *opts.laddr.IPAddr)

	var results stress.Results
	if opts.rate != 0 {
		log.Printf(
			"Stress is attacking %d targets in %s order and %d rate for %s...\n",
			len(targets),
			opts.ordering,
			opts.rate,
			opts.duration,
		)
		results = attacker.AttackRate(targets, opts.rate, opts.duration)
	} else if opts.concurrency != 0 {
		concurrency := opts.concurrency
		if opts.concurrency > opts.number {
			concurrency = opts.number
		}
		log.Printf(
			"Stress is attacking %d targets in %s order and %d concurrency level for %d times...\n",
			len(targets),
			opts.ordering,
			concurrency,
			opts.number,
		)
		results = attacker.AttackConcy(targets, opts.concurrency, opts.number)
	}

	log.Printf("Done! Writing results to '%s'...", opts.outputf)
	err = results.Encode(out)
	if err != nil {
		return err
	}

	data, err := stress.ReportText(results)
	if err != nil {
		return err
	}

	_, err = os.Stdout.Write(data)

	return err
}

const (
	errRatePrefix        = "Rate: "
	errDurationPrefix    = "Duration: "
	errConcurrencyPrefix = "Concurrency Level: "
	errNumberPrefix      = "Number: "
	errOutputFilePrefix  = "Output file: "
	errTargetsFilePrefix = "Targets file: "
	errBodyFilePrefix    = "Body file: "
	errOrderingPrefix    = "Ordering: "
	errReportingPrefix   = "Reporting: "
)

// headers is the http.Header used in each target request
// it is defined here to implement the flag.Value interface
// in order to support multiple identical flags for request header
// specification
type headers struct{ http.Header }

func (h headers) String() string {
	buf := &bytes.Buffer{}
	if err := h.Write(buf); err != nil {
		return ""
	}
	return buf.String()
}

func (h headers) Set(value string) error {
	parts := strings.SplitN(value, ":", 2)
	if len(parts) != 2 {
		return fmt.Errorf("Header '%s' has a wrong format", value)
	}
	key, val := strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])
	if key == "" || val == "" {
		return fmt.Errorf("Header '%s' has a wrong format", value)
	}
	h.Add(key, val)
	return nil
}

// localAddr implements the Flag interface for parsing net.IPAddr
type localAddr struct{ *net.IPAddr }

func (ip *localAddr) Set(value string) (err error) {
	ip.IPAddr, err = net.ResolveIPAddr("ip", value)
	return
}
<|endoftext|>


<commit_before>package release

import (
	"time"

	"github.com/go-kit/kit/log"

	"github.com/weaveworks/flux/update"
)

type Changes interface {
	CalculateRelease(update.ReleaseContext, log.Logger) ([]*update.ServiceUpdate, update.Result, error)
	ReleaseKind() update.ReleaseKind
	ReleaseType() update.ReleaseType
	CommitMessage() string
}

func Release(rc *ReleaseContext, changes Changes, logger log.Logger) (results update.Result, err error) {
	defer func(start time.Time) {
		update.ObserveRelease(
			start,
			err == nil,
			changes.ReleaseType(),
			changes.ReleaseKind(),
		)
	}(time.Now())

	logger = log.NewContext(logger).With("type", "release")

	updates, results, err := changes.CalculateRelease(rc, logger)
	if err != nil {
		return nil, err
	}

	err = ApplyChanges(rc, updates, logger)
	return results, err
}

func ApplyChanges(rc *ReleaseContext, updates []*update.ServiceUpdate, logger log.Logger) error {
	logger.Log("updates", len(updates))
	if len(updates) == 0 {
		logger.Log("exit", "no images to update for services given")
		return nil
	}

	timer := update.NewStageTimer("push_changes")
	err := rc.WriteUpdates(updates)
	timer.ObserveDuration()
	return err
}
<commit_msg>Change ApplyChanges stage timer to write_changes<commit_after>package release

import (
	"time"

	"github.com/go-kit/kit/log"

	"github.com/weaveworks/flux/update"
)

type Changes interface {
	CalculateRelease(update.ReleaseContext, log.Logger) ([]*update.ServiceUpdate, update.Result, error)
	ReleaseKind() update.ReleaseKind
	ReleaseType() update.ReleaseType
	CommitMessage() string
}

func Release(rc *ReleaseContext, changes Changes, logger log.Logger) (results update.Result, err error) {
	defer func(start time.Time) {
		update.ObserveRelease(
			start,
			err == nil,
			changes.ReleaseType(),
			changes.ReleaseKind(),
		)
	}(time.Now())

	logger = log.NewContext(logger).With("type", "release")

	updates, results, err := changes.CalculateRelease(rc, logger)
	if err != nil {
		return nil, err
	}

	err = ApplyChanges(rc, updates, logger)
	return results, err
}

func ApplyChanges(rc *ReleaseContext, updates []*update.ServiceUpdate, logger log.Logger) error {
	logger.Log("updates", len(updates))
	if len(updates) == 0 {
		logger.Log("exit", "no images to update for services given")
		return nil
	}

	timer := update.NewStageTimer("write_changes")
	err := rc.WriteUpdates(updates)
	timer.ObserveDuration()
	return err
}
<|endoftext|>


<commit_before>package sacloud

// IPv6Addr IPアドレス(IPv6)
type IPv6Addr struct {
	HostName  string     `json:",omitempty"` // ホスト名
	IPv6Addr  string     `json:",omitempty"` // IPv6アドレス
	Interface *Interface `json:",omitempty"` // インターフェース
	IPv6Net   *IPv6Net   `json:",omitempty"` // IPv6サブネット

}

// CreateNewIPv6Addr IPv6アドレス作成
func CreateNewIPv6Addr() *IPv6Addr {
	return &IPv6Addr{
		IPv6Net: &IPv6Net{
			Resource: &Resource{},
		},
	}
}
<commit_msg>Add IPv6Add functions<commit_after>package sacloud

// IPv6Addr IPアドレス(IPv6)
type IPv6Addr struct {
	HostName  string     `json:",omitempty"` // ホスト名
	IPv6Addr  string     `json:",omitempty"` // IPv6アドレス
	Interface *Interface `json:",omitempty"` // インターフェース
	IPv6Net   *IPv6Net   `json:",omitempty"` // IPv6サブネット

}

// GetIPv6NetID IPv6アドレスが所属するIPv6NetのIDを取得
func (a *IPv6Addr) GetIPv6NetID() int64 {
	if a.IPv6Net != nil {
		return a.IPv6Net.ID
	}
	return 0
}

// GetInternetID IPv6アドレスを所有するルータ+スイッチ(Internet)のIDを取得
func (a *IPv6Addr) GetInternetID() int64 {
	if a.IPv6Net != nil && a.IPv6Net.Switch != nil && a.IPv6Net.Switch.Internet != nil {
		return a.IPv6Net.Switch.Internet.ID
	}
	return 0
}

// CreateNewIPv6Addr IPv6アドレス作成
func CreateNewIPv6Addr() *IPv6Addr {
	return &IPv6Addr{
		IPv6Net: &IPv6Net{
			Resource: &Resource{},
		},
	}
}
<|endoftext|>


<commit_before>package hello

import (
    "fmt"
    "net/http"
    "time"
)

func init() {
    http.HandleFunc("/svg/month", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {

text := r.URL.Query().Get("text")
width := r.URL.Query().Get("width")
if width == "" {
   width = "300"
}

height := r.URL.Query().Get("height")
if height  == "" {
   height = "20"
}
dy := r.URL.Query().Get("dy")

if dy  == "" {
   dy = "-2.6em"
}

fill := r.URL.Query().Get("fill")

if fill  == "" {
   fill = "000000"
}

format := r.URL.Query().Get("format")

if format  == "" {
   format = "January 2006"
}

if text == "" {
   text = time.Now().Format(format)
} else {
   text = text + " " + time.Now().Format(format)
}
    w.Header().Set("Content-Type","image/svg+xml")

   output := fmt.Sprintf(`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  viewBox="0 0 %s %s">

    <text text-anchor="left"  style="font-family: Arial, Helvetica, Verdana" font-weight="bold" fill="#%s" dy='%s' font-size="ANY SIZE">%s</text>
</svg>`, width, height, fill, dy, text)

  //  w.Header().Set("Content-Length", fmt.Sprintf("%d",len(output)))
    fmt.Fprint(w, output)
}
<commit_msg>setup<commit_after>package hello

import (
	"fmt"
	"net/http"
	"time"
)

func init() {
	http.HandleFunc("/svg/month", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {

	text := r.URL.Query().Get("text")
	width := r.URL.Query().Get("width")
	if width == "" {
		width = "300"
	}

	height := r.URL.Query().Get("height")
	if height == "" {
		height = "20"
	}

	dx := r.URL.Query().Get("dx")

	if dx == "" {
		dx = "0"
	}

	dy := r.URL.Query().Get("dy")

	if dy == "" {
		dy = "-2.6em"
	}

	fill := r.URL.Query().Get("fill")

	if fill == "" {
		fill = "000000"
	}

	format := r.URL.Query().Get("format")

	if format == "" {
		format = "January 2006"
	}

	size := r.URL.Query().Get("size")

	if size == "" {
		size = "ANY SIZE"
	}

	if text == "" {
		text = time.Now().Format(format)
	} else {
		text = text + " " + time.Now().Format(format)
	}
	w.Header().Set("Content-Type", "image/svg+xml")

	output := fmt.Sprintf(`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  viewBox="0 0 %s %s">
    <text text-anchor="left"  style="font-family: Arial, Helvetica, Verdana" font-weight="bold" fill="#%s" dx='%s' dy='%s' font-size="%s">%s</text>
</svg>`, width, height, fill, dx, dy, size, text)

	//  w.Header().Set("Content-Length", fmt.Sprintf("%d",len(output)))
	fmt.Fprint(w, output)
}
<|endoftext|>


<commit_before><commit_msg>json-backend: cleanup<commit_after><|endoftext|>


<commit_before>package docker

import (
	"flag"
	"fmt"
	"github.com/dotcloud/docker/utils"
	"log"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"syscall"
)

// Setup networking
func setupNetworking(gw string) {
	if gw == "" {
		return
	}
	if _, err := ip("route", "add", "default", "via", gw); err != nil {
		log.Fatalf("Unable to set up networking: %v", err)
	}
}

// Setup working directory
func setupWorkingDirectory(workdir string) {
	if workdir == "" {
		return
	}
	if err := syscall.Chdir(workdir); err != nil {
		log.Fatalf("Unable to change dir to %v: %v", workdir, err)
	}
}

// Takes care of dropping privileges to the desired user
func changeUser(u string) {
	if u == "" {
		return
	}
	userent, err := utils.UserLookup(u)
	if err != nil {
		log.Fatalf("Unable to find user %v: %v", u, err)
	}

	uid, err := strconv.Atoi(userent.Uid)
	if err != nil {
		log.Fatalf("Invalid uid: %v", userent.Uid)
	}
	gid, err := strconv.Atoi(userent.Gid)
	if err != nil {
		log.Fatalf("Invalid gid: %v", userent.Gid)
	}

	if err := syscall.Setgid(gid); err != nil {
		log.Fatalf("setgid failed: %v", err)
	}
	if err := syscall.Setuid(uid); err != nil {
		log.Fatalf("setuid failed: %v", err)
	}
}

// Clear environment pollution introduced by lxc-start
func cleanupEnv(env ListOpts) {
	os.Clearenv()
	for _, kv := range env {
		parts := strings.SplitN(kv, "=", 2)
		if len(parts) == 1 {
			parts = append(parts, "")
		}
		os.Setenv(parts[0], parts[1])
	}
}

func executeProgram(name string, args []string) {
	path, err := exec.LookPath(name)
	if err != nil {
		log.Printf("Unable to locate %v", name)
		os.Exit(127)
	}

	if err := syscall.Exec(path, args, os.Environ()); err != nil {
		panic(err)
	}
}

// Sys Init code
// This code is run INSIDE the container and is responsible for setting
// up the environment before running the actual process
func SysInit() {
	if len(os.Args) <= 1 {
		fmt.Println("You should not invoke docker-init manually")
		os.Exit(1)
	}
	var u = flag.String("u", "", "username or uid")
	var gw = flag.String("g", "", "gateway address")
	var workdir = flag.String("w", "", "workdir")

	var flEnv ListOpts
	flag.Var(&flEnv, "e", "Set environment variables")

	flag.Parse()

	cleanupEnv(flEnv)
	setupNetworking(*gw)
	setupWorkingDirectory(*workdir)
	changeUser(*u)
	executeProgram(flag.Arg(0), flag.Args())
}
<commit_msg>Use netlink directly instead of /bin/ip in Sysinit<commit_after>package docker

import (
	"flag"
	"fmt"
	"github.com/dotcloud/docker/netlink"
	"github.com/dotcloud/docker/utils"
	"log"
	"net"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"syscall"
)

// Setup networking
func setupNetworking(gw string) {
	if gw == "" {
		return
	}

	ip := net.ParseIP(gw)
	if ip == nil {
		log.Fatalf("Unable to set up networking, %s is not a valid IP", gw)
		return
	}

	if err := netlink.AddDefaultGw(ip); err != nil {
		log.Fatalf("Unable to set up networking: %v", err)
	}
}

// Setup working directory
func setupWorkingDirectory(workdir string) {
	if workdir == "" {
		return
	}
	if err := syscall.Chdir(workdir); err != nil {
		log.Fatalf("Unable to change dir to %v: %v", workdir, err)
	}
}

// Takes care of dropping privileges to the desired user
func changeUser(u string) {
	if u == "" {
		return
	}
	userent, err := utils.UserLookup(u)
	if err != nil {
		log.Fatalf("Unable to find user %v: %v", u, err)
	}

	uid, err := strconv.Atoi(userent.Uid)
	if err != nil {
		log.Fatalf("Invalid uid: %v", userent.Uid)
	}
	gid, err := strconv.Atoi(userent.Gid)
	if err != nil {
		log.Fatalf("Invalid gid: %v", userent.Gid)
	}

	if err := syscall.Setgid(gid); err != nil {
		log.Fatalf("setgid failed: %v", err)
	}
	if err := syscall.Setuid(uid); err != nil {
		log.Fatalf("setuid failed: %v", err)
	}
}

// Clear environment pollution introduced by lxc-start
func cleanupEnv(env ListOpts) {
	os.Clearenv()
	for _, kv := range env {
		parts := strings.SplitN(kv, "=", 2)
		if len(parts) == 1 {
			parts = append(parts, "")
		}
		os.Setenv(parts[0], parts[1])
	}
}

func executeProgram(name string, args []string) {
	path, err := exec.LookPath(name)
	if err != nil {
		log.Printf("Unable to locate %v", name)
		os.Exit(127)
	}

	if err := syscall.Exec(path, args, os.Environ()); err != nil {
		panic(err)
	}
}

// Sys Init code
// This code is run INSIDE the container and is responsible for setting
// up the environment before running the actual process
func SysInit() {
	if len(os.Args) <= 1 {
		fmt.Println("You should not invoke docker-init manually")
		os.Exit(1)
	}
	var u = flag.String("u", "", "username or uid")
	var gw = flag.String("g", "", "gateway address")
	var workdir = flag.String("w", "", "workdir")

	var flEnv ListOpts
	flag.Var(&flEnv, "e", "Set environment variables")

	flag.Parse()

	cleanupEnv(flEnv)
	setupNetworking(*gw)
	setupWorkingDirectory(*workdir)
	changeUser(*u)
	executeProgram(flag.Arg(0), flag.Args())
}
<|endoftext|>


<commit_before>/*
Package systray is a cross platfrom Go library to place an icon and menu in the notification area.
Supports Windows and Mac OSX currently, Linux coming soon.
Methods can be called from any goroutine except Run(), which should be called at the very beginning of main() to lock at main thread.
*/
package systray

/*
#cgo linux pkg-config: gtk+-3.0 appindicator3-0.1
#cgo linux CFLAGS: -DLINUX -Wno-deprecated-declarations
#cgo windows CFLAGS: -DWIN32 -DUNICODE -D_UNICODE
#cgo darwin CFLAGS: -DDARWIN -x objective-c
#cgo darwin LDFLAGS: -framework Cocoa

#include "systray.h"
*/
import "C"
import (
	"runtime"
	"sync"
	"unsafe"
)

// MenuItem is used to keep track each menu item of systray
// Don't create it directly, use the one systray.AddMenuItem() returned
type MenuItem struct {
	// Id uniquely identify a menu item, not supposed to be modified
	Id string
	// Title is the text shows on menu item
	Title string
	// Tooltip is the text shows when point to menu item
	Tooltip string
	// Disabled menu item is gray out and has no effect when clicked
	Disabled bool
	// Checked menu item has a tick before title
	Checked bool

	// Ch is the channel which will be notified when menu item clicked
	Ch chan interface{}
}

var (
	readyCh       = make(chan interface{})
	clickedCh     = make(chan interface{})
	menuItems     = make(map[string]*MenuItem)
	menuItemsLock sync.RWMutex
)

// Run initializes GUI and starts event loop, then invoke the onReady callback.
// It blocks until systray.Quit() is called.
// Should be called at the very beginning of main() to lock at main thread.
func Run(onReady func()) {
	runtime.LockOSThread()
	go func() {
		<-readyCh
		onReady()
	}()

	C.nativeLoop()
}

// Quit the systray and whole app
func Quit() {
	C.quit()
}

// SetIcon sets the systray icon.
// iconBytes should be the content of .ico for windows and .png for other platforms.
func SetIcon(iconBytes []byte) {
	cstr := (*C.char)(unsafe.Pointer(&iconBytes[0]))
	C.setIcon(cstr, (C.int)(len(iconBytes)))
}

// SetTitle sets the systray title, only available on Mac.
func SetTitle(title string) {
	C.setTitle(C.CString(title))
}

// SetTitle sets the systray tooltip after the mouse stayed on tray icon for a while, only available on Mac.
func SetTooltip(tooltip string) {
	C.setTooltip(C.CString(tooltip))
}

// Add menu item with designated title and tooltip, returning a channel that
// notifies whenever that menu item has been clicked.
//
// Menu items are keyed to an id. If the same id is added twice, the 2nd one
// overwrites the first.
//
// AddMenuItem can be safely invoked from different goroutines.
func AddMenuItem(id string, title string, tooltip string) *MenuItem {
	item := &MenuItem{id, title, tooltip, false, false, nil}
	item.Ch = make(chan interface{})
	Update(item)
	return item
}

// Update propogates changes on a menu item to systray
func Update(item *MenuItem) {
	menuItemsLock.Lock()
	defer menuItemsLock.Unlock()
	menuItems[item.Id] = item
	var disabled C.short = 0
	if item.Disabled {
		disabled = 1
	}
	var checked C.short = 0
	if item.Checked {
		checked = 1
	}
	C.add_or_update_menu_item(
		C.CString(item.Id),
		C.CString(item.Title),
		C.CString(item.Tooltip),
		disabled,
		checked,
	)
}

//export systray_ready
func systray_ready() {
	readyCh <- nil
}

//export systray_menu_item_selected
func systray_menu_item_selected(cId *C.char) {
	id := C.GoString(cId)
	menuItemsLock.RLock()
	item := menuItems[id]
	menuItemsLock.RUnlock()
	select {
	case item.Ch <- nil:
	// in case no one waiting for the channel
	default:
	}
}
<commit_msg>getlantern/lantern#2143 Comment tweaks<commit_after>/*
Package systray is a cross platfrom Go library to place an icon and menu in the notification area.
Supports Windows and Mac OSX currently, Linux coming soon.
Methods can be called from any goroutine except Run(), which should be called at the very beginning of main() to lock at main thread.
*/
package systray

/*
#cgo linux pkg-config: gtk+-3.0 appindicator3-0.1
#cgo linux CFLAGS: -DLINUX -Wno-deprecated-declarations
#cgo windows CFLAGS: -DWIN32 -DUNICODE -D_UNICODE
#cgo darwin CFLAGS: -DDARWIN -x objective-c
#cgo darwin LDFLAGS: -framework Cocoa

#include "systray.h"
*/
import "C"
import (
	"runtime"
	"sync"
	"unsafe"
)

// MenuItem is used to keep track each menu item of systray
// Don't create it directly, use the one systray.AddMenuItem() returned
type MenuItem struct {
	// Id uniquely identify a menu item, not supposed to be modified
	Id string
	// Title is the text shown on menu item
	Title string
	// Tooltip is the text shown when pointing to menu item
	Tooltip string
	// Disabled menu item is grayed out and has no effect when clicked
	Disabled bool
	// Checked menu item has a tick before the title
	Checked bool

	// Ch is the channel which will be notified when the menu item is clicked
	Ch chan interface{}
}

var (
	readyCh       = make(chan interface{})
	clickedCh     = make(chan interface{})
	menuItems     = make(map[string]*MenuItem)
	menuItemsLock sync.RWMutex
)

// Run initializes GUI and starts the event loop, then invokes the onReady
// callback.
// It blocks until systray.Quit() is called.
// Should be called at the very beginning of main() to lock at main thread.
func Run(onReady func()) {
	runtime.LockOSThread()
	go func() {
		<-readyCh
		onReady()
	}()

	C.nativeLoop()
}

// Quit the systray and whole app
func Quit() {
	C.quit()
}

// SetIcon sets the systray icon.
// iconBytes should be the content of .ico for windows and .png for other
// platforms.
func SetIcon(iconBytes []byte) {
	cstr := (*C.char)(unsafe.Pointer(&iconBytes[0]))
	C.setIcon(cstr, (C.int)(len(iconBytes)))
}

// SetTitle sets the systray title, only available on Mac.
func SetTitle(title string) {
	C.setTitle(C.CString(title))
}

// SetTitle sets the systray tooltip to display on mouse hover of the tray icon,
// only available on Mac.
func SetTooltip(tooltip string) {
	C.setTooltip(C.CString(tooltip))
}

// Add menu item with designated title and tooltip, returning a channel that
// notifies whenever that menu item has been clicked.
//
// Menu items are keyed to an id. If the same id is added twice, the 2nd one
// overwrites the first.
//
// AddMenuItem can be safely invoked from different goroutines.
func AddMenuItem(id string, title string, tooltip string) *MenuItem {
	item := &MenuItem{id, title, tooltip, false, false, nil}
	item.Ch = make(chan interface{})
	Update(item)
	return item
}

// Update propogates changes on a menu item to systray
func Update(item *MenuItem) {
	menuItemsLock.Lock()
	defer menuItemsLock.Unlock()
	menuItems[item.Id] = item
	var disabled C.short = 0
	if item.Disabled {
		disabled = 1
	}
	var checked C.short = 0
	if item.Checked {
		checked = 1
	}
	C.add_or_update_menu_item(
		C.CString(item.Id),
		C.CString(item.Title),
		C.CString(item.Tooltip),
		disabled,
		checked,
	)
}

//export systray_ready
func systray_ready() {
	readyCh <- nil
}

//export systray_menu_item_selected
func systray_menu_item_selected(cId *C.char) {
	id := C.GoString(cId)
	menuItemsLock.RLock()
	item := menuItems[id]
	menuItemsLock.RUnlock()
	select {
	case item.Ch <- nil:
	// in case no one waiting for the channel
	default:
	}
}
<|endoftext|>


<commit_before>package application

import (
	"errors"
	"fmt"
	"time"

	"github.com/bjyoungblood/gozw/zwave/command-class"
	"github.com/bjyoungblood/gozw/zwave/protocol"
	"github.com/bjyoungblood/gozw/zwave/security"
	"github.com/bjyoungblood/gozw/zwave/serial-api"
	"github.com/boltdb/bolt"
	"github.com/davecgh/go-spew/spew"
)

// @todo should probably be 60 seconds, but 30 is easier for dev
const MaxSecureInclusionDuration = time.Second * 30

// Note: always use the smallest size based on the options
// @todo: also, implement the ability to use different options
const (
	SecurePayloadMaxSizeExplore   = 26 // in bytes
	SecurePayloadMaxSizeAutoRoute = 28
	SecurePayloadMaxSizeNoRoute   = 34
)

const (
	SecuritySequenceSequencedFlag   byte = 0x10
	SecuritySequenceSecondFrameFlag      = 0x20
	SecuritySequenceCounterMask          = 0x0f
)

type ApplicationLayer struct {
	ApiVersion     string
	ApiLibraryType string

	HomeId uint32
	NodeId byte

	Version             byte
	ApiType             string
	IsPrimaryController bool
	ApplicationVersion  byte
	ApplicationRevision byte
	SupportedFunctions  []byte

	NodeList []byte

	serialApi     serialapi.ISerialAPILayer
	securityLayer security.ISecurityLayer
	nodes         map[byte]*Node

	db *bolt.DB

	// maps node id to channel
	secureInclusionStep map[byte]chan error
}

func NewApplicationLayer(serialApi serialapi.ISerialAPILayer) (app *ApplicationLayer, err error) {
	app = &ApplicationLayer{
		serialApi:     serialApi,
		securityLayer: security.NewSecurityLayer(),
		nodes:         map[byte]*Node{},

		secureInclusionStep: map[byte]chan error{},
	}

	err = app.initDb()
	if err != nil {
		return
	}

	go app.handleApplicationCommands()
	go app.handleControllerUpdates()

	err = app.initZWave()

	return
}

func (a *ApplicationLayer) Nodes() map[byte]*Node {
	return a.nodes
}

func (a *ApplicationLayer) Node(nodeId byte) (*Node, error) {
	if node, ok := a.nodes[nodeId]; ok {
		return node, nil
	}

	return nil, errors.New("Node not found")
}

func (a *ApplicationLayer) initDb() (err error) {
	a.db, err = bolt.Open("data.db", 0600, &bolt.Options{})
	if err != nil {
		return
	}

	a.db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists([]byte("nodes"))
		if err != nil {
			return err
		}

		return nil
	})

	return nil
}

func (a *ApplicationLayer) initZWave() error {
	version, err := a.serialApi.GetVersion()
	if err != nil {
		return err
	}

	a.ApiVersion = version.Version
	a.ApiLibraryType = version.GetLibraryTypeString()

	a.HomeId, a.NodeId, err = a.serialApi.MemoryGetId()
	if err != nil {
		return err
	}

	serialApiCapabilities, err := a.serialApi.GetSerialApiCapabilities()
	if err != nil {
		return err
	}

	a.ApplicationVersion = serialApiCapabilities.ApplicationVersion
	a.ApplicationRevision = serialApiCapabilities.ApplicationRevision
	a.SupportedFunctions = serialApiCapabilities.GetSupportedFunctions()

	initData, err := a.serialApi.GetInitAppData()
	if err != nil {
		return err
	}

	a.Version = initData.Version
	a.ApiType = initData.GetApiType()
	a.IsPrimaryController = initData.IsPrimaryController()
	a.NodeList = initData.GetNodeIds()

	for _, nodeId := range a.NodeList {
		node, err := NewNodeFromDb(a, nodeId)
		if err == nil {
			a.nodes[nodeId] = node
			continue
		}

		spew.Dump(err)

		a.nodes[nodeId] = NewNode(a, nodeId)
		a.nodes[nodeId].initialize()

		if nodeId == 52 {
			a.nodes[nodeId].RequestSupportedSecurityCommands()
		}
	}

	return nil
}

func (a *ApplicationLayer) Shutdown() error {
	return a.db.Close()
}

func (a *ApplicationLayer) AddNode() error {
	newNodeInfo, err := a.serialApi.AddNode()
	if err != nil {
		return err
	}

	node := NewNode(a, newNodeInfo.Source)
	node.setFromAddNodeCallback(newNodeInfo)
	a.nodes[node.NodeId] = node

	if node.IsSecure() {
		fmt.Println("Starting secure inclusion")
		err = a.includeSecureNode(node.NodeId)
		if err != nil {
			return err
		}

		time.Sleep(time.Millisecond * 50)
		err := node.RequestSupportedSecurityCommands()
		if err != nil {
			fmt.Println(err)
		}

		select {
		case <-node.receivedSecurityInfo:
		case <-time.After(time.Second * 5):
			fmt.Println("timed out after requesting security commands")
		}
	}

	spew.Dump(node)

	node.AddAssociation(1, 1)

	return nil
}

func (a *ApplicationLayer) RemoveNode() error {
	result, err := a.serialApi.RemoveNode()

	if err != nil {
		return err
	}

	return a.db.Update(func(tx *bolt.Tx) error {
		return tx.Bucket([]byte("nodes")).Delete([]byte{result.Source})
	})
}

func (a *ApplicationLayer) RemoveFailedNode(nodeId byte) (ok bool, err error) {
	ok, err = a.serialApi.RemoveFailedNode(nodeId)

	if ok && err != nil {
		err = a.db.Update(func(tx *bolt.Tx) error {
			return tx.Bucket([]byte("nodes")).Delete([]byte{nodeId})
		})
	}

	return
}

func (a *ApplicationLayer) handleApplicationCommands() {
	for cmd := range a.serialApi.ControllerCommands() {
		switch cmd.CommandData[0] {

		case commandclass.CommandClassSecurity:
			a.handleSecurityCommand(cmd)

		default:
			if node, err := a.Node(cmd.SrcNodeId); err == nil {
				go node.receiveApplicationCommand(cmd)
			} else {
				fmt.Println("Received command for unknown node", cmd.SrcNodeId)
			}

		}

	}
}

func (a *ApplicationLayer) handleControllerUpdates() {
	for update := range a.serialApi.ControllerUpdates() {

		switch update.Status {

		case protocol.UpdateStateNodeInfoReceived,
			protocol.UpdateStateNodeInfoReqFailed:
			if node, ok := a.nodes[update.NodeId]; ok {
				node.receiveControllerUpdate(update)
			} else {
				fmt.Println("controller update:", spew.Sdump(update))
			}

		default:
			fmt.Println("controller update:", spew.Sdump(update))

		}

	}
}

func (a *ApplicationLayer) SendData(dstNode byte, payload []byte) error {
	_, err := a.serialApi.SendData(dstNode, payload)
	return err
}

// SendDataSecure encapsulates payload in a security encapsulation command and
// sends it to the destination node.
func (a *ApplicationLayer) SendDataSecure(dstNode byte, payload []byte) error {
	// This function wraps the private sendDataSecure because no external packages
	// should ever call this while in inclusion mode (and doing so would be incorrect)
	return a.sendDataSecure(dstNode, payload, false)
}

func (a *ApplicationLayer) sendDataSecure(dstNode byte, payload []byte, inclusionMode bool) error {
	// Previously, this function would just split and prepare the payload based on
	// whether it should be split after figuring out whether to segment. For now,
	// we're just going to assume that we will never have to worry about segmenting.
	// It wasn't too hard to implement before, but since I couldn't find a real payload
	// big enough, it wasn't possible to verify the implementation, so I didn't port
	// it while refactoring (for simplicity's sake).

	// Get a nonce from the other node
	receiverNonce, err := a.securityLayer.GetExternalNonce(dstNode)
	if err != nil {
		fmt.Println("requesting nonce")
		a.SendData(dstNode, commandclass.NewSecurityNonceGet())
		receiverNonce, err = a.securityLayer.WaitForExternalNonce(dstNode)
		fmt.Println("got nonce")

		if err != nil {
			fmt.Println("error getting nonce", err)
			return err
		}
	}

	senderNonce, err := a.securityLayer.GenerateInternalNonce()
	if err != nil {
		return err
	}

	var securityByte byte = 0
	// var securityByte byte = sequenceCounter & SecuritySequenceCounterMask
	// if sequenced {
	// 	securityByte |= SecuritySequenceSequencedFlag
	//
	// 	if isSecondFrame {
	// 		securityByte |= SecuritySequenceSecondFrameFlag
	// 	}
	// }

	securePayload := append([]byte{securityByte}, payload...)

	encapsulatedMessage := a.securityLayer.EncapsulateMessage(
		securePayload,
		senderNonce,
		receiverNonce,
		1,
		dstNode,
		inclusionMode,
	)

	return a.SendData(dstNode, encapsulatedMessage)
}

func (a *ApplicationLayer) includeSecureNode(nodeId byte) error {
	a.secureInclusionStep[nodeId] = make(chan error)
	a.SendData(nodeId, commandclass.NewSecuritySchemeGet())

	defer close(a.secureInclusionStep[nodeId])
	defer delete(a.secureInclusionStep, nodeId)

	select {
	case err := <-a.secureInclusionStep[nodeId]:
		if err != nil {
			return err
		}
	case <-time.After(time.Second * 10):
		return errors.New("Secure inclusion timeout")
	}

	a.sendDataSecure(
		nodeId,
		commandclass.NewSecurityNetworkKeySet(security.NetworkKey), // @todo
		true,
	)

	select {
	case err := <-a.secureInclusionStep[nodeId]:
		return err
	case <-time.After(time.Second * 20):
		return errors.New("Secure inclusion timeout")
	}
}

func (a *ApplicationLayer) handleSecurityCommand(cmd serialapi.ApplicationCommand) {
	switch cmd.CommandData[1] {

	case commandclass.CommandSecurityMessageEncapsulation, commandclass.CommandSecurityMessageEncapsulationNonceGet:
		// @todo determine whether to bother with sequenced messages. According to
		// openzwave, they didn't bother to implement it because they never ran across
		// a situation where a frame was large enough that it needed to be sequenced.
		// in any case, the following is the following is the process to follow with
		// or without sequencing:

		// 1. decrypt message
		// 2. if it's the first half of a sequenced message, wait for the second half
		// 2.5  if it's an EncapsulationGetNonce, then send a NonceReport back to the sender
		// 3. if it's the second half of a sequenced message, reassemble the payloads
		// 4. emit the decrypted (possibly recombined) message back

		data := commandclass.ParseSecurityMessageEncapsulation(cmd.CommandData)
		msg, err := a.securityLayer.DecryptMessage(data)

		if err != nil {
			fmt.Println("error handling encrypted message", err)
			return
		}

		if msg[0] == commandclass.CommandClassSecurity && msg[1] == commandclass.CommandNetworkKeyVerify {
			if ch, ok := a.secureInclusionStep[cmd.SrcNodeId]; ok {
				ch <- nil
			}
			return
		}

		if node, ok := a.nodes[cmd.SrcNodeId]; ok {
			cmd.CommandData = msg
			go node.receiveApplicationCommand(cmd)
		} else {
			fmt.Println("Received secure command for unknown node", cmd.SrcNodeId)
		}

	case commandclass.CommandSecurityNonceGet:
		nonce, err := a.securityLayer.GenerateInternalNonce()
		if err != nil {
			fmt.Println("error generating internal nonce", err)
		}

		reply := commandclass.NewSecurityNonceReport(nonce)
		a.SendData(cmd.SrcNodeId, reply)

	case commandclass.CommandSecurityNonceReport:
		nonceReport := commandclass.ParseSecurityNonceReport(cmd.CommandData)
		a.securityLayer.ReceiveNonce(cmd.SrcNodeId, nonceReport)

	case commandclass.CommandSecuritySchemeReport:
		if ch, ok := a.secureInclusionStep[cmd.SrcNodeId]; ok {
			ch <- nil
		}

	default:
		fmt.Println("Unexpected security command:", spew.Sdump(cmd))
	}
}
<commit_msg>Requesting nonce from node allows retries<commit_after>package application

import (
	"errors"
	"fmt"
	"time"

	"github.com/bjyoungblood/gozw/zwave/command-class"
	"github.com/bjyoungblood/gozw/zwave/protocol"
	"github.com/bjyoungblood/gozw/zwave/security"
	"github.com/bjyoungblood/gozw/zwave/serial-api"
	"github.com/boltdb/bolt"
	"github.com/davecgh/go-spew/spew"
)

// @todo should probably be 60 seconds, but 30 is easier for dev
const MaxSecureInclusionDuration = time.Second * 30

// Note: always use the smallest size based on the options
// @todo: also, implement the ability to use different options
const (
	SecurePayloadMaxSizeExplore   = 26 // in bytes
	SecurePayloadMaxSizeAutoRoute = 28
	SecurePayloadMaxSizeNoRoute   = 34
)

const (
	SecuritySequenceSequencedFlag   byte = 0x10
	SecuritySequenceSecondFrameFlag      = 0x20
	SecuritySequenceCounterMask          = 0x0f
)

type ApplicationLayer struct {
	ApiVersion     string
	ApiLibraryType string

	HomeId uint32
	NodeId byte

	Version             byte
	ApiType             string
	IsPrimaryController bool
	ApplicationVersion  byte
	ApplicationRevision byte
	SupportedFunctions  []byte

	NodeList []byte

	serialApi     serialapi.ISerialAPILayer
	securityLayer security.ISecurityLayer
	nodes         map[byte]*Node

	db *bolt.DB

	// maps node id to channel
	secureInclusionStep map[byte]chan error
}

func NewApplicationLayer(serialApi serialapi.ISerialAPILayer) (app *ApplicationLayer, err error) {
	app = &ApplicationLayer{
		serialApi:     serialApi,
		securityLayer: security.NewSecurityLayer(),
		nodes:         map[byte]*Node{},

		secureInclusionStep: map[byte]chan error{},
	}

	err = app.initDb()
	if err != nil {
		return
	}

	go app.handleApplicationCommands()
	go app.handleControllerUpdates()

	err = app.initZWave()

	return
}

func (a *ApplicationLayer) Nodes() map[byte]*Node {
	return a.nodes
}

func (a *ApplicationLayer) Node(nodeId byte) (*Node, error) {
	if node, ok := a.nodes[nodeId]; ok {
		return node, nil
	}

	return nil, errors.New("Node not found")
}

func (a *ApplicationLayer) initDb() (err error) {
	a.db, err = bolt.Open("data.db", 0600, &bolt.Options{})
	if err != nil {
		return
	}

	a.db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists([]byte("nodes"))
		if err != nil {
			return err
		}

		return nil
	})

	return nil
}

func (a *ApplicationLayer) initZWave() error {
	version, err := a.serialApi.GetVersion()
	if err != nil {
		return err
	}

	a.ApiVersion = version.Version
	a.ApiLibraryType = version.GetLibraryTypeString()

	a.HomeId, a.NodeId, err = a.serialApi.MemoryGetId()
	if err != nil {
		return err
	}

	serialApiCapabilities, err := a.serialApi.GetSerialApiCapabilities()
	if err != nil {
		return err
	}

	a.ApplicationVersion = serialApiCapabilities.ApplicationVersion
	a.ApplicationRevision = serialApiCapabilities.ApplicationRevision
	a.SupportedFunctions = serialApiCapabilities.GetSupportedFunctions()

	initData, err := a.serialApi.GetInitAppData()
	if err != nil {
		return err
	}

	a.Version = initData.Version
	a.ApiType = initData.GetApiType()
	a.IsPrimaryController = initData.IsPrimaryController()
	a.NodeList = initData.GetNodeIds()

	for _, nodeId := range a.NodeList {
		node, err := NewNodeFromDb(a, nodeId)
		if err == nil {
			a.nodes[nodeId] = node
			continue
		}

		spew.Dump(err)

		a.nodes[nodeId] = NewNode(a, nodeId)
		a.nodes[nodeId].initialize()

		if nodeId == 52 {
			a.nodes[nodeId].RequestSupportedSecurityCommands()
		}
	}

	return nil
}

func (a *ApplicationLayer) Shutdown() error {
	return a.db.Close()
}

func (a *ApplicationLayer) AddNode() error {
	newNodeInfo, err := a.serialApi.AddNode()
	if err != nil {
		return err
	}

	node := NewNode(a, newNodeInfo.Source)
	node.setFromAddNodeCallback(newNodeInfo)
	a.nodes[node.NodeId] = node

	if node.IsSecure() {
		fmt.Println("Starting secure inclusion")
		err = a.includeSecureNode(node.NodeId)
		if err != nil {
			return err
		}

		time.Sleep(time.Millisecond * 50)
		err := node.RequestSupportedSecurityCommands()
		if err != nil {
			fmt.Println(err)
		}

		select {
		case <-node.receivedSecurityInfo:
		case <-time.After(time.Second * 5):
			fmt.Println("timed out after requesting security commands")
		}
	}

	spew.Dump(node)

	node.AddAssociation(1, 1)

	return nil
}

func (a *ApplicationLayer) RemoveNode() error {
	result, err := a.serialApi.RemoveNode()

	if err != nil {
		return err
	}

	return a.db.Update(func(tx *bolt.Tx) error {
		return tx.Bucket([]byte("nodes")).Delete([]byte{result.Source})
	})
}

func (a *ApplicationLayer) RemoveFailedNode(nodeId byte) (ok bool, err error) {
	ok, err = a.serialApi.RemoveFailedNode(nodeId)

	if ok && err != nil {
		err = a.db.Update(func(tx *bolt.Tx) error {
			return tx.Bucket([]byte("nodes")).Delete([]byte{nodeId})
		})
	}

	return
}

func (a *ApplicationLayer) handleApplicationCommands() {
	for cmd := range a.serialApi.ControllerCommands() {
		switch cmd.CommandData[0] {

		case commandclass.CommandClassSecurity:
			a.handleSecurityCommand(cmd)

		default:
			if node, err := a.Node(cmd.SrcNodeId); err == nil {
				go node.receiveApplicationCommand(cmd)
			} else {
				fmt.Println("Received command for unknown node", cmd.SrcNodeId)
			}

		}

	}
}

func (a *ApplicationLayer) handleControllerUpdates() {
	for update := range a.serialApi.ControllerUpdates() {

		switch update.Status {

		case protocol.UpdateStateNodeInfoReceived,
			protocol.UpdateStateNodeInfoReqFailed:
			if node, ok := a.nodes[update.NodeId]; ok {
				node.receiveControllerUpdate(update)
			} else {
				fmt.Println("controller update:", spew.Sdump(update))
			}

		default:
			fmt.Println("controller update:", spew.Sdump(update))

		}

	}
}

func (a *ApplicationLayer) SendData(dstNode byte, payload []byte) error {
	_, err := a.serialApi.SendData(dstNode, payload)
	return err
}

// SendDataSecure encapsulates payload in a security encapsulation command and
// sends it to the destination node.
func (a *ApplicationLayer) SendDataSecure(dstNode byte, payload []byte) error {
	// This function wraps the private sendDataSecure because no external packages
	// should ever call this while in inclusion mode (and doing so would be incorrect)
	return a.sendDataSecure(dstNode, payload, false)
}

func (a *ApplicationLayer) requestNonceForNode(dstNode byte) (security.Nonce, error) {
	err := a.SendData(dstNode, commandclass.NewSecurityNonceGet())

	if err != nil {
		return nil, err
	}

	return a.securityLayer.WaitForExternalNonce(dstNode)
}

func (a *ApplicationLayer) getOrRequestNonceForNode(dstNode byte) (nonce security.Nonce, err error) {
	if nonce, err = a.securityLayer.GetExternalNonce(dstNode); err == nil {
		return nonce, nil
	}

	for i := 0; i < 3; i++ {
		nonce, err = a.requestNonceForNode(dstNode)
		if err == nil {
			break
		}

		fmt.Printf("get nonce attempt #%d failed\n", i)
		time.Sleep(50 * time.Millisecond)
	}

	return nonce, err
}

func (a *ApplicationLayer) sendDataSecure(dstNode byte, payload []byte, inclusionMode bool) error {
	// Previously, this function would just split and prepare the payload based on
	// whether it should be split after figuring out whether to segment. For now,
	// we're just going to assume that we will never have to worry about segmenting.
	// It wasn't too hard to implement before, but since I couldn't find a real payload
	// big enough, it wasn't possible to verify the implementation, so I didn't port
	// it while refactoring (for simplicity's sake).

	// Get a nonce from the other node
	receiverNonce, err := a.getOrRequestNonceForNode(dstNode)
	if err != nil {
		return err
	}

	senderNonce, err := a.securityLayer.GenerateInternalNonce()
	if err != nil {
		return err
	}

	var securityByte byte = 0
	// var securityByte byte = sequenceCounter & SecuritySequenceCounterMask
	// if sequenced {
	// 	securityByte |= SecuritySequenceSequencedFlag
	//
	// 	if isSecondFrame {
	// 		securityByte |= SecuritySequenceSecondFrameFlag
	// 	}
	// }

	securePayload := append([]byte{securityByte}, payload...)

	encapsulatedMessage := a.securityLayer.EncapsulateMessage(
		securePayload,
		senderNonce,
		receiverNonce,
		1,
		dstNode,
		inclusionMode,
	)

	return a.SendData(dstNode, encapsulatedMessage)
}

func (a *ApplicationLayer) includeSecureNode(nodeId byte) error {
	a.secureInclusionStep[nodeId] = make(chan error)
	a.SendData(nodeId, commandclass.NewSecuritySchemeGet())

	defer close(a.secureInclusionStep[nodeId])
	defer delete(a.secureInclusionStep, nodeId)

	select {
	case err := <-a.secureInclusionStep[nodeId]:
		if err != nil {
			return err
		}
	case <-time.After(time.Second * 10):
		return errors.New("Secure inclusion timeout")
	}

	a.sendDataSecure(
		nodeId,
		commandclass.NewSecurityNetworkKeySet(security.NetworkKey), // @todo
		true,
	)

	select {
	case err := <-a.secureInclusionStep[nodeId]:
		return err
	case <-time.After(time.Second * 20):
		return errors.New("Secure inclusion timeout")
	}
}

func (a *ApplicationLayer) handleSecurityCommand(cmd serialapi.ApplicationCommand) {
	switch cmd.CommandData[1] {

	case commandclass.CommandSecurityMessageEncapsulation, commandclass.CommandSecurityMessageEncapsulationNonceGet:
		// @todo determine whether to bother with sequenced messages. According to
		// openzwave, they didn't bother to implement it because they never ran across
		// a situation where a frame was large enough that it needed to be sequenced.
		// in any case, the following is the following is the process to follow with
		// or without sequencing:

		// 1. decrypt message
		// 2. if it's the first half of a sequenced message, wait for the second half
		// 2.5  if it's an EncapsulationGetNonce, then send a NonceReport back to the sender
		// 3. if it's the second half of a sequenced message, reassemble the payloads
		// 4. emit the decrypted (possibly recombined) message back

		data := commandclass.ParseSecurityMessageEncapsulation(cmd.CommandData)
		msg, err := a.securityLayer.DecryptMessage(data)

		if err != nil {
			fmt.Println("error handling encrypted message", err)
			return
		}

		if msg[0] == commandclass.CommandClassSecurity && msg[1] == commandclass.CommandNetworkKeyVerify {
			if ch, ok := a.secureInclusionStep[cmd.SrcNodeId]; ok {
				ch <- nil
			}
			return
		}

		if node, ok := a.nodes[cmd.SrcNodeId]; ok {
			cmd.CommandData = msg
			go node.receiveApplicationCommand(cmd)
		} else {
			fmt.Println("Received secure command for unknown node", cmd.SrcNodeId)
		}

	case commandclass.CommandSecurityNonceGet:
		nonce, err := a.securityLayer.GenerateInternalNonce()
		if err != nil {
			fmt.Println("error generating internal nonce", err)
		}

		reply := commandclass.NewSecurityNonceReport(nonce)
		a.SendData(cmd.SrcNodeId, reply)

	case commandclass.CommandSecurityNonceReport:
		nonceReport := commandclass.ParseSecurityNonceReport(cmd.CommandData)
		a.securityLayer.ReceiveNonce(cmd.SrcNodeId, nonceReport)

	case commandclass.CommandSecuritySchemeReport:
		if ch, ok := a.secureInclusionStep[cmd.SrcNodeId]; ok {
			ch <- nil
		}

	default:
		fmt.Println("Unexpected security command:", spew.Sdump(cmd))
	}
}
<|endoftext|>


<commit_before>package schyntax

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"os"
	"testing"
	"time"

	"github.com/schyntax/go-schyntax/internals"
)

type testsData struct {
	TestsVersion int
	Hash         string
	Suites       map[string][]*check
}

type check struct {
	Format          string
	Date            time.Time
	Prev            *time.Time
	Next            *time.Time
	ParseErrorIndex *int
}

var tests testsData

func TestMain(m *testing.M) {

	file, err := ioutil.ReadFile("tests.json")
	if err != nil {
		log.Fatal(err)
	}

	if err = json.Unmarshal(file, &tests); err != nil {
		log.Fatal(err)
	}

	os.Exit(m.Run())
}

func TestSuites(t *testing.T) {
	for name, checks := range tests.Suites {
		t.Logf("-----SUITE %s-----", name)
		for _, check := range checks {
			runTest(t, check)
		}
	}
}

func runTest(t *testing.T, check *check) {
	t.Log(`Testing "` + check.Format + `" - Start ` + check.Date.String())

	sch, err := New(check.Format)
	if err != nil {
		if check.ParseErrorIndex != nil {
			// we were expecting an error
			if parseError, ok := err.(*internals.ParseError); ok {
				if parseError.Index() == *check.ParseErrorIndex {
					t.Log("Expected Parse Error ✓")
				} else {
					t.Errorf("Wrong parse error index. Expected: %d. Actual: %d.\n", *check.ParseErrorIndex, parseError.Error())
				}

				return
			}
		}

		t.Error(err)
		return
	}

	if check.ParseErrorIndex != nil {
		t.Errorf("Expected a parse error at index %d, but no error was thrown.", *check.ParseErrorIndex)
		return
	}

	prev, pErr := sch.PreviousAtOrBefore(check.Date)

	if pErr != nil {
		if _, ok := pErr.(*ValidTimeNotFoundError); ok && check.Prev == nil {
			t.Log("Prev ✓ (ValidTimeNotFoundError)")
		} else {
			t.Error(pErr)
		}
	} else if check.Prev == nil {
		t.Error("Expected a ValidTimeNotFoundError. Date returned from previous: " + prev.String())
	} else if !prev.Equal(*check.Prev) {
		t.Error("Expected: " + check.Prev.String() + ", Actual: " + prev.String())
	} else {
		t.Log("Prev ✓")
	}

	next, nErr := sch.NextAfter(check.Date)

	if nErr != nil {
		if _, ok := nErr.(*ValidTimeNotFoundError); ok && check.Next == nil {
			t.Log("Prev ✓ (ValidTimeNotFoundError)")
		} else {
			t.Error(nErr)
		}
	} else if check.Next == nil {
		t.Error("Expected a ValidTimeNotFoundError. Date returned from next: " + next.String())
	} else if !next.Equal(*check.Next) {
		t.Error("Expected: " + check.Next.String() + ", Actual: " + next.String())
	} else {
		t.Log("Next ✓")
	}

}
<commit_msg>Reduce tests output<commit_after>package schyntax

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"os"
	"testing"
	"time"

	"github.com/schyntax/go-schyntax/internals"
)

type testsData struct {
	TestsVersion int
	Hash         string
	Suites       map[string][]*check
}

type check struct {
	Format          string
	Date            time.Time
	Prev            *time.Time
	Next            *time.Time
	ParseErrorIndex *int
}

var tests testsData

func TestMain(m *testing.M) {

	file, err := ioutil.ReadFile("tests.json")
	if err != nil {
		log.Fatal(err)
	}

	if err = json.Unmarshal(file, &tests); err != nil {
		log.Fatal(err)
	}

	os.Exit(m.Run())
}

func TestSuites(t *testing.T) {
	for name, checks := range tests.Suites {
		t.Logf("-----SUITE %s-----", name)
		for _, check := range checks {
			runTest(t, check)
		}
	}
}

func runTest(t *testing.T, check *check) {
	t.Log(`Testing "` + check.Format + `" - Start ` + check.Date.String())

	sch, err := New(check.Format)
	if err != nil {
		if check.ParseErrorIndex != nil {
			// we were expecting an error
			if parseError, ok := err.(*internals.ParseError); ok {
				if parseError.Index() == *check.ParseErrorIndex {
					logNonVerbose(t, "Expected Parse Error ✓")
				} else {
					t.Errorf("Wrong parse error index. Expected: %d. Actual: %d.\n", *check.ParseErrorIndex, parseError.Error())
				}
				return
			}
		}

		t.Error(err)
		return
	}

	if check.ParseErrorIndex != nil {
		t.Errorf("Expected a parse error at index %d, but no error was thrown.", *check.ParseErrorIndex)
		return
	}

	prev, pErr := sch.PreviousAtOrBefore(check.Date)

	if pErr != nil {
		if _, ok := pErr.(*ValidTimeNotFoundError); ok && check.Prev == nil {
			logNonVerbose(t, "Prev ✓ (ValidTimeNotFoundError)")
		} else {
			t.Error(pErr)
		}
	} else if check.Prev == nil {
		t.Error("Expected a ValidTimeNotFoundError. Date returned from previous: " + prev.String())
	} else if !prev.Equal(*check.Prev) {
		t.Error("Expected: " + check.Prev.String() + ", Actual: " + prev.String())
	} else {
		logNonVerbose(t, "Prev ✓")
	}

	next, nErr := sch.NextAfter(check.Date)

	if nErr != nil {
		if _, ok := nErr.(*ValidTimeNotFoundError); ok && check.Next == nil {
			logNonVerbose(t, "Prev ✓ (ValidTimeNotFoundError)")
		} else {
			t.Error(nErr)
		}
	} else if check.Next == nil {
		t.Error("Expected a ValidTimeNotFoundError. Date returned from next: " + next.String())
	} else if !next.Equal(*check.Next) {
		t.Error("Expected: " + check.Next.String() + ", Actual: " + next.String())
	} else {
		logNonVerbose(t, "Next ✓")
	}

}

func logNonVerbose(t *testing.T, msg string) {
	if testing.Verbose() {
		t.Log(msg)
	}
}
<|endoftext|>


<commit_before>package orm

import (
	"testing"
)

//DSLTest is used to test SQL creation
type DSLTest struct {
	ID          int
	FieldString string
	FieldInt    int
}

//DSLTestWithoutID is used to test SQL creation
type DSLTestWithoutID struct {
	FieldString string
	FieldInt    int
}

func TestAssembleSQLCreateTable(t *testing.T) {
	var handler Handler
	handler.table = DSLTest{}

	expected := `create table DSLTest (ID serial NOT NULL, FieldString character varying, FieldInt integer,  constraint DSLTest_pkey primary key (id));`
	got, _ := handler.assembleSQLCreateTable()
	if got != expected {
		t.Fatalf("\nExpected:\t %v\nGot:\t\t %v\n", expected, got)
	}

	handler.table = DSLTestWithoutID{}
	got, err := handler.assembleSQLCreateTable()
	if got != "" {
		t.Fatalf("\nExpected:\t \"\"\nGot:\t\t %v\n", got)
	}

	if err.Error() != "ID field not found on struct DSLTestWithoutID" {
		t.Fatalf("\nExpected:\t %v\nGot:\t\t %v\n", "ID field not found on struct DSLTestWithoutID", err.Error())
	}
}

func TestCreateTable(t *testing.T) {
	//connect to Postgres
	orm, scream := ConnectToPostgres()
	if scream != nil {
		panic(scream)
	}

	ormTest := orm.NewHandler(DSLTest{})
	ormTest.DropTable()
	err := ormTest.CreateTable()
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	ormTest.sqlCreateTable = "super wrong sql"
	err = ormTest.CreateTable()

	if err.Error() != "pq: syntax error at or near \"super\"" {
		t.Fatalf("%v", err.Error())
	}

	ormTest = orm.NewHandler(DSLTestWithoutID{})
	ormTest.sqlCreateTable = ""
	ormTest.DropTable()
	err = ormTest.CreateTable()
	if err.Error() != "ID field not found on struct DSLTestWithoutID" {
		t.Fatalf("err: %v", err.Error())
	}

}
<commit_msg>Add unit tests for DropSQL<commit_after>package orm

import (
	"testing"
)

//DSLTest is used to test SQL creation
type DSLTest struct {
	ID          int
	FieldString string
	FieldInt    int
}

//DSLTestWithoutID is used to test SQL creation
type DSLTestWithoutID struct {
	FieldString string
	FieldInt    int
}

func TestAssembleSQLCreateTable(t *testing.T) {
	var handler Handler
	handler.table = DSLTest{}

	expected := `create table DSLTest (ID serial NOT NULL, FieldString character varying, FieldInt integer,  constraint DSLTest_pkey primary key (id));`
	got, _ := handler.assembleSQLCreateTable()
	if got != expected {
		t.Fatalf("\nExpected:\t %v\nGot:\t\t %v\n", expected, got)
	}

	handler.table = DSLTestWithoutID{}
	got, err := handler.assembleSQLCreateTable()
	if got != "" {
		t.Fatalf("\nExpected:\t \"\"\nGot:\t\t %v\n", got)
	}

	if err.Error() != "ID field not found on struct DSLTestWithoutID" {
		t.Fatalf("\nExpected:\t %v\nGot:\t\t %v\n", "ID field not found on struct DSLTestWithoutID", err.Error())
	}
}

func TestCreateTable(t *testing.T) {
	//connect to Postgres
	orm, scream := ConnectToPostgres()
	if scream != nil {
		panic(scream)
	}

	ormTest := orm.NewHandler(DSLTest{})
	ormTest.DropTable()
	err := ormTest.CreateTable()
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	ormTest.sqlCreateTable = "super wrong sql"
	err = ormTest.CreateTable()

	if err.Error() != "pq: syntax error at or near \"super\"" {
		t.Fatalf("%v", err.Error())
	}

	ormTest = orm.NewHandler(DSLTestWithoutID{})
	ormTest.sqlCreateTable = ""
	ormTest.DropTable()
	err = ormTest.CreateTable()
	if err.Error() != "ID field not found on struct DSLTestWithoutID" {
		t.Fatalf("err: %v", err.Error())
	}
}

func TestAssembleSQLDropTable(t *testing.T) {
	var handler Handler
	handler.table = DSLTest{}

	expected := `drop table DSLTest;`
	got := handler.assembleSQLDropTable()
	if got != expected {
		t.Fatalf("\nExpected:\t %v\nGot:\t\t %v\n", expected, got)
	}
}

func TestDropTable(t *testing.T) {
	//connect to Postgres
	orm, scream := ConnectToPostgres()
	if scream != nil {
		panic(scream)
	}

	ormTest := orm.NewHandler(DSLTest{})
	ormTest.CreateTable()
	err := ormTest.DropTable()
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	ormTest.CreateTable()
	ormTest.sqlDropTable = "super wrong sql"
	err = ormTest.DropTable()
	if err.Error() != "pq: syntax error at or near \"super\"" {
		t.Fatalf("%v", err.Error())
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 The Vanadium 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 vlog

import (
	"v.io/x/lib/llog"
)

// Info logs to the INFO log.
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
func Info(args ...interface{}) {
	Log.log.Print(llog.InfoLog, args...)
	Log.maybeFlush()
}

// Infof logs to the INFO log.
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
func Infof(format string, args ...interface{}) {
	Log.log.Printf(llog.InfoLog, format, args...)
	Log.maybeFlush()
}

// InfoDepth acts as Info but uses depth to determine which call frame to log.
// A depth of 0 is equivalent to calling Info.
func InfoDepth(depth int, args ...interface{}) {
	Log.log.PrintDepth(llog.InfoLog, depth, args...)
	Log.maybeFlush()
}

// InfoFileLine acts as Info but uses file and line as the call frame to log.
func InfoFileLine(file string, line int, args ...interface{}) {
	Log.log.PrintFileLine(llog.InfoLog, file, line, args...)
	Log.maybeFlush()
}

// InfoStack logs the current goroutine's stack if the all parameter
// is false, or the stacks of all goroutines if it's true.
func InfoStack(all bool) {
	infoStack(Log, all)
}

// V returns true if the configured logging level is greater than or equal to its parameter
func V(level Level) bool {
	return Log.log.VDepth(0, llog.Level(level))
}

// VDepth acts as V but uses depth to determine which call frame to check V.
// A depth of 0 is equivalent to calling V.
func VDepth(depth int, level Level) bool {
	return Log.log.VDepth(0, llog.Level(level))
}

// VI is like V, except that it returns an instance of the Info
// interface that will either log (if level >= the configured level)
// or discard its parameters. This allows for logger.VI(2).Info
// style usage.
func VI(level Level) interface {
	// Info logs to the INFO log.
	// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
	Info(args ...interface{})

	// Infoln logs to the INFO log.
	// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
	Infof(format string, args ...interface{})

	// InfoDepth acts as Info but uses depth to determine which call frame to log.
	// A depth of 0 is equivalent to calling Info.
	InfoDepth(depth int, args ...interface{})

	// InfoStack logs the current goroutine's stack if the all parameter
	// is false, or the stacks of all goroutines if it's true.
	InfoStack(all bool)
} {
	if Log.log.VDepth(0, llog.Level(level)) {
		return Log
	}
	return &discardInfo{}
}

// Flush flushes all pending log I/O.
func FlushLog() {
	Log.FlushLog()
}

// Error logs to the ERROR and INFO logs.
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
func Error(args ...interface{}) {
	Log.log.Print(llog.ErrorLog, args...)
	Log.maybeFlush()
}

// ErrorDepth acts as Error but uses depth to determine which call frame to log.
// A depth of 0 is equivalent to calling Error.
func ErrorDepth(depth int, args ...interface{}) {
	Log.log.PrintDepth(llog.ErrorLog, depth, args...)
	Log.maybeFlush()
}

// Errorf logs to the ERROR and INFO logs.
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
func Errorf(format string, args ...interface{}) {
	Log.log.Printf(llog.ErrorLog, format, args...)
	Log.maybeFlush()
}

// Fatal logs to the FATAL, ERROR and INFO logs,
// including a stack trace of all running goroutines, then calls os.Exit(255).
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
func Fatal(args ...interface{}) {
	Log.log.Print(llog.FatalLog, args...)
}

// FatalDepth acts as Fatal but uses depth to determine which call frame to log.
// A depth of 0 is equivalent to calling Fatal.
func FatalDepth(depth int, args ...interface{}) {
	Log.log.PrintDepth(llog.FatalLog, depth, args...)
}

// Fatalf logs to the FATAL, ERROR and INFO logs,
// including a stack trace of all running goroutines, then calls os.Exit(255).
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
func Fatalf(format string, args ...interface{}) {
	Log.log.Printf(llog.FatalLog, format, args...)
}

// ConfigureLogging configures all future logging. Some options
// may not be usable if ConfigureLogging is called from an init function,
// in which case an error will be returned. The Configured error is
// returned if ConfigureLogger has already been called unless the
// OverridePriorConfiguration options is included.
func Configure(opts ...LoggingOpts) error {
	return Log.Configure(opts...)
}

// Stats returns stats on how many lines/bytes haven been written to
// this set of logs.
func Stats() (infoStats, errorStats struct{ Lines, Bytes int64 }) {
	return Log.Stats()
}

// Panic is equivalent to Error() followed by a call to panic().
func Panic(args ...interface{}) {
	Log.Panic(args...)
}

// PanicDepth acts as Panic but uses depth to determine which call frame to log.
// A depth of 0 is equivalent to calling Panic.
func PanicDepth(depth int, args ...interface{}) {
	Log.PanicDepth(depth, args...)
}

// Panicf is equivalent to Errorf() followed by a call to panic().
func Panicf(format string, args ...interface{}) {
	Log.Panicf(format, args...)
}
<commit_msg>Fix vlog.VDepth (#54)<commit_after>// Copyright 2015 The Vanadium 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 vlog

import (
	"v.io/x/lib/llog"
)

// Info logs to the INFO log.
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
func Info(args ...interface{}) {
	Log.log.Print(llog.InfoLog, args...)
	Log.maybeFlush()
}

// Infof logs to the INFO log.
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
func Infof(format string, args ...interface{}) {
	Log.log.Printf(llog.InfoLog, format, args...)
	Log.maybeFlush()
}

// InfoDepth acts as Info but uses depth to determine which call frame to log.
// A depth of 0 is equivalent to calling Info.
func InfoDepth(depth int, args ...interface{}) {
	Log.log.PrintDepth(llog.InfoLog, depth, args...)
	Log.maybeFlush()
}

// InfoFileLine acts as Info but uses file and line as the call frame to log.
func InfoFileLine(file string, line int, args ...interface{}) {
	Log.log.PrintFileLine(llog.InfoLog, file, line, args...)
	Log.maybeFlush()
}

// InfoStack logs the current goroutine's stack if the all parameter
// is false, or the stacks of all goroutines if it's true.
func InfoStack(all bool) {
	infoStack(Log, all)
}

// V returns true if the configured logging level is greater than or equal to its parameter
func V(level Level) bool {
	return Log.log.VDepth(0, llog.Level(level))
}

// VDepth acts as V but uses depth to determine which call frame to check V.
// A depth of 0 is equivalent to calling V.
func VDepth(depth int, level Level) bool {
	return Log.log.VDepth(depth, llog.Level(level))
}

// VI is like V, except that it returns an instance of the Info
// interface that will either log (if level >= the configured level)
// or discard its parameters. This allows for logger.VI(2).Info
// style usage.
func VI(level Level) interface {
	// Info logs to the INFO log.
	// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
	Info(args ...interface{})

	// Infoln logs to the INFO log.
	// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
	Infof(format string, args ...interface{})

	// InfoDepth acts as Info but uses depth to determine which call frame to log.
	// A depth of 0 is equivalent to calling Info.
	InfoDepth(depth int, args ...interface{})

	// InfoStack logs the current goroutine's stack if the all parameter
	// is false, or the stacks of all goroutines if it's true.
	InfoStack(all bool)
} {
	if Log.log.VDepth(0, llog.Level(level)) {
		return Log
	}
	return &discardInfo{}
}

// Flush flushes all pending log I/O.
func FlushLog() {
	Log.FlushLog()
}

// Error logs to the ERROR and INFO logs.
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
func Error(args ...interface{}) {
	Log.log.Print(llog.ErrorLog, args...)
	Log.maybeFlush()
}

// ErrorDepth acts as Error but uses depth to determine which call frame to log.
// A depth of 0 is equivalent to calling Error.
func ErrorDepth(depth int, args ...interface{}) {
	Log.log.PrintDepth(llog.ErrorLog, depth, args...)
	Log.maybeFlush()
}

// Errorf logs to the ERROR and INFO logs.
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
func Errorf(format string, args ...interface{}) {
	Log.log.Printf(llog.ErrorLog, format, args...)
	Log.maybeFlush()
}

// Fatal logs to the FATAL, ERROR and INFO logs,
// including a stack trace of all running goroutines, then calls os.Exit(255).
// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
func Fatal(args ...interface{}) {
	Log.log.Print(llog.FatalLog, args...)
}

// FatalDepth acts as Fatal but uses depth to determine which call frame to log.
// A depth of 0 is equivalent to calling Fatal.
func FatalDepth(depth int, args ...interface{}) {
	Log.log.PrintDepth(llog.FatalLog, depth, args...)
}

// Fatalf logs to the FATAL, ERROR and INFO logs,
// including a stack trace of all running goroutines, then calls os.Exit(255).
// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
func Fatalf(format string, args ...interface{}) {
	Log.log.Printf(llog.FatalLog, format, args...)
}

// ConfigureLogging configures all future logging. Some options
// may not be usable if ConfigureLogging is called from an init function,
// in which case an error will be returned. The Configured error is
// returned if ConfigureLogger has already been called unless the
// OverridePriorConfiguration options is included.
func Configure(opts ...LoggingOpts) error {
	return Log.Configure(opts...)
}

// Stats returns stats on how many lines/bytes haven been written to
// this set of logs.
func Stats() (infoStats, errorStats struct{ Lines, Bytes int64 }) {
	return Log.Stats()
}

// Panic is equivalent to Error() followed by a call to panic().
func Panic(args ...interface{}) {
	Log.Panic(args...)
}

// PanicDepth acts as Panic but uses depth to determine which call frame to log.
// A depth of 0 is equivalent to calling Panic.
func PanicDepth(depth int, args ...interface{}) {
	Log.PanicDepth(depth, args...)
}

// Panicf is equivalent to Errorf() followed by a call to panic().
func Panicf(format string, args ...interface{}) {
	Log.Panicf(format, args...)
}
<|endoftext|>


<commit_before>package engine

import (
	"bufio"
	"bytes"
	"errors"
	"strings"
)

type (
	TerrainType rune

	TerrainMap struct {
		Bounds AABB
		// y, x
		TerrainTypes [][]TerrainType
	}
)

const (
	TT_GRASS TerrainType = 'G'
	TT_DIRT  TerrainType = 'D'
	TT_ROCK  TerrainType = 'R'
)

func NewTerrainMap(bounds AABB, s string) (TerrainMap, error) {
	if len(s) == 0 {
		return TerrainMap{}, errors.New("invalid TerrainType")
	}

	w, h := bounds.Width(), bounds.Height()
	tm := make([][]TerrainType, h)

	if len(s) == 1 {
		for row, _ := range tm {
			tm[row] = make([]TerrainType, w)
		}

		for _, row := range tm {
			for x, _ := range row {
				row[x] = TerrainType(s[0])
			}
		}
	} else {
		s = strings.TrimLeft(s, "\n")
		if strings.Count(s, "\n") != h {
			return TerrainMap{}, errors.New("bounds height doesn't match num lines")
		}

		buf := bufio.NewReader(strings.NewReader(s))
		for y, _ := range tm {
			row := make([]TerrainType, 0, w)
			rowStr, err := buf.ReadString("\n"[0])
			if err != nil {
				return TerrainMap{}, err
			}

			rowStr = strings.TrimRight(rowStr, "\n")

			if len(rowStr) != w {
				return TerrainMap{}, errors.New("bounds width doesn't match line width")
			}

			for _, c := range rowStr {
				row = append(row, TerrainType(c))
			}
			tm[y] = row
		}
	}
	return TerrainMap{bounds, tm}, nil
}

func (m TerrainMap) Cell(c Cell) TerrainType {
	x := c.X - m.Bounds.TopL.X
	y := -(c.Y - m.Bounds.TopL.Y)

	return m.TerrainTypes[y][x]
}

func (m TerrainMap) Slice(bounds AABB) (TerrainMap, error) {
	// Check if the slice asked for is contained within my bounds
	if !m.Bounds.Contains(bounds.TopL) || !m.Bounds.Contains(bounds.BotR) {
		return m, errors.New("invalid terrain slice")
	}

	x := bounds.TopL.X - m.Bounds.TopL.X
	y := -(bounds.TopL.Y - m.Bounds.TopL.Y)
	w, h := bounds.Width(), bounds.Height()
	rows := make([][]TerrainType, h)

	for i, row := range m.TerrainTypes[y : y+h] {
		rows[i] = row[x : x+w]
	}

	return TerrainMap{
		bounds,
		rows,
	}, nil
}

func (m TerrainMap) String() string {
	w, h := len(m.TerrainTypes[0]), len(m.TerrainTypes)
	w += 1 // For \n char

	buf := bytes.NewBuffer(make([]byte, 0, w*h+1))
	buf.WriteRune('\n')
	for _, row := range m.TerrainTypes {
		for _, t := range row {
			buf.WriteRune(rune(t))
		}
		buf.WriteRune('\n')
	}

	return buf.String()
}

func (terrainMap TerrainMap) SaveToFile(filename string) {
}
<commit_msg>removed an unimplemented method<commit_after>package engine

import (
	"bufio"
	"bytes"
	"errors"
	"strings"
)

type (
	TerrainType rune

	TerrainMap struct {
		Bounds AABB
		// y, x
		TerrainTypes [][]TerrainType
	}
)

const (
	TT_GRASS TerrainType = 'G'
	TT_DIRT  TerrainType = 'D'
	TT_ROCK  TerrainType = 'R'
)

func NewTerrainMap(bounds AABB, s string) (TerrainMap, error) {
	if len(s) == 0 {
		return TerrainMap{}, errors.New("invalid TerrainType")
	}

	w, h := bounds.Width(), bounds.Height()
	tm := make([][]TerrainType, h)

	if len(s) == 1 {
		for row, _ := range tm {
			tm[row] = make([]TerrainType, w)
		}

		for _, row := range tm {
			for x, _ := range row {
				row[x] = TerrainType(s[0])
			}
		}
	} else {
		s = strings.TrimLeft(s, "\n")
		if strings.Count(s, "\n") != h {
			return TerrainMap{}, errors.New("bounds height doesn't match num lines")
		}

		buf := bufio.NewReader(strings.NewReader(s))
		for y, _ := range tm {
			row := make([]TerrainType, 0, w)
			rowStr, err := buf.ReadString("\n"[0])
			if err != nil {
				return TerrainMap{}, err
			}

			rowStr = strings.TrimRight(rowStr, "\n")

			if len(rowStr) != w {
				return TerrainMap{}, errors.New("bounds width doesn't match line width")
			}

			for _, c := range rowStr {
				row = append(row, TerrainType(c))
			}
			tm[y] = row
		}
	}
	return TerrainMap{bounds, tm}, nil
}

func (m TerrainMap) Cell(c Cell) TerrainType {
	x := c.X - m.Bounds.TopL.X
	y := -(c.Y - m.Bounds.TopL.Y)

	return m.TerrainTypes[y][x]
}

func (m TerrainMap) Slice(bounds AABB) (TerrainMap, error) {
	// Check if the slice asked for is contained within my bounds
	if !m.Bounds.Contains(bounds.TopL) || !m.Bounds.Contains(bounds.BotR) {
		return m, errors.New("invalid terrain slice")
	}

	x := bounds.TopL.X - m.Bounds.TopL.X
	y := -(bounds.TopL.Y - m.Bounds.TopL.Y)
	w, h := bounds.Width(), bounds.Height()
	rows := make([][]TerrainType, h)

	for i, row := range m.TerrainTypes[y : y+h] {
		rows[i] = row[x : x+w]
	}

	return TerrainMap{
		bounds,
		rows,
	}, nil
}

func (m TerrainMap) String() string {
	w, h := len(m.TerrainTypes[0]), len(m.TerrainTypes)
	w += 1 // For \n char

	buf := bytes.NewBuffer(make([]byte, 0, w*h+1))
	buf.WriteRune('\n')
	for _, row := range m.TerrainTypes {
		for _, t := range row {
			buf.WriteRune(rune(t))
		}
		buf.WriteRune('\n')
	}

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


<commit_before>package typhon

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"strings"

	"github.com/monzo/slog"
	"github.com/monzo/terrors"
	"github.com/monzo/terrors/proto"
)

var (
	mapTerr2Status = map[string]int{
		terrors.ErrBadRequest:         http.StatusBadRequest,
		terrors.ErrBadResponse:        http.StatusNotAcceptable,
		terrors.ErrForbidden:          http.StatusForbidden,
		terrors.ErrInternalService:    http.StatusInternalServerError,
		terrors.ErrNotFound:           http.StatusNotFound,
		terrors.ErrPreconditionFailed: http.StatusPreconditionFailed,
		terrors.ErrTimeout:            http.StatusGatewayTimeout,
		terrors.ErrUnauthorized:       http.StatusUnauthorized,
	}
	mapStatus2Terr map[int]string
)

func init() {
	mapStatus2Terr = make(map[int]string, len(mapTerr2Status))
	for k, v := range mapTerr2Status {
		mapStatus2Terr[v] = k
	}
}

// ErrorStatusCode returns an HTTP status code for the error
func ErrorStatusCode(err error) int {
	code := terrors.Wrap(err, nil).(*terrors.Error).Code
	if c, ok := mapTerr2Status[strings.SplitN(code, ".", 2)[0]]; ok {
		return c
	}
	return http.StatusInternalServerError
}

// terr2StatusCode converts HTTP status codes to a roughly equivalent terrors' code
func status2TerrCode(code int) string {
	if c, ok := mapStatus2Terr[code]; ok {
		return c
	}
	return terrors.ErrInternalService
}

// ErrorFilter serialises and de-serialises response errors
func ErrorFilter(req Request, svc Service) Response {
	// If the request contains an error, short-circuit and return that directly
	var rsp Response
	if req.err != nil {
		rsp = NewResponse(req)
		rsp.Error = req.err
	} else {
		rsp = svc(req)
	}

	if rsp.Response == nil {
		rsp.Response = newHTTPResponse(req)
	}
	if rsp.Request == nil {
		rsp.Request = &req
	}

	if rsp.Error != nil {
		if rsp.StatusCode == http.StatusOK {
			// We got an error, but there is no error in the underlying response; marshal
			if rsp.Body != nil {
				rsp.Body.Close()
			}
			rsp.Body = &bufCloser{}
			terr := terrors.Wrap(rsp.Error, nil).(*terrors.Error)
			rsp.Encode(terrors.Marshal(terr))
			rsp.StatusCode = ErrorStatusCode(terr)
			rsp.Header.Set("Terror", "1")
		}
	} else if rsp.StatusCode >= 400 && rsp.StatusCode <= 599 {
		// There is an error in the underlying response; unmarshal
		b, _ := rsp.BodyBytes(false)
		switch rsp.Header.Get("Terror") {
		case "1":
			tp := &terrorsproto.Error{}
			if err := json.Unmarshal(b, tp); err != nil {
				slog.Warn(rsp.Request, "Failed to unmarshal terror: %v", err)
				rsp.Error = errors.New(string(b))
			} else {
				rsp.Error = terrors.Unmarshal(tp)
			}

		default:
			rsp.Error = errors.New(string(b))
		}
	}

	if rsp.Error != nil && rsp.Error.Error() == "" {
		if rsp.Response != nil {
			rsp.Error = fmt.Errorf("Response error (%d)", rsp.StatusCode)
		} else {
			rsp.Error = fmt.Errorf("Response error")
		}
	}

	return rsp
}
<commit_msg>Add HTTP status codes in comments to make referancing easier<commit_after>package typhon

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"strings"

	"github.com/monzo/slog"
	"github.com/monzo/terrors"
	"github.com/monzo/terrors/proto"
)

var (
	mapTerr2Status = map[string]int{
		terrors.ErrBadRequest:         http.StatusBadRequest,          // 400
		terrors.ErrBadResponse:        http.StatusNotAcceptable,       // 406
		terrors.ErrForbidden:          http.StatusForbidden,           // 403
		terrors.ErrInternalService:    http.StatusInternalServerError, // 500
		terrors.ErrNotFound:           http.StatusNotFound,            // 404
		terrors.ErrPreconditionFailed: http.StatusPreconditionFailed,  // 412
		terrors.ErrTimeout:            http.StatusGatewayTimeout,      // 504
		terrors.ErrUnauthorized:       http.StatusUnauthorized,        // 401
	}
	mapStatus2Terr map[int]string
)

func init() {
	mapStatus2Terr = make(map[int]string, len(mapTerr2Status))
	for k, v := range mapTerr2Status {
		mapStatus2Terr[v] = k
	}
}

// ErrorStatusCode returns an HTTP status code for the error
func ErrorStatusCode(err error) int {
	code := terrors.Wrap(err, nil).(*terrors.Error).Code
	if c, ok := mapTerr2Status[strings.SplitN(code, ".", 2)[0]]; ok {
		return c
	}
	return http.StatusInternalServerError
}

// terr2StatusCode converts HTTP status codes to a roughly equivalent terrors' code
func status2TerrCode(code int) string {
	if c, ok := mapStatus2Terr[code]; ok {
		return c
	}
	return terrors.ErrInternalService
}

// ErrorFilter serialises and de-serialises response errors
func ErrorFilter(req Request, svc Service) Response {
	// If the request contains an error, short-circuit and return that directly
	var rsp Response
	if req.err != nil {
		rsp = NewResponse(req)
		rsp.Error = req.err
	} else {
		rsp = svc(req)
	}

	if rsp.Response == nil {
		rsp.Response = newHTTPResponse(req)
	}
	if rsp.Request == nil {
		rsp.Request = &req
	}

	if rsp.Error != nil {
		if rsp.StatusCode == http.StatusOK {
			// We got an error, but there is no error in the underlying response; marshal
			if rsp.Body != nil {
				rsp.Body.Close()
			}
			rsp.Body = &bufCloser{}
			terr := terrors.Wrap(rsp.Error, nil).(*terrors.Error)
			rsp.Encode(terrors.Marshal(terr))
			rsp.StatusCode = ErrorStatusCode(terr)
			rsp.Header.Set("Terror", "1")
		}
	} else if rsp.StatusCode >= 400 && rsp.StatusCode <= 599 {
		// There is an error in the underlying response; unmarshal
		b, _ := rsp.BodyBytes(false)
		switch rsp.Header.Get("Terror") {
		case "1":
			tp := &terrorsproto.Error{}
			if err := json.Unmarshal(b, tp); err != nil {
				slog.Warn(rsp.Request, "Failed to unmarshal terror: %v", err)
				rsp.Error = errors.New(string(b))
			} else {
				rsp.Error = terrors.Unmarshal(tp)
			}

		default:
			rsp.Error = errors.New(string(b))
		}
	}

	if rsp.Error != nil && rsp.Error.Error() == "" {
		if rsp.Response != nil {
			rsp.Error = fmt.Errorf("Response error (%d)", rsp.StatusCode)
		} else {
			rsp.Error = fmt.Errorf("Response error")
		}
	}

	return rsp
}
<|endoftext|>