<commit_before>// Copyright 2015 Google Inc. All rights reserved.
//
// 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 main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
)

var (
	chdir = flag.String("p", "", "Change to a path before executing test")
	touch = flag.String("f", "", "Write a file on success")
)

// This will copy the stdout from the test process to our stdout
// unless it only contains "PASS\n".
func handleStdout(stdout io.Reader) {
	reader := bufio.NewReader(stdout)

	// This is intentionally 6 instead of 5 to check for EOF
	buf, _ := reader.Peek(6)
	if bytes.Equal(buf, []byte("PASS\n")) {
		return
	}

	io.Copy(os.Stdout, reader)
}

func main() {
	flag.Parse()

	if flag.NArg() == 0 {
		fmt.Fprintln(os.Stderr, "error: must pass at least one test executable")
		os.Exit(1)
	}

	test, err := filepath.Abs(flag.Arg(0))
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: Failed to locate test binary: %s", err)
	}

	cmd := exec.Command(test, flag.Args()[1:]...)
	if *chdir != "" {
		cmd.Dir = *chdir
	}

	cmd.Stderr = os.Stderr
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

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

	handleStdout(stdout)

	if err = cmd.Wait(); err != nil {
		if e, ok := err.(*exec.ExitError); ok {
			if status, ok := e.Sys().(syscall.WaitStatus); ok && status.Exited() {
				os.Exit(status.ExitStatus())
			} else if status.Signaled() {
				fmt.Fprintf(os.Stderr, "test got signal %s\n", status.Signal())
				os.Exit(1)
			}
		}
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	if *touch != "" {
		err = ioutil.WriteFile(*touch, []byte{}, 0666)
		if err != nil {
			panic(err)
		}
	}

	os.Exit(0)
}
<commit_msg>gotestrunner: Make GOROOT absolute before chdir<commit_after>// Copyright 2015 Google Inc. All rights reserved.
//
// 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 main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"syscall"
)

var (
	chdir = flag.String("p", "", "Change to a path before executing test")
	touch = flag.String("f", "", "Write a file on success")
)

// This will copy the stdout from the test process to our stdout
// unless it only contains "PASS\n".
func handleStdout(stdout io.Reader) {
	reader := bufio.NewReader(stdout)

	// This is intentionally 6 instead of 5 to check for EOF
	buf, _ := reader.Peek(6)
	if bytes.Equal(buf, []byte("PASS\n")) {
		return
	}

	io.Copy(os.Stdout, reader)
}

func main() {
	flag.Parse()

	if flag.NArg() == 0 {
		fmt.Fprintln(os.Stderr, "error: must pass at least one test executable")
		os.Exit(1)
	}

	test, err := filepath.Abs(flag.Arg(0))
	if err != nil {
		fmt.Fprintln(os.Stderr, "error: Failed to locate test binary:", err)
	}

	cmd := exec.Command(test, flag.Args()[1:]...)
	if *chdir != "" {
		cmd.Dir = *chdir

		// GOROOT is commonly a relative path in Android, make it
		// absolute if we're changing directories.
		if absRoot, err := filepath.Abs(runtime.GOROOT()); err == nil {
			os.Setenv("GOROOT", absRoot)
		} else {
			fmt.Fprintln(os.Stderr, "error: Failed to locate GOROOT:", err)
		}
	}

	cmd.Stderr = os.Stderr
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

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

	handleStdout(stdout)

	if err = cmd.Wait(); err != nil {
		if e, ok := err.(*exec.ExitError); ok {
			if status, ok := e.Sys().(syscall.WaitStatus); ok && status.Exited() {
				os.Exit(status.ExitStatus())
			} else if status.Signaled() {
				fmt.Fprintf(os.Stderr, "test got signal %s\n", status.Signal())
				os.Exit(1)
			}
		}
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	if *touch != "" {
		err = ioutil.WriteFile(*touch, []byte{}, 0666)
		if err != nil {
			panic(err)
		}
	}

	os.Exit(0)
}
<|endoftext|>


<commit_before>package nrsc

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"testing"
	"time"
)

const (
	root = "/tmp/nrsc-test"
	port = 9888
)

func TestText(t *testing.T) {
	expected := map[string]string{
		"Content-Size": "12",
		"Content-Type": "text/plain",
	}
	checkPath(t, "ht.txt", expected)
}

func TestSub(t *testing.T) {
	expected := map[string]string{
		"Content-Size": "1150",
		"Content-Type": "image/",
	}
	checkPath(t, "sub/favicon.ico", expected)
}

// / serves a template
func TestTempalte(t *testing.T) {
	server := startServer(t)
	if server == nil {
		t.Fatalf("can't start server")
	}
	defer server.Process.Kill()

	url := fmt.Sprintf("http://localhost:%d", port)
	resp, err := http.Get(url)
	if err != nil {
		t.Fatalf("can't GET / - %s", err)
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatalf("can't read body - %s", err)
	}

	if string(data) != "The number is 7\n" {
		t.Fatalf("bad template reply - %s", string(data))
	}
}

func createMain() error {
	filename := fmt.Sprintf("%s/main.go", root)
	file, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	fmt.Fprintf(file, code, port)
	return nil
}

func initDir() error {
	// Ignore error value, since it might not be there
	os.RemoveAll(root)

	err := os.Mkdir(root, 0777)
	if err != nil {
		return err
	}

	return createMain()
}

func get(path string) (*http.Response, error) {
	url := fmt.Sprintf("http://localhost:%d/static/%s", port, path)
	return http.Get(url)
}

func startServer(t *testing.T) *exec.Cmd {
	cmd := exec.Command(fmt.Sprintf("%s/nrsc-test", root))
	// Ignore errors, test will fail anyway if server not running
	cmd.Start()

	// Wait for server
	url := fmt.Sprintf("http://localhost:%d", port)
	start := time.Now()
	for time.Since(start) < time.Duration(2*time.Second) {
		_, err := http.Get(url)
		if err == nil {
			return cmd
		}
		time.Sleep(time.Second / 10)
	}

	if cmd.Process != nil {
		cmd.Process.Kill()
	}
	t.Fatalf("can't connect to server")
	return nil
}

func fixGOPATH(cwd string) {
	path := os.Getenv("GOPATH")
	if len(path) == 0 {
		os.Setenv("GOPATH", fmt.Sprintf("%s/../..", cwd))
	}
}

func init() {
	if err := initDir(); err != nil {
		panic(err)
	}

	cwd, _ := os.Getwd()
	path := func(name string) string {
		return fmt.Sprintf("%s/%s", cwd, name)
	}
	fixGOPATH(cwd)

	os.Chdir(root)
	defer os.Chdir(cwd)

	cmd := exec.Command("go", "install")
	if err := cmd.Run(); err != nil {
		fmt.Printf("error building: %s\n", err)
		panic(err)
	}

	cmd = exec.Command(path("pack.sh"), "nrsc-test", path("test-resources"))
	if err := cmd.Run(); err != nil {
		fmt.Printf("error packing: %s\n", err)
		panic(err)
	}
}

func checkHeaders(t *testing.T, expected map[string]string, headers http.Header) {
	for key := range expected {
		v1 := expected[key]
		v2 := headers.Get(key)
		if !strings.HasPrefix(v2, v1) {
			t.Fatalf("bad header %s: %s <-> %s", key, v1, v2)
		}
	}

	key := "Last-Modified"
	value := headers.Get(key)
	if value == "" {
		t.Fatalf("no %s header", key)
	}
}

func checkPath(t *testing.T, path string, expected map[string]string) {
	server := startServer(t)
	if server == nil {
		return
	}
	defer server.Process.Kill()

	resp, err := get(path)
	if err != nil {
		t.Fatalf("%s\n", err)
	}

	if resp.StatusCode != http.StatusOK {
		t.Fatalf("bad reply - %s", resp.Status)
	}

	checkHeaders(t, expected, resp.Header)
}

const code = `
package main

import (
	"fmt"
	"net/http"
	"os"

	"nrsc"
)

type params struct {
	Number  int
}

func indexHandler(w http.ResponseWriter, req *http.Request) {
	t, err := nrsc.LoadTemplates(nil, "t.html")
	if err != nil {
		http.NotFound(w, req)
	}
	if err = t.Execute(w, params{7}); err != nil {
		http.NotFound(w, req)
	}
}

func main() {
	nrsc.Handle("/static/")
	http.HandleFunc("/", indexHandler)
	if err := http.ListenAndServe(":%d", nil); err != nil {
		fmt.Fprintf(os.Stderr, "error: %%s\n", err)
		os.Exit(1)
	}
}
`
<commit_msg>Right exectable name<commit_after>package nrsc

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"testing"
	"time"
)

const (
	root = "/tmp/nrsc-test"
	port = 9888
)

func TestText(t *testing.T) {
	expected := map[string]string{
		"Content-Size": "12",
		"Content-Type": "text/plain",
	}
	checkPath(t, "ht.txt", expected)
}

func TestSub(t *testing.T) {
	expected := map[string]string{
		"Content-Size": "1150",
		"Content-Type": "image/",
	}
	checkPath(t, "sub/favicon.ico", expected)
}

// / serves a template
func TestTempalte(t *testing.T) {
	server := startServer(t)
	if server == nil {
		t.Fatalf("can't start server")
	}
	defer server.Process.Kill()

	url := fmt.Sprintf("http://localhost:%d", port)
	resp, err := http.Get(url)
	if err != nil {
		t.Fatalf("can't GET / - %s", err)
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatalf("can't read body - %s", err)
	}

	if string(data) != "The number is 7\n" {
		t.Fatalf("bad template reply - %s", string(data))
	}
}

func createMain() error {
	filename := fmt.Sprintf("%s/main.go", root)
	file, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	fmt.Fprintf(file, code, port)
	return nil
}

func initDir() error {
	// Ignore error value, since it might not be there
	os.RemoveAll(root)

	err := os.Mkdir(root, 0777)
	if err != nil {
		return err
	}

	return createMain()
}

func get(path string) (*http.Response, error) {
	url := fmt.Sprintf("http://localhost:%d/static/%s", port, path)
	return http.Get(url)
}

func startServer(t *testing.T) *exec.Cmd {
	cmd := exec.Command(fmt.Sprintf("%s/nrsc-test", root))
	// Ignore errors, test will fail anyway if server not running
	cmd.Start()

	// Wait for server
	url := fmt.Sprintf("http://localhost:%d", port)
	start := time.Now()
	for time.Since(start) < time.Duration(2*time.Second) {
		_, err := http.Get(url)
		if err == nil {
			return cmd
		}
		time.Sleep(time.Second / 10)
	}

	if cmd.Process != nil {
		cmd.Process.Kill()
	}
	t.Fatalf("can't connect to server")
	return nil
}

func fixGOPATH(cwd string) {
	path := os.Getenv("GOPATH")
	if len(path) == 0 {
		os.Setenv("GOPATH", fmt.Sprintf("%s/../..", cwd))
	}
}

func init() {
	if err := initDir(); err != nil {
		panic(err)
	}

	cwd, _ := os.Getwd()
	path := func(name string) string {
		return fmt.Sprintf("%s/%s", cwd, name)
	}
	fixGOPATH(cwd)

	os.Chdir(root)
	defer os.Chdir(cwd)

	cmd := exec.Command("go", "install")
	if err := cmd.Run(); err != nil {
		fmt.Printf("error building: %s\n", err)
		panic(err)
	}

	cmd = exec.Command(path("nrsc"), "nrsc-test", path("test-resources"))
	if err := cmd.Run(); err != nil {
		fmt.Printf("error packing: %s\n", err)
		panic(err)
	}
}

