<commit_before>/**
 * Warning: Generated code! do not change!
 * Generated by: go/AppCtx.ftl
 */
package impl

import (
	"encoding/json"
	"net/http"

	"github.com/quintans/goSQL/db"
	"github.com/quintans/maze"
	"github.com/quintans/taskboard/go/service"
)

func NewAppCtx(
	w http.ResponseWriter,
	r *http.Request,
	filters []*maze.Filter,
	taskBoardService service.ITaskBoardService,
) *AppCtx {
	var this = new(AppCtx)
	this.Context = maze.NewContext(w, r, filters)
	this.taskBoardService = taskBoardService
	return this
}

var _ maze.IContext = &AppCtx{}

type AppCtx struct {
	*maze.Context

	Principal        *Principal
	Store            db.IDb
	taskBoardService service.ITaskBoardService
}

func (this *AppCtx) Proceed() error {
	return this.Next(this.GetRequest())(this)
}

func (this *AppCtx) GetTaskBoardService() service.ITaskBoardService {
	return this.taskBoardService
}

func (this *AppCtx) SetTaskBoardService(taskBoardService service.ITaskBoardService) {
	this.taskBoardService = taskBoardService
}

func (this *AppCtx) BuildJsonRpcTaskBoardService(transaction func(ctx maze.IContext) error) *maze.JsonRpc {
	// JSON-RPC services
	var rpc = maze.NewJsonRpc(this.taskBoardService, transaction) // json-rpc builder
	rpc.SetActionFilters("WhoAmI", authorize("USER"))
	rpc.SetActionFilters("FetchBoardUsers", authorize("USER"))
	rpc.SetActionFilters("FetchBoardAllUsers", authorize("ADMIN"))
	rpc.SetActionFilters("FetchBoards", authorize("USER"))
	rpc.SetActionFilters("FetchBoardById", authorize("USER"))
	rpc.SetActionFilters("FullyLoadBoardById", authorize("USER"))
	rpc.SetActionFilters("SaveBoard", authorize("ADMIN"))
	rpc.SetActionFilters("DeleteBoard", authorize("ADMIN"))
	rpc.SetActionFilters("AddLane", authorize("ADMIN"))
	rpc.SetActionFilters("SaveLane", authorize("ADMIN"))
	rpc.SetActionFilters("DeleteLastLane", authorize("ADMIN"))
	rpc.SetActionFilters("SaveUser", authorize("ADMIN"))
	rpc.SetActionFilters("FetchUsers", authorize("ADMIN"))
	rpc.SetActionFilters("DeleteUser", authorize("ADMIN"))
	rpc.SetActionFilters("AddUserToBoard", authorize("ADMIN"))
	rpc.SetActionFilters("RemoveUserFromBoard", authorize("ADMIN"))
	rpc.SetActionFilters("SaveUserName", authorize("USER"))
	rpc.SetActionFilters("ChangeUserPassword", authorize("USER"))
	rpc.SetActionFilters("SaveTask", authorize("USER"))
	rpc.SetActionFilters("MoveTask", authorize("USER"))
	rpc.SetActionFilters("FetchNotifications", authorize("USER"))
	rpc.SetActionFilters("SaveNotification", authorize("USER"))
	rpc.SetActionFilters("DeleteNotification", authorize("USER"))
	return rpc
}

func (this *AppCtx) Reply(value interface{}) error {
	// JSON Vulnerability Protection.
	// AngularJS will automatically strip the prefix before processing it as JSON.
	result, err := json.Marshal(value)
	if err != nil {
		return err
	}
	if _, err = this.Response.Write([]byte(")]}',\n")); err != nil {
		return err
	}
	_, err = this.Response.Write(result)
	return err
}

func authorize(roles ...string) func(ctx maze.IContext) error {
	return func(ctx maze.IContext) error {
		user := ctx.(*AppCtx).Principal
		for _, r := range roles {
			for _, role := range user.Roles {
				if r == string(role) {
					if err := ctx.Proceed(); err != nil {
						return err
					}
					return nil
				}
			}
		}
		http.Error(ctx.GetResponse(), "Unauthorized", http.StatusUnauthorized)
		return nil
	}
}
<commit_msg>simplified Proceed()<commit_after>/**
 * Warning: Generated code! do not change!
 * Generated by: go/AppCtx.ftl
 */
package impl

import (
	"encoding/json"
	"net/http"

	"github.com/quintans/goSQL/db"
	"github.com/quintans/maze"
	"github.com/quintans/taskboard/go/service"
)

func NewAppCtx(
	w http.ResponseWriter,
	r *http.Request,
	filters []*maze.Filter,
	taskBoardService service.ITaskBoardService,
) *AppCtx {
	var this = new(AppCtx)
	this.Context = maze.NewContext(w, r, filters)
	this.taskBoardService = taskBoardService
	return this
}

var _ maze.IContext = &AppCtx{}

type AppCtx struct {
	*maze.Context

	Principal        *Principal
	Store            db.IDb
	taskBoardService service.ITaskBoardService
}

func (this *AppCtx) Proceed() error {
	return this.Next(this)
}

func (this *AppCtx) GetTaskBoardService() service.ITaskBoardService {
	return this.taskBoardService
}

func (this *AppCtx) SetTaskBoardService(taskBoardService service.ITaskBoardService) {
	this.taskBoardService = taskBoardService
}

func (this *AppCtx) BuildJsonRpcTaskBoardService(transaction func(ctx maze.IContext) error) *maze.JsonRpc {
	// JSON-RPC services
	var rpc = maze.NewJsonRpc(this.taskBoardService, transaction) // json-rpc builder
	rpc.SetActionFilters("WhoAmI", authorize("USER"))
	rpc.SetActionFilters("FetchBoardUsers", authorize("USER"))
	rpc.SetActionFilters("FetchBoardAllUsers", authorize("ADMIN"))
	rpc.SetActionFilters("FetchBoards", authorize("USER"))
	rpc.SetActionFilters("FetchBoardById", authorize("USER"))
	rpc.SetActionFilters("FullyLoadBoardById", authorize("USER"))
	rpc.SetActionFilters("SaveBoard", authorize("ADMIN"))
	rpc.SetActionFilters("DeleteBoard", authorize("ADMIN"))
	rpc.SetActionFilters("AddLane", authorize("ADMIN"))
	rpc.SetActionFilters("SaveLane", authorize("ADMIN"))
	rpc.SetActionFilters("DeleteLastLane", authorize("ADMIN"))
	rpc.SetActionFilters("SaveUser", authorize("ADMIN"))
	rpc.SetActionFilters("FetchUsers", authorize("ADMIN"))
	rpc.SetActionFilters("DeleteUser", authorize("ADMIN"))
	rpc.SetActionFilters("AddUserToBoard", authorize("ADMIN"))
	rpc.SetActionFilters("RemoveUserFromBoard", authorize("ADMIN"))
	rpc.SetActionFilters("SaveUserName", authorize("USER"))
	rpc.SetActionFilters("ChangeUserPassword", authorize("USER"))
	rpc.SetActionFilters("SaveTask", authorize("USER"))
	rpc.SetActionFilters("MoveTask", authorize("USER"))
	rpc.SetActionFilters("FetchNotifications", authorize("USER"))
	rpc.SetActionFilters("SaveNotification", authorize("USER"))
	rpc.SetActionFilters("DeleteNotification", authorize("USER"))
	return rpc
}

func (this *AppCtx) Reply(value interface{}) error {
	// JSON Vulnerability Protection.
	// AngularJS will automatically strip the prefix before processing it as JSON.
	result, err := json.Marshal(value)
	if err != nil {
		return err
	}
	if _, err = this.Response.Write([]byte(")]}',\n")); err != nil {
		return err
	}
	_, err = this.Response.Write(result)
	return err
}

