<commit_before>package numbers

import (
	"errors"
	"reflect"
	"testing"
)

// TestFactorsList unit test FactorsList function.
func TestFactorsList(t *testing.T) {
	testCases := []struct {
		input    int
		expected []int
		err      error
	}{
		{2, []int{2}, nil},
		{15, []int{3, 5}, nil},
		{26, []int{2, 13}, nil},
		{37, []int{37}, nil},
		{42, []int{2, 3, 7}, nil},
		{-1, []int(nil), errors.New("no prime factors for numbers below two. received '-1'")},
	}
	for _, test := range testCases {
		observed, err := FactorsList(test.input)
		if err != nil {
			if test.err.Error() != err.Error() {
				t.Error(err)
			}
		}
		if !reflect.DeepEqual(observed, test.expected) {
			t.Errorf("for input '%d', expected '%v', got '%v'",
				test.input, test.expected, observed)
		}
	}
}

// BenchmarkFactorList benchmark FactorsList function.
func BenchmarkFactorList(b *testing.B) {
	for i := 0; i <= b.N; i++ {
		_, err := FactorsList(1000)
		if err != nil {
			b.Error(err)
		}
	}
}

// TestIsPrime unit test IsPrime function.
func TestIsPrime(t *testing.T) {
	testCases := []struct {
		input    int
		expected bool
	}{
		{-5, false},
		{0, false},
		{2, true},
		{6, false},
		{13, true},
	}
	for _, test := range testCases {
		observed := IsPrime(test.input)
		if observed != test.expected {
			t.Errorf("for input '%d', expected '%t', got '%t'",
				test.input, test.expected, observed)
		}
	}
}

// BenchmarkIsPrime benchmark IsPrime function.
func BenchmarkIsPrime(b *testing.B) {
	for i := 0; i <= b.N; i++ {
		_ = IsPrime(1728459)
	}
}

// TestFibonacciGen unit test FibonacciGen function.
func TestFibonacciGen(t *testing.T) {
	testCases := []struct {
		input, expected int
	}{
		{1, 0},
		{2, 1},
		{3, 1},
		{4, 2},
		{5, 3},
		{8, 13},
		{10, 34},
		{12, 89},
	}
	for _, test := range testCases {
		var observed int
		c := FibonacciGen()
		for n := 0; n < test.input; n++ {
			observed = <-c
		}
		if observed != test.expected {
			t.Errorf("for input '%d', expected '%d', got '%d'", test.input, test.expected, observed)
		}
	}
}

// BenchmarkFibonacciGen benchmark FibonacciGen function.
func BenchmarkFibonacciGen(b *testing.B) {
	for i := 0; i <= b.N; i++ {
		c := FibonacciGen()
		for n := 0; n < 10000; n++ {
			_ = <-c
		}
	}
}

// TestNthFibonacci unit test NthFibonacci function.
func TestNthFibonacci(t *testing.T) {
	var testCases = []struct {
		input, expected int
	}{
		{1, 1},
		{5, 5},
		{7, 13},
		{10, 55},
		{19, 4181},
	}
	for _, test := range testCases {
		observed := NthFibonacci(test.input)
		if observed != test.expected {
			t.Errorf("for input '%d', expected '%d', got '%d'",
				test.input, test.expected, observed)
		}
	}
}

// BenchmarkNthFibonacci benchmark NthFibonacci function.
func BenchmarkNthFibonacci(b *testing.B) {
	for i := 0; i < b.N; i++ {
		_ = NthFibonacci(10000)
	}
}

// TestEvenNumbers unit test EvenNumbers function.
func TestEvenNumbers(t *testing.T) {
	testCases := []struct {
		inputA, inputB int
		expected       []int
		err            error
	}{
		{1, 1, []int(nil), nil},
		{1, 3, []int{2}, nil},
		{4, 8, []int{4, 6, 8}, nil},
		{-4, 8, []int{-4, -2, 0, 2, 4, 6, 8}, nil},
		{-1, -2, []int(nil), errors.New("a must be greater than b. received a '-1' and b '-2'")},
	}
	for _, test := range testCases {
		observed, err := EvenNumbers(test.inputA, test.inputB)
		if err != nil {
			if err.Error() != test.err.Error() {
				t.Error(err)
			}
		}
		if !reflect.DeepEqual(observed, test.expected) {
			t.Errorf("for a '%d' and b '%d', expected '%v', got '%v'",
				test.inputA, test.inputB, test.expected, observed)
		}
	}
}
<commit_msg>Add benchmark test for EvenNumbers function<commit_after>package numbers

import (
	"errors"
	"reflect"
	"testing"
)

// TestFactorsList unit test FactorsList function.
func TestFactorsList(t *testing.T) {
	testCases := []struct {
		input    int
		expected []int
		err      error
	}{
		{2, []int{2}, nil},
		{15, []int{3, 5}, nil},
		{26, []int{2, 13}, nil},
		{37, []int{37}, nil},
		{42, []int{2, 3, 7}, nil},
		{-1, []int(nil), errors.New("no prime factors for numbers below two. received '-1'")},
	}
	for _, test := range testCases {
		observed, err := FactorsList(test.input)
		if err != nil {
			if test.err.Error() != err.Error() {
				t.Error(err)
			}
		}
		if !reflect.DeepEqual(observed, test.expected) {
			t.Errorf("for input '%d', expected '%v', got '%v'",
				test.input, test.expected, observed)
		}
	}
}

// BenchmarkFactorList benchmark FactorsList function.
func BenchmarkFactorList(b *testing.B) {
	for i := 0; i <= b.N; i++ {
		_, err := FactorsList(1000)
		if err != nil {
			b.Error(err)
		}
	}
}

// TestIsPrime unit test IsPrime function.
func TestIsPrime(t *testing.T) {
	testCases := []struct {
		input    int
		expected bool
	}{
		{-5, false},
		{0, false},
		{2, true},
		{6, false},
		{13, true},
	}
	for _, test := range testCases {
		observed := IsPrime(test.input)
		if observed != test.expected {
			t.Errorf("for input '%d', expected '%t', got '%t'",
				test.input, test.expected, observed)
		}
	}
}

// BenchmarkIsPrime benchmark IsPrime function.
func BenchmarkIsPrime(b *testing.B) {
	for i := 0; i <= b.N; i++ {
		_ = IsPrime(1728459)
	}
}

// TestFibonacciGen unit test FibonacciGen function.
func TestFibonacciGen(t *testing.T) {
	testCases := []struct {
		input, expected int
	}{
		{1, 0},
		{2, 1},
		{3, 1},
		{4, 2},
		{5, 3},
		{8, 13},
		{10, 34},
		{12, 89},
	}
	for _, test := range testCases {
		var observed int
		c := FibonacciGen()
		for n := 0; n < test.input; n++ {
			observed = <-c
		}
		if observed != test.expected {
			t.Errorf("for input '%d', expected '%d', got '%d'", test.input, test.expected, observed)
		}
	}
}

// BenchmarkFibonacciGen benchmark FibonacciGen function.
func BenchmarkFibonacciGen(b *testing.B) {
	for i := 0; i <= b.N; i++ {
		c := FibonacciGen()
		for n := 0; n < 10000; n++ {
			_ = <-c
		}
	}
}

// TestNthFibonacci unit test NthFibonacci function.
func TestNthFibonacci(t *testing.T) {
	var testCases = []struct {
		input, expected int
	}{
		{1, 1},
		{5, 5},
		{7, 13},
		{10, 55},
		{19, 4181},
	}
	for _, test := range testCases {
		observed := NthFibonacci(test.input)
		if observed != test.expected {
			t.Errorf("for input '%d', expected '%d', got '%d'",
				test.input, test.expected, observed)
		}
	}
}

// BenchmarkNthFibonacci benchmark NthFibonacci function.
func BenchmarkNthFibonacci(b *testing.B) {
	for i := 0; i < b.N; i++ {
		_ = NthFibonacci(10000)
	}
}

// TestEvenNumbers unit test EvenNumbers function.
func TestEvenNumbers(t *testing.T) {
	testCases := []struct {
		inputA, inputB int
		expected       []int
		err            error
	}{
		{1, 1, []int(nil), nil},
		{1, 3, []int{2}, nil},
		{4, 8, []int{4, 6, 8}, nil},
		{-4, 8, []int{-4, -2, 0, 2, 4, 6, 8}, nil},
		{-1, -2, []int(nil), errors.New("a must be greater than b. received a '-1' and b '-2'")},
	}
	for _, test := range testCases {
		observed, err := EvenNumbers(test.inputA, test.inputB)
		if err != nil {
			if err.Error() != test.err.Error() {
				t.Error(err)
			}
		}
		if !reflect.DeepEqual(observed, test.expected) {
			t.Errorf("for a '%d' and b '%d', expected '%v', got '%v'",
				test.inputA, test.inputB, test.expected, observed)
		}
	}
}

// BenchmarkEvenNumbers benchmark EvenNumbers function.
func BenchmarkEvenNumbers(b *testing.B) {
	for i := 0; i <= b.N; i++ {
		_, err := EvenNumbers(1, 100000)
		if err != nil {
			b.Error(err)
		}
	}
}
<|endoftext|>


<commit_before>// errchk $G -e $D/$F.go

// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

func use(bool) {}

type T1 *int
type T2 *int

type T3 struct {}

var t3 T3

func main() {
	// Arguments to comparison must be
	// assignable one to the other (or vice versa)
	// so chan int can be compared against
	// directional channels but channel of different
	// direction cannot be compared against each other.
	var c1 chan <-int
	var c2 <-chan int
	var c3 chan int

	use(c1 == c2)	// ERROR "invalid operation"
	use(c2 == c1)	// ERROR "invalid operation"
	use(c1 == c3)
	use(c2 == c2)
	use(c3 == c1)
	use(c3 == c2)

	// Same applies to named types.
	var p1 T1
	var p2 T2
	var p3 *int

	use(p1 == p2)	// ERROR "invalid operation"
	use(p2 == p1)	// ERROR "invalid operation"
	use(p1 == p3)
	use(p2 == p2)
	use(p3 == p1)
	use(p3 == p2)

	// Comparison of structs should have a good message
	use(t3 == t3)	// ERROR "struct"
}
<commit_msg>test: match gccgo error messages for cmp6.go<commit_after>// errchk $G -e $D/$F.go

// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

func use(bool) {}

type T1 *int
type T2 *int

type T3 struct {}

var t3 T3

func main() {
	// Arguments to comparison must be
	// assignable one to the other (or vice versa)
	// so chan int can be compared against
	// directional channels but channel of different
	// direction cannot be compared against each other.
	var c1 chan <-int
	var c2 <-chan int
	var c3 chan int

	use(c1 == c2)	// ERROR "invalid operation|incompatible"
	use(c2 == c1)	// ERROR "invalid operation|incompatible"
	use(c1 == c3)
	use(c2 == c2)
	use(c3 == c1)
	use(c3 == c2)

	// Same applies to named types.
	var p1 T1
	var p2 T2
	var p3 *int

	use(p1 == p2)	// ERROR "invalid operation|incompatible"
	use(p2 == p1)	// ERROR "invalid operation|incompatible"
	use(p1 == p3)
	use(p2 == p2)
	use(p3 == p1)
	use(p3 == p2)

	// Comparison of structs should have a good message
	use(t3 == t3)	// ERROR "struct|expected"
}
<|endoftext|>


<commit_before>package offheap

import (
	"fmt"
	"os"
	"syscall"

	"github.com/glycerine/gommap"
)

// The MmapMalloc struct represents either an anonymous, private
// region of memory (if path was "", or a memory mapped file if
// path was supplied to Malloc() at creation.
//
// Malloc() creates and returns an MmapMalloc struct, which can then
// be later Free()-ed. Malloc() calls request memory directly
// from the kernel via mmap(). Memory can optionally be backed
// by a file for simplicity/efficiency of saving to disk.
//
// For use when the Go GC overhead is too large, and you need to move
// the hash table off-heap.
//
type MmapMalloc struct {
	Path         string `capid:"0"`
	File         *os.File
	Fd           int         `capid:"1"`
	FileBytesLen int64       `capid:"2"`
	BytesAlloc   int64       `capid:"3"`
	MMap         gommap.MMap // equiv to Mem
	Mem          []byte      `capid:"4"` // equiv to Mmap
}

// TruncateTo enlarges or shortens the file backing the
// memory map to be size newSize bytes. It only impacts
// the file underlying the mapping, not
// the mapping itself at this point.
func (mm *MmapMalloc) TruncateTo(newSize int64) {
	if mm.File == nil {
		panic("cannot call TruncateTo() on a non-file backed MmapMalloc.")
	}
	err := syscall.Ftruncate(int(mm.File.Fd()), newSize)
	if err != nil {
		panic(err)
	}
}

// Free eleases the memory allocation back to the OS by removing
// the (possibly anonymous and private) memroy mapped file that
// was backing it. Warning: any pointers still remaining will crash
// the program if dereferenced.
func (mm *MmapMalloc) Free() {
	if mm.File != nil {
		mm.File.Close()
	}
	err := mm.MMap.UnsafeUnmap()
	if err != nil {
		panic(err)
	}
}

