<commit_before>package langserver

import (
	"context"
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"go/types"
	"log"
	"path/filepath"
	"reflect"
	"strings"
	"sync"

	opentracing "github.com/opentracing/opentracing-go"

	"github.com/sourcegraph/sourcegraph-go/pkg/lsp"

	"golang.org/x/tools/go/loader"
)

func (h *LangHandler) typecheck(ctx context.Context, conn JSONRPC2Conn, fileURI string, position lsp.Position) (*token.FileSet, *ast.Ident, *loader.PackageInfo, error) {
	parentSpan := opentracing.SpanFromContext(ctx)
	span := parentSpan.Tracer().StartSpan("langserver-go: load program",
		opentracing.Tags{"fileURI": fileURI},
		opentracing.ChildOf(parentSpan.Context()),
	)
	ctx = opentracing.ContextWithSpan(ctx, span)
	defer span.Finish()

	filename := h.FilePath(fileURI)

	contents, err := h.readFile(ctx, fileURI)
	if err != nil {
		return nil, nil, nil, err
	}
	offset, valid, why := offsetForPosition(contents, position)
	if !valid {
		return nil, nil, nil, fmt.Errorf("invalid position: %s:%d:%d (%s)", filename, position.Line, position.Character, why)
	}

	bctx := h.OverlayBuildContext(ctx, h.defaultBuildContext(), !h.init.NoOSFileSystemAccess)

	bpkg, err := ContainingPackage(bctx, filename)
	if mpErr, ok := err.(*build.MultiplePackageError); ok {
		bpkg, err = buildPackageForNamedFileInMultiPackageDir(bpkg, mpErr, filepath.Base(filename))
		if err != nil {
			return nil, nil, nil, err
		}
	} else if err != nil {
		return nil, nil, nil, err
	}

	// TODO(sqs): do all pkgs in workspace together?
	fset, prog, diags, err := h.cachedTypecheck(ctx, bctx, bpkg)
	if err != nil {
		return nil, nil, nil, err
	}

	if len(diags) > 0 {
		go func() {
			if err := h.publishDiagnostics(ctx, conn, diags); err != nil {
				log.Printf("warning: failed to send diagnostics: %s.", err)
			}
		}()
	}

	start := posForFileOffset(fset, filename, offset)
	if start == token.NoPos {
		return nil, nil, nil, fmt.Errorf("invalid location: %s:#%d", filename, offset)
	}

	pkg, nodes, _ := prog.PathEnclosingInterval(start, start)
	if len(nodes) == 0 {
		return nil, nil, nil, fmt.Errorf("no node found at %s offset %d", fset.Position(start), offset)
	}
	node, ok := nodes[0].(*ast.Ident)
	if !ok {
		lineCol := func(p token.Pos) string {
			pp := fset.Position(p)
			return fmt.Sprintf("%d:%d", pp.Line, pp.Column)
		}
		return nil, nil, nil, &invalidNodeError{
			Node: nodes[0],
			msg:  fmt.Sprintf("invalid node: %s (%s-%s)", reflect.TypeOf(nodes[0]).Elem(), lineCol(nodes[0].Pos()), lineCol(nodes[0].End())),
		}
	}
	return fset, node, pkg, nil
}

type invalidNodeError struct {
	Node ast.Node
	msg  string
}

func (e *invalidNodeError) Error() string {
	return e.msg
}

func posForFileOffset(fset *token.FileSet, filename string, offset int) token.Pos {
	var f *token.File
	fset.Iterate(func(ff *token.File) bool {
		if ff.Name() == filename {
			f = ff
			return false // break out of loop
		}
		return true
	})
	if f == nil {
		return token.NoPos
	}
	return f.Pos(offset)
}

// buildPackageForNamedFileInMultiPackageDir returns a package that
// refer to the package named by filename. If there are multiple
// (e.g.) main packages in a dir in separate files, this lets you
// synthesize a *build.Package that just refers to one. It's necessary
// to handle that case.
func buildPackageForNamedFileInMultiPackageDir(bpkg *build.Package, m *build.MultiplePackageError, filename string) (*build.Package, error) {
	copy := *bpkg
	bpkg = &copy

	// First, find which package name each filename is in.
	fileToPkgName := make(map[string]string, len(m.Files))
	for i, f := range m.Files {
		fileToPkgName[f] = m.Packages[i]
	}

	pkgName := fileToPkgName[filename]
	if pkgName == "" {
		return nil, fmt.Errorf("package %q in %s has no file %q", bpkg.ImportPath, bpkg.Dir, filename)
	}

	filterToFilesInPackage := func(files []string, pkgName string) []string {
		var keep []string
		for _, f := range files {
			if fileToPkgName[f] == pkgName {
				keep = append(keep, f)
			}
		}
		return keep
	}

	// Trim the *GoFiles fields to only those files in the same
	// package.
	bpkg.Name = pkgName
	if pkgName == "main" {
		// TODO(sqs): If the package name is "main", and there are
		// multiple main packages that are separate programs (and,
		// e.g., expected to be run directly run `go run main1.go
		// main2.go`), then this will break because it will try to
		// compile them all together. There's no good way to handle
		// that case that I can think of, other than with heuristics.
	}
	var nonXTestPkgName, xtestPkgName string
	if strings.HasSuffix(pkgName, "_test") {
		nonXTestPkgName = strings.TrimSuffix(pkgName, "_test")
		xtestPkgName = pkgName
	} else {
		nonXTestPkgName = pkgName
		xtestPkgName = pkgName + "_test"
	}
	bpkg.GoFiles = filterToFilesInPackage(bpkg.GoFiles, nonXTestPkgName)
	bpkg.TestGoFiles = filterToFilesInPackage(bpkg.TestGoFiles, nonXTestPkgName)
	bpkg.XTestGoFiles = filterToFilesInPackage(bpkg.XTestGoFiles, xtestPkgName)

	return bpkg, nil
}

type typecheckKey struct {
	importPath, srcDir, name string

	// TODO(sqs): needs to include a list of files in the key...there
	// can be multiple packages (e.g., build-tag-disabled main.go
	// files) with the same names

	// TODO(sqs): include build context in key
}

type typecheckResult struct {
	fset *token.FileSet
	prog *loader.Program
	err  error
}

func (h *LangHandler) typecheckMu(k typecheckKey) *sync.Mutex {
	h.mu.Lock()
	mu, ok := h.cacheMus[k]
	if !ok {
		mu = new(sync.Mutex)
		h.cacheMus[k] = mu
	}
	h.mu.Unlock()
	return mu
}

func (h *LangHandler) cachedTypecheck(ctx context.Context, bctx *build.Context, bpkg *build.Package) (*token.FileSet, *loader.Program, diagnostics, error) {
	parentSpan := opentracing.SpanFromContext(ctx)
	span := parentSpan.Tracer().StartSpan("langserver-go: typecheck",
		opentracing.Tags{"pkg": bpkg.ImportPath},
		opentracing.ChildOf(parentSpan.Context()),
	)
	ctx = opentracing.ContextWithSpan(ctx, span)
	defer span.Finish()

	k := typecheckKey{bpkg.ImportPath, bpkg.Dir, bpkg.Name}

	mu := h.typecheckMu(k)
	mu.Lock()
	defer mu.Unlock()

	res, ok := h.cache[k]
	span.SetTag("cached", ok)
	var diags diagnostics
	if !ok {
		res.fset = token.NewFileSet()
		res.prog, diags, res.err = typecheck(res.fset, bctx, bpkg)
		h.cache[k] = res
	}
	return res.fset, res.prog, diags, res.err
}

// TODO(sqs): allow typechecking just a specific file not in a package, too
func typecheck(fset *token.FileSet, bctx *build.Context, bpkg *build.Package) (*loader.Program, diagnostics, error) {
	var typeErrs []error
	conf := loader.Config{
		Fset: fset,
		TypeChecker: types.Config{
			DisableUnusedImportCheck: true,
			FakeImportC:              true,
			Error: func(err error) {
				typeErrs = append(typeErrs, err)
			},
		},
		Build:       bctx,
		Cwd:         bpkg.Dir,
		AllowErrors: true,
		TypeCheckFuncBodies: func(p string) bool {
			return bpkg.ImportPath == p
		},
		ParserMode: parser.AllErrors, // prevent parser from bailing out
		FindPackage: func(bctx *build.Context, importPath, fromDir string, mode build.ImportMode) (*build.Package, error) {
			// When importing a package, ignore any
			// MultipleGoErrors. This occurs, e.g., when you have a
			// main.go with "// +build ignore" that imports the
			// non-main package in the same dir.
			bpkg, err := bctx.Import(importPath, fromDir, mode)
			if err != nil && !isMultiplePackageError(err) {
				return bpkg, err
			}
			return bpkg, nil
		},
	}

	// For efficiency, we zero out unnecessary
	// results to save memory.
	//
	// TODO(sqs): investigate other ways to speed this up using
	// AfterTypeCheck; see
	// https://sourcegraph.com/github.com/golang/tools@5ffc3249d341c947aa65178abbf2253ed49c9e03/-/blob/cmd/guru/referrers.go#L148.
	conf.AfterTypeCheck = func(info *loader.PackageInfo, files []*ast.File) {
		if !conf.TypeCheckFuncBodies(info.Pkg.Path()) {
			clearInfoFields(info)
		}
	}

	var goFiles []string
	goFiles = append(goFiles, bpkg.GoFiles...)
	goFiles = append(goFiles, bpkg.TestGoFiles...)
	if strings.HasSuffix(bpkg.Name, "_test") {
		goFiles = append(goFiles, bpkg.XTestGoFiles...)
	}
	for i, filename := range goFiles {
		goFiles[i] = filepath.Join(bpkg.Dir, filename)
	}
	conf.CreateFromFilenames(bpkg.ImportPath, goFiles...)
	prog, err := conf.Load()
	if err != nil && prog == nil {
		return nil, nil, err
	}

	var diags diagnostics
	for _, e := range typeErrs {
		if diags == nil {
			diags = diagnostics{}
		}
		filename, diag, err := parseLoaderError(e.Error())
		if err != nil {
			return nil, nil, err
		}
		diags[filename] = append(diags[filename], diag)
	}

	return prog, diags, nil
}

func clearInfoFields(info *loader.PackageInfo) {
	// TODO(adonovan): opt: save memory by eliminating unneeded scopes/objects.
	// (Requires go/types change for Go 1.7.)
	//   info.Pkg.Scope().ClearChildren()

	// Discard the file ASTs and their accumulated type
	// information to save memory.
	info.Files = nil
	info.Defs = make(map[*ast.Ident]types.Object)
	info.Uses = make(map[*ast.Ident]types.Object)
	info.Implicits = make(map[ast.Node]types.Object)

	// Also, disable future collection of wholly unneeded
	// type information for the package in case there is
	// more type-checking to do (augmentation).
	info.Types = nil
	info.Scopes = nil
	info.Selections = nil
}

func isMultiplePackageError(err error) bool {
	_, ok := err.(*build.MultiplePackageError)
	return ok
}
<commit_msg>langserver: inline typecheckMu + protect against concurrent writes to h.cache<commit_after>package langserver

import (
	"context"
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"go/types"
	"log"
	"path/filepath"
	"reflect"
	"strings"
	"sync"

	opentracing "github.com/opentracing/opentracing-go"

	"github.com/sourcegraph/sourcegraph-go/pkg/lsp"

	"golang.org/x/tools/go/loader"
)

func (h *LangHandler) typecheck(ctx context.Context, conn JSONRPC2Conn, fileURI string, position lsp.Position) (*token.FileSet, *ast.Ident, *loader.PackageInfo, error) {
	parentSpan := opentracing.SpanFromContext(ctx)
	span := parentSpan.Tracer().StartSpan("langserver-go: load program",
		opentracing.Tags{"fileURI": fileURI},
		opentracing.ChildOf(parentSpan.Context()),
	)
	ctx = opentracing.ContextWithSpan(ctx, span)
	defer span.Finish()

	filename := h.FilePath(fileURI)

	contents, err := h.readFile(ctx, fileURI)
	if err != nil {
		return nil, nil, nil, err
	}
	offset, valid, why := offsetForPosition(contents, position)
	if !valid {
		return nil, nil, nil, fmt.Errorf("invalid position: %s:%d:%d (%s)", filename, position.Line, position.Character, why)
	}

	bctx := h.OverlayBuildContext(ctx, h.defaultBuildContext(), !h.init.NoOSFileSystemAccess)

	bpkg, err := ContainingPackage(bctx, filename)
	if mpErr, ok := err.(*build.MultiplePackageError); ok {
		bpkg, err = buildPackageForNamedFileInMultiPackageDir(bpkg, mpErr, filepath.Base(filename))
		if err != nil {
			return nil, nil, nil, err
		}
	} else if err != nil {
		return nil, nil, nil, err
	}

	// TODO(sqs): do all pkgs in workspace together?
	fset, prog, diags, err := h.cachedTypecheck(ctx, bctx, bpkg)
	if err != nil {
		return nil, nil, nil, err
	}

	if len(diags) > 0 {
		go func() {
			if err := h.publishDiagnostics(ctx, conn, diags); err != nil {
				log.Printf("warning: failed to send diagnostics: %s.", err)
			}
		}()
	}

	start := posForFileOffset(fset, filename, offset)
	if start == token.NoPos {
		return nil, nil, nil, fmt.Errorf("invalid location: %s:#%d", filename, offset)
	}

	pkg, nodes, _ := prog.PathEnclosingInterval(start, start)
	if len(nodes) == 0 {
		return nil, nil, nil, fmt.Errorf("no node found at %s offset %d", fset.Position(start), offset)
	}
	node, ok := nodes[0].(*ast.Ident)
	if !ok {
		lineCol := func(p token.Pos) string {
			pp := fset.Position(p)
			return fmt.Sprintf("%d:%d", pp.Line, pp.Column)
		}
		return nil, nil, nil, &invalidNodeError{
			Node: nodes[0],
			msg:  fmt.Sprintf("invalid node: %s (%s-%s)", reflect.TypeOf(nodes[0]).Elem(), lineCol(nodes[0].Pos()), lineCol(nodes[0].End())),
		}
	}
	return fset, node, pkg, nil
}