func authorize(roles ...string) func(ctx maze.IContext) error {
	return func(ctx maze.IContext) error {
		user := ctx.(*AppCtx).Principal
		for _, r := range roles {
			for _, role := range user.Roles {
				if r == string(role) {
					if err := ctx.Proceed(); err != nil {
						return err
					}
					return nil
				}
			}
		}
		http.Error(ctx.GetResponse(), "Unauthorized", http.StatusUnauthorized)
		return nil
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package libkb

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"os"
	"os/exec"
	"strings"
	"sync"

	"github.com/blang/semver"
)

type GpgCLI struct {
	Contextified
	path    string
	options []string
	version string
	tty     string

	mutex *sync.Mutex

	logUI LogUI
}

func NewGpgCLI(g *GlobalContext, logUI LogUI) *GpgCLI {
	if logUI == nil {
		logUI = g.Log
	}
	return &GpgCLI{
		Contextified: NewContextified(g),
		mutex:        new(sync.Mutex),
		logUI:        logUI,
	}
}

func (g *GpgCLI) SetTTY(t string) {
	g.tty = t
}

func (g *GpgCLI) Configure(mctx MetaContext) (err error) {

	g.mutex.Lock()
	defer g.mutex.Unlock()

	prog := g.G().Env.GetGpg()
	opts := g.G().Env.GetGpgOptions()

	if len(prog) > 0 {
		err = canExec(prog)
	} else {
		prog, err = exec.LookPath("gpg2")
		if err != nil {
			prog, err = exec.LookPath("gpg")
		}
	}
	if err != nil {
		return err
	}

	mctx.Debug("| configured GPG w/ path: %s", prog)

	g.path = prog
	g.options = opts

	return
}

// CanExec returns true if a gpg executable exists.
func (g *GpgCLI) CanExec(mctx MetaContext) (bool, error) {
	err := g.Configure(mctx)
	if IsExecError(err) {
		return false, nil
	}
	if err != nil {
		return false, err
	}
	return true, nil
}

// Path returns the path of the gpg executable.
// Path is only available if CanExec() is true.
func (g *GpgCLI) Path(mctx MetaContext) string {
	canExec, err := g.CanExec(mctx)
	if err == nil && canExec {
		return g.path
	}
	return ""
}

func (g *GpgCLI) ImportKeyArmored(mctx MetaContext, secret bool, fp PGPFingerprint, tty string) (string, error) {
	g.outputVersion(mctx)
	var cmd string
	var which string
	if secret {
		cmd = "--export-secret-key"
		which = "secret "
	} else {
		cmd = "--export"
	}

	arg := RunGpg2Arg{
		Arguments: []string{"--armor", cmd, fp.String()},
		Stdout:    true,
		TTY:       tty,
	}

	res := g.Run2(mctx, arg)
	if res.Err != nil {
		return "", res.Err
	}

	buf := new(bytes.Buffer)
	_, err := buf.ReadFrom(res.Stdout)
	if err != nil {
		return "", err
	}
	armored := buf.String()

	// Convert to posix style on windows
	armored = PosixLineEndings(armored)

	if err := res.Wait(); err != nil {
		return "", err
	}

	if len(armored) == 0 {
		return "", NoKeyError{fmt.Sprintf("No %skey found for fingerprint %s", which, fp)}
	}

	return armored, nil
}

func (g *GpgCLI) ImportKey(mctx MetaContext, secret bool, fp PGPFingerprint, tty string) (*PGPKeyBundle, error) {

	armored, err := g.ImportKeyArmored(mctx, secret, fp, tty)
	if err != nil {
		return nil, err
	}

	bundle, w, err := ReadOneKeyFromString(armored)
	w.Warn(g.G())
	if err != nil {
		return nil, err
	}

	// For secret keys, *also* import the key in public mode, and then grab the
	// ArmoredPublicKey from that. That's because the public import goes out of
	// its way to preserve the exact armored string from GPG.
	if secret {
		publicBundle, err := g.ImportKey(mctx, false, fp, tty)
		if err != nil {
			return nil, err
		}
		bundle.ArmoredPublicKey = publicBundle.ArmoredPublicKey

		// It's a bug that gpg --export-secret-keys doesn't grep subkey revocations.
		// No matter, we have both in-memory, so we can copy it over here
		bundle.CopySubkeyRevocations(publicBundle.Entity)
	}

	return bundle, nil
}

func (g *GpgCLI) ExportKeyArmored(mctx MetaContext, s string) (err error) {
	g.outputVersion(mctx)
	arg := RunGpg2Arg{
		Arguments: []string{"--import"},
		Stdin:     true,
	}
	res := g.Run2(mctx, arg)
	if res.Err != nil {
		return res.Err
	}
	_, err = res.Stdin.Write([]byte(s))
	if err != nil {
		return err
	}
	err = res.Stdin.Close()
	if err != nil {
		return err
	}
	err = res.Wait()
	return err
}

func (g *GpgCLI) ExportKey(mctx MetaContext, k PGPKeyBundle, private bool, batch bool) (err error) {
	g.outputVersion(mctx)
	arg := RunGpg2Arg{
		Arguments: []string{"--import"},
		Stdin:     true,
	}

	if batch {
		arg.Arguments = append(arg.Arguments, "--batch")
	}

	res := g.Run2(mctx, arg)
	if res.Err != nil {
		return res.Err
	}

	e1 := k.EncodeToStream(res.Stdin, private)
	e2 := res.Stdin.Close()
	e3 := res.Wait()
	return PickFirstError(e1, e2, e3)
}

func (g *GpgCLI) Sign(mctx MetaContext, fp PGPFingerprint, payload []byte) (string, error) {
	g.outputVersion(mctx)
	arg := RunGpg2Arg{
		Arguments: []string{"--armor", "--sign", "-u", fp.String()},
		Stdout:    true,
		Stdin:     true,
	}

	res := g.Run2(mctx, arg)
	if res.Err != nil {
		return "", res.Err
	}

	_, err := res.Stdin.Write(payload)
	if err != nil {
		return "", err
	}
	res.Stdin.Close()

	buf := new(bytes.Buffer)
	_, err = buf.ReadFrom(res.Stdout)
	if err != nil {
		return "", err
	}
	armored := buf.String()

	// Convert to posix style on windows
	armored = PosixLineEndings(armored)

	if err := res.Wait(); err != nil {
		return "", err
	}

	return armored, nil
}

func (g *GpgCLI) Version() (string, error) {
	if len(g.version) > 0 {
		return g.version, nil
	}

	args := append(g.options, "--version")
	out, err := exec.Command(g.path, args...).Output()
	if err != nil {
		return "", err
	}
	g.version = string(out)
	return g.version, nil
}

func (g *GpgCLI) outputVersion(mctx MetaContext) {
	v, err := g.Version()
	if err != nil {
		mctx.Debug("error getting GPG version: %s", err)
		return
	}
	mctx.Debug("GPG version:\n%s", v)
}

func (g *GpgCLI) SemanticVersion() (*semver.Version, error) {
	out, err := g.Version()
	if err != nil {
		return nil, err
	}
	lines := strings.Split(out, "\n")
	if len(lines) == 0 {
		return nil, errors.New("empty gpg version")
	}
	parts := strings.Fields(lines[0])
	if len(parts) < 3 {
		return nil, fmt.Errorf("unhandled gpg version output %q full: %q", lines[0], lines)
	}
	return semver.New(parts[2])
}

func (g *GpgCLI) VersionAtLeast(s string) (bool, error) {
	min, err := semver.New(s)
	if err != nil {
		return false, err
	}
	cur, err := g.SemanticVersion()
	if err != nil {
		return false, err
	}
	return cur.GTE(*min), nil
}

type RunGpg2Arg struct {
	Arguments []string
	Stdin     bool
	Stderr    bool
	Stdout    bool
	TTY       string
}

type RunGpg2Res struct {
	Stdin  io.WriteCloser
	Stdout io.ReadCloser
	Stderr io.ReadCloser
	Wait   func() error
	Err    error
}

func (g *GpgCLI) Run2(mctx MetaContext, arg RunGpg2Arg) (res RunGpg2Res) {
	if g.path == "" {
		res.Err = errors.New("no gpg path set")
		return
	}

	cmd := g.MakeCmd(mctx, arg.Arguments, arg.TTY)

	if arg.Stdin {
		if res.Stdin, res.Err = cmd.StdinPipe(); res.Err != nil {
			return
		}
	}

	var stdout, stderr io.ReadCloser

	if stdout, res.Err = cmd.StdoutPipe(); res.Err != nil {
		return
	}
	if stderr, res.Err = cmd.StderrPipe(); res.Err != nil {
		return
	}

	if res.Err = cmd.Start(); res.Err != nil {
		return
	}

	waited := false
	out := 0
	ch := make(chan error)
	var fep FirstErrorPicker

	res.Wait = func() error {
		for out > 0 {
			fep.Push(<-ch)
			out--
		}
		if !waited {
			waited = true
			err := cmd.Wait()
			if err != nil {
				fep.Push(ErrorToGpgError(err))
			}
			return fep.Error()
		}
		return nil
	}

	bgmctx := mctx.BackgroundWithLogTags()
	if !arg.Stdout {
		out++
		go func() {
			ch <- DrainPipe(stdout, func(s string) { bgmctx.Debug(s) })
		}()
	} else {
		res.Stdout = stdout
	}

	if !arg.Stderr {
		out++
		go func() {
			ch <- DrainPipe(stderr, func(s string) { bgmctx.Debug(s) })
		}()
	} else {
		res.Stderr = stderr
	}

	return
}

func (g *GpgCLI) MakeCmd(mctx MetaContext, args []string, tty string) *exec.Cmd {
	var nargs []string
	if g.options != nil {
		nargs = make([]string, len(g.options))
		copy(nargs, g.options)
		nargs = append(nargs, args...)
	} else {
		nargs = args
	}
	if g.G().Service {
		nargs = append([]string{"--no-tty"}, nargs...)
	}
	mctx.Debug("| running Gpg: %s %s", g.path, strings.Join(nargs, " "))
	ret := exec.Command(g.path, nargs...)
	if tty == "" {
		tty = g.tty
	}
	if tty != "" {
		ret.Env = append(os.Environ(), "GPG_TTY="+tty)
		mctx.Debug("| setting GPG_TTY=%s", tty)
	} else {
		mctx.Debug("| no tty provided, GPG_TTY will not be changed")
	}
	return ret
}
<commit_msg>gpg always no-auto-check-trustdb (#19278)<commit_after>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package libkb

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"os"
	"os/exec"
	"strings"
	"sync"

	"github.com/blang/semver"
)

type GpgCLI struct {
	Contextified
	path    string
	options []string
	version string
	tty     string

	mutex *sync.Mutex

	logUI LogUI
}

func NewGpgCLI(g *GlobalContext, logUI LogUI) *GpgCLI {
	if logUI == nil {
		logUI = g.Log
	}
	return &GpgCLI{
		Contextified: NewContextified(g),
		mutex:        new(sync.Mutex),
		logUI:        logUI,
	}
}

func (g *GpgCLI) SetTTY(t string) {
	g.tty = t
}

func (g *GpgCLI) Configure(mctx MetaContext) (err error) {

	g.mutex.Lock()
	defer g.mutex.Unlock()

	prog := g.G().Env.GetGpg()
	opts := g.G().Env.GetGpgOptions()

	if len(prog) > 0 {
		err = canExec(prog)
	} else {
		prog, err = exec.LookPath("gpg2")
		if err != nil {
			prog, err = exec.LookPath("gpg")
		}
	}
	if err != nil {
		return err
	}

	mctx.Debug("| configured GPG w/ path: %s", prog)

	g.path = prog
	g.options = opts

	return
}

// CanExec returns true if a gpg executable exists.
func (g *GpgCLI) CanExec(mctx MetaContext) (bool, error) {
	err := g.Configure(mctx)
	if IsExecError(err) {
		return false, nil
	}
	if err != nil {
		return false, err
	}
	return true, nil
}

// Path returns the path of the gpg executable.
// Path is only available if CanExec() is true.
func (g *GpgCLI) Path(mctx MetaContext) string {
	canExec, err := g.CanExec(mctx)
	if err == nil && canExec {
		return g.path
	}
	return ""
}

func (g *GpgCLI) ImportKeyArmored(mctx MetaContext, secret bool, fp PGPFingerprint, tty string) (string, error) {
	g.outputVersion(mctx)
	var cmd string
	var which string
	if secret {
		cmd = "--export-secret-key"
		which = "secret "
	} else {
		cmd = "--export"
	}

	arg := RunGpg2Arg{
		Arguments: []string{"--armor", cmd, fp.String()},
		Stdout:    true,
		TTY:       tty,
	}

	res := g.Run2(mctx, arg)
	if res.Err != nil {
		return "", res.Err
	}

	buf := new(bytes.Buffer)
	_, err := buf.ReadFrom(res.Stdout)
	if err != nil {
		return "", err
	}
	armored := buf.String()

	// Convert to posix style on windows
	armored = PosixLineEndings(armored)

	if err := res.Wait(); err != nil {
		return "", err
	}

	if len(armored) == 0 {
		return "", NoKeyError{fmt.Sprintf("No %skey found for fingerprint %s", which, fp)}
	}

	return armored, nil
}

func (g *GpgCLI) ImportKey(mctx MetaContext, secret bool, fp PGPFingerprint, tty string) (*PGPKeyBundle, error) {

	armored, err := g.ImportKeyArmored(mctx, secret, fp, tty)
	if err != nil {
		return nil, err
	}

	bundle, w, err := ReadOneKeyFromString(armored)
	w.Warn(g.G())
	if err != nil {
		return nil, err
	}

	// For secret keys, *also* import the key in public mode, and then grab the
	// ArmoredPublicKey from that. That's because the public import goes out of
	// its way to preserve the exact armored string from GPG.
	if secret {
		publicBundle, err := g.ImportKey(mctx, false, fp, tty)
		if err != nil {
			return nil, err
		}
		bundle.ArmoredPublicKey = publicBundle.ArmoredPublicKey

		// It's a bug that gpg --export-secret-keys doesn't grep subkey revocations.
		// No matter, we have both in-memory, so we can copy it over here
		bundle.CopySubkeyRevocations(publicBundle.Entity)
	}

	return bundle, nil
}

func (g *GpgCLI) ExportKeyArmored(mctx MetaContext, s string) (err error) {
	g.outputVersion(mctx)
	arg := RunGpg2Arg{
		Arguments: []string{"--import"},
		Stdin:     true,
	}
	res := g.Run2(mctx, arg)
	if res.Err != nil {
		return res.Err
	}
	_, err = res.Stdin.Write([]byte(s))
	if err != nil {
		return err
	}
	err = res.Stdin.Close()
	if err != nil {
		return err
	}
	err = res.Wait()
	return err
}

func (g *GpgCLI) ExportKey(mctx MetaContext, k PGPKeyBundle, private bool, batch bool) (err error) {
	g.outputVersion(mctx)
	arg := RunGpg2Arg{
		Arguments: []string{"--import"},
		Stdin:     true,
	}

	if batch {
		arg.Arguments = append(arg.Arguments, "--batch")
	}

	res := g.Run2(mctx, arg)
	if res.Err != nil {
		return res.Err
	}

	e1 := k.EncodeToStream(res.Stdin, private)
	e2 := res.Stdin.Close()
	e3 := res.Wait()
	return PickFirstError(e1, e2, e3)
}

func (g *GpgCLI) Sign(mctx MetaContext, fp PGPFingerprint, payload []byte) (string, error) {
	g.outputVersion(mctx)
	arg := RunGpg2Arg{
		Arguments: []string{"--armor", "--sign", "-u", fp.String()},
		Stdout:    true,
		Stdin:     true,
	}

	res := g.Run2(mctx, arg)
	if res.Err != nil {
		return "", res.Err
	}

	_, err := res.Stdin.Write(payload)
	if err != nil {
		return "", err
	}
	res.Stdin.Close()

	buf := new(bytes.Buffer)
	_, err = buf.ReadFrom(res.Stdout)
	if err != nil {
		return "", err
	}
	armored := buf.String()

	// Convert to posix style on windows
	armored = PosixLineEndings(armored)

	if err := res.Wait(); err != nil {
		return "", err
	}

	return armored, nil
}

func (g *GpgCLI) Version() (string, error) {
	if len(g.version) > 0 {
		return g.version, nil
	}

	args := append(g.options, "--version")
	out, err := exec.Command(g.path, args...).Output()
	if err != nil {
		return "", err
	}
	g.version = string(out)
	return g.version, nil
}

func (g *GpgCLI) outputVersion(mctx MetaContext) {
	v, err := g.Version()
	if err != nil {
		mctx.Debug("error getting GPG version: %s", err)
		return
	}
	mctx.Debug("GPG version:\n%s", v)
}

func (g *GpgCLI) SemanticVersion() (*semver.Version, error) {
	out, err := g.Version()
	if err != nil {
		return nil, err
	}
	lines := strings.Split(out, "\n")
	if len(lines) == 0 {
		return nil, errors.New("empty gpg version")
	}
	parts := strings.Fields(lines[0])
	if len(parts) < 3 {
		return nil, fmt.Errorf("unhandled gpg version output %q full: %q", lines[0], lines)
	}
	return semver.New(parts[2])
}

func (g *GpgCLI) VersionAtLeast(s string) (bool, error) {
	min, err := semver.New(s)
	if err != nil {
		return false, err
	}
	cur, err := g.SemanticVersion()
	if err != nil {
		return false, err
	}
	return cur.GTE(*min), nil
}

type RunGpg2Arg struct {
	Arguments []string
	Stdin     bool
	Stderr    bool
	Stdout    bool
	TTY       string
}

type RunGpg2Res struct {
	Stdin  io.WriteCloser
	Stdout io.ReadCloser
	Stderr io.ReadCloser
	Wait   func() error
	Err    error
}

func (g *GpgCLI) Run2(mctx MetaContext, arg RunGpg2Arg) (res RunGpg2Res) {
	if g.path == "" {
		res.Err = errors.New("no gpg path set")
		return
	}

	cmd := g.MakeCmd(mctx, arg.Arguments, arg.TTY)

	if arg.Stdin {
		if res.Stdin, res.Err = cmd.StdinPipe(); res.Err != nil {
			return
		}
	}

	var stdout, stderr io.ReadCloser

	if stdout, res.Err = cmd.StdoutPipe(); res.Err != nil {
		return
	}
	if stderr, res.Err = cmd.StderrPipe(); res.Err != nil {
		return
	}

	if res.Err = cmd.Start(); res.Err != nil {
		return
	}

	waited := false
	out := 0
	ch := make(chan error)
	var fep FirstErrorPicker

	res.Wait = func() error {
		for out > 0 {
			fep.Push(<-ch)
			out--
		}
		if !waited {
			waited = true
			err := cmd.Wait()
			if err != nil {
				fep.Push(ErrorToGpgError(err))
			}
			return fep.Error()
		}
		return nil
	}

	bgmctx := mctx.BackgroundWithLogTags()
	if !arg.Stdout {
		out++
		go func() {
			ch <- DrainPipe(stdout, func(s string) { bgmctx.Debug(s) })
		}()
	} else {
		res.Stdout = stdout
	}

	if !arg.Stderr {
		out++
		go func() {
			ch <- DrainPipe(stderr, func(s string) { bgmctx.Debug(s) })
		}()
	} else {
		res.Stderr = stderr
	}

	return
}

func (g *GpgCLI) MakeCmd(mctx MetaContext, args []string, tty string) *exec.Cmd {
	var nargs []string
	if g.options != nil {
		nargs = make([]string, len(g.options))
		copy(nargs, g.options)
		nargs = append(nargs, args...)
	} else {
		nargs = args
	}
	// Always use --no-auto-check-trustdb to prevent gpg from refreshing trustdb.
	// Refreshing the trustdb can cause hangs when bad keys from CVE-2019-13050 are in the keyring.
	// --no-auto-check-trustdb was introduced around gpg 1.0 so ought to always be implemented.
	nargs = append([]string{"--no-auto-check-trustdb"}, nargs...)
	if g.G().Service {
		nargs = append([]string{"--no-tty"}, nargs...)
	}
	mctx.Debug("| running Gpg: %s %s", g.path, strings.Join(nargs, " "))
	ret := exec.Command(g.path, nargs...)
	if tty == "" {
		tty = g.tty
	}
	if tty != "" {
		ret.Env = append(os.Environ(), "GPG_TTY="+tty)
		mctx.Debug("| setting GPG_TTY=%s", tty)
	} else {
		mctx.Debug("| no tty provided, GPG_TTY will not be changed")
	}
	return ret
}
<|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 stats

import (
	"encoding/json"
	"fmt"
	"sync"
	"time"
)

// Timings is meant to tracks timing data
// by named categories as well as histograms.
type Timings struct {
	mu         sync.Mutex
	totalCount int64
	totalTime  int64
	histograms map[string]*Histogram
}

func NewTimings(name string) *Timings {
	t := &Timings{histograms: make(map[string]*Histogram)}
	if name != "" {
		Publish(name, t)
	}
	return t
}

func (t *Timings) Add(name string, elapsed time.Duration) {
	t.mu.Lock()
	defer t.mu.Unlock()

	hist, ok := t.histograms[name]
	if !ok {
		hist = NewGenericHistogram("", bucketCutoffs, bucketLabels, "Count", "Time")
		t.histograms[name] = hist
	}
	elapsedNs := int64(elapsed)
	hist.Add(elapsedNs)
	t.totalCount++
	t.totalTime += elapsedNs
}

// Record is a convenience function that records completion
// timing data based on the provided start time of an event.
func (t *Timings) Record(name string, startTime time.Time) {
	t.Add(name, time.Now().Sub(startTime))
}

func (t *Timings) String() string {
	t.mu.Lock()
	defer t.mu.Unlock()

	tm := struct {
		TotalCount int64
		totalTime  int64
		Histograms map[string]*Histogram
	}{
		t.totalCount,
		t.totalTime,
		t.histograms,
	}
	data, err := json.Marshal(tm)
	if err != nil {
		data, _ = json.Marshal(err.Error())
	}
	return string(data)
}

func (t *Timings) Histograms(h map[string]*Histogram) {
	t.mu.Lock()
	defer t.mu.Unlock()
	h = make(map[string]*Histogram, len(t.histograms))
	for k, v := range t.histograms {
		h[k] = v
	}
	return
}

func (t *Timings) Count() int64 {
	t.mu.Lock()
	defer t.mu.Unlock()
	return t.totalCount
}

func (t *Timings) Time() int64 {
	t.mu.Lock()
	defer t.mu.Unlock()
	return t.totalTime
}

func (t *Timings) Counts() map[string]int64 {
	t.mu.Lock()
	defer t.mu.Unlock()

	counts := make(map[string]int64, len(t.histograms)+1)
	for k, v := range t.histograms {
		counts[k] = v.Count()
	}
	counts["All"] = t.totalCount
	return counts
}

var bucketCutoffs = []int64{0.0005 * 1e9, 0.001 * 1e9, 0.005 * 1e9, 0.010 * 1e9, 0.050 * 1e9, 0.100 * 1e9, 0.500 * 1e9, 1.000 * 1e9, 5.000 * 1e9, 10.00 * 1e9}

var bucketLabels []string

func init() {
	bucketLabels = make([]string, len(bucketCutoffs)+1)
	for i, v := range bucketCutoffs {
		bucketLabels[i] = fmt.Sprintf("%.4f", float64(v)/1e9)
	}
	bucketLabels[len(bucketLabels)-1] = "Max"
}
<commit_msg>bug fix: timings.Histograms signature.<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 stats

import (
	"encoding/json"
	"fmt"
	"sync"
	"time"
)

// Timings is meant to tracks timing data
// by named categories as well as histograms.
type Timings struct {
	mu         sync.Mutex
	totalCount int64
	totalTime  int64
	histograms map[string]*Histogram
}

func NewTimings(name string) *Timings {
	t := &Timings{histograms: make(map[string]*Histogram)}
	if name != "" {
		Publish(name, t)
	}
	return t
}

func (t *Timings) Add(name string, elapsed time.Duration) {
	t.mu.Lock()
	defer t.mu.Unlock()

	hist, ok := t.histograms[name]
	if !ok {
		hist = NewGenericHistogram("", bucketCutoffs, bucketLabels, "Count", "Time")
		t.histograms[name] = hist
	}
	elapsedNs := int64(elapsed)
	hist.Add(elapsedNs)
	t.totalCount++
	t.totalTime += elapsedNs
}

// Record is a convenience function that records completion
// timing data based on the provided start time of an event.
func (t *Timings) Record(name string, startTime time.Time) {
	t.Add(name, time.Now().Sub(startTime))
}

func (t *Timings) String() string {
	t.mu.Lock()
	defer t.mu.Unlock()

	tm := struct {
		TotalCount int64
		totalTime  int64
		Histograms map[string]*Histogram
	}{
		t.totalCount,
		t.totalTime,
		t.histograms,
	}
	data, err := json.Marshal(tm)
	if err != nil {
		data, _ = json.Marshal(err.Error())
	}
	return string(data)
}

func (t *Timings) Histograms() (h map[string]*Histogram) {
	t.mu.Lock()
	defer t.mu.Unlock()
	h = make(map[string]*Histogram, len(t.histograms))
	for k, v := range t.histograms {
		h[k] = v
	}
	return
}

func (t *Timings) Count() int64 {
	t.mu.Lock()
	defer t.mu.Unlock()
	return t.totalCount
}

func (t *Timings) Time() int64 {
	t.mu.Lock()
	defer t.mu.Unlock()
	return t.totalTime
}

func (t *Timings) Counts() map[string]int64 {
	t.mu.Lock()
	defer t.mu.Unlock()

	counts := make(map[string]int64, len(t.histograms)+1)
	for k, v := range t.histograms {
		counts[k] = v.Count()
	}
	counts["All"] = t.totalCount
	return counts
}

var bucketCutoffs = []int64{0.0005 * 1e9, 0.001 * 1e9, 0.005 * 1e9, 0.010 * 1e9, 0.050 * 1e9, 0.100 * 1e9, 0.500 * 1e9, 1.000 * 1e9, 5.000 * 1e9, 10.00 * 1e9}

var bucketLabels []string

func init() {
	bucketLabels = make([]string, len(bucketCutoffs)+1)
	for i, v := range bucketCutoffs {
		bucketLabels[i] = fmt.Sprintf("%.4f", float64(v)/1e9)
	}
	bucketLabels[len(bucketLabels)-1] = "Max"
}
<|endoftext|>


<commit_before>//=====================================================================
//
// ragesocks.go -
//
// Created by skywind on 2018/03/01
// Last Modified: 2018/03/01 23:52:50
//
//=====================================================================
// vim: set ts=4 sw=4 tw=0 noet fdm=indent foldlevel=99 :

package main

import (
	"flag"
	"log"
	"crypto/rc4"
	"strconv"
	"net"
	"io"
	// "os"
)

//---------------------------------------------------------------------
// config
//---------------------------------------------------------------------
type Config struct {
	run_mode string
	server_host string
	client_host string
	server_port int
	client_port int
	key string
	method string
}

var config = Config {}

//---------------------------------------------------------------------
// Protocol
//---------------------------------------------------------------------
type Protocol struct {
	crypt_send *rc4.Cipher
	crypt_recv *rc4.Cipher
	twice_send *rc4.Cipher
	twice_recv *rc4.Cipher
	conn *net.TCPConn
	esock *net.TCPConn
	remote_address string
}

//---------------------------------------------------------------------
// arguments_init()
//---------------------------------------------------------------------
func arguments_init() bool {
	server := flag.Bool("server", false, "Running mode")
	server_host := flag.String("s", "", "Server address")
	client_host := flag.String("b", "", "Local address")
	server_port := flag.Int("p", 1030, "Server port")
	client_port := flag.Int("l", 1030, "Client port")
	method := flag.String("m", "rc4", "Encryption method")
	key := flag.String("k", "", "Key string")
	flag.Parse()
	config.run_mode = "client"
	if *server {
		config.run_mode = "server"
	}
	config.server_host = *server_host
	config.client_host = *client_host
	config.server_port = *server_port
	config.client_port = *client_port
	config.method = *method
	config.key = *key
	if config.run_mode == "server" {
		if config.server_host == "" {
			config.server_host = "0.0.0.0"
		}
	}	else {
		if config.server_host == "" {
			log.Print("ERROR: empty server address, use -h to help")
			return false
		}
		if config.client_host == "" {
			config.client_host = "localhost"
		}
	}
	log.Print("[config] running mode: ", config.run_mode)
	log.Print("[config] server address: ", config.server_host)
	log.Print("[config] server port: ", config.server_port)
	log.Print("[config] client address: ", config.client_host)
	log.Print("[config] client port: ", config.client_port)
	return true
}

//---------------------------------------------------------------------
// handle error
//---------------------------------------------------------------------
func handle_error(err error) bool {
	if err == nil {
		return true
	}
	log.Printf("ERROR: %s", err.Error());
	return false
}

//---------------------------------------------------------------------
// main()
//---------------------------------------------------------------------
func main() {
	if !arguments_init() {
		return
	}

	endpoint := ""

	if config.run_mode == "server" {
		endpoint = config.server_host + ":" + strconv.Itoa(config.server_port)
	}	else {
		endpoint = config.client_host + ":" + strconv.Itoa(config.client_port)
	}

	addr, err := net.ResolveTCPAddr("tcp4", endpoint)
	if !handle_error(err) {
		return
	}

	listener, err := net.ListenTCP("tcp4", addr)
	if !handle_error(err) {
		return
	}

	log.Printf("%s is listening on %s", config.run_mode, endpoint)

	for {
		conn, err := listener.AcceptTCP()
		if err == nil {
			key := []byte(config.key)
			protocol := Protocol {}
			protocol.crypt_recv, _ = rc4.NewCipher(key)
			protocol.crypt_send, _ = rc4.NewCipher(key)
			protocol.twice_recv = nil
			protocol.twice_send = nil
			protocol.conn = conn
			protocol.esock = nil
			protocol.remote_address = ""
			if config.run_mode == "server" {
				protocol.esock = conn
				go func (protocol *Protocol) {
					defer protocol.conn.Close()
					handle_server(protocol)
				}(&protocol)
			}	else {
				go func (protocol *Protocol) {
					defer protocol.conn.Close()
					handle_client(protocol)
				}(&protocol)
			}
		}	else {
			handle_error(err)
		}
	}
}

//---------------------------------------------------------------------
// encryption send
//---------------------------------------------------------------------
func encrypt_send(protocol *Protocol, buf []byte) (int, error) {
	if (protocol.crypt_send != nil) {
		protocol.crypt_send.XORKeyStream(buf, buf)
	}
	if (protocol.twice_send != nil) {
		protocol.twice_send.XORKeyStream(buf, buf)
	}
	return protocol.esock.Write(buf)
}

//---------------------------------------------------------------------
// encryption recv
//---------------------------------------------------------------------
func encrypt_recv(protocol *Protocol, buf []byte) (int, error) {
	n, err := protocol.esock.Read(buf)
	if err != nil {
		return n, err
	}
	if (protocol.twice_recv != nil) {
		protocol.twice_recv.XORKeyStream(buf[:n], buf[:n])
	}
	if (protocol.crypt_recv != nil) {
		protocol.crypt_recv.XORKeyStream(buf[:n], buf[:n])
	}
	return n, nil
}

//---------------------------------------------------------------------
// encryption recv all
//---------------------------------------------------------------------
func encrypt_recv_all(protocol *Protocol, buf []byte) (int, error) {
	n, err := io.ReadFull(protocol.esock, buf)
	if err != nil {
		return n, err
	}
	if (protocol.twice_recv != nil) {
		protocol.twice_recv.XORKeyStream(buf, buf)
	}
	if (protocol.crypt_recv != nil) {
		protocol.crypt_recv.XORKeyStream(buf, buf)
	}
	return n, err
}

//---------------------------------------------------------------------
// socks5 hand shake
//---------------------------------------------------------------------
func socks5_handshake(conn *net.TCPConn) string {
	buf := [512]byte {}
	conn.SetReadDeadline(time.Now().Add(time.Second * 10))
	n, err := io.ReadFull(conn, buf[:2])
	if !handleError(err) {
		return ""
	}
	if n != 2 || n <= 0 {
		log.Printf("ERROR: handshake error 1")
		return ""
	}
	if buf[0] != 5 {
		log.Printf("ERROR: unsupported protocol: %d", buf[0])
		return ""
	}
	n = int(buf[1])
	m, err := io.ReadFull(conn, buf[:n])
	if m != n {
		log.Printf("ERROR: size mismatch %d/%d", m, n)
		return ""
	}

	conn.Write([]byte{0x05, 0x00})

	n, err = io.ReadFull(conn, buf[:4])

	if !handleError(err) {
		return ""
	}

	if n !=4 {
		log.Printf("ERROR: bad header")
		return ""
	}

	if buf[0] != 5 {
		log.Printf("ERROR: unsupported protocol: %d", buf[0])
		return ""
	}

	if buf[1] != 1 {
		log.Print("ERROR: unsupported cmd: %d", buf[1])
		return ""
	}

	var host string

	switch buf[3] {
	case 1:
		n, err = io.ReadFull(conn, buf[:6])
		if !handleError(err) {
			return ""
		}
		if n != 6 {
			log.Print("ERROR: expect more bytes")
			return ""
		}
		host = net.IPv4(buf[0],buf[1],buf[2],buf[3]).String()
	case 3:
		n, err = io.ReadFull(conn, buf[:1])
		if !handleError(err) {
			return ""
		}
		if n != 1 {
			log.Printf("error size")
			return ""
		}
		size := int(buf[0])
		n, err = io.ReadFull(conn, buf[:size + 2])
		if !handleError(err) {
			return ""
		}
		if n != size + 2 {
			log.Print("ERROR: expect more bytes")
			return ""
		}
		host = string(buf[:n - 2])
		// log.Printf("host2 is %s size is %d", host, size)
	case 4:
		n, err = io.ReadFull(conn, buf[:18])
		if !handleError(err) {
			return ""
		}
		if n != 18 {
			log.Print("ERROR: expect more bytes")
			return ""
		}
		b := buf[:16]
		host = net.IP{b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19]}.String()
		// log.Printf("host3 is %s", host)
	default:
		log.Print("ERROR: unsupport address type: %d", buf[3])
		return ""
	}

	conn.SetReadDeadline(time.Time{})
	port := strconv.Itoa(int(buf[n-2]) * 256 | int(buf[n-1]))

	return host + ":" + port
}

