<commit_before>// Copyright 2015, David Howden
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package cmdflag unifies the configuration of stores using command line flags across
// several tools.
//
// FIXME: Need a more coherent way of doing this: it's now a huge mess.
package cmdflag

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"strings"

	"github.com/mitchellh/goamz/aws"

	"tchaik.com/store"
	"tchaik.com/store/cafs"
)

var localStore, remoteStore string
var mediaFileSystemCache, artworkFileSystemCache string
var trimPathPrefix, addPathPrefix string

func init() {
	flag.StringVar(&localStore, "local-store", "/", "local media store, full local path /path/to/root")
	flag.StringVar(&remoteStore, "remote-store", "", "remote media store, tchstore server address <hostname>:<port>, or s3://<bucket>/path/to/root for S3")

	flag.StringVar(&artworkFileSystemCache, "artwork-cache", "", "path to local artwork cache (content addressable)")
	flag.StringVar(&mediaFileSystemCache, "media-cache", "", "path to local media cache")

	flag.StringVar(&trimPathPrefix, "trim-path-prefix", "", "remove prefix from every path")
	flag.StringVar(&addPathPrefix, "add-path-prefix", "", "add prefix to every path")
}

type stores struct {
	media, artwork store.FileSystem
}

func buildRemoteStore(s *stores) (err error) {
	if remoteStore == "" {
		return nil
	}
	var c store.Client
	if strings.HasPrefix(remoteStore, "s3://") {
		path := strings.TrimPrefix(remoteStore, "s3://")
		bucketPathSplit := strings.Split(path, "/")

		if len(bucketPathSplit) == 0 {
			return fmt.Errorf("invalid S3 path: %#v\n", remoteStore)
		}
		bucket := bucketPathSplit[0]
		var auth aws.Auth
		auth, err = aws.GetAuth("", "") // Extract credentials from the current instance.
		if err != nil {
			return fmt.Errorf("error getting AWS credentials: %v", err)
		}
		c = store.NewS3Client(bucket, auth, aws.APSoutheast2)
	} else {
		c = store.NewClient(remoteStore, "")
		s.artwork = store.NewRemoteFileSystem(store.NewClient(remoteStore, "artwork"))
	}

	s.media = store.NewRemoteChunkedFileSystem(c, 32*1024)
	if s.artwork == nil {
		s.artwork = store.Trace(store.ArtworkFileSystem(s.media), "artwork")
	}
	return nil
}

func buildLocalStore(s *stores) {
	if localStore != "" {
		fs := store.NewFileSystem(http.Dir(localStore), fmt.Sprintf("localstore (%v)", localStore))
		if s.media != nil {
			s.media = store.MultiFileSystem(fs, s.media)
		} else {
			s.media = fs
		}

		afs := store.Trace(store.ArtworkFileSystem(fs), "local artworkstore")
		if s.artwork != nil {
			s.artwork = store.MultiFileSystem(afs, s.artwork)
		} else {
			s.artwork = afs
		}
	}
}

func buildMediaCache(s *stores) {
	if mediaFileSystemCache != "" {
		var errCh <-chan error
		localCache := store.Dir(mediaFileSystemCache)
		s.media, errCh = store.NewCachedFileSystem(s.media, localCache)
		go func() {
			for err := range errCh {
				// TODO: pull this out!
				log.Printf("mediaFileSystem cache: %v", err)
			}
		}()
	}
}

func buildArtworkCache(s *stores) error {
	if artworkFileSystemCache != "" {
		cfs, err := cafs.New(store.Dir(artworkFileSystemCache))
		if err != nil {
			return fmt.Errorf("error creating artwork cafs: %v", err)
		}

		var errCh <-chan error
		s.artwork, errCh = store.NewCachedFileSystem(
			s.artwork,
			cfs,
		)
		go func() {
			for err := range errCh {
				// TODO: pull this out!
				log.Printf("artwork cache: %v", err)
			}
		}()
	}
	return nil
}

// Stores returns a media and artwork filesystem as defined by the command line flags.
func Stores() (media, artwork store.FileSystem, err error) {
	s := &stores{}
	err = buildRemoteStore(s)
	if err != nil {
		return nil, nil, err
	}

	buildLocalStore(s)
	buildMediaCache(s)

	err = buildArtworkCache(s)
	if err != nil {
		return nil, nil, err
	}

	if trimPathPrefix != "" || addPathPrefix != "" {
		s.media = store.PathRewrite(s.media, trimPathPrefix, addPathPrefix)
		s.artwork = store.PathRewrite(s.artwork, trimPathPrefix, addPathPrefix)
	}
	return s.media, s.artwork, nil
}
<commit_msg>Add support for gs:// urls in remote-store param.<commit_after>// Copyright 2015, David Howden
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package cmdflag unifies the configuration of stores using command line flags across
// several tools.
//
// FIXME: Need a more coherent way of doing this: it's now a huge mess.
package cmdflag

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"strings"

	"github.com/mitchellh/goamz/aws"

	"tchaik.com/store"
	"tchaik.com/store/cafs"
)

var localStore, remoteStore string
var mediaFileSystemCache, artworkFileSystemCache string
var trimPathPrefix, addPathPrefix string

func init() {
	flag.StringVar(&localStore, "local-store", "/", "local media store, full local path /path/to/root")
	flag.StringVar(&remoteStore, "remote-store", "", "remote media store, tchstore server address <hostname>:<port>, s3://<bucket>/path/to/root for S3, or gs://<bucket>/path/to/root for Google Cloud Storage")

	flag.StringVar(&artworkFileSystemCache, "artwork-cache", "", "path to local artwork cache (content addressable)")
	flag.StringVar(&mediaFileSystemCache, "media-cache", "", "path to local media cache")

	flag.StringVar(&trimPathPrefix, "trim-path-prefix", "", "remove prefix from every path")
	flag.StringVar(&addPathPrefix, "add-path-prefix", "", "add prefix to every path")
}

type stores struct {
	media, artwork store.FileSystem
}

func buildRemoteStore(s *stores) (err error) {
	if remoteStore == "" {
		return nil
	}

	var c store.Client
	switch {
	case strings.HasPrefix(remoteStore, "s3://"):
		path := strings.TrimPrefix(remoteStore, "s3://")
		bucketPathSplit := strings.Split(path, "/")

		if len(bucketPathSplit) == 0 {
			return fmt.Errorf("invalid S3 path: %#v", remoteStore)
		}
		bucket := bucketPathSplit[0]
		var auth aws.Auth
		auth, err = aws.GetAuth("", "") // Extract credentials from the current instance.
		if err != nil {
			return fmt.Errorf("error getting AWS credentials: %v", err)
		}
		c = store.NewS3Client(bucket, auth, aws.APSoutheast2)

	case strings.HasPrefix(remoteStore, "gs://"):
		path := strings.TrimPrefix(remoteStore, "gs://")
		bucketPathSplit := strings.Split(path, "/")

		if len(bucketPathSplit) == 0 {
			return fmt.Errorf("invalid Google Cloud Storage path: %#v", remoteStore)
		}
		bucket := bucketPathSplit[0]
		if len(bucket) == 0 {
			return fmt.Errorf("invalid Google Cloud Storage path: %#v", remoteStore)
		}
		c = store.NewCloudStorageClient(bucket)

	default:
		c = store.NewClient(remoteStore, "")
		s.artwork = store.NewRemoteFileSystem(store.NewClient(remoteStore, "artwork"))
	}

	s.media = store.NewRemoteChunkedFileSystem(c, 32*1024)
	if s.artwork == nil {
		s.artwork = store.Trace(store.ArtworkFileSystem(s.media), "artwork")
	}
	return nil
}

func buildLocalStore(s *stores) {
	if localStore != "" {
		fs := store.NewFileSystem(http.Dir(localStore), fmt.Sprintf("localstore (%v)", localStore))
		if s.media != nil {
			s.media = store.MultiFileSystem(fs, s.media)
		} else {
			s.media = fs
		}

		afs := store.Trace(store.ArtworkFileSystem(fs), "local artworkstore")
		if s.artwork != nil {
			s.artwork = store.MultiFileSystem(afs, s.artwork)
		} else {
			s.artwork = afs
		}
	}
}

func buildMediaCache(s *stores) {
	if mediaFileSystemCache != "" {
		var errCh <-chan error
		localCache := store.Dir(mediaFileSystemCache)
		s.media, errCh = store.NewCachedFileSystem(s.media, localCache)
		go func() {
			for err := range errCh {
				// TODO: pull this out!
				log.Printf("mediaFileSystem cache: %v", err)
			}
		}()
	}
}

func buildArtworkCache(s *stores) error {
	if artworkFileSystemCache != "" {
		cfs, err := cafs.New(store.Dir(artworkFileSystemCache))
		if err != nil {
			return fmt.Errorf("error creating artwork cafs: %v", err)
		}

		var errCh <-chan error
		s.artwork, errCh = store.NewCachedFileSystem(
			s.artwork,
			cfs,
		)
		go func() {
			for err := range errCh {
				// TODO: pull this out!
				log.Printf("artwork cache: %v", err)
			}
		}()
	}
	return nil
}

// Stores returns a media and artwork filesystem as defined by the command line flags.
func Stores() (media, artwork store.FileSystem, err error) {
	s := &stores{}
	err = buildRemoteStore(s)
	if err != nil {
		return nil, nil, err
	}

	buildLocalStore(s)
	buildMediaCache(s)

	err = buildArtworkCache(s)
	if err != nil {
		return nil, nil, err
	}

	if trimPathPrefix != "" || addPathPrefix != "" {
		s.media = store.PathRewrite(s.media, trimPathPrefix, addPathPrefix)
		s.artwork = store.PathRewrite(s.artwork, trimPathPrefix, addPathPrefix)
	}
	return s.media, s.artwork, nil
}
<|endoftext|>


<commit_before>// Copyright 2013-2019 Aerospike, Inc.
//
// 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 aerospike_test