//Malloc() creates a new
//
// If path is not empty then we memory map to the give path as well.
// Otherwise it is just like a call to malloc(): an anonymous memory allocation,
// outside the realm of the Go Garbage Collector.
// If numBytes is -1, then we take the size from the path file's size.
// The returned value's .Mem member holds a []byte pointing to the returned memory (as does .MMap, for use in other gommap calls).
//
func Malloc(numBytes int64, path string) *MmapMalloc {

	mm := MmapMalloc{
		Path: path,
	}

	flags := syscall.MAP_SHARED
	if path == "" {
		flags = syscall.MAP_ANON | syscall.MAP_PRIVATE
		mm.Fd = -1

		if numBytes < 0 {
			panic("numBytes was negative but path was also empty: don't know how much to allocate!")
		}

	} else {

		if dirExists(mm.Path) {
			panic(fmt.Sprintf("path '%s' already exists as a directory, so cannot be used as a memory mapped file.", mm.Path))
		}

		if !fileExists(mm.Path) {
			file, err := os.Create(mm.Path)
			if err != nil {
				panic(err)
			}
			mm.File = file
		} else {
			file, err := os.OpenFile(mm.Path, os.O_RDWR, 0777)
			if err != nil {
				panic(err)
			}
			mm.File = file
		}
		mm.Fd = int(mm.File.Fd())
	}

	sz := numBytes
	if path != "" {
		// file-backed memory
		if numBytes < 0 {

			var stat syscall.Stat_t
			if err := syscall.Fstat(mm.Fd, &stat); err != nil {
				panic(err)
			}
			sz = stat.Size

		} else {
			// set to the size requested
			err := syscall.Ftruncate(mm.Fd, numBytes)
			if err != nil {
				panic(err)
			}
		}
		mm.FileBytesLen = sz
	}
	// INVAR: sz holds non-negative length of memory/file.

	mm.BytesAlloc = sz

	prot := syscall.PROT_READ | syscall.PROT_WRITE

	vprintf("\n ------->> path = '%v',  mm.Fd = %v, with flags = %x, sz = %v,  prot = '%v'\n", path, mm.Fd, flags, sz, prot)

	var mmap []byte
	var err error
	if mm.Fd == -1 {

		flags = syscall.MAP_ANON | syscall.MAP_PRIVATE
		i1 := int64(-1)
		m1 := uintptr(uint64(i1))
		mmap, err = gommap.MapAt(0, m1, 0, int64(sz), gommap.ProtFlags(prot), gommap.MapFlags(flags))

		// save for reference:
		// the raw call also works, and doesn't need the i1/m1 conversion to work
		// around the crappy uintptr-based interface of gommap:
		// mmap, err = syscall.Mmap(-1, 0, int(sz), prot, flags)

	} else {

		flags = syscall.MAP_SHARED
		mmap, err = syscall.Mmap(mm.Fd, 0, int(sz), prot, flags)
	}
	if err != nil {
		panic(err)
	}

	mm.MMap = mmap
	mm.Mem = mmap

	return &mm
}

// returns once sync-to-disk is done
func (mm *MmapMalloc) BlockUntilSync() {
	mm.MMap.Sync(gommap.MS_SYNC)
}

// schedules sync, but may return before it is done.
func (mm *MmapMalloc) BackgrounSync() {
	mm.MMap.Sync(gommap.MS_ASYNC)
}
<commit_msg>atg. docs++<commit_after>package offheap

import (
	"fmt"
	"os"
	"syscall"

	"github.com/glycerine/gommap"
)

// The MmapMalloc struct represents either an anonymous, private
// region of memory (if path was "", or a memory mapped file if
// path was supplied to Malloc() at creation.
//
// Malloc() creates and returns an MmapMalloc struct, which can then
// be later Free()-ed. Malloc() calls request memory directly
// from the kernel via mmap(). Memory can optionally be backed
// by a file for simplicity/efficiency of saving to disk.
//
// For use when the Go GC overhead is too large, and you need to move
// the hash table off-heap.
//
type MmapMalloc struct {
	Path         string `capid:"0"`
	File         *os.File
	Fd           int         `capid:"1"`
	FileBytesLen int64       `capid:"2"`
	BytesAlloc   int64       `capid:"3"`
	MMap         gommap.MMap // equiv to Mem
	Mem          []byte      `capid:"4"` // equiv to Mmap
}

// TruncateTo enlarges or shortens the file backing the
// memory map to be size newSize bytes. It only impacts
// the file underlying the mapping, not
// the mapping itself at this point.
func (mm *MmapMalloc) TruncateTo(newSize int64) {
	if mm.File == nil {
		panic("cannot call TruncateTo() on a non-file backed MmapMalloc.")
	}
	err := syscall.Ftruncate(int(mm.File.Fd()), newSize)
	if err != nil {
		panic(err)
	}
}

// Free eleases the memory allocation back to the OS by removing
// the (possibly anonymous and private) memroy mapped file that
// was backing it. Warning: any pointers still remaining will crash
// the program if dereferenced.
func (mm *MmapMalloc) Free() {
	if mm.File != nil {
		mm.File.Close()
	}
	err := mm.MMap.UnsafeUnmap()
	if err != nil {
		panic(err)
	}
}

// Malloc() creates a new memory region that is provided directly
// by OS via the mmap() call, and is thus not scanned by the Go
// garbage collector.
//
// If path is not empty then we memory map to the given path.
// Otherwise it is just like a call to malloc(): an anonymous memory allocation,
// outside the realm of the Go Garbage Collector.
// If numBytes is -1, then we take the size from the path file's size. Otherwise
// the file is expanded or truncated to be numBytes in size.
// The returned value's .Mem member holds a []byte pointing to the returned memory (as does .MMap, for use in other gommap calls).
//
func Malloc(numBytes int64, path string) *MmapMalloc {

	mm := MmapMalloc{
		Path: path,
	}

	flags := syscall.MAP_SHARED
	if path == "" {
		flags = syscall.MAP_ANON | syscall.MAP_PRIVATE
		mm.Fd = -1

		if numBytes < 0 {
			panic("numBytes was negative but path was also empty: don't know how much to allocate!")
		}

	} else {

		if dirExists(mm.Path) {
			panic(fmt.Sprintf("path '%s' already exists as a directory, so cannot be used as a memory mapped file.", mm.Path))
		}

		if !fileExists(mm.Path) {
			file, err := os.Create(mm.Path)
			if err != nil {
				panic(err)
			}
			mm.File = file
		} else {
			file, err := os.OpenFile(mm.Path, os.O_RDWR, 0777)
			if err != nil {
				panic(err)
			}
			mm.File = file
		}
		mm.Fd = int(mm.File.Fd())
	}

	sz := numBytes
	if path != "" {
		// file-backed memory
		if numBytes < 0 {

			var stat syscall.Stat_t
			if err := syscall.Fstat(mm.Fd, &stat); err != nil {
				panic(err)
			}
			sz = stat.Size

		} else {
			// set to the size requested
			err := syscall.Ftruncate(mm.Fd, numBytes)
			if err != nil {
				panic(err)
			}
		}
		mm.FileBytesLen = sz
	}
	// INVAR: sz holds non-negative length of memory/file.

	mm.BytesAlloc = sz

	prot := syscall.PROT_READ | syscall.PROT_WRITE

	vprintf("\n ------->> path = '%v',  mm.Fd = %v, with flags = %x, sz = %v,  prot = '%v'\n", path, mm.Fd, flags, sz, prot)

	var mmap []byte
	var err error
	if mm.Fd == -1 {

		flags = syscall.MAP_ANON | syscall.MAP_PRIVATE
		i1 := int64(-1)
		m1 := uintptr(uint64(i1))
		mmap, err = gommap.MapAt(0, m1, 0, int64(sz), gommap.ProtFlags(prot), gommap.MapFlags(flags))

		// save for reference:
		// the raw call also works, and doesn't need the i1/m1 conversion to work
		// around the crappy uintptr-based interface of gommap:
		// mmap, err = syscall.Mmap(-1, 0, int(sz), prot, flags)

	} else {

		flags = syscall.MAP_SHARED
		mmap, err = syscall.Mmap(mm.Fd, 0, int(sz), prot, flags)
	}
	if err != nil {
		panic(err)
	}

	mm.MMap = mmap
	mm.Mem = mmap

	return &mm
}

// returns once sync-to-disk is done
func (mm *MmapMalloc) BlockUntilSync() {
	mm.MMap.Sync(gommap.MS_SYNC)
}

// schedules sync, but may return before it is done.
func (mm *MmapMalloc) BackgrounSync() {
	mm.MMap.Sync(gommap.MS_ASYNC)
}
<|endoftext|>


<commit_before>// Copyright 2016-2021 The Libsacloud Authors
//
// 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 libsacloud

// Version バージョン
const Version = "2.18.1"
<commit_msg>Bump to v2.19.0<commit_after>// Copyright 2016-2021 The Libsacloud Authors
//
// 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 libsacloud

// Version バージョン
const Version = "2.19.0"
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013-2014, Jeremy Bingham (<jbingham@gmail.com>)
 *
 * 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.
 */

// Users and clients ended up having to be split apart after all, once adding
// the SQL backing started falling into place. Users are very similar to
// clients, except that they are unique across the whole server and can log in
// via the web interface, while clients are only unique across an organization
// and cannot log in over the web. Basically, users are generally for something
// you would do, while a client would be associated with a specific node.
//
// Note: At this time, organizations are not implemented, so the difference
// between clients and users is a little less stark.
package user

import (
	"github.com/ctdk/goiardi/data_store"
	"fmt"
	"github.com/ctdk/goiardi/chef_crypto"
	"github.com/ctdk/goiardi/util"
	"github.com/ctdk/goiardi/config"
	"net/http"
	"encoding/gob"
	"bytes"
)

type User struct {
	Username string `json:"username"`
	Name string `json:"name"`
	Email string `json:"email"`
	Admin bool `json:"admin"`
	pubKey string `json:"public_key"`
	passwd string
	Salt []byte
}

// Generate a new set of RSA keys for the user. The new private key is saved
// with the user object, the public key is given to the user and not saved on
// the server at all.
func (u *User) GenerateKeys() (string, error){
	priv_pem, pub_pem, err := chef_crypto.GenerateRSAKeys()
	if err != nil {
		return "", err
	}
	c.pubKey = pub_pem
	return priv_pem, nil
}

// Checks that the provided public key is valid. Wrapper around
// chef_crypto.ValidatePublicKey(), but with a different error type.
func ValidatePublicKey(publicKey interface{}) (bool, util.Gerror) {
	ok, pkerr := chef_crypto.ValidatePublicKey(publicKey)
	var err util.Gerror
	if !ok {
		err = util.Errorf(pkerr.Error())
	}
	return ok, err
}

// Is the user an admin? If use-auth is false, this always returns true.
func (u *User) IsAdmin() bool {
	if !config.Config.UseAuth {
		return true
	}
	return u.Admin
}

// Users are never validators, so always return false. This is true even if
// auth mode is not on.
func (u *User) IsValidator() bool {
	return false
}

func (u *User) IsSelf(other *Actor) bool {
	if !config.Config.UseAuth {
		return true
	}
}

func (u *User) IsUser() bool {
	return true
}

func (u *User) IsClient() bool {
	return false
}

// Return the user's public key. Part of the Actor interface.
func (u *User) PublicKey() string {
	return u.pubKey
}

// Validate and set the user's password. Will not set a password for a client.
func (u *User) SetPasswd(password string) util.Gerror {
	if len(password) < 6 {
		err := util.Errorf("Password must have at least 6 characters")
		return err
	}
	/* If those validations pass, set the password */
	var perr error
	u.passwd, perr = chef_crypto.HashPasswd(password, u.Salt)
	if perr != nil {
		err := util.Errorf(perr.Error())
		return err
	}
	return nil
}

// Check the provided password to see if it matches the stored password hash.
func (u *User) CheckPasswd(password string) util.Gerror {
	h, perr := chef_crypto.HashPasswd(password, u.Salt)
	if perr != nil {
		err := util.Errorf(perr.Error())
		return err
	}
	if u.passwd != h {
		err := util.Errorf("password did not match")
		return err
	}

	return nil
}

func validateUserName(name string) util.Gerror {
	if !util.ValidateUserName(name) {
		err := util.Errorf("Field 'name' invalid")
		return err
	}
	return nil
}

func (u *User) GetName() string {
	return u.Username
}

func (u *User) URLType() string {
	return "users"
}
<commit_msg>new user thing checkpoint<commit_after>/*
 * Copyright (c) 2013-2014, Jeremy Bingham (<jbingham@gmail.com>)
 *
 * 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.
 */

// Users and clients ended up having to be split apart after all, once adding
// the SQL backing started falling into place. Users are very similar to
// clients, except that they are unique across the whole server and can log in
// via the web interface, while clients are only unique across an organization
// and cannot log in over the web. Basically, users are generally for something
// you would do, while a client would be associated with a specific node.
//
// Note: At this time, organizations are not implemented, so the difference
// between clients and users is a little less stark.
package user

import (
	"github.com/ctdk/goiardi/data_store"
	"fmt"
	"github.com/ctdk/goiardi/chef_crypto"
	"github.com/ctdk/goiardi/util"
	"github.com/ctdk/goiardi/config"
	"net/http"
	"encoding/gob"
	"bytes"
)

type User struct {
	Username string `json:"username"`
	Name string `json:"name"`
	Email string `json:"email"`
	Admin bool `json:"admin"`
	pubKey string `json:"public_key"`
	passwd string
	Salt []byte
}

// Create a new API user.
func New(name string) (*User, util.Gerror) {

}

// Gets a user.
func Get(name string) (*User, util.Gerror){

}

func (u *User) Save() util.Gerror {

}

// Deletes a user, but will refuse to do so and give an error if it is the last
// administrator user.
func (u *User) Delete() util.Gerror {

}

// Renames a user. Save() must be called after this method is used. Will not
// rename the last administrator user.
func (u *User) Rename(new_name string) util.Gerror {

}

// Build a new user from a JSON object.
func NewFromJson(json_user map[string]interface{}) (*User, util.Gerror) {

}

// Update a user from a JSON object, carrying out a bunch of validations inside.
func UpdateFromJson(json_user map[string]interface{}) util.Gerror {

}

// Returns a list of users.
func GetList() []string {

}