//---------------------------------------------------------------------
// socks5 - establish
//---------------------------------------------------------------------
func socks5_estab(conn *net.TCPConn) {
	conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
}

//---------------------------------------------------------------------
// client entry
//---------------------------------------------------------------------
func handle_client(protocol *Protocol) {
}

//---------------------------------------------------------------------
// server entry
//---------------------------------------------------------------------
func handle_server(protocol *Protocol) {
}

<commit_msg>commit new ragesocks.go<commit_after>//=====================================================================
//
// ragesocks.go -
//
// Created by skywind on 2018/03/01
// Last Modified: 2018/03/01 23:52:50
//
//=====================================================================
// vim: set ts=4 sw=4 tw=0 noet fdm=indent foldlevel=99 :

package main

import (
	"flag"
	"log"
	"crypto/rc4"
	"strconv"
	"net"
	"io"
	// "os"
)

//---------------------------------------------------------------------
// config
//---------------------------------------------------------------------
type Config struct {
	run_mode string
	server_host string
	client_host string
	server_port int
	client_port int
	key string
	method string
}

var config = Config {}

//---------------------------------------------------------------------
// Protocol
//---------------------------------------------------------------------
type Protocol struct {
	crypt_send *rc4.Cipher
	crypt_recv *rc4.Cipher
	twice_send *rc4.Cipher
	twice_recv *rc4.Cipher
	conn *net.TCPConn
	esock *net.TCPConn
	remote_address string
}