func checkHeaders(t *testing.T, expected map[string]string, headers http.Header) {
	for key := range expected {
		v1 := expected[key]
		v2 := headers.Get(key)
		if !strings.HasPrefix(v2, v1) {
			t.Fatalf("bad header %s: %s <-> %s", key, v1, v2)
		}
	}

	key := "Last-Modified"
	value := headers.Get(key)
	if value == "" {
		t.Fatalf("no %s header", key)
	}
}

func checkPath(t *testing.T, path string, expected map[string]string) {
	server := startServer(t)
	if server == nil {
		return
	}
	defer server.Process.Kill()

	resp, err := get(path)
	if err != nil {
		t.Fatalf("%s\n", err)
	}

	if resp.StatusCode != http.StatusOK {
		t.Fatalf("bad reply - %s", resp.Status)
	}

	checkHeaders(t, expected, resp.Header)
}

const code = `
package main

import (
	"fmt"
	"net/http"
	"os"

	"nrsc"
)

type params struct {
	Number  int
}

func indexHandler(w http.ResponseWriter, req *http.Request) {
	t, err := nrsc.LoadTemplates(nil, "t.html")
	if err != nil {
		http.NotFound(w, req)
	}
	if err = t.Execute(w, params{7}); err != nil {
		http.NotFound(w, req)
	}
}

func main() {
	nrsc.Handle("/static/")
	http.HandleFunc("/", indexHandler)
	if err := http.ListenAndServe(":%d", nil); err != nil {
		fmt.Fprintf(os.Stderr, "error: %%s\n", err)
		os.Exit(1)
	}
}
`
<|endoftext|>


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

// package ntpclient implements NTP request.
package ntpclient

import (
	// "encoding/binary"
	"net"
	"time"
)

type Request struct {
	Host    string
	Port    uint
	Version uint
	Timeout time.Duration
}

type ntpTime struct {
	Seconds  uint32
	Fraction uint32
}

type msg struct {
	LiVnMode       byte // Leap Indicator (2) + Version (3) + Mode (3)
	Stratum        byte
	Poll           byte
	Precision      byte
	RootDelay      uint32
	RootDispersion uint32
	ReferenceId    uint32
	ReferenceTime  ntpTime
	OriginTime     ntpTime
	ReceiveTime    ntpTime
	TransmitTime   ntpTime
}

func (t ntpTime) UTC() time.Time {
	nsec := uint64(t.Seconds)*1e9 + (uint64(t.Fraction) * 1e9 >> 32)
	return time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC).Add(time.Duration(nsec))
}

func send(r *Request) (time.Time, error) {
	// validate host/port
	// set version
	// set net deadline
	return time.Now(), error
}

func CustomClient(r Request) (time.Time, error) {
	return time.Now(), error
}

func Client(host string) (time.Time, error) {
	return time.Now(), error
}
<commit_msg>unix file style<commit_after>// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// package ntpclient implements NTP request.
package ntpclient

import (
	// "encoding/binary"
	"net"
	"time"
)

type Request struct {
	Host    string
	Port    uint
	Version uint
	Timeout time.Duration
}

type ntpTime struct {
	Seconds  uint32
	Fraction uint32
}

type msg struct {
	LiVnMode       byte // Leap Indicator (2) + Version (3) + Mode (3)
	Stratum        byte
	Poll           byte
	Precision      byte
	RootDelay      uint32
	RootDispersion uint32
	ReferenceId    uint32
	ReferenceTime  ntpTime
	OriginTime     ntpTime
	ReceiveTime    ntpTime
	TransmitTime   ntpTime
}

func (t ntpTime) UTC() time.Time {
	nsec := uint64(t.Seconds)*1e9 + (uint64(t.Fraction) * 1e9 >> 32)
	return time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC).Add(time.Duration(nsec))
}

func send(r *Request) (time.Time, error) {
	// validate host/port
	// set version
	// set net deadline
	return time.Now(), error
}

func CustomClient(r Request) (time.Time, error) {
	return time.Now(), error
}

func Client(host string) (time.Time, error) {
	return time.Now(), error
}
<|endoftext|>


<commit_before>package binutil

import (
	"encoding/binary"
	"io"
	"reflect"
)

var pad [8]byte

type Writer struct {
	W      io.Writer
	Offset uint32 //FIXME: int64?
	Err    error
}

func (w *Writer) WriteLE(v interface{}) {
	if w.Err != nil {
		return
	}
	w.Err = binary.Write(w.W, binary.LittleEndian, v)
	if w.Err != nil {
		return
	}
	w.Offset += uint32(reflect.TypeOf(v).Size())
}

func (w *Writer) WriteFromSized(r SizedReader) {
	if w.Err != nil {
		return
	}
	var n int64
	n, w.Err = io.CopyN(w.W, r, r.Size())
	if w.Err != nil {
		return
	}
	aligned := RoomTaken(r)
	if aligned > n {
		w.W.Write(pad[:aligned-n])
		n = aligned
	}
	w.Offset += uint32(n)
}
<commit_msg>Update binutil/writer.go<commit_after>package binutil

import (
	"encoding/binary"
	"io"
	"reflect"
)

var pad [8]byte

type Writer struct {
	W      io.Writer
	Offset uint32 //FIXME: int64?
	Err    error
}

func (w *Writer) WriteLE(v interface{}) {
	if w.Err != nil {
		return
	}
	w.Err = binary.Write(w.W, binary.LittleEndian, v)
	if w.Err != nil {
		return
	}
	w.Offset += uint32(reflect.TypeOf(v).Size())
}

func (w *Writer) WriteFromSized(r SizedReader) {
	if w.Err != nil {
		return
	}
	var n int64
	n, w.Err = io.CopyN(w.W, r, r.Size())
	if w.Err != nil {
		return
	}
	aligned := RoomTaken(r)
	_, w.Err = w.W.Write(pad[:aligned-n])
	if w.Err != nil {
		return
	}
	n = aligned
	w.Offset += uint32(n)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"go/parser"
	"go/token"

	linenoise "github.com/GeertJohan/go.linenoise"
	"github.com/glycerine/bigbird/chicken"
)

func main() {
	chicken.Start()

	for {
		line, err := linenoise.Line("> ")
		if err != nil {
			if err.Error() == "prompt was quited with a killsignal" {
				//fmt.Printf("ignoring: prompt was quited with a killsignal\n")
				continue
			}
			fmt.Printf("error: %v\n", err)
			continue
		}
		//fmt.Printf("line is %v\n", line)

		fset := token.NewFileSet()
		f, err := parser.ParseFile(fset, "", interface{}(line), parser.Trace)
		if err != nil {
			fmt.Printf("parse error: %v\n", err)
			continue
		}
		if f == nil {
			fmt.Printf("ast returned was nil\n")
		} else {
			fmt.Printf("f is %v\n", f)
		}
		schemeSrc := line

		s := chicken.Eval(schemeSrc)
		fmt.Printf("%v\n", s)
	}
}
<commit_msg>straight through to scheme, no parsing<commit_after>package main

import (
	"fmt"

	linenoise "github.com/GeertJohan/go.linenoise"
	"github.com/glycerine/bigbird/chicken"
)

func main() {
	chicken.Start()

	for {
		line, err := linenoise.Line("> ")
		if err != nil {
			if err.Error() == "prompt was quited with a killsignal" {
				//fmt.Printf("ignoring: prompt was quited with a killsignal\n")
				continue
			}
			fmt.Printf("error: %v\n", err)
			continue
		}
		//fmt.Printf("line is %v\n", line)

		/*
			fset := token.NewFileSet()
			f, err := parser.ParseFile(fset, "", interface{}(line), parser.Trace)
			if err != nil {
				fmt.Printf("parse error: %v\n", err)
				continue
			}
			if f == nil {
				fmt.Printf("ast returned was nil\n")
			} else {
				fmt.Printf("f is %v\n", f)
			}
		*/
		schemeSrc := line

		s := chicken.Eval(schemeSrc)
		fmt.Printf("%v\n", s)
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 blob

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"strings"

	"golang.org/x/net/context"

	"github.com/jacobsa/gcloud/gcs"
)

// Return a blob store that stores blobs in the supplied GCS bucket. GCS object
// names look like:
//
//     <prefix><score>
//
// where <score> is the result of calling Score.Hex.
//
// The blob store trusts that it has full ownership of this portion of the
// bucket's namespace -- if a score name exists, then it points to the correct
// data.
//
// The returned store does not support Flush or Contains; these methods must
// not be called.
func NewGCSStore(
	bucket gcs.Bucket,
	prefix string) (store *GCSStore) {
	store = &GCSStore{
		bucket:     bucket,
		namePrefix: prefix,
	}

	return
}

type GCSStore struct {
	bucket     gcs.Bucket
	namePrefix string
}

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

func (s *GCSStore) makeName(score Score) (name string) {
	name = s.namePrefix + score.Hex()
	return
}

////////////////////////////////////////////////////////////////////////
// Public interface
////////////////////////////////////////////////////////////////////////

func (s *GCSStore) Store(blob []byte) (score Score, err error) {
	// Compute a score and an object name.
	score = ComputeScore(blob)
	name := s.makeName(score)

	// Create the object.
	//
	// TODO(jacobsa): Set MD5 and CRC32C. See issue #18.
	req := &gcs.CreateObjectRequest{
		Name:     name,
		Contents: bytes.NewReader(blob),
	}

	_, err = s.bucket.CreateObject(context.Background(), req)
	if err != nil {
		err = fmt.Errorf("CreateObject: %v", err)
		return
	}

	return
}

func (s *GCSStore) Flush() (err error) {
	panic("GCSStore.Flush not supported; wiring code bug?")
}

func (s *GCSStore) Contains(score Score) (b bool) {
	panic("GCSStore.Contains not supported; wiring code bug?")
}

func (s *GCSStore) Load(score Score) (blob []byte, err error) {
	// Create a ReadCloser.
	req := &gcs.ReadObjectRequest{
		Name: s.makeName(score),
	}

	rc, err := s.bucket.NewReader(context.Background(), req)
	if err != nil {
		err = fmt.Errorf("NewReader: %v", err)
		return
	}

	// Read from it.
	blob, err = ioutil.ReadAll(rc)
	if err != nil {
		rc.Close()
		err = fmt.Errorf("ReadAll: %v", err)
		return
	}

	// Close it.
	err = rc.Close()
	if err != nil {
		err = fmt.Errorf("Close: %v", err)
		return
	}

	return
}

// List all of the blobs that are known to be durable in the bucket.
func (s *GCSStore) List() (scores []Score, err error) {
	req := &gcs.ListObjectsRequest{
		Prefix: s.namePrefix,
	}

	// List repeatedly until we're done.
	for {
		// Call the bucket.
		var listing *gcs.Listing
		listing, err = s.bucket.ListObjects(context.Background(), req)
		if err != nil {
			err = fmt.Errorf("ListObjects: %v", err)
			return
		}

		// Process results.
		for _, o := range listing.Objects {
			if !strings.HasPrefix(o.Name, s.namePrefix) {
				err = fmt.Errorf("Unexpected object name: %q", o.Name)
				return
			}

			var score Score
			hexScore := strings.TrimPrefix(o.Name, s.namePrefix)
			score, err = ParseHexScore(hexScore)
			if err != nil {
				err = fmt.Errorf("Unexpected hex score %q: %v", hexScore, err)
				return
			}

			scores = append(scores, score)
		}

		// Continue?
		if listing.ContinuationToken == "" {
			break
		}

		req.ContinuationToken = listing.ContinuationToken
	}

	return
}
<commit_msg>Set expected checksums when calling GCS.<commit_after>// Copyright 2015 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 blob

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"strings"

	"golang.org/x/net/context"

	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/gcsutil"
)