type invalidNodeError struct {
	Node ast.Node
	msg  string
}

func (e *invalidNodeError) Error() string {
	return e.msg
}

func posForFileOffset(fset *token.FileSet, filename string, offset int) token.Pos {
	var f *token.File
	fset.Iterate(func(ff *token.File) bool {
		if ff.Name() == filename {
			f = ff
			return false // break out of loop
		}
		return true
	})
	if f == nil {
		return token.NoPos
	}
	return f.Pos(offset)
}

// buildPackageForNamedFileInMultiPackageDir returns a package that
// refer to the package named by filename. If there are multiple
// (e.g.) main packages in a dir in separate files, this lets you
// synthesize a *build.Package that just refers to one. It's necessary
// to handle that case.
func buildPackageForNamedFileInMultiPackageDir(bpkg *build.Package, m *build.MultiplePackageError, filename string) (*build.Package, error) {
	copy := *bpkg
	bpkg = &copy

	// First, find which package name each filename is in.
	fileToPkgName := make(map[string]string, len(m.Files))
	for i, f := range m.Files {
		fileToPkgName[f] = m.Packages[i]
	}

	pkgName := fileToPkgName[filename]
	if pkgName == "" {
		return nil, fmt.Errorf("package %q in %s has no file %q", bpkg.ImportPath, bpkg.Dir, filename)
	}

	filterToFilesInPackage := func(files []string, pkgName string) []string {
		var keep []string
		for _, f := range files {
			if fileToPkgName[f] == pkgName {
				keep = append(keep, f)
			}
		}
		return keep
	}

	// Trim the *GoFiles fields to only those files in the same
	// package.
	bpkg.Name = pkgName
	if pkgName == "main" {
		// TODO(sqs): If the package name is "main", and there are
		// multiple main packages that are separate programs (and,
		// e.g., expected to be run directly run `go run main1.go
		// main2.go`), then this will break because it will try to
		// compile them all together. There's no good way to handle
		// that case that I can think of, other than with heuristics.
	}
	var nonXTestPkgName, xtestPkgName string
	if strings.HasSuffix(pkgName, "_test") {
		nonXTestPkgName = strings.TrimSuffix(pkgName, "_test")
		xtestPkgName = pkgName
	} else {
		nonXTestPkgName = pkgName
		xtestPkgName = pkgName + "_test"
	}
	bpkg.GoFiles = filterToFilesInPackage(bpkg.GoFiles, nonXTestPkgName)
	bpkg.TestGoFiles = filterToFilesInPackage(bpkg.TestGoFiles, nonXTestPkgName)
	bpkg.XTestGoFiles = filterToFilesInPackage(bpkg.XTestGoFiles, xtestPkgName)

	return bpkg, nil
}

type typecheckKey struct {
	importPath, srcDir, name string

	// TODO(sqs): needs to include a list of files in the key...there
	// can be multiple packages (e.g., build-tag-disabled main.go
	// files) with the same names

	// TODO(sqs): include build context in key
}

type typecheckResult struct {
	fset *token.FileSet
	prog *loader.Program
	err  error
}

func (h *LangHandler) cachedTypecheck(ctx context.Context, bctx *build.Context, bpkg *build.Package) (*token.FileSet, *loader.Program, diagnostics, error) {
	parentSpan := opentracing.SpanFromContext(ctx)
	span := parentSpan.Tracer().StartSpan("langserver-go: typecheck",
		opentracing.Tags{"pkg": bpkg.ImportPath},
		opentracing.ChildOf(parentSpan.Context()),
	)
	ctx = opentracing.ContextWithSpan(ctx, span)
	defer span.Finish()

	k := typecheckKey{bpkg.ImportPath, bpkg.Dir, bpkg.Name}

	// Acquire a per-K mutex. This prevents us from doing duplicate work to
	// prepare K. It does not, however, protect against concurrent writes by
	// multiple K's to h.cache (we use h.mu for that).
	h.mu.Lock()
	kmu, ok := h.cacheMus[k]
	if !ok {
		kmu = new(sync.Mutex)
		h.cacheMus[k] = kmu
	}
	h.mu.Unlock()

	kmu.Lock()
	defer kmu.Unlock()

	h.mu.Lock()
	res, ok := h.cache[k]
	h.mu.Unlock()
	span.SetTag("cached", ok)
	var diags diagnostics
	if !ok {
		res.fset = token.NewFileSet()
		res.prog, diags, res.err = typecheck(res.fset, bctx, bpkg)
		h.mu.Lock()
		h.cache[k] = res
		h.mu.Unlock()
	}
	return res.fset, res.prog, diags, res.err
}

// TODO(sqs): allow typechecking just a specific file not in a package, too
func typecheck(fset *token.FileSet, bctx *build.Context, bpkg *build.Package) (*loader.Program, diagnostics, error) {
	var typeErrs []error
	conf := loader.Config{
		Fset: fset,
		TypeChecker: types.Config{
			DisableUnusedImportCheck: true,
			FakeImportC:              true,
			Error: func(err error) {
				typeErrs = append(typeErrs, err)
			},
		},
		Build:       bctx,
		Cwd:         bpkg.Dir,
		AllowErrors: true,
		TypeCheckFuncBodies: func(p string) bool {
			return bpkg.ImportPath == p
		},
		ParserMode: parser.AllErrors, // prevent parser from bailing out
		FindPackage: func(bctx *build.Context, importPath, fromDir string, mode build.ImportMode) (*build.Package, error) {
			// When importing a package, ignore any
			// MultipleGoErrors. This occurs, e.g., when you have a
			// main.go with "// +build ignore" that imports the
			// non-main package in the same dir.
			bpkg, err := bctx.Import(importPath, fromDir, mode)
			if err != nil && !isMultiplePackageError(err) {
				return bpkg, err
			}
			return bpkg, nil
		},
	}

	// For efficiency, we zero out unnecessary
	// results to save memory.
	//
	// TODO(sqs): investigate other ways to speed this up using
	// AfterTypeCheck; see
	// https://sourcegraph.com/github.com/golang/tools@5ffc3249d341c947aa65178abbf2253ed49c9e03/-/blob/cmd/guru/referrers.go#L148.
	conf.AfterTypeCheck = func(info *loader.PackageInfo, files []*ast.File) {
		if !conf.TypeCheckFuncBodies(info.Pkg.Path()) {
			clearInfoFields(info)
		}
	}

	var goFiles []string
	goFiles = append(goFiles, bpkg.GoFiles...)
	goFiles = append(goFiles, bpkg.TestGoFiles...)
	if strings.HasSuffix(bpkg.Name, "_test") {
		goFiles = append(goFiles, bpkg.XTestGoFiles...)
	}
	for i, filename := range goFiles {
		goFiles[i] = filepath.Join(bpkg.Dir, filename)
	}
	conf.CreateFromFilenames(bpkg.ImportPath, goFiles...)
	prog, err := conf.Load()
	if err != nil && prog == nil {
		return nil, nil, err
	}

	var diags diagnostics
	for _, e := range typeErrs {
		if diags == nil {
			diags = diagnostics{}
		}
		filename, diag, err := parseLoaderError(e.Error())
		if err != nil {
			return nil, nil, err
		}
		diags[filename] = append(diags[filename], diag)
	}

	return prog, diags, nil
}

func clearInfoFields(info *loader.PackageInfo) {
	// TODO(adonovan): opt: save memory by eliminating unneeded scopes/objects.
	// (Requires go/types change for Go 1.7.)
	//   info.Pkg.Scope().ClearChildren()

	// Discard the file ASTs and their accumulated type
	// information to save memory.
	info.Files = nil
	info.Defs = make(map[*ast.Ident]types.Object)
	info.Uses = make(map[*ast.Ident]types.Object)
	info.Implicits = make(map[ast.Node]types.Object)

	// Also, disable future collection of wholly unneeded
	// type information for the package in case there is
	// more type-checking to do (augmentation).
	info.Types = nil
	info.Scopes = nil
	info.Selections = nil
}

func isMultiplePackageError(err error) bool {
	_, ok := err.(*build.MultiplePackageError)
	return ok
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/crooks/yamn/idlog"
	"github.com/crooks/yamn/keymgr"
	"github.com/luksen/maildir"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"
)

const (
	version        string = "0.2c"
	dayLength      int    = 24 * 60 * 60 // Day in seconds
	maxFragLength         = 17910
	maxCopies             = 5
	base64LineWrap        = 64
	rfc5322date           = "Mon, 2 Jan 2006 15:04:05 -0700"
	shortdate             = "2 Jan 2006"
)

var (
	Trace   *log.Logger
	Info    *log.Logger
	Warn    *log.Logger
	Error   *log.Logger
	Pubring *keymgr.Pubring
	IdDb    *idlog.IDLog
	ChunkDb *Chunk
)

func logInit(
	traceHandle io.Writer,
	infoHandle io.Writer,
	warnHandle io.Writer,
	errorHandle io.Writer) {

	Trace = log.New(traceHandle,
		"Trace: ",
		log.Ldate|log.Ltime|log.Lshortfile)

	Info = log.New(infoHandle,
		"Info: ",
		log.Ldate|log.Ltime|log.Lshortfile)

	Warn = log.New(warnHandle,
		"Warn: ",
		log.Ldate|log.Ltime|log.Lshortfile)

	Error = log.New(errorHandle,
		"Error: ",
		log.Ldate|log.Ltime|log.Lshortfile)
}

func main() {
	var err error
	flags()
	if cfg.General.LogToFile {
		logfile, err := os.OpenFile(
			cfg.Files.Logfile,
			os.O_RDWR|os.O_CREATE|os.O_APPEND,
			0640,
		)
		if err != nil {
			fmt.Fprintf(
				os.Stderr,
				"Error opening logfile: %s.\n",
				err,
			)
			os.Exit(1)
		}
		switch strings.ToLower(cfg.General.Loglevel) {
		case "trace":
			logInit(logfile,
				logfile,
				logfile,
				logfile,
			)
		case "info":
			logInit(ioutil.Discard,
				logfile,
				logfile,
				logfile,
			)
		case "warn":
			logInit(ioutil.Discard,
				ioutil.Discard,
				logfile,
				logfile,
			)
		case "error":
			logInit(ioutil.Discard,
				ioutil.Discard,
				ioutil.Discard,
				logfile,
			)
		default:
			fmt.Fprintf(
				os.Stderr,
				"Unknown loglevel: %s.  Assuming \"Info\".\n",
				cfg.General.Loglevel,
			)
			logInit(ioutil.Discard,
				logfile,
				logfile,
				logfile,
			)
		}
	} else {
		switch strings.ToLower(cfg.General.Loglevel) {
		case "trace":
			logInit(os.Stdout,
				os.Stdout,
				os.Stdout,
				os.Stderr,
			)
		case "info":
			logInit(ioutil.Discard,
				os.Stdout,
				os.Stdout,
				os.Stderr,
			)
		case "warn":
			logInit(ioutil.Discard,
				ioutil.Discard,
				os.Stdout,
				os.Stderr,
			)
		case "error":
			logInit(
				ioutil.Discard,
				ioutil.Discard,
				ioutil.Discard,
				os.Stderr,
			)
		default:
			fmt.Fprintf(
				os.Stderr,
				"Unknown loglevel: %s.  Assuming \"Info\".\n",
				cfg.General.Loglevel,
			)
			logInit(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)
		} // End of stdout/stderr logging setup
	} // End of logging setup
	if flag_client {
		mixprep()
	} else if flag_stdin {
		dir := maildir.Dir(cfg.Files.Maildir)
		newmsg, err := dir.NewDelivery()
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		stdin, err := ioutil.ReadAll(os.Stdin)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		newmsg.Write(stdin)
		newmsg.Close()
	} else if flag_remailer {
		err = loopServer()
		if err != nil {
			panic(err)
		}
	} else if flag_dummy {
		injectDummy()
	}
	if flag_send {
		// Flush the outbound pool
		poolOutboundSend()
	}
	if flag_debug {
		j, err := json.MarshalIndent(cfg, "", "    ")
		if err != nil {
			fmt.Printf("Debugging Error: %s\n", err)
			os.Exit(1)
		}
		fmt.Printf("%s\n", j)
	}
}
<commit_msg>When debugging the config, don't do anything else.<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/crooks/yamn/idlog"
	"github.com/crooks/yamn/keymgr"
	"github.com/luksen/maildir"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"
)

const (
	version        string = "0.2c"
	dayLength      int    = 24 * 60 * 60 // Day in seconds
	maxFragLength         = 17910
	maxCopies             = 5
	base64LineWrap        = 64
	rfc5322date           = "Mon, 2 Jan 2006 15:04:05 -0700"
	shortdate             = "2 Jan 2006"
)