//---------------------------------------------------------------------
// arguments_init()
//---------------------------------------------------------------------
func arguments_init() bool {
	server := flag.Bool("server", false, "Running mode")
	server_host := flag.String("s", "", "Server address")
	client_host := flag.String("b", "", "Local address")
	server_port := flag.Int("p", 1030, "Server port")
	client_port := flag.Int("l", 1030, "Client port")
	method := flag.String("m", "rc4", "Encryption method")
	key := flag.String("k", "", "Key string")
	flag.Parse()
	config.run_mode = "client"
	if *server {
		config.run_mode = "server"
	}
	config.server_host = *server_host
	config.client_host = *client_host
	config.server_port = *server_port
	config.client_port = *client_port
	config.method = *method
	config.key = *key
	if config.run_mode == "server" {
		if config.server_host == "" {
			config.server_host = "0.0.0.0"
		}
	}	else {
		if config.server_host == "" {
			log.Print("ERROR: empty server address, use -h to help")
			return false
		}
		if config.client_host == "" {
			config.client_host = "localhost"
		}
	}
	log.Print("[config] running mode: ", config.run_mode)
	log.Print("[config] server address: ", config.server_host)
	log.Print("[config] server port: ", config.server_port)
	log.Print("[config] client address: ", config.client_host)
	log.Print("[config] client port: ", config.client_port)
	return true
}