// Return a blob store that stores blobs in the supplied GCS bucket. GCS object
// names look like:
//
//     <prefix><score>
//
// where <score> is the result of calling Score.Hex.
//
// The blob store trusts that it has full ownership of this portion of the
// bucket's namespace -- if a score name exists, then it points to the correct
// data.
//
// The returned store does not support Flush or Contains; these methods must
// not be called.
func NewGCSStore(
	bucket gcs.Bucket,
	prefix string) (store *GCSStore) {
	store = &GCSStore{
		bucket:     bucket,
		namePrefix: prefix,
	}

	return
}

type GCSStore struct {
	bucket     gcs.Bucket
	namePrefix string
}

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

func (s *GCSStore) makeName(score Score) (name string) {
	name = s.namePrefix + score.Hex()
	return
}

////////////////////////////////////////////////////////////////////////
// Public interface
////////////////////////////////////////////////////////////////////////

func (s *GCSStore) Store(blob []byte) (score Score, err error) {
	// Compute a score and an object name.
	score = ComputeScore(blob)
	name := s.makeName(score)

	// Create the object.
	req := &gcs.CreateObjectRequest{
		Name:     name,
		Contents: bytes.NewReader(blob),
		CRC32C:   gcsutil.CRC32C(blob),
		MD5:      gcsutil.MD5(blob),
	}

	_, err = s.bucket.CreateObject(context.Background(), req)
	if err != nil {
		err = fmt.Errorf("CreateObject: %v", err)
		return
	}

	return
}

func (s *GCSStore) Flush() (err error) {
	panic("GCSStore.Flush not supported; wiring code bug?")
}

func (s *GCSStore) Contains(score Score) (b bool) {
	panic("GCSStore.Contains not supported; wiring code bug?")
}

func (s *GCSStore) Load(score Score) (blob []byte, err error) {
	// Create a ReadCloser.
	req := &gcs.ReadObjectRequest{
		Name: s.makeName(score),
	}

	rc, err := s.bucket.NewReader(context.Background(), req)
	if err != nil {
		err = fmt.Errorf("NewReader: %v", err)
		return
	}

	// Read from it.
	blob, err = ioutil.ReadAll(rc)
	if err != nil {
		rc.Close()
		err = fmt.Errorf("ReadAll: %v", err)
		return
	}

	// Close it.
	err = rc.Close()
	if err != nil {
		err = fmt.Errorf("Close: %v", err)
		return
	}

	return
}

// List all of the blobs that are known to be durable in the bucket.
func (s *GCSStore) List() (scores []Score, err error) {
	req := &gcs.ListObjectsRequest{
		Prefix: s.namePrefix,
	}

	// List repeatedly until we're done.
	for {
		// Call the bucket.
		var listing *gcs.Listing
		listing, err = s.bucket.ListObjects(context.Background(), req)
		if err != nil {
			err = fmt.Errorf("ListObjects: %v", err)
			return
		}

		// Process results.
		for _, o := range listing.Objects {
			if !strings.HasPrefix(o.Name, s.namePrefix) {
				err = fmt.Errorf("Unexpected object name: %q", o.Name)
				return
			}

			var score Score
			hexScore := strings.TrimPrefix(o.Name, s.namePrefix)
			score, err = ParseHexScore(hexScore)
			if err != nil {
				err = fmt.Errorf("Unexpected hex score %q: %v", hexScore, err)
				return
			}

			scores = append(scores, score)
		}

		// Continue?
		if listing.ContinuationToken == "" {
			break
		}

		req.ContinuationToken = listing.ContinuationToken
	}

	return
}
<|endoftext|>


<commit_before>package blocks

import (
	"encoding/json"
	"time"

	"github.com/jtmelton/appsensor-reverse-proxy/Godeps/_workspace/src/github.com/golang/glog"
	"github.com/jtmelton/appsensor-reverse-proxy/Godeps/_workspace/src/github.com/parnurzeal/gorequest"
)

func RefreshBlocks(blockRefreshUrl *string) {
	//"http://localhost:8090/api/v1.0/blocks"
	_, body, _ := gorequest.New().Get(*blockRefreshUrl).End()

	var blocks Blocks

	if err := json.Unmarshal([]byte(body), &blocks); err != nil {
		panic(err)
	}

	for _, element := range blocks {

		// temporary hack for dealing w/ java block store
		// it keeps timestamp in microseconds for some reason
		element.Endtime = element.Endtime / 1000

		t, _ := unixToTime(element.Endtime)

		// only add if this is still a valid time block
		if time.Now().Before(t) {
			//back to json so it's hashable
			jsonStr, _ := json.Marshal(element)
			StoredBlocks.Add(string(jsonStr))
		}

	}

//	glog.Info(StoredBlocks.Len())
	glog.Infof("Retrieved %d blocks, total stored: %d", len(blocks), StoredBlocks.Len())
//	glog.Info("STORED blocks: ", StoredBlocks.Flatten())
//	glog.Info("Printing response: ", resp)
//	glog.Info("Printing body: ", body)
}
<commit_msg>updating block refresh<commit_after>package blocks

import (
	"encoding/json"
	"time"

	"github.com/jtmelton/appsensor-reverse-proxy/Godeps/_workspace/src/github.com/golang/glog"
	"github.com/jtmelton/appsensor-reverse-proxy/Godeps/_workspace/src/github.com/parnurzeal/gorequest"
)

func RefreshBlocks(blockRefreshUrl *string) {
	//"http://localhost:8090/api/v1.0/blocks"
	_, body, _ := gorequest.New().Get(*blockRefreshUrl).End()

	var blocks Blocks

	if err := json.Unmarshal([]byte(body), &blocks); err != nil {
		panic(err)
	}

	for _, element := range blocks {

		// temporary hack for dealing w/ java block store
		// it keeps timestamp in microseconds for some reason
		element.Endtime = element.Endtime / 1000

		t, _ := unixToTime(element.Endtime)

		// only add if this is still a valid time block
		if time.Now().Before(t) {
			//back to json so it's hashable
			jsonStr, _ := json.Marshal(element)
			StoredBlocks.Add(string(jsonStr))
		}

	}

	//	glog.Info(StoredBlocks.Len())
	glog.Infof("Retrieved %d blocks, total stored: %d", len(blocks), StoredBlocks.Len())
	//	glog.Info("STORED blocks: ", StoredBlocks.Flatten())
	//	glog.Info("Printing response: ", resp)
	//	glog.Info("Printing body: ", body)
}
<|endoftext|>


<commit_before>package cmd

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/go-errors/errors"
	"github.com/mdp/qrterminal"
	"github.com/privacybydesign/irmago"
	"github.com/privacybydesign/irmago/internal/common"
	"github.com/privacybydesign/irmago/server"
	sseclient "github.com/sietseringers/go-sse"
	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
)

// requestCmd represents the request command
var requestCmd = &cobra.Command{
	Use:   "request",
	Short: "Generate an IRMA session request",
	Run: func(cmd *cobra.Command, args []string) {
		request, _, err := configureRequest(cmd)
		if err != nil {
			die("", err)
		}

		flags := cmd.Flags()
		authmethod, _ := flags.GetString("authmethod")
		var output string
		if authmethod == "none" || authmethod == "token" {
			output = prettyprint(request)
		} else {
			key, _ := flags.GetString("key")
			name, _ := flags.GetString("name")
			if output, err = signRequest(request, name, authmethod, key); err != nil {
				die("Failed to sign request", err)
			}
		}

		fmt.Println(output)
	},
}

func configureJWTKey(authmethod, key string) (interface{}, jwt.SigningMethod, error) {
	var (
		err    error
		sk     interface{}
		jwtalg jwt.SigningMethod
		bts    []byte
	)
	// If the key refers to an existing file, use contents of the file as key
	if bts, err = common.ReadKey("", key); err != nil {
		bts = []byte(key)
	}
	switch authmethod {
	case "hmac":
		jwtalg = jwt.SigningMethodHS256
		if sk, err = common.Base64Decode(bts); err != nil {
			return nil, nil, err
		}
	case "rsa":
		jwtalg = jwt.SigningMethodRS256
		if sk, err = jwt.ParseRSAPrivateKeyFromPEM(bts); err != nil {
			return nil, nil, err
		}
	default:
		return nil, nil, errors.Errorf("Unsupported signing algorithm: '%s'", authmethod)
	}

	return sk, jwtalg, nil
}

func signRequest(request irma.RequestorRequest, name, authmethod, key string) (string, error) {
	sk, jwtalg, err := configureJWTKey(authmethod, key)
	if err != nil {
		return "", err
	}
	return irma.SignRequestorRequest(request, jwtalg, sk, name)
}

func configureRequest(cmd *cobra.Command) (irma.RequestorRequest, *irma.Configuration, error) {
	irmaconfigPath, err := cmd.Flags().GetString("schemes-path")
	if err != nil {
		return nil, nil, err
	}
	irmaconfig, err := irma.NewConfiguration(irmaconfigPath, irma.ConfigurationOptions{})
	if err != nil {
		return nil, nil, err
	}
	if err = irmaconfig.ParseFolder(); err != nil {
		return nil, nil, err
	}
	if len(irmaconfig.SchemeManagers) == 0 {
		if err = irmaconfig.DownloadDefaultSchemes(); err != nil {
			return nil, nil, err
		}
	}

	request, err := constructSessionRequest(cmd, irmaconfig)
	if err != nil {
		return nil, nil, err
	}

	return request, irmaconfig, nil
}

// Helper functions

func wait(initialStatus server.Status, transport *irma.HTTPTransport, statuschan chan server.Status) {
	events := make(chan *sseclient.Event)

	go func() {
		for {
			if e := <-events; e != nil && e.Type != "open" {
				status := server.Status(strings.Trim(string(e.Data), `"`))
				statuschan <- status
				if status.Finished() {
					return
				}
			}
		}
	}()

	if err := sseclient.Notify(nil, transport.Server+"statusevents", true, events); err != nil {
		fmt.Println("SSE failed, fallback to polling", err)
		close(events)
		poll(initialStatus, transport, statuschan)
		return
	}
}

// poll recursively polls the session status until a final status is received.
func poll(initialStatus server.Status, transport *irma.HTTPTransport, statuschan chan server.Status) {
	// First we wait
	<-time.NewTimer(pollInterval).C

	// Get session status
	var s string
	if err := transport.Get("status", &s); err != nil {
		_ = server.LogFatal(err)
	}
	status := server.Status(strings.Trim(s, `"`))

	// report if status changed
	if status != initialStatus {
		statuschan <- status
	}

	if status.Finished() {
		return
	}
	go poll(status, transport, statuschan)
}

func constructSessionRequest(cmd *cobra.Command, conf *irma.Configuration) (irma.RequestorRequest, error) {
	disclose, _ := cmd.Flags().GetStringArray("disclose")
	issue, _ := cmd.Flags().GetStringArray("issue")
	sign, _ := cmd.Flags().GetStringArray("sign")
	message, _ := cmd.Flags().GetString("message")
	jsonrequest, _ := cmd.Flags().GetString("request")

	if len(disclose) == 0 && len(issue) == 0 && len(sign) == 0 && message == "" {
		if jsonrequest == "" {
			return nil, errors.New("Provide either a complete session request using --request or construct one using the other flags")
		}
		request, err := server.ParseSessionRequest(jsonrequest)
		if err != nil {
			return nil, err
		}
		return request, nil
	}

	if jsonrequest != "" {
		return nil, errors.New("Provide either a complete session request using --request or construct one using the other flags")
	}

	if len(sign) != 0 {
		if len(disclose) != 0 {
			return nil, errors.New("cannot combine disclosure and signature sessions, use either --disclose or --sign")
		}
		if len(issue) != 0 {
			return nil, errors.New("cannot combine issuance and signature sessions, use either --issue or --sign")
		}
		if message == "" {
			return nil, errors.New("signature sessions require a message to be signed using --message")
		}
	}

	var request irma.RequestorRequest
	if len(disclose) != 0 && len(issue) == 0 {
		disclose, err := parseAttrs(disclose, conf)
		if err != nil {
			return nil, err
		}
		request = &irma.ServiceProviderRequest{
			Request: irma.NewDisclosureRequest(),
		}
		request.SessionRequest().(*irma.DisclosureRequest).Disclose = disclose
	}
	if len(sign) != 0 {
		disclose, err := parseAttrs(sign, conf)
		if err != nil {
			return nil, err
		}
		request = &irma.SignatureRequestorRequest{
			Request: irma.NewSignatureRequest(message),
		}
		request.SessionRequest().(*irma.SignatureRequest).Disclose = disclose
	}
	if len(issue) != 0 {
		creds, err := parseCredentials(issue, conf)
		if err != nil {
			return nil, err
		}
		disclose, err := parseAttrs(disclose, conf)
		if err != nil {
			return nil, err
		}
		request = &irma.IdentityProviderRequest{
			Request: irma.NewIssuanceRequest(creds),
		}
		request.SessionRequest().(*irma.IssuanceRequest).Disclose = disclose
	}

	return request, nil
}