// Convert the user to a JSON object, massaging it as needed to keep the chef
// client happy (be it knife, chef-pedant, etc.)
func (u *User) ToJson() map[string]interface{} {

}

func (u *User) isLastAdmin() bool {

}

// Generate a new set of RSA keys for the user. The new private key is saved
// with the user object, the public key is given to the user and not saved on
// the server at all.
func (u *User) GenerateKeys() (string, error){
	priv_pem, pub_pem, err := chef_crypto.GenerateRSAKeys()
	if err != nil {
		return "", err
	}
	c.pubKey = pub_pem
	return priv_pem, nil
}

// Checks that the provided public key is valid. Wrapper around
// chef_crypto.ValidatePublicKey(), but with a different error type.
func ValidatePublicKey(publicKey interface{}) (bool, util.Gerror) {
	ok, pkerr := chef_crypto.ValidatePublicKey(publicKey)
	var err util.Gerror
	if !ok {
		err = util.Errorf(pkerr.Error())
	}
	return ok, err
}

// Is the user an admin? If use-auth is false, this always returns true.
func (u *User) IsAdmin() bool {
	if !config.Config.UseAuth {
		return true
	}
	return u.Admin
}

// Users are never validators, so always return false. This is true even if
// auth mode is not on.
func (u *User) IsValidator() bool {
	return false
}

func (u *User) IsSelf(other *Actor) bool {
	if !config.Config.UseAuth {
		return true
	}
	if ou, ok := other.(*User); ok {
		if u.Username == ou.Username {
			return true
		}
	}
	return false
}

func (u *User) IsUser() bool {
	return true
}

func (u *User) IsClient() bool {
	return false
}

// Return the user's public key. Part of the Actor interface.
func (u *User) PublicKey() string {
	return u.pubKey
}

// Set the user's public key. Part of the Actor interface.
func (u *User) SetPublicKey(pk interface{}) error {
	switch pk := pk.(type) {
		case string:
			ok, err := ValidatePublicKey(pk)
			if !ok {
				return err
			}
			u.pubKey = pk
		default:
			err := fmt.Errorf("invalid type %T for public key", pk)
	}
	return nil
}

// Validate and set the user's password. Will not set a password for a client.
func (u *User) SetPasswd(password string) util.Gerror {
	if len(password) < 6 {
		err := util.Errorf("Password must have at least 6 characters")
		return err
	}
	/* If those validations pass, set the password */
	var perr error
	u.passwd, perr = chef_crypto.HashPasswd(password, u.Salt)
	if perr != nil {
		err := util.Errorf(perr.Error())
		return err
	}
	return nil
}

// Check the provided password to see if it matches the stored password hash.
func (u *User) CheckPasswd(password string) util.Gerror {
	h, perr := chef_crypto.HashPasswd(password, u.Salt)
	if perr != nil {
		err := util.Errorf(perr.Error())
		return err
	}
	if u.passwd != h {
		err := util.Errorf("password did not match")
		return err
	}

	return nil
}

func validateUserName(name string) util.Gerror {
	if !util.ValidateUserName(name) {
		err := util.Errorf("Field 'name' invalid")
		return err
	}
	return nil
}

func (u *User) GetName() string {
	return u.Username
}

func (u *User) URLType() string {
	return "users"
}
<|endoftext|>


<commit_before>package executer

import (
	"bufio"
	"bytes"
	"github.com/subutai-io/base/agent/agent/container"
	"github.com/subutai-io/base/agent/config"
	"github.com/subutai-io/base/agent/log"
	"gopkg.in/lxc/go-lxc.v2"
	"io"
	"os"
	"os/exec"
	"os/user"
	"strconv"
	"strings"
	"sync"
	"syscall"
	"time"
	"unsafe"
)

type EncRequest struct {
	HostId  string `json:"hostid"`
	Request string `json:"request"`
}
type Request struct {
	Id      string         `json:"id"`
	Request RequestOptions `json:"request"`
}

type RequestOptions struct {
	Type        string            `json:"type"`
	Id          string            `json:"id"`
	CommandId   string            `json:"commandId"`
	WorkingDir  string            `json:"workingDirectory"`
	Command     string            `json:"command"`
	Args        []string          `json:"args"`
	Environment map[string]string `json:"environment"`
	StdOut      string            `json:"stdOut"`
	StdErr      string            `json:"stdErr"`
	RunAs       string            `json:"runAs"`
	Timeout     int               `json:"timeout"`
	IsDaemon    int               `json:"isDaemon"`
}

type Response struct {
	ResponseOpts ResponseOptions `json:"response"`
	Id           string          `json:"id"`
}

type ResponseOptions struct {
	Type           string `json:"type"`
	Id             string `json:"id"`
	CommandId      string `json:"commandId"`
	Pid            int    `json:"pid"`
	ResponseNumber int    `json:"responseNumber,omitempty"`
	StdOut         string `json:"stdOut,omitempty"`
	StdErr         string `json:"stdErr,omitempty"`
	ExitCode       string `json:"exitCode,omitempty"`
}

func ExecHost(req RequestOptions, out_c chan<- ResponseOptions) {
	cmd := buildCmd(&req)
	if cmd == nil {
		close(out_c)
		return
	}
	//read/write pipes stdout
	rop, wop, _ := os.Pipe()
	//read/out pipes stderr
	rep, wep, _ := os.Pipe()

	defer rop.Close()
	defer rep.Close()

	cmd.Stdout = wop
	cmd.Stderr = wep
	if req.IsDaemon == 1 {
		cmd.SysProcAttr = &syscall.SysProcAttr{}
		cmd.SysProcAttr.Setpgid = true
		cmd.SysProcAttr.Credential = &syscall.Credential{Uid: 0, Gid: 0}
	}
	err := cmd.Start()
	log.Check(log.WarnLevel, "Executing command: "+req.CommandId+" "+req.Command+" "+strings.Join(req.Args, " "), err)

	wop.Close()
	wep.Close()

	start := time.Now().Unix()
	end := time.Now().Add(time.Duration(req.Timeout) * time.Second).Unix()
	var response = genericResponse(&req)
	response.ResponseNumber = 1
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()
		r := bufio.NewReader(rop)
		for line, isPrefix, err := r.ReadLine(); err == nil; line, isPrefix, err = r.ReadLine() {
			response.StdOut = response.StdOut + string(line)
			if !isPrefix {
				response.StdOut = response.StdOut + "\n"
			}
			if len(response.StdOut) > 50000 {
				out_c <- response
				start = now()
				response.StdErr, response.StdOut = "", ""
				response.ResponseNumber++
			}
			if end-now() < 0 {
				break
			}
		}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		scanErr := bufio.NewScanner(rep)
		for scanErr.Scan() {
			response.StdErr = response.StdErr + scanErr.Text() + "\n"
			if len(response.StdErr) > 50000 {
				out_c <- response
				start = now()
				response.StdErr, response.StdOut = "", ""
				response.ResponseNumber++
			}
			if end-now() < 0 {
				break
			}
		}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		for end-now() > 0 {
			if now()-start > 10 {
				out_c <- response
				start = now()
				response.StdErr, response.StdOut = "", ""
				response.ResponseNumber++
			}
			time.Sleep(time.Second)
		}
	}()

	done := make(chan error)
	go func() { done <- cmd.Wait() }()
	select {
	case <-done:
		response.ExitCode = "0"
		if req.IsDaemon != 1 {
			response.ExitCode = strconv.Itoa(cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus())
		}
		out_c <- response
		end = -1
	case <-time.After(time.Duration(req.Timeout) * time.Second):
		if req.IsDaemon == 1 {
			response.ExitCode = "0"
			out_c <- response
			<-done
		} else {
			cmd.Process.Kill()
			response.Type = config.Broker.ExecuteTimeout
			cmd.Process.Wait()
			if cmd.ProcessState != nil {
				response.ExitCode = strconv.Itoa(cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus())
			} else {
				response.ExitCode = "-1"
			}
			out_c <- response
		}
	}
	wg.Wait()
	close(out_c)
}

func buildCmd(r *RequestOptions) *exec.Cmd {
	user, err := user.Lookup(r.RunAs)
	if log.Check(log.WarnLevel, "User lookup: "+r.RunAs, err) {
		return nil
	}
	uid, err := strconv.Atoi(user.Uid)
	if log.Check(log.WarnLevel, "UID lookup: "+user.Uid, err) {
		return nil
	}
	gid, err := strconv.Atoi(user.Gid)
	if log.Check(log.WarnLevel, "GID lookup: "+user.Gid, err) {
		return nil
	}
	gid32 := *(*uint32)(unsafe.Pointer(&gid))
	uid32 := *(*uint32)(unsafe.Pointer(&uid))

	var buff bytes.Buffer
	buff.WriteString(r.Command + " ")
	for _, arg := range r.Args {
		buff.WriteString(arg + " ")
	}
	cmd := exec.Command("/bin/bash", "-c", buff.String())
	cmd.Dir = r.WorkingDir
	cmd.SysProcAttr = &syscall.SysProcAttr{}
	cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uid32, Gid: gid32}

	return cmd
}

//prepare basic response
func genericResponse(req *RequestOptions) ResponseOptions {
	return ResponseOptions{
		Type:      config.Broker.ExecuteResponce,
		CommandId: req.CommandId,
		Id:        req.Id,
	}
}

func now() int64 {
	return time.Now().Unix()
}

func AttachContainer(name string, r RequestOptions, out_c chan<- ResponseOptions) {
	lxc_c, _ := lxc.NewContainer(name, config.Agent.LxcPrefix)
	opts := lxc.DefaultAttachOptions

	var res ResponseOptions = genericResponse(&r)

	o_read, o_write, _ := os.Pipe()
	e_read, e_write, _ := os.Pipe()

	var chunk bytes.Buffer
	defer o_read.Close()
	defer e_read.Close()

	opts.StdoutFd = o_write.Fd()
	opts.StderrFd = e_write.Fd()

	opts.UID, opts.GID = container.GetCredentials(r.RunAs, name)

	opts.Cwd = r.WorkingDir

	var exitCode int
	var cmd bytes.Buffer

	cmd.WriteString(r.Command)
	for _, a := range r.Args {
		cmd.WriteString(a + " ")
	}

	log.Debug("Executing command in container " + name + ":" + cmd.String())
	go func() {
		exitCode, _ = lxc_c.RunCommandStatus([]string{"timeout", strconv.Itoa(r.Timeout), "/bin/bash", "-c", cmd.String()}, opts)

		o_write.Close()
		e_write.Close()
	}()

	out := bufio.NewScanner(o_read)
	var e bytes.Buffer
	start_time := time.Now().Unix()

	res.ResponseNumber = 1
	for out.Scan() {
		//we have more stdout coming in
		//collect 1000 bytes and send the chunk
		chunk.WriteString(out.Text() + "\n")
		//send chunk every 1000 bytes or 10 seconds
		if chunk.Len() >= 1000 || now()-start_time >= 10 {
			res.StdOut = chunk.String()
			out_c <- res
			chunk.Truncate(0)
			res.ResponseNumber++
			start_time = now()
		}
	}

	io.Copy(&e, e_read)
	if exitCode == 0 {
		res.Type = config.Broker.ExecuteResponce
		res.ExitCode = strconv.Itoa(exitCode)
		if chunk.Len() > 0 {
			res.StdOut = chunk.String()
		}
		res.StdErr = e.String()
		out_c <- res
	} else {
		if exitCode/256 == 124 {
			res.Type = config.Broker.ExecuteTimeout
		}
		res.ExitCode = strconv.Itoa(exitCode / 256)
		res.StdOut = chunk.String()
		res.StdErr = e.String()
		out_c <- res
	}
	lxc.Release(lxc_c)
	close(out_c)
}
<commit_msg>Fixed early exitcode.<commit_after>package executer

import (
	"bufio"
	"bytes"
	"github.com/subutai-io/base/agent/agent/container"
	"github.com/subutai-io/base/agent/config"
	"github.com/subutai-io/base/agent/log"
	"gopkg.in/lxc/go-lxc.v2"
	"io"
	"os"
	"os/exec"
	"os/user"
	"strconv"
	"strings"
	"sync"
	"syscall"
	"time"
	"unsafe"
)

type EncRequest struct {
	HostId  string `json:"hostid"`
	Request string `json:"request"`
}
type Request struct {
	Id      string         `json:"id"`
	Request RequestOptions `json:"request"`
}

type RequestOptions struct {
	Type        string            `json:"type"`
	Id          string            `json:"id"`
	CommandId   string            `json:"commandId"`
	WorkingDir  string            `json:"workingDirectory"`
	Command     string            `json:"command"`
	Args        []string          `json:"args"`
	Environment map[string]string `json:"environment"`
	StdOut      string            `json:"stdOut"`
	StdErr      string            `json:"stdErr"`
	RunAs       string            `json:"runAs"`
	Timeout     int               `json:"timeout"`
	IsDaemon    int               `json:"isDaemon"`
}

type Response struct {
	ResponseOpts ResponseOptions `json:"response"`
	Id           string          `json:"id"`
}

type ResponseOptions struct {
	Type           string `json:"type"`
	Id             string `json:"id"`
	CommandId      string `json:"commandId"`
	Pid            int    `json:"pid"`
	ResponseNumber int    `json:"responseNumber,omitempty"`
	StdOut         string `json:"stdOut,omitempty"`
	StdErr         string `json:"stdErr,omitempty"`
	ExitCode       string `json:"exitCode,omitempty"`
}