//---------------------------------------------------------------------
// handle error
//---------------------------------------------------------------------
func handle_error(err error) bool {
	if err == nil {
		return true
	}
	log.Printf("ERROR: %s", err.Error());
	return false
}

//---------------------------------------------------------------------
// main()
//---------------------------------------------------------------------
func main() {
	if !arguments_init() {
		return
	}

	endpoint := ""

	if config.run_mode == "server" {
		endpoint = config.server_host + ":" + strconv.Itoa(config.server_port)
	}	else {
		endpoint = config.client_host + ":" + strconv.Itoa(config.client_port)
	}

	addr, err := net.ResolveTCPAddr("tcp4", endpoint)
	if !handle_error(err) {
		return
	}

	listener, err := net.ListenTCP("tcp4", addr)
	if !handle_error(err) {
		return
	}

	log.Printf("%s is listening on %s", config.run_mode, endpoint)

	for {
		conn, err := listener.AcceptTCP()
		if err == nil {
			key := []byte(config.key)
			protocol := Protocol {}
			protocol.crypt_recv, _ = rc4.NewCipher(key)
			protocol.crypt_send, _ = rc4.NewCipher(key)
			protocol.twice_recv = nil
			protocol.twice_send = nil
			protocol.conn = conn
			protocol.esock = nil
			protocol.remote_address = ""
			if config.run_mode == "server" {
				protocol.esock = conn
				go func (protocol *Protocol) {
					defer protocol.conn.Close()
					handle_server(protocol)
				}(&protocol)
			}	else {
				go func (protocol *Protocol) {
					defer protocol.conn.Close()
					handle_client(protocol)
				}(&protocol)
			}
		}	else {
			handle_error(err)
		}
	}
}

//---------------------------------------------------------------------
// encryption send
//---------------------------------------------------------------------
func encrypt_send(protocol *Protocol, buf []byte) (int, error) {
	if (protocol.crypt_send != nil) {
		protocol.crypt_send.XORKeyStream(buf, buf)
	}
	if (protocol.twice_send != nil) {
		protocol.twice_send.XORKeyStream(buf, buf)
	}
	return protocol.esock.Write(buf)
}

//---------------------------------------------------------------------
// encryption recv
//---------------------------------------------------------------------
func encrypt_recv(protocol *Protocol, buf []byte) (int, error) {
	n, err := protocol.esock.Read(buf)
	if err != nil {
		return n, err
	}
	if (protocol.twice_recv != nil) {
		protocol.twice_recv.XORKeyStream(buf[:n], buf[:n])
	}
	if (protocol.crypt_recv != nil) {
		protocol.crypt_recv.XORKeyStream(buf[:n], buf[:n])
	}
	return n, nil
}

//---------------------------------------------------------------------
// encryption recv all
//---------------------------------------------------------------------
func encrypt_recv_all(protocol *Protocol, buf []byte) (int, error) {
	n, err := io.ReadFull(protocol.esock, buf)
	if err != nil {
		return n, err
	}
	if (protocol.twice_recv != nil) {
		protocol.twice_recv.XORKeyStream(buf, buf)
	}
	if (protocol.crypt_recv != nil) {
		protocol.crypt_recv.XORKeyStream(buf, buf)
	}
	return n, err
}

//---------------------------------------------------------------------
// socks5 hand shake
//---------------------------------------------------------------------
func socks5_handshake(conn *net.TCPConn) string {
	buf := [512]byte {}
	conn.SetReadDeadline(time.Now().Add(time.Second * 10))
	n, err := io.ReadFull(conn, buf[:2])
	if !handleError(err) {
		return ""
	}
	if n != 2 || n <= 0 {
		log.Printf("ERROR: handshake error 1")
		return ""
	}
	if buf[0] != 5 {
		log.Printf("ERROR: unsupported protocol: %d", buf[0])
		return ""
	}
	n = int(buf[1])
	m, err := io.ReadFull(conn, buf[:n])
	if m != n {
		log.Printf("ERROR: size mismatch %d/%d", m, n)
		return ""
	}

	conn.Write([]byte{0x05, 0x00})

	n, err = io.ReadFull(conn, buf[:4])

	if !handleError(err) {
		return ""
	}

	if n !=4 {
		log.Printf("ERROR: bad header")
		return ""
	}

	if buf[0] != 5 {
		log.Printf("ERROR: unsupported protocol: %d", buf[0])
		return ""
	}

	if buf[1] != 1 {
		log.Print("ERROR: unsupported cmd: %d", buf[1])
		return ""
	}

	var host string

	switch buf[3] {
	case 1:
		n, err = io.ReadFull(conn, buf[:6])
		if !handleError(err) {
			return ""
		}
		if n != 6 {
			log.Print("ERROR: expect more bytes")
			return ""
		}
		host = net.IPv4(buf[0],buf[1],buf[2],buf[3]).String()
	case 3:
		n, err = io.ReadFull(conn, buf[:1])
		if !handleError(err) {
			return ""
		}
		if n != 1 {
			log.Printf("error size")
			return ""
		}
		size := int(buf[0])
		n, err = io.ReadFull(conn, buf[:size + 2])
		if !handleError(err) {
			return ""
		}
		if n != size + 2 {
			log.Print("ERROR: expect more bytes")
			return ""
		}
		host = string(buf[:n - 2])
		// log.Printf("host2 is %s size is %d", host, size)
	case 4:
		n, err = io.ReadFull(conn, buf[:18])
		if !handleError(err) {
			return ""
		}
		if n != 18 {
			log.Print("ERROR: expect more bytes")
			return ""
		}
		b := buf[:16]
		host = net.IP{b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19]}.String()
		// log.Printf("host3 is %s", host)
	default:
		log.Print("ERROR: unsupport address type: %d", buf[3])
		return ""
	}

	conn.SetReadDeadline(time.Time{})
	port := strconv.Itoa(int(buf[n-2]) * 256 | int(buf[n-1]))

	return host + ":" + port
}

//---------------------------------------------------------------------
// socks5 - establish
//---------------------------------------------------------------------
func socks5_estab(conn *net.TCPConn) {
	conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
}

//---------------------------------------------------------------------
// client entry
//---------------------------------------------------------------------
func handle_client(protocol *Protocol) {
	conn := protocol.conn

	address := socks5_handshake(conn)

	if address == "" {
		return
	}

	log.Printf("destination: %s", address)

	client, err := net.Dial("tcp", address)
	if !handle_error(err) {
		return
	}

	protocol.esock = client
}

//---------------------------------------------------------------------
// server entry
//---------------------------------------------------------------------
func handle_server(protocol *Protocol) {
	conn := protocol.conn
}

<|endoftext|>


<commit_before>package teams

import (
	"context"
	"fmt"

	"github.com/keybase/client/go/libkb"
	"github.com/keybase/client/go/protocol/keybase1"
)

func HandleRotateRequest(ctx context.Context, g *libkb.GlobalContext, teamID keybase1.TeamID, generation keybase1.PerTeamKeyGeneration) (err error) {

	ctx = libkb.WithLogTag(ctx, "CLKR")
	defer g.CTrace(ctx, fmt.Sprintf("HandleRotateRequest(%s,%d)", teamID, generation), func() error { return err })()

	team, err := Load(ctx, g, keybase1.LoadTeamArg{
		ID:          teamID,
		ForceRepoll: true,
	})
	if err != nil {
		return err
	}

	if team.Generation() > generation {
		g.Log.CDebugf(ctx, "current team generation %d > team.clkr generation %d, not rotating", team.Generation(), generation)
		return nil
	}

	g.Log.CDebugf(ctx, "rotating team %s (%s)", team.Name(), teamID)
	if err := team.Rotate(ctx); err != nil {
		g.Log.CDebugf(ctx, "rotating team %s (%s) error: %s", team.Name(), teamID, err)
		return err
	}

	g.Log.CDebugf(ctx, "sucess rotating team %s (%s)", team.Name(), teamID)
	return nil
}

func reloadLocal(ctx context.Context, g *libkb.GlobalContext, row keybase1.TeamChangeRow, change keybase1.TeamChangeSet) error {
	if change.Renamed {
		// This force reloads the team as a side effect
		return g.GetTeamLoader().NotifyTeamRename(ctx, row.Id, row.Name)
	}

	_, err := Load(ctx, g, keybase1.LoadTeamArg{
		ID:          row.Id,
		ForceRepoll: true,
	})
	return err
}