func parseCredentials(credentialsStr []string, conf *irma.Configuration) ([]*irma.CredentialRequest, error) {
	list := make([]*irma.CredentialRequest, 0, len(credentialsStr))

	for _, credStr := range credentialsStr {
		parts := strings.Split(credStr, "=")
		if len(parts) != 2 {
			return nil, errors.New("--issue argument must contain exactly 1 = sign")
		}
		credIdStr, attrsStr := parts[0], parts[1]
		credtype := conf.CredentialTypes[irma.NewCredentialTypeIdentifier(credIdStr)]
		if credtype == nil {
			return nil, errors.New("unknown credential type: " + credIdStr)
		}

		attrsSlice := strings.Split(attrsStr, ",")
		if len(attrsSlice) != len(credtype.AttributeTypes) {
			return nil, errors.Errorf("%d attributes required but %d provided for %s", len(credtype.AttributeTypes), len(attrsSlice), credIdStr)
		}

		attrs := make(map[string]string, len(attrsSlice))
		for i, typ := range credtype.AttributeTypes {
			attrs[typ.ID] = attrsSlice[i]
		}
		list = append(list, &irma.CredentialRequest{
			CredentialTypeID: irma.NewCredentialTypeIdentifier(credIdStr),
			Attributes:       attrs,
		})
	}

	return list, nil
}

func parseAttrs(attrsStr []string, conf *irma.Configuration) (irma.AttributeConDisCon, error) {
	list := make(irma.AttributeConDisCon, 0, len(attrsStr))
	for _, disjunctionStr := range attrsStr {
		disjunction := irma.AttributeDisCon{}
		attrids := strings.Split(disjunctionStr, ",")
		for _, attridStr := range attrids {
			attrid := irma.NewAttributeTypeIdentifier(attridStr)
			if conf.AttributeTypes[attrid] == nil {
				return nil, errors.New("unknown attribute: " + attridStr)
			}
			disjunction = append(disjunction, irma.AttributeCon{irma.AttributeRequest{Type: attrid}})
		}
		list = append(list, disjunction)
	}
	return list, nil
}

func startServer(port int) {
	mux := http.NewServeMux()
	mux.HandleFunc("/", irmaServer.HandlerFunc())
	httpServer = &http.Server{Addr: ":" + strconv.Itoa(port), Handler: mux}
	go func() {
		err := httpServer.ListenAndServe()
		if err != nil && err != http.ErrServerClosed {
			die("Failed to start server", err)
		}
	}()
}

func printQr(qr *irma.Qr, noqr bool) error {
	qrBts, err := json.Marshal(qr)
	if err != nil {
		return err
	}
	if noqr {
		fmt.Println(string(qrBts))
	} else {
		qrterminal.GenerateWithConfig(string(qrBts), qrterminal.Config{
			Level:     qrterminal.L,
			Writer:    os.Stdout,
			BlackChar: qrterminal.BLACK,
			WhiteChar: qrterminal.WHITE,
		})
	}
	return nil
}

func printSessionResult(result *server.SessionResult) {
	fmt.Println("Session result:")
	fmt.Println(prettyprint(result))
}

func init() {
	RootCmd.AddCommand(requestCmd)

	flags := requestCmd.Flags()
	flags.SortFlags = false

	addRequestFlags(flags)
}

func authmethodAlias(f *pflag.FlagSet, name string) pflag.NormalizedName {
	switch name {
	case "authmethod":
		name = "auth-method"
		break
	}
	return pflag.NormalizedName(name)
}

func addRequestFlags(flags *pflag.FlagSet) {
	flags.StringP("schemes-path", "s", irma.DefaultSchemesPath(), "path to irma_configuration")
	flags.StringP("auth-method", "a", "none", "Authentication method to server (none, token, rsa, hmac)")
	flags.SetNormalizeFunc(authmethodAlias)
	flags.String("key", "", "Key to sign request with")
	flags.String("name", "", "Requestor name")
	flags.StringArray("disclose", nil, "Add an attribute disjunction (comma-separated)")
	flags.StringArray("issue", nil, "Add a credential to issue")
	flags.StringArray("sign", nil, "Add an attribute disjunction to signature session")
	flags.String("message", "", "Message to sign in signature session")
}
<commit_msg>feat: support revocation in irma session and irma request<commit_after>package cmd

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/go-errors/errors"
	"github.com/mdp/qrterminal"
	"github.com/privacybydesign/irmago"
	"github.com/privacybydesign/irmago/internal/common"
	"github.com/privacybydesign/irmago/server"
	sseclient "github.com/sietseringers/go-sse"
	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
)

// requestCmd represents the request command
var requestCmd = &cobra.Command{
	Use:   "request",
	Short: "Generate an IRMA session request",
	Run: func(cmd *cobra.Command, args []string) {
		request, _, err := configureRequest(cmd)
		if err != nil {
			die("", err)
		}

		flags := cmd.Flags()
		authmethod, _ := flags.GetString("authmethod")
		var output string
		if authmethod == "none" || authmethod == "token" {
			output = prettyprint(request)
		} else {
			key, _ := flags.GetString("key")
			name, _ := flags.GetString("name")
			if output, err = signRequest(request, name, authmethod, key); err != nil {
				die("Failed to sign request", err)
			}
		}

		fmt.Println(output)
	},
}

func configureJWTKey(authmethod, key string) (interface{}, jwt.SigningMethod, error) {
	var (
		err    error
		sk     interface{}
		jwtalg jwt.SigningMethod
		bts    []byte
	)
	// If the key refers to an existing file, use contents of the file as key
	if bts, err = common.ReadKey("", key); err != nil {
		bts = []byte(key)
	}
	switch authmethod {
	case "hmac":
		jwtalg = jwt.SigningMethodHS256
		if sk, err = common.Base64Decode(bts); err != nil {
			return nil, nil, err
		}
	case "rsa":
		jwtalg = jwt.SigningMethodRS256
		if sk, err = jwt.ParseRSAPrivateKeyFromPEM(bts); err != nil {
			return nil, nil, err
		}
	default:
		return nil, nil, errors.Errorf("Unsupported signing algorithm: '%s'", authmethod)
	}

	return sk, jwtalg, nil
}

func signRequest(request irma.RequestorRequest, name, authmethod, key string) (string, error) {
	sk, jwtalg, err := configureJWTKey(authmethod, key)
	if err != nil {
		return "", err
	}
	return irma.SignRequestorRequest(request, jwtalg, sk, name)
}

func configureRequest(cmd *cobra.Command) (irma.RequestorRequest, *irma.Configuration, error) {
	irmaconfigPath, err := cmd.Flags().GetString("schemes-path")
	if err != nil {
		return nil, nil, err
	}
	irmaconfig, err := irma.NewConfiguration(irmaconfigPath, irma.ConfigurationOptions{})
	if err != nil {
		return nil, nil, err
	}
	if err = irmaconfig.ParseFolder(); err != nil {
		return nil, nil, err
	}
	if len(irmaconfig.SchemeManagers) == 0 {
		if err = irmaconfig.DownloadDefaultSchemes(); err != nil {
			return nil, nil, err
		}
	}

	request, err := constructSessionRequest(cmd, irmaconfig)
	if err != nil {
		return nil, nil, err
	}

	return request, irmaconfig, nil
}

// Helper functions

func wait(initialStatus server.Status, transport *irma.HTTPTransport, statuschan chan server.Status) {
	events := make(chan *sseclient.Event)

	go func() {
		for {
			if e := <-events; e != nil && e.Type != "open" {
				status := server.Status(strings.Trim(string(e.Data), `"`))
				statuschan <- status
				if status.Finished() {
					return
				}
			}
		}
	}()

	if err := sseclient.Notify(nil, transport.Server+"statusevents", true, events); err != nil {
		fmt.Println("SSE failed, fallback to polling", err)
		close(events)
		poll(initialStatus, transport, statuschan)
		return
	}
}

// poll recursively polls the session status until a final status is received.
func poll(initialStatus server.Status, transport *irma.HTTPTransport, statuschan chan server.Status) {
	// First we wait
	<-time.NewTimer(pollInterval).C

	// Get session status
	var s string
	if err := transport.Get("status", &s); err != nil {
		_ = server.LogFatal(err)
	}
	status := server.Status(strings.Trim(s, `"`))

	// report if status changed
	if status != initialStatus {
		statuschan <- status
	}

	if status.Finished() {
		return
	}
	go poll(status, transport, statuschan)
}

func constructSessionRequest(cmd *cobra.Command, conf *irma.Configuration) (irma.RequestorRequest, error) {
	disclose, _ := cmd.Flags().GetStringArray("disclose")
	issue, _ := cmd.Flags().GetStringArray("issue")
	sign, _ := cmd.Flags().GetStringArray("sign")
	message, _ := cmd.Flags().GetString("message")
	jsonrequest, _ := cmd.Flags().GetString("request")
	revocationKey, _ := cmd.Flags().GetString("revocation-key")

	if len(disclose) == 0 && len(issue) == 0 && len(sign) == 0 && message == "" {
		if jsonrequest == "" {
			return nil, errors.New("Provide either a complete session request using --request or construct one using the other flags")
		}
		request, err := server.ParseSessionRequest(jsonrequest)
		if err != nil {
			return nil, err
		}
		return request, nil
	}

	if jsonrequest != "" {
		return nil, errors.New("Provide either a complete session request using --request or construct one using the other flags")
	}

	if len(sign) != 0 {
		if len(disclose) != 0 {
			return nil, errors.New("cannot combine disclosure and signature sessions, use either --disclose or --sign")
		}
		if len(issue) != 0 {
			return nil, errors.New("cannot combine issuance and signature sessions, use either --issue or --sign")
		}
		if message == "" {
			return nil, errors.New("signature sessions require a message to be signed using --message")
		}
	}

	var request irma.RequestorRequest
	if len(disclose) != 0 && len(issue) == 0 {
		disclose, err := parseAttrs(disclose, conf)
		if err != nil {
			return nil, err
		}
		request = &irma.ServiceProviderRequest{
			Request: irma.NewDisclosureRequest(),
		}
		request.SessionRequest().(*irma.DisclosureRequest).Disclose = disclose
	}
	if len(sign) != 0 {
		disclose, err := parseAttrs(sign, conf)
		if err != nil {
			return nil, err
		}
		request = &irma.SignatureRequestorRequest{
			Request: irma.NewSignatureRequest(message),
		}
		request.SessionRequest().(*irma.SignatureRequest).Disclose = disclose
	}
	if len(issue) != 0 {
		creds, err := parseCredentials(issue, revocationKey, conf)
		if err != nil {
			return nil, err
		}
		disclose, err := parseAttrs(disclose, conf)
		if err != nil {
			return nil, err
		}
		request = &irma.IdentityProviderRequest{
			Request: irma.NewIssuanceRequest(creds),
		}
		request.SessionRequest().(*irma.IssuanceRequest).Disclose = disclose
	}

	return request, nil
}