func ExecHost(req RequestOptions, out_c chan<- ResponseOptions) {
	cmd := buildCmd(&req)
	if cmd == nil {
		close(out_c)
		return
	}
	//read/write pipes stdout
	rop, wop, _ := os.Pipe()
	//read/out pipes stderr
	rep, wep, _ := os.Pipe()

	defer rop.Close()
	defer rep.Close()

	cmd.Stdout = wop
	cmd.Stderr = wep
	if req.IsDaemon == 1 {
		cmd.SysProcAttr = &syscall.SysProcAttr{}
		cmd.SysProcAttr.Setpgid = true
		cmd.SysProcAttr.Credential = &syscall.Credential{Uid: 0, Gid: 0}
	}
	err := cmd.Start()
	log.Check(log.WarnLevel, "Executing command: "+req.CommandId+" "+req.Command+" "+strings.Join(req.Args, " "), err)

	wop.Close()
	wep.Close()

	start := time.Now().Unix()
	end := time.Now().Add(time.Duration(req.Timeout) * time.Second).Unix()
	var response = genericResponse(&req)
	response.ResponseNumber = 1
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()
		r := bufio.NewReader(rop)
		for line, isPrefix, err := r.ReadLine(); err == nil; line, isPrefix, err = r.ReadLine() {
			response.StdOut = response.StdOut + string(line)
			if !isPrefix {
				response.StdOut = response.StdOut + "\n"
			}
			if len(response.StdOut) > 50000 {
				out_c <- response
				start = now()
				response.StdErr, response.StdOut = "", ""
				response.ResponseNumber++
			}
		}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		scanErr := bufio.NewScanner(rep)
		for scanErr.Scan() {
			response.StdErr = response.StdErr + scanErr.Text() + "\n"
			if len(response.StdErr) > 50000 {
				out_c <- response
				start = now()
				response.StdErr, response.StdOut = "", ""
				response.ResponseNumber++
			}
		}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		for end-now() > 0 {
			if now()-start > 10 {
				out_c <- response
				start = now()
				response.StdErr, response.StdOut = "", ""
				response.ResponseNumber++
			}
			time.Sleep(time.Millisecond * 100)
		}
	}()

	done := make(chan error)
	go func() { done <- cmd.Wait() }()
	select {
	case <-done:
		end = -1
		wg.Wait()
		response.ExitCode = "0"
		if req.IsDaemon != 1 {
			response.ExitCode = strconv.Itoa(cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus())
		}
		out_c <- response
	case <-time.After(time.Duration(req.Timeout) * time.Second):
		if req.IsDaemon == 1 {
			response.ExitCode = "0"
			out_c <- response
			<-done
		} else {
			cmd.Process.Kill()
			response.Type = config.Broker.ExecuteTimeout
			cmd.Process.Wait()
			if cmd.ProcessState != nil {
				response.ExitCode = strconv.Itoa(cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus())
			} else {
				response.ExitCode = "-1"
			}
			out_c <- response
		}
		wg.Wait()
	}
	close(out_c)
}

func buildCmd(r *RequestOptions) *exec.Cmd {
	user, err := user.Lookup(r.RunAs)
	if log.Check(log.WarnLevel, "User lookup: "+r.RunAs, err) {
		return nil
	}
	uid, err := strconv.Atoi(user.Uid)
	if log.Check(log.WarnLevel, "UID lookup: "+user.Uid, err) {
		return nil
	}
	gid, err := strconv.Atoi(user.Gid)
	if log.Check(log.WarnLevel, "GID lookup: "+user.Gid, err) {
		return nil
	}
	gid32 := *(*uint32)(unsafe.Pointer(&gid))
	uid32 := *(*uint32)(unsafe.Pointer(&uid))

	var buff bytes.Buffer
	buff.WriteString(r.Command + " ")
	for _, arg := range r.Args {
		buff.WriteString(arg + " ")
	}
	cmd := exec.Command("/bin/bash", "-c", buff.String())
	cmd.Dir = r.WorkingDir
	cmd.SysProcAttr = &syscall.SysProcAttr{}
	cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uid32, Gid: gid32}

	return cmd
}

//prepare basic response
func genericResponse(req *RequestOptions) ResponseOptions {
	return ResponseOptions{
		Type:      config.Broker.ExecuteResponce,
		CommandId: req.CommandId,
		Id:        req.Id,
	}
}

func now() int64 {
	return time.Now().Unix()
}

func AttachContainer(name string, r RequestOptions, out_c chan<- ResponseOptions) {
	lxc_c, _ := lxc.NewContainer(name, config.Agent.LxcPrefix)
	opts := lxc.DefaultAttachOptions

	var res ResponseOptions = genericResponse(&r)

	o_read, o_write, _ := os.Pipe()
	e_read, e_write, _ := os.Pipe()

	var chunk bytes.Buffer
	defer o_read.Close()
	defer e_read.Close()

	opts.StdoutFd = o_write.Fd()
	opts.StderrFd = e_write.Fd()

	opts.UID, opts.GID = container.GetCredentials(r.RunAs, name)

	opts.Cwd = r.WorkingDir

	var exitCode int
	var cmd bytes.Buffer

	cmd.WriteString(r.Command)
	for _, a := range r.Args {
		cmd.WriteString(a + " ")
	}

	log.Debug("Executing command in container " + name + ":" + cmd.String())
	go func() {
		exitCode, _ = lxc_c.RunCommandStatus([]string{"timeout", strconv.Itoa(r.Timeout), "/bin/bash", "-c", cmd.String()}, opts)

		o_write.Close()
		e_write.Close()
	}()

	out := bufio.NewScanner(o_read)
	var e bytes.Buffer
	start_time := time.Now().Unix()

	res.ResponseNumber = 1
	for out.Scan() {
		//we have more stdout coming in
		//collect 1000 bytes and send the chunk
		chunk.WriteString(out.Text() + "\n")
		//send chunk every 1000 bytes or 10 seconds
		if chunk.Len() >= 1000 || now()-start_time >= 10 {
			res.StdOut = chunk.String()
			out_c <- res
			chunk.Truncate(0)
			res.ResponseNumber++
			start_time = now()
		}
	}

	io.Copy(&e, e_read)
	if exitCode == 0 {
		res.Type = config.Broker.ExecuteResponce
		res.ExitCode = strconv.Itoa(exitCode)
		if chunk.Len() > 0 {
			res.StdOut = chunk.String()
		}
		res.StdErr = e.String()
		out_c <- res
	} else {
		if exitCode/256 == 124 {
			res.Type = config.Broker.ExecuteTimeout
		}
		res.ExitCode = strconv.Itoa(exitCode / 256)
		res.StdOut = chunk.String()
		res.StdErr = e.String()
		out_c <- res
	}
	lxc.Release(lxc_c)
	close(out_c)
}
<|endoftext|>


<commit_before>// [ $GOOS != nacl ] || exit 0  # NaCl runner elides NUL in output
// [ $GORUN != "a" ] || exit 0  # Android runner gets confused by the NUL output
// $G $D/$F.go && $L $F.$A && ./$A.out >tmp.go &&
// errchk $G -e tmp.go
// rm -f tmp.go

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Test source files and strings containing NUL and invalid UTF-8.

package main

import (
	"fmt"
	"os"
)

func main() {
	var s = "\xc2\xff"
	var t = "\xd0\xfe"
	var u = "\xab\x00\xfc"

	if len(s) != 2 || s[0] != 0xc2 || s[1] != 0xff ||
		len(t) != 2 || t[0] != 0xd0 || t[1] != 0xfe ||
		len(u) != 3 || u[0] != 0xab || u[1] != 0x00 || u[2] != 0xfc {
		println("BUG: non-UTF-8 string mangled");
		os.Exit(2)
	}

	fmt.Print(`
package main

var x = "in string ` + "\x00" + `"	// ERROR "NUL"

var y = ` + "`in raw string \x00 foo`" + `  // ERROR "NUL"

// in comment ` + "\x00" + `  // ERROR "NUL"

/* in other comment ` + "\x00" + ` */ // ERROR "NUL"

/* in source code */ ` + "\x00" + `// ERROR "NUL"

var xx = "in string ` + "\xc2\xff" + `" // ERROR "UTF-8"

var yy = ` + "`in raw string \xff foo`" + `  // ERROR "UTF-8"

// in comment ` + "\xe2\x80\x01" + `  // ERROR "UTF-8"

/* in other comment ` + "\xe0\x00\x00" + ` */ // ERROR "UTF-8"

/* in variable name */
var z` + "\xc1\x81" + ` int // ERROR "UTF-8"

/* in source code */ ` + "\xc2A" + `// ERROR "UTF-8"

`)
}

<commit_msg>fix build<commit_after>// [ $GOOS != nacl ] || exit 0  # NaCl runner elides NUL in output
// [ "$GORUN" != "a" ] || exit 0  # Android runner gets confused by the NUL output
// $G $D/$F.go && $L $F.$A && ./$A.out >tmp.go &&
// errchk $G -e tmp.go
// rm -f tmp.go

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Test source files and strings containing NUL and invalid UTF-8.

package main

import (
	"fmt"
	"os"
)

func main() {
	var s = "\xc2\xff"
	var t = "\xd0\xfe"
	var u = "\xab\x00\xfc"

	if len(s) != 2 || s[0] != 0xc2 || s[1] != 0xff ||
		len(t) != 2 || t[0] != 0xd0 || t[1] != 0xfe ||
		len(u) != 3 || u[0] != 0xab || u[1] != 0x00 || u[2] != 0xfc {
		println("BUG: non-UTF-8 string mangled");
		os.Exit(2)
	}

	fmt.Print(`
package main

var x = "in string ` + "\x00" + `"	// ERROR "NUL"

var y = ` + "`in raw string \x00 foo`" + `  // ERROR "NUL"

// in comment ` + "\x00" + `  // ERROR "NUL"

/* in other comment ` + "\x00" + ` */ // ERROR "NUL"

/* in source code */ ` + "\x00" + `// ERROR "NUL"

var xx = "in string ` + "\xc2\xff" + `" // ERROR "UTF-8"

var yy = ` + "`in raw string \xff foo`" + `  // ERROR "UTF-8"

// in comment ` + "\xe2\x80\x01" + `  // ERROR "UTF-8"

/* in other comment ` + "\xe0\x00\x00" + ` */ // ERROR "UTF-8"

/* in variable name */
var z` + "\xc1\x81" + ` int // ERROR "UTF-8"

/* in source code */ ` + "\xc2A" + `// ERROR "UTF-8"

`)
}

<|endoftext|>


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

// +build !go1.7

package context

import (
	"errors"
	"fmt"
	"sync"
	"time"
)

// An emptyCtx is never canceled, has no values, and has no deadline.  It is not
// struct{}, since vars of this type must have distinct addresses.
type emptyCtx int

func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
	return
}

func (*emptyCtx) Done() <-chan struct{} {
	return nil
}

func (*emptyCtx) Err() error {
	return nil
}

func (*emptyCtx) Value(key interface{}) interface{} {
	return nil
}

func (e *emptyCtx) String() string {
	switch e {
	case background:
		return "context.Background"
	case todo:
		return "context.TODO"
	}
	return "unknown empty Context"
}

var (
	background = new(emptyCtx)
	todo       = new(emptyCtx)
)

// Canceled is the error returned by Context.Err when the context is canceled.
var Canceled = errors.New("context canceled")

// DeadlineExceeded is the error returned by Context.Err when the context's
// deadline passes.
var DeadlineExceeded = errors.New("context deadline exceeded")

// WithCancel returns a copy of parent with a new Done channel. The returned
// context's Done channel is closed when the returned cancel function is called
// or when the parent context's Done channel is closed, whichever happens first.
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this Context complete.
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
	c := newCancelCtx(parent)
	propagateCancel(parent, c)
	return c, func() { c.cancel(true, Canceled) }
}

// newCancelCtx returns an initialized cancelCtx.
func newCancelCtx(parent Context) *cancelCtx {
	return &cancelCtx{
		Context: parent,
		done:    make(chan struct{}),
	}
}

// propagateCancel arranges for child to be canceled when parent is.
func propagateCancel(parent Context, child canceler) {
	if parent.Done() == nil {
		return // parent is never canceled
	}
	if p, ok := parentCancelCtx(parent); ok {
		p.mu.Lock()
		if p.err != nil {
			// parent has already been canceled
			child.cancel(false, p.err)
		} else {
			if p.children == nil {
				p.children = make(map[canceler]bool)
			}
			p.children[child] = true
		}
		p.mu.Unlock()
	} else {
		go func() {
			select {
			case <-parent.Done():
				child.cancel(false, parent.Err())
			case <-child.Done():
			}
		}()
	}
}

// parentCancelCtx follows a chain of parent references until it finds a
// *cancelCtx.  This function understands how each of the concrete types in this
// package represents its parent.
func parentCancelCtx(parent Context) (*cancelCtx, bool) {
	for {
		switch c := parent.(type) {
		case *cancelCtx:
			return c, true
		case *timerCtx:
			return c.cancelCtx, true
		case *valueCtx:
			parent = c.Context
		default:
			return nil, false
		}
	}
}

// removeChild removes a context from its parent.
func removeChild(parent Context, child canceler) {
	p, ok := parentCancelCtx(parent)
	if !ok {
		return
	}
	p.mu.Lock()
	if p.children != nil {
		delete(p.children, child)
	}
	p.mu.Unlock()
}

// A canceler is a context type that can be canceled directly.  The
// implementations are *cancelCtx and *timerCtx.
type canceler interface {
	cancel(removeFromParent bool, err error)
	Done() <-chan struct{}
}

// A cancelCtx can be canceled.  When canceled, it also cancels any children
// that implement canceler.
type cancelCtx struct {
	Context

	done chan struct{} // closed by the first cancel call.

	mu       sync.Mutex
	children map[canceler]bool // set to nil by the first cancel call
	err      error             // set to non-nil by the first cancel call
}

func (c *cancelCtx) Done() <-chan struct{} {
	return c.done
}