var (
	Trace   *log.Logger
	Info    *log.Logger
	Warn    *log.Logger
	Error   *log.Logger
	Pubring *keymgr.Pubring
	IdDb    *idlog.IDLog
	ChunkDb *Chunk
)

func logInit(
	traceHandle io.Writer,
	infoHandle io.Writer,
	warnHandle io.Writer,
	errorHandle io.Writer) {

	Trace = log.New(traceHandle,
		"Trace: ",
		log.Ldate|log.Ltime|log.Lshortfile)

	Info = log.New(infoHandle,
		"Info: ",
		log.Ldate|log.Ltime|log.Lshortfile)

	Warn = log.New(warnHandle,
		"Warn: ",
		log.Ldate|log.Ltime|log.Lshortfile)

	Error = log.New(errorHandle,
		"Error: ",
		log.Ldate|log.Ltime|log.Lshortfile)
}

func main() {
	var err error
	flags()
	if cfg.General.LogToFile {
		logfile, err := os.OpenFile(
			cfg.Files.Logfile,
			os.O_RDWR|os.O_CREATE|os.O_APPEND,
			0640,
		)
		if err != nil {
			fmt.Fprintf(
				os.Stderr,
				"Error opening logfile: %s.\n",
				err,
			)
			os.Exit(1)
		}
		switch strings.ToLower(cfg.General.Loglevel) {
		case "trace":
			logInit(logfile,
				logfile,
				logfile,
				logfile,
			)
		case "info":
			logInit(ioutil.Discard,
				logfile,
				logfile,
				logfile,
			)
		case "warn":
			logInit(ioutil.Discard,
				ioutil.Discard,
				logfile,
				logfile,
			)
		case "error":
			logInit(ioutil.Discard,
				ioutil.Discard,
				ioutil.Discard,
				logfile,
			)
		default:
			fmt.Fprintf(
				os.Stderr,
				"Unknown loglevel: %s.  Assuming \"Info\".\n",
				cfg.General.Loglevel,
			)
			logInit(ioutil.Discard,
				logfile,
				logfile,
				logfile,
			)
		}
	} else {
		switch strings.ToLower(cfg.General.Loglevel) {
		case "trace":
			logInit(os.Stdout,
				os.Stdout,
				os.Stdout,
				os.Stderr,
			)
		case "info":
			logInit(ioutil.Discard,
				os.Stdout,
				os.Stdout,
				os.Stderr,
			)
		case "warn":
			logInit(ioutil.Discard,
				ioutil.Discard,
				os.Stdout,
				os.Stderr,
			)
		case "error":
			logInit(
				ioutil.Discard,
				ioutil.Discard,
				ioutil.Discard,
				os.Stderr,
			)
		default:
			fmt.Fprintf(
				os.Stderr,
				"Unknown loglevel: %s.  Assuming \"Info\".\n",
				cfg.General.Loglevel,
			)
			logInit(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)
		} // End of stdout/stderr logging setup
	} // End of logging setup

	// If the debug flag is set, print the config in JSON format and then exit.
	if flag_debug {
		j, err := json.MarshalIndent(cfg, "", "    ")
		if err != nil {
			fmt.Printf("Debugging Error: %s\n", err)
			os.Exit(1)
		}
		fmt.Printf("%s\n", j)
		os.Exit(0)
	}

	if flag_client {
		mixprep()
	} else if flag_stdin {
		dir := maildir.Dir(cfg.Files.Maildir)
		newmsg, err := dir.NewDelivery()
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		stdin, err := ioutil.ReadAll(os.Stdin)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		newmsg.Write(stdin)
		newmsg.Close()
	} else if flag_remailer {
		err = loopServer()
		if err != nil {
			panic(err)
		}
	} else if flag_dummy {
		injectDummy()
	}
	if flag_send {
		// Flush the outbound pool
		poolOutboundSend()
	}
}
<|endoftext|>


<commit_before>package api

import (
	"context"
	"net/http"

	"github.com/gorilla/mux"

	"github.com/ovh/cds/engine/api/project"
	"github.com/ovh/cds/engine/api/repositoriesmanager"
	"github.com/ovh/cds/engine/api/workflow"
	"github.com/ovh/cds/sdk"
)

func (api *API) getWorkflowHooksHandler() Handler {
	return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		hooks, err := workflow.LoadAllHooks(api.mustDB())
		if err != nil {
			return sdk.WrapError(err, "getWorkflowHooksHandler")
		}

		return WriteJSON(w, hooks, http.StatusOK)
	}
}

func (api *API) getWorkflowHookModelsHandler() Handler {
	return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		vars := mux.Vars(r)
		key := vars["key"]
		workflowName := vars["permWorkflowName"]
		nodeID, errN := requestVarInt(r, "nodeID")
		if errN != nil {
			return sdk.WrapError(errN, "getWorkflowHookModelsHandler")
		}

		p, errP := project.Load(api.mustDB(), api.Cache, key, getUser(ctx))
		if errP != nil {
			return sdk.WrapError(errP, "getWorkflowHookModelsHandler > project.Load")
		}

		wf, errW := workflow.Load(api.mustDB(), api.Cache, key, workflowName, getUser(ctx), workflow.LoadOptions{})
		if errW != nil {
			return sdk.WrapError(errW, "getWorkflowHookModelsHandler > workflow.Load")
		}

		node := wf.GetNode(nodeID)
		if node == nil {
			return sdk.WrapError(sdk.ErrWorkflowNodeNotFound, "getWorkflowHookModelsHandler")
		}

		m, err := workflow.LoadHookModels(api.mustDB())
		if err != nil {
			return sdk.WrapError(err, "getWorkflowHookModelsHandler")
		}

		// Post processing  on repositoryWebHook
		hasRepoManager := false
		repoWebHookEnable := false
		if node.Context.Application != nil && node.Context.Application.RepositoryFullname != "" {
			hasRepoManager = true
		}
		var webHookInfo repositoriesmanager.WebhooksInfos
		if hasRepoManager {
			// Call VCS to know if repository allows webhook and get the configuration fields
			vcsServer := repositoriesmanager.GetProjectVCSServer(p, node.Context.Application.VCSServer)
			if vcsServer != nil {
				client, errclient := repositoriesmanager.AuthorizedClient(api.mustDB(), api.Cache, vcsServer)
				if errclient != nil {
					return sdk.WrapError(errclient, "getWorkflowHookModelsHandler> Cannot get vcs client")
				}
				var errWH error
				webHookInfo, errWH = repositoriesmanager.GetWebhooksInfos(client)
				if errWH != nil {
					return sdk.WrapError(errWH, "getWorkflowHookModelsHandler> Cannot get vcs web hook info")
				}
				repoWebHookEnable = webHookInfo.WebhooksSupported && !webHookInfo.WebhooksDisabled
			}
		}

		indexToDelete := -1
		for i := range m {
			if m[i].Name == sdk.RepositoryWebHookModelName {
				if !repoWebHookEnable {
					indexToDelete = i
					break
				} else {
					m[i].Icon = webHookInfo.Icon
				}
			}

		}
		if indexToDelete > -1 {
			m = append(m[0:indexToDelete], m[indexToDelete+1:]...)
		}

		return WriteJSON(w, m, http.StatusOK)
	}
}

func (api *API) getWorkflowHookModelHandler() Handler {
	return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		vars := mux.Vars(r)
		name := vars["model"]
		m, err := workflow.LoadHookModelByName(api.mustDB(), name)
		if err != nil {
			return sdk.WrapError(err, "getWorkflowHookModelHandler")
		}
		return WriteJSON(w, m, http.StatusOK)
	}
}

func (api *API) postWorkflowHookModelHandler() Handler {
	return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		m := &sdk.WorkflowHookModel{}
		if err := UnmarshalBody(r, m); err != nil {
			return sdk.WrapError(err, "postWorkflowHookModelHandler")
		}

		tx, errtx := api.mustDB().Begin()
		if errtx != nil {
			return sdk.WrapError(errtx, "postWorkflowHookModelHandler> Unable to start transaction")
		}
		defer tx.Rollback()

		if err := workflow.InsertHookModel(tx, m); err != nil {
			return sdk.WrapError(err, "postWorkflowHookModelHandler")
		}

		if err := tx.Commit(); err != nil {
			return sdk.WrapError(err, "postWorkflowHookModelHandler> Unable to commit transaction")
		}

		return WriteJSON(w, m, http.StatusCreated)
	}
}

func (api *API) putWorkflowHookModelHandler() Handler {
	return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		m := &sdk.WorkflowHookModel{}
		if err := UnmarshalBody(r, m); err != nil {
			return err
		}

		tx, errtx := api.mustDB().Begin()
		if errtx != nil {
			return sdk.WrapError(errtx, "putWorkflowHookModelHandler> Unable to start transaction")
		}

		defer tx.Rollback()

		if err := workflow.UpdateHookModel(tx, m); err != nil {
			return sdk.WrapError(err, "putWorkflowHookModelHandler")
		}

		if err := tx.Commit(); err != nil {
			return sdk.WrapError(errtx, "putWorkflowHookModelHandler> Unable to commit transaction")
		}

		return WriteJSON(w, m, http.StatusOK)
	}
}
<commit_msg>fix (ui): don't always display repo poller #2258 (#2261)<commit_after>package api

import (
	"context"
	"net/http"

	"github.com/gorilla/mux"

	"github.com/ovh/cds/engine/api/project"
	"github.com/ovh/cds/engine/api/repositoriesmanager"
	"github.com/ovh/cds/engine/api/workflow"
	"github.com/ovh/cds/sdk"
)

func (api *API) getWorkflowHooksHandler() Handler {
	return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		hooks, err := workflow.LoadAllHooks(api.mustDB())
		if err != nil {
			return sdk.WrapError(err, "getWorkflowHooksHandler")
		}

		return WriteJSON(w, hooks, http.StatusOK)
	}
}

func (api *API) getWorkflowHookModelsHandler() Handler {
	return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		vars := mux.Vars(r)
		key := vars["key"]
		workflowName := vars["permWorkflowName"]
		nodeID, errN := requestVarInt(r, "nodeID")
		if errN != nil {
			return sdk.WrapError(errN, "getWorkflowHookModelsHandler")
		}

		p, errP := project.Load(api.mustDB(), api.Cache, key, getUser(ctx))
		if errP != nil {
			return sdk.WrapError(errP, "getWorkflowHookModelsHandler > project.Load")
		}

		wf, errW := workflow.Load(api.mustDB(), api.Cache, key, workflowName, getUser(ctx), workflow.LoadOptions{})
		if errW != nil {
			return sdk.WrapError(errW, "getWorkflowHookModelsHandler > workflow.Load")
		}

		node := wf.GetNode(nodeID)
		if node == nil {
			return sdk.WrapError(sdk.ErrWorkflowNodeNotFound, "getWorkflowHookModelsHandler")
		}

		m, err := workflow.LoadHookModels(api.mustDB())
		if err != nil {
			return sdk.WrapError(err, "getWorkflowHookModelsHandler")
		}

		// Post processing  on repositoryWebHook
		hasRepoManager := false
		repoWebHookEnable, repoPollerEnable := false, false
		if node.Context.Application != nil && node.Context.Application.RepositoryFullname != "" {
			hasRepoManager = true
		}
		var webHookInfo repositoriesmanager.WebhooksInfos
		if hasRepoManager {
			// Call VCS to know if repository allows webhook and get the configuration fields
			vcsServer := repositoriesmanager.GetProjectVCSServer(p, node.Context.Application.VCSServer)
			if vcsServer != nil {
				client, errclient := repositoriesmanager.AuthorizedClient(api.mustDB(), api.Cache, vcsServer)
				if errclient != nil {
					return sdk.WrapError(errclient, "getWorkflowHookModelsHandler> Cannot get vcs client")
				}
				var errWH error
				webHookInfo, errWH = repositoriesmanager.GetWebhooksInfos(client)
				if errWH != nil {
					return sdk.WrapError(errWH, "getWorkflowHookModelsHandler> Cannot get vcs web hook info")
				}
				repoWebHookEnable = webHookInfo.WebhooksSupported && !webHookInfo.WebhooksDisabled

				pollInfo, errPoll := repositoriesmanager.GetPollingInfos(client)
				if errPoll != nil {
					return sdk.WrapError(errPoll, "getWorkflowHookModelsHandler> Cannot get vcs poller info")
				}
				repoPollerEnable = pollInfo.PollingSupported && !pollInfo.PollingDisabled
			}
		}

		models := []sdk.WorkflowHookModel{}
		for i := range m {
			switch m[i].Name {
			case sdk.RepositoryWebHookModelName:
				if repoWebHookEnable {
					m[i].Icon = webHookInfo.Icon
					models = append(models, m[i])
				}
			case sdk.GitPollerModelName:
				if repoPollerEnable {
					models = append(models, m[i])
				}
			default:
				models = append(models, m[i])
			}
		}

		return WriteJSON(w, models, http.StatusOK)
	}
}

func (api *API) getWorkflowHookModelHandler() Handler {
	return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		vars := mux.Vars(r)
		name := vars["model"]
		m, err := workflow.LoadHookModelByName(api.mustDB(), name)
		if err != nil {
			return sdk.WrapError(err, "getWorkflowHookModelHandler")
		}
		return WriteJSON(w, m, http.StatusOK)
	}
}