func parseCredentials(
	credentialsStr []string, revocationKey string, conf *irma.Configuration,
) ([]*irma.CredentialRequest, error) {
	list := make([]*irma.CredentialRequest, 0, len(credentialsStr))
	revocationUsed := false

	for _, credStr := range credentialsStr {
		parts := strings.Split(credStr, "=")
		if len(parts) != 2 {
			return nil, errors.New("--issue argument must contain exactly 1 = sign")
		}
		credIdStr, attrsStr := parts[0], parts[1]
		credtype := conf.CredentialTypes[irma.NewCredentialTypeIdentifier(credIdStr)]
		if credtype == nil {
			return nil, errors.New("unknown credential type: " + credIdStr)
		}

		attrsSlice := strings.Split(attrsStr, ",")
		attrcount := len(credtype.AttributeTypes)
		if credtype.RevocationSupported() {
			attrcount -= 1
		}
		if len(attrsSlice) != attrcount {
			return nil, errors.Errorf("%d attributes required but %d provided for %s", attrcount, len(attrsSlice), credIdStr)
		}

		attrs := make(map[string]string, len(attrsSlice))
		i := 0
		for _, typ := range credtype.AttributeTypes {
			if typ.RevocationAttribute {
				continue
			}
			attrs[typ.ID] = attrsSlice[i]
			i++
		}
		req := &irma.CredentialRequest{
			CredentialTypeID: irma.NewCredentialTypeIdentifier(credIdStr),
			Attributes:       attrs,
		}
		if credtype.RevocationSupported() {
			if revocationKey == "" {
				return nil, errors.Errorf("revocationKey required for %s", credIdStr)
			}
			revocationUsed = true
			req.RevocationKey = revocationKey
		}
		list = append(list, req)
	}

	if !revocationUsed && revocationKey != "" {
		return nil, errors.New("revocation key specified but no credential uses revocation")
	}

	return list, nil
}

func parseAttrs(attrsStr []string, conf *irma.Configuration) (irma.AttributeConDisCon, error) {
	list := make(irma.AttributeConDisCon, 0, len(attrsStr))
	for _, disjunctionStr := range attrsStr {
		disjunction := irma.AttributeDisCon{}
		attrids := strings.Split(disjunctionStr, ",")
		for _, attridStr := range attrids {
			attrid := irma.NewAttributeTypeIdentifier(attridStr)
			if conf.AttributeTypes[attrid] == nil {
				return nil, errors.New("unknown attribute: " + attridStr)
			}
			disjunction = append(disjunction, irma.AttributeCon{irma.AttributeRequest{Type: attrid}})
		}
		list = append(list, disjunction)
	}
	return list, nil
}

func startServer(port int) {
	mux := http.NewServeMux()
	mux.HandleFunc("/", irmaServer.HandlerFunc())
	httpServer = &http.Server{Addr: ":" + strconv.Itoa(port), Handler: mux}
	go func() {
		err := httpServer.ListenAndServe()
		if err != nil && err != http.ErrServerClosed {
			die("Failed to start server", err)
		}
	}()
}

func printQr(qr *irma.Qr, noqr bool) error {
	qrBts, err := json.Marshal(qr)
	if err != nil {
		return err
	}
	if noqr {
		fmt.Println(string(qrBts))
	} else {
		qrterminal.GenerateWithConfig(string(qrBts), qrterminal.Config{
			Level:     qrterminal.L,
			Writer:    os.Stdout,
			BlackChar: qrterminal.BLACK,
			WhiteChar: qrterminal.WHITE,
		})
	}
	return nil
}

func printSessionResult(result *server.SessionResult) {
	fmt.Println("Session result:")
	fmt.Println(prettyprint(result))
}

func init() {
	RootCmd.AddCommand(requestCmd)

	flags := requestCmd.Flags()
	flags.SortFlags = false

	addRequestFlags(flags)
}

func authmethodAlias(f *pflag.FlagSet, name string) pflag.NormalizedName {
	switch name {
	case "authmethod":
		name = "auth-method"
		break
	}
	return pflag.NormalizedName(name)
}

func addRequestFlags(flags *pflag.FlagSet) {
	flags.StringP("schemes-path", "s", irma.DefaultSchemesPath(), "path to irma_configuration")
	flags.StringP("auth-method", "a", "none", "Authentication method to server (none, token, rsa, hmac)")
	flags.SetNormalizeFunc(authmethodAlias)
	flags.String("key", "", "Key to sign request with")
	flags.String("name", "", "Requestor name")
	flags.StringArray("disclose", nil, "Add an attribute disjunction (comma-separated)")
	flags.StringArray("issue", nil, "Add a credential to issue")
	flags.StringArray("sign", nil, "Add an attribute disjunction to signature session")
	flags.String("message", "", "Message to sign in signature session")
	flags.String("revocation-key", "", "Revocation key")
}
<|endoftext|>


<commit_before>package openapi

import "strconv"

// SuccessResponse returns a success response object.
// If there are 2 or more success responses (like created and ok),
// it's not sure which is returned.
// If only match the default response or 2XX response, returned status code will be 0.
func (op *Operation) SuccessResponse() (*Response, int, bool) {
	if op.Responses == nil {
		return nil, -1, false
	}
	var defaultResponse *Response
	for statusStr, resp := range op.Responses {
		switch statusStr {
		case "default":
			defaultResponse = resp
		case "2XX":
			defaultResponse = resp
		case "1XX", "3XX", "4XX", "5XX":
			continue
		}
		statusInt, err := strconv.Atoi(statusStr)
		if err != nil {
			continue
		}
		if statusInt/100 == 2 {
			return resp, statusInt, true
		}
	}
	return defaultResponse, 0, false
}
<commit_msg>add nil check for operation<commit_after>package openapi

import "strconv"

// SuccessResponse returns a success response object.
// If there are 2 or more success responses (like created and ok),
// it's not sure which is returned.
// If only match the default response or 2XX response, returned status code will be 0.
func (op *Operation) SuccessResponse() (*Response, int, bool) {
	if op == nil || op.Responses == nil {
		return nil, -1, false
	}
	var defaultResponse *Response
	for statusStr, resp := range op.Responses {
		switch statusStr {
		case "default":
			defaultResponse = resp
		case "2XX":
			defaultResponse = resp
		case "1XX", "3XX", "4XX", "5XX":
			continue
		}
		statusInt, err := strconv.Atoi(statusStr)
		if err != nil {
			continue
		}
		if statusInt/100 == 2 {
			return resp, statusInt, true
		}
	}
	return defaultResponse, 0, false
}
<|endoftext|>


<commit_before>package opts

import (
	"fmt"
	"net"
	"regexp"
	"strings"

	"github.com/docker/engine-api/types/filters"
)

var (
	alphaRegexp  = regexp.MustCompile(`[a-zA-Z]`)
	domainRegexp = regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`)
)

// ListOpts holds a list of values and a validation function.
type ListOpts struct {
	values    *[]string
	validator ValidatorFctType
}

// NewListOpts creates a new ListOpts with the specified validator.
func NewListOpts(validator ValidatorFctType) ListOpts {
	var values []string
	return *NewListOptsRef(&values, validator)
}

// NewListOptsRef creates a new ListOpts with the specified values and validator.
func NewListOptsRef(values *[]string, validator ValidatorFctType) *ListOpts {
	return &ListOpts{
		values:    values,
		validator: validator,
	}
}

func (opts *ListOpts) String() string {
	return fmt.Sprintf("%v", []string((*opts.values)))
}

// Set validates if needed the input value and adds it to the
// internal slice.
func (opts *ListOpts) Set(value string) error {
	if opts.validator != nil {
		v, err := opts.validator(value)
		if err != nil {
			return err
		}
		value = v
	}
	(*opts.values) = append((*opts.values), value)
	return nil
}

// Delete removes the specified element from the slice.
func (opts *ListOpts) Delete(key string) {
	for i, k := range *opts.values {
		if k == key {
			(*opts.values) = append((*opts.values)[:i], (*opts.values)[i+1:]...)
			return
		}
	}
}

// GetMap returns the content of values in a map in order to avoid
// duplicates.
func (opts *ListOpts) GetMap() map[string]struct{} {
	ret := make(map[string]struct{})
	for _, k := range *opts.values {
		ret[k] = struct{}{}
	}
	return ret
}

// GetAll returns the values of slice.
func (opts *ListOpts) GetAll() []string {
	return (*opts.values)
}

// GetAllOrEmpty returns the values of the slice
// or an empty slice when there are no values.
func (opts *ListOpts) GetAllOrEmpty() []string {
	v := *opts.values
	if v == nil {
		return make([]string, 0)
	}
	return v
}

// Get checks the existence of the specified key.
func (opts *ListOpts) Get(key string) bool {
	for _, k := range *opts.values {
		if k == key {
			return true
		}
	}
	return false
}

// Len returns the amount of element in the slice.
func (opts *ListOpts) Len() int {
	return len((*opts.values))
}

// Type returns a string name for this Option type
func (opts *ListOpts) Type() string {
	return "list"
}

// NamedOption is an interface that list and map options
// with names implement.
type NamedOption interface {
	Name() string
}

// NamedListOpts is a ListOpts with a configuration name.
// This struct is useful to keep reference to the assigned
// field name in the internal configuration struct.
type NamedListOpts struct {
	name string
	ListOpts
}

var _ NamedOption = &NamedListOpts{}

// NewNamedListOptsRef creates a reference to a new NamedListOpts struct.
func NewNamedListOptsRef(name string, values *[]string, validator ValidatorFctType) *NamedListOpts {
	return &NamedListOpts{
		name:     name,
		ListOpts: *NewListOptsRef(values, validator),
	}
}

// Name returns the name of the NamedListOpts in the configuration.
func (o *NamedListOpts) Name() string {
	return o.name
}

//MapOpts holds a map of values and a validation function.
type MapOpts struct {
	values    map[string]string
	validator ValidatorFctType
}

// Set validates if needed the input value and add it to the
// internal map, by splitting on '='.
func (opts *MapOpts) Set(value string) error {
	if opts.validator != nil {
		v, err := opts.validator(value)
		if err != nil {
			return err
		}
		value = v
	}
	vals := strings.SplitN(value, "=", 2)
	if len(vals) == 1 {
		(opts.values)[vals[0]] = ""
	} else {
		(opts.values)[vals[0]] = vals[1]
	}
	return nil
}

// GetAll returns the values of MapOpts as a map.
func (opts *MapOpts) GetAll() map[string]string {
	return opts.values
}

func (opts *MapOpts) String() string {
	return fmt.Sprintf("%v", map[string]string((opts.values)))
}

// Type returns a string name for this Option type
func (opts *MapOpts) Type() string {
	return "map"
}

// NewMapOpts creates a new MapOpts with the specified map of values and a validator.
func NewMapOpts(values map[string]string, validator ValidatorFctType) *MapOpts {
	if values == nil {
		values = make(map[string]string)
	}
	return &MapOpts{
		values:    values,
		validator: validator,
	}
}

// NamedMapOpts is a MapOpts struct with a configuration name.
// This struct is useful to keep reference to the assigned
// field name in the internal configuration struct.
type NamedMapOpts struct {
	name string
	MapOpts
}

var _ NamedOption = &NamedMapOpts{}

// NewNamedMapOpts creates a reference to a new NamedMapOpts struct.
func NewNamedMapOpts(name string, values map[string]string, validator ValidatorFctType) *NamedMapOpts {
	return &NamedMapOpts{
		name:    name,
		MapOpts: *NewMapOpts(values, validator),
	}
}

// Name returns the name of the NamedMapOpts in the configuration.
func (o *NamedMapOpts) Name() string {
	return o.name
}

// ValidatorFctType defines a validator function that returns a validated string and/or an error.
type ValidatorFctType func(val string) (string, error)

// ValidatorFctListType defines a validator function that returns a validated list of string and/or an error
type ValidatorFctListType func(val string) ([]string, error)

// ValidateIPAddress validates an Ip address.
func ValidateIPAddress(val string) (string, error) {
	var ip = net.ParseIP(strings.TrimSpace(val))
	if ip != nil {
		return ip.String(), nil
	}
	return "", fmt.Errorf("%s is not an ip address", val)
}

// ValidateDNSSearch validates domain for resolvconf search configuration.
// A zero length domain is represented by a dot (.).
func ValidateDNSSearch(val string) (string, error) {
	if val = strings.Trim(val, " "); val == "." {
		return val, nil
	}
	return validateDomain(val)
}

func validateDomain(val string) (string, error) {
	if alphaRegexp.FindString(val) == "" {
		return "", fmt.Errorf("%s is not a valid domain", val)
	}
	ns := domainRegexp.FindSubmatch([]byte(val))
	if len(ns) > 0 && len(ns[1]) < 255 {
		return string(ns[1]), nil
	}
	return "", fmt.Errorf("%s is not a valid domain", val)
}

// ValidateLabel validates that the specified string is a valid label, and returns it.
// Labels are in the form on key=value.
func ValidateLabel(val string) (string, error) {
	if strings.Count(val, "=") < 1 {
		return "", fmt.Errorf("bad attribute format: %s", val)
	}
	return val, nil
}

// ValidateSysctl validates a sysctl and returns it.
func ValidateSysctl(val string) (string, error) {
	validSysctlMap := map[string]bool{
		"kernel.msgmax":          true,
		"kernel.msgmnb":          true,
		"kernel.msgmni":          true,
		"kernel.sem":             true,
		"kernel.shmall":          true,
		"kernel.shmmax":          true,
		"kernel.shmmni":          true,
		"kernel.shm_rmid_forced": true,
	}
	validSysctlPrefixes := []string{
		"net.",
		"fs.mqueue.",
	}
	arr := strings.Split(val, "=")
	if len(arr) < 2 {
		return "", fmt.Errorf("sysctl '%s' is not whitelisted", val)
	}
	if validSysctlMap[arr[0]] {
		return val, nil
	}

	for _, vp := range validSysctlPrefixes {
		if strings.HasPrefix(arr[0], vp) {
			return val, nil
		}
	}
	return "", fmt.Errorf("sysctl '%s' is not whitelisted", val)
}

// FilterOpt is a flag type for validating filters
type FilterOpt struct {
	filter filters.Args
}

// NewFilterOpt returns a new FilterOpt
func NewFilterOpt() FilterOpt {
	return FilterOpt{filter: filters.NewArgs()}
}

func (o *FilterOpt) String() string {
	repr, err := filters.ToParam(o.filter)
	if err != nil {
		return "invalid filters"
	}
	return repr
}

// Set sets the value of the opt by parsing the command line value
func (o *FilterOpt) Set(value string) error {
	var err error
	o.filter, err = filters.ParseFlag(value, o.filter)
	return err
}

// Type returns the option type
func (o *FilterOpt) Type() string {
	return "filter"
}

// Value returns the value of this option
func (o *FilterOpt) Value() filters.Args {
	return o.filter
}
<commit_msg>correct some nits in comment and test files<commit_after>package opts

import (
	"fmt"
	"net"
	"regexp"
	"strings"

	"github.com/docker/engine-api/types/filters"
)

var (
	alphaRegexp  = regexp.MustCompile(`[a-zA-Z]`)
	domainRegexp = regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`)
)