func (c *cancelCtx) Err() error {
	c.mu.Lock()
	defer c.mu.Unlock()
	return c.err
}

func (c *cancelCtx) String() string {
	return fmt.Sprintf("%v.WithCancel", c.Context)
}

// cancel closes c.done, cancels each of c's children, and, if
// removeFromParent is true, removes c from its parent's children.
func (c *cancelCtx) cancel(removeFromParent bool, err error) {
	if err == nil {
		panic("context: internal error: missing cancel error")
	}
	c.mu.Lock()
	if c.err != nil {
		c.mu.Unlock()
		return // already canceled
	}
	c.err = err
	close(c.done)
	for child := range c.children {
		// NOTE: acquiring the child's lock while holding parent's lock.
		child.cancel(false, err)
	}
	c.children = nil
	c.mu.Unlock()

	if removeFromParent {
		removeChild(c.Context, c)
	}
}

// WithDeadline returns a copy of the parent context with the deadline adjusted
// to be no later than d.  If the parent's deadline is already earlier than d,
// WithDeadline(parent, d) is semantically equivalent to parent.  The returned
// context's Done channel is closed when the deadline expires, when the returned
// cancel function is called, or when the parent context's Done channel is
// closed, whichever happens first.
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this Context complete.
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
	if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
		// The current deadline is already sooner than the new one.
		return WithCancel(parent)
	}
	c := &timerCtx{
		cancelCtx: newCancelCtx(parent),
		deadline:  deadline,
	}
	propagateCancel(parent, c)
	d := deadline.Sub(time.Now())
	if d <= 0 {
		c.cancel(true, DeadlineExceeded) // deadline has already passed
		return c, func() { c.cancel(true, Canceled) }
	}
	c.mu.Lock()
	defer c.mu.Unlock()
	if c.err == nil {
		c.timer = time.AfterFunc(d, func() {
			c.cancel(true, DeadlineExceeded)
		})
	}
	return c, func() { c.cancel(true, Canceled) }
}

// A timerCtx carries a timer and a deadline.  It embeds a cancelCtx to
// implement Done and Err.  It implements cancel by stopping its timer then
// delegating to cancelCtx.cancel.
type timerCtx struct {
	*cancelCtx
	timer *time.Timer // Under cancelCtx.mu.

	deadline time.Time
}

func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
	return c.deadline, true
}

func (c *timerCtx) String() string {
	return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
}

func (c *timerCtx) cancel(removeFromParent bool, err error) {
	c.cancelCtx.cancel(false, err)
	if removeFromParent {
		// Remove this timerCtx from its parent cancelCtx's children.
		removeChild(c.cancelCtx.Context, c)
	}
	c.mu.Lock()
	if c.timer != nil {
		c.timer.Stop()
		c.timer = nil
	}
	c.mu.Unlock()
}

// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
//
// Canceling this context releases resources associated with it, so code should
// call cancel as soon as the operations running in this Context complete:
//
// 	func slowOperationWithTimeout(ctx context.Context) (Result, error) {
// 		ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
// 		defer cancel()  // releases resources if slowOperation completes before timeout elapses
// 		return slowOperation(ctx)
// 	}
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
	return WithDeadline(parent, time.Now().Add(timeout))
}

// WithValue returns a copy of parent in which the value associated with key is
// val.
//
// Use context Values only for request-scoped data that transits processes and
// APIs, not for passing optional parameters to functions.
func WithValue(parent Context, key interface{}, val interface{}) Context {
	return &valueCtx{parent, key, val}
}

// A valueCtx carries a key-value pair.  It implements Value for that key and
// delegates all other calls to the embedded Context.
type valueCtx struct {
	Context
	key, val interface{}
}

func (c *valueCtx) String() string {
	return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
}

func (c *valueCtx) Value(key interface{}) interface{} {
	if c.key == key {
		return c.val
	}
	return c.Context.Value(key)
}
<commit_msg>Delete pre_go17.go<commit_after><|endoftext|>


<commit_before>package util

import (
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strconv"
	"sync"
	"time"
)

type HTTPClientIface interface {
	Get(*http.Request) ([]byte, int, error)
	Post(*http.Request) ([]byte, int, error)
	Do(*http.Request) ([]byte, int, error)
}

type Response struct {
	Response *http.Response
	Err      error
}

type HTTPClient struct {
	Timeout int
	client  *http.Client
}

func NewHTTPClient(timeout int, client *http.Client) *HTTPClient {
	var c = http.DefaultClient
	if client != nil {
		c = client
	}
	hc := &HTTPClient{
		Timeout: timeout,
		client:  c,
	}
	hc.client.Timeout = time.Duration(timeout) * time.Second

	return hc
}

// NewHTTPReqeust makes a http request
func NewHTTPReqeust(method, url string, queries, headers map[string]string, body []byte) (*http.Request, error) {
	req, err := http.NewRequest(method, url, nil)
	if err != nil {
		return nil, err
	}

	if queries != nil {
		query := req.URL.Query()
		for key, val := range queries {
			query.Set(key, val)
		}
		req.URL.RawQuery = query.Encode()
	}

	if headers != nil {
		for key, val := range headers {
			req.Header.Set(key, val)
		}
	}

	if body != nil {
		req.Body = ioutil.NopCloser(bytes.NewReader(body))
	}

	return req, nil
}

func (hc *HTTPClient) Do(req *http.Request) ([]byte, int, error) {
	res, err := hc.client.Do(req)
	if err != nil {
		return nil, 0, err
	}

	if res.StatusCode != http.StatusOK {
		return nil, res.StatusCode, fmt.Errorf("resp code is %d", res.StatusCode)
	}

	b, err := ioutil.ReadAll(res.Body)
	defer res.Body.Close()

	if err != nil {
		return nil, res.StatusCode, err
	}

	return b, res.StatusCode, nil
}

// DoParallel http requests, and get response list. Response could be nil
func (hc *HTTPClient) DoParallel(reqs ...*http.Request) []*Response {
	var reqNum = len(reqs)
	var resps = make([]*Response, reqNum)
	var wg sync.WaitGroup
	for i := 0; i < reqNum; i++ {
		wg.Add(1)
		defer wg.Done()
		var resp Response
		resp.Response, resp.Err = hc.client.Do(reqs[i])
		resps[i] = &resp
	}
	wg.Wait()
	return resps
}

// Get returns http response body in []byte, timeout in second
func (hc *HTTPClient) Get(req *http.Request) ([]byte, int, error) {
	req.Method = "GET"
	return hc.Do(req)
}

// Post do http post
func (hc *HTTPClient) Post(req *http.Request) ([]byte, int, error) {
	req.Method = "POST"
	return hc.Do(req)
}

// GetReadCloser for downloading file
func (hc *HTTPClient) GetReadCloser(req *http.Request) (io.ReadCloser, string, int, error) {
	var err error
	var res *http.Response

	res, err = hc.client.Do(req)
	if err != nil {
		return nil, "", 0, err
	}

	if res.StatusCode != http.StatusOK {
		return nil, "", 0, fmt.Errorf("resp code is %d", res.StatusCode)
	}

	contentType := res.Header.Get("Content-Type")
	contentLength, err := strconv.Atoi(res.Header.Get("Content-Length"))
	if err != nil {
		return nil, "", 0, err
	}

	return res.Body, contentType, contentLength, nil
}

func MustLoadCertificates(privateKeyFile, certificateFile, caFile string) (tls.Certificate, *x509.CertPool) {
	mycert, err := tls.LoadX509KeyPair(certificateFile, privateKeyFile)
	if err != nil {
		panic(err)
	}
	pem, err := ioutil.ReadFile(caFile)
	if err != nil {
		panic(err)
	}

	certPool := x509.NewCertPool()
	if !certPool.AppendCertsFromPEM(pem) {
		panic("Failed appending certs")
	}

	return mycert, certPool
}

func MustGetTlsConfiguration(privateKeyFile, certificateFile, caFile string) *tls.Config {
	config := &tls.Config{}
	mycert, certPool := MustLoadCertificates(privateKeyFile, certificateFile, caFile)
	config.Certificates = make([]tls.Certificate, 1)
	config.Certificates[0] = mycert

	config.RootCAs = certPool
	config.ClientCAs = certPool
	config.InsecureSkipVerify = true

	//config.ClientAuth = tls.RequireAndVerifyClientCert

	//Optional stuff

	//Use only modern ciphers
	config.CipherSuites = []uint16{tls.TLS_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}

	//Use only TLS v1.2
	config.MinVersion = tls.VersionTLS12

	//Don't allow session resumption
	// config.SessionTicketsDisabled = true
	return config
}
<commit_msg>fix do parallel<commit_after>package util

import (
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strconv"
	"sync"
	"time"
)

type HTTPClientIface interface {
	Get(*http.Request) ([]byte, int, error)
	Post(*http.Request) ([]byte, int, error)
	Do(*http.Request) ([]byte, int, error)
	DoParallel(...*http.Request) []*Response
}

type Response struct {
	Response *http.Response
	Err      error
}

type HTTPClient struct {
	Timeout int
	client  *http.Client
}

func NewHTTPClient(timeout int, client *http.Client) *HTTPClient {
	var c = http.DefaultClient
	if client != nil {
		c = client
	}
	hc := &HTTPClient{
		Timeout: timeout,
		client:  c,
	}
	hc.client.Timeout = time.Duration(timeout) * time.Second

	return hc
}

// NewHTTPReqeust makes a http request
func NewHTTPReqeust(method, url string, queries, headers map[string]string, body []byte) (*http.Request, error) {
	req, err := http.NewRequest(method, url, nil)
	if err != nil {
		return nil, err
	}

	if queries != nil {
		query := req.URL.Query()
		for key, val := range queries {
			query.Set(key, val)
		}
		req.URL.RawQuery = query.Encode()
	}

	if headers != nil {
		for key, val := range headers {
			req.Header.Set(key, val)
		}
	}

	if body != nil {
		req.Body = ioutil.NopCloser(bytes.NewReader(body))
	}

	return req, nil
}

func (hc *HTTPClient) Do(req *http.Request) ([]byte, int, error) {
	res, err := hc.client.Do(req)
	if err != nil {
		return nil, 0, err
	}

	if res.StatusCode != http.StatusOK {
		return nil, res.StatusCode, fmt.Errorf("resp code is %d", res.StatusCode)
	}

	b, err := ioutil.ReadAll(res.Body)
	defer res.Body.Close()

	if err != nil {
		return nil, res.StatusCode, err
	}

	return b, res.StatusCode, nil
}

// DoParallel http requests, and get response list. Response could be nil
func (hc *HTTPClient) DoParallel(reqs ...*http.Request) []*Response {
	var reqNum = len(reqs)
	var resps = make([]*Response, reqNum)
	var wg sync.WaitGroup
	for i := 0; i < reqNum; i++ {
		go func(idx int) {
			wg.Add(1)
			var resp Response
			resp.Response, resp.Err = hc.client.Do(reqs[idx])
			resps[idx] = &resp
			wg.Done()
		}(i)
	}
	wg.Wait()
	return resps
}

// Get returns http response body in []byte, timeout in second
func (hc *HTTPClient) Get(req *http.Request) ([]byte, int, error) {
	req.Method = "GET"
	return hc.Do(req)
}

// Post do http post
func (hc *HTTPClient) Post(req *http.Request) ([]byte, int, error) {
	req.Method = "POST"
	return hc.Do(req)
}

// GetReadCloser for downloading file
func (hc *HTTPClient) GetReadCloser(req *http.Request) (io.ReadCloser, string, int, error) {
	var err error
	var res *http.Response

	res, err = hc.client.Do(req)
	if err != nil {
		return nil, "", 0, err
	}

	if res.StatusCode != http.StatusOK {
		return nil, "", 0, fmt.Errorf("resp code is %d", res.StatusCode)
	}

	contentType := res.Header.Get("Content-Type")
	contentLength, err := strconv.Atoi(res.Header.Get("Content-Length"))
	if err != nil {
		return nil, "", 0, err
	}

	return res.Body, contentType, contentLength, nil
}

func MustLoadCertificates(privateKeyFile, certificateFile, caFile string) (tls.Certificate, *x509.CertPool) {
	mycert, err := tls.LoadX509KeyPair(certificateFile, privateKeyFile)
	if err != nil {
		panic(err)
	}
	pem, err := ioutil.ReadFile(caFile)
	if err != nil {
		panic(err)
	}

	certPool := x509.NewCertPool()
	if !certPool.AppendCertsFromPEM(pem) {
		panic("Failed appending certs")
	}

	return mycert, certPool
}

func MustGetTlsConfiguration(privateKeyFile, certificateFile, caFile string) *tls.Config {
	config := &tls.Config{}
	mycert, certPool := MustLoadCertificates(privateKeyFile, certificateFile, caFile)
	config.Certificates = make([]tls.Certificate, 1)
	config.Certificates[0] = mycert

	config.RootCAs = certPool
	config.ClientCAs = certPool
	config.InsecureSkipVerify = true

	//config.ClientAuth = tls.RequireAndVerifyClientCert

	//Optional stuff

	//Use only modern ciphers
	config.CipherSuites = []uint16{tls.TLS_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
		tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
		tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}

	//Use only TLS v1.2
	config.MinVersion = tls.VersionTLS12

	//Don't allow session resumption
	// config.SessionTicketsDisabled = true
	return config
}
<|endoftext|>


<commit_before>// Copyright 2016 The OPA Authors.  All rights reserved.
// Use of this source code is governed by an Apache2
// license that can be found in the LICENSE file.

package util

import (
	"bytes"
	"encoding/json"
	"io"
)