func handleChangeSingle(ctx context.Context, g *libkb.GlobalContext, row keybase1.TeamChangeRow, change keybase1.TeamChangeSet) (err error) {
	change.KeyRotated = row.KeyRotated
	change.MembershipChanged = row.MembershipChanged

	defer g.CTrace(ctx, fmt.Sprintf("team.handleChangeSingle(%+v, %+v)", row, change), func() error { return err })()

	if err = reloadLocal(ctx, g, row, change); err != nil {
		return err
	}
	g.NotifyRouter.HandleTeamChanged(ctx, row.Id, row.Name, row.LatestSeqno, change)
	return nil
}

func HandleChangeNotification(ctx context.Context, g *libkb.GlobalContext, rows []keybase1.TeamChangeRow, changes keybase1.TeamChangeSet) error {
	for _, row := range rows {
		if err := handleChangeSingle(ctx, g, row, changes); err != nil {
			return err
		}
	}
	return nil
}

func HandleSBSRequest(ctx context.Context, g *libkb.GlobalContext, msg keybase1.TeamSBSMsg) error {
	return nil
}
<commit_msg>WIP handle team.sbs<commit_after>package teams

import (
	"context"
	"fmt"

	"github.com/keybase/client/go/libkb"
	"github.com/keybase/client/go/protocol/keybase1"
)

func HandleRotateRequest(ctx context.Context, g *libkb.GlobalContext, teamID keybase1.TeamID, generation keybase1.PerTeamKeyGeneration) (err error) {

	ctx = libkb.WithLogTag(ctx, "CLKR")
	defer g.CTrace(ctx, fmt.Sprintf("HandleRotateRequest(%s,%d)", teamID, generation), func() error { return err })()

	team, err := Load(ctx, g, keybase1.LoadTeamArg{
		ID:          teamID,
		ForceRepoll: true,
	})
	if err != nil {
		return err
	}

	if team.Generation() > generation {
		g.Log.CDebugf(ctx, "current team generation %d > team.clkr generation %d, not rotating", team.Generation(), generation)
		return nil
	}

	g.Log.CDebugf(ctx, "rotating team %s (%s)", team.Name(), teamID)
	if err := team.Rotate(ctx); err != nil {
		g.Log.CDebugf(ctx, "rotating team %s (%s) error: %s", team.Name(), teamID, err)
		return err
	}

	g.Log.CDebugf(ctx, "sucess rotating team %s (%s)", team.Name(), teamID)
	return nil
}

func reloadLocal(ctx context.Context, g *libkb.GlobalContext, row keybase1.TeamChangeRow, change keybase1.TeamChangeSet) error {
	if change.Renamed {
		// This force reloads the team as a side effect
		return g.GetTeamLoader().NotifyTeamRename(ctx, row.Id, row.Name)
	}

	_, err := Load(ctx, g, keybase1.LoadTeamArg{
		ID:          row.Id,
		ForceRepoll: true,
	})
	return err
}

func handleChangeSingle(ctx context.Context, g *libkb.GlobalContext, row keybase1.TeamChangeRow, change keybase1.TeamChangeSet) (err error) {
	change.KeyRotated = row.KeyRotated
	change.MembershipChanged = row.MembershipChanged

	defer g.CTrace(ctx, fmt.Sprintf("team.handleChangeSingle(%+v, %+v)", row, change), func() error { return err })()

	if err = reloadLocal(ctx, g, row, change); err != nil {
		return err
	}
	g.NotifyRouter.HandleTeamChanged(ctx, row.Id, row.Name, row.LatestSeqno, change)
	return nil
}

func HandleChangeNotification(ctx context.Context, g *libkb.GlobalContext, rows []keybase1.TeamChangeRow, changes keybase1.TeamChangeSet) error {
	for _, row := range rows {
		if err := handleChangeSingle(ctx, g, row, changes); err != nil {
			return err
		}
	}
	return nil
}

func HandleSBSRequest(ctx context.Context, g *libkb.GlobalContext, msg keybase1.TeamSBSMsg) error {
	for _, invitee := range msg.Invitees {
		if err := handleSingleSBSRequest(ctx, g, msg.TeamID, invitee); err != nil {

		}
	}

	return nil

}

func handleSingleSBSRequest(ctx context.Context, g *libkb.GlobalContext, teamID keybase1.TeamID, invitee keybase1.TeamInvitee) error {
	uv := NewUserVersion(invitee.Uid, invitee.EldestSeqno)
	req, err := reqFromRole(uv, invitee.Role)
	if err != nil {
		return err
	}

	team, err := GetForTeamManagement(ctx, g, teamID)
	if err != nil {
		return err
	}

	_ = team
	_ = req

	return nil
}
<|endoftext|>


<commit_before>package main

// index template
const index = `[[define "index"]]<!doctype html>

[[template "head" . ]]

<ng-include src="'pages/global.html'"></ng-include>

[[template "header" . ]]

[[end]]`

// head items
const head = `[[define "head"]]
<base href="/[[ .base ]]">
<title data-ng-bind="page.title">[[ .title ]]</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="[[ .desc ]]" />[[if .nsfw -]]
<meta name="rating" content="adult" />
<meta name="rating" content="RTA-5042-1996-1400-1577-RTA" />
[[- end]]
<link rel="stylesheet" href="/assets/prim/[[ .primcss ]]" />
<link rel="stylesheet" href="/assets/styles/[[ .style ]]" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">

[[template "angular" . ]][[template "headinclude" . ]]
[[end]]`

// angular config
const angular = `[[define "angular"]][[end]]`

// site header
const header = `[[define "header"]]

[[template "navmenuinclude" . ]][[template "navmenu" . ]]

<ng-include src="'pages/menus/nav.html'"></ng-include>

Sign in

<ng-include src="'pages/menus/user.html'"></ng-include>

[[end]]`

const navmenu = `[[define "navmenu"]][[ range $ib := .imageboards]]

[[ $ib.Title ]]

[[end]][[end]]`
<commit_msg>move stylesheets above js<commit_after>package main

// index template
const index = `[[define "index"]]<!doctype html>

[[template "head" . ]]

<ng-include src="'pages/global.html'"></ng-include>

[[template "header" . ]]

[[end]]`

// head items
const head = `[[define "head"]]
<base href="/[[ .base ]]">
<title data-ng-bind="page.title">[[ .title ]]</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="[[ .desc ]]" />[[if .nsfw -]]
<meta name="rating" content="adult" />
<meta name="rating" content="RTA-5042-1996-1400-1577-RTA" />
[[- end]]
<link rel="stylesheet" href="/assets/prim/[[ .primcss ]]" />
<link rel="stylesheet" href="/assets/styles/[[ .style ]]" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">

[[template "angular" . ]][[template "headinclude" . ]]
[[end]]`

// angular config
const angular = `[[define "angular"]][[end]]`

// site header
const header = `[[define "header"]]

[[template "navmenuinclude" . ]][[template "navmenu" . ]]

<ng-include src="'pages/menus/nav.html'"></ng-include>

Sign in

<ng-include src="'pages/menus/user.html'"></ng-include>

[[end]]`

const navmenu = `[[define "navmenu"]][[ range $ib := .imageboards]]
[[ $ib.Title ]]

[[end]][[end]]`
<|endoftext|>


<commit_before>package term

import . "fmt"
import . "regexp"
import "strings"
import "github.com/mndrix/golog/lex"

// Term represents a single Prolog term which might be an atom, a structure,
// a number, etc.
type Term interface {
    // Functor returns the term's name
    Functor() string

    // Arity returns the number of arguments a term has. An atom has 0 arity.
    Arity() int

    // Arguments returns a slice of this term's arguments, if any
    Arguments() []Term

    // Body returns a term's second argument; otherwise, panics
    Body() Term

    // Head returns a term's first argument; otherwise, panics
    Head() Term

    // Error returns an error value if this is an error term
    Error() error

    // IsClause returns true if the term is like 'Head :- Body'
    IsClause() bool

    // String provides a string representation of a term
    String() string

    // Indicator() provides a "predicate indicator" representation of a term
    Indicator() string
}