func (api *API) postWorkflowHookModelHandler() Handler {
	return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		m := &sdk.WorkflowHookModel{}
		if err := UnmarshalBody(r, m); err != nil {
			return sdk.WrapError(err, "postWorkflowHookModelHandler")
		}

		tx, errtx := api.mustDB().Begin()
		if errtx != nil {
			return sdk.WrapError(errtx, "postWorkflowHookModelHandler> Unable to start transaction")
		}
		defer tx.Rollback()

		if err := workflow.InsertHookModel(tx, m); err != nil {
			return sdk.WrapError(err, "postWorkflowHookModelHandler")
		}

		if err := tx.Commit(); err != nil {
			return sdk.WrapError(err, "postWorkflowHookModelHandler> Unable to commit transaction")
		}

		return WriteJSON(w, m, http.StatusCreated)
	}
}

func (api *API) putWorkflowHookModelHandler() Handler {
	return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		m := &sdk.WorkflowHookModel{}
		if err := UnmarshalBody(r, m); err != nil {
			return err
		}

		tx, errtx := api.mustDB().Begin()
		if errtx != nil {
			return sdk.WrapError(errtx, "putWorkflowHookModelHandler> Unable to start transaction")
		}

		defer tx.Rollback()

		if err := workflow.UpdateHookModel(tx, m); err != nil {
			return sdk.WrapError(err, "putWorkflowHookModelHandler")
		}

		if err := tx.Commit(); err != nil {
			return sdk.WrapError(errtx, "putWorkflowHookModelHandler> Unable to commit transaction")
		}

		return WriteJSON(w, m, http.StatusOK)
	}
}
<|endoftext|>


<commit_before>package ztex

import (
	"fmt"
	"strings"
)

// FlashEnabled indicates whether or not the flash is enabled.
type FlashEnabled uint8

// String returns a human-readable description of whether or not the
// flash is enabled.
func (f FlashEnabled) String() string {
	switch f {
	case 0:
		return "Disabled"
	case 1:
		return "Enabled"
	default:
		return "Unknown"
	}
}

// FlashSize represents the size of a sector in the flash.
type FlashSize [2]uint8

// String returns a human-readable description of the size of a sector
// in the flash.
func (f FlashSize) String() string { return binaryPrefix(uint64(f.Number()), "B") }

// Number returns the size of a sector in the flash.
func (f FlashSize) Number() uint16 { return bytesToUint16(f) }

// FlashCount represents the number of sectors in the flash.
type FlashCount [4]uint8

// String returns a human-readable description of the number of sectors
// in the flash.
func (f FlashCount) String() string { return fmt.Sprintf("%v", f.Number()) }

// Number returns the number of sectors in the flash.
func (f FlashCount) Number() uint32 { return bytesToUint32(f) }

// FlashError represents the error code in the flash.
type FlashError uint8

// FlashStatus indicates the current status of the flash.
type FlashStatus struct {
	FlashEnabled
	FlashSize
	FlashCount
	FlashError
}

// String returns a human-readable description of the flash status.
func (f FlashStatus) String() string {
	x := []string{}
	x = append(x, fmt.Sprintf("Enabled(%v)", f.FlashEnabled))
	x = append(x, fmt.Sprintf("Size(%v)", f.FlashSize))
	x = append(x, fmt.Sprintf("Count(%v)", f.FlashCount))
	x = append(x, fmt.Sprintf("Error(%v)", f.FlashError))
	return strings.Join(x, ", ")
}
<commit_msg>Compute flash sector size properly.<commit_after>package ztex

import (
	"fmt"
	"strings"
)

// FlashEnabled indicates whether or not the flash is enabled.
type FlashEnabled uint8

// String returns a human-readable description of whether or not the
// flash is enabled.
func (f FlashEnabled) String() string {
	switch f {
	case 0:
		return "Disabled"
	case 1:
		return "Enabled"
	default:
		return "Unknown"
	}
}

// FlashSize represents the size of a sector in the flash.
type FlashSize [2]uint8

// String returns a human-readable description of the size of a sector
// in the flash.
func (f FlashSize) String() string { return binaryPrefix(uint64(f.Number()), "B") }

// Number returns the size of a sector in the flash.
func (f FlashSize) Number() uint16 {
	z := bytesToUint16(f)
	if z&0x8000 == 0 {
		z = 1 << (z & 0x7fff)
	}
	return z
}

// FlashCount represents the number of sectors in the flash.
type FlashCount [4]uint8

// String returns a human-readable description of the number of sectors
// in the flash.
func (f FlashCount) String() string { return fmt.Sprintf("%v", f.Number()) }

// Number returns the number of sectors in the flash.
func (f FlashCount) Number() uint32 { return bytesToUint32(f) }

// FlashError represents the error code in the flash.
type FlashError uint8

// FlashStatus indicates the current status of the flash.
type FlashStatus struct {
	FlashEnabled
	FlashSize
	FlashCount
	FlashError
}

// String returns a human-readable description of the flash status.
func (f FlashStatus) String() string {
	x := []string{}
	x = append(x, fmt.Sprintf("Enabled(%v)", f.FlashEnabled))
	x = append(x, fmt.Sprintf("Size(%v)", f.FlashSize))
	x = append(x, fmt.Sprintf("Count(%v)", f.FlashCount))
	x = append(x, fmt.Sprintf("Error(%v)", f.FlashError))
	return strings.Join(x, ", ")
}
<|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 in the root of the source
// tree.

package layers

import (
	"github.com/google/gopacket"
	"testing"
)

// testPacketIPSecESP is the packet:
//   04:30:37.629376 IP 190.0.0.1 > 190.0.0.2: ESP(spi=0x0000006e,seq=0x13), length 116
//      0x0000:  0000 0000 0012 0011 434a d70a 0800 4500  ........CJ....E.
//      0x0010:  0088 0000 4000 4032 be40 be00 0001 be00  ....@.@2.@......
//      0x0020:  0002 0000 006e 0000 0013 82f4 1077 0418  .....n.......w..
//      0x0030:  e8ce dc45 1bac 22bb daaf 2ad2 c2e8 315b  ...E.."...*...1[
//      0x0040:  ce9a 39da 2aae cf43 3716 70ab 7e7c 4676  ..9.*..C7.p.~|Fv
//      0x0050:  c3fc d109 c990 274d f81c 6534 9a40 a0ef  ......'M..e4.@..
//      0x0060:  46b1 7da5 05af dda8 d0ba 6e23 d1ee 1f10  F.}.......n#....
//      0x0070:  730c 7371 03b1 445c 2f70 852f 8475 12fb  s.sq..D\/p./.u..
//      0x0080:  b057 a19b a617 bae7 09ca 8836 942f 3334  .W.........6./34
//      0x0090:  312b 96d2 a4e3                           1+....
var testPacketIPSecESP = []byte{
	0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x11, 0x43, 0x4a, 0xd7, 0x0a, 0x08, 0x00, 0x45, 0x00,
	0x00, 0x88, 0x00, 0x00, 0x40, 0x00, 0x40, 0x32, 0xbe, 0x40, 0xbe, 0x00, 0x00, 0x01, 0xbe, 0x00,
	0x00, 0x02, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x13, 0x82, 0xf4, 0x10, 0x77, 0x04, 0x18,
	0xe8, 0xce, 0xdc, 0x45, 0x1b, 0xac, 0x22, 0xbb, 0xda, 0xaf, 0x2a, 0xd2, 0xc2, 0xe8, 0x31, 0x5b,
	0xce, 0x9a, 0x39, 0xda, 0x2a, 0xae, 0xcf, 0x43, 0x37, 0x16, 0x70, 0xab, 0x7e, 0x7c, 0x46, 0x76,
	0xc3, 0xfc, 0xd1, 0x09, 0xc9, 0x90, 0x27, 0x4d, 0xf8, 0x1c, 0x65, 0x34, 0x9a, 0x40, 0xa0, 0xef,
	0x46, 0xb1, 0x7d, 0xa5, 0x05, 0xaf, 0xdd, 0xa8, 0xd0, 0xba, 0x6e, 0x23, 0xd1, 0xee, 0x1f, 0x10,
	0x73, 0x0c, 0x73, 0x71, 0x03, 0xb1, 0x44, 0x5c, 0x2f, 0x70, 0x85, 0x2f, 0x84, 0x75, 0x12, 0xfb,
	0xb0, 0x57, 0xa1, 0x9b, 0xa6, 0x17, 0xba, 0xe7, 0x09, 0xca, 0x88, 0x36, 0x94, 0x2f, 0x33, 0x34,
	0x31, 0x2b, 0x96, 0xd2, 0xa4, 0xe3,
}

func TestPacketIPSecESP(t *testing.T) {
	p := gopacket.NewPacket(testPacketIPSecESP, LinkTypeEthernet, gopacket.Default)
	if p.ErrorLayer() != nil {
		t.Error("Failed to decode packet:", p.ErrorLayer().Error())
	}
	checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeIPSecESP}, t)
}
func BenchmarkDecodePacketIPSecESP(b *testing.B) {
	for i := 0; i < b.N; i++ {
		gopacket.NewPacket(testPacketIPSecESP, LinkTypeEthernet, gopacket.NoCopy)
	}
}
<commit_msg>Add tests for IPsec AH decoding<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 in the root of the source
// tree.

package layers

import (
	"github.com/google/gopacket"
	"reflect"
	"testing"
)

// testPacketIPSecAHTransport is the packet:
//   20:45:10.325850 IP 192.168.1.1 > 192.168.1.2: AH(spi=0x00000101,seq=0x1): ICMP echo request, id 1560, seq 1, length 64
//      0x0000:  7ec0 ffc6 48f1 1a0e 3c4e 3b3a 0800 4500  ~...H...<N;:..E.
//      0x0010:  006c 650a 4000 4033 5201 c0a8 0101 c0a8  .le.@.@3R.......
//      0x0020:  0102 0104 0000 0000 0101 0000 0001 2533  ..............%3
//      0x0030:  01b1 a20b b6f1 bdbf 9d9e 0800 fbe5 0618  ................
//      0x0040:  0001 c6e1 a354 0000 0000 c8f7 0400 0000  .....T..........
//      0x0050:  0000 1011 1213 1415 1617 1819 1a1b 1c1d  ................
//      0x0060:  1e1f 2021 2223 2425 2627 2829 2a2b 2c2d  ...!"#$%&'()*+,-
//      0x0070:  2e2f 3031 3233 3435 3637                 ./01234567
var testPacketIPSecAHTransport = []byte{
	0x7e, 0xc0, 0xff, 0xc6, 0x48, 0xf1, 0x1a, 0x0e, 0x3c, 0x4e, 0x3b, 0x3a, 0x08, 0x00, 0x45, 0x00,
	0x00, 0x6c, 0x65, 0x0a, 0x40, 0x00, 0x40, 0x33, 0x52, 0x01, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8,
	0x01, 0x02, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x25, 0x33,
	0x01, 0xb1, 0xa2, 0x0b, 0xb6, 0xf1, 0xbd, 0xbf, 0x9d, 0x9e, 0x08, 0x00, 0xfb, 0xe5, 0x06, 0x18,
	0x00, 0x01, 0xc6, 0xe1, 0xa3, 0x54, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xf7, 0x04, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
	0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
	0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
}

func TestPacketIPSecAHTransport(t *testing.T) {
	p := gopacket.NewPacket(testPacketIPSecAHTransport, LinkTypeEthernet, gopacket.Default)
	if p.ErrorLayer() != nil {
		t.Error("Failed to decode packet:", p.ErrorLayer().Error())
	}
	checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeIPSecAH, LayerTypeICMPv4, gopacket.LayerTypePayload}, t)
	if got, ok := p.Layer(LayerTypeIPSecAH).(*IPSecAH); ok {
		want := &IPSecAH{
			Reserved:           0x0,
			SPI:                0x101,
			Seq:                1,
			AuthenticationData: []byte{0x25, 0x33, 0x01, 0xb1, 0xa2, 0x0b, 0xb6, 0xf1, 0xbd, 0xbf, 0x9d, 0x9e},
		}
		want.BaseLayer = BaseLayer{testPacketIPSecAHTransport[34:58], testPacketIPSecAHTransport[58:]}
		want.NextHeader = IPProtocolICMPv4
		want.HeaderLength = 0x4
		want.ActualLength = 0x18
		if !reflect.DeepEqual(want, got) {
			t.Errorf("IPSecAH layer mismatch, \nwant %#v\ngot  %#v\n", want, got)
		}
	}
}

func BenchmarkDecodePacketIPSecAHTransport(b *testing.B) {
	for i := 0; i < b.N; i++ {
		gopacket.NewPacket(testPacketIPSecAHTransport, LinkTypeEthernet, gopacket.NoCopy)
	}
}