import (
	"math"
	"math/rand"
	"time"

	. "github.com/aerospike/aerospike-client-go"
	// . "github.com/aerospike/aerospike-client-go/logger"
	// . "github.com/aerospike/aerospike-client-go/types"

	// . "github.com/aerospike/aerospike-client-go/utils/buffer"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

// ALL tests are isolated by SetName and Key, which are 50 random characters
var _ = Describe("Truncate operations test", func() {
	initTestVars()

	Context("Truncate", func() {
		var err error
		var ns = *namespace
		var set = randString(50)
		var key *Key
		var wpolicy = NewWritePolicy(0, 0)
		wpolicy.SendKey = true

		const keyCount = 1000
		bin1 := NewBin("Aerospike1", rand.Intn(math.MaxInt16))
		bin2 := NewBin("Aerospike2", randString(100))

		BeforeEach(func() {
			for i := 0; i < keyCount; i++ {
				key, err = NewKey(ns, set, i)
				Expect(err).ToNot(HaveOccurred())

				_, err = client.Operate(wpolicy, key, PutOp(bin1), PutOp(bin2), GetOp())
				Expect(err).ToNot(HaveOccurred())
			}
		})

		var countRecords = func(namespace, setName string) int {
			stmt := NewStatement(namespace, setName)
			res, err := client.Query(nil, stmt)
			Expect(err).ToNot(HaveOccurred())

			cnt := 0
			for rec := range res.Results() {
				Expect(rec.Err).ToNot(HaveOccurred())
				cnt++
			}

			return cnt
		}

		It("must truncate only the current set", func() {
			Expect(countRecords(ns, set)).To(Equal(keyCount))

			err := client.Truncate(nil, ns, set, nil)
			Expect(err).ToNot(HaveOccurred())

			time.Sleep(time.Second)
			Expect(countRecords(ns, set)).To(Equal(0))
		})

		It("must truncate the whole namespace", func() {
			Expect(countRecords(ns, "")).ToNot(Equal(0))

			err := client.Truncate(nil, ns, "", nil)
			Expect(err).ToNot(HaveOccurred())

			time.Sleep(time.Second)
			Expect(countRecords(ns, "")).To(Equal(0))
		})

		It("must truncate only older records", func() {
			t := time.Now()

			Expect(countRecords(ns, set)).To(Equal(keyCount))

			for i := keyCount; i < 2*keyCount; i++ {
				key, err = NewKey(ns, set, i)
				Expect(err).ToNot(HaveOccurred())

				_, err = client.Operate(wpolicy, key, PutOp(bin1), PutOp(bin2), GetOp())
				Expect(err).ToNot(HaveOccurred())
			}
			Expect(countRecords(ns, set)).To(Equal(2 * keyCount))

			err := client.Truncate(nil, ns, set, &t)
			Expect(err).ToNot(HaveOccurred())

			time.Sleep(3 * time.Second)
			Expect(countRecords(ns, set)).To(Equal(keyCount))
		})

	})
})
<commit_msg>fix truncate test<commit_after>// Copyright 2013-2019 Aerospike, Inc.
//
// 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 aerospike_test

import (
	"math"
	"math/rand"
	"time"

	. "github.com/aerospike/aerospike-client-go"
	// . "github.com/aerospike/aerospike-client-go/logger"
	// . "github.com/aerospike/aerospike-client-go/types"

	// . "github.com/aerospike/aerospike-client-go/utils/buffer"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

// ALL tests are isolated by SetName and Key, which are 50 random characters
var _ = Describe("Truncate operations test", func() {
	initTestVars()

	Context("Truncate", func() {
		var err error
		var ns = *namespace
		var set = randString(50)
		var key *Key
		var wpolicy = NewWritePolicy(0, 0)
		wpolicy.SendKey = true

		const keyCount = 1000
		bin1 := NewBin("Aerospike1", rand.Intn(math.MaxInt16))
		bin2 := NewBin("Aerospike2", randString(100))

		BeforeEach(func() {
			for i := 0; i < keyCount; i++ {
				key, err = NewKey(ns, set, i)
				Expect(err).ToNot(HaveOccurred())

				_, err = client.Operate(wpolicy, key, PutOp(bin1), PutOp(bin2), GetOp())
				Expect(err).ToNot(HaveOccurred())
			}
		})

		var countRecords = func(namespace, setName string) int {
			stmt := NewStatement(namespace, setName)
			res, err := client.Query(nil, stmt)
			Expect(err).ToNot(HaveOccurred())

			cnt := 0
			for rec := range res.Results() {
				Expect(rec.Err).ToNot(HaveOccurred())
				cnt++
			}

			return cnt
		}

		It("must truncate only the current set", func() {
			Expect(countRecords(ns, set)).To(Equal(keyCount))

			err := client.Truncate(nil, ns, set, nil)
			Expect(err).ToNot(HaveOccurred())

			time.Sleep(time.Second)
			Expect(countRecords(ns, set)).To(Equal(0))
		})

		It("must truncate the whole namespace", func() {
			Expect(countRecords(ns, "")).ToNot(Equal(0))

			err := client.Truncate(nil, ns, "", nil)
			Expect(err).ToNot(HaveOccurred())

			time.Sleep(time.Second)
			Expect(countRecords(ns, "")).To(Equal(0))
		})

		It("must truncate only older records", func() {
			time.Sleep(3 * time.Second)
			t := time.Now()

			Expect(countRecords(ns, set)).To(Equal(keyCount))

			for i := keyCount; i < 2*keyCount; i++ {
				key, err = NewKey(ns, set, i)
				Expect(err).ToNot(HaveOccurred())

				_, err = client.Operate(wpolicy, key, PutOp(bin1), PutOp(bin2), GetOp())
				Expect(err).ToNot(HaveOccurred())
			}
			Expect(countRecords(ns, set)).To(Equal(2 * keyCount))

			err := client.Truncate(nil, ns, set, &t)
			Expect(err).ToNot(HaveOccurred())

			time.Sleep(3 * time.Second)
			Expect(countRecords(ns, set)).To(Equal(keyCount))
		})

	})
})
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

var (
	flagOut  = flag.String("o", "", "output file")
	flagFunc = flag.String("func", "Fuzz", "entry function")

	workdir string
)

const (
	mainPkg = "go-fuzz-main"
)

// Copies the package with all dependent packages into a temp dir,
// instruments Go source files there and builds setting GOROOT to the temp dir.
func main() {
	flag.Parse()
	if len(flag.Args()) != 1 {
		failf("usage: go-fuzz-build pkg")
	}
	if os.Getenv("GOROOT") == "" {
		failf("GOROOT env var is not set, set it to Go installation dir")
	}

	pkg := flag.Arg(0)

	// To produce error messages (this is much faster and gives correct line numbers).
	testNormalBuild(pkg)

	deps := make(map[string]bool)
	for _, p := range goListList(pkg, "Deps") {
		deps[p] = true
	}
	deps[pkg] = true
	// These packages are used by go-fuzz-dep, so we need to copy them regardless.
	deps["runtime"] = true
	deps["syscall"] = true
	deps["time"] = true
	deps["unsafe"] = true

	if *flagOut == "" {
		*flagOut = goListProps(pkg, "Name")[0] + "-fuzz"
	}

	var err error
	workdir, err = ioutil.TempDir("", "go-fuzz-build")
	if err != nil {
		failf("failed to create temp dir: %v", err)
	}
	defer os.RemoveAll(workdir)

	if deps["runtime/cgo"] {
		// Trick go command into thinking that it has up-to-date sources for cmd/cgo.
		cgoDir := filepath.Join(workdir, "src", "cmd", "cgo")
		if err := os.MkdirAll(cgoDir, 0700); err != nil {
			failf("failed to create temp dir: %v", err)
		}
		src := "// +build never\npackage main\n"
		if err := ioutil.WriteFile(filepath.Join(cgoDir, "fake.go"), []byte(src), 0600); err != nil {
			failf("failed to write temp file: %v", err)
		}
	}
	copyDir(filepath.Join(os.Getenv("GOROOT"), "pkg", "tool"), filepath.Join(workdir, "pkg", "tool"), false, true)
	copyDir(filepath.Join(os.Getenv("GOROOT"), "pkg", "include"), filepath.Join(workdir, "pkg", "include"), false, true)
	for p := range deps {
		clonePackage(workdir, p)
	}
	createFuzzMain(pkg)

	cmd := exec.Command("go", "build", "-tags", "gofuzz", "-o", *flagOut, mainPkg)
	for _, v := range os.Environ() {
		if strings.HasPrefix(v, "GOROOT") {
			continue
		}
		cmd.Env = append(cmd.Env, v)
	}
	cmd.Env = append(cmd.Env, "GOROOT="+workdir)
	if out, err := cmd.CombinedOutput(); err != nil {
		failf("failed to execute go build: %v\n%v", err, string(out))
	}
}

func testNormalBuild(pkg string) {
	var err error
	workdir, err = ioutil.TempDir("", "go-fuzz-build")
	if err != nil {
		failf("failed to create temp dir: %v", err)
	}
	defer func() {
		os.RemoveAll(workdir)
		workdir = ""
	}()
	createFuzzMain(pkg)
	cmd := exec.Command("go", "build", "-tags", "gofuzz", "-o", filepath.Join(workdir, "bin"), mainPkg)
	cmd.Env = append([]string{"GOPATH=" + workdir + ":" + os.Getenv("GOPATH")}, os.Environ()...)
	if out, err := cmd.CombinedOutput(); err != nil {
		failf("failed to execute go build: %v\n%v", err, string(out))
	}
}

func createFuzzMain(pkg string) {
	if err := os.MkdirAll(filepath.Join(workdir, "src", mainPkg), 0700); err != nil {
		failf("failed to create temp dir: %v", err)
	}
	src := fmt.Sprintf(mainSrc, pkg, *flagFunc)
	if err := ioutil.WriteFile(filepath.Join(workdir, "src", mainPkg, "main.go"), []byte(src), 0600); err != nil {
		failf("failed to write temp file: %v", err)
	}
}

func clonePackage(workdir, pkg string) {
	dir := goListProps(pkg, "Dir")[0]
	if !strings.HasSuffix(dir, pkg) {
		failf("package dir '%v' does not end with import path '%v'", dir, pkg)
	}
	newDir := filepath.Join(workdir, "src", pkg)
	copyDir(dir, newDir, true, false)
	ignore := []string{
		"runtime",       // lots of non-determinism and irrelevant code paths (e.g. different paths in mallocgc, chans and maps)
		"unsafe",        // nothing to see here (also creates import cycle with go-fuzz-dep)
		"errors",        // nothing to see here (also creates import cycle with go-fuzz-dep)
		"syscall",       // creates import cycle with go-fuzz-dep (and probably nothing to see here)
		"sync",          // non-deterministic and not interesting (also creates import cycle with go-fuzz-dep)
		"sync/atomic",   // not interesting (also creates import cycle with go-fuzz-dep)
		"time",          // creates import cycle with go-fuzz-dep
		"runtime/cgo",   // why would we instrument it?
		"runtime/pprof", // why would we instrument it?
		"runtime/race",  // why would we instrument it?
	}
	for _, p := range ignore {
		if pkg == p {
			return
		}
	}
	files, err := ioutil.ReadDir(newDir)
	if err != nil {
		failf("failed to scan dir '%v': %v", dir, err)
	}
	for _, f := range files {
		if f.IsDir() {
			continue
		}
		if !strings.HasSuffix(f.Name(), ".go") {
			continue
		}
		fn := filepath.Join(newDir, f.Name())
		newFn := fn + ".cover"
		instrument(fn, newFn)
		err := os.Rename(newFn, fn)
		if err != nil {
			failf("failed to rename file: %v", err)
		}
	}
}

func copyDir(dir, newDir string, src, rec bool) {
	if err := os.MkdirAll(newDir, 0700); err != nil {
		failf("failed to create temp dir: %v", err)
	}
	files, err := ioutil.ReadDir(dir)
	if err != nil {
		failf("failed to scan dir '%v': %v", dir, err)
	}
	for _, f := range files {
		if f.IsDir() {
			if rec {
				copyDir(filepath.Join(dir, f.Name()), filepath.Join(newDir, f.Name()), src, rec)
			}
			continue
		}
		if src && !isSourceFile(f.Name()) {
			continue
		}
		data, err := ioutil.ReadFile(filepath.Join(dir, f.Name()))
		if err != nil {
			failf("failed to read file: %v", err)
		}
		if err := ioutil.WriteFile(filepath.Join(newDir, f.Name()), data, 0700); err != nil {
			failf("failed to write temp file: %v", err)
		}
	}
}

func goListList(pkg, what string) []string {
	templ := fmt.Sprintf("{{range .%v}}{{.}}|{{end}}", what)
	out, err := exec.Command("go", "list", "-tags", "gofuzz", "-f", templ, pkg).CombinedOutput()
	if err != nil {
		failf("failed to execute 'go list -f \"%v\" %v': %v\n%v", templ, pkg, err, string(out))
	}
	if len(out) < 2 {
		failf("go list output is empty")
	}
	out = out[:len(out)-2]
	return strings.Split(string(out), "|")
}

func goListProps(pkg string, props ...string) []string {
	templ := ""
	for _, p := range props {
		templ += fmt.Sprintf("{{.%v}}|", p)
	}
	out, err := exec.Command("go", "list", "-tags", "gofuzz", "-f", templ, pkg).CombinedOutput()
	if err != nil {
		failf("failed to execute 'go list -f \"%v\" %v': %v\n%v", templ, pkg, err, string(out))
	}
	if len(out) == 0 {
		failf("go list output is empty")
	}
	out = out[:len(out)-1]
	return strings.Split(string(out), "|")
}

func failf(str string, args ...interface{}) {
	if workdir != "" {
		os.RemoveAll(workdir)
	}
	fmt.Fprintf(os.Stderr, str+"\n", args...)
	os.Exit(1)
}

func isSourceFile(f string) bool {
	return strings.HasSuffix(f, ".go") ||
		strings.HasSuffix(f, ".s") ||
		strings.HasSuffix(f, ".S") ||
		strings.HasSuffix(f, ".c") ||
		strings.HasSuffix(f, ".h") ||
		strings.HasSuffix(f, ".cxx") ||
		strings.HasSuffix(f, ".cpp") ||
		strings.HasSuffix(f, ".c++") ||
		strings.HasSuffix(f, ".cc")
}

var mainSrc = `
package main

import (
	target "%v"
	dep "github.com/dvyukov/go-fuzz/go-fuzz-dep"
)

func main() {
	dep.Main(target.%v)
}
`
<commit_msg>add diagnostic for relative import paths in go-fuzz-build<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

var (
	flagOut  = flag.String("o", "", "output file")
	flagFunc = flag.String("func", "Fuzz", "entry function")

	workdir string
)

const (
	mainPkg = "go-fuzz-main"
)

// Copies the package with all dependent packages into a temp dir,
// instruments Go source files there and builds setting GOROOT to the temp dir.
func main() {
	flag.Parse()
	if len(flag.Args()) != 1 || len(flag.Arg(0)) == 0 {
		failf("usage: go-fuzz-build pkg")
	}
	if os.Getenv("GOROOT") == "" {
		failf("GOROOT env var is not set, set it to Go installation dir")
	}
	pkg := flag.Arg(0)
	if pkg[0] == '.' {
		failf("relative import paths are not supported, please specify full package name")
	}

	// To produce error messages (this is much faster and gives correct line numbers).
	testNormalBuild(pkg)

	deps := make(map[string]bool)
	for _, p := range goListList(pkg, "Deps") {
		deps[p] = true
	}
	deps[pkg] = true
	// These packages are used by go-fuzz-dep, so we need to copy them regardless.
	deps["runtime"] = true
	deps["syscall"] = true
	deps["time"] = true
	deps["unsafe"] = true

	if *flagOut == "" {
		*flagOut = goListProps(pkg, "Name")[0] + "-fuzz"
	}

	var err error
	workdir, err = ioutil.TempDir("", "go-fuzz-build")
	if err != nil {
		failf("failed to create temp dir: %v", err)
	}
	defer os.RemoveAll(workdir)

	if deps["runtime/cgo"] {
		// Trick go command into thinking that it has up-to-date sources for cmd/cgo.
		cgoDir := filepath.Join(workdir, "src", "cmd", "cgo")
		if err := os.MkdirAll(cgoDir, 0700); err != nil {
			failf("failed to create temp dir: %v", err)
		}
		src := "// +build never\npackage main\n"
		if err := ioutil.WriteFile(filepath.Join(cgoDir, "fake.go"), []byte(src), 0600); err != nil {
			failf("failed to write temp file: %v", err)
		}
	}
	copyDir(filepath.Join(os.Getenv("GOROOT"), "pkg", "tool"), filepath.Join(workdir, "pkg", "tool"), false, true)
	copyDir(filepath.Join(os.Getenv("GOROOT"), "pkg", "include"), filepath.Join(workdir, "pkg", "include"), false, true)
	for p := range deps {
		clonePackage(workdir, p)
	}
	createFuzzMain(pkg)

	cmd := exec.Command("go", "build", "-tags", "gofuzz", "-o", *flagOut, mainPkg)
	for _, v := range os.Environ() {
		if strings.HasPrefix(v, "GOROOT") {
			continue
		}
		cmd.Env = append(cmd.Env, v)
	}
	cmd.Env = append(cmd.Env, "GOROOT="+workdir)
	if out, err := cmd.CombinedOutput(); err != nil {
		failf("failed to execute go build: %v\n%v", err, string(out))
	}
}

func testNormalBuild(pkg string) {
	var err error
	workdir, err = ioutil.TempDir("", "go-fuzz-build")
	if err != nil {
		failf("failed to create temp dir: %v", err)
	}
	defer func() {
		os.RemoveAll(workdir)
		workdir = ""
	}()
	createFuzzMain(pkg)
	cmd := exec.Command("go", "build", "-tags", "gofuzz", "-o", filepath.Join(workdir, "bin"), mainPkg)
	cmd.Env = append([]string{"GOPATH=" + workdir + ":" + os.Getenv("GOPATH")}, os.Environ()...)
	if out, err := cmd.CombinedOutput(); err != nil {
		failf("failed to execute go build: %v\n%v", err, string(out))
	}
}

func createFuzzMain(pkg string) {
	if err := os.MkdirAll(filepath.Join(workdir, "src", mainPkg), 0700); err != nil {
		failf("failed to create temp dir: %v", err)
	}
	src := fmt.Sprintf(mainSrc, pkg, *flagFunc)
	if err := ioutil.WriteFile(filepath.Join(workdir, "src", mainPkg, "main.go"), []byte(src), 0600); err != nil {
		failf("failed to write temp file: %v", err)
	}
}

func clonePackage(workdir, pkg string) {
	dir := goListProps(pkg, "Dir")[0]
	if !strings.HasSuffix(dir, pkg) {
		failf("package dir '%v' does not end with import path '%v'", dir, pkg)
	}
	newDir := filepath.Join(workdir, "src", pkg)
	copyDir(dir, newDir, true, false)
	ignore := []string{
		"runtime",       // lots of non-determinism and irrelevant code paths (e.g. different paths in mallocgc, chans and maps)
		"unsafe",        // nothing to see here (also creates import cycle with go-fuzz-dep)
		"errors",        // nothing to see here (also creates import cycle with go-fuzz-dep)
		"syscall",       // creates import cycle with go-fuzz-dep (and probably nothing to see here)
		"sync",          // non-deterministic and not interesting (also creates import cycle with go-fuzz-dep)
		"sync/atomic",   // not interesting (also creates import cycle with go-fuzz-dep)
		"time",          // creates import cycle with go-fuzz-dep
		"runtime/cgo",   // why would we instrument it?
		"runtime/pprof", // why would we instrument it?
		"runtime/race",  // why would we instrument it?
	}
	for _, p := range ignore {
		if pkg == p {
			return
		}
	}
	files, err := ioutil.ReadDir(newDir)
	if err != nil {
		failf("failed to scan dir '%v': %v", dir, err)
	}
	for _, f := range files {
		if f.IsDir() {
			continue
		}
		if !strings.HasSuffix(f.Name(), ".go") {
			continue
		}
		fn := filepath.Join(newDir, f.Name())
		newFn := fn + ".cover"
		instrument(fn, newFn)
		err := os.Rename(newFn, fn)
		if err != nil {
			failf("failed to rename file: %v", err)
		}
	}
}

func copyDir(dir, newDir string, src, rec bool) {
	if err := os.MkdirAll(newDir, 0700); err != nil {
		failf("failed to create temp dir: %v", err)
	}
	files, err := ioutil.ReadDir(dir)
	if err != nil {
		failf("failed to scan dir '%v': %v", dir, err)
	}
	for _, f := range files {
		if f.IsDir() {
			if rec {
				copyDir(filepath.Join(dir, f.Name()), filepath.Join(newDir, f.Name()), src, rec)
			}
			continue
		}
		if src && !isSourceFile(f.Name()) {
			continue
		}
		data, err := ioutil.ReadFile(filepath.Join(dir, f.Name()))
		if err != nil {
			failf("failed to read file: %v", err)
		}
		if err := ioutil.WriteFile(filepath.Join(newDir, f.Name()), data, 0700); err != nil {
			failf("failed to write temp file: %v", err)
		}
	}
}

func goListList(pkg, what string) []string {
	templ := fmt.Sprintf("{{range .%v}}{{.}}|{{end}}", what)
	out, err := exec.Command("go", "list", "-tags", "gofuzz", "-f", templ, pkg).CombinedOutput()
	if err != nil {
		failf("failed to execute 'go list -f \"%v\" %v': %v\n%v", templ, pkg, err, string(out))
	}
	if len(out) < 2 {
		failf("go list output is empty")
	}
	out = out[:len(out)-2]
	return strings.Split(string(out), "|")
}

func goListProps(pkg string, props ...string) []string {
	templ := ""
	for _, p := range props {
		templ += fmt.Sprintf("{{.%v}}|", p)
	}
	out, err := exec.Command("go", "list", "-tags", "gofuzz", "-f", templ, pkg).CombinedOutput()
	if err != nil {
		failf("failed to execute 'go list -f \"%v\" %v': %v\n%v", templ, pkg, err, string(out))
	}
	if len(out) == 0 {
		failf("go list output is empty")
	}
	out = out[:len(out)-1]
	return strings.Split(string(out), "|")
}

func failf(str string, args ...interface{}) {
	if workdir != "" {
		os.RemoveAll(workdir)
	}
	fmt.Fprintf(os.Stderr, str+"\n", args...)
	os.Exit(1)
}

func isSourceFile(f string) bool {
	return strings.HasSuffix(f, ".go") ||
		strings.HasSuffix(f, ".s") ||
		strings.HasSuffix(f, ".S") ||
		strings.HasSuffix(f, ".c") ||
		strings.HasSuffix(f, ".h") ||
		strings.HasSuffix(f, ".cxx") ||
		strings.HasSuffix(f, ".cpp") ||
		strings.HasSuffix(f, ".c++") ||
		strings.HasSuffix(f, ".cc")
}

var mainSrc = `
package main

import (
	target "%v"
	dep "github.com/dvyukov/go-fuzz/go-fuzz-dep"
)

func main() {
	dep.Main(target.%v)
}
`
<|endoftext|>


<commit_before>package bowling

import (
	"fmt"
	"log"
)

type Game struct {
	frames []*Frame
	rolls  []int
}

func NewGame() *Game {
	return &Game{}
}

func (g *Game) Roll(pins int) error {
	g.rolls = append(g.rolls, pins)
	return nil
}

func (g *Game) parseFrames() {
	g.frames = []*Frame{}
	for _, roll := range g.rolls {
		if len(g.frames) == 0 {
			isComplete := roll == 10
			g.frames = append(g.frames, &Frame{roll, 0, isComplete})
		} else if !g.lastFrame().isComplete {
			g.lastFrame().rollTwo = roll
			g.lastFrame().isComplete = true
		} else {
			isComplete := roll == 10
			g.frames = append(g.frames, &Frame{roll, 0, isComplete})
		}
	}
}

func (g *Game) Score() (score int, err error) {
	g.parseFrames()
	fmt.Printf("rolls: %v\nframes: %v\n", g.rolls, g.frames)
	for i, frame := range g.frames[0:10] {
		score += frame.score(g.frames[i+1:])
	}
	return score, nil
}

func (g *Game) lastFrame() *Frame {
	return g.frames[len(g.frames)-1]
}

type Frame struct {
	rollOne    int
	rollTwo    int
	isComplete bool
}

func (f *Frame) String() string {
	return fmt.Sprintf("[%d, %d]", f.rollOne, f.rollTwo)
}

func (f *Frame) score(nextFrames []*Frame) int {
	if f.isOpenFrame() {
		return f.rollOne + f.rollTwo
	}
	nextFrame := nextFrames[0]
	nextRoll := nextFrame.rollOne
	nextNextRoll := nextFrame.rollTwo
	if f.isSpare() {
		return 10 + nextRoll
	}
	if f.isStrike() {
		return 10 + nextRoll + nextNextRoll
	}
	log.Fatalf("frame %v is not an open frame, spare, or strike", f)
	return 0
}

func (f *Frame) isStrike() bool {
	return isStrike(f.rollOne)
}

func (f *Frame) isSpare() bool {
	return !f.isStrike() && f.rollOne+f.rollTwo == 10
}

func (f *Frame) isOpenFrame() bool {
	return !f.isStrike() && !f.isSpare()
}

func isStrike(roll int) bool {
	return roll == 10
}
<commit_msg>Pass more tests<commit_after>package bowling

import (
	"fmt"
	"log"
)

type Game struct {
	frames []*Frame
	rolls  []int
}

func NewGame() *Game {
	return &Game{}
}

func (g *Game) Roll(pins int) error {
	g.rolls = append(g.rolls, pins)
	return nil
}

func (g *Game) parseFrames() {
	g.frames = []*Frame{}
	for _, roll := range g.rolls {
		if len(g.frames) == 0 {
			isComplete := roll == 10
			g.frames = append(g.frames, &Frame{roll, 0, isComplete})
		} else if !g.lastFrame().isComplete {
			g.lastFrame().rollTwo = roll
			g.lastFrame().isComplete = true
		} else {
			isComplete := roll == 10
			g.frames = append(g.frames, &Frame{roll, 0, isComplete})
		}
	}
}

func (g *Game) Score() (total int, err error) {
	g.parseFrames()
	fmt.Printf("rolls: %v\nframes: %v\n", g.rolls, g.frames)
	if len(g.frames) < 10 {
		return 0, fmt.Errorf("not enough frames %v", g.frames)
	}
	for i, frame := range g.frames[0:10] {
		score := frame.score(g.frames[i+1:])
		fmt.Printf("frame: %v score %v\n", frame, score)
		total += score
	}
	return total, nil
}

func (g *Game) lastFrame() *Frame {
	return g.frames[len(g.frames)-1]
}

type Frame struct {
	rollOne    int
	rollTwo    int
	isComplete bool
}

func (f *Frame) String() string {
	return fmt.Sprintf("[%d, %d]", f.rollOne, f.rollTwo)
}

func (f *Frame) score(nextFrames []*Frame) int {
	if f.isOpenFrame() {
		return f.rollOne + f.rollTwo
	}
	nextRoll, nextNextRoll := nextRolls(nextFrames)
	if f.isSpare() {
		return 10 + nextRoll
	}
	if f.isStrike() {
		return 10 + nextRoll + nextNextRoll
	}
	log.Fatalf("frame %v is not an open frame, spare, or strike", f)
	return 0
}

func (f *Frame) isStrike() bool {
	return isStrike(f.rollOne)
}

func (f *Frame) isSpare() bool {
	return !f.isStrike() && f.rollOne+f.rollTwo == 10
}

func (f *Frame) isOpenFrame() bool {
	return !f.isStrike() && !f.isSpare()
}

func isStrike(roll int) bool {
	return roll == 10
}

func nextRolls(nextFrames []*Frame) (nextRoll int, nextNextRoll int) {
	if len(nextFrames) == 0 {
		return 0, 0
	}
	rolls := []int{}
	for _, frame := range nextFrames {
		if frame.isStrike() {
			rolls = append(rolls, frame.rollOne)
		} else {
			rolls = append(rolls, frame.rollOne)
			rolls = append(rolls, frame.rollTwo)
		}
	}

	if len(rolls) >= 2 {
		return rolls[0], rolls[1]
	} else if len(rolls) == 1 {
		return rolls[0], 0
	} else {
		log.Fatalf("rolls %v is empty", rolls)
		return 0, 0
	}
}
<|endoftext|>


<commit_before>package ws

import (
	"fmt"
	"net/http"
)

func NewWsResponse(errorFinder ServiceErrorFinder) *WsResponse {
	r := new(WsResponse)
	r.Errors = new(ServiceErrors)
	r.Errors.ErrorFinder = errorFinder

	r.Headers = make(map[string]string)

	return r
}

type WsRequest struct {
	PathParameters  map[string]string
	HttpMethod      string
	RequestBody     interface{}
	QueryParams     *WsParams
	PathParams      []string
	FrameworkErrors []*WsFrameworkError
	populatedFields map[string]bool
	UserIdentity    WsIdentity
}

func (wsr *WsRequest) HasFrameworkErrors() bool {
	return len(wsr.FrameworkErrors) > 0
}

func (wsr *WsRequest) AddFrameworkError(f *WsFrameworkError) {
	wsr.FrameworkErrors = append(wsr.FrameworkErrors, f)
}

func (wsr *WsRequest) RecordFieldAsPopulated(fieldName string) {
	if wsr.populatedFields == nil {
		wsr.populatedFields = make(map[string]bool)
	}

	wsr.populatedFields[fieldName] = true
}

func (wsr *WsRequest) WasFieldPopulated(fieldName string) bool {
	return wsr.populatedFields[fieldName] != false
}

type WsResponse struct {
	HttpStatus int
	Body       interface{}
	Errors     *ServiceErrors
	Headers    map[string]string
}

type WsRequestProcessor interface {
	Process(request *WsRequest, response *WsResponse)
}

type WsRequestValidator interface {
	Validate(errors *ServiceErrors, request *WsRequest)
}

type WsUnmarshallTarget interface {
	UnmarshallTarget() interface{}
}

type WsUnmarshaller interface {
	Unmarshall(req *http.Request, wsReq *WsRequest) error
}

type WsResponseWriter interface {
	Write(res *WsResponse, w http.ResponseWriter) error
	WriteErrors(errors *ServiceErrors, w http.ResponseWriter) error
	WriteAbnormalStatus(status int, w http.ResponseWriter) error
}

type AbnormalStatusWriter interface {
	WriteAbnormalStatus(status int, w http.ResponseWriter) error
}

func WriteMetaData(w http.ResponseWriter, r *WsResponse, defaultHeaders map[string]string) {

	additionalHeaders := r.Headers

	for k, v := range defaultHeaders {

		if additionalHeaders == nil || additionalHeaders[k] == "" {
			w.Header().Add(k, v)
		}

	}

	if additionalHeaders != nil {
		for k, v := range additionalHeaders {
			w.Header().Add(k, v)
		}
	}

}
<commit_msg>HTTP server refactoring<commit_after>package ws

import (
	"net/http"
)

func NewWsResponse(errorFinder ServiceErrorFinder) *WsResponse {
	r := new(WsResponse)
	r.Errors = new(ServiceErrors)
	r.Errors.ErrorFinder = errorFinder

	r.Headers = make(map[string]string)

	return r
}

type WsRequest struct {
	PathParameters  map[string]string
	HttpMethod      string
	RequestBody     interface{}
	QueryParams     *WsParams
	PathParams      []string
	FrameworkErrors []*WsFrameworkError
	populatedFields map[string]bool
	UserIdentity    WsIdentity
}

func (wsr *WsRequest) HasFrameworkErrors() bool {
	return len(wsr.FrameworkErrors) > 0
}

func (wsr *WsRequest) AddFrameworkError(f *WsFrameworkError) {
	wsr.FrameworkErrors = append(wsr.FrameworkErrors, f)
}

func (wsr *WsRequest) RecordFieldAsPopulated(fieldName string) {
	if wsr.populatedFields == nil {
		wsr.populatedFields = make(map[string]bool)
	}

	wsr.populatedFields[fieldName] = true
}

func (wsr *WsRequest) WasFieldPopulated(fieldName string) bool {
	return wsr.populatedFields[fieldName] != false
}

type WsResponse struct {
	HttpStatus int
	Body       interface{}
	Errors     *ServiceErrors
	Headers    map[string]string
}

type WsRequestProcessor interface {
	Process(request *WsRequest, response *WsResponse)
}

type WsRequestValidator interface {
	Validate(errors *ServiceErrors, request *WsRequest)
}

type WsUnmarshallTarget interface {
	UnmarshallTarget() interface{}
}

type WsUnmarshaller interface {
	Unmarshall(req *http.Request, wsReq *WsRequest) error
}

type WsResponseWriter interface {
	Write(res *WsResponse, w http.ResponseWriter) error
	WriteErrors(errors *ServiceErrors, w http.ResponseWriter) error
	WriteAbnormalStatus(status int, w http.ResponseWriter) error
}

type AbnormalStatusWriter interface {
	WriteAbnormalStatus(status int, w http.ResponseWriter) error
}

func WriteMetaData(w http.ResponseWriter, r *WsResponse, defaultHeaders map[string]string) {

	additionalHeaders := r.Headers

	for k, v := range defaultHeaders {

		if additionalHeaders == nil || additionalHeaders[k] == "" {
			w.Header().Add(k, v)
		}

	}

	if additionalHeaders != nil {
		for k, v := range additionalHeaders {
			w.Header().Add(k, v)
		}
	}

}
<|endoftext|>


<commit_before>// Copyright 2016 Marc-Antoine Ruel. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

// Packages the static files in a .go file.
//go:generate go run ../package/main.go -out static_files_gen.go ../../../web

// dlibox drives the dlibox LED strip on a Raspberry Pi. It runs a web server
// for remote control.
package main

import (
	"fmt"
	"os"
	"runtime"
	"sync"

	"github.com/maruel/dlibox/go/donotuse/conn/spi"
	"github.com/maruel/dlibox/go/donotuse/devices"
	"github.com/maruel/dlibox/go/donotuse/devices/apa102"
	"github.com/maruel/dlibox/go/donotuse/host"
	"github.com/maruel/dlibox/go/screen"
)

// APA102 contains light specific settings.
type APA102 struct {
	sync.Mutex
	// Speed of the transfer.
	SPIspeed int64
	// Number of lights controlled by this device. If lower than the actual
	// number of lights, the remaining lights will flash oddly.
	NumberLights int
}

func (a *APA102) ResetDefault() {
	a.Lock()
	defer a.Unlock()
	a.SPIspeed = 10000000
	a.NumberLights = 150
}

func (a *APA102) Validate() error {
	a.Lock()
	defer a.Unlock()
	return nil
}

// initLEDs initializes the LED strip.
func initLEDs(fake bool, config *APA102) (devices.Display, func(), []string, int, error) {
	if fake {
		// Output (terminal with ANSI codes or APA102).
		// Hardcode to 100 characters when using a terminal output.
		// TODO(maruel): Query the terminal and use its width.
		leds := screen.New(100)
		end := func() { os.Stdout.Write([]byte("\033[0m\n")) }
		// Use lower refresh rate too.
		return leds, end, []string{"fake=1"}, 30, nil
	}

	fps := 60
	if host.MaxSpeed() < 900000 || runtime.NumCPU() < 4 {
		// Use 30Hz on slower devices because it is too slow.
		fps = 30
	}
	spiBus, err := spi.New(-1, -1)
	if err != nil {
		return nil, nil, nil, 0, err
	}
	if err = spiBus.Speed(config.SPIspeed); err != nil {
		return nil, nil, nil, 0, err
	}
	end := func() { spiBus.Close() }
	leds, err := apa102.New(spiBus, config.NumberLights, 255, 6500)
	if err != nil {
		return nil, end, nil, 0, err
	}
	return leds, end, []string{fmt.Sprintf("APA102=%d", config.NumberLights)}, fps, nil
}
<commit_msg>Enables specifying the SPI bus number.<commit_after>// Copyright 2016 Marc-Antoine Ruel. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

// Packages the static files in a .go file.
//go:generate go run ../package/main.go -out static_files_gen.go ../../../web

// dlibox drives the dlibox LED strip on a Raspberry Pi. It runs a web server
// for remote control.
package main

import (
	"fmt"
	"os"
	"runtime"
	"sync"

	"github.com/maruel/dlibox/go/donotuse/conn/spi"
	"github.com/maruel/dlibox/go/donotuse/devices"
	"github.com/maruel/dlibox/go/donotuse/devices/apa102"
	"github.com/maruel/dlibox/go/donotuse/host"
	"github.com/maruel/dlibox/go/screen"
)

// APA102 contains light specific settings.
type APA102 struct {
	sync.Mutex
	// BusNumber is the SPI bus number to use, defaults to -1.
	BusNumber int
	// Speed of the transfer.
	SPIspeed int64
	// Number of lights controlled by this device. If lower than the actual
	// number of lights, the remaining lights will flash oddly.
	NumberLights int
}

func (a *APA102) ResetDefault() {
	a.Lock()
	defer a.Unlock()
	a.BusNumber = -1
	a.SPIspeed = 10000000
	a.NumberLights = 150
}

func (a *APA102) Validate() error {
	a.Lock()
	defer a.Unlock()
	return nil
}

// initLEDs initializes the LED strip.
func initLEDs(fake bool, config *APA102) (devices.Display, func(), []string, int, error) {
	if fake {
		// Output (terminal with ANSI codes or APA102).
		// Hardcode to 100 characters when using a terminal output.
		// TODO(maruel): Query the terminal and use its width.
		leds := screen.New(100)
		end := func() { os.Stdout.Write([]byte("\033[0m\n")) }
		// Use lower refresh rate too.
		return leds, end, []string{"fake=1"}, 30, nil
	}

	fps := 60
	if host.MaxSpeed() < 900000 || runtime.NumCPU() < 4 {
		// Use 30Hz on slower devices because it is too slow.
		fps = 30
	}
	spiBus, err := spi.New(config.BusNumber, 0)
	if err != nil {
		return nil, nil, nil, 0, err
	}
	if err = spiBus.Speed(config.SPIspeed); err != nil {
		return nil, nil, nil, 0, err
	}
	end := func() { spiBus.Close() }
	leds, err := apa102.New(spiBus, config.NumberLights, 255, 6500)
	if err != nil {
		return nil, end, nil, 0, err
	}
	return leds, end, []string{fmt.Sprintf("APA102=%d", config.NumberLights)}, fps, nil
}
<|endoftext|>


<commit_before>/*
   Copyright 2014 Outbrain Inc.

   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 http

import (
	"fmt"
	"github.com/go-martini/martini"
	"github.com/martini-contrib/render"
	"net/http"
	"strconv"
	"strings"

	"github.com/outbrain/orchestrator/go/agent"
	"github.com/outbrain/orchestrator/go/attributes"
)

type HttpAgentsAPI struct{}

var AgentsAPI HttpAgentsAPI = HttpAgentsAPI{}

// SubmitAgent registeres an agent. It is initiated by an agent to register itself.
func (this *HttpAgentsAPI) SubmitAgent(params martini.Params, r render.Render) {
	port, err := strconv.Atoi(params["port"])
	if err != nil {
		r.JSON(200, &APIResponse{Code: ERROR, Message: err.Error()})
		return
	}

	output, err := agent.SubmitAgent(params["host"], port, params["token"])
	if err != nil {
		r.JSON(200, &APIResponse{Code: ERROR, Message: err.Error()})
		return
	}
	r.JSON(200, output)
}

// SetHostAttribute is a utility method that allows per-host key-value store.
func (this *HttpAgentsAPI) SetHostAttribute(params martini.Params, r render.Render, req *http.Request) {
	err := attributes.SetHostAttributes(params["host"], params["attrVame"], params["attrValue"])

	if err != nil {
		r.JSON(200, &APIResponse{Code: ERROR, Message: fmt.Sprintf("%+v", err)})
		return
	}

	r.JSON(200, (err == nil))
}

// GetHostAttributeByAttributeName returns a host attribute
func (this *HttpAgentsAPI) GetHostAttributeByAttributeName(params martini.Params, r render.Render, req *http.Request) {

	output, err := attributes.GetHostAttributesByAttribute(params["attr"], req.URL.Query().Get("valueMatch"))

	if err != nil {
		r.JSON(200, &APIResponse{Code: ERROR, Message: fmt.Sprintf("%+v", err)})
		return
	}

	r.JSON(200, output)
}

// AgentsHosts provides list of agent host names
func (this *HttpAgentsAPI) AgentsHosts(params martini.Params, r render.Render, req *http.Request) string {
	agents, err := agent.ReadAgents()
	hostnames := []string{}
	for _, agent := range agents {
		hostnames = append(hostnames, agent.Hostname)
	}

	if err != nil {
		r.JSON(200, &APIResponse{Code: ERROR, Message: fmt.Sprintf("%+v", err)})
		return ""
	}

	if req.URL.Query().Get("format") == "txt" {
		return strings.Join(hostnames, "\n")
	} else {
		r.JSON(200, hostnames)
	}
	return ""
}

// AgentsInstances provides list of assumed MySQL instances (host:port)
func (this *HttpAgentsAPI) AgentsInstances(params martini.Params, r render.Render, req *http.Request) string {
	agents, err := agent.ReadAgents()
	hostnames := []string{}
	for _, agent := range agents {
		hostnames = append(hostnames, fmt.Sprintf("%s:%d", agent.Hostname, agent.MySQLPort))
	}

	if err != nil {
		r.JSON(200, &APIResponse{Code: ERROR, Message: fmt.Sprintf("%+v", err)})
		return ""
	}

	if req.URL.Query().Get("format") == "txt" {
		return strings.Join(hostnames, "\n")
	} else {
		r.JSON(200, hostnames)
	}
	return ""
}

// RegisterRequests makes for the de-facto list of known API calls
func (this *HttpAgentsAPI) RegisterRequests(m *martini.ClassicMartini) {
	m.Get("/api/submit-agent/:host/:port/:token", this.SubmitAgent)
	m.Get("/api/host-attribute/:host/:attrVame/:attrValue", this.SetHostAttribute)
	m.Get("/api/host-attribute/attr/:attr/", this.GetHostAttributeByAttributeName)
	m.Get("/api/agents-hosts", this.AgentsHosts)
	m.Get("/api/agents-instances", this.AgentsInstances)
}
<commit_msg>Adding an agent ping endpoint This is a lightweight endpoint the agents can hit to verify connectivity with the server.  There is a related change coming for orchestrator-agent that change the local status depending on if this connectivity fails for a long enough period of time.<commit_after>/*
   Copyright 2014 Outbrain Inc.

   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 http

import (
	"fmt"
	"net/http"
	"strconv"
	"strings"

	"github.com/go-martini/martini"
	"github.com/martini-contrib/render"

	"github.com/outbrain/orchestrator/go/agent"
	"github.com/outbrain/orchestrator/go/attributes"
)

type HttpAgentsAPI struct{}

var AgentsAPI HttpAgentsAPI = HttpAgentsAPI{}

// SubmitAgent registeres an agent. It is initiated by an agent to register itself.
func (this *HttpAgentsAPI) SubmitAgent(params martini.Params, r render.Render) {
	port, err := strconv.Atoi(params["port"])
	if err != nil {
		r.JSON(200, &APIResponse{Code: ERROR, Message: err.Error()})
		return
	}

	output, err := agent.SubmitAgent(params["host"], port, params["token"])
	if err != nil {
		r.JSON(200, &APIResponse{Code: ERROR, Message: err.Error()})
		return
	}
	r.JSON(200, output)
}

// SetHostAttribute is a utility method that allows per-host key-value store.
func (this *HttpAgentsAPI) SetHostAttribute(params martini.Params, r render.Render, req *http.Request) {
	err := attributes.SetHostAttributes(params["host"], params["attrVame"], params["attrValue"])

	if err != nil {
		r.JSON(200, &APIResponse{Code: ERROR, Message: fmt.Sprintf("%+v", err)})
		return
	}

	r.JSON(200, (err == nil))
}

// GetHostAttributeByAttributeName returns a host attribute
func (this *HttpAgentsAPI) GetHostAttributeByAttributeName(params martini.Params, r render.Render, req *http.Request) {

	output, err := attributes.GetHostAttributesByAttribute(params["attr"], req.URL.Query().Get("valueMatch"))

	if err != nil {
		r.JSON(200, &APIResponse{Code: ERROR, Message: fmt.Sprintf("%+v", err)})
		return
	}

	r.JSON(200, output)
}

// AgentsHosts provides list of agent host names
func (this *HttpAgentsAPI) AgentsHosts(params martini.Params, r render.Render, req *http.Request) string {
	agents, err := agent.ReadAgents()
	hostnames := []string{}
	for _, agent := range agents {
		hostnames = append(hostnames, agent.Hostname)
	}

	if err != nil {
		r.JSON(200, &APIResponse{Code: ERROR, Message: fmt.Sprintf("%+v", err)})
		return ""
	}

	if req.URL.Query().Get("format") == "txt" {
		return strings.Join(hostnames, "\n")
	} else {
		r.JSON(200, hostnames)
	}
	return ""
}

// AgentsInstances provides list of assumed MySQL instances (host:port)
func (this *HttpAgentsAPI) AgentsInstances(params martini.Params, r render.Render, req *http.Request) string {
	agents, err := agent.ReadAgents()
	hostnames := []string{}
	for _, agent := range agents {
		hostnames = append(hostnames, fmt.Sprintf("%s:%d", agent.Hostname, agent.MySQLPort))
	}

	if err != nil {
		r.JSON(200, &APIResponse{Code: ERROR, Message: fmt.Sprintf("%+v", err)})
		return ""
	}

	if req.URL.Query().Get("format") == "txt" {
		return strings.Join(hostnames, "\n")
	} else {
		r.JSON(200, hostnames)
	}
	return ""
}

func (this *HttpAgentsAPI) AgentPing(params martini.Params, r render.Render, req *http.Request) {
	r.JSON(200, "OK")
}

// RegisterRequests makes for the de-facto list of known API calls
func (this *HttpAgentsAPI) RegisterRequests(m *martini.ClassicMartini) {
	m.Get("/api/submit-agent/:host/:port/:token", this.SubmitAgent)
	m.Get("/api/host-attribute/:host/:attrVame/:attrValue", this.SetHostAttribute)
	m.Get("/api/host-attribute/attr/:attr/", this.GetHostAttributeByAttributeName)
	m.Get("/api/agents-hosts", this.AgentsHosts)
	m.Get("/api/agents-instances", this.AgentsInstances)
	m.Get("/api/agent-ping", this.AgentPing)
}
<|endoftext|>


<commit_before>package isogram

// IsIsogram returns whether the provided string is an isogram.
// In other words, whether the string does not contain any duplicate characters.
func IsIsogram(s string) bool {
	return true
}
<commit_msg>Solve isogram<commit_after>package isogram

import "strings"

// IsIsogram returns whether the provided string is an isogram.
// In other words, whether the string does not contain any duplicate characters.
func IsIsogram(s string) bool {
	parsed := strings.ToLower(removeWhitespaceAndHyphens(s))
	seen := make(map[rune]bool)
	for _, c := range parsed {
		if (seen[c]) == true {
			return false
		}
		seen[c] = true
	}
	return true
}

func removeWhitespaceAndHyphens(s string) string {
	return strings.Map(func(r rune) rune {
		if r == ' ' || r == '-' {
			return -1
		}
		return r
	}, s)
}
<|endoftext|>


<commit_before>package main

import (
    "gopkg.in/yaml.v2"
    "io/ioutil"
    "fmt"
    "encoding/hex"
    "encoding/binary"
    "github.com/fuzxxl/nfc/2.0/nfc"
    "github.com/fuzxxl/freefare/0.3/freefare"
    "./keydiversification"
)

// TODO: move to a separate helper module
func string_to_aeskey(keydata_str string) (*freefare.DESFireKey, error) {
    keydata := new([16]byte)
    to_keydata, err := hex.DecodeString(keydata_str)
    if err != nil {
        key := freefare.NewDESFireAESKey(*keydata, 0)
        return key, err
    }
    copy(keydata[0:], to_keydata)
    key := freefare.NewDESFireAESKey(*keydata, 0)
    return key,nil
}

func bytes_to_aeskey(source []byte) (*freefare.DESFireKey) {
    keydata := new([16]byte)
    copy(keydata[0:], source)
    key := freefare.NewDESFireAESKey(*keydata, 0)
    return key
}

func string_to_byte(source string) (byte, error) {
    bytearray, err := hex.DecodeString(source)
    if err != nil {
        return 0x0, err
    }
    return bytearray[0], nil
}

func main() {
    keys_data, err := ioutil.ReadFile("keys.yaml")
    if err != nil {
        panic(err)
    }

    keymap := make(map[interface{}]interface{});
    err = yaml.Unmarshal([]byte(keys_data), &keymap);
    if err != nil {
        panic(err)
    }

    apps_data, err := ioutil.ReadFile("apps.yaml")
    if err != nil {
        panic(err)
    }

    appmap := make(map[interface{}]interface{});
    err = yaml.Unmarshal([]byte(apps_data), &appmap);
    if err != nil {
        panic(err)
    }

    // Application-id from config
    aidbytes, err := hex.DecodeString(appmap["hacklab_acl"].(map[interface{}]interface{})["aid"].(string))
    if err != nil {
        panic(err)
    }
    aidint, n := binary.Uvarint(aidbytes)
    if n <= 0 {
        panic(fmt.Sprintf("binary.Uvarint returned %d", n))
    }
    aid := freefare.NewDESFireAid(uint32(aidint))
    //fmt.Println(aid)
    // Needed for diversification
    sysid, err := hex.DecodeString(appmap["hacklab_acl"].(map[interface{}]interface{})["sysid"].(string))
    if err != nil {
        panic(err)
    }

    // Key id numbers from config
    uid_read_key_id, err := string_to_byte(appmap["hacklab_acl"].(map[interface{}]interface{})["uid_read_key_id"].(string))
    if err != nil {
        panic(err)
    }
    acl_read_key_id, err := string_to_byte(appmap["hacklab_acl"].(map[interface{}]interface{})["acl_read_key_id"].(string))
    if err != nil {
        panic(err)
    }
    acl_write_key_id, err := string_to_byte(appmap["hacklab_acl"].(map[interface{}]interface{})["acl_write_key_id"].(string))
    if err != nil {
        panic(err)
    }
    prov_key_id, err := string_to_byte(appmap["hacklab_acl"].(map[interface{}]interface{})["provisioning_key_id"].(string))
    if err != nil {
        panic(err)
    }

    // Defaul (null) key
    nullkeydata := new([8]byte)
    defaultkey := freefare.NewDESFireDESKey(*nullkeydata)

    // New card master key
    new_master_key, err := string_to_aeskey(keymap["card_master"].(string))
    if err != nil {
        panic(err)
    }
    //fmt.Println(new_master_key)

    // The static app key to read UID
    uid_read_key, err := string_to_aeskey(keymap["uid_read_key"].(string))
    if err != nil {
        panic(err)
    }
    //fmt.Println(uid_read_key)

    // Bases for the diversified keys
    prov_key_base, err := hex.DecodeString(keymap["prov_master"].(string))
    if err != nil {
        panic(err)
    }
    acl_read_base, err := hex.DecodeString(keymap["acl_read_key"].(string))
    if err != nil {
        panic(err)
    }
    acl_write_base, err := hex.DecodeString(keymap["acl_write_key"].(string))
    if err != nil {
        panic(err)
    }

    // Open device and get tags list
    d, err := nfc.Open("");
    if err != nil {
        panic(err)
    }

    tags, err := freefare.GetTags(d);
    if err != nil {
        panic(err)
    }

    // Initialize each tag with our app
    for i := 0; i < len(tags); i++ {
        tag := tags[i]
        fmt.Println(tag.String(), tag.UID())

        // Skip non desfire tags
        if (tag.Type() != freefare.DESFire) {
            fmt.Println("Skipped");
            continue
        }

        desfiretag := tag.(freefare.DESFireTag)

        // Connect to this tag
        fmt.Println("Connecting");
        error := desfiretag.Connect()
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        fmt.Println("Authenticating");
        error = desfiretag.Authenticate(0,*defaultkey)
        if error != nil {
            fmt.Println("Failed, trying agin with new key")
            error = desfiretag.Authenticate(0,*new_master_key)
            if error != nil {
                panic(error)
            }
            fmt.Println("Changing key back to default")
            error = desfiretag.ChangeKey(0,  *defaultkey, *new_master_key);
            if error != nil {
                panic(error)
            }
            fmt.Println("Re-auth with default key")
            error = desfiretag.Authenticate(0,*defaultkey)
            if error != nil {
                panic(error)
            }
            fmt.Println("Formatting (to get a clean state)")
            error = desfiretag.FormatPICC()
            if error != nil {
                panic(error)
            }
            return
        }
        fmt.Println("Done");

        // Get card real UID
        realuid_str, error := desfiretag.CardUID()
        if error != nil {
            panic(error)
        }
        realuid, error := hex.DecodeString(realuid_str);
        if error != nil {
            panic(error)
        }

        // Calculate the diversified keys
        prov_key_bytes, err := keydiversification.AES128(prov_key_base, aidbytes, realuid, sysid)
        if err != nil {
            panic(err)
        }
        prov_key := bytes_to_aeskey(prov_key_bytes)
        acl_read_bytes, err := keydiversification.AES128(acl_read_base, aidbytes, realuid, sysid)
        if err != nil {
            panic(err)
        }
        acl_read_key := bytes_to_aeskey(acl_read_bytes)
        acl_write_bytes, err := keydiversification.AES128(acl_write_base, aidbytes, realuid, sysid)
        if err != nil {
            panic(err)
        }
        acl_write_key := bytes_to_aeskey(acl_write_bytes)

        fmt.Println("Changing default master key");
        error = desfiretag.ChangeKey(0, *new_master_key, *defaultkey);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        /**
         * This is not needed for creating the application and does not help when changing application keys
        fmt.Println("Re-auth with new key")
        error = desfiretag.Authenticate(0,*new_master_key)
        if error != nil {
            panic(error)
        }
         */

        fmt.Println("Creating application");
        // TODO:Figure out what the settings byte (now hardcoded to 0xFF as it was in libfreefare example code) actually does
        error = desfiretag.CreateApplication(aid, 0xFF, 6 | freefare.CryptoAES);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        fmt.Println("Selecting application");
        // TODO:Figure out what the settings byte (now hardcoded to 0xFF as it was in libfreefare exampkle code) actually does
        error = desfiretag.SelectApplication(aid);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        /**
         * Does not work
        fmt.Println("Re-auth with new master key")
        error = desfiretag.Authenticate(0,*new_master_key)
        if error != nil {
            panic(error)
        }
         */

        /**
         * Also does not work
        fmt.Println("Re-auth with default key")
        error = desfiretag.Authenticate(0,*defaultkey)
        if error != nil {
            panic(error)
        }
         */

        fmt.Println("Changing provisioning key");
        error = desfiretag.ChangeKey(prov_key_id, *prov_key, *defaultkey);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        fmt.Println("Re-auth with new provisioning key")
        error = desfiretag.Authenticate(prov_key_id,*prov_key)
        if error != nil {
            panic(error)
        }

        fmt.Println("Changing static UID reading key");
        error = desfiretag.ChangeKey(uid_read_key_id, *uid_read_key, *defaultkey);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        fmt.Println("Changing ACL reading key");
        error = desfiretag.ChangeKey(acl_read_key_id, *acl_read_key, *defaultkey);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        fmt.Println("Changing ACL writing key");
        error = desfiretag.ChangeKey(acl_write_key_id, *acl_write_key, *defaultkey);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        fmt.Println("Creating ACL data file");
        error = desfiretag.CreateDataFile(0, freefare.Enciphered, freefare.MakeDESFireAccessRights(acl_read_key_id, acl_write_key_id, prov_key_id, prov_key_id), 8, false)
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        // Not sure if this is actually needed
        fmt.Println("Committing");
        error = desfiretag.CommitTransaction()
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        fmt.Println("Disconnecting");
        error = desfiretag.Disconnect()
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");
    }

}<commit_msg>skip the commit step for now<commit_after>package main