// UnmarshalJSON parses the JSON encoded data and stores the result in the value
// pointed to by x.
//
// This function is intended to be used in place of the standard json.Marshal
// function when json.Number is required.
func UnmarshalJSON(bs []byte, x interface{}) (err error) {
	buf := bytes.NewBuffer(bs)
	decoder := NewJSONDecoder(buf)
	return decoder.Decode(x)
}

// NewJSONDecoder returns a new decoder that reads from r.
//
// This function is intended to be used in place of the standard json.NewDecoder
// when json.Number is required.
func NewJSONDecoder(r io.Reader) *json.Decoder {
	decoder := json.NewDecoder(r)
	decoder.UseNumber()
	return decoder
}

// MustUnmarshalJSON parse the JSON encoded data and returns the result.
//
// If the data cannot be decoded, this function will panic. This function is for
// test purposes.
func MustUnmarshalJSON(bs []byte) interface{} {
	var x interface{}
	if err := UnmarshalJSON(bs, &x); err != nil {
		panic(err)
	}
	return x
}

// MustMarshalJSON returns the JSON encoding of x
//
// If the data cannot be encoded, this function will panic. This function is for
// test purposes.
func MustMarshalJSON(x interface{}) []byte {
	bs, err := json.Marshal(x)
	if err != nil {
		panic(err)
	}
	return bs
}

// RoundTrip encodes to JSON, and decodes the result again.
//
// Thereby, it is converting its argument to the representation expected by
// rego.Input and inmem's Write operations. Works with both references and
// values.
func RoundTrip(x *interface{}) error {
	bs, err := json.Marshal(x)
	if err != nil {
		return err
	}
	return json.Unmarshal(bs, x)
}
<commit_msg>util.RoundTrip(): use neighbouring UnmarshalJSON function<commit_after>// Copyright 2016 The OPA Authors.  All rights reserved.
// Use of this source code is governed by an Apache2
// license that can be found in the LICENSE file.

package util

import (
	"bytes"
	"encoding/json"
	"io"
)

// UnmarshalJSON parses the JSON encoded data and stores the result in the value
// pointed to by x.
//
// This function is intended to be used in place of the standard json.Marshal
// function when json.Number is required.
func UnmarshalJSON(bs []byte, x interface{}) (err error) {
	buf := bytes.NewBuffer(bs)
	decoder := NewJSONDecoder(buf)
	return decoder.Decode(x)
}

// NewJSONDecoder returns a new decoder that reads from r.
//
// This function is intended to be used in place of the standard json.NewDecoder
// when json.Number is required.
func NewJSONDecoder(r io.Reader) *json.Decoder {
	decoder := json.NewDecoder(r)
	decoder.UseNumber()
	return decoder
}

// MustUnmarshalJSON parse the JSON encoded data and returns the result.
//
// If the data cannot be decoded, this function will panic. This function is for
// test purposes.
func MustUnmarshalJSON(bs []byte) interface{} {
	var x interface{}
	if err := UnmarshalJSON(bs, &x); err != nil {
		panic(err)
	}
	return x
}

// MustMarshalJSON returns the JSON encoding of x
//
// If the data cannot be encoded, this function will panic. This function is for
// test purposes.
func MustMarshalJSON(x interface{}) []byte {
	bs, err := json.Marshal(x)
	if err != nil {
		panic(err)
	}
	return bs
}

// RoundTrip encodes to JSON, and decodes the result again.
//
// Thereby, it is converting its argument to the representation expected by
// rego.Input and inmem's Write operations. Works with both references and
// values.
func RoundTrip(x *interface{}) error {
	bs, err := json.Marshal(x)
	if err != nil {
		return err
	}
	return UnmarshalJSON(bs, x)
}
<|endoftext|>


<commit_before>// Copyright 2012 Google, Inc. All rights reserved.
// Copyright 2009-2011 Andreas Krennmair. All rights reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree.

package layers

import (
	"code.google.com/p/gopacket"
	"encoding/binary"
	"fmt"
	"net"
)

// IPv6 is the layer for the IPv6 header.
type IPv6 struct {
	// http://www.networksorcery.com/enp/protocol/ipv6.htm
	BaseLayer
	Version      uint8
	TrafficClass uint8
	FlowLabel    uint32
	Length       uint16
	NextHeader   IPProtocol
	HopLimit     uint8
	SrcIP        net.IP
	DstIP        net.IP
	HopByHop     *IPv6HopByHop
	// hbh will be pointed to by HopByHop if that layer exists.
	hbh IPv6HopByHop
}

// LayerType returns LayerTypeIPv6
func (i *IPv6) LayerType() gopacket.LayerType { return LayerTypeIPv6 }
func (i *IPv6) NetworkFlow() gopacket.Flow {
	return gopacket.NewFlow(EndpointIPv6, i.SrcIP, i.DstIP)
}

const (
	IPv6HopByHopOptionJumbogram = 0xC2 // RFC 2675
)

// SerializeTo writes the serialized form of this layer into the
// SerializationBuffer, implementing gopacket.SerializableLayer.
// See the docs for gopacket.SerializableLayer for more info.
func (ip6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
	payload := b.Bytes()
	if ip6.HopByHop != nil {
		return fmt.Errorf("unable to serialize hopbyhop for now")
	}
	bytes, err := b.PrependBytes(40)
	if err != nil {
		return err
	}
	bytes[0] = (ip6.Version << 4) | (ip6.TrafficClass >> 4)
	bytes[1] = (ip6.TrafficClass << 4) | uint8(ip6.FlowLabel>>16)
	binary.BigEndian.PutUint16(bytes[2:], uint16(ip6.FlowLabel))
	if opts.FixLengths {
		ip6.Length = uint16(len(payload))
	}
	binary.BigEndian.PutUint16(bytes[4:], ip6.Length)
	bytes[6] = byte(ip6.NextHeader)
	bytes[7] = byte(ip6.HopLimit)
	if len(ip6.SrcIP) != 16 {
		return fmt.Errorf("invalid src ip %v", ip6.SrcIP)
	}
	if len(ip6.DstIP) != 16 {
		return fmt.Errorf("invalid dst ip %v", ip6.DstIP)
	}
	copy(bytes[8:], ip6.SrcIP)
	copy(bytes[24:], ip6.DstIP)
	return nil
}

func (ip6 *IPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
	ip6.Version = uint8(data[0]) >> 4
	ip6.TrafficClass = uint8((binary.BigEndian.Uint16(data[0:2]) >> 4) & 0x00FF)
	ip6.FlowLabel = binary.BigEndian.Uint32(data[0:4]) & 0x000FFFFF
	ip6.Length = binary.BigEndian.Uint16(data[4:6])
	ip6.NextHeader = IPProtocol(data[6])
	ip6.HopLimit = data[7]
	ip6.SrcIP = data[8:24]
	ip6.DstIP = data[24:40]
	ip6.HopByHop = nil
	// We initially set the payload to all bytes after 40.  ip6.Length or the
	// HopByHop jumbogram option can both change this eventually, though.
	ip6.BaseLayer = BaseLayer{data[:40], data[40:]}

	// We treat a HopByHop IPv6 option as part of the IPv6 packet, since its
	// options are crucial for understanding what's actually happening per packet.
	if ip6.NextHeader == IPProtocolIPv6HopByHop {
		ip6.hbh.DecodeFromBytes(ip6.Payload, df)
		hbhLen := len(ip6.hbh.Contents)
		// Reset IPv6 contents to include the HopByHop header.
		ip6.BaseLayer = BaseLayer{data[:40+hbhLen], data[40+hbhLen:]}
		ip6.HopByHop = &ip6.hbh
		if ip6.Length == 0 {
			for _, o := range ip6.hbh.Options {
				if o.OptionType == IPv6HopByHopOptionJumbogram {
					if len(o.OptionData) != 4 {
						return fmt.Errorf("Invalid jumbo packet option length")
					}
					payloadLength := binary.BigEndian.Uint32(o.OptionData)
					pEnd := int(payloadLength)
					if pEnd > len(ip6.Payload) {
						df.SetTruncated()
					} else {
						ip6.Payload = ip6.Payload[:pEnd]
						ip6.hbh.Payload = ip6.Payload
					}
					return nil
				}
			}
			return fmt.Errorf("IPv6 length 0, but HopByHop header does not have jumbogram option")
		}
	}
	if ip6.Length == 0 {
		return fmt.Errorf("IPv6 length 0, but next header is %v, not HopByHop", ip6.NextHeader)
	} else {
		pEnd := int(ip6.Length)
		if pEnd > len(ip6.Payload) {
			df.SetTruncated()
			pEnd = len(ip6.Payload)
		}
		ip6.Payload = ip6.Payload[:pEnd]
	}
	return nil
}

func (i *IPv6) CanDecode() gopacket.LayerClass {
	return LayerTypeIPv6
}
func (i *IPv6) NextLayerType() gopacket.LayerType {
	if i.HopByHop != nil {
		return i.HopByHop.NextHeader.LayerType()
	}
	return i.NextHeader.LayerType()
}

func decodeIPv6(data []byte, p gopacket.PacketBuilder) error {
	ip6 := &IPv6{}
	err := ip6.DecodeFromBytes(data, p)
	p.AddLayer(ip6)
	p.SetNetworkLayer(ip6)
	if ip6.HopByHop != nil {
		// TODO(gconnell):  Since HopByHop is now an integral part of the IPv6
		// layer, should it actually be added as its own layer?  I'm leaning towards
		// no.
		p.AddLayer(ip6.HopByHop)
	}
	if err != nil {
		return err
	}
	if ip6.HopByHop != nil {
		return p.NextDecoder(ip6.HopByHop.NextHeader)
	}
	return p.NextDecoder(ip6.NextHeader)
}

func (i *IPv6HopByHop) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
	i.ipv6ExtensionBase = decodeIPv6ExtensionBase(data)
	i.Options = i.opts[:0]
	var opt *IPv6HopByHopOption
	for d := i.Contents[2:]; len(d) > 0; d = d[opt.ActualLength:] {
		i.Options = append(i.Options, IPv6HopByHopOption(decodeIPv6HeaderTLVOption(d)))
		opt = &i.Options[len(i.Options)-1]
	}
	return nil
}

func decodeIPv6HopByHop(data []byte, p gopacket.PacketBuilder) error {
	i := &IPv6HopByHop{}
	err := i.DecodeFromBytes(data, p)
	p.AddLayer(i)
	if err != nil {
		return err
	}
	return p.NextDecoder(i.NextHeader)
}

type ipv6HeaderTLVOption struct {
	OptionType, OptionLength uint8
	ActualLength             int
	OptionData               []byte
}

func decodeIPv6HeaderTLVOption(data []byte) (h ipv6HeaderTLVOption) {
	if data[0] == 0 {
		h.ActualLength = 1
		return
	}
	h.OptionType = data[0]
	h.OptionLength = data[1]
	h.ActualLength = int(h.OptionLength) + 2
	h.OptionData = data[2:h.ActualLength]
	return
}

// IPv6HopByHopOption is a TLV option present in an IPv6 hop-by-hop extension.
type IPv6HopByHopOption ipv6HeaderTLVOption

type ipv6ExtensionBase struct {
	BaseLayer
	NextHeader   IPProtocol
	HeaderLength uint8
	ActualLength int
}

func decodeIPv6ExtensionBase(data []byte) (i ipv6ExtensionBase) {
	i.NextHeader = IPProtocol(data[0])
	i.HeaderLength = data[1]
	i.ActualLength = int(i.HeaderLength)*8 + 8
	i.Contents = data[:i.ActualLength]
	i.Payload = data[i.ActualLength:]
	return
}

// IPv6ExtensionSkipper is a DecodingLayer which decodes and ignores v6
// extensions.  You can use it with a DecodingLayerParser to handle IPv6 stacks
// which may or may not have extensions.
type IPv6ExtensionSkipper struct {
	NextHeader IPProtocol
	BaseLayer
}

func (i *IPv6ExtensionSkipper) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
	extension := decodeIPv6ExtensionBase(data)
	i.BaseLayer = BaseLayer{data[:extension.ActualLength], data[extension.ActualLength:]}
	i.NextHeader = extension.NextHeader
	return nil
}
func (i *IPv6ExtensionSkipper) CanDecode() gopacket.LayerClass {
	return LayerClassIPv6Extension
}
func (i *IPv6ExtensionSkipper) NextLayerType() gopacket.LayerType {
	return i.NextHeader.LayerType()
}

// IPv6HopByHop is the IPv6 hop-by-hop extension.
type IPv6HopByHop struct {
	ipv6ExtensionBase
	Options []IPv6HopByHopOption
	opts    [2]IPv6HopByHopOption
}

// LayerType returns LayerTypeIPv6HopByHop.
func (i *IPv6HopByHop) LayerType() gopacket.LayerType { return LayerTypeIPv6HopByHop }

// IPv6Routing is the IPv6 routing extension.
type IPv6Routing struct {
	ipv6ExtensionBase
	RoutingType  uint8
	SegmentsLeft uint8
	// This segment is supposed to be zero according to RFC2460, the second set of
	// 4 bytes in the extension.
	Reserved []byte
	// SourceRoutingIPs is the set of IPv6 addresses requested for source routing,
	// set only if RoutingType == 0.
	SourceRoutingIPs []net.IP
}

// LayerType returns LayerTypeIPv6Routing.
func (i *IPv6Routing) LayerType() gopacket.LayerType { return LayerTypeIPv6Routing }

func decodeIPv6Routing(data []byte, p gopacket.PacketBuilder) error {
	i := &IPv6Routing{
		ipv6ExtensionBase: decodeIPv6ExtensionBase(data),
		RoutingType:       data[2],
		SegmentsLeft:      data[3],
		Reserved:          data[4:8],
	}
	switch i.RoutingType {
	case 0: // Source routing
		if (len(data)-8)%16 != 0 {
			return fmt.Errorf("Invalid IPv6 source routing, length of type 0 packet %d", len(data))
		}
		for d := i.Contents[8:]; len(d) >= 16; d = d[16:] {
			i.SourceRoutingIPs = append(i.SourceRoutingIPs, net.IP(d[:16]))
		}
	}
	p.AddLayer(i)
	return p.NextDecoder(i.NextHeader)
}