func IsVariable(t Term) bool {
    switch t.(type) {
        case *Compound:
            return false
        case *Variable:
            return true
        case *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

func IsError(t Term) bool {
    switch t.(type) {
        case *Compound:
            return false
        case *Variable:
            return false
        case *Error:
            return true
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// QuoteFunctor returns a canonical representation of a term's name
// by quoting characters that require quoting
func QuoteFunctor(name string) string {
    // names composed entirely of graphic characters need no quoting
    allGraphic := true
    for _, c := range name {
        if !lex.IsGraphic(c) {
            allGraphic = false
            break
        }
    }
    if allGraphic {
        return name
    }

    nonAlpha, err := MatchString(`\W`, name)
    maybePanic(err)
    nonLower, err := MatchString(`^[^a-z]`, name)
    if nonAlpha || nonLower {
        escapedName := strings.Replace(name, `'`, `\'`, -1)
        return Sprintf("'%s'", escapedName)
    }

    return name
}

func maybePanic(err error) {
    if err != nil {
        panic(err)
    }
}
<commit_msg>Godoc friendly heading for term package<commit_after>// Data structures for representing Prolog terms
package term

import . "fmt"
import . "regexp"
import "strings"
import "github.com/mndrix/golog/lex"

// Term represents a single Prolog term which might be an atom, a structure,
// a number, etc.
type Term interface {
    // Functor returns the term's name
    Functor() string

    // Arity returns the number of arguments a term has. An atom has 0 arity.
    Arity() int

    // Arguments returns a slice of this term's arguments, if any
    Arguments() []Term

    // Body returns a term's second argument; otherwise, panics
    Body() Term

    // Head returns a term's first argument; otherwise, panics
    Head() Term

    // Error returns an error value if this is an error term
    Error() error

    // IsClause returns true if the term is like 'Head :- Body'
    IsClause() bool

    // String provides a string representation of a term
    String() string

    // Indicator() provides a "predicate indicator" representation of a term
    Indicator() string
}

func IsVariable(t Term) bool {
    switch t.(type) {
        case *Compound:
            return false
        case *Variable:
            return true
        case *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

func IsError(t Term) bool {
    switch t.(type) {
        case *Compound:
            return false
        case *Variable:
            return false
        case *Error:
            return true
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// QuoteFunctor returns a canonical representation of a term's name
// by quoting characters that require quoting
func QuoteFunctor(name string) string {
    // names composed entirely of graphic characters need no quoting
    allGraphic := true
    for _, c := range name {
        if !lex.IsGraphic(c) {
            allGraphic = false
            break
        }
    }
    if allGraphic {
        return name
    }

    nonAlpha, err := MatchString(`\W`, name)
    maybePanic(err)
    nonLower, err := MatchString(`^[^a-z]`, name)
    if nonAlpha || nonLower {
        escapedName := strings.Replace(name, `'`, `\'`, -1)
        return Sprintf("'%s'", escapedName)
    }

    return name
}

func maybePanic(err error) {
    if err != nil {
        panic(err)
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package backups_test

import (
	gc "gopkg.in/check.v1"

	"github.com/juju/juju/api/backups"
	"github.com/juju/juju/apiserver/params"
)

type listSuite struct {
	baseSuite
}

var _ = gc.Suite(&listSuite{})

func (s *listSuite) TestList(c *gc.C) {
	cleanup := backups.PatchClientFacadeCall(s.client,
		func(req string, paramsIn interface{}, resp interface{}) error {
			c.Check(req, gc.Equals, "List")

			c.Assert(paramsIn, gc.FitsTypeOf, params.BackupsListArgs{})

			if result, ok := resp.(*params.BackupsListResult); ok {
				result.List = make([]params.BackupsMetadataResult, 1)
				var resultItem params.BackupsMetadataResult
				resultItem.UpdateFromMetadata(s.meta)
				result.List[0] = resultItem
			} else {
				c.Log("wrong output structure")
				c.Fail()
			}
			return nil
		},
	)
	defer cleanup()

	result, err := s.client.List()
	c.Assert(err, gc.IsNil)

	c.Assert(result.List, gc.HasLen, 1)
	resultItem := result.List[0]
	s.checkMetadataResult(c, &resultItem, s.meta, "")
}
<commit_msg>Adjust to baseSuite.<commit_after>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package backups_test

import (
	gc "gopkg.in/check.v1"

	"github.com/juju/juju/api/backups"
	"github.com/juju/juju/apiserver/params"
)

type listSuite struct {
	baseSuite
}

var _ = gc.Suite(&listSuite{})

func (s *listSuite) TestList(c *gc.C) {
	cleanup := backups.PatchClientFacadeCall(s.client,
		func(req string, paramsIn interface{}, resp interface{}) error {
			c.Check(req, gc.Equals, "List")

			c.Assert(paramsIn, gc.FitsTypeOf, params.BackupsListArgs{})

			if result, ok := resp.(*params.BackupsListResult); ok {
				result.List = make([]params.BackupsMetadataResult, 1)
				var resultItem params.BackupsMetadataResult
				resultItem.UpdateFromMetadata(s.Meta)
				result.List[0] = resultItem
			} else {
				c.Fatalf("wrong output structure")
			}
			return nil
		},
	)
	defer cleanup()

	result, err := s.client.List()
	c.Assert(err, gc.IsNil)

	c.Assert(result.List, gc.HasLen, 1)
	resultItem := result.List[0]
	s.checkMetadataResult(c, &resultItem, s.Meta)
}
<|endoftext|>


<commit_before>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package crossmodel

import (
	"github.com/juju/errors"
	"github.com/juju/loggo"

	"github.com/juju/juju/api/base"
	"github.com/juju/juju/apiserver/params"
)

var logger = loggo.GetLogger("juju.api.crossmodel")

// Client allows access to the cross model management API end points.
type Client struct {
	base.ClientFacade
	facade base.FacadeCaller
}

// NewClient creates a new client for accessing the cross model relations API.
func NewClient(st base.APICallCloser) *Client {
	frontend, backend := base.NewClientFacade(st, "CrossModelRelations")
	return &Client{ClientFacade: frontend, facade: backend}
}

// Offer prepares service's endpoints for consumption.
func (c *Client) Offer(service string, endpoints []string, url string, users []string) ([]params.ErrorResult, error) {
	offers := []params.CrossModelOffer{
		params.CrossModelOffer{service, endpoints, url, users},
	}

	out := params.ErrorResults{}
	if err := c.facade.FacadeCall("Offer", params.CrossModelOffers{Offers: offers}, &out); err != nil {
		return nil, errors.Trace(err)
	}
	return out.Results, nil
}

// Show returns offered remote service details for a given URL.
func (c *Client) Show(url string) (params.RemoteServiceInfo, error) {
	found := params.RemoteServiceInfoResults{}

	err := c.facade.FacadeCall("Show", []string{url}, &found)
	if err != nil {
		return params.RemoteServiceInfo{}, errors.Trace(err)
	}

	result := found.Results
	if len(result) > 1 {
		return params.RemoteServiceInfo{}, errors.Errorf("expected to find one result for url %q but found %d", url, len(result))
	}

	if len(result) == 0 {
		return params.RemoteServiceInfo{}, errors.NotFoundf("remote service with url %q", url)
	}

	theOne := result[0]
	if theOne.Error != nil {
		return params.RemoteServiceInfo{}, errors.Trace(theOne.Error)
	}
	return theOne.Result, nil
}
<commit_msg>Changed to != 1<commit_after>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package crossmodel

import (
	"github.com/juju/errors"
	"github.com/juju/loggo"

	"github.com/juju/juju/api/base"
	"github.com/juju/juju/apiserver/params"
)

var logger = loggo.GetLogger("juju.api.crossmodel")

// Client allows access to the cross model management API end points.
type Client struct {
	base.ClientFacade
	facade base.FacadeCaller
}

// NewClient creates a new client for accessing the cross model relations API.
func NewClient(st base.APICallCloser) *Client {
	frontend, backend := base.NewClientFacade(st, "CrossModelRelations")
	return &Client{ClientFacade: frontend, facade: backend}
}

// Offer prepares service's endpoints for consumption.
func (c *Client) Offer(service string, endpoints []string, url string, users []string) ([]params.ErrorResult, error) {
	offers := []params.CrossModelOffer{
		params.CrossModelOffer{service, endpoints, url, users},
	}

	out := params.ErrorResults{}
	if err := c.facade.FacadeCall("Offer", params.CrossModelOffers{Offers: offers}, &out); err != nil {
		return nil, errors.Trace(err)
	}
	return out.Results, nil
}

// Show returns offered remote service details for a given URL.
func (c *Client) Show(url string) (params.RemoteServiceInfo, error) {
	found := params.RemoteServiceInfoResults{}

	err := c.facade.FacadeCall("Show", []string{url}, &found)
	if err != nil {
		return params.RemoteServiceInfo{}, errors.Trace(err)
	}

	result := found.Results
	if len(result) != 1 {
		return params.RemoteServiceInfo{}, errors.Errorf("expected to find one result for url %q but found %d", url, len(result))
	}

	theOne := result[0]
	if theOne.Error != nil {
		return params.RemoteServiceInfo{}, errors.Trace(theOne.Error)
	}
	return theOne.Result, nil
}
<|endoftext|>


<commit_before>//  Copyright (c) 2014 Couchbase, 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 bleve

import (
	"sort"
	"sync"

	"github.com/blevesearch/bleve/document"
	"github.com/blevesearch/bleve/search"
)

type indexAliasImpl struct {
	indexes []Index
	mutex   sync.RWMutex
	open    bool
}

// NewIndexAlias creates a new IndexAlias over the provided
// Index objects.
func NewIndexAlias(indexes ...Index) *indexAliasImpl {
	return &indexAliasImpl{
		indexes: indexes,
		open:    true,
	}
}

func (i *indexAliasImpl) isAliasToSingleIndex() error {
	if len(i.indexes) < 1 {
		return ErrorAliasEmpty
	} else if len(i.indexes) > 1 {
		return ErrorAliasMulti
	}
	return nil
}

func (i *indexAliasImpl) Index(id string, data interface{}) error {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return err
	}

	return i.indexes[0].Index(id, data)
}

func (i *indexAliasImpl) Delete(id string) error {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return err
	}

	return i.indexes[0].Delete(id)
}

func (i *indexAliasImpl) Batch(b *Batch) error {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return err
	}

	return i.indexes[0].Batch(b)
}

func (i *indexAliasImpl) Document(id string) (*document.Document, error) {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil, ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil, err
	}

	return i.indexes[0].Document(id)
}

func (i *indexAliasImpl) DocCount() (uint64, error) {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	rv := uint64(0)

	if !i.open {
		return 0, ErrorIndexClosed
	}

	for _, index := range i.indexes {
		otherCount, err := index.DocCount()
		if err != nil {
			return 0, err
		}
		rv += otherCount
	}

	return rv, nil
}

func (i *indexAliasImpl) Search(req *SearchRequest) (*SearchResult, error) {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil, ErrorIndexClosed
	}

	if len(i.indexes) < 1 {
		return nil, ErrorAliasEmpty
	}

	// short circuit the simple case
	if len(i.indexes) == 1 {
		return i.indexes[0].Search(req)
	}

	return MultiSearch(req, i.indexes...)
}

func (i *indexAliasImpl) Fields() ([]string, error) {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil, ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil, err
	}

	return i.indexes[0].Fields()
}

func (i *indexAliasImpl) DumpAll() chan interface{} {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil
	}

	return i.indexes[0].DumpAll()
}

func (i *indexAliasImpl) DumpDoc(id string) chan interface{} {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil
	}

	return i.indexes[0].DumpDoc(id)
}

func (i *indexAliasImpl) DumpFields() chan interface{} {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil
	}

	return i.indexes[0].DumpFields()
}

func (i *indexAliasImpl) Close() error {
	i.mutex.Lock()
	defer i.mutex.Unlock()

	i.open = false
	return nil
}

func (i *indexAliasImpl) Mapping() *IndexMapping {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil
	}

	return i.indexes[0].Mapping()
}

func (i *indexAliasImpl) Stats() *IndexStat {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil
	}

	return i.indexes[0].Stats()
}

func (i *indexAliasImpl) GetInternal(key []byte) ([]byte, error) {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil, ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil, err
	}

	return i.indexes[0].GetInternal(key)
}

func (i *indexAliasImpl) SetInternal(key, val []byte) error {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return err
	}

	return i.indexes[0].SetInternal(key, val)
}

func (i *indexAliasImpl) DeleteInternal(key []byte) error {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return err
	}

	return i.indexes[0].DeleteInternal(key)
}

func (i *indexAliasImpl) Add(indexes ...Index) {
	i.mutex.Lock()
	defer i.mutex.Unlock()

	i.indexes = append(i.indexes, indexes...)
}

func (i *indexAliasImpl) removeSingle(index Index) {
	for pos, in := range i.indexes {
		if in == index {
			i.indexes = append(i.indexes[:pos], i.indexes[pos+1:]...)
			break
		}
	}
}

func (i *indexAliasImpl) Remove(indexes ...Index) {
	i.mutex.Lock()
	defer i.mutex.Unlock()

	for _, in := range indexes {
		i.removeSingle(in)
	}
}

func (i *indexAliasImpl) Swap(in, out []Index) {
	i.mutex.Lock()
	defer i.mutex.Unlock()

	// add
	i.indexes = append(i.indexes, in...)

	// delete
	for _, ind := range out {
		i.removeSingle(ind)
	}
}