import (
    "gopkg.in/yaml.v2"
    "io/ioutil"
    "fmt"
    "encoding/hex"
    "encoding/binary"
    "github.com/fuzxxl/nfc/2.0/nfc"
    "github.com/fuzxxl/freefare/0.3/freefare"
    "./keydiversification"
)

// TODO: move to a separate helper module
func string_to_aeskey(keydata_str string) (*freefare.DESFireKey, error) {
    keydata := new([16]byte)
    to_keydata, err := hex.DecodeString(keydata_str)
    if err != nil {
        key := freefare.NewDESFireAESKey(*keydata, 0)
        return key, err
    }
    copy(keydata[0:], to_keydata)
    key := freefare.NewDESFireAESKey(*keydata, 0)
    return key,nil
}

func bytes_to_aeskey(source []byte) (*freefare.DESFireKey) {
    keydata := new([16]byte)
    copy(keydata[0:], source)
    key := freefare.NewDESFireAESKey(*keydata, 0)
    return key
}

func string_to_byte(source string) (byte, error) {
    bytearray, err := hex.DecodeString(source)
    if err != nil {
        return 0x0, err
    }
    return bytearray[0], nil
}

func main() {
    keys_data, err := ioutil.ReadFile("keys.yaml")
    if err != nil {
        panic(err)
    }

    keymap := make(map[interface{}]interface{});
    err = yaml.Unmarshal([]byte(keys_data), &keymap);
    if err != nil {
        panic(err)
    }

    apps_data, err := ioutil.ReadFile("apps.yaml")
    if err != nil {
        panic(err)
    }

    appmap := make(map[interface{}]interface{});
    err = yaml.Unmarshal([]byte(apps_data), &appmap);
    if err != nil {
        panic(err)
    }

    // Application-id from config
    aidbytes, err := hex.DecodeString(appmap["hacklab_acl"].(map[interface{}]interface{})["aid"].(string))
    if err != nil {
        panic(err)
    }
    aidint, n := binary.Uvarint(aidbytes)
    if n <= 0 {
        panic(fmt.Sprintf("binary.Uvarint returned %d", n))
    }
    aid := freefare.NewDESFireAid(uint32(aidint))
    //fmt.Println(aid)
    // Needed for diversification
    sysid, err := hex.DecodeString(appmap["hacklab_acl"].(map[interface{}]interface{})["sysid"].(string))
    if err != nil {
        panic(err)
    }

    // Key id numbers from config
    uid_read_key_id, err := string_to_byte(appmap["hacklab_acl"].(map[interface{}]interface{})["uid_read_key_id"].(string))
    if err != nil {
        panic(err)
    }
    acl_read_key_id, err := string_to_byte(appmap["hacklab_acl"].(map[interface{}]interface{})["acl_read_key_id"].(string))
    if err != nil {
        panic(err)
    }
    acl_write_key_id, err := string_to_byte(appmap["hacklab_acl"].(map[interface{}]interface{})["acl_write_key_id"].(string))
    if err != nil {
        panic(err)
    }
    prov_key_id, err := string_to_byte(appmap["hacklab_acl"].(map[interface{}]interface{})["provisioning_key_id"].(string))
    if err != nil {
        panic(err)
    }

    // Defaul (null) key
    nullkeydata := new([8]byte)
    defaultkey := freefare.NewDESFireDESKey(*nullkeydata)

    // New card master key
    new_master_key, err := string_to_aeskey(keymap["card_master"].(string))
    if err != nil {
        panic(err)
    }
    //fmt.Println(new_master_key)

    // The static app key to read UID
    uid_read_key, err := string_to_aeskey(keymap["uid_read_key"].(string))
    if err != nil {
        panic(err)
    }
    //fmt.Println(uid_read_key)

    // Bases for the diversified keys
    prov_key_base, err := hex.DecodeString(keymap["prov_master"].(string))
    if err != nil {
        panic(err)
    }
    acl_read_base, err := hex.DecodeString(keymap["acl_read_key"].(string))
    if err != nil {
        panic(err)
    }
    acl_write_base, err := hex.DecodeString(keymap["acl_write_key"].(string))
    if err != nil {
        panic(err)
    }

    // Open device and get tags list
    d, err := nfc.Open("");
    if err != nil {
        panic(err)
    }

    tags, err := freefare.GetTags(d);
    if err != nil {
        panic(err)
    }

    // Initialize each tag with our app
    for i := 0; i < len(tags); i++ {
        tag := tags[i]
        fmt.Println(tag.String(), tag.UID())

        // Skip non desfire tags
        if (tag.Type() != freefare.DESFire) {
            fmt.Println("Skipped");
            continue
        }

        desfiretag := tag.(freefare.DESFireTag)

        // Connect to this tag
        fmt.Println("Connecting");
        error := desfiretag.Connect()
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        fmt.Println("Authenticating");
        error = desfiretag.Authenticate(0,*defaultkey)
        if error != nil {
            fmt.Println("Failed, trying agin with new key")
            error = desfiretag.Authenticate(0,*new_master_key)
            if error != nil {
                panic(error)
            }
            fmt.Println("Changing key back to default")
            error = desfiretag.ChangeKey(0,  *defaultkey, *new_master_key);
            if error != nil {
                panic(error)
            }
            fmt.Println("Re-auth with default key")
            error = desfiretag.Authenticate(0,*defaultkey)
            if error != nil {
                panic(error)
            }
            fmt.Println("Formatting (to get a clean state)")
            error = desfiretag.FormatPICC()
            if error != nil {
                panic(error)
            }
            return
        }
        fmt.Println("Done");

        // Get card real UID
        realuid_str, error := desfiretag.CardUID()
        if error != nil {
            panic(error)
        }
        realuid, error := hex.DecodeString(realuid_str);
        if error != nil {
            panic(error)
        }

        // Calculate the diversified keys
        prov_key_bytes, err := keydiversification.AES128(prov_key_base, aidbytes, realuid, sysid)
        if err != nil {
            panic(err)
        }
        prov_key := bytes_to_aeskey(prov_key_bytes)
        acl_read_bytes, err := keydiversification.AES128(acl_read_base, aidbytes, realuid, sysid)
        if err != nil {
            panic(err)
        }
        acl_read_key := bytes_to_aeskey(acl_read_bytes)
        acl_write_bytes, err := keydiversification.AES128(acl_write_base, aidbytes, realuid, sysid)
        if err != nil {
            panic(err)
        }
        acl_write_key := bytes_to_aeskey(acl_write_bytes)

        fmt.Println("Changing default master key");
        error = desfiretag.ChangeKey(0, *new_master_key, *defaultkey);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        /**
         * This is not needed for creating the application and does not help when changing application keys
        fmt.Println("Re-auth with new key")
        error = desfiretag.Authenticate(0,*new_master_key)
        if error != nil {
            panic(error)
        }
         */

        fmt.Println("Creating application");
        // TODO:Figure out what the settings byte (now hardcoded to 0xFF as it was in libfreefare example code) actually does
        error = desfiretag.CreateApplication(aid, 0xFF, 6 | freefare.CryptoAES);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        fmt.Println("Selecting application");
        // TODO:Figure out what the settings byte (now hardcoded to 0xFF as it was in libfreefare exampkle code) actually does
        error = desfiretag.SelectApplication(aid);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        /**
         * Does not work
        fmt.Println("Re-auth with new master key")
        error = desfiretag.Authenticate(0,*new_master_key)
        if error != nil {
            panic(error)
        }
         */

        /**
         * Also does not work
        fmt.Println("Re-auth with default key")
        error = desfiretag.Authenticate(0,*defaultkey)
        if error != nil {
            panic(error)
        }
         */

        fmt.Println("Changing provisioning key");
        error = desfiretag.ChangeKey(prov_key_id, *prov_key, *defaultkey);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        fmt.Println("Re-auth with new provisioning key")
        error = desfiretag.Authenticate(prov_key_id,*prov_key)
        if error != nil {
            panic(error)
        }

        fmt.Println("Changing static UID reading key");
        error = desfiretag.ChangeKey(uid_read_key_id, *uid_read_key, *defaultkey);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        fmt.Println("Changing ACL reading key");
        error = desfiretag.ChangeKey(acl_read_key_id, *acl_read_key, *defaultkey);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        fmt.Println("Changing ACL writing key");
        error = desfiretag.ChangeKey(acl_write_key_id, *acl_write_key, *defaultkey);
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        fmt.Println("Creating ACL data file");
        error = desfiretag.CreateDataFile(0, freefare.Enciphered, freefare.MakeDESFireAccessRights(acl_read_key_id, acl_write_key_id, prov_key_id, prov_key_id), 8, false)
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");

        /**
         * Only needed when working with backup files
        // Not sure if this is actually needed
        fmt.Println("Committing");
        error = desfiretag.CommitTransaction()
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");
         */

        fmt.Println("Disconnecting");
        error = desfiretag.Disconnect()
        if error != nil {
            panic(error)
        }
        fmt.Println("Done");
    }

}<|endoftext|>


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