// IPv6Fragment is the IPv6 fragment header, used for packet
// fragmentation/defragmentation.
type IPv6Fragment struct {
	BaseLayer
	NextHeader IPProtocol
	// Reserved1 is bits [8-16), from least to most significant, 0-indexed
	Reserved1      uint8
	FragmentOffset uint16
	// Reserved2 is bits [29-31), from least to most significant, 0-indexed
	Reserved2      uint8
	MoreFragments  bool
	Identification uint32
}

// LayerType returns LayerTypeIPv6Fragment.
func (i *IPv6Fragment) LayerType() gopacket.LayerType { return LayerTypeIPv6Fragment }

func decodeIPv6Fragment(data []byte, p gopacket.PacketBuilder) error {
	i := &IPv6Fragment{
		BaseLayer:      BaseLayer{data[:8], data[8:]},
		NextHeader:     IPProtocol(data[0]),
		Reserved1:      data[1],
		FragmentOffset: binary.BigEndian.Uint16(data[2:4]) >> 3,
		Reserved2:      data[3] & 0x6 >> 1,
		MoreFragments:  data[3]&0x1 != 0,
		Identification: binary.BigEndian.Uint32(data[4:8]),
	}
	p.AddLayer(i)
	return p.NextDecoder(gopacket.DecodeFragment)
}

// IPv6DestinationOption is a TLV option present in an IPv6 destination options extension.
type IPv6DestinationOption ipv6HeaderTLVOption

// IPv6Destination is the IPv6 destination options header.
type IPv6Destination struct {
	ipv6ExtensionBase
	Options []IPv6DestinationOption
}

// LayerType returns LayerTypeIPv6Destination.
func (i *IPv6Destination) LayerType() gopacket.LayerType { return LayerTypeIPv6Destination }

func decodeIPv6Destination(data []byte, p gopacket.PacketBuilder) error {
	i := &IPv6Destination{
		ipv6ExtensionBase: decodeIPv6ExtensionBase(data),
		// We guess we'll 1-2 options, one regular option at least, then maybe one
		// padding option.
		Options: make([]IPv6DestinationOption, 0, 2),
	}
	var opt *IPv6DestinationOption
	for d := i.Contents[2:]; len(d) > 0; d = d[opt.ActualLength:] {
		i.Options = append(i.Options, IPv6DestinationOption(decodeIPv6HeaderTLVOption(d)))
		opt = &i.Options[len(i.Options)-1]
	}
	p.AddLayer(i)
	return p.NextDecoder(i.NextHeader)
}
<commit_msg>Add serialization for IPv6Destination header.<commit_after>// Copyright 2012 Google, Inc. All rights reserved.
// Copyright 2009-2011 Andreas Krennmair. All rights reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree.

package layers

import (
	"code.google.com/p/gopacket"
	"encoding/binary"
	"fmt"
	"net"
)

// IPv6 is the layer for the IPv6 header.
type IPv6 struct {
	// http://www.networksorcery.com/enp/protocol/ipv6.htm
	BaseLayer
	Version      uint8
	TrafficClass uint8
	FlowLabel    uint32
	Length       uint16
	NextHeader   IPProtocol
	HopLimit     uint8
	SrcIP        net.IP
	DstIP        net.IP
	HopByHop     *IPv6HopByHop
	// hbh will be pointed to by HopByHop if that layer exists.
	hbh IPv6HopByHop
}

// LayerType returns LayerTypeIPv6
func (i *IPv6) LayerType() gopacket.LayerType { return LayerTypeIPv6 }
func (i *IPv6) NetworkFlow() gopacket.Flow {
	return gopacket.NewFlow(EndpointIPv6, i.SrcIP, i.DstIP)
}

const (
	IPv6HopByHopOptionJumbogram = 0xC2 // RFC 2675
)

// SerializeTo writes the serialized form of this layer into the
// SerializationBuffer, implementing gopacket.SerializableLayer.
// See the docs for gopacket.SerializableLayer for more info.
func (ip6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
	payload := b.Bytes()
	if ip6.HopByHop != nil {
		return fmt.Errorf("unable to serialize hopbyhop for now")
	}
	bytes, err := b.PrependBytes(40)
	if err != nil {
		return err
	}
	bytes[0] = (ip6.Version << 4) | (ip6.TrafficClass >> 4)
	bytes[1] = (ip6.TrafficClass << 4) | uint8(ip6.FlowLabel>>16)
	binary.BigEndian.PutUint16(bytes[2:], uint16(ip6.FlowLabel))
	if opts.FixLengths {
		ip6.Length = uint16(len(payload))
	}
	binary.BigEndian.PutUint16(bytes[4:], ip6.Length)
	bytes[6] = byte(ip6.NextHeader)
	bytes[7] = byte(ip6.HopLimit)
	if len(ip6.SrcIP) != 16 {
		return fmt.Errorf("invalid src ip %v", ip6.SrcIP)
	}
	if len(ip6.DstIP) != 16 {
		return fmt.Errorf("invalid dst ip %v", ip6.DstIP)
	}
	copy(bytes[8:], ip6.SrcIP)
	copy(bytes[24:], ip6.DstIP)
	return nil
}

func (ip6 *IPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
	ip6.Version = uint8(data[0]) >> 4
	ip6.TrafficClass = uint8((binary.BigEndian.Uint16(data[0:2]) >> 4) & 0x00FF)
	ip6.FlowLabel = binary.BigEndian.Uint32(data[0:4]) & 0x000FFFFF
	ip6.Length = binary.BigEndian.Uint16(data[4:6])
	ip6.NextHeader = IPProtocol(data[6])
	ip6.HopLimit = data[7]
	ip6.SrcIP = data[8:24]
	ip6.DstIP = data[24:40]
	ip6.HopByHop = nil
	// We initially set the payload to all bytes after 40.  ip6.Length or the
	// HopByHop jumbogram option can both change this eventually, though.
	ip6.BaseLayer = BaseLayer{data[:40], data[40:]}

	// We treat a HopByHop IPv6 option as part of the IPv6 packet, since its
	// options are crucial for understanding what's actually happening per packet.
	if ip6.NextHeader == IPProtocolIPv6HopByHop {
		ip6.hbh.DecodeFromBytes(ip6.Payload, df)
		hbhLen := len(ip6.hbh.Contents)
		// Reset IPv6 contents to include the HopByHop header.
		ip6.BaseLayer = BaseLayer{data[:40+hbhLen], data[40+hbhLen:]}
		ip6.HopByHop = &ip6.hbh
		if ip6.Length == 0 {
			for _, o := range ip6.hbh.Options {
				if o.OptionType == IPv6HopByHopOptionJumbogram {
					if len(o.OptionData) != 4 {
						return fmt.Errorf("Invalid jumbo packet option length")
					}
					payloadLength := binary.BigEndian.Uint32(o.OptionData)
					pEnd := int(payloadLength)
					if pEnd > len(ip6.Payload) {
						df.SetTruncated()
					} else {
						ip6.Payload = ip6.Payload[:pEnd]
						ip6.hbh.Payload = ip6.Payload
					}
					return nil
				}
			}
			return fmt.Errorf("IPv6 length 0, but HopByHop header does not have jumbogram option")
		}
	}
	if ip6.Length == 0 {
		return fmt.Errorf("IPv6 length 0, but next header is %v, not HopByHop", ip6.NextHeader)
	} else {
		pEnd := int(ip6.Length)
		if pEnd > len(ip6.Payload) {
			df.SetTruncated()
			pEnd = len(ip6.Payload)
		}
		ip6.Payload = ip6.Payload[:pEnd]
	}
	return nil
}

func (i *IPv6) CanDecode() gopacket.LayerClass {
	return LayerTypeIPv6
}
func (i *IPv6) NextLayerType() gopacket.LayerType {
	if i.HopByHop != nil {
		return i.HopByHop.NextHeader.LayerType()
	}
	return i.NextHeader.LayerType()
}

func decodeIPv6(data []byte, p gopacket.PacketBuilder) error {
	ip6 := &IPv6{}
	err := ip6.DecodeFromBytes(data, p)
	p.AddLayer(ip6)
	p.SetNetworkLayer(ip6)
	if ip6.HopByHop != nil {
		// TODO(gconnell):  Since HopByHop is now an integral part of the IPv6
		// layer, should it actually be added as its own layer?  I'm leaning towards
		// no.
		p.AddLayer(ip6.HopByHop)
	}
	if err != nil {
		return err
	}
	if ip6.HopByHop != nil {
		return p.NextDecoder(ip6.HopByHop.NextHeader)
	}
	return p.NextDecoder(ip6.NextHeader)
}

func (i *IPv6HopByHop) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
	i.ipv6ExtensionBase = decodeIPv6ExtensionBase(data)
	i.Options = i.opts[:0]
	var opt *IPv6HopByHopOption
	for d := i.Contents[2:]; len(d) > 0; d = d[opt.ActualLength:] {
		i.Options = append(i.Options, IPv6HopByHopOption(decodeIPv6HeaderTLVOption(d)))
		opt = &i.Options[len(i.Options)-1]
	}
	return nil
}

func decodeIPv6HopByHop(data []byte, p gopacket.PacketBuilder) error {
	i := &IPv6HopByHop{}
	err := i.DecodeFromBytes(data, p)
	p.AddLayer(i)
	if err != nil {
		return err
	}
	return p.NextDecoder(i.NextHeader)
}

type ipv6HeaderTLVOption struct {
	OptionType, OptionLength uint8
	ActualLength             int
	OptionData               []byte
}

func decodeIPv6HeaderTLVOption(data []byte) (h ipv6HeaderTLVOption) {
	if data[0] == 0 {
		h.ActualLength = 1
		return
	}
	h.OptionType = data[0]
	h.OptionLength = data[1]
	h.ActualLength = int(h.OptionLength) + 2
	h.OptionData = data[2:h.ActualLength]
	return
}

func (h *ipv6HeaderTLVOption) serializeTo(b gopacket.SerializeBuffer, fixLengths bool) (int, error) {
	if fixLengths {
		h.OptionLength = uint8(len(h.OptionData))
	}
	length := int(h.OptionLength) + 2
	data, err := b.PrependBytes(length)
	if err != nil {
		return 0, err
	}
	data[0] = h.OptionType
	data[1] = h.OptionLength
	copy(data[2:], h.OptionData)
	return length, nil
}

// IPv6HopByHopOption is a TLV option present in an IPv6 hop-by-hop extension.
type IPv6HopByHopOption ipv6HeaderTLVOption

type ipv6ExtensionBase struct {
	BaseLayer
	NextHeader   IPProtocol
	HeaderLength uint8
	ActualLength int
}

func decodeIPv6ExtensionBase(data []byte) (i ipv6ExtensionBase) {
	i.NextHeader = IPProtocol(data[0])
	i.HeaderLength = data[1]
	i.ActualLength = int(i.HeaderLength)*8 + 8
	i.Contents = data[:i.ActualLength]
	i.Payload = data[i.ActualLength:]
	return
}

// IPv6ExtensionSkipper is a DecodingLayer which decodes and ignores v6
// extensions.  You can use it with a DecodingLayerParser to handle IPv6 stacks
// which may or may not have extensions.
type IPv6ExtensionSkipper struct {
	NextHeader IPProtocol
	BaseLayer
}

func (i *IPv6ExtensionSkipper) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
	extension := decodeIPv6ExtensionBase(data)
	i.BaseLayer = BaseLayer{data[:extension.ActualLength], data[extension.ActualLength:]}
	i.NextHeader = extension.NextHeader
	return nil
}
func (i *IPv6ExtensionSkipper) CanDecode() gopacket.LayerClass {
	return LayerClassIPv6Extension
}
func (i *IPv6ExtensionSkipper) NextLayerType() gopacket.LayerType {
	return i.NextHeader.LayerType()
}

// IPv6HopByHop is the IPv6 hop-by-hop extension.
type IPv6HopByHop struct {
	ipv6ExtensionBase
	Options []IPv6HopByHopOption
	opts    [2]IPv6HopByHopOption
}

// LayerType returns LayerTypeIPv6HopByHop.
func (i *IPv6HopByHop) LayerType() gopacket.LayerType { return LayerTypeIPv6HopByHop }

// IPv6Routing is the IPv6 routing extension.
type IPv6Routing struct {
	ipv6ExtensionBase
	RoutingType  uint8
	SegmentsLeft uint8
	// This segment is supposed to be zero according to RFC2460, the second set of
	// 4 bytes in the extension.
	Reserved []byte
	// SourceRoutingIPs is the set of IPv6 addresses requested for source routing,
	// set only if RoutingType == 0.
	SourceRoutingIPs []net.IP
}

// LayerType returns LayerTypeIPv6Routing.
func (i *IPv6Routing) LayerType() gopacket.LayerType { return LayerTypeIPv6Routing }

func decodeIPv6Routing(data []byte, p gopacket.PacketBuilder) error {
	i := &IPv6Routing{
		ipv6ExtensionBase: decodeIPv6ExtensionBase(data),
		RoutingType:       data[2],
		SegmentsLeft:      data[3],
		Reserved:          data[4:8],
	}
	switch i.RoutingType {
	case 0: // Source routing
		if (len(data)-8)%16 != 0 {
			return fmt.Errorf("Invalid IPv6 source routing, length of type 0 packet %d", len(data))
		}
		for d := i.Contents[8:]; len(d) >= 16; d = d[16:] {
			i.SourceRoutingIPs = append(i.SourceRoutingIPs, net.IP(d[:16]))
		}
	}
	p.AddLayer(i)
	return p.NextDecoder(i.NextHeader)
}