// ListOpts holds a list of values and a validation function.
type ListOpts struct {
	values    *[]string
	validator ValidatorFctType
}

// NewListOpts creates a new ListOpts with the specified validator.
func NewListOpts(validator ValidatorFctType) ListOpts {
	var values []string
	return *NewListOptsRef(&values, validator)
}

// NewListOptsRef creates a new ListOpts with the specified values and validator.
func NewListOptsRef(values *[]string, validator ValidatorFctType) *ListOpts {
	return &ListOpts{
		values:    values,
		validator: validator,
	}
}

func (opts *ListOpts) String() string {
	return fmt.Sprintf("%v", []string((*opts.values)))
}

// Set validates if needed the input value and adds it to the
// internal slice.
func (opts *ListOpts) Set(value string) error {
	if opts.validator != nil {
		v, err := opts.validator(value)
		if err != nil {
			return err
		}
		value = v
	}
	(*opts.values) = append((*opts.values), value)
	return nil
}

// Delete removes the specified element from the slice.
func (opts *ListOpts) Delete(key string) {
	for i, k := range *opts.values {
		if k == key {
			(*opts.values) = append((*opts.values)[:i], (*opts.values)[i+1:]...)
			return
		}
	}
}

// GetMap returns the content of values in a map in order to avoid
// duplicates.
func (opts *ListOpts) GetMap() map[string]struct{} {
	ret := make(map[string]struct{})
	for _, k := range *opts.values {
		ret[k] = struct{}{}
	}
	return ret
}

// GetAll returns the values of slice.
func (opts *ListOpts) GetAll() []string {
	return (*opts.values)
}

// GetAllOrEmpty returns the values of the slice
// or an empty slice when there are no values.
func (opts *ListOpts) GetAllOrEmpty() []string {
	v := *opts.values
	if v == nil {
		return make([]string, 0)
	}
	return v
}

// Get checks the existence of the specified key.
func (opts *ListOpts) Get(key string) bool {
	for _, k := range *opts.values {
		if k == key {
			return true
		}
	}
	return false
}

// Len returns the amount of element in the slice.
func (opts *ListOpts) Len() int {
	return len((*opts.values))
}

// Type returns a string name for this Option type
func (opts *ListOpts) Type() string {
	return "list"
}

// NamedOption is an interface that list and map options
// with names implement.
type NamedOption interface {
	Name() string
}

// NamedListOpts is a ListOpts with a configuration name.
// This struct is useful to keep reference to the assigned
// field name in the internal configuration struct.
type NamedListOpts struct {
	name string
	ListOpts
}

var _ NamedOption = &NamedListOpts{}

// NewNamedListOptsRef creates a reference to a new NamedListOpts struct.
func NewNamedListOptsRef(name string, values *[]string, validator ValidatorFctType) *NamedListOpts {
	return &NamedListOpts{
		name:     name,
		ListOpts: *NewListOptsRef(values, validator),
	}
}

// Name returns the name of the NamedListOpts in the configuration.
func (o *NamedListOpts) Name() string {
	return o.name
}

// MapOpts holds a map of values and a validation function.
type MapOpts struct {
	values    map[string]string
	validator ValidatorFctType
}

// Set validates if needed the input value and add it to the
// internal map, by splitting on '='.
func (opts *MapOpts) Set(value string) error {
	if opts.validator != nil {
		v, err := opts.validator(value)
		if err != nil {
			return err
		}
		value = v
	}
	vals := strings.SplitN(value, "=", 2)
	if len(vals) == 1 {
		(opts.values)[vals[0]] = ""
	} else {
		(opts.values)[vals[0]] = vals[1]
	}
	return nil
}

// GetAll returns the values of MapOpts as a map.
func (opts *MapOpts) GetAll() map[string]string {
	return opts.values
}

func (opts *MapOpts) String() string {
	return fmt.Sprintf("%v", map[string]string((opts.values)))
}

// Type returns a string name for this Option type
func (opts *MapOpts) Type() string {
	return "map"
}

// NewMapOpts creates a new MapOpts with the specified map of values and a validator.
func NewMapOpts(values map[string]string, validator ValidatorFctType) *MapOpts {
	if values == nil {
		values = make(map[string]string)
	}
	return &MapOpts{
		values:    values,
		validator: validator,
	}
}

// NamedMapOpts is a MapOpts struct with a configuration name.
// This struct is useful to keep reference to the assigned
// field name in the internal configuration struct.
type NamedMapOpts struct {
	name string
	MapOpts
}

var _ NamedOption = &NamedMapOpts{}

// NewNamedMapOpts creates a reference to a new NamedMapOpts struct.
func NewNamedMapOpts(name string, values map[string]string, validator ValidatorFctType) *NamedMapOpts {
	return &NamedMapOpts{
		name:    name,
		MapOpts: *NewMapOpts(values, validator),
	}
}

// Name returns the name of the NamedMapOpts in the configuration.
func (o *NamedMapOpts) Name() string {
	return o.name
}

// ValidatorFctType defines a validator function that returns a validated string and/or an error.
type ValidatorFctType func(val string) (string, error)

// ValidatorFctListType defines a validator function that returns a validated list of string and/or an error
type ValidatorFctListType func(val string) ([]string, error)

// ValidateIPAddress validates an Ip address.
func ValidateIPAddress(val string) (string, error) {
	var ip = net.ParseIP(strings.TrimSpace(val))
	if ip != nil {
		return ip.String(), nil
	}
	return "", fmt.Errorf("%s is not an ip address", val)
}

// ValidateDNSSearch validates domain for resolvconf search configuration.
// A zero length domain is represented by a dot (.).
func ValidateDNSSearch(val string) (string, error) {
	if val = strings.Trim(val, " "); val == "." {
		return val, nil
	}
	return validateDomain(val)
}

func validateDomain(val string) (string, error) {
	if alphaRegexp.FindString(val) == "" {
		return "", fmt.Errorf("%s is not a valid domain", val)
	}
	ns := domainRegexp.FindSubmatch([]byte(val))
	if len(ns) > 0 && len(ns[1]) < 255 {
		return string(ns[1]), nil
	}
	return "", fmt.Errorf("%s is not a valid domain", val)
}

// ValidateLabel validates that the specified string is a valid label, and returns it.
// Labels are in the form on key=value.
func ValidateLabel(val string) (string, error) {
	if strings.Count(val, "=") < 1 {
		return "", fmt.Errorf("bad attribute format: %s", val)
	}
	return val, nil
}

// ValidateSysctl validates a sysctl and returns it.
func ValidateSysctl(val string) (string, error) {
	validSysctlMap := map[string]bool{
		"kernel.msgmax":          true,
		"kernel.msgmnb":          true,
		"kernel.msgmni":          true,
		"kernel.sem":             true,
		"kernel.shmall":          true,
		"kernel.shmmax":          true,
		"kernel.shmmni":          true,
		"kernel.shm_rmid_forced": true,
	}
	validSysctlPrefixes := []string{
		"net.",
		"fs.mqueue.",
	}
	arr := strings.Split(val, "=")
	if len(arr) < 2 {
		return "", fmt.Errorf("sysctl '%s' is not whitelisted", val)
	}
	if validSysctlMap[arr[0]] {
		return val, nil
	}

	for _, vp := range validSysctlPrefixes {
		if strings.HasPrefix(arr[0], vp) {
			return val, nil
		}
	}
	return "", fmt.Errorf("sysctl '%s' is not whitelisted", val)
}

// FilterOpt is a flag type for validating filters
type FilterOpt struct {
	filter filters.Args
}

// NewFilterOpt returns a new FilterOpt
func NewFilterOpt() FilterOpt {
	return FilterOpt{filter: filters.NewArgs()}
}

func (o *FilterOpt) String() string {
	repr, err := filters.ToParam(o.filter)
	if err != nil {
		return "invalid filters"
	}
	return repr
}

// Set sets the value of the opt by parsing the command line value
func (o *FilterOpt) Set(value string) error {
	var err error
	o.filter, err = filters.ParseFlag(value, o.filter)
	return err
}

// Type returns the option type
func (o *FilterOpt) Type() string {
	return "filter"
}