package rpcwrap

import (
	"bufio"
	"crypto/tls"
	"errors"
	"io"
	"net"
	"net/http"
	"time"

	"golang.org/x/net/context"

	log "github.com/golang/glog"
	rpc "github.com/youtube/vitess/go/rpcplus"
	"github.com/youtube/vitess/go/rpcwrap/auth"
	"github.com/youtube/vitess/go/rpcwrap/proto"
	"github.com/youtube/vitess/go/stats"
)

const (
	connected = "200 Connected to Go RPC"
)

var (
	connCount    = stats.NewInt("connection-count")
	connAccepted = stats.NewInt("connection-accepted")
)

type ClientCodecFactory func(conn io.ReadWriteCloser) rpc.ClientCodec

type BufferedConnection struct {
	isClosed bool
	*bufio.Reader
	io.WriteCloser
}

func NewBufferedConnection(conn io.ReadWriteCloser) *BufferedConnection {
	connCount.Add(1)
	connAccepted.Add(1)
	return &BufferedConnection{false, bufio.NewReader(conn), conn}
}

// FIXME(sougou/szopa): Find a better way to track connection count.
func (bc *BufferedConnection) Close() error {
	if !bc.isClosed {
		bc.isClosed = true
		connCount.Add(-1)
	}
	return bc.WriteCloser.Close()
}