// testPacketIPSecAHTunnel is the packet:
//   14:45:43.252917 IP 192.168.1.1 > 192.168.1.2: AH(spi=0x00000101,seq=0x1): IP 172.16.1.1 > 172.16.2.1: ICMP echo request, id 31322, seq 1, length 64 (ipip-proto-4)
//      0x0000:  7220 4d91 63c9 566c ed2d 73cd 0800 4500  r.M.c.Vl.-s...E.
//      0x0010:  0080 0000 4000 4033 b6f7 c0a8 0101 c0a8  ....@.@3........
//      0x0020:  0102 0404 0000 0000 0101 0000 0001 cca4  ................
//      0x0030:  01da 9eb4 fb75 10fe 5a59 4500 0054 a96f  .....u..ZYE..T.o
//      0x0040:  4000 4001 3617 ac10 0101 ac10 0201 0800  @.@.6...........
//      0x0050:  d75f 7a5a 0001 0741 3355 0000 0000 a9db  ._zZ...A3U......
//      0x0060:  0300 0000 0000 1011 1213 1415 1617 1819  ................
//      0x0070:  1a1b 1c1d 1e1f 2021 2223 2425 2627 2829  .......!"#$%&'()
//      0x0080:  2a2b 2c2d 2e2f 3031 3233 3435 3637       *+,-./01234567
var testPacketIPSecAHTunnel = []byte{
	0x72, 0x20, 0x4d, 0x91, 0x63, 0xc9, 0x56, 0x6c, 0xed, 0x2d, 0x73, 0xcd, 0x08, 0x00, 0x45, 0x00,
	0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x40, 0x33, 0xb6, 0xf7, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8,
	0x01, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0xcc, 0xa4,
	0x01, 0xda, 0x9e, 0xb4, 0xfb, 0x75, 0x10, 0xfe, 0x5a, 0x59, 0x45, 0x00, 0x00, 0x54, 0xa9, 0x6f,
	0x40, 0x00, 0x40, 0x01, 0x36, 0x17, 0xac, 0x10, 0x01, 0x01, 0xac, 0x10, 0x02, 0x01, 0x08, 0x00,
	0xd7, 0x5f, 0x7a, 0x5a, 0x00, 0x01, 0x07, 0x41, 0x33, 0x55, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xdb,
	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
	0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
	0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
}

func TestPacketIPSecAHTunnel(t *testing.T) {
	p := gopacket.NewPacket(testPacketIPSecAHTunnel, LinkTypeEthernet, gopacket.Default)
	if p.ErrorLayer() != nil {
		t.Error("Failed to decode packet:", p.ErrorLayer().Error())
	}
	checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeIPSecAH, LayerTypeIPv4, LayerTypeICMPv4, gopacket.LayerTypePayload}, t)
	if got, ok := p.Layer(LayerTypeIPSecAH).(*IPSecAH); ok {
		want := &IPSecAH{
			Reserved:           0x0,
			SPI:                0x101,
			Seq:                1,
			AuthenticationData: []byte{0xcc, 0xa4, 0x01, 0xda, 0x9e, 0xb4, 0xfb, 0x75, 0x10, 0xfe, 0x5a, 0x59},
		}
		want.BaseLayer = BaseLayer{testPacketIPSecAHTunnel[34:58], testPacketIPSecAHTunnel[58:]}
		want.NextHeader = IPProtocolIPv4
		want.HeaderLength = 0x4
		want.ActualLength = 0x18
		if !reflect.DeepEqual(want, got) {
			t.Errorf("IPSecAH layer mismatch, \nwant %#v\ngot  %#v\n", want, got)
		}
	}
}

func BenchmarkDecodePacketIPSecAHTunnel(b *testing.B) {
	for i := 0; i < b.N; i++ {
		gopacket.NewPacket(testPacketIPSecAHTunnel, LinkTypeEthernet, gopacket.NoCopy)
	}
}

// testPacketIPSecESP is the packet:
//   04:30:37.629376 IP 190.0.0.1 > 190.0.0.2: ESP(spi=0x0000006e,seq=0x13), length 116
//      0x0000:  0000 0000 0012 0011 434a d70a 0800 4500  ........CJ....E.
//      0x0010:  0088 0000 4000 4032 be40 be00 0001 be00  ....@.@2.@......
//      0x0020:  0002 0000 006e 0000 0013 82f4 1077 0418  .....n.......w..
//      0x0030:  e8ce dc45 1bac 22bb daaf 2ad2 c2e8 315b  ...E.."...*...1[
//      0x0040:  ce9a 39da 2aae cf43 3716 70ab 7e7c 4676  ..9.*..C7.p.~|Fv
//      0x0050:  c3fc d109 c990 274d f81c 6534 9a40 a0ef  ......'M..e4.@..
//      0x0060:  46b1 7da5 05af dda8 d0ba 6e23 d1ee 1f10  F.}.......n#....
//      0x0070:  730c 7371 03b1 445c 2f70 852f 8475 12fb  s.sq..D\/p./.u..
//      0x0080:  b057 a19b a617 bae7 09ca 8836 942f 3334  .W.........6./34
//      0x0090:  312b 96d2 a4e3                           1+....
var testPacketIPSecESP = []byte{
	0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x11, 0x43, 0x4a, 0xd7, 0x0a, 0x08, 0x00, 0x45, 0x00,
	0x00, 0x88, 0x00, 0x00, 0x40, 0x00, 0x40, 0x32, 0xbe, 0x40, 0xbe, 0x00, 0x00, 0x01, 0xbe, 0x00,
	0x00, 0x02, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x13, 0x82, 0xf4, 0x10, 0x77, 0x04, 0x18,
	0xe8, 0xce, 0xdc, 0x45, 0x1b, 0xac, 0x22, 0xbb, 0xda, 0xaf, 0x2a, 0xd2, 0xc2, 0xe8, 0x31, 0x5b,
	0xce, 0x9a, 0x39, 0xda, 0x2a, 0xae, 0xcf, 0x43, 0x37, 0x16, 0x70, 0xab, 0x7e, 0x7c, 0x46, 0x76,
	0xc3, 0xfc, 0xd1, 0x09, 0xc9, 0x90, 0x27, 0x4d, 0xf8, 0x1c, 0x65, 0x34, 0x9a, 0x40, 0xa0, 0xef,
	0x46, 0xb1, 0x7d, 0xa5, 0x05, 0xaf, 0xdd, 0xa8, 0xd0, 0xba, 0x6e, 0x23, 0xd1, 0xee, 0x1f, 0x10,
	0x73, 0x0c, 0x73, 0x71, 0x03, 0xb1, 0x44, 0x5c, 0x2f, 0x70, 0x85, 0x2f, 0x84, 0x75, 0x12, 0xfb,
	0xb0, 0x57, 0xa1, 0x9b, 0xa6, 0x17, 0xba, 0xe7, 0x09, 0xca, 0x88, 0x36, 0x94, 0x2f, 0x33, 0x34,
	0x31, 0x2b, 0x96, 0xd2, 0xa4, 0xe3,
}

func TestPacketIPSecESP(t *testing.T) {
	p := gopacket.NewPacket(testPacketIPSecESP, LinkTypeEthernet, gopacket.Default)
	if p.ErrorLayer() != nil {
		t.Error("Failed to decode packet:", p.ErrorLayer().Error())
	}
	checkLayers(p, []gopacket.LayerType{LayerTypeEthernet, LayerTypeIPv4, LayerTypeIPSecESP}, t)
}

func BenchmarkDecodePacketIPSecESP(b *testing.B) {
	for i := 0; i < b.N; i++ {
		gopacket.NewPacket(testPacketIPSecESP, LinkTypeEthernet, gopacket.NoCopy)
	}
}
<|endoftext|>


<commit_before>package main

import "github.com/Sirupsen/logrus"
import logger "./logger"
import wschat "./wschat"
import "encoding/json"
import "io/ioutil"
import "./chat_sender"

var log = logger.GetLogger()

type Config struct {
	Channels   []string  `json:"channels"`
	LogglyKey string  `json:"loggly-key"`
}

func main() {
	file, e := ioutil.ReadFile("./config.json")
	if e != nil {
		log.WithFields(logrus.Fields{
			"err": e,
		}).Fatal("Error opening config")
	}

  var config Config
  e = json.Unmarshal(file, &config)
	if e != nil {
		log.WithFields(logrus.Fields{
			"err": e,
		}).Fatal("Error parsing config")
	}

  log.WithFields(logrus.Fields{
    "channels": config.Channels,
    "loggly_key": config.LogglyKey,
  }).Info("Config loaded.")

  cs := chatsender.ChatSender{config.LogglyKey}

  for _, channel := range config.Channels{
    ws := wschat.WsIrc{channel, nil, cs.SendLine}
    ws.Start()
  }
  for {}
}
<commit_msg>Adding Gosched to main tight loop<commit_after>package main

import "github.com/Sirupsen/logrus"
import logger "./logger"
import wschat "./wschat"
import "encoding/json"
import "io/ioutil"
import "./chat_sender"
import "runtime"

var log = logger.GetLogger()

type Config struct {
	Channels   []string  `json:"channels"`
	LogglyKey string  `json:"loggly-key"`
}

func main() {
	file, e := ioutil.ReadFile("./config.json")
	if e != nil {
		log.WithFields(logrus.Fields{
			"err": e,
		}).Fatal("Error opening config")
	}

  var config Config
  e = json.Unmarshal(file, &config)
	if e != nil {
		log.WithFields(logrus.Fields{
			"err": e,
		}).Fatal("Error parsing config")
	}

  log.WithFields(logrus.Fields{
    "channels": config.Channels,
    "loggly_key": config.LogglyKey,
  }).Info("Config loaded.")

  cs := chatsender.ChatSender{config.LogglyKey}

  for _, channel := range config.Channels{
    ws := wschat.WsIrc{channel, nil, cs.SendLine}
    ws.Start()
  }
  for {
    runtime.Gosched()
  }
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/tls"
	"errors"
	"io/ioutil"
	"log"
	"net/http"
	"os"

	"github.com/labstack/echo"
	"github.com/solid/solidproxy"
)

var (
	debugPrefix = "[debug] "
	debugFlags  = log.Flags() | log.Lshortfile
)

func main() {
	configProxy := solidproxy.NewServerConfig()
	configAgent := solidproxy.NewServerConfig()
	configAgent.EnableTLS = true

	// logger
	solidproxy.Logger = log.New(ioutil.Discard, "", 0)

	if len(os.Getenv("SOLIDPROXY_VERBOSE")) > 0 {
		configProxy.Verbose = true // default= false
		configAgent.Verbose = true // default= false
		solidproxy.Logger = log.New(os.Stderr, debugPrefix, debugFlags)
	}
	if len(os.Getenv("SOLIDPROXY_INSECURE")) > 0 {
		configProxy.InsecureSkipVerify = true // default= false
	}
	if len(os.Getenv("SOLIDPROXY_AGENT")) > 0 {
		configProxy.Agent = os.Getenv("SOLIDPROXY_AGENT")
		configAgent.Agent = os.Getenv("SOLIDPROXY_AGENT")
	}
	if len(os.Getenv("SOLIDPROXY_USER")) > 0 {
		configProxy.User = os.Getenv("SOLIDPROXY_USER")
	}
	if len(os.Getenv("SOLIDPROXY_TLSKEY")) > 0 {
		configProxy.TLSKey = os.Getenv("SOLIDPROXY_TLSKEY")
		configAgent.TLSKey = os.Getenv("SOLIDPROXY_TLSKEY")
	}
	if len(os.Getenv("SOLIDPROXY_TLSCERT")) > 0 {
		configProxy.TLSCert = os.Getenv("SOLIDPROXY_TLSCERT")
		configAgent.TLSCert = os.Getenv("SOLIDPROXY_TLSCERT")
	}
	// Proxy config
	if len(os.Getenv("SOLIDPROXY_PROXYPORT")) > 0 {
		configProxy.Port = os.Getenv("SOLIDPROXY_PROXYPORT") // default= :3129
	}
	// Enable or not HTTPS
	if len(os.Getenv("SOLIDPROXY_DISABLEPROXYTLS")) == 0 {
		configProxy.EnableTLS = false // default= true
	}
	// Agent config
	if len(os.Getenv("SOLIDPROXY_AGENTPORT")) > 0 {
		configAgent.Port = os.Getenv("SOLIDPROXY_AGENTPORT") // default= :3200
	}

	// Create handlers
	proxyHandler := solidproxy.NewProxyServer(configProxy)
	agentHandler := solidproxy.NewAgentServer(configAgent)
	// Start server
	solidproxy.Logger.Println("Starting SolidProxy", solidproxy.GetVersion())

	// start proxy server
	proxyServer, err := NewServer(proxyHandler, configProxy)
	if err != nil {
		solidproxy.Logger.Println("Cannot start proxy server:", err.Error())
		return
	}
	agentServer, err := NewServer(agentHandler, configAgent)
	if err != nil {
		solidproxy.Logger.Println("Cannot start agent server:", err.Error())
		return
	}

	// Start servers
	go agentHandler.StartServer(agentServer)
	proxyHandler.StartServer(proxyServer)
}

func NewServer(handler *echo.Echo, config *solidproxy.ServerConfig) (*http.Server, error) {
	// Create proxy server listener and set config values
	var err error
	s := &http.Server{
		Addr:    ":" + config.Port,
		Handler: handler,
	}
	if config.EnableTLS {
		if len(config.TLSKey) == 0 || len(config.TLSCert) == 0 {
			return s, errors.New("TLS cert or key missing")
		}
		s.TLSConfig = new(tls.Config)
		s.TLSConfig.MinVersion = tls.VersionTLS12
		s.TLSConfig.NextProtos = []string{"h2"}
		// use strong crypto
		s.TLSConfig.PreferServerCipherSuites = true
		s.TLSConfig.CurvePreferences = []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256}
		s.TLSConfig.CipherSuites = []uint16{
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
		}
		s.TLSConfig.Certificates = make([]tls.Certificate, 1)
		s.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(config.TLSCert, config.TLSKey)
		if err != nil {
			return s, err
		}
	}
	return s, nil
}
<commit_msg>renames the server to proxy-server/proxy-server.go<commit_after><|endoftext|>