// Value returns the value of this option
func (o *FilterOpt) Value() filters.Args {
	return o.filter
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"time"

	"github.com/google/go-github/github"
)

type Contribution struct {
	Date time.Time
	Num  int
}

const dateFormat string = "2006-01-02"

func (c *Contribution) UnmarshalJSON(data []byte) error {
	var i []interface{}
	err := json.Unmarshal(data, &i)
	if err != nil {
		return err
	}

	if v, ok := i[0].(string); ok {
		c.Date, err = time.Parse(dateFormat, v)
	}
	if err != nil {
		return err
	}

	if v, ok := i[1].(float64); ok {
		c.Num = int(v)
	}

	return nil
}

func getContributions(user github.User) []Contribution {
	login := github.Stringify(user.Login)
	url := "https://github.com/users/" + login[1:len(login)-1] + "/contributions.json"
	var contribData []Contribution

	resp, err := http.Get(url)
	defer resp.Body.Close()
	if err != nil {
		log.Fatal(err)
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	if data == nil {
		log.Fatalln("No data returned.")
	}

	err = json.Unmarshal(data, &contribData)
	if err != nil {
		log.Fatal(err)
	}

	return contribData
}

func getOrgMembers(orgName string) []github.User {
	client := github.NewClient(nil)

	users, _, err := client.Organizations.ListMembers(orgName, nil)
	if err != nil {
		log.Fatal(err)
	}

	return users
}

func main() {
	flag.Parse()
	var i interface{} = flag.Arg(0)
	var users []github.User

	var v, ok = i.(string)
	if ok == false || v == "" {
		log.Fatalln("Usage: orgstreak <orgName>")
	} else {
		users = getOrgMembers(v)
	}

	orgContribs := make(map[time.Time]int)
	userContributions := make(chan []Contribution, len(users))

	for _, user := range users {
		go func(u github.User) {
			userContributions <- getContributions(u)
		}(user)
	}

	for y := 0; y < len(users); y++ {
		select {
		case userContribution := <-userContributions:
			for _, contrib := range userContribution {
				orgContribs[contrib.Date] += contrib.Num
			}
		}
	}

	contribData := []interface{}{}
	for k, v := range orgContribs {
		contribData = append(contribData, []interface{}{k.Format(dateFormat), v})
	}
	j, err := json.Marshal(contribData)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", j)
}
<commit_msg>dont need timestamp in my usage string<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"

	"github.com/google/go-github/github"
)

type Contribution struct {
	Date time.Time
	Num  int
}

const dateFormat string = "2006-01-02"

func (c *Contribution) UnmarshalJSON(data []byte) error {
	var i []interface{}
	err := json.Unmarshal(data, &i)
	if err != nil {
		return err
	}

	if v, ok := i[0].(string); ok {
		c.Date, err = time.Parse(dateFormat, v)
	}
	if err != nil {
		return err
	}

	if v, ok := i[1].(float64); ok {
		c.Num = int(v)
	}

	return nil
}