// DialHTTP connects to a go HTTP RPC server using the specified codec.
// use 0 as connectTimeout for no timeout
// use nil as config to not use TLS
func DialHTTP(network, address, codecName string, cFactory ClientCodecFactory, connectTimeout time.Duration, config *tls.Config) (*rpc.Client, error) {
	return dialHTTP(network, address, codecName, cFactory, false, connectTimeout, config)
}

// DialAuthHTTP connects to an authenticated go HTTP RPC server using
// the specified codec and credentials.
// use 0 as connectTimeout for no timeout
// use nil as config to not use TLS
func DialAuthHTTP(network, address, user, password, codecName string, cFactory ClientCodecFactory, connectTimeout time.Duration, config *tls.Config) (conn *rpc.Client, err error) {
	if conn, err = dialHTTP(network, address, codecName, cFactory, true, connectTimeout, config); err != nil {
		return
	}
	reply := new(auth.GetNewChallengeReply)
	if err = conn.Call(context.TODO(), "AuthenticatorCRAMMD5.GetNewChallenge", "", reply); err != nil {
		return
	}
	proof := auth.CRAMMD5GetExpected(user, password, reply.Challenge)

	if err = conn.Call(
		context.TODO(),
		"AuthenticatorCRAMMD5.Authenticate",
		auth.AuthenticateRequest{Proof: proof}, new(auth.AuthenticateReply)); err != nil {
		return
	}
	return
}