<commit_before>// client_docker_test.go - optional client docker test
// Copyright (C) 2019  David Stainton.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// +build docker_test

package client

import (
	"testing"

	"github.com/katzenpost/client/config"
	"github.com/katzenpost/client/session"
	"github.com/katzenpost/core/utils"
	"github.com/stretchr/testify/require"
)

func TestClientBlockingSendReceive(t *testing.T) {
	require := require.New(t)

	// Load catshadow config file.
	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	session, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := session.GetService("loop")
	require.NoError(err)

	reply, err := session.BlockingSendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	require.True(utils.CtIsZero(reply))
}

func TestClientBlockingSendReceiveWithDecoyTraffic(t *testing.T) {
	require := require.New(t)

	// Load catshadow config file.
	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	cfg.Debug.DisableDecoyTraffic = false
	client, err := New(cfg)
	require.NoError(err)

	session, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := session.GetService("loop")
	require.NoError(err)

	reply, err := session.BlockingSendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	require.True(utils.CtIsZero(reply))
}

func TestClientAsyncSendReceive(t *testing.T) {
	require := require.New(t)

	// Load catshadow config file.
	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	clientSession, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := clientSession.GetService("loop")
	require.NoError(err)

	msgID, err := clientSession.SendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	t.Logf("sent message ID %x", msgID)

	eventRaw := <-clientSession.EventSink
	event1 := eventRaw.(*session.MessageSentEvent)
	require.Equal(msgID[:], event1.MessageID[:])
	t.Logf("received event: %s", event1)

	eventRaw = <-clientSession.EventSink
	event2 := eventRaw.(*session.MessageReplyEvent)
	t.Logf("received event: %s", event2)
	require.Equal(msgID[:], event2.MessageID[:])
	require.True(utils.CtIsZero(event2.Payload))
	require.NoError(event2.Err)
}
<commit_msg>Put Docker in the test names<commit_after>// client_docker_test.go - optional client docker test
// Copyright (C) 2019  David Stainton.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// +build docker_test

package client

import (
	"testing"

	"github.com/katzenpost/client/config"
	"github.com/katzenpost/client/session"
	"github.com/katzenpost/core/utils"
	"github.com/stretchr/testify/require"
)

func TestDockerClientBlockingSendReceive(t *testing.T) {
	require := require.New(t)

	// Load catshadow config file.
	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	session, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := session.GetService("loop")
	require.NoError(err)

	reply, err := session.BlockingSendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	require.True(utils.CtIsZero(reply))
}

func TestDockerClientBlockingSendReceiveWithDecoyTraffic(t *testing.T) {
	require := require.New(t)

	// Load catshadow config file.
	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	cfg.Debug.DisableDecoyTraffic = false
	client, err := New(cfg)
	require.NoError(err)

	session, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := session.GetService("loop")
	require.NoError(err)

	reply, err := session.BlockingSendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	require.True(utils.CtIsZero(reply))
}

func TestDockerClientAsyncSendReceive(t *testing.T) {
	require := require.New(t)

	// Load catshadow config file.
	cfg, err := config.LoadFile("testdata/client.toml")
	require.NoError(err)

	cfg, linkKey := AutoRegisterRandomClient(cfg)
	client, err := New(cfg)
	require.NoError(err)

	clientSession, err := client.NewSession(linkKey)
	require.NoError(err)

	desc, err := clientSession.GetService("loop")
	require.NoError(err)

	msgID, err := clientSession.SendUnreliableMessage(desc.Name, desc.Provider, []byte("hello"))
	require.NoError(err)
	t.Logf("sent message ID %x", msgID)

	eventRaw := <-clientSession.EventSink
	event1 := eventRaw.(*session.MessageSentEvent)
	require.Equal(msgID[:], event1.MessageID[:])
	t.Logf("received event: %s", event1)

	eventRaw = <-clientSession.EventSink
	event2 := eventRaw.(*session.MessageReplyEvent)
	t.Logf("received event: %s", event2)
	require.Equal(msgID[:], event2.MessageID[:])
	require.True(utils.CtIsZero(event2.Payload))
	require.NoError(event2.Err)
}
<|endoftext|>


<commit_before>package sshproxy

import (
	"errors"
	"fmt"
	"path"
	"path/filepath"

	tilde "gopkg.in/mattes/go-expand-tilde.v1"
)

// SSHProxy is a type which contains configs for an ssh connection.
type SSHProxy struct {
	// SSH configs.
	User string `yaml:"user"`
	Host string `yaml:"host"`
	Port int    `yaml:"port"`
	Key  string `yaml:"key"`
	// Config filepath.
	Filename string
	// Name of SSHProxy config.
	Name string
}

// String representation of SSHProxy.
func (s *SSHProxy) String() string {
	if s.User == "" || s.Host == "" {
		return "<SSHProxy: empty>"
	}
	return fmt.Sprintf("<SSHProxy: %v@%v>", s.User, s.Host)
}

// // Info for SSHProxy value.
// func (s *SSHProxy) Info() string {
// 	return fmt.Sprintf("<SSHProxy:\n"+
// 		"  Name: %v\n"+
// 		"  User: %v\n"+
// 		"  Host: %v\n"+
// 		"  Port: %v\n"+
// 		"  Key: %v\n"+
// 		"  Filename: %v\n>",
// 		s.Name, s.User, s.Host, s.Port, s.Key, s.Filename)
// }

// Info for SSHProxy value.
func (s *SSHProxy) Info() string {
	return fmt.Sprintf("[%v]\n"+
		"  User: %v\n"+
		"  Host: %v\n"+
		"  Port: %v\n"+
		"  Key: %v\n",
		s.Name, s.User, s.Host, s.Port, s.Key)
}

// Validate SSHProxy fields.
func (s *SSHProxy) Validate() error {
	// Check that the `User` is not blank.
	if s.User == "" {
		return errors.New("[config] Invalid User")
	}

	// Check that the `Host` is not blank.
	if s.Host == "" {
		return errors.New("[config] Invalid Host")
	}

	// Expand key path if path contains tilde.
	expandedKey, err := tilde.Expand(s.Key)
	if err != nil {
		return errors.New("[config] Expanding Key path")
	}

	// If `Key` is not an absolute path, then make `Key` an
	// absolute path that is relative to `Filename`.
	if !path.IsAbs(expandedKey) {
		// Get dirname of config file.
		dir := filepath.Dir(s.Filename)
		// Join dirname and keypath.
		expandedKey = filepath.Join(dir, expandedKey)
		// Absolute path.
		expandedKey, err = filepath.Abs(expandedKey)
		if err != nil {
			errMsg := fmt.Sprintf("[config] Key path %v", err)
			return errors.New(errMsg)
		}
	}
	// Set `Key`.
	s.Key = expandedKey
	return nil
}

// UnmarshalYAML - Populate an SSHProxy struct from a yaml byte string.
// https://goo.gl/yvLJkj
func (s *SSHProxy) UnmarshalYAML(unmarshal func(interface{}) error) error {
	// Create an alias type.
	type SSHAlias SSHProxy

	// Convert new value to the alias type.
	var temp = (*SSHAlias)(Default())

	// Unmarshal into the aliased type.
	if err := unmarshal(temp); err != nil {
		return err
	}

	// Case the alias back to the original type.
	*s = SSHProxy(*temp)
	return nil
}

// New - Create a new SSHProxy object with given values.
func New(user, host string, port int, key string) *SSHProxy {
	return &SSHProxy{
		User: user,
		Host: host,
		Port: port,
		Key:  key,
	}
}

// Default - Create a new SSHProxy object with default values.
func Default() *SSHProxy {
	return &SSHProxy{
		User: "",
		Host: "",
		Port: getDefaultPort(),
		Key:  getDefaultKey(),
	}
}
<commit_msg>Remove old SSHProxy.Info<commit_after>package sshproxy

import (
	"errors"
	"fmt"
	"path"
	"path/filepath"

	tilde "gopkg.in/mattes/go-expand-tilde.v1"
)

// SSHProxy is a type which contains configs for an ssh connection.
type SSHProxy struct {
	// SSH configs.
	User string `yaml:"user"`
	Host string `yaml:"host"`
	Port int    `yaml:"port"`
	Key  string `yaml:"key"`
	// Config filepath.
	Filename string
	// Name of SSHProxy config.
	Name string
}

// String representation of SSHProxy.
func (s *SSHProxy) String() string {
	if s.User == "" || s.Host == "" {
		return "<SSHProxy: empty>"
	}
	return fmt.Sprintf("<SSHProxy: %v@%v>", s.User, s.Host)
}

// Info for SSHProxy value.
func (s *SSHProxy) Info() string {
	return fmt.Sprintf("[%v]\n"+
		"  User: %v\n"+
		"  Host: %v\n"+
		"  Port: %v\n"+
		"  Key: %v\n",
		s.Name, s.User, s.Host, s.Port, s.Key)
}

// Validate SSHProxy fields.
func (s *SSHProxy) Validate() error {
	// Check that the `User` is not blank.
	if s.User == "" {
		return errors.New("[config] Invalid User")
	}

	// Check that the `Host` is not blank.
	if s.Host == "" {
		return errors.New("[config] Invalid Host")
	}

	// Expand key path if path contains tilde.
	expandedKey, err := tilde.Expand(s.Key)
	if err != nil {
		return errors.New("[config] Expanding Key path")
	}

	// If `Key` is not an absolute path, then make `Key` an
	// absolute path that is relative to `Filename`.
	if !path.IsAbs(expandedKey) {
		// Get dirname of config file.
		dir := filepath.Dir(s.Filename)
		// Join dirname and keypath.
		expandedKey = filepath.Join(dir, expandedKey)
		// Absolute path.
		expandedKey, err = filepath.Abs(expandedKey)
		if err != nil {
			errMsg := fmt.Sprintf("[config] Key path %v", err)
			return errors.New(errMsg)
		}
	}
	// Set `Key`.
	s.Key = expandedKey
	return nil
}

// UnmarshalYAML - Populate an SSHProxy struct from a yaml byte string.
// https://goo.gl/yvLJkj
func (s *SSHProxy) UnmarshalYAML(unmarshal func(interface{}) error) error {
	// Create an alias type.
	type SSHAlias SSHProxy

	// Convert new value to the alias type.
	var temp = (*SSHAlias)(Default())

	// Unmarshal into the aliased type.
	if err := unmarshal(temp); err != nil {
		return err
	}

	// Case the alias back to the original type.
	*s = SSHProxy(*temp)
	return nil
}

// New - Create a new SSHProxy object with given values.
func New(user, host string, port int, key string) *SSHProxy {
	return &SSHProxy{
		User: user,
		Host: host,
		Port: port,
		Key:  key,
	}
}