// MultiSearch executes a SearchRequest across multiple
// Index objects, then merges the results.
func MultiSearch(req *SearchRequest, indexes ...Index) (*SearchResult, error) {
	results := make(chan *SearchResult)
	errs := make(chan error)

	// remember the original from and size
	size := req.Size
	req.Size += req.From
	from := req.From
	req.From = 0

	// FIXME should create new request for
	// child queries, disable highlighting
	// and field loading
	// then, perform these steps only on
	// the final results

	// run search on each index in separate go routine
	var waitGroup sync.WaitGroup

	var searchChildIndex = func(waitGroup *sync.WaitGroup, in Index, results chan *SearchResult, errs chan error) {
		go func() {
			defer waitGroup.Done()
			searchResult, err := in.Search(req)
			if err != nil {
				errs <- err
			} else {
				results <- searchResult
			}
		}()
	}

	for _, in := range indexes {
		waitGroup.Add(1)
		searchChildIndex(&waitGroup, in, results, errs)
	}

	// on another go routine, close after finished
	go func() {
		waitGroup.Wait()
		close(results)
		close(errs)
	}()

	var sr *SearchResult
	var err error
	var result *SearchResult
	ok := true
	for ok {
		select {
		case result, ok = <-results:
			if ok {
				if sr == nil {
					// first result
					sr = result
				} else {
					// merge with previous
					sr.Merge(result)
				}
			}
		case err, ok = <-errs:
		}
	}

	// for now stop on any error
	// FIXME offer other behaviors
	if err != nil {
		return nil, err
	}

	// merge just concatenated all the hits
	// now lets clean it up

	// first sort it by score
	sort.Sort(sr.Hits)

	// now skip over the correct From
	req.From = from
	if req.From > 0 && len(sr.Hits) > req.From {
		sr.Hits = sr.Hits[req.From:]
	} else if req.From > 0 {
		sr.Hits = search.DocumentMatchCollection{}
	}

	// now trim to the correct size
	req.Size = size
	if req.Size > 0 && len(sr.Hits) > req.Size {
		sr.Hits = sr.Hits[0:req.Size]
	}

	// fix up facets
	for name, fr := range req.Facets {
		sr.Facets.Fixup(name, fr.Size)
	}

	return sr, nil
}
<commit_msg>better fix for returning on first error closes #126<commit_after>//  Copyright (c) 2014 Couchbase, 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 bleve

import (
	"sort"
	"sync"

	"github.com/blevesearch/bleve/document"
	"github.com/blevesearch/bleve/search"
)

type indexAliasImpl struct {
	indexes []Index
	mutex   sync.RWMutex
	open    bool
}

// NewIndexAlias creates a new IndexAlias over the provided
// Index objects.
func NewIndexAlias(indexes ...Index) *indexAliasImpl {
	return &indexAliasImpl{
		indexes: indexes,
		open:    true,
	}
}

func (i *indexAliasImpl) isAliasToSingleIndex() error {
	if len(i.indexes) < 1 {
		return ErrorAliasEmpty
	} else if len(i.indexes) > 1 {
		return ErrorAliasMulti
	}
	return nil
}

func (i *indexAliasImpl) Index(id string, data interface{}) error {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return err
	}

	return i.indexes[0].Index(id, data)
}

func (i *indexAliasImpl) Delete(id string) error {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return err
	}

	return i.indexes[0].Delete(id)
}

func (i *indexAliasImpl) Batch(b *Batch) error {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return err
	}

	return i.indexes[0].Batch(b)
}

func (i *indexAliasImpl) Document(id string) (*document.Document, error) {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil, ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil, err
	}

	return i.indexes[0].Document(id)
}

func (i *indexAliasImpl) DocCount() (uint64, error) {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	rv := uint64(0)

	if !i.open {
		return 0, ErrorIndexClosed
	}

	for _, index := range i.indexes {
		otherCount, err := index.DocCount()
		if err != nil {
			return 0, err
		}
		rv += otherCount
	}

	return rv, nil
}

func (i *indexAliasImpl) Search(req *SearchRequest) (*SearchResult, error) {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil, ErrorIndexClosed
	}

	if len(i.indexes) < 1 {
		return nil, ErrorAliasEmpty
	}

	// short circuit the simple case
	if len(i.indexes) == 1 {
		return i.indexes[0].Search(req)
	}

	return MultiSearch(req, i.indexes...)
}

func (i *indexAliasImpl) Fields() ([]string, error) {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil, ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil, err
	}

	return i.indexes[0].Fields()
}

func (i *indexAliasImpl) DumpAll() chan interface{} {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil
	}

	return i.indexes[0].DumpAll()
}

func (i *indexAliasImpl) DumpDoc(id string) chan interface{} {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil
	}

	return i.indexes[0].DumpDoc(id)
}

func (i *indexAliasImpl) DumpFields() chan interface{} {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil
	}

	return i.indexes[0].DumpFields()
}

func (i *indexAliasImpl) Close() error {
	i.mutex.Lock()
	defer i.mutex.Unlock()

	i.open = false
	return nil
}

func (i *indexAliasImpl) Mapping() *IndexMapping {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil
	}

	return i.indexes[0].Mapping()
}

func (i *indexAliasImpl) Stats() *IndexStat {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil
	}

	return i.indexes[0].Stats()
}

func (i *indexAliasImpl) GetInternal(key []byte) ([]byte, error) {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return nil, ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return nil, err
	}

	return i.indexes[0].GetInternal(key)
}

func (i *indexAliasImpl) SetInternal(key, val []byte) error {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return err
	}

	return i.indexes[0].SetInternal(key, val)
}

func (i *indexAliasImpl) DeleteInternal(key []byte) error {
	i.mutex.RLock()
	defer i.mutex.RUnlock()

	if !i.open {
		return ErrorIndexClosed
	}

	err := i.isAliasToSingleIndex()
	if err != nil {
		return err
	}

	return i.indexes[0].DeleteInternal(key)
}

func (i *indexAliasImpl) Add(indexes ...Index) {
	i.mutex.Lock()
	defer i.mutex.Unlock()

	i.indexes = append(i.indexes, indexes...)
}

func (i *indexAliasImpl) removeSingle(index Index) {
	for pos, in := range i.indexes {
		if in == index {
			i.indexes = append(i.indexes[:pos], i.indexes[pos+1:]...)
			break
		}
	}
}

func (i *indexAliasImpl) Remove(indexes ...Index) {
	i.mutex.Lock()
	defer i.mutex.Unlock()

	for _, in := range indexes {
		i.removeSingle(in)
	}
}

func (i *indexAliasImpl) Swap(in, out []Index) {
	i.mutex.Lock()
	defer i.mutex.Unlock()

	// add
	i.indexes = append(i.indexes, in...)

	// delete
	for _, ind := range out {
		i.removeSingle(ind)
	}
}

// MultiSearch executes a SearchRequest across multiple
// Index objects, then merges the results.
func MultiSearch(req *SearchRequest, indexes ...Index) (*SearchResult, error) {
	results := make(chan *SearchResult)
	errs := make(chan error)

	// remember the original from and size
	size := req.Size
	req.Size += req.From
	from := req.From
	req.From = 0

	// FIXME should create new request for
	// child queries, disable highlighting
	// and field loading
	// then, perform these steps only on
	// the final results

	// run search on each index in separate go routine
	var waitGroup sync.WaitGroup

	var searchChildIndex = func(waitGroup *sync.WaitGroup, in Index, results chan *SearchResult, errs chan error) {
		go func() {
			defer waitGroup.Done()
			searchResult, err := in.Search(req)
			if err != nil {
				errs <- err
			} else {
				results <- searchResult
			}
		}()
	}

	for _, in := range indexes {
		waitGroup.Add(1)
		searchChildIndex(&waitGroup, in, results, errs)
	}

	// on another go routine, close after finished
	go func() {
		waitGroup.Wait()
		close(results)
		close(errs)
	}()

	var sr *SearchResult
	var err error
	var result *SearchResult
	ok := true
	for ok {
		select {
		case result, ok = <-results:
			if ok {
				if sr == nil {
					// first result
					sr = result
				} else {
					// merge with previous
					sr.Merge(result)
				}
			}
		case err, ok = <-errs:
			// for now stop on any error
			// FIXME offer other behaviors
			if err != nil {
				return nil, err
			}
		}
	}

	// merge just concatenated all the hits
	// now lets clean it up

	// first sort it by score
	sort.Sort(sr.Hits)

	// now skip over the correct From
	req.From = from
	if req.From > 0 && len(sr.Hits) > req.From {
		sr.Hits = sr.Hits[req.From:]
	} else if req.From > 0 {
		sr.Hits = search.DocumentMatchCollection{}
	}

	// now trim to the correct size
	req.Size = size
	if req.Size > 0 && len(sr.Hits) > req.Size {
		sr.Hits = sr.Hits[0:req.Size]
	}

	// fix up facets
	for name, fr := range req.Facets {
		sr.Facets.Fixup(name, fr.Size)
	}

	return sr, nil
}
<|endoftext|>


<commit_before>package goStrongswanVici

import (
	"fmt"
)

type TerminateRequest struct {
	Child    string `json:"child,omitempty"`
	Ike      string `json:"ike,omitempty"`
	Child_id string `json:"child-id,omitempty"`
	Ike_id   string `json:"ike-id,omitempty"`
	Timeout  string `json:"timeout,omitempty"`
	Loglevel string `json:"loglevel,omitempty"`
}

// To be simple, kill a client that is connecting to this server. A client is a sa.
//Terminates an SA while streaming control-log events.
func (c *ClientConn) Terminate(r *TerminateRequest) (err error) {
	err = handlePanic(func() (err error) {
		reqMap := &map[string]interface{}{}
		ConvertToGeneral(r, reqMap)
		msg, err := c.Request("terminate", *reqMap)
		if err != nil {
			return
		}
		if msg["success"] != "yes" {
			return fmt.Errorf("[Terminate] %s", msg["errmsg"])
		}
		return
	})
	return
}
<commit_msg>add force option to terminate<commit_after>package goStrongswanVici

import (
	"fmt"
)

type TerminateRequest struct {
	Child    string `json:"child,omitempty"`
	Ike      string `json:"ike,omitempty"`
	Child_id string `json:"child-id,omitempty"`
	Ike_id   string `json:"ike-id,omitempty"`
	Force    string `json:"force,omitempty"`
	Timeout  string `json:"timeout,omitempty"`
	Loglevel string `json:"loglevel,omitempty"`
}

// To be simple, kill a client that is connecting to this server. A client is a sa.
//Terminates an SA while streaming control-log events.
func (c *ClientConn) Terminate(r *TerminateRequest) (err error) {
	err = handlePanic(func() (err error) {
		reqMap := &map[string]interface{}{}
		ConvertToGeneral(r, reqMap)
		msg, err := c.Request("terminate", *reqMap)
		if err != nil {
			return
		}
		if msg["success"] != "yes" {
			return fmt.Errorf("[Terminate] %s", msg["errmsg"])
		}
		return
	})
	return
}
<|endoftext|>