func dialHTTP(network, address, codecName string, cFactory ClientCodecFactory, auth bool, connectTimeout time.Duration, config *tls.Config) (*rpc.Client, error) {
	var err error
	var conn net.Conn
	if connectTimeout != 0 {
		conn, err = net.DialTimeout(network, address, connectTimeout)
	} else {
		conn, err = net.Dial(network, address)
	}
	if err != nil {
		return nil, err
	}

	if config != nil {
		conn = tls.Client(conn, config)
	}

	_, err = io.WriteString(conn, "CONNECT "+GetRpcPath(codecName, auth)+" HTTP/1.0\n\n")
	if err != nil {
		return nil, err
	}

	// Require successful HTTP response
	// before switching to RPC protocol.
	buffered := NewBufferedConnection(conn)
	resp, err := http.ReadResponse(buffered.Reader, &http.Request{Method: "CONNECT"})
	if err == nil && resp.Status == connected {
		return rpc.NewClientWithCodec(cFactory(buffered)), nil
	}
	if err == nil {
		err = errors.New("unexpected HTTP response: " + resp.Status)
	}
	conn.Close()
	return nil, &net.OpError{Op: "dial-http", Net: network + " " + address, Addr: nil, Err: err}
}

type ServerCodecFactory func(conn io.ReadWriteCloser) rpc.ServerCodec

// ServeRPC handles rpc requests using the hijack scheme of rpc
func ServeRPC(codecName string, cFactory ServerCodecFactory) {
	http.Handle(GetRpcPath(codecName, false), &rpcHandler{cFactory, rpc.DefaultServer, false})
}

// ServeAuthRPC handles authenticated rpc requests using the hijack
// scheme of rpc
func ServeAuthRPC(codecName string, cFactory ServerCodecFactory) {
	http.Handle(GetRpcPath(codecName, true), &rpcHandler{cFactory, AuthenticatedServer, true})
}

// ServeCustomRPC serves the given rpc requests with the provided ServeMux,
// authenticated or not
func ServeCustomRPC(handler *http.ServeMux, server *rpc.Server, useAuth bool, codecName string, cFactory ServerCodecFactory) {
	handler.Handle(GetRpcPath(codecName, useAuth), &rpcHandler{cFactory, server, useAuth})
}

// AuthenticatedServer is an rpc.Server instance that serves
// authenticated calls.
var AuthenticatedServer = rpc.NewServer()

// rpcHandler handles rpc queries for a 'CONNECT' method.
type rpcHandler struct {
	cFactory ServerCodecFactory
	server   *rpc.Server
	useAuth  bool
}