// Default - Create a new SSHProxy object with default values.
func Default() *SSHProxy {
	return &SSHProxy{
		User: "",
		Host: "",
		Port: getDefaultPort(),
		Key:  getDefaultKey(),
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/binary"
	"encoding/json"
	"flag"
	"io"
	"log"
	"os"
	"strings"

	"github.com/thomersch/grandine/fileformat"

	"github.com/golang/protobuf/proto"
	geom "github.com/twpayne/go-geom"
	"github.com/twpayne/go-geom/encoding/wkb"
)

const (
	cookie  = "ABCD"
	version = 0
)

type GeoJSON struct {
	Type     string
	Features []geoJSONFeature
}

type geoJSONFeature struct {
	Type       string
	Properties map[string]string
	Geometry   struct {
		Type        string
		Coordinates [][][2]float64
	}
}

func (g *geoJSONFeature) WKB() []byte {
	var crdss [][]geom.Coord

	for _, coordset := range g.Geometry.Coordinates {
		var crds []geom.Coord
		for _, crd := range coordset {
			crds = append(crds, geom.Coord{crd[0], crd[1]})
		}
		crdss = append(crdss, crds)
	}

	var elem geom.T
	switch g.Geometry.Type {
	case "LineString":
		elem = geom.NewLineString(geom.XY).MustSetCoords(crdss[0])
	case "Polygon":
		elem = geom.NewPolygon(geom.XY).MustSetCoords(crdss)
	default:
		log.Fatalf("type %v not yet implemented", g.Geometry.Type)
	}
	buf, err := wkb.Marshal(elem, binary.LittleEndian)
	if err != nil {
		log.Fatal(err)
	}
	return buf
}

type Feature interface {
	WKB() []byte
}

func main() {
	source := flag.String("src", "geo.geojson", "")
	dest := flag.String("dest", "geo.unnamed", "")
	flag.Parse()

	f, err := os.Open(*source)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	out, err := os.Create(*dest)
	if err != nil {
		log.Fatal(err)
	}
	defer out.Close()

	if strings.HasSuffix(*source, ".geojson") {
		log.Println("Decoding geojson, encoding .unnamed")
		writeFileHeader(out)

		var gj GeoJSON
		if err := json.NewDecoder(f).Decode(&gj); err != nil {
			log.Fatal(err)
		}

		// for now write a block for every feature
		for _, feat := range gj.Features {
			writeBlock(out, []Feature{&feat})
		}
	} else {
		log.Println("Decoding .unnamed, writing geojson")
		readFileHeader(f)
		// readBlocks()
	}
}

func writeFileHeader(w io.Writer) {
	// Cookie
	w.Write([]byte(cookie))

	// Version
	binary.Write(w, binary.LittleEndian, uint32(version))
}

func writeBlock(w io.Writer, fs []Feature) {
	blockBody := &fileformat.Body{}
	for _, f := range fs {
		blockBody.Feature = append(blockBody.Feature, &fileformat.Feature{
			Geom: f.WKB(),
		})
	}
	bodyBuf, err := proto.Marshal(blockBody)
	if err != nil {
		log.Fatal(err)
	}

	// Body Length (fill later)
	binary.Write(w, binary.LittleEndian, uint32(len(bodyBuf)))
	// Flags
	binary.Write(w, binary.LittleEndian, uint16(0))
	// Compression
	binary.Write(w, binary.LittleEndian, uint8(0))
	// Message Type
	binary.Write(w, binary.LittleEndian, uint8(0))

	w.Write(bodyBuf)
}

func readFileHeader(r io.Reader) {
	var (
		ck   = make([]byte, 4)
		vers uint32
	)
	if _, err := r.Read(ck); err != nil {
		log.Fatal(err)
	}
	if string(ck) != cookie {
		log.Fatal("invalid cookie")
	}

	if err := binary.Read(r, binary.LittleEndian, &vers); err != nil {
		log.Fatal(err)
	}
	if vers > version {
		log.Fatal("invalid file version")
	}
}
<commit_msg>decoder (to geojson)<commit_after>package main

import (
	"encoding/binary"
	"encoding/json"
	"flag"
	"io"
	"log"
	"os"
	"strings"

	"github.com/thomersch/grandine/fileformat"

	"github.com/golang/protobuf/proto"
	geom "github.com/twpayne/go-geom"
	"github.com/twpayne/go-geom/encoding/geojson"
	"github.com/twpayne/go-geom/encoding/wkb"
)

const (
	cookie  = "ABCD"
	version = 0
)

type GeoJSON struct {
	Type     string
	Features []geoJSONFeature
}

type geoJSONFeature struct {
	Type       string
	Properties map[string]string
	Geometry   struct {
		Type        string
		Coordinates [][][2]float64
	}
}

func (g *geoJSONFeature) WKB() []byte {
	var crdss [][]geom.Coord

	for _, coordset := range g.Geometry.Coordinates {
		var crds []geom.Coord
		for _, crd := range coordset {
			crds = append(crds, geom.Coord{crd[0], crd[1]})
		}
		crdss = append(crdss, crds)
	}

	var elem geom.T
	switch g.Geometry.Type {
	case "LineString":
		elem = geom.NewLineString(geom.XY).MustSetCoords(crdss[0])
	case "Polygon":
		elem = geom.NewPolygon(geom.XY).MustSetCoords(crdss)
	default:
		log.Fatalf("type %v not yet implemented", g.Geometry.Type)
	}
	buf, err := wkb.Marshal(elem, binary.LittleEndian)
	if err != nil {
		log.Fatal(err)
	}
	return buf
}

type WKBable interface {
	WKB() []byte
}

type GeoJSONable geom.T

func main() {
	source := flag.String("src", "geo.geojson", "")
	dest := flag.String("dest", "geo.unnamed", "")
	flag.Parse()

	f, err := os.Open(*source)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	out, err := os.Create(*dest)
	if err != nil {
		log.Fatal(err)
	}
	defer out.Close()

	if strings.HasSuffix(*source, ".geojson") {
		log.Println("Decoding geojson, encoding .unnamed")
		writeFileHeader(out)

		var gj GeoJSON
		if err := json.NewDecoder(f).Decode(&gj); err != nil {
			log.Fatal(err)
		}

		// for now write a block for every feature
		for _, feat := range gj.Features {
			writeBlock(out, []WKBable{&feat})
		}
	} else {
		log.Println("Decoding .unnamed, writing geojson")
		readFileHeader(f)
		var gjfc geojson.FeatureCollection
		for _, f := range readBlocks(f) {
			gjfc.Features = append(gjfc.Features, &geojson.Feature{
				Geometry: f,
			})
		}
		buf, err := gjfc.MarshalJSON()
		if err != nil {
			log.Fatal(err)
		}
		out.Write(buf)
	}
}

func writeFileHeader(w io.Writer) {
	// Cookie
	w.Write([]byte(cookie))

	// Version
	binary.Write(w, binary.LittleEndian, uint32(version))
}

func writeBlock(w io.Writer, fs []WKBable) {
	blockBody := &fileformat.Body{}
	for _, f := range fs {
		blockBody.Feature = append(blockBody.Feature, &fileformat.Feature{
			Geom: f.WKB(),
		})
	}
	bodyBuf, err := proto.Marshal(blockBody)
	if err != nil {
		log.Fatal(err)
	}

	// Body Length (fill later)
	binary.Write(w, binary.LittleEndian, uint32(len(bodyBuf)))
	// Flags
	binary.Write(w, binary.LittleEndian, uint16(0))
	// Compression
	binary.Write(w, binary.LittleEndian, uint8(0))
	// Message Type
	binary.Write(w, binary.LittleEndian, uint8(0))

	w.Write(bodyBuf)
}

func readFileHeader(r io.Reader) {
	var (
		ck   = make([]byte, 4)
		vers uint32
	)
	if _, err := r.Read(ck); err != nil {
		log.Fatal(err)
	}
	if string(ck) != cookie {
		log.Fatal("invalid cookie")
	}

	if err := binary.Read(r, binary.LittleEndian, &vers); err != nil {
		log.Fatal(err)
	}
	if vers > version {
		log.Fatal("invalid file version")
	}
}

func readBlocks(r io.Reader) []GeoJSONable {
	var fs []GeoJSONable
	for {
		var (
			blockLength uint32
			flags       uint16
			compression uint8
			messageType uint8
		)
		if err := binary.Read(r, binary.LittleEndian, &blockLength); err != nil {
			if err == io.EOF {
				break
			}
			log.Fatal(err)
		}
		if err := binary.Read(r, binary.LittleEndian, &flags); err != nil {
			log.Fatal(err)
		}
		if err := binary.Read(r, binary.LittleEndian, &compression); err != nil {
			if compression != 0 {
				log.Fatal("compression is not supported")
			}
		}
		if err := binary.Read(r, binary.LittleEndian, &messageType); err != nil {
			if messageType != 0 {
				log.Fatal("message type is not supported")
			}
		}

		var (
			buf       = make([]byte, blockLength)
			blockBody fileformat.Body
		)
		if _, err := r.Read(buf); err != nil {
			log.Fatal(err)
		}
		if err := proto.Unmarshal(buf, &blockBody); err != nil {
			log.Fatal(err)
		}
		for _, f := range blockBody.GetFeature() {
			geom, err := wkb.Unmarshal(f.Geom)
			if err != nil {
				log.Fatal(err)
			}
			fs = append(fs, geom)
		}
	}
	return fs
}
<|endoftext|>


<commit_before>package gameserver

import (
	"fmt"
)
<commit_msg>small<commit_after>package gameserver

import (
	"fmt"
	"os"
)

const (
	ERROR_LOG bool = true
	DEBUG_LOG bool = true
)

var LOGV = util.NewLogger(DEBUG_LOG, "DEBUG", os.Stdout)
var LOGE = util.NewLogger(ERROR_LOG, "ERROR", os.Stderr)
<|endoftext|>


<commit_before>package frame

import (
	"github.com/as/drawcache"
	"github.com/as/frame/box"
	"github.com/as/frame/font"
	"image"
	"image/draw"
)

const (
	FrElastic = 1 << iota
	FrUTF8
)

var (
	// Enables the UTF-8 experiment
	ForceUTF8Experiment = false
	// Enables the Elastic Tabstop experiement
	ForceElasticTabstopExperiment = false
)

// Frame is a write-only container for editable text
type Frame struct {
	b *image.RGBA
	r image.Rectangle
	box.Run
	ir *box.Run

	p0 int64
	p1 int64

	flags int

	Font *font.Font
	Color
	Ticked bool
	Scroll func(int)
	drawcache.Drawer
	op draw.Op

	maxtab int
	full   int

	tick      draw.Image
	tickback  draw.Image
	tickscale int
	tickoff   bool
	maxlines  int
	modified  bool
	noredraw  bool

	pts     [][2]image.Point
	hexFont *font.Font
	hex     []draw.Image

	// Points to the font subpackage's StringN?BG or RuneN?BG functions
	stringBG     func(draw.Image, image.Point, image.Image, image.Point, *font.Font, []byte, image.Image, image.Point) int
	stringNBG    func(draw.Image, image.Point, image.Image, image.Point, *font.Font, []byte) int
	newRulerFunc func(s []byte, ft *font.Font) box.Ruler
}

func (f *Frame) SetFlags(flat int) {
	//TODO(as)
}

func newRuneFrame(r image.Rectangle, ft *font.Font, b *image.RGBA, cols Color, runes ...bool) *Frame {
	spaceDx := ft.Measure(' ')
	f := &Frame{
		Font:         ft,
		maxtab:       4 * spaceDx,
		Color:        cols,
		Run:          box.NewRun(spaceDx, 5000, ft, box.NewRuneRuler),
		stringBG:     font.RuneBG,
		stringNBG:    font.RuneNBG,
		newRulerFunc: box.NewRuneRuler,
		op:           draw.Src,
	}
	f.setrects(r, b)
	f.inittick()
	run := box.NewRun(spaceDx, 5000, ft, box.NewRuneRuler)
	f.ir = &run
	f.Drawer = drawcache.New()
	return f
}

// New creates a new frame on b with bounds r. The image b is used
// as the frame's internal bitmap cache.
func New(r image.Rectangle, ft *font.Font, b *image.RGBA, cols Color, runes ...bool) *Frame {
	if (len(runes) > 0 && runes[0]) || ForceUTF8Experiment {
		return newRuneFrame(r, ft, b, cols)
	}
	spaceDx := ft.Measure(' ')
	f := &Frame{
		Font:         ft,
		maxtab:       4 * spaceDx,
		Color:        cols,
		Run:          box.NewRun(spaceDx, 5000, ft),
		stringBG:     font.StringBG,
		stringNBG:    font.StringNBG,
		newRulerFunc: box.NewByteRuler,
		op:           draw.Src,
	}
	f.setrects(r, b)
	f.inittick()
	run := box.NewRun(spaceDx, 5000, ft)
	f.ir = &run
	f.Drawer = drawcache.New()
	return f
}

func (f *Frame) RGBA() *image.RGBA {
	return f.b
}
func (f *Frame) Size() image.Point {
	r := f.RGBA().Bounds()
	return image.Pt(r.Dx(), r.Dy())
}

// Dirty returns true if the contents of the frame have changes since the last redraw
func (f *Frame) Dirty() bool {
	return f.modified
}

// SetDirty alters the frame's internal state
func (f *Frame) SetDirty(dirty bool) {
	f.modified = dirty
}

func (f *Frame) SetOp(op draw.Op) {
	f.op = op

}

// Close closes the frame
func (f *Frame) Close() error {
	return nil
}

// Reset resets the frame to display on image b with bounds r and font ft.
func (f *Frame) Reset(r image.Rectangle, b *image.RGBA, ft *font.Font) {
	f.r = r
	f.b = b
	f.SetFont(ft)
}

func (f *Frame) SetFont(ft *font.Font) {
	f.Font = ft
	f.Run.Reset(ft)
	f.Refresh()
}

// Bounds returns the frame's clipping rectangle
func (f *Frame) Bounds() image.Rectangle {
	return f.r.Bounds()
}

// Full returns true if the last line in the frame is full
func (f *Frame) Full() bool {
	return f.full == 1
}

// Maxline returns the max number of wrapped lines fitting on the frame
func (f *Frame) MaxLine() int {
	return f.maxlines
}

// Line returns the number of wrapped lines currently in the frame
func (f *Frame) Line() int {
	return f.Nlines
}

// Len returns the number of bytes currently in the frame
func (f *Frame) Len() int64 {
	return f.Nchars
}

// Dot returns the range of the selected text
func (f *Frame) Dot() (p0, p1 int64) {
	return f.p0, f.p1
}

func (f *Frame) setrects(r image.Rectangle, b *image.RGBA) {
	f.b = b
	f.r = r
	f.r.Max.Y -= f.r.Dy() % f.Font.Dy()
	f.maxlines = f.r.Dy() / f.Font.Dy()
}

func (f *Frame) clear(freeall bool) {
	if f.Nbox != 0 {
		f.Run.Delete(0, f.Nbox-1)
	}
	if f.Box != nil {
		free(f.Box)
	}
	if freeall {
		// TODO: unnecessary
		freeimage(f.tick)
		freeimage(f.tickback)
		f.tick = nil
		f.tickback = nil
	}
	f.Box = nil
	f.Ticked = false
}

func free(i interface{}) {
}
func freeimage(i image.Image) {
}
<commit_msg>mintab,maxtab fix<commit_after>package frame

import (
	"github.com/as/drawcache"
	"github.com/as/frame/box"
	"github.com/as/frame/font"
	"image"
	"image/draw"
)

const (
	FrElastic = 1 << iota
	FrUTF8
)

var (
	// Enables the UTF-8 experiment
	ForceUTF8Experiment = false
	// Enables the Elastic Tabstop experiement
	ForceElasticTabstopExperiment = false
)

// Frame is a write-only container for editable text
type Frame struct {
	b *image.RGBA
	r image.Rectangle
	box.Run
	ir *box.Run

	p0 int64
	p1 int64

	flags int

	Font *font.Font
	Color
	Ticked bool
	Scroll func(int)
	drawcache.Drawer
	op draw.Op

	maxtab int
	full   int

	tick      draw.Image
	tickback  draw.Image
	tickscale int
	tickoff   bool
	maxlines  int
	modified  bool
	noredraw  bool

	pts     [][2]image.Point
	hexFont *font.Font
	hex     []draw.Image

	// Points to the font subpackage's StringN?BG or RuneN?BG functions
	stringBG     func(draw.Image, image.Point, image.Image, image.Point, *font.Font, []byte, image.Image, image.Point) int
	stringNBG    func(draw.Image, image.Point, image.Image, image.Point, *font.Font, []byte) int
	newRulerFunc func(s []byte, ft *font.Font) box.Ruler

	elastic bool
}

func (f *Frame) SetFlags(flat int) {
	//TODO(as)
}

func newRuneFrame(r image.Rectangle, ft *font.Font, b *image.RGBA, cols Color, runes ...bool) *Frame {
	mintab := ft.Measure(' ')
	maxtab := mintab*4
	elastic := ForceElasticTabstopExperiment
	if elastic{
		mintab=maxtab
	}
	f := &Frame{
		Font:         ft,
		maxtab:       maxtab,
		Color:        cols,
		Run:          box.NewRun(mintab, 5000, ft, box.NewRuneRuler),
		stringBG:     font.RuneBG,
		stringNBG:    font.RuneNBG,
		newRulerFunc: box.NewRuneRuler,
		op:           draw.Src,
	}
	f.setrects(r, b)
	f.inittick()
	run := box.NewRun(mintab, 5000, ft, box.NewRuneRuler)
	f.ir = &run
	f.Drawer = drawcache.New()
	return f
}

// New creates a new frame on b with bounds r. The image b is used
// as the frame's internal bitmap cache.
func New(r image.Rectangle, ft *font.Font, b *image.RGBA, cols Color, runes ...bool) *Frame {
	if (len(runes) > 0 && runes[0]) || ForceUTF8Experiment {
		return newRuneFrame(r, ft, b, cols)
	}
	mintab := ft.Measure(' ')
	maxtab := mintab*4
	elastic := ForceElasticTabstopExperiment
	if elastic{
		mintab=maxtab
	}
	f := &Frame{
		Font:         ft,
		maxtab:       maxtab,
		Color:        cols,
		Run:          box.NewRun(mintab, 5000, ft),
		stringBG:     font.StringBG,
		stringNBG:    font.StringNBG,
		newRulerFunc: box.NewByteRuler,
		op:           draw.Src,
		elastic: elastic,
	}
	f.setrects(r, b)
	f.inittick()
	run := box.NewRun(mintab, 5000, ft)
	f.ir = &run
	f.Drawer = drawcache.New()
	return f
}

func (f *Frame) RGBA() *image.RGBA {
	return f.b
}
func (f *Frame) Size() image.Point {
	r := f.RGBA().Bounds()
	return image.Pt(r.Dx(), r.Dy())
}

// Dirty returns true if the contents of the frame have changes since the last redraw
func (f *Frame) Dirty() bool {
	return f.modified
}

// SetDirty alters the frame's internal state
func (f *Frame) SetDirty(dirty bool) {
	f.modified = dirty
}

func (f *Frame) SetOp(op draw.Op) {
	f.op = op

}

// Close closes the frame
func (f *Frame) Close() error {
	return nil
}

// Reset resets the frame to display on image b with bounds r and font ft.
func (f *Frame) Reset(r image.Rectangle, b *image.RGBA, ft *font.Font) {
	f.r = r
	f.b = b
	f.SetFont(ft)
}

func (f *Frame) SetFont(ft *font.Font) {
	f.Font = ft
	f.Run.Reset(ft)
	f.Refresh()
}

// Bounds returns the frame's clipping rectangle
func (f *Frame) Bounds() image.Rectangle {
	return f.r.Bounds()
}

// Full returns true if the last line in the frame is full
func (f *Frame) Full() bool {
	return f.full == 1
}

// Maxline returns the max number of wrapped lines fitting on the frame
func (f *Frame) MaxLine() int {
	return f.maxlines
}

// Line returns the number of wrapped lines currently in the frame
func (f *Frame) Line() int {
	return f.Nlines
}

// Len returns the number of bytes currently in the frame
func (f *Frame) Len() int64 {
	return f.Nchars
}

// Dot returns the range of the selected text
func (f *Frame) Dot() (p0, p1 int64) {
	return f.p0, f.p1
}

func (f *Frame) setrects(r image.Rectangle, b *image.RGBA) {
	f.b = b
	f.r = r
	f.r.Max.Y -= f.r.Dy() % f.Font.Dy()
	f.maxlines = f.r.Dy() / f.Font.Dy()
}

func (f *Frame) clear(freeall bool) {
	if f.Nbox != 0 {
		f.Run.Delete(0, f.Nbox-1)
	}
	if f.Box != nil {
		free(f.Box)
	}
	if freeall {
		// TODO: unnecessary
		freeimage(f.tick)
		freeimage(f.tickback)
		f.tick = nil
		f.tickback = nil
	}
	f.Box = nil
	f.Ticked = false
}

func free(i interface{}) {
}
func freeimage(i image.Image) {
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package install

import (
	"encoding/json"
	"testing"

	"k8s.io/apimachinery/pkg/api/meta"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/kubernetes/federation/apis/federation"
	"k8s.io/kubernetes/federation/apis/federation/v1beta1"
	"k8s.io/kubernetes/pkg/api/legacyscheme"
)

func TestResourceVersioner(t *testing.T) {
	accessor := meta.NewAccessor()
	cluster := federation.Cluster{ObjectMeta: metav1.ObjectMeta{ResourceVersion: "10"}}
	version, err := accessor.ResourceVersion(&cluster)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if version != "10" {
		t.Errorf("unexpected version %v", version)
	}

	clusterList := federation.ClusterList{ListMeta: metav1.ListMeta{ResourceVersion: "10"}}
	version, err = accessor.ResourceVersion(&clusterList)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if version != "10" {
		t.Errorf("unexpected version %v", version)
	}
}

func TestCodec(t *testing.T) {
	cluster := federation.Cluster{}
	// We do want to use package registered rather than testapi here, because we
	// want to test if the package install and package registered work as expected.
	data, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(legacyscheme.Registry.GroupOrDie(federation.GroupName).GroupVersion), &cluster)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	other := federation.Cluster{}
	if err := json.Unmarshal(data, &other); err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if other.APIVersion != legacyscheme.Registry.GroupOrDie(federation.GroupName).GroupVersion.String() || other.Kind != "Cluster" {
		t.Errorf("unexpected unmarshalled object %#v", other)
	}
}

func TestInterfacesFor(t *testing.T) {
	if _, err := legacyscheme.Registry.GroupOrDie(federation.GroupName).InterfacesFor(federation.SchemeGroupVersion); err == nil {
		t.Fatalf("unexpected non-error: %v", err)
	}
	for i, version := range legacyscheme.Registry.GroupOrDie(federation.GroupName).GroupVersions {
		if vi, err := legacyscheme.Registry.GroupOrDie(federation.GroupName).InterfacesFor(version); err != nil || vi == nil {
			t.Fatalf("%d: unexpected result: %v", i, err)
		}
	}
}

func TestRESTMapper(t *testing.T) {
	gv := v1beta1.SchemeGroupVersion
	clusterGVK := gv.WithKind("Cluster")

	if gvk, err := legacyscheme.Registry.GroupOrDie(federation.GroupName).RESTMapper.KindFor(gv.WithResource("clusters")); err != nil || gvk != clusterGVK {
		t.Errorf("unexpected version mapping: %v %v", gvk, err)
	}

	if m, err := legacyscheme.Registry.GroupOrDie(federation.GroupName).RESTMapper.RESTMapping(clusterGVK.GroupKind(), ""); err != nil || m.GroupVersionKind != clusterGVK || m.Resource != "clusters" {
		t.Errorf("unexpected version mapping: %#v %v", m, err)
	}

	for _, version := range legacyscheme.Registry.GroupOrDie(federation.GroupName).GroupVersions {
		mapping, err := legacyscheme.Registry.GroupOrDie(federation.GroupName).RESTMapper.RESTMapping(clusterGVK.GroupKind(), version.Version)
		if err != nil {
			t.Errorf("unexpected error: %v", err)
		}

		if mapping.Resource != "clusters" {
			t.Errorf("incorrect resource name: %#v", mapping)
		}
		if mapping.GroupVersionKind.GroupVersion() != version {
			t.Errorf("incorrect groupVersion: %v", mapping)
		}

		interfaces, _ := legacyscheme.Registry.GroupOrDie(federation.GroupName).InterfacesFor(version)
		if mapping.ObjectConvertor != interfaces.ObjectConvertor {
			t.Errorf("unexpected: %#v, expected: %#v", mapping, interfaces)
		}

		rc := &federation.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
		name, err := mapping.MetadataAccessor.Name(rc)
		if err != nil {
			t.Errorf("unexpected error: %v", err)
		}
		if name != "foo" {
			t.Errorf("unable to retrieve object meta with: %v", mapping.MetadataAccessor)
		}
	}
}
<commit_msg>Amend the error messages in install_test.go<commit_after>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package install

import (
	"encoding/json"
	"testing"

	"k8s.io/apimachinery/pkg/api/meta"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/kubernetes/federation/apis/federation"
	"k8s.io/kubernetes/federation/apis/federation/v1beta1"
	"k8s.io/kubernetes/pkg/api/legacyscheme"
)

func TestResourceVersioner(t *testing.T) {
	accessor := meta.NewAccessor()
	cluster := federation.Cluster{ObjectMeta: metav1.ObjectMeta{ResourceVersion: "10"}}
	version, err := accessor.ResourceVersion(&cluster)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if version != "10" {
		t.Errorf("version = %v, want 10", version)
	}

	clusterList := federation.ClusterList{ListMeta: metav1.ListMeta{ResourceVersion: "10"}}
	version, err = accessor.ResourceVersion(&clusterList)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if version != "10" {
		t.Errorf("version = %v, want 10", version)
	}
}

func TestCodec(t *testing.T) {
	cluster := federation.Cluster{}
	// We do want to use package registered rather than testapi here, because we
	// want to test if the package install and package registered work as expected.
	data, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(legacyscheme.Registry.GroupOrDie(federation.GroupName).GroupVersion), &cluster)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	other := federation.Cluster{}
	if err := json.Unmarshal(data, &other); err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if other.APIVersion != legacyscheme.Registry.GroupOrDie(federation.GroupName).GroupVersion.String() || other.Kind != "Cluster" {
		t.Errorf("unexpected unmarshalled object %#v", other)
	}
}