// IPv6Fragment is the IPv6 fragment header, used for packet
// fragmentation/defragmentation.
type IPv6Fragment struct {
	BaseLayer
	NextHeader IPProtocol
	// Reserved1 is bits [8-16), from least to most significant, 0-indexed
	Reserved1      uint8
	FragmentOffset uint16
	// Reserved2 is bits [29-31), from least to most significant, 0-indexed
	Reserved2      uint8
	MoreFragments  bool
	Identification uint32
}

// LayerType returns LayerTypeIPv6Fragment.
func (i *IPv6Fragment) LayerType() gopacket.LayerType { return LayerTypeIPv6Fragment }

func decodeIPv6Fragment(data []byte, p gopacket.PacketBuilder) error {
	i := &IPv6Fragment{
		BaseLayer:      BaseLayer{data[:8], data[8:]},
		NextHeader:     IPProtocol(data[0]),
		Reserved1:      data[1],
		FragmentOffset: binary.BigEndian.Uint16(data[2:4]) >> 3,
		Reserved2:      data[3] & 0x6 >> 1,
		MoreFragments:  data[3]&0x1 != 0,
		Identification: binary.BigEndian.Uint32(data[4:8]),
	}
	p.AddLayer(i)
	return p.NextDecoder(gopacket.DecodeFragment)
}

// IPv6DestinationOption is a TLV option present in an IPv6 destination options extension.
type IPv6DestinationOption ipv6HeaderTLVOption

func (o *IPv6DestinationOption) serializeTo(b gopacket.SerializeBuffer, fixLengths bool) (int, error) {
	return (*ipv6HeaderTLVOption)(o).serializeTo(b, fixLengths)
}

// IPv6Destination is the IPv6 destination options header.
type IPv6Destination struct {
	ipv6ExtensionBase
	Options []IPv6DestinationOption
}

// LayerType returns LayerTypeIPv6Destination.
func (i *IPv6Destination) LayerType() gopacket.LayerType { return LayerTypeIPv6Destination }

func decodeIPv6Destination(data []byte, p gopacket.PacketBuilder) error {
	i := &IPv6Destination{
		ipv6ExtensionBase: decodeIPv6ExtensionBase(data),
		// We guess we'll 1-2 options, one regular option at least, then maybe one
		// padding option.
		Options: make([]IPv6DestinationOption, 0, 2),
	}
	var opt *IPv6DestinationOption
	for d := i.Contents[2:]; len(d) > 0; d = d[opt.ActualLength:] {
		i.Options = append(i.Options, IPv6DestinationOption(decodeIPv6HeaderTLVOption(d)))
		opt = &i.Options[len(i.Options)-1]
	}
	p.AddLayer(i)
	return p.NextDecoder(i.NextHeader)
}

// SerializeTo writes the serialized form of this layer into the
// SerializationBuffer, implementing gopacket.SerializableLayer.
// See the docs for gopacket.SerializableLayer for more info.
func (i *IPv6Destination) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
	optionLength := 0
	for _, opt := range i.Options {
		l, err := opt.serializeTo(b, opts.FixLengths)
		if err != nil {
			return err
		}
		optionLength += l
	}
	bytes, err := b.PrependBytes(2)
	if err != nil {
		return err
	}
	bytes[0] = uint8(i.NextHeader)
	if opts.FixLengths {
		i.HeaderLength = uint8((optionLength + 2) / 8)
	}
	bytes[1] = i.HeaderLength
	return nil
}
<|endoftext|>


<commit_before>package lbctx

import (
	"github.com/lhcb-org/lbx/lbctx/vcs"
)

// Repos is the database of known repositories
var Repos = RepoInfos{
	"gaudi": []RepoInfo{
		{
			Cmd:  vcs.Svn,
			Repo: "svn+ssh://svn.cern.ch/reps/gaudi",
			Root: "/reps/gaudi",
		},
		{
			Cmd:  vcs.Svn,
			Repo: "http://svn.cern.ch/guest/gaudi",
			Root: "/guest/gaudi",
		},
	},

	"lbsvn": []RepoInfo{
		{
			Cmd:  vcs.Svn,
			Repo: "svn+ssh://svn.cern.ch/reps/lhcb",
			Root: "/reps/lhcb",
		},
		{
			Cmd:  vcs.Svn,
			Repo: "http://svn.cern.ch/guest/lhcb",
			Root: "/guest/lhcb",
		},
	},

	"dirac": []RepoInfo{
		{
			Cmd:  vcs.Svn,
			Repo: "svn+ssh://svn.cern.ch/reps/dirac",
			Root: "/reps/dirac",
		},
		{
			Cmd:  vcs.Svn,
			Repo: "http://svn.cern.ch/guest/dirac",
			Root: "/guest/dirac",
		},
	},

	"lhcbint": []RepoInfo{
		{
			Cmd:  vcs.Svn,
			Repo: "svn+ssh://svn.cern.ch/reps/lhcbint",
			Root: "/reps/lhcbint",
		},
	},
}

type RepoInfo struct {
	Cmd  *vcs.Cmd
	Repo string
	Root string
}

type RepoInfos map[string][]RepoInfo

// Repositories returns a map of named-repositories
func Repositories(user, protocol string) RepoInfos {
	repos := make(RepoInfos, len(Repos))
	for k := range Repos {
		repos[k] = append([]RepoInfo{}, Repos[k]...)
	}
	if user != "" {

	}
	return repos
}

func (repo *RepoInfo) ListPackages(hat string) []string {
	pkgs := make([]string, 0)
	return pkgs
}
<commit_msg>lbctx: impl. repository scrapping<commit_after>package lbctx

import (
	"bufio"
	"bytes"
	"strings"

	"github.com/lhcb-org/lbx/lbctx/vcs"
)

// Repos is the database of known repositories
var Repos = RepoDb{
	"gaudi": RepoInfos{
		{
			Cmd:  vcs.Svn,
			Repo: "svn+ssh://svn.cern.ch/reps/gaudi",
		},
		{
			Cmd:  vcs.Svn,
			Repo: "http://svn.cern.ch/guest/gaudi",
		},
	},

	"lbsvn": RepoInfos{
		{
			Cmd:  vcs.Svn,
			Repo: "svn+ssh://svn.cern.ch/reps/lhcb",
		},
		{
			Cmd:  vcs.Svn,
			Repo: "http://svn.cern.ch/guest/lhcb",
		},
	},

	"dirac": RepoInfos{
		{
			Cmd:  vcs.Svn,
			Repo: "svn+ssh://svn.cern.ch/reps/dirac",
		},
		{
			Cmd:  vcs.Svn,
			Repo: "http://svn.cern.ch/guest/dirac",
		},
	},

	"lhcbint": RepoInfos{
		{
			Cmd:  vcs.Svn,
			Repo: "svn+ssh://svn.cern.ch/reps/lhcbint",
		},
	},
}

type RepoInfo struct {
	Cmd  *vcs.Cmd
	Repo string

	pkgs Packages
}

type RepoInfos []RepoInfo
type RepoDb map[string]RepoInfos

// Repositories returns a map of named-repositories
func Repositories(user, protocol string) RepoDb {
	repos := make(RepoDb, len(Repos))
	for k := range Repos {
		repos[k] = append([]RepoInfo{}, Repos[k]...)
	}
	if user != "" {

	}
	return repos
}

func (repos *RepoInfos) ListPackages(hat string) []Package {
	for _, repo := range *repos {
		pkgs := repo.ListPackages(hat)
		if pkgs != nil {
			return pkgs
		}
	}
	return nil
}

func (repo *RepoInfo) ListPackages(hat string) []Package {
	if repo.pkgs == nil {
		err := repo.initPkgs()
		if err != nil {
			return nil
		}
	}
	pkgs := make([]Package, 0)
	for _, pkg := range repo.pkgs {
		if !strings.HasPrefix(pkg.Name, hat) {
			continue
		}
		pkgs = append(pkgs, pkg)
	}
	return pkgs
}

func (repo *RepoInfo) initPkgs() error {
	var err error

	// FIXME: first check 'propget version' >= 2.0

	// assume propget-version >= 2.0
	bout, err := vcs.Run(repo.Cmd, "propget packages {repo}", "repo", repo.Repo)
	if err != nil {
		return nil
	}

	pkgs := make(Packages)
	scan := bufio.NewScanner(bytes.NewReader(bout))
	for scan.Scan() {
		bline := bytes.Trim(scan.Bytes(), " \n")
		if bytes.HasPrefix(bline, []byte("#")) {
			continue
		}
		bline = bytes.Replace(bline, []byte("\t"), []byte(" "), -1)
		tokens := make([]string, 0)
		for _, tok := range strings.Split(string(bline), " ") {
			tok = strings.Trim(tok, " \t\n")
			if tok == "" {
				continue
			}
			tokens = append(tokens, tok)
		}

		if len(tokens) <= 0 {
			continue
		}
		project := ""
		pkgname := tokens[0]
		if len(tokens) > 1 {
			project = tokens[1]
		}
		pkgs[pkgname] = Package{
			Name:    pkgname,
			Project: project,
			Repo:    repo.Repo,
		}
	}
	err = scan.Err()
	if err != nil {
		return err
	}

	repo.pkgs = pkgs
	return err
}
<|endoftext|>


<commit_before>// This package contains utility methos for testing
package test

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
)

func GetTestCasePath() string {
	//TODO: Right now the command is hardcoded. We should decide how to fix this.
	dirPath, err := filepath.Abs("../test/tools")

	if err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(-1)
	}

	return filepath.Join(dirPath, "test")
}

func PrintSoftErrors(softerrors []error) {
	for _, err := range softerrors {
		fmt.Fprintln(os.Stderr, err.Error())
	}
}

// this method redirects the process's stdout to the test stdout
func LaunchTestCase() (*exec.Cmd, error) {
	cmd := exec.Command(GetTestCasePath())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Start()
	return cmd, err
}

func LaunchTestCaseAndWaitForInitialization() (*exec.Cmd, error) {
	return launchProcessAndWaitInitialization(GetTestCasePath())
}

// starts a process and waits until it writes everythin to stdout: that way we know it has been initialized.
// the process launched should close stdout once it has been fully initialized.
// this method redirects the process's stdout to the test stdout
func launchProcessAndWaitInitialization(file string) (*exec.Cmd, error) {
	cmd := exec.Command(file)

	childout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	defer childout.Close()

	if err := cmd.Start(); err != nil {
		return nil, err
	}

	io.Copy(os.Stdout, childout)

	return cmd, nil
}
<commit_msg>[test] Fix GetTestCasePath.<commit_after>// This package contains utility methos for testing
package test

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
)

func GetTestCasePath() string {
	//TODO: Right now the command is hardcoded. We should decide how to fix this.
	dirPath, err := filepath.Abs("../test/tools")

	if err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(-1)
	}

	path, err := filepath.EvalSymlinks(filepath.Join(dirPath, "test"))
	if err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(-1)
	}

	return path
}

func PrintSoftErrors(softerrors []error) {
	for _, err := range softerrors {
		fmt.Fprintln(os.Stderr, err.Error())
	}
}

// this method redirects the process's stdout to the test stdout
func LaunchTestCase() (*exec.Cmd, error) {
	cmd := exec.Command(GetTestCasePath())
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Start()
	return cmd, err
}

func LaunchTestCaseAndWaitForInitialization() (*exec.Cmd, error) {
	return launchProcessAndWaitInitialization(GetTestCasePath())
}

// starts a process and waits until it writes everythin to stdout: that way we know it has been initialized.
// the process launched should close stdout once it has been fully initialized.
// this method redirects the process's stdout to the test stdout
func launchProcessAndWaitInitialization(file string) (*exec.Cmd, error) {
	cmd := exec.Command(file)

	childout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	defer childout.Close()

	if err := cmd.Start(); err != nil {
		return nil, err
	}

	io.Copy(os.Stdout, childout)

	return cmd, nil
}
<|endoftext|>


<commit_before>package util

import (
	"os"
	"strings"
)

var (
	// Hostname is the machine's hostname.
	Hostname string
	// FullHostname will, if false, uses the hostname upto the first ".". Run Set()
	// manually after changing.
	FullHostname bool
)

// Clean cleans a hostname based on the current FullHostname setting.
func Clean(s string) string {
	if !FullHostname {
		s = strings.SplitN(s, ".", 2)[0]
	}
	return strings.ToLower(s)
}

// Set sets Hostntame based on the current preferences.
func Set() {
	h, err := os.Hostname()
	if err == nil {
		if !FullHostname {
			h = strings.SplitN(h, ".", 2)[0]
		}
	} else {
		h = "unknown"
	}
	Hostname = Clean(h)
}

func init() {
	Set()
}
<commit_msg>util: document package<commit_after>// Package util defines utilities for bosun.
package util

import (
	"os"
	"strings"
)

var (
	// Hostname is the machine's hostname.
	Hostname string
	// FullHostname will, if false, uses the hostname upto the first ".". Run Set()
	// manually after changing.
	FullHostname bool
)

// Clean cleans a hostname based on the current FullHostname setting.
func Clean(s string) string {
	if !FullHostname {
		s = strings.SplitN(s, ".", 2)[0]
	}
	return strings.ToLower(s)
}

// Set sets Hostntame based on the current preferences.
func Set() {
	h, err := os.Hostname()
	if err == nil {
		if !FullHostname {
			h = strings.SplitN(h, ".", 2)[0]
		}
	} else {
		h = "unknown"
	}
	Hostname = Clean(h)
}

func init() {
	Set()
}
<|endoftext|>