// ServeHTTP implements http.Handler's ServeHTTP
func (h *rpcHandler) ServeHTTP(c http.ResponseWriter, req *http.Request) {
	if req.Method != "CONNECT" {
		c.Header().Set("Content-Type", "text/plain; charset=utf-8")
		c.WriteHeader(http.StatusMethodNotAllowed)
		io.WriteString(c, "405 must CONNECT\n")
		return
	}
	conn, _, err := c.(http.Hijacker).Hijack()
	if err != nil {
		log.Errorf("rpc hijacking %s: %v", req.RemoteAddr, err)
		return
	}
	io.WriteString(conn, "HTTP/1.0 "+connected+"\n\n")
	codec := h.cFactory(NewBufferedConnection(conn))
	ctx := proto.NewContext(req.RemoteAddr)
	if h.useAuth {
		if authenticated, err := auth.Authenticate(ctx, codec); !authenticated {
			if err != nil {
				log.Errorf("authentication erred at %s: %v", req.RemoteAddr, err)
			}
			codec.Close()
			return
		}
	}
	h.server.ServeCodecWithContext(ctx, codec)
}

// GetRpcPath returns the toplevel path used for serving RPCs over HTTP
func GetRpcPath(codecName string, auth bool) string {
	path := "/_" + codecName + "_rpc_"
	if auth {
		path += "/auth"
	}
	return path
}
<commit_msg>HTTP RPC: modify server to handle http requests<commit_after>// Copyright 2012, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package rpcwrap

import (
	"bufio"
	"crypto/tls"
	"errors"
	"io"
	"net"
	"net/http"
	"sync"
	"time"

	"golang.org/x/net/context"

	log "github.com/golang/glog"
	rpc "github.com/youtube/vitess/go/rpcplus"
	"github.com/youtube/vitess/go/rpcwrap/auth"
	"github.com/youtube/vitess/go/rpcwrap/proto"
	"github.com/youtube/vitess/go/stats"
)

const (
	connected = "200 Connected to Go RPC"
)

var (
	connCount    = stats.NewInt("connection-count")
	connAccepted = stats.NewInt("connection-accepted")
)

type ClientCodecFactory func(conn io.ReadWriteCloser) rpc.ClientCodec

type BufferedConnection struct {
	isClosed bool
	*bufio.Reader
	io.WriteCloser
}

func NewBufferedConnection(conn io.ReadWriteCloser) *BufferedConnection {
	connCount.Add(1)
	connAccepted.Add(1)
	return &BufferedConnection{false, bufio.NewReader(conn), conn}
}

// FIXME(sougou/szopa): Find a better way to track connection count.
func (bc *BufferedConnection) Close() error {
	if !bc.isClosed {
		bc.isClosed = true
		connCount.Add(-1)
	}
	return bc.WriteCloser.Close()
}

// DialHTTP connects to a go HTTP RPC server using the specified codec.
// use 0 as connectTimeout for no timeout
// use nil as config to not use TLS
func DialHTTP(network, address, codecName string, cFactory ClientCodecFactory, connectTimeout time.Duration, config *tls.Config) (*rpc.Client, error) {
	return dialHTTP(network, address, codecName, cFactory, false, connectTimeout, config)
}

// DialAuthHTTP connects to an authenticated go HTTP RPC server using
// the specified codec and credentials.
// use 0 as connectTimeout for no timeout
// use nil as config to not use TLS
func DialAuthHTTP(network, address, user, password, codecName string, cFactory ClientCodecFactory, connectTimeout time.Duration, config *tls.Config) (conn *rpc.Client, err error) {
	if conn, err = dialHTTP(network, address, codecName, cFactory, true, connectTimeout, config); err != nil {
		return
	}
	reply := new(auth.GetNewChallengeReply)
	if err = conn.Call(context.TODO(), "AuthenticatorCRAMMD5.GetNewChallenge", "", reply); err != nil {
		return
	}
	proof := auth.CRAMMD5GetExpected(user, password, reply.Challenge)

	if err = conn.Call(
		context.TODO(),
		"AuthenticatorCRAMMD5.Authenticate",
		auth.AuthenticateRequest{Proof: proof}, new(auth.AuthenticateReply)); err != nil {
		return
	}
	return
}

func dialHTTP(network, address, codecName string, cFactory ClientCodecFactory, auth bool, connectTimeout time.Duration, config *tls.Config) (*rpc.Client, error) {
	var err error
	var conn net.Conn
	if connectTimeout != 0 {
		conn, err = net.DialTimeout(network, address, connectTimeout)
	} else {
		conn, err = net.Dial(network, address)
	}
	if err != nil {
		return nil, err
	}

	if config != nil {
		conn = tls.Client(conn, config)
	}

	_, err = io.WriteString(conn, "CONNECT "+GetRpcPath(codecName, auth)+" HTTP/1.0\n\n")
	if err != nil {
		return nil, err
	}

	// Require successful HTTP response
	// before switching to RPC protocol.
	buffered := NewBufferedConnection(conn)
	resp, err := http.ReadResponse(buffered.Reader, &http.Request{Method: "CONNECT"})
	if err == nil && resp.Status == connected {
		return rpc.NewClientWithCodec(cFactory(buffered)), nil
	}
	if err == nil {
		err = errors.New("unexpected HTTP response: " + resp.Status)
	}
	conn.Close()
	return nil, &net.OpError{Op: "dial-http", Net: network + " " + address, Addr: nil, Err: err}
}

type ServerCodecFactory func(conn io.ReadWriteCloser) rpc.ServerCodec

// ServeRPC handles rpc requests using the hijack scheme of rpc
func ServeRPC(codecName string, cFactory ServerCodecFactory) {
	http.Handle(GetRpcPath(codecName, false), &rpcHandler{cFactory, rpc.DefaultServer, false})
}

// ServeAuthRPC handles authenticated rpc requests using the hijack
// scheme of rpc
func ServeAuthRPC(codecName string, cFactory ServerCodecFactory) {
	http.Handle(GetRpcPath(codecName, true), &rpcHandler{cFactory, AuthenticatedServer, true})
}

// ServeCustomRPC serves the given rpc requests with the provided ServeMux,
// authenticated or not
func ServeCustomRPC(handler *http.ServeMux, server *rpc.Server, useAuth bool, codecName string, cFactory ServerCodecFactory) {
	handler.Handle(GetRpcPath(codecName, useAuth), &rpcHandler{cFactory, server, useAuth})
}

// AuthenticatedServer is an rpc.Server instance that serves
// authenticated calls.
var AuthenticatedServer = rpc.NewServer()

// rpcHandler handles rpc queries for a 'CONNECT' method.
type rpcHandler struct {
	cFactory ServerCodecFactory
	server   *rpc.Server
	useAuth  bool
}

// ServeHTTP implements http.Handler's ServeHTTP
func (h *rpcHandler) ServeHTTP(c http.ResponseWriter, req *http.Request) {
	if req.Method != "CONNECT" {
		c.Header().Set("Content-Type", "text/plain; charset=utf-8")
		c.WriteHeader(http.StatusMethodNotAllowed)
		io.WriteString(c, "405 must CONNECT\n")
		return
	}
	conn, _, err := c.(http.Hijacker).Hijack()
	if err != nil {
		log.Errorf("rpc hijacking %s: %v", req.RemoteAddr, err)
		return
	}
	io.WriteString(conn, "HTTP/1.0 "+connected+"\n\n")
	codec := h.cFactory(NewBufferedConnection(conn))
	ctx := proto.NewContext(req.RemoteAddr)
	if h.useAuth {
		if authenticated, err := auth.Authenticate(ctx, codec); !authenticated {
			if err != nil {
				log.Errorf("authentication erred at %s: %v", req.RemoteAddr, err)
			}
			codec.Close()
			return
		}
	}
	h.server.ServeCodecWithContext(ctx, codec)
}

// GetRpcPath returns the toplevel path used for serving RPCs over HTTP
func GetRpcPath(codecName string, auth bool) string {
	path := "/_" + codecName + "_rpc_"
	if auth {
		path += "/auth"
	}
	return path
}

// httpRpcHandler handles rpc queries for a all types of HTTP requests.
type httpRpcHandler struct {
	cFactory ServerCodecFactory
	server   *rpc.Server
}

// ServeHTTP implements http.Handler's ServeHTTP
func (h *httpRpcHandler) ServeHTTP(c http.ResponseWriter, req *http.Request) {
	codec := h.cFactory(NewBufferedConnection(
		&httpReadWriteCloser{rw: c, req: req},
	))

	ctx := proto.NewContext(req.RemoteAddr)

	h.server.ServeCodecWithContextOnce(
		new(sync.Mutex),
		false,
		ctx,
		codec,
	)

	codec.Close()
}

func ServeHTTPRPC(handler *http.ServeMux, server *rpc.Server, codecName string, cFactory ServerCodecFactory) {
	handler.Handle(GetRpcPath(codecName, false), &httpRpcHandler{cFactory, server})
}

type httpReadWriteCloser struct {
	rw  http.ResponseWriter
	req *http.Request
}

func (i *httpReadWriteCloser) Read(p []byte) (n int, err error) {
	return i.req.Body.Read(p)
}

func (i *httpReadWriteCloser) Write(p []byte) (n int, err error) {
	return i.rw.Write(p)
}

func (i *httpReadWriteCloser) Close() error {
	return i.req.Body.Close()
}
<|endoftext|>


<commit_before>package oval

import (
	"encoding/xml"
	"fmt"
	"os"
)

type ParserError struct {
	s string
}

func (pe *ParserError) Error() string {
	return pe.s
}

type config struct {
	flagDebug          bool
	maxChecks          int
	centosRedhatKludge int
}

type dataMgr struct {
	dpkg dpkgDataMgr
	rpm  rpmDataMgr
}

func (d *dataMgr) dataMgrInit() {
	d.dpkg.init()
	d.rpm.init()
}

func (d *dataMgr) dataMgrRun(precognition bool) {
	if precognition {
		d.dpkg.prepare()
		d.rpm.prepare()
	}
	go d.dpkg.run()
	go d.rpm.run()
}

func (d *dataMgr) dataMgrClose() {
	close(d.dpkg.schan)
	close(d.rpm.schan)
}

var parserCfg config
var dmgr dataMgr

func defaultParserConfig() config {
	return config{
		flagDebug:          false,
		maxChecks:          10,
		centosRedhatKludge: 0,
	}
}

func SetDebug(f bool) {
	parserCfg.flagDebug = f
}

func SetMaxChecks(i int) {
	parserCfg.maxChecks = i
}

func debugPrint(s string, args ...interface{}) {
	if !parserCfg.flagDebug {
		return
	}
	fmt.Fprintf(os.Stdout, s, args...)
}

func Execute(od *GOvalDefinitions) []GOvalResult {
	var precognition bool = false
	debugPrint("executing all applicable checks\n")

	if parserCfg.flagDebug {
		precognition = true
	}

	dmgr.dataMgrInit()
	dmgr.dataMgrRun(precognition)

	results := make([]GOvalResult, 0)
	reschan := make(chan GOvalResult)
	curchecks := 0
	expect := len(od.Definitions.Definitions)
	for _, v := range od.Definitions.Definitions {
		debugPrint("executing definition %s...\n", v.ID)

		for {
			nodata := false
			select {
			case s := <-reschan:
				results = append(results, s)
				curchecks--
				expect--
			default:
				nodata = true
				break
			}
			if nodata {
				break
			}
		}

		if curchecks == parserCfg.maxChecks {
			// Block and wait for a free slot.
			s := <-reschan
			results = append(results, s)
			curchecks--
			expect--
		}
		go v.evaluate(reschan, od)
		curchecks++
	}

	for expect > 0 {
		s := <-reschan
		results = append(results, s)
		expect--
	}

	dmgr.dataMgrClose()

	return results
}

func Init() {
	parserCfg = defaultParserConfig()
}

func Parse(path string) (*GOvalDefinitions, error) {
	var od GOvalDefinitions
	var perr ParserError

	parserCfg.centosRedhatKludge = centosDetection()

	debugPrint("parsing %s\n", path)

	xfd, err := os.Open(path)
	if err != nil {
		perr.s = fmt.Sprintf("error opening file: %v", err)
		return nil, &perr
	}

	decoder := xml.NewDecoder(xfd)
	ok := decoder.Decode(&od)
	if ok != nil {
		perr.s = fmt.Sprintf("error parsing %v: invalid xml format?", path)
		return nil, &perr
	}
	xfd.Close()

	return &od, nil
}
<commit_msg>use pkg datamgr precognition by default for now<commit_after>package oval

import (
	"encoding/xml"
	"fmt"
	"os"
)

type ParserError struct {
	s string
}

func (pe *ParserError) Error() string {
	return pe.s
}

type config struct {
	flagDebug          bool
	maxChecks          int
	centosRedhatKludge int
}

type dataMgr struct {
	dpkg dpkgDataMgr
	rpm  rpmDataMgr
}

func (d *dataMgr) dataMgrInit() {
	d.dpkg.init()
	d.rpm.init()
}

func (d *dataMgr) dataMgrRun(precognition bool) {
	if precognition {
		d.dpkg.prepare()
		d.rpm.prepare()
	}
	go d.dpkg.run()
	go d.rpm.run()
}

func (d *dataMgr) dataMgrClose() {
	close(d.dpkg.schan)
	close(d.rpm.schan)
}

var parserCfg config
var dmgr dataMgr