func getContributions(user github.User) []Contribution {
	login := github.Stringify(user.Login)
	url := "https://github.com/users/" + login[1:len(login)-1] + "/contributions.json"
	var contribData []Contribution

	resp, err := http.Get(url)
	defer resp.Body.Close()
	if err != nil {
		log.Fatal(err)
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	if data == nil {
		log.Fatalln("No data returned.")
	}

	err = json.Unmarshal(data, &contribData)
	if err != nil {
		log.Fatal(err)
	}

	return contribData
}

func getOrgMembers(orgName string) []github.User {
	client := github.NewClient(nil)

	users, _, err := client.Organizations.ListMembers(orgName, nil)
	if err != nil {
		log.Fatal(err)
	}

	return users
}

func main() {
	flag.Parse()
	var i interface{} = flag.Arg(0)
	var users []github.User

	var v, ok = i.(string)
	if ok == false || v == "" {
		fmt.Println("Usage: orgstreak <orgName>")
		os.Exit(1)
	} else {
		users = getOrgMembers(v)
	}

	orgContribs := make(map[time.Time]int)
	userContributions := make(chan []Contribution, len(users))

	for _, user := range users {
		go func(u github.User) {
			userContributions <- getContributions(u)
		}(user)
	}

	for y := 0; y < len(users); y++ {
		select {
		case userContribution := <-userContributions:
			for _, contrib := range userContribution {
				orgContribs[contrib.Date] += contrib.Num
			}
		}
	}

	contribData := []interface{}{}
	for k, v := range orgContribs {
		contribData = append(contribData, []interface{}{k.Format(dateFormat), v})
	}
	j, err := json.Marshal(contribData)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", j)
}
<|endoftext|>


<commit_before>package orm

import (
	"database/sql"
	"time"
)

// Specify struct name that respect gorm's conventions, for tables that does not

type PostsNoNotify struct {
	User int64
	Hpid int64
	Time time.Time
}

func (x PostsNoNotify) TableName() string {
	return "posts_no_notify"
}

type CommentsNoNotify struct {
	From int64
	To   int64
	Hpid int64
	Time time.Time
}

func (x CommentsNoNotify) TableName() string {
	return "comments_no_notify"
}

type CommentsNotify struct {
	From int64
	To   int64
	Hpid int64
	Time time.Time
}

func (x CommentsNotify) TableName() string {
	return "comments_notify"
}

type Ban struct {
	User       int64
	Motivation string
}

func (x Ban) TableName() string {
	return "ban"
}

type Blacklist struct {
	From       int64
	To         int64
	Motivation string
}

func (x Blacklist) TableName() string {
	return "blacklist"
}

type Whitelist struct {
	From int64
	To   int64
}

func (x Whitelist) TableName() string {
	return "whitelist"
}

type Follow struct {
	From     int64
	To       int64
	Time     time.Time
	Notified bool
}

func (x Follow) TableName() string {
	return "follow"
}

type ProjectNotify struct {
	Group int64
	To    int64
	Time  time.Time
}

func (x ProjectNotify) TableName() string {
	return "groups_notify"
}

type ProjectPostsNoNotify struct {
	User int64
	Hpid int64
	Time time.Time
}

func (x ProjectPostsNoNotify) TableName() string {
	return "groups_posts_no_notify"
}

type ProjectCommentsNoNotify struct {
	From int64
	To   int64
	Hpid int64
	Time time.Time
}

func (x ProjectCommentsNoNotify) TableName() string {
	return "groups_comments_no_notify"
}

type ProjectCommentsNotify struct {
	From int64
	To   int64
	Hpid int64
	Time time.Time
}

func (x ProjectCommentsNotify) TableName() string {
	return "groups_comments_notify"
}

// Begin structures with table name that respect conventions
// In this cas we don't need to map struct with table manually with TableName

type User struct {
	Counter     int64 `primaryKey:"yes"`
	Last        time.Time
	NotifyStory string `sql:"type:json"`
	Private     bool
	Lang        sql.NullString `sql:"type:varchar(2)"`
	Username    string         `sql:"type:varchar(90)"`
	// Field commented out, to avoid the  possibility to fetch and show the password field
	//	Password    string         `sql:"type:varchar(40)"`
	Name       string `sql:"type:varchar(60)"`
	Surname    string `sql:"tyoe:varchar(60)"`
	Email      string `sql:"type:varchar(350)"`
	Gender     bool
	BirthDate  time.Time
	BoardLang  sql.NullString `sql:"type:varchar(2)"`
	Timezone   string         `sql:"type:varchar(35)"`
	Viewonline bool
	// User struct references Profile with a 1:1 relation
	Profile Profile
}

type Profile struct {
	Counter int64 `primaryKey:"yes"`
	// Field commented out, to avoid the  possibility to fetch and show the IP Address and User Agent field
	//	RemoteAddr     string `sql:"type:inet"`
	//	HttpUserAgent  string `sql:"type:text"`
	Website        string `sql:"type:varchar(350)"`
	Quotes         string `sql:"type:text"`
	Biography      string `sql:"type:text"`
	Interests      string `sql:"type:text"`
	Github         string `sql:"type:varchar(350)"`
	Skype          string `sql:"type:varchar(350)"`
	Jabber         string `sql:"type:varchar(350)"`
	Yahoo          string `sql:"type:varchar(350)"`
	Userscript     string `sql:"type:varchar(128)"`
	Template       int16
	MobileTemplate int16
	Dateformat     string `sql:"type:varchar(25)"`
	Facebook       string `sql:"type:varchar(350)"`
	Twitter        string `sql:"type:varchar(350)"`
	Steam          string `sql:"type:varchar(350)"`
	Push           bool
	Pushregtime    time.Time
}

type ClosedProfile struct {
	Counter int64 `primaryKey:"yes"`
}

type Post struct {
	Hpid    int64 `primaryKey:"yes"`
	From    int64
	To      int64
	Pid     int64
	Message string `sql:"type:text"`
	Notify  bool
	Time    time.Time
}

type PostThumb struct {
	Hpid int64
	User int64
	Vote int16
}

func (x PostThumb) TableName() string {
	return "thumbs"
}

type Lurker struct {
	User int64
	Post int64
	Time time.Time
}

type Comment struct {
	Hcid    int64 `primaryKey:"yes"`
	Hpid    int64
	From    int64
	To      int64
	Message string `sql:"type:text"`
	Time    time.Time
}

type Bookmark struct {
	Hpid int64
	From int64
	Time time.Time
}

type Pm struct {
	Pmid    int64 `primaryKey:"yes"`
	From    int64
	To      int64
	Pid     int64
	Message string `sql:"type:text"`
	Read    bool
	Time    time.Time
}

type Project struct {
	Counter     int64  `primaryKey:"yes"`
	Description string `sql:"type:text"`
	Owner       int64
	Name        string `sql:"type:varchar(30)"`
	Private     bool
	Photo       sql.NullString `sql:"type:varchar(350)"`
	Website     string         `sql:"type:varchar(350)"`
	Goal        string         `sql:"type:text"`
	Visible     bool
	Open        bool
}

func (x Project) TableName() string {
	return "groups"
}

type ProjectMember struct {
	Group int64
	User  int64
}

func (x ProjectMember) TableName() string {
	return "groups_members"
}

type ProjectPost struct {
	Hpid    int64 `primaryKey:"yes"`
	From    int64
	To      int64
	Pid     int64
	Message string `sql:"type:text"`
	News    bool
	Time    time.Time
}

func (x ProjectPost) TableName() string {
	return "groups_posts"
}

type ProjectPostThumb struct {
	Hpid int64
	User int64
	Vote int16
}

func (x ProjectPostThumb) TableName() string {
	return "groups_thumb"
}

type ProjectPostLurker struct {
	User int64
	Post int64
	Time time.Time
}

func (x ProjectPostLurker) TableName() string {
	return "groups_lurkers"
}

type ProjectComment struct {
	Hcid    int64 `primaryKey:"yes"`
	Hpid    int64
	From    int64
	To      int64
	Message string `sql:"type:text"`
	Time    time.Time
}

func (x ProjectComment) TableName() string {
	return "groups_comments"
}

type ProjectBookmark struct {
	Hpid int64
	From int64
	Time time.Time
}

func (x ProjectBookmark) TableName() string {
	return "groups_bookmarks"
}

type ProjectFollower struct {
	Group int64
	User  int64
}

func (x ProjectFollower) TableName() string {
	return "groups_followers"
}

type CommentThumb struct {
	Hcid int64
	User int64
	Vote int16
}

type ProjectCommentThumb struct {
	Hcid int64
	User int64
	Vote int16
}

func (x ProjectCommentThumb) TableName() string {
	return "groups_comment_thumbs"
}
<commit_msg>Fix typo<commit_after>package orm

import (
	"database/sql"
	"time"
)

// Specify struct name that respect gorm's conventions, for tables that does not

type PostsNoNotify struct {
	User int64
	Hpid int64
	Time time.Time
}

func (x PostsNoNotify) TableName() string {
	return "posts_no_notify"
}

type CommentsNoNotify struct {
	From int64
	To   int64
	Hpid int64
	Time time.Time
}

func (x CommentsNoNotify) TableName() string {
	return "comments_no_notify"
}

type CommentsNotify struct {
	From int64
	To   int64
	Hpid int64
	Time time.Time
}

func (x CommentsNotify) TableName() string {
	return "comments_notify"
}

type Ban struct {
	User       int64
	Motivation string
}

func (x Ban) TableName() string {
	return "ban"
}

type Blacklist struct {
	From       int64
	To         int64
	Motivation string
}

func (x Blacklist) TableName() string {
	return "blacklist"
}

type Whitelist struct {
	From int64
	To   int64
}

func (x Whitelist) TableName() string {
	return "whitelist"
}

type Follow struct {
	From     int64
	To       int64
	Time     time.Time
	Notified bool
}

func (x Follow) TableName() string {
	return "follow"
}

type ProjectNotify struct {
	Group int64
	To    int64
	Time  time.Time
}

func (x ProjectNotify) TableName() string {
	return "groups_notify"
}

type ProjectPostsNoNotify struct {
	User int64
	Hpid int64
	Time time.Time
}

func (x ProjectPostsNoNotify) TableName() string {
	return "groups_posts_no_notify"
}

type ProjectCommentsNoNotify struct {
	From int64
	To   int64
	Hpid int64
	Time time.Time
}

func (x ProjectCommentsNoNotify) TableName() string {
	return "groups_comments_no_notify"
}

type ProjectCommentsNotify struct {
	From int64
	To   int64
	Hpid int64
	Time time.Time
}

func (x ProjectCommentsNotify) TableName() string {
	return "groups_comments_notify"
}

// Begin structures with table name that respect conventions
// In this cas we don't need to map struct with table manually with TableName

type User struct {
	Counter     int64 `primaryKey:"yes"`
	Last        time.Time
	NotifyStory string `sql:"type:json"`
	Private     bool
	Lang        sql.NullString `sql:"type:varchar(2)"`
	Username    string         `sql:"type:varchar(90)"`
	// Field commented out, to avoid the  possibility to fetch and show the password field
	//	Password    string         `sql:"type:varchar(40)"`
	Name       string `sql:"type:varchar(60)"`
	Surname    string `sql:"tyoe:varchar(60)"`
	Email      string `sql:"type:varchar(350)"`
	Gender     bool
	BirthDate  time.Time
	BoardLang  sql.NullString `sql:"type:varchar(2)"`
	Timezone   string         `sql:"type:varchar(35)"`
	Viewonline bool
	// User struct references Profile with a 1:1 relation
	Profile Profile
}

type Profile struct {
	Counter int64 `primaryKey:"yes"`
	// Field commented out, to avoid the  possibility to fetch and show the IP Address and User Agent field
	//	RemoteAddr     string `sql:"type:inet"`
	//	HttpUserAgent  string `sql:"type:text"`
	Website        string `sql:"type:varchar(350)"`
	Quotes         string `sql:"type:text"`
	Biography      string `sql:"type:text"`
	Interests      string `sql:"type:text"`
	Github         string `sql:"type:varchar(350)"`
	Skype          string `sql:"type:varchar(350)"`
	Jabber         string `sql:"type:varchar(350)"`
	Yahoo          string `sql:"type:varchar(350)"`
	Userscript     string `sql:"type:varchar(128)"`
	Template       int16
	MobileTemplate int16
	Dateformat     string `sql:"type:varchar(25)"`
	Facebook       string `sql:"type:varchar(350)"`
	Twitter        string `sql:"type:varchar(350)"`
	Steam          string `sql:"type:varchar(350)"`
	Push           bool
	Pushregtime    time.Time
}

type ClosedProfile struct {
	Counter int64 `primaryKey:"yes"`
}

type Post struct {
	Hpid    int64 `primaryKey:"yes"`
	From    int64
	To      int64
	Pid     int64
	Message string `sql:"type:text"`
	Notify  bool
	Time    time.Time
}

type PostThumb struct {
	Hpid int64
	User int64
	Vote int16
}

func (x PostThumb) TableName() string {
	return "thumbs"
}

type Lurker struct {
	User int64
	Post int64
	Time time.Time
}

type Comment struct {
	Hcid    int64 `primaryKey:"yes"`
	Hpid    int64
	From    int64
	To      int64
	Message string `sql:"type:text"`
	Time    time.Time
}

type Bookmark struct {
	Hpid int64
	From int64
	Time time.Time
}

type Pm struct {
	Pmid    int64 `primaryKey:"yes"`
	From    int64
	To      int64
	Pid     int64
	Message string `sql:"type:text"`
	Read    bool
	Time    time.Time
}

type Project struct {
	Counter     int64  `primaryKey:"yes"`
	Description string `sql:"type:text"`
	Owner       int64
	Name        string `sql:"type:varchar(30)"`
	Private     bool
	Photo       sql.NullString `sql:"type:varchar(350)"`
	Website     string         `sql:"type:varchar(350)"`
	Goal        string         `sql:"type:text"`
	Visible     bool
	Open        bool
}

func (x Project) TableName() string {
	return "groups"
}

type ProjectMember struct {
	Group int64
	User  int64
}

func (x ProjectMember) TableName() string {
	return "groups_members"
}

type ProjectPost struct {
	Hpid    int64 `primaryKey:"yes"`
	From    int64
	To      int64
	Pid     int64
	Message string `sql:"type:text"`
	News    bool
	Time    time.Time
}

func (x ProjectPost) TableName() string {
	return "groups_posts"
}

type ProjectPostThumb struct {
	Hpid int64
	User int64
	Vote int16
}

func (x ProjectPostThumb) TableName() string {
	return "groups_thumbs"
}

type ProjectPostLurker struct {
	User int64
	Post int64
	Time time.Time
}

func (x ProjectPostLurker) TableName() string {
	return "groups_lurkers"
}

type ProjectComment struct {
	Hcid    int64 `primaryKey:"yes"`
	Hpid    int64
	From    int64
	To      int64
	Message string `sql:"type:text"`
	Time    time.Time
}

func (x ProjectComment) TableName() string {
	return "groups_comments"
}

type ProjectBookmark struct {
	Hpid int64
	From int64
	Time time.Time
}

func (x ProjectBookmark) TableName() string {
	return "groups_bookmarks"
}

type ProjectFollower struct {
	Group int64
	User  int64
}

func (x ProjectFollower) TableName() string {
	return "groups_followers"
}

type CommentThumb struct {
	Hcid int64
	User int64
	Vote int16
}

type ProjectCommentThumb struct {
	Hcid int64
	User int64
	Vote int16
}

func (x ProjectCommentThumb) TableName() string {
	return "groups_comment_thumbs"
}
<|endoftext|>


<commit_before>package a

import (
	"flag"
	"github.com/miekg/dns"
	"github.com/zmap/zdns"
	"strings"
)

// result to be returned by scan of host
type Result struct {
	Addresses []string `json:"addresses"`
}

// Per Connection Lookup ======================================================
//
type Lookup struct {
	Factory *RoutineLookupFactory
}

func dotName(name string) string {
	return strings.Join([]string{name, "."}, "")
}

func (s *Lookup) DoLookup(name string) (interface{}, zdns.Status, error) {
	// get a name server to use for this connection
	nameServer := s.Factory.Factory.RandomNameServer()
	// this is where we do scanning
	res := Result{Addresses: []string{}}

	m := new(dns.Msg)
	m.SetQuestion(dotName(name), dns.TypeA)
	m.RecursionDesired = true

	r, _, err := s.Factory.Client.Exchange(m, nameServer)
	if err != nil {
		return nil, zdns.STATUS_ERROR, err
	}
	if r.Rcode != dns.RcodeSuccess {
		return nil, zdns.STATUS_BAD_RCODE, nil
	}
	for _, ans := range r.Answer {
		if a, ok := ans.(*dns.A); ok {
			res.Addresses = append(res.Addresses, a.A.String())
		}
	}
	return &res, zdns.STATUS_SUCCESS, nil
}

// Per GoRoutine Factory ======================================================
//
type RoutineLookupFactory struct {
	Factory *GlobalLookupFactory
	Client  *dns.Client
}

func (s *RoutineLookupFactory) MakeLookup() (zdns.Lookup, error) {
	a := Lookup{Factory: s}
	return &a, nil
}

// Global Factory =============================================================
//
type GlobalLookupFactory struct {
	zdns.BaseGlobalLookupFactory
}

func (s *GlobalLookupFactory) AddFlags(f *flag.FlagSet) {
	//f.IntVar(&s.Timeout, "timeout", 0, "")
}

// Command-line Help Documentation. This is the descriptive text what is
// returned when you run zdns module --help
func (s *GlobalLookupFactory) Help() string {
	return ""
}

func (s *GlobalLookupFactory) MakeRoutineFactory() (zdns.RoutineLookupFactory, error) {
	c := new(dns.Client)
	r := RoutineLookupFactory{Factory: s, Client: c}
	return &r, nil
}

// Global Registration ========================================================
//
func init() {
	var s GlobalLookupFactory
	zdns.RegisterLookup("a", &s)
}
<commit_msg>a bit more rational semantics<commit_after>package a

import (
	"flag"
	"github.com/miekg/dns"
	"github.com/zmap/zdns"
	"strings"
)

// result to be returned by scan of host
type Result struct {
	Addresses []string `json:"addresses"`
}

// Per Connection Lookup ======================================================
//
type Lookup struct {
	Factory *RoutineLookupFactory
}

func dotName(name string) string {
	return strings.Join([]string{name, "."}, "")
}

func (s *Lookup) DoLookup(name string) (interface{}, zdns.Status, error) {
	// get a name server to use for this connection
	nameServer := s.Factory.Factory.RandomNameServer()
	// this is where we do scanning
	res := Result{Addresses: []string{}}

	m := new(dns.Msg)
	m.SetQuestion(dotName(name), dns.TypeA)
	m.RecursionDesired = true

	r, _, err := s.Factory.Client.Exchange(m, nameServer)
	if err != nil {
		return nil, zdns.STATUS_ERROR, err
	}
	if r.Rcode != dns.RcodeSuccess {
		return nil, zdns.STATUS_BAD_RCODE, nil
	}
	for _, ans := range r.Answer {
		if a, ok := ans.(*dns.A); ok {
			res.Addresses = append(res.Addresses, a.A.String())
		}
	}
	return &res, zdns.STATUS_SUCCESS, nil
}

// Per GoRoutine Factory ======================================================
//
type RoutineLookupFactory struct {
	Factory *GlobalLookupFactory
	Client  *dns.Client
}

func (s *RoutineLookupFactory) Initialize(f *GlobalLookupFactory) {
	s.Factory = f
	s.Client = new(dns.Client)
}

func (s *RoutineLookupFactory) MakeLookup() (zdns.Lookup, error) {
	a := Lookup{Factory: s}
	return &a, nil
}

// Global Factory =============================================================
//
type GlobalLookupFactory struct {
	zdns.BaseGlobalLookupFactory
}

func (s *GlobalLookupFactory) AddFlags(f *flag.FlagSet) {
	//f.IntVar(&s.Timeout, "timeout", 0, "")
}

// Command-line Help Documentation. This is the descriptive text what is
// returned when you run zdns module --help
func (s *GlobalLookupFactory) Help() string {
	return ""
}

func (s *GlobalLookupFactory) MakeRoutineFactory() (zdns.RoutineLookupFactory, error) {
	r := new(RoutineLookupFactory)
	r.Initialize(s)
	return r, nil
}

// Global Registration ========================================================
//
func init() {
	s := new(GlobalLookupFactory)
	zdns.RegisterLookup("a", s)
}
<|endoftext|>