func TestInterfacesFor(t *testing.T) {
	if _, err := legacyscheme.Registry.GroupOrDie(federation.GroupName).InterfacesFor(federation.SchemeGroupVersion); err == nil {
		t.Fatalf("unexpected non-error: %v", err)
	}
	for i, version := range legacyscheme.Registry.GroupOrDie(federation.GroupName).GroupVersions {
		if vi, err := legacyscheme.Registry.GroupOrDie(federation.GroupName).InterfacesFor(version); err != nil || vi == nil {
			t.Fatalf("%d: unexpected result: %v", i, err)
		}
	}
}

func TestRESTMapper(t *testing.T) {
	gv := v1beta1.SchemeGroupVersion
	clusterGVK := gv.WithKind("Cluster")

	if gvk, err := legacyscheme.Registry.GroupOrDie(federation.GroupName).RESTMapper.KindFor(gv.WithResource("clusters")); err != nil || gvk != clusterGVK {
		t.Errorf("unexpected version mapping: %v %v", gvk, err)
	}

	if m, err := legacyscheme.Registry.GroupOrDie(federation.GroupName).RESTMapper.RESTMapping(clusterGVK.GroupKind(), ""); err != nil || m.GroupVersionKind != clusterGVK || m.Resource != "clusters" {
		t.Errorf("unexpected version mapping: %#v %v", m, err)
	}

	for _, version := range legacyscheme.Registry.GroupOrDie(federation.GroupName).GroupVersions {
		mapping, err := legacyscheme.Registry.GroupOrDie(federation.GroupName).RESTMapper.RESTMapping(clusterGVK.GroupKind(), version.Version)
		if err != nil {
			t.Errorf("unexpected error: %v", err)
		}

		if mapping.Resource != "clusters" {
			t.Errorf("incorrect resource name: %#v", mapping)
		}
		if mapping.GroupVersionKind.GroupVersion() != version {
			t.Errorf("incorrect groupVersion: %v", mapping)
		}

		interfaces, _ := legacyscheme.Registry.GroupOrDie(federation.GroupName).InterfacesFor(version)
		if mapping.ObjectConvertor != interfaces.ObjectConvertor {
			t.Errorf("mapping: %#v, interfaces: %#v", mapping, interfaces)
		}

		rc := &federation.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
		name, err := mapping.MetadataAccessor.Name(rc)
		if err != nil {
			t.Errorf("unexpected error: %v", err)
		}
		if name != "foo" {
			t.Errorf("unable to retrieve object meta with: %v", mapping.MetadataAccessor)
		}
	}
}
<|endoftext|>