func defaultParserConfig() config {
	return config{
		flagDebug:          false,
		maxChecks:          10,
		centosRedhatKludge: 0,
	}
}

func SetDebug(f bool) {
	parserCfg.flagDebug = f
}

func SetMaxChecks(i int) {
	parserCfg.maxChecks = i
}

func debugPrint(s string, args ...interface{}) {
	if !parserCfg.flagDebug {
		return
	}
	fmt.Fprintf(os.Stdout, s, args...)
}

func Execute(od *GOvalDefinitions) []GOvalResult {
	var precognition bool = false
	debugPrint("executing all applicable checks\n")

	precognition = true

	dmgr.dataMgrInit()
	dmgr.dataMgrRun(precognition)

	results := make([]GOvalResult, 0)
	reschan := make(chan GOvalResult)
	curchecks := 0
	expect := len(od.Definitions.Definitions)
	for _, v := range od.Definitions.Definitions {
		debugPrint("executing definition %s...\n", v.ID)

		for {
			nodata := false
			select {
			case s := <-reschan:
				results = append(results, s)
				curchecks--
				expect--
			default:
				nodata = true
				break
			}
			if nodata {
				break
			}
		}

		if curchecks == parserCfg.maxChecks {
			// Block and wait for a free slot.
			s := <-reschan
			results = append(results, s)
			curchecks--
			expect--
		}
		go v.evaluate(reschan, od)
		curchecks++
	}

	for expect > 0 {
		s := <-reschan
		results = append(results, s)
		expect--
	}

	dmgr.dataMgrClose()

	return results
}

func Init() {
	parserCfg = defaultParserConfig()
}

func Parse(path string) (*GOvalDefinitions, error) {
	var od GOvalDefinitions
	var perr ParserError

	parserCfg.centosRedhatKludge = centosDetection()

	debugPrint("parsing %s\n", path)

	xfd, err := os.Open(path)
	if err != nil {
		perr.s = fmt.Sprintf("error opening file: %v", err)
		return nil, &perr
	}

	decoder := xml.NewDecoder(xfd)
	ok := decoder.Decode(&od)
	if ok != nil {
		perr.s = fmt.Sprintf("error parsing %v: invalid xml format?", path)
		return nil, &perr
	}
	xfd.Close()

	return &od, nil
}
<|endoftext|>


<commit_before>package gocbcore

import (
	"sync"
	"sync/atomic"
	"unsafe"
)

// The data for a request that can be queued with a memdqueueconn,
//   and can potentially be rerouted to multiple servers due to
//   configuration changes.
type memdQRequest struct {
	memdRequest

	// Static routing properties
	ReplicaIdx int
	Callback   Callback
	Persistent bool

	// This stores a pointer to the server that currently own
	//   this request.  When a request is resolved or cancelled,
	//   this is nulled out.  This property allows the request to
	//   lookup who owns it during cancelling as well as prevents
	//   callback after cancel, or cancel after callback.
	queuedWith unsafe.Pointer

	// Holds the next item in the opList, this is used by the
	//   memdOpQueue to avoid extra GC for a discreet list
	//   element structure.
	queueNext *memdQRequest
}

func (req *memdQRequest) QueueOwner() *memdQueue {
	return (*memdQueue)(atomic.LoadPointer(&req.queuedWith))
}

type drainedReqCallback func(*memdQRequest)

type memdQueue struct {
	lock      sync.RWMutex
	isDrained bool
	reqsCh    chan *memdQRequest
}

func createMemdQueue() *memdQueue {
	return &memdQueue{
		reqsCh: make(chan *memdQRequest, 5000),
	}
}

func (s *memdQueue) QueueRequest(req *memdQRequest) bool {
	s.lock.RLock()
	if s.isDrained {
		s.lock.RUnlock()
		return false
	}

	oldSP := atomic.SwapPointer(&req.queuedWith, unsafe.Pointer(s))
	if oldSP != nil {
		panic("Request was dispatched while already queued somewhere.")
	}

	logDebugf("Writing request to queue!")

	// Try to write the request to the queue, if the queue is full,
	//   we immediately fail the request with a queueOverflow error.
	select {
	case s.reqsCh <- req:
		s.lock.RUnlock()
		return true

	default:
		s.lock.RUnlock()
		// As long as we have not lost ownership, dispatch a queue overflow error.
		if atomic.CompareAndSwapPointer(&req.queuedWith, unsafe.Pointer(s), nil) {
			req.Callback(nil, overloadError{})
		}
		return true
	}
}

func (req *memdQRequest) Cancel() bool {
	queue := (*memdQueue)(atomic.SwapPointer(&req.queuedWith, nil))
	if queue == nil {
		return false
	}
	return true
}

func (queue *memdQueue) UnqueueRequest(req *memdQRequest) bool {
	return atomic.CompareAndSwapPointer(&req.queuedWith, unsafe.Pointer(queue), nil)
}

func (queue *memdQueue) drainTillEmpty(reqCb drainedReqCallback) {
	for {
		select {
		case req := <-queue.reqsCh:
			if queue.UnqueueRequest(req) {
				reqCb(req)
			}
		default:
			return
		}
	}
}

func (queue *memdQueue) drainTillSignal(reqCb drainedReqCallback, signal chan bool) {
	for {
		select {
		case req := <-queue.reqsCh:
			if queue.UnqueueRequest(req) {
				reqCb(req)
			}
		case <-signal:
			queue.drainTillEmpty(reqCb)
			return
		}
	}
}

// Drains all the requests out of the queue.  This will mark the queue as drained
//   (further attempts to send it requests will fail), and call the specified
//   callback for each request that was still queued.
func (queue *memdQueue) Drain(reqCb drainedReqCallback, readersDoneSig chan bool) {
	// Start up our drainer goroutine.  This will ensure that queue is constantly
	//   being drained while we perform the shutdown of the queue, without this,
	//   we may deadlock between trying to write to a full queue, and trying to
	//   get the lock to mark it as draining.
	signal := make(chan bool)
	go queue.drainTillSignal(reqCb, signal)

	// First we mark this queue as draining, this will prevent further requests
	//   from being dispatched from any external sources.
	queue.lock.Lock()
	queue.isDrained = true
	queue.lock.Unlock()

	// If there is anyone actively processing data off this queue, we need to wait
	//   till they've stopped before we can clear this queue, this is because of
	//   the fact that its possible that the processor might need to put a request
	//   back in the queue if it fails to handle it and we need to make sure the
	//   queue is emptying so there is room for the processor to put it in.
	if readersDoneSig != nil {
		<-readersDoneSig
	}

	// Signal our drain coroutine that it can stop now (once its emptied the queue).
	signal <- true
}
<commit_msg>Don't corrupt other queues if we don't have to.<commit_after>package gocbcore

import (
	"sync"
	"sync/atomic"
	"unsafe"
)

// The data for a request that can be queued with a memdqueueconn,
//   and can potentially be rerouted to multiple servers due to
//   configuration changes.
type memdQRequest struct {
	memdRequest

	// Static routing properties
	ReplicaIdx int
	Callback   Callback
	Persistent bool

	// This stores a pointer to the server that currently own
	//   this request.  When a request is resolved or cancelled,
	//   this is nulled out.  This property allows the request to
	//   lookup who owns it during cancelling as well as prevents
	//   callback after cancel, or cancel after callback.
	queuedWith unsafe.Pointer

	// Holds the next item in the opList, this is used by the
	//   memdOpQueue to avoid extra GC for a discreet list
	//   element structure.
	queueNext *memdQRequest
}

func (req *memdQRequest) QueueOwner() *memdQueue {
	return (*memdQueue)(atomic.LoadPointer(&req.queuedWith))
}

type drainedReqCallback func(*memdQRequest)

type memdQueue struct {
	lock      sync.RWMutex
	isDrained bool
	reqsCh    chan *memdQRequest
}

func createMemdQueue() *memdQueue {
	return &memdQueue{
		reqsCh: make(chan *memdQRequest, 5000),
	}
}

func (s *memdQueue) QueueRequest(req *memdQRequest) bool {
	s.lock.RLock()
	if s.isDrained {
		s.lock.RUnlock()
		return false
	}

	if !atomic.CompareAndSwapPointer(&req.queuedWith, nil, unsafe.Pointer(s)) {
		panic("Request was dispatched while already queued somewhere.")
	}

	logDebugf("Writing request to queue!")

	// Try to write the request to the queue, if the queue is full,
	//   we immediately fail the request with a queueOverflow error.
	select {
	case s.reqsCh <- req:
		s.lock.RUnlock()
		return true

	default:
		s.lock.RUnlock()
		// As long as we have not lost ownership, dispatch a queue overflow error.
		if atomic.CompareAndSwapPointer(&req.queuedWith, unsafe.Pointer(s), nil) {
			req.Callback(nil, overloadError{})
		}
		return true
	}
}

func (req *memdQRequest) Cancel() bool {
	queue := (*memdQueue)(atomic.SwapPointer(&req.queuedWith, nil))
	if queue == nil {
		return false
	}
	return true
}

func (queue *memdQueue) UnqueueRequest(req *memdQRequest) bool {
	return atomic.CompareAndSwapPointer(&req.queuedWith, unsafe.Pointer(queue), nil)
}

func (queue *memdQueue) drainTillEmpty(reqCb drainedReqCallback) {
	for {
		select {
		case req := <-queue.reqsCh:
			if queue.UnqueueRequest(req) {
				reqCb(req)
			}
		default:
			return
		}
	}
}

func (queue *memdQueue) drainTillSignal(reqCb drainedReqCallback, signal chan bool) {
	for {
		select {
		case req := <-queue.reqsCh:
			if queue.UnqueueRequest(req) {
				reqCb(req)
			}
		case <-signal:
			queue.drainTillEmpty(reqCb)
			return
		}
	}
}

// Drains all the requests out of the queue.  This will mark the queue as drained
//   (further attempts to send it requests will fail), and call the specified
//   callback for each request that was still queued.
func (queue *memdQueue) Drain(reqCb drainedReqCallback, readersDoneSig chan bool) {
	// Start up our drainer goroutine.  This will ensure that queue is constantly
	//   being drained while we perform the shutdown of the queue, without this,
	//   we may deadlock between trying to write to a full queue, and trying to
	//   get the lock to mark it as draining.
	signal := make(chan bool)
	go queue.drainTillSignal(reqCb, signal)

	// First we mark this queue as draining, this will prevent further requests
	//   from being dispatched from any external sources.
	queue.lock.Lock()
	queue.isDrained = true
	queue.lock.Unlock()

	// If there is anyone actively processing data off this queue, we need to wait
	//   till they've stopped before we can clear this queue, this is because of
	//   the fact that its possible that the processor might need to put a request
	//   back in the queue if it fails to handle it and we need to make sure the
	//   queue is emptying so there is room for the processor to put it in.
	if readersDoneSig != nil {
		<-readersDoneSig
	}

	// Signal our drain coroutine that it can stop now (once its emptied the queue).
	signal <- true
}
<|endoftext|>


<commit_before>package ogone

import (
	"bytes"
	"net/http"
	"net/url"
)

type AliasGateway struct {
}

func NewAliasGateway() *AliasGateway {
	return &AliasGateway{}
}

func (g *AliasGateway) SandboxSend(r *AliasRequest) (*AliasResponse, error) {
	return g.sendRequest(r, "https://secure.ogone.com/ncol/test/alias_gateway_utf8.asp")
}

func (g *AliasGateway) Send(r *AliasRequest) (*AliasResponse, error) {
	return g.sendRequest(r, "https://secure.ogone.com/ncol/prod/alias_gateway_utf8.asp")
}

func (g *AliasGateway) sendRequest(r *AliasRequest, gatewayUrl string) (*AliasResponse, error) {

	values := url.Values{}

	for k, v := range r.Data() {
		values.Add(k, v)
	}

	req, err := http.NewRequest("GET", gatewayUrl+"?"+values.Encode(), bytes.NewBufferString(""))

	if err != nil {
		return nil, err
	}

	res, err := http.DefaultTransport.RoundTrip(req)

	if err != nil {
		return nil, err
	}

	redirectUrl, err := res.Location()

	if err != nil {
		return nil, err
	}

	return NewAliasResponse(redirectUrl), nil
}
<commit_msg>test fail<commit_after>package ogone

import (

	"bytes"
	"net/http"
	"net/url"
)

type AliasGateway struct {
}

func NewAliasGateway() *AliasGateway {
	return &AliasGateway{}
}

func (g *AliasGateway) SandboxSend(r *AliasRequest) (*AliasResponse, error) {
	return g.sendRequest(r, "https://secure.ogone.com/ncol/test/alias_gateway_utf8.asp")
}

func (g *AliasGateway) Send(r *AliasRequest) (*AliasResponse, error) {
	return g.sendRequest(r, "https://secure.ogone.com/ncol/prod/alias_gateway_utf8.asp")
}

func (g *AliasGateway) sendRequest(r *AliasRequest, gatewayUrl string) (*AliasResponse, error) {

	values := url.Values{}

	for k, v := range r.Data() {
		values.Add(k, v)
	}

	req, err := http.NewRequest("GET", gatewayUrl+"?"+values.Encode(), bytes.NewBufferString(""))

	if err != nil {
		return nil, err
	}

	res, err := http.DefaultTransport.RoundTrip(req)

	if err != nil {
		return nil, err
	}

	redirectUrl, err := res.Location()

	if err != nil {
		return nil, err
	}

	return NewAliasResponse(redirectUrl), nil
}
<|endoftext|>