<commit_before>package api

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

	"github.com/hashicorp/vault/helper/jsonutil"
)

const (
	wrappedResponseLocation = "cubbyhole/response"
)

var (
	// The default TTL that will be used with `sys/wrapping/wrap`, can be
	// changed
	DefaultWrappingTTL = "5m"

	// The default function used if no other function is set, which honors the
	// env var and wraps `sys/wrapping/wrap`
	DefaultWrappingLookupFunc = func(operation, path string) string {
		if os.Getenv(EnvVaultWrapTTL) != "" {
			return os.Getenv(EnvVaultWrapTTL)
		}

		if (operation == "PUT" || operation == "POST") && path == "sys/wrapping/wrap" {
			return DefaultWrappingTTL
		}

		return ""
	}
)

// Logical is used to perform logical backend operations on Vault.
type Logical struct {
	c *Client
}

// Logical is used to return the client for logical-backend API calls.
func (c *Client) Logical() *Logical {
	return &Logical{c: c}
}

func (c *Logical) Read(path string) (*Secret, error) {
	r := c.c.NewRequest("GET", "/v1/"+path)
	resp, err := c.c.RawRequest(r)
	if resp != nil {
		defer resp.Body.Close()
	}
	if resp != nil && resp.StatusCode == 404 {
		secret, err := ParseSecret(resp.Body)
		switch err {
		case nil:
		case io.EOF:
			return nil, nil
		default:
			return nil, err
		}
		if secret != nil && (len(secret.Warnings) > 0 || len(secret.Data) > 0) {
			return secret, nil
		}
		return nil, nil
	}
	if err != nil {
		return nil, err
	}

	return ParseSecret(resp.Body)
}

func (c *Logical) List(path string) (*Secret, error) {
	r := c.c.NewRequest("LIST", "/v1/"+path)
	// Set this for broader compatibility, but we use LIST above to be able to
	// handle the wrapping lookup function
	r.Method = "GET"
	r.Params.Set("list", "true")
	resp, err := c.c.RawRequest(r)
	if resp != nil {
		defer resp.Body.Close()
	}
	if resp != nil && resp.StatusCode == 404 {
		secret, err := ParseSecret(resp.Body)
		switch err {
		case nil:
		case io.EOF:
			return nil, nil
		default:
			return nil, err
		}
		if secret != nil && (len(secret.Warnings) > 0 || len(secret.Data) > 0) {
			return secret, nil
		}
		return nil, nil
	}
	if err != nil {
		return nil, err
	}

	return ParseSecret(resp.Body)
}

func (c *Logical) Write(path string, data map[string]interface{}) (*Secret, error) {
	r := c.c.NewRequest("PUT", "/v1/"+path)
	if err := r.SetJSONBody(data); err != nil {
		return nil, err
	}

	resp, err := c.c.RawRequest(r)
	if resp != nil {
		defer resp.Body.Close()
	}
	if resp != nil && resp.StatusCode == 404 {
		secret, err := ParseSecret(resp.Body)
		switch err {
		case nil:
		case io.EOF:
			return nil, nil
		default:
			return nil, err
		}
		if secret != nil && (len(secret.Warnings) > 0 || len(secret.Data) > 0) {
			return secret, nil
		}
		return nil, nil
	}
	if err != nil {
		return nil, err
	}

	if resp.StatusCode == 200 {
		return ParseSecret(resp.Body)
	}

	return nil, nil
}

func (c *Logical) Delete(path string) (*Secret, error) {
	r := c.c.NewRequest("DELETE", "/v1/"+path)
	resp, err := c.c.RawRequest(r)
	if resp != nil {
		defer resp.Body.Close()
	}
	if resp != nil && resp.StatusCode == 404 {
		secret, err := ParseSecret(resp.Body)
		switch err {
		case nil:
		case io.EOF:
			return nil, nil
		default:
			return nil, err
		}
		if secret != nil && (len(secret.Warnings) > 0 || len(secret.Data) > 0) {
			return secret, nil
		}
		return nil, nil
	}
	if err != nil {
		return nil, err
	}

	if resp.StatusCode == 200 {
		return ParseSecret(resp.Body)
	}

	return nil, nil
}

func (c *Logical) Unwrap(wrappingToken string) (*Secret, error) {
	var data map[string]interface{}
	if wrappingToken != "" {
		if c.c.Token() == "" {
			c.c.SetToken(wrappingToken)
		} else if wrappingToken != c.c.Token() {
			data = map[string]interface{}{
				"token": wrappingToken,
			}
		}
	}

	r := c.c.NewRequest("PUT", "/v1/sys/wrapping/unwrap")
	if err := r.SetJSONBody(data); err != nil {
		return nil, err
	}

	resp, err := c.c.RawRequest(r)
	if resp != nil {
		defer resp.Body.Close()
	}

	// Return all errors except those that are from a 404 as we handle the not
	// found error as a special case.
	if err != nil && (resp == nil || resp.StatusCode != 404) {
		return nil, err
	}
	if resp == nil {
		return nil, nil
	}

	switch resp.StatusCode {
	case http.StatusOK: // New method is supported
		return ParseSecret(resp.Body)
	case http.StatusNotFound: // Fall back to old method
	default:
		return nil, nil
	}

	if wrappingToken != "" {
		origToken := c.c.Token()
		defer c.c.SetToken(origToken)
		c.c.SetToken(wrappingToken)
	}

	secret, err := c.Read(wrappedResponseLocation)
	if err != nil {
		return nil, fmt.Errorf("error reading %s: %s", wrappedResponseLocation, err)
	}
	if secret == nil {
		return nil, fmt.Errorf("no value found at %s", wrappedResponseLocation)
	}
	if secret.Data == nil {
		return nil, fmt.Errorf("\"data\" not found in wrapping response")
	}
	if _, ok := secret.Data["response"]; !ok {
		return nil, fmt.Errorf("\"response\" not found in wrapping response \"data\" map")
	}

	wrappedSecret := new(Secret)
	buf := bytes.NewBufferString(secret.Data["response"].(string))
	if err := jsonutil.DecodeJSONFromReader(buf, wrappedSecret); err != nil {
		return nil, fmt.Errorf("error unmarshalling wrapped secret: %s", err)
	}

	return wrappedSecret, nil
}
<commit_msg>On 404 if there is no actual body, return orig err. (#4262)<commit_after>package api

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

	"github.com/hashicorp/vault/helper/jsonutil"
)

const (
	wrappedResponseLocation = "cubbyhole/response"
)

var (
	// The default TTL that will be used with `sys/wrapping/wrap`, can be
	// changed
	DefaultWrappingTTL = "5m"

	// The default function used if no other function is set, which honors the
	// env var and wraps `sys/wrapping/wrap`
	DefaultWrappingLookupFunc = func(operation, path string) string {
		if os.Getenv(EnvVaultWrapTTL) != "" {
			return os.Getenv(EnvVaultWrapTTL)
		}

		if (operation == "PUT" || operation == "POST") && path == "sys/wrapping/wrap" {
			return DefaultWrappingTTL
		}

		return ""
	}
)

// Logical is used to perform logical backend operations on Vault.
type Logical struct {
	c *Client
}

// Logical is used to return the client for logical-backend API calls.
func (c *Client) Logical() *Logical {
	return &Logical{c: c}
}

func (c *Logical) Read(path string) (*Secret, error) {
	r := c.c.NewRequest("GET", "/v1/"+path)
	resp, err := c.c.RawRequest(r)
	if resp != nil {
		defer resp.Body.Close()
	}
	if resp != nil && resp.StatusCode == 404 {
		secret, parseErr := ParseSecret(resp.Body)
		switch parseErr {
		case nil:
		case io.EOF:
			return nil, nil
		default:
			return nil, parseErr
		}
		if secret != nil && (len(secret.Warnings) > 0 || len(secret.Data) > 0) {
			return secret, nil
		}
		return nil, err
	}
	if err != nil {
		return nil, err
	}

	return ParseSecret(resp.Body)
}

func (c *Logical) List(path string) (*Secret, error) {
	r := c.c.NewRequest("LIST", "/v1/"+path)
	// Set this for broader compatibility, but we use LIST above to be able to
	// handle the wrapping lookup function
	r.Method = "GET"
	r.Params.Set("list", "true")
	resp, err := c.c.RawRequest(r)
	if resp != nil {
		defer resp.Body.Close()
	}
	if resp != nil && resp.StatusCode == 404 {
		secret, parseErr := ParseSecret(resp.Body)
		switch parseErr {
		case nil:
		case io.EOF:
			return nil, nil
		default:
			return nil, parseErr
		}
		if secret != nil && (len(secret.Warnings) > 0 || len(secret.Data) > 0) {
			return secret, nil
		}
		return nil, err
	}
	if err != nil {
		return nil, err
	}

	return ParseSecret(resp.Body)
}

func (c *Logical) Write(path string, data map[string]interface{}) (*Secret, error) {
	r := c.c.NewRequest("PUT", "/v1/"+path)
	if err := r.SetJSONBody(data); err != nil {
		return nil, err
	}

	resp, err := c.c.RawRequest(r)
	if resp != nil {
		defer resp.Body.Close()
	}
	if resp != nil && resp.StatusCode == 404 {
		secret, parseErr := ParseSecret(resp.Body)
		switch parseErr {
		case nil:
		case io.EOF:
			return nil, nil
		default:
			return nil, parseErr
		}
		if secret != nil && (len(secret.Warnings) > 0 || len(secret.Data) > 0) {
			return secret, nil
		}
		return nil, err
	}
	if err != nil {
		return nil, err
	}

	if resp.StatusCode == 200 {
		return ParseSecret(resp.Body)
	}

	return nil, nil
}

func (c *Logical) Delete(path string) (*Secret, error) {
	r := c.c.NewRequest("DELETE", "/v1/"+path)
	resp, err := c.c.RawRequest(r)
	if resp != nil {
		defer resp.Body.Close()
	}
	if resp != nil && resp.StatusCode == 404 {
		secret, parseErr := ParseSecret(resp.Body)
		switch parseErr {
		case nil:
		case io.EOF:
			return nil, nil
		default:
			return nil, parseErr
		}
		if secret != nil && (len(secret.Warnings) > 0 || len(secret.Data) > 0) {
			return secret, nil
		}
		return nil, err
	}
	if err != nil {
		return nil, err
	}

	if resp.StatusCode == 200 {
		return ParseSecret(resp.Body)
	}

	return nil, nil
}

func (c *Logical) Unwrap(wrappingToken string) (*Secret, error) {
	var data map[string]interface{}
	if wrappingToken != "" {
		if c.c.Token() == "" {
			c.c.SetToken(wrappingToken)
		} else if wrappingToken != c.c.Token() {
			data = map[string]interface{}{
				"token": wrappingToken,
			}
		}
	}

	r := c.c.NewRequest("PUT", "/v1/sys/wrapping/unwrap")
	if err := r.SetJSONBody(data); err != nil {
		return nil, err
	}

	resp, err := c.c.RawRequest(r)
	if resp != nil {
		defer resp.Body.Close()
	}

	// Return all errors except those that are from a 404 as we handle the not
	// found error as a special case.
	if err != nil && (resp == nil || resp.StatusCode != 404) {
		return nil, err
	}
	if resp == nil {
		return nil, nil
	}

	switch resp.StatusCode {
	case http.StatusOK: // New method is supported
		return ParseSecret(resp.Body)
	case http.StatusNotFound: // Fall back to old method
	default:
		return nil, nil
	}

	if wrappingToken != "" {
		origToken := c.c.Token()
		defer c.c.SetToken(origToken)
		c.c.SetToken(wrappingToken)
	}

	secret, err := c.Read(wrappedResponseLocation)
	if err != nil {
		return nil, fmt.Errorf("error reading %s: %s", wrappedResponseLocation, err)
	}
	if secret == nil {
		return nil, fmt.Errorf("no value found at %s", wrappedResponseLocation)
	}
	if secret.Data == nil {
		return nil, fmt.Errorf("\"data\" not found in wrapping response")
	}
	if _, ok := secret.Data["response"]; !ok {
		return nil, fmt.Errorf("\"response\" not found in wrapping response \"data\" map")
	}

	wrappedSecret := new(Secret)
	buf := bytes.NewBufferString(secret.Data["response"].(string))
	if err := jsonutil.DecodeJSONFromReader(buf, wrappedSecret); err != nil {
		return nil, fmt.Errorf("error unmarshalling wrapped secret: %s", err)
	}

	return wrappedSecret, nil
}
<|endoftext|>


<commit_before>// Copyright 2013-2017 Aerospike, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package types

import (
	"errors"
	"strings"
)

// AerospikeError implements error interface for aerospike specific errors.
// All errors returning from the library are of this type.
// Errors resulting from Go's stdlib are not translated to this type, unless
// they are a net.Timeout error.
type AerospikeError struct {
	error

	resultCode ResultCode
	inDoubt    bool
}

// ResultCode returns the ResultCode from AerospikeError object.
func (ase AerospikeError) ResultCode() ResultCode {
	return ase.resultCode
}

// InDoubt determines if a write transaction may have completed or not.
func (ase AerospikeError) InDoubt() bool {
	return ase.inDoubt
}

// SetInDoubt sets whether it is possible that the write transaction may have completed
// even though this error was generated.  This may be the case when a
// client error occurs (like timeout) after the command was sent to the server.
func (ase AerospikeError) SetInDoubt(isRead bool, commandSentCounter int) {
	if !isRead && (commandSentCounter > 1 || (commandSentCounter == 1 && (ase.resultCode == TIMEOUT || ase.resultCode <= 0))) {
		ase.inDoubt = true
	}
}

// MarkInDoubt marks an error as in doubt.
func (ase AerospikeError) MarkInDoubt() {
	ase.inDoubt = true
}

// NewAerospikeError generates a new AerospikeError instance.
// If no message is provided, the result code will be translated into the default
// error message automatically.
func NewAerospikeError(code ResultCode, messages ...string) error {
	if len(messages) == 0 {
		messages = []string{ResultCodeToString(code)}
	}

	err := errors.New(strings.Join(messages, " "))
	return AerospikeError{error: err, resultCode: code}
}

var ErrRecordsetClosed = NewAerospikeError(RECORDSET_CLOSED, "Recordset has already been closed.")
var ErrConnectionPoolEmpty = NewAerospikeError(NO_AVAILABLE_CONNECTIONS_TO_NODE)
<commit_msg>Document how to use AerospikeError type in the code. Fixes github issue #222<commit_after>// Copyright 2013-2017 Aerospike, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package types

import (
	"errors"
	"strings"
)

// AerospikeError implements error interface for aerospike specific errors.
// All errors returning from the library are of this type.
// Errors resulting from Go's stdlib are not translated to this type, unless
// they are a net.Timeout error.
type AerospikeError struct {
	error

	resultCode ResultCode
	inDoubt    bool
}

// ResultCode returns the ResultCode from AerospikeError object.
func (ase AerospikeError) ResultCode() ResultCode {
	return ase.resultCode
}

// InDoubt determines if a write transaction may have completed or not.
func (ase AerospikeError) InDoubt() bool {
	return ase.inDoubt
}

// SetInDoubt sets whether it is possible that the write transaction may have completed
// even though this error was generated.  This may be the case when a
// client error occurs (like timeout) after the command was sent to the server.
func (ase AerospikeError) SetInDoubt(isRead bool, commandSentCounter int) {
	if !isRead && (commandSentCounter > 1 || (commandSentCounter == 1 && (ase.resultCode == TIMEOUT || ase.resultCode <= 0))) {
		ase.inDoubt = true
	}
}

// MarkInDoubt marks an error as in doubt.
func (ase AerospikeError) MarkInDoubt() {
	ase.inDoubt = true
}

// NewAerospikeError generates a new AerospikeError instance.
// If no message is provided, the result code will be translated into the default
// error message automatically.
// To be able to check for error type, you could use the following:
//   if aerr, ok := err.(AerospikeError); ok {
//       errCode := aerr.ResultCode()
//       errMessage := aerr.Error()
//   }
func NewAerospikeError(code ResultCode, messages ...string) error {
	if len(messages) == 0 {
		messages = []string{ResultCodeToString(code)}
	}

	err := errors.New(strings.Join(messages, " "))
	return AerospikeError{error: err, resultCode: code}
}

var ErrRecordsetClosed = NewAerospikeError(RECORDSET_CLOSED, "Recordset has already been closed.")
var ErrConnectionPoolEmpty = NewAerospikeError(NO_AVAILABLE_CONNECTIONS_TO_NODE)
<|endoftext|>


<commit_before>package types

import (
	"os"
	"time"

	"github.com/docker/docker/daemon/network"
	"github.com/docker/docker/pkg/version"
	"github.com/docker/docker/runconfig"
)

// ContainerCreateResponse contains the information returned to a client on the
// creation of a new container.
type ContainerCreateResponse struct {
	// ID is the ID of the created container.
	ID string `json:"Id"`

	// Warnings are any warnings encountered during the creation of the container.
	Warnings []string `json:"Warnings"`
}

// POST /containers/{name:.*}/exec
type ContainerExecCreateResponse struct {
	// ID is the exec ID.
	ID string `json:"Id"`
}

// POST /auth
type AuthResponse struct {
	// Status is the authentication status
	Status string `json:"Status"`
}

// POST "/containers/"+containerID+"/wait"
type ContainerWaitResponse struct {
	// StatusCode is the status code of the wait job
	StatusCode int `json:"StatusCode"`
}

// POST "/commit?container="+containerID
type ContainerCommitResponse struct {
	ID string `json:"Id"`
}

// GET "/containers/{name:.*}/changes"
type ContainerChange struct {
	Kind int
	Path string
}

// GET "/images/{name:.*}/history"
type ImageHistory struct {
	ID        string `json:"Id"`
	Created   int64
	CreatedBy string
	Tags      []string
	Size      int64
	Comment   string
}

// DELETE "/images/{name:.*}"
type ImageDelete struct {
	Untagged string `json:",omitempty"`
	Deleted  string `json:",omitempty"`
}

// GET "/images/json"
type Image struct {
	ID          string `json:"Id"`
	ParentId    string
	RepoTags    []string
	RepoDigests []string
	Created     int
	Size        int
	VirtualSize int
	Labels      map[string]string
}

type GraphDriverData struct {
	Name string
	Data map[string]string
}

// GET "/images/{name:.*}/json"
type ImageInspect struct {
	Id              string
	Parent          string
	Comment         string
	Created         string
	Container       string
	ContainerConfig *runconfig.Config
	DockerVersion   string
	Author          string
	Config          *runconfig.Config
	Architecture    string
	Os              string
	Size            int64
	VirtualSize     int64
	GraphDriver     GraphDriverData
}

// GET  "/containers/json"
type Port struct {
	IP          string `json:",omitempty"`
	PrivatePort int
	PublicPort  int `json:",omitempty"`
	Type        string
}

type Container struct {
	ID         string `json:"Id"`
	Names      []string
	Image      string
	Command    string
	Created    int
	Ports      []Port
	SizeRw     int `json:",omitempty"`
	SizeRootFs int `json:",omitempty"`
	Labels     map[string]string
	Status     string
	HostConfig struct {
		NetworkMode string `json:",omitempty"`
	}
}

// POST "/containers/"+containerID+"/copy"
type CopyConfig struct {
	Resource string
}

// ContainerPathStat is used to encode the header from
// 	GET /containers/{name:.*}/archive
// "name" is the file or directory name.
// "path" is the absolute path to the resource in the container.
type ContainerPathStat struct {
	Name  string      `json:"name"`
	Path  string      `json:"path"`
	Size  int64       `json:"size"`
	Mode  os.FileMode `json:"mode"`
	Mtime time.Time   `json:"mtime"`
}

// GET "/containers/{name:.*}/top"
type ContainerProcessList struct {
	Processes [][]string
	Titles    []string
}

type Version struct {
	Version       string
	ApiVersion    version.Version
	GitCommit     string
	GoVersion     string
	Os            string
	Arch          string
	KernelVersion string `json:",omitempty"`
	Experimental  bool   `json:",omitempty"`
	BuildTime     string `json:",omitempty"`
}

// GET "/info"
type Info struct {
	ID                 string
	Containers         int
	Images             int
	Driver             string
	DriverStatus       [][2]string
	MemoryLimit        bool
	SwapLimit          bool
	CpuCfsPeriod       bool
	CpuCfsQuota        bool
	IPv4Forwarding     bool
	BridgeNfIptables   bool
	BridgeNfIp6tables  bool
	Debug              bool
	NFd                int
	OomKillDisable     bool
	NGoroutines        int
	SystemTime         string
	ExecutionDriver    string
	LoggingDriver      string
	NEventsListener    int
	KernelVersion      string
	OperatingSystem    string
	IndexServerAddress string
	RegistryConfig     interface{}
	InitSha1           string
	InitPath           string
	NCPU               int
	MemTotal           int64
	DockerRootDir      string
	HttpProxy          string
	HttpsProxy         string
	NoProxy            string
	Name               string
	Labels             []string
	ExperimentalBuild  bool
}

// This struct is a temp struct used by execStart
// Config fields is part of ExecConfig in runconfig package
type ExecStartCheck struct {
	// ExecStart will first check if it's detached
	Detach bool
	// Check if there's a tty
	Tty bool
}

type ContainerState struct {
	Running    bool
	Paused     bool
	Restarting bool
	OOMKilled  bool
	Dead       bool
	Pid        int
	ExitCode   int
	Error      string
	StartedAt  string
	FinishedAt string
}

// GET "/containers/{name:.*}/json"
type ContainerJSONBase struct {
	Id              string
	Created         string
	Path            string
	Args            []string
	State           *ContainerState
	Image           string
	NetworkSettings *network.Settings
	ResolvConfPath  string
	HostnamePath    string
	HostsPath       string
	LogPath         string
	Name            string
	RestartCount    int
	Driver          string
	ExecDriver      string
	MountLabel      string
	ProcessLabel    string
	AppArmorProfile string
	ExecIDs         []string
	HostConfig      *runconfig.HostConfig
	GraphDriver     GraphDriverData
}

type ContainerJSON struct {
	*ContainerJSONBase
	Mounts []MountPoint
	Config *runconfig.Config
}

// backcompatibility struct along with ContainerConfig
type ContainerJSONPre120 struct {
	*ContainerJSONBase
	Volumes   map[string]string
	VolumesRW map[string]bool
	Config    *ContainerConfig
}

type ContainerConfig struct {
	*runconfig.Config

	// backward compatibility, they now live in HostConfig
	Memory     int64
	MemorySwap int64
	CpuShares  int64
	Cpuset     string
}

// MountPoint represents a mount point configuration inside the container.
type MountPoint struct {
	Name        string `json:",omitempty"`
	Source      string
	Destination string
	Driver      string `json:",omitempty"`
	Mode        string
	RW          bool
}
<commit_msg>Windows: Factoring out unused fields<commit_after>package types

import (
	"os"
	"time"

	"github.com/docker/docker/daemon/network"
	"github.com/docker/docker/pkg/version"
	"github.com/docker/docker/runconfig"
)

// ContainerCreateResponse contains the information returned to a client on the
// creation of a new container.
type ContainerCreateResponse struct {
	// ID is the ID of the created container.
	ID string `json:"Id"`

	// Warnings are any warnings encountered during the creation of the container.
	Warnings []string `json:"Warnings"`
}

// POST /containers/{name:.*}/exec
type ContainerExecCreateResponse struct {
	// ID is the exec ID.
	ID string `json:"Id"`
}

// POST /auth
type AuthResponse struct {
	// Status is the authentication status
	Status string `json:"Status"`
}

// POST "/containers/"+containerID+"/wait"
type ContainerWaitResponse struct {
	// StatusCode is the status code of the wait job
	StatusCode int `json:"StatusCode"`
}

// POST "/commit?container="+containerID
type ContainerCommitResponse struct {
	ID string `json:"Id"`
}

// GET "/containers/{name:.*}/changes"
type ContainerChange struct {
	Kind int
	Path string
}

// GET "/images/{name:.*}/history"
type ImageHistory struct {
	ID        string `json:"Id"`
	Created   int64
	CreatedBy string
	Tags      []string
	Size      int64
	Comment   string
}

// DELETE "/images/{name:.*}"
type ImageDelete struct {
	Untagged string `json:",omitempty"`
	Deleted  string `json:",omitempty"`
}

// GET "/images/json"
type Image struct {
	ID          string `json:"Id"`
	ParentId    string
	RepoTags    []string
	RepoDigests []string
	Created     int
	Size        int
	VirtualSize int
	Labels      map[string]string
}

type GraphDriverData struct {
	Name string
	Data map[string]string
}

// GET "/images/{name:.*}/json"
type ImageInspect struct {
	Id              string
	Parent          string
	Comment         string
	Created         string
	Container       string
	ContainerConfig *runconfig.Config
	DockerVersion   string
	Author          string
	Config          *runconfig.Config
	Architecture    string
	Os              string
	Size            int64
	VirtualSize     int64
	GraphDriver     GraphDriverData
}

// GET  "/containers/json"
type Port struct {
	IP          string `json:",omitempty"`
	PrivatePort int
	PublicPort  int `json:",omitempty"`
	Type        string
}

type Container struct {
	ID         string `json:"Id"`
	Names      []string
	Image      string
	Command    string
	Created    int
	Ports      []Port
	SizeRw     int `json:",omitempty"`
	SizeRootFs int `json:",omitempty"`
	Labels     map[string]string
	Status     string
	HostConfig struct {
		NetworkMode string `json:",omitempty"`
	}
}

// POST "/containers/"+containerID+"/copy"
type CopyConfig struct {
	Resource string
}

// ContainerPathStat is used to encode the header from
// 	GET /containers/{name:.*}/archive
// "name" is the file or directory name.
// "path" is the absolute path to the resource in the container.
type ContainerPathStat struct {
	Name  string      `json:"name"`
	Path  string      `json:"path"`
	Size  int64       `json:"size"`
	Mode  os.FileMode `json:"mode"`
	Mtime time.Time   `json:"mtime"`
}

// GET "/containers/{name:.*}/top"
type ContainerProcessList struct {
	Processes [][]string
	Titles    []string
}

type Version struct {
	Version       string
	ApiVersion    version.Version
	GitCommit     string
	GoVersion     string
	Os            string
	Arch          string
	KernelVersion string `json:",omitempty"`
	Experimental  bool   `json:",omitempty"`
	BuildTime     string `json:",omitempty"`
}

// GET "/info"
type Info struct {
	ID                 string
	Containers         int
	Images             int
	Driver             string
	DriverStatus       [][2]string
	MemoryLimit        bool
	SwapLimit          bool
	CpuCfsPeriod       bool
	CpuCfsQuota        bool
	IPv4Forwarding     bool
	BridgeNfIptables   bool
	BridgeNfIp6tables  bool
	Debug              bool
	NFd                int
	OomKillDisable     bool
	NGoroutines        int
	SystemTime         string
	ExecutionDriver    string
	LoggingDriver      string
	NEventsListener    int
	KernelVersion      string
	OperatingSystem    string
	IndexServerAddress string
	RegistryConfig     interface{}
	InitSha1           string
	InitPath           string
	NCPU               int
	MemTotal           int64
	DockerRootDir      string
	HttpProxy          string
	HttpsProxy         string
	NoProxy            string
	Name               string
	Labels             []string
	ExperimentalBuild  bool
}

// This struct is a temp struct used by execStart
// Config fields is part of ExecConfig in runconfig package
type ExecStartCheck struct {
	// ExecStart will first check if it's detached
	Detach bool
	// Check if there's a tty
	Tty bool
}

type ContainerState struct {
	Running    bool
	Paused     bool
	Restarting bool
	OOMKilled  bool
	Dead       bool
	Pid        int
	ExitCode   int
	Error      string
	StartedAt  string
	FinishedAt string
}

// GET "/containers/{name:.*}/json"
type ContainerJSONBase struct {
	Id              string
	Created         string
	Path            string
	Args            []string
	State           *ContainerState
	Image           string
	NetworkSettings *network.Settings
	ResolvConfPath  string
	HostnamePath    string
	HostsPath       string
	LogPath         string
	Name            string
	RestartCount    int
	Driver          string
	ExecDriver      string
	MountLabel      string
	ProcessLabel    string
	AppArmorProfile string
	ExecIDs         []string
	HostConfig      *runconfig.HostConfig
	GraphDriver     GraphDriverData
}

type ContainerJSON struct {
	*ContainerJSONBase
	Mounts []MountPoint
	Config *runconfig.Config
}

// backcompatibility struct along with ContainerConfig. Note this is not
// used by the Windows daemon.
type ContainerJSONPre120 struct {
	*ContainerJSONBase
	Volumes   map[string]string
	VolumesRW map[string]bool
	Config    *ContainerConfig
}

type ContainerConfig struct {
	*runconfig.Config

	// backward compatibility, they now live in HostConfig
	Memory     int64
	MemorySwap int64
	CpuShares  int64
	Cpuset     string
}

// MountPoint represents a mount point configuration inside the container.
type MountPoint struct {
	Name        string `json:",omitempty"`
	Source      string
	Destination string
	Driver      string `json:",omitempty"`
	Mode        string
	RW          bool
}
<|endoftext|>


<commit_before>package fixchain

import (
	"net/http"
	"testing"

	"github.com/google/certificate-transparency/go/x509"
)

var constructChainTests = []fixTest{
	// constructChain()
	{ // Correct chain returns chain
		cert:  googleLeaf,
		chain: []string{verisignRoot, thawteIntermediate},
		roots: []string{verisignRoot},

		function: "constructChain",
		expectedChains: [][]string{
			{"Google", "Thawte", "VeriSign"},
		},
	},
	{ // No roots results in an error
		cert:  googleLeaf,
		chain: []string{verisignRoot, thawteIntermediate},

		function:     "constructChain",
		expectedErrs: []errorType{VerifyFailed},
	},
	{ // Incomplete chain results in an error
		cert:  googleLeaf,
		roots: []string{verisignRoot},

		function:     "constructChain",
		expectedErrs: []errorType{VerifyFailed},
	},
	{ // The wrong intermediate and root results in an error
		cert:  megaLeaf,
		chain: []string{verisignRoot, thawteIntermediate},
		roots: []string{verisignRoot},

		function:     "constructChain",
		expectedErrs: []errorType{VerifyFailed},
	},
	{ // The wrong root results in an error
		cert:  megaLeaf,
		chain: []string{verisignRoot, comodoIntermediate},
		roots: []string{verisignRoot},

		function:     "constructChain",
		expectedErrs: []errorType{VerifyFailed},
	},
}

var fixChainTests = []fixTest{
	// fixChain()
	{ // Correct chain returns multiple chains - the complete one initially
		// given, and one containing the cert for Thawte downloaded by
		// augmentIntermediates() from the url in the AIA information of the
		// googleLeaf cert.
		// Note: In practice this should not happen, as fixChain is only called
		// if constructChain fails.
		cert:  googleLeaf,
		chain: []string{verisignRoot, thawteIntermediate},
		roots: []string{verisignRoot},

		function: "fixChain",
		expectedChains: [][]string{
			{"Google", "Thawte", "VeriSign"},
			{"Google", "Thawte", "VeriSign"},
		},
	},
	{ // No roots results in an error
		cert:  googleLeaf,
		chain: []string{verisignRoot, thawteIntermediate},

		function:     "fixChain",
		expectedErrs: []errorType{FixFailed},
	},
	{ // Incomplete chain returns fixed chain
		cert:  googleLeaf,
		roots: []string{verisignRoot},

		function: "fixChain",
		expectedChains: [][]string{
			{"Google", "Thawte", "VeriSign"},
		},
	},
	{ // The wrong intermediate and root results in an error
		cert:  megaLeaf,
		chain: []string{verisignRoot, thawteIntermediate},
		roots: []string{verisignRoot},

		function:     "fixChain",
		expectedErrs: []errorType{FixFailed},
	},
	{ // The wrong root results in an error
		cert:  megaLeaf,
		chain: []string{verisignRoot, comodoIntermediate},
		roots: []string{verisignRoot},

		function:     "fixChain",
		expectedErrs: []errorType{FixFailed},
	},
}

func setUpFix(t *testing.T, i int, ft *fixTest) *toFix {
	// Create & populate toFix to test from fixTest info
	fix := &toFix{
		cert:  GetTestCertificateFromPEM(t, ft.cert),
		chain: newDedupedChain(extractTestChain(t, i, ft.chain)),
		roots: extractTestRoots(t, i, ft.roots),
		cache: newURLCache(&http.Client{}, false),
	}

	intermediates := x509.NewCertPool()
	for j, cert := range ft.chain {
		ok := intermediates.AppendCertsFromPEM([]byte(cert))
		if !ok {
			t.Errorf("#%d: Failed to parse intermediate #%d", i, j)
		}
	}

	fix.opts = &x509.VerifyOptions{
		Intermediates:     intermediates,
		Roots:             fix.roots,
		DisableTimeChecks: true,
		KeyUsages:         []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
	}

	return fix
}

func testFixChainFunctions(t *testing.T, i int, ft *fixTest) {
	fix := setUpFix(t, i, ft)

	var chains [][]*x509.Certificate
	var ferrs []*FixError
	switch ft.function {
	case "constructChain":
		chains, ferrs = fix.constructChain()
	case "fixChain":
		chains, ferrs = fix.fixChain()
	case "handleChain":
		chains, ferrs = fix.handleChain()
	}

	matchTestChainList(t, i, ft.expectedChains, chains)
	matchTestErrorList(t, i, ft.expectedErrs, ferrs)
}

func TestFixChainFunctions(t *testing.T) {
	var allTests []fixTest
	allTests = append(allTests, constructChainTests...)
	allTests = append(allTests, fixChainTests...)
	allTests = append(allTests, handleChainTests...)
	for i, ft := range allTests {
		testFixChainFunctions(t, i, &ft)
	}
}
<commit_msg>Add tests for new synchronous Fix() function<commit_after>package fixchain

import (
	"net/http"
	"testing"

	"github.com/google/certificate-transparency/go/x509"
)

var constructChainTests = []fixTest{
	// constructChain()
	{ // Correct chain returns chain
		cert:  googleLeaf,
		chain: []string{verisignRoot, thawteIntermediate},
		roots: []string{verisignRoot},

		function: "constructChain",
		expectedChains: [][]string{
			{"Google", "Thawte", "VeriSign"},
		},
	},
	{ // No roots results in an error
		cert:  googleLeaf,
		chain: []string{verisignRoot, thawteIntermediate},

		function:     "constructChain",
		expectedErrs: []errorType{VerifyFailed},
	},
	{ // Incomplete chain results in an error
		cert:  googleLeaf,
		roots: []string{verisignRoot},

		function:     "constructChain",
		expectedErrs: []errorType{VerifyFailed},
	},
	{ // The wrong intermediate and root results in an error
		cert:  megaLeaf,
		chain: []string{verisignRoot, thawteIntermediate},
		roots: []string{verisignRoot},

		function:     "constructChain",
		expectedErrs: []errorType{VerifyFailed},
	},
	{ // The wrong root results in an error
		cert:  megaLeaf,
		chain: []string{verisignRoot, comodoIntermediate},
		roots: []string{verisignRoot},

		function:     "constructChain",
		expectedErrs: []errorType{VerifyFailed},
	},
}

var fixChainTests = []fixTest{
	// fixChain()
	{ // Correct chain returns multiple chains - the complete one initially
		// given, and one containing the cert for Thawte downloaded by
		// augmentIntermediates() from the url in the AIA information of the
		// googleLeaf cert.
		// Note: In practice this should not happen, as fixChain is only called
		// if constructChain fails.
		cert:  googleLeaf,
		chain: []string{verisignRoot, thawteIntermediate},
		roots: []string{verisignRoot},

		function: "fixChain",
		expectedChains: [][]string{
			{"Google", "Thawte", "VeriSign"},
			{"Google", "Thawte", "VeriSign"},
		},
	},
	{ // No roots results in an error
		cert:  googleLeaf,
		chain: []string{verisignRoot, thawteIntermediate},

		function:     "fixChain",
		expectedErrs: []errorType{FixFailed},
	},
	{ // Incomplete chain returns fixed chain
		cert:  googleLeaf,
		roots: []string{verisignRoot},

		function: "fixChain",
		expectedChains: [][]string{
			{"Google", "Thawte", "VeriSign"},
		},
	},
	{ // The wrong intermediate and root results in an error
		cert:  megaLeaf,
		chain: []string{verisignRoot, thawteIntermediate},
		roots: []string{verisignRoot},

		function:     "fixChain",
		expectedErrs: []errorType{FixFailed},
	},
	{ // The wrong root results in an error
		cert:  megaLeaf,
		chain: []string{verisignRoot, comodoIntermediate},
		roots: []string{verisignRoot},

		function:     "fixChain",
		expectedErrs: []errorType{FixFailed},
	},
}

func setUpFix(t *testing.T, i int, ft *fixTest) *toFix {
	// Create & populate toFix to test from fixTest info
	fix := &toFix{
		cert:  GetTestCertificateFromPEM(t, ft.cert),
		chain: newDedupedChain(extractTestChain(t, i, ft.chain)),
		roots: extractTestRoots(t, i, ft.roots),
		cache: newURLCache(&http.Client{}, false),
	}

	intermediates := x509.NewCertPool()
	for j, cert := range ft.chain {
		ok := intermediates.AppendCertsFromPEM([]byte(cert))
		if !ok {
			t.Errorf("#%d: Failed to parse intermediate #%d", i, j)
		}
	}

	fix.opts = &x509.VerifyOptions{
		Intermediates:     intermediates,
		Roots:             fix.roots,
		DisableTimeChecks: true,
		KeyUsages:         []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
	}

	return fix
}

func testFixChainFunctions(t *testing.T, i int, ft *fixTest) {
	fix := setUpFix(t, i, ft)

	var chains [][]*x509.Certificate
	var ferrs []*FixError
	switch ft.function {
	case "constructChain":
		chains, ferrs = fix.constructChain()
	case "fixChain":
		chains, ferrs = fix.fixChain()
	case "handleChain":
		chains, ferrs = fix.handleChain()
	}

	matchTestChainList(t, i, ft.expectedChains, chains)
	matchTestErrorList(t, i, ft.expectedErrs, ferrs)
}

func TestFixChainFunctions(t *testing.T) {
	var allTests []fixTest
	allTests = append(allTests, constructChainTests...)
	allTests = append(allTests, fixChainTests...)
	allTests = append(allTests, handleChainTests...)
	for i, ft := range allTests {
		testFixChainFunctions(t, i, &ft)
	}
}

func TestFix(t *testing.T) {
	for i, test := range handleChainTests {
		chains, ferrs := Fix(GetTestCertificateFromPEM(t, test.cert),
			extractTestChain(t, i, test.chain),
			extractTestRoots(t, i, test.roots),
			&http.Client{})

		matchTestChainList(t, i, test.expectedChains, chains)
		matchTestErrorList(t, i, test.expectedErrs, ferrs)
	}
}
<|endoftext|>


<commit_before>// errorcheck -0 -m -l

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

// Test, using compiler diagnostic flags, that bounds check elimination
// is eliminating the correct checks.

package foo

var (
	s []int

	a1 [1]int
	a1k [1000]int
	a100k [100000]int

	p1 *[1]int
	p1k *[1000]int
	p100k *[100000]int

	i int
	ui uint
	i8 int8
	ui8 uint8
	i16 int16
	ui16 uint16
	i32 int32
	ui32 uint32
	i64 int64
	ui64 uint64
)

func main() {
	// Most things need checks.
	use(s[i])
	use(a1[i])
	use(a1k[i])
	use(a100k[i])
	use(p1[i])
	use(p1k[i])
	use(p100k[i])

	use(s[ui])
	use(a1[ui])
	use(a1k[ui])
	use(a100k[ui])
	use(p1[ui])
	use(p1k[ui])
	use(p100k[ui])

	use(s[i8])
	use(a1[i8])
	use(a1k[i8])
	use(a100k[i8])
	use(p1[i8])
	use(p1k[i8])
	use(p100k[i8])

	// Unsigned 8-bit numbers don't need checks for len >= 2⁸.
	use(s[ui8])
	use(a1[ui8])
	use(a1k[ui8])  // ERROR "index bounds check elided"
	use(a100k[ui8])  // ERROR "index bounds check elided"
	use(p1[ui8])
	use(p1k[ui8])  // ERROR "index bounds check elided"
	use(p100k[ui8])  // ERROR "index bounds check elided"

	use(s[i16])
	use(a1[i16])
	use(a1k[i16])
	use(a100k[i16])
	use(p1[i16])
	use(p1k[i16])
	use(p100k[i16])

	// Unsigned 16-bit numbers don't need checks for len >= 2¹⁶.
	use(s[ui16])
	use(a1[ui16])
	use(a1k[ui16])
	use(a100k[ui16])  // ERROR "index bounds check elided"
	use(p1[ui16])
	use(p1k[ui16])
	use(p100k[ui16])  // ERROR "index bounds check elided"

	use(s[i32])
	use(a1[i32])
	use(a1k[i32])
	use(a100k[i32])
	use(p1[i32])
	use(p1k[i32])
	use(p100k[i32])

	use(s[ui32])
	use(a1[ui32])
	use(a1k[ui32])
	use(a100k[ui32])
	use(p1[ui32])
	use(p1k[ui32])
	use(p100k[ui32])

	use(s[i64])
	use(a1[i64])
	use(a1k[i64])
	use(a100k[i64])
	use(p1[i64])
	use(p1k[i64])
	use(p100k[i64])

	use(s[ui64])
	use(a1[ui64])
	use(a1k[ui64])
	use(a100k[ui64])
	use(p1[ui64])
	use(p1k[ui64])
	use(p100k[ui64])

	// Mod truncates the maximum value to one less than the argument,
	// but signed mod can be negative, so only unsigned mod counts.
	use(s[i%999])
	use(a1[i%999])
	use(a1k[i%999])
	use(a100k[i%999])
	use(p1[i%999])
	use(p1k[i%999])
	use(p100k[i%999])

	use(s[ui%999])
	use(a1[ui%999])
	use(a1k[ui%999])  // ERROR "index bounds check elided"
	use(a100k[ui%999])  // ERROR "index bounds check elided"
	use(p1[ui%999])
	use(p1k[ui%999])  // ERROR "index bounds check elided"
	use(p100k[ui%999])  // ERROR "index bounds check elided"

	use(s[i%1000])
	use(a1[i%1000])
	use(a1k[i%1000])
	use(a100k[i%1000])
	use(p1[i%1000])
	use(p1k[i%1000])
	use(p100k[i%1000])

	use(s[ui%1000])
	use(a1[ui%1000])
	use(a1k[ui%1000])  // ERROR "index bounds check elided"
	use(a100k[ui%1000])  // ERROR "index bounds check elided"
	use(p1[ui%1000])
	use(p1k[ui%1000])  // ERROR "index bounds check elided"
	use(p100k[ui%1000])  // ERROR "index bounds check elided"

	use(s[i%1001])
	use(a1[i%1001])
	use(a1k[i%1001])
	use(a100k[i%1001])
	use(p1[i%1001])
	use(p1k[i%1001])
	use(p100k[i%1001])

	use(s[ui%1001])
	use(a1[ui%1001])
	use(a1k[ui%1001])
	use(a100k[ui%1001])  // ERROR "index bounds check elided"
	use(p1[ui%1001])
	use(p1k[ui%1001])
	use(p100k[ui%1001])  // ERROR "index bounds check elided"

	// Bitwise and truncates the maximum value to the mask value.
	// The result (for a positive mask) cannot be negative, so elision
	// applies to both signed and unsigned indexes.
	use(s[i&999])
	use(a1[i&999])
	use(a1k[i&999])  // ERROR "index bounds check elided"
	use(a100k[i&999])  // ERROR "index bounds check elided"
	use(p1[i&999])
	use(p1k[i&999])  // ERROR "index bounds check elided"
	use(p100k[i&999])  // ERROR "index bounds check elided"

	use(s[ui&999])
	use(a1[ui&999])
	use(a1k[ui&999])  // ERROR "index bounds check elided"
	use(a100k[ui&999])  // ERROR "index bounds check elided"
	use(p1[ui&999])
	use(p1k[ui&999])  // ERROR "index bounds check elided"
	use(p100k[ui&999])  // ERROR "index bounds check elided"

	use(s[i&1000])
	use(a1[i&1000])
	use(a1k[i&1000])
	use(a100k[i&1000])  // ERROR "index bounds check elided"
	use(p1[i&1000])
	use(p1k[i&1000])
	use(p100k[i&1000])  // ERROR "index bounds check elided"

	use(s[ui&1000])
	use(a1[ui&1000])
	use(a1k[ui&1000])
	use(a100k[ui&1000])  // ERROR "index bounds check elided"
	use(p1[ui&1000])
	use(p1k[ui&1000])
	use(p100k[ui&1000])  // ERROR "index bounds check elided"

	// Right shift cuts the effective number of bits in the index,
	// but only for unsigned (signed stays negative).
	use(s[i32>>22])
	use(a1[i32>>22])
	use(a1k[i32>>22])
	use(a100k[i32>>22])
	use(p1[i32>>22])
	use(p1k[i32>>22])
	use(p100k[i32>>22])

	use(s[ui32>>22])
	use(a1[ui32>>22])
	use(a1k[ui32>>22])
	use(a100k[ui32>>22])  // ERROR "index bounds check elided"
	use(p1[ui32>>22])
	use(p1k[ui32>>22])
	use(p100k[ui32>>22])  // ERROR "index bounds check elided"

	use(s[i32>>23])
	use(a1[i32>>23])
	use(a1k[i32>>23])
	use(a100k[i32>>23])
	use(p1[i32>>23])
	use(p1k[i32>>23])
	use(p100k[i32>>23])

	use(s[ui32>>23])
	use(a1[ui32>>23])
	use(a1k[ui32>>23])  // ERROR "index bounds check elided"
	use(a100k[ui32>>23])  // ERROR "index bounds check elided"
	use(p1[ui32>>23])
	use(p1k[ui32>>23])  // ERROR "index bounds check elided"
	use(p100k[ui32>>23])  // ERROR "index bounds check elided"

	// Division cuts the range like right shift does.
	use(s[i/1e6])
	use(a1[i/1e6])
	use(a1k[i/1e6])
	use(a100k[i/1e6])
	use(p1[i/1e6])
	use(p1k[i/1e6])
	use(p100k[i/1e6])

	use(s[ui/1e6])
	use(a1[ui/1e6])
	use(a1k[ui/1e6])
	use(p1[ui/1e6])
	use(p1k[ui/1e6])

	use(s[i/1e7])
	use(a1[i/1e7])
	use(a1k[i/1e7])
	use(a100k[i/1e7])
	use(p1[i/1e7])
	use(p1k[i/1e7])
	use(p100k[i/1e7])

	use(s[ui/1e7])
	use(a1[ui/1e7])
	use(p1[ui/1e7])
}

var sum int

func use(x int) {
	sum += x
}
<commit_msg>test: gofmt bounds.go<commit_after>// errorcheck -0 -m -l

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

// Test, using compiler diagnostic flags, that bounds check elimination
// is eliminating the correct checks.

package foo

var (
	s []int

	a1    [1]int
	a1k   [1000]int
	a100k [100000]int

	p1    *[1]int
	p1k   *[1000]int
	p100k *[100000]int

	i    int
	ui   uint
	i8   int8
	ui8  uint8
	i16  int16
	ui16 uint16
	i32  int32
	ui32 uint32
	i64  int64
	ui64 uint64
)

func main() {
	// Most things need checks.
	use(s[i])
	use(a1[i])
	use(a1k[i])
	use(a100k[i])
	use(p1[i])
	use(p1k[i])
	use(p100k[i])

	use(s[ui])
	use(a1[ui])
	use(a1k[ui])
	use(a100k[ui])
	use(p1[ui])
	use(p1k[ui])
	use(p100k[ui])

	use(s[i8])
	use(a1[i8])
	use(a1k[i8])
	use(a100k[i8])
	use(p1[i8])
	use(p1k[i8])
	use(p100k[i8])

	// Unsigned 8-bit numbers don't need checks for len >= 2⁸.
	use(s[ui8])
	use(a1[ui8])
	use(a1k[ui8])   // ERROR "index bounds check elided"
	use(a100k[ui8]) // ERROR "index bounds check elided"
	use(p1[ui8])
	use(p1k[ui8])   // ERROR "index bounds check elided"
	use(p100k[ui8]) // ERROR "index bounds check elided"

	use(s[i16])
	use(a1[i16])
	use(a1k[i16])
	use(a100k[i16])
	use(p1[i16])
	use(p1k[i16])
	use(p100k[i16])

	// Unsigned 16-bit numbers don't need checks for len >= 2¹⁶.
	use(s[ui16])
	use(a1[ui16])
	use(a1k[ui16])
	use(a100k[ui16]) // ERROR "index bounds check elided"
	use(p1[ui16])
	use(p1k[ui16])
	use(p100k[ui16]) // ERROR "index bounds check elided"

	use(s[i32])
	use(a1[i32])
	use(a1k[i32])
	use(a100k[i32])
	use(p1[i32])
	use(p1k[i32])
	use(p100k[i32])

	use(s[ui32])
	use(a1[ui32])
	use(a1k[ui32])
	use(a100k[ui32])
	use(p1[ui32])
	use(p1k[ui32])
	use(p100k[ui32])

	use(s[i64])
	use(a1[i64])
	use(a1k[i64])
	use(a100k[i64])
	use(p1[i64])
	use(p1k[i64])
	use(p100k[i64])

	use(s[ui64])
	use(a1[ui64])
	use(a1k[ui64])
	use(a100k[ui64])
	use(p1[ui64])
	use(p1k[ui64])
	use(p100k[ui64])

	// Mod truncates the maximum value to one less than the argument,
	// but signed mod can be negative, so only unsigned mod counts.
	use(s[i%999])
	use(a1[i%999])
	use(a1k[i%999])
	use(a100k[i%999])
	use(p1[i%999])
	use(p1k[i%999])
	use(p100k[i%999])

	use(s[ui%999])
	use(a1[ui%999])
	use(a1k[ui%999])   // ERROR "index bounds check elided"
	use(a100k[ui%999]) // ERROR "index bounds check elided"
	use(p1[ui%999])
	use(p1k[ui%999])   // ERROR "index bounds check elided"
	use(p100k[ui%999]) // ERROR "index bounds check elided"

	use(s[i%1000])
	use(a1[i%1000])
	use(a1k[i%1000])
	use(a100k[i%1000])
	use(p1[i%1000])
	use(p1k[i%1000])
	use(p100k[i%1000])

	use(s[ui%1000])
	use(a1[ui%1000])
	use(a1k[ui%1000])   // ERROR "index bounds check elided"
	use(a100k[ui%1000]) // ERROR "index bounds check elided"
	use(p1[ui%1000])
	use(p1k[ui%1000])   // ERROR "index bounds check elided"
	use(p100k[ui%1000]) // ERROR "index bounds check elided"

	use(s[i%1001])
	use(a1[i%1001])
	use(a1k[i%1001])
	use(a100k[i%1001])
	use(p1[i%1001])
	use(p1k[i%1001])
	use(p100k[i%1001])

	use(s[ui%1001])
	use(a1[ui%1001])
	use(a1k[ui%1001])
	use(a100k[ui%1001]) // ERROR "index bounds check elided"
	use(p1[ui%1001])
	use(p1k[ui%1001])
	use(p100k[ui%1001]) // ERROR "index bounds check elided"

	// Bitwise and truncates the maximum value to the mask value.
	// The result (for a positive mask) cannot be negative, so elision
	// applies to both signed and unsigned indexes.
	use(s[i&999])
	use(a1[i&999])
	use(a1k[i&999])   // ERROR "index bounds check elided"
	use(a100k[i&999]) // ERROR "index bounds check elided"
	use(p1[i&999])
	use(p1k[i&999])   // ERROR "index bounds check elided"
	use(p100k[i&999]) // ERROR "index bounds check elided"

	use(s[ui&999])
	use(a1[ui&999])
	use(a1k[ui&999])   // ERROR "index bounds check elided"
	use(a100k[ui&999]) // ERROR "index bounds check elided"
	use(p1[ui&999])
	use(p1k[ui&999])   // ERROR "index bounds check elided"
	use(p100k[ui&999]) // ERROR "index bounds check elided"

	use(s[i&1000])
	use(a1[i&1000])
	use(a1k[i&1000])
	use(a100k[i&1000]) // ERROR "index bounds check elided"
	use(p1[i&1000])
	use(p1k[i&1000])
	use(p100k[i&1000]) // ERROR "index bounds check elided"

	use(s[ui&1000])
	use(a1[ui&1000])
	use(a1k[ui&1000])
	use(a100k[ui&1000]) // ERROR "index bounds check elided"
	use(p1[ui&1000])
	use(p1k[ui&1000])
	use(p100k[ui&1000]) // ERROR "index bounds check elided"

	// Right shift cuts the effective number of bits in the index,
	// but only for unsigned (signed stays negative).
	use(s[i32>>22])
	use(a1[i32>>22])
	use(a1k[i32>>22])
	use(a100k[i32>>22])
	use(p1[i32>>22])
	use(p1k[i32>>22])
	use(p100k[i32>>22])

	use(s[ui32>>22])
	use(a1[ui32>>22])
	use(a1k[ui32>>22])
	use(a100k[ui32>>22]) // ERROR "index bounds check elided"
	use(p1[ui32>>22])
	use(p1k[ui32>>22])
	use(p100k[ui32>>22]) // ERROR "index bounds check elided"

	use(s[i32>>23])
	use(a1[i32>>23])
	use(a1k[i32>>23])
	use(a100k[i32>>23])
	use(p1[i32>>23])
	use(p1k[i32>>23])
	use(p100k[i32>>23])

	use(s[ui32>>23])
	use(a1[ui32>>23])
	use(a1k[ui32>>23])   // ERROR "index bounds check elided"
	use(a100k[ui32>>23]) // ERROR "index bounds check elided"
	use(p1[ui32>>23])
	use(p1k[ui32>>23])   // ERROR "index bounds check elided"
	use(p100k[ui32>>23]) // ERROR "index bounds check elided"

	// Division cuts the range like right shift does.
	use(s[i/1e6])
	use(a1[i/1e6])
	use(a1k[i/1e6])
	use(a100k[i/1e6])
	use(p1[i/1e6])
	use(p1k[i/1e6])
	use(p100k[i/1e6])

	use(s[ui/1e6])
	use(a1[ui/1e6])
	use(a1k[ui/1e6])
	use(p1[ui/1e6])
	use(p1k[ui/1e6])

	use(s[i/1e7])
	use(a1[i/1e7])
	use(a1k[i/1e7])
	use(a100k[i/1e7])
	use(p1[i/1e7])
	use(p1k[i/1e7])
	use(p100k[i/1e7])

	use(s[ui/1e7])
	use(a1[ui/1e7])
	use(p1[ui/1e7])
}

var sum int

func use(x int) {
	sum += x
}
<|endoftext|>


<commit_before>package inbound

import (
	"context"

	"v2ray.com/core/app/proxyman"
	"v2ray.com/core/app/proxyman/mux"
	"v2ray.com/core/common"
	"v2ray.com/core/common/net"
	"v2ray.com/core/proxy"
	"v2ray.com/core/transport/internet/domainsocket"
)

type UnixInboundHandler struct {
	tag            string
	listenerHolder *domainsocket.Listener
	ctx            context.Context
	path           string
	proxy          proxy.Inbound
	mux            *mux.Server
}

func (uih *UnixInboundHandler) Start() {
	var err error
	uih.listenerHolder, err = domainsocket.ListenDS(uih.ctx, uih.path)
	if err != nil {
		newError(err).AtError().WriteToLog()
	}
	err = uih.listenerHolder.LowerUP()
	if err != nil {
		newError(err).AtError().WriteToLog()
	}
	nchan := make(chan net.Conn, 2)
	err = uih.listenerHolder.UP(nchan, false)
	if err != nil {
		newError(err).AtError().WriteToLog()
	}
	go uih.progressTraffic(nchan)
	return
}
func (uih *UnixInboundHandler) progressTraffic(rece <-chan net.Conn) {

	for {
		conn, notclosed := <-rece
		if !notclosed {
			return
		}
		go func(conn net.Conn) {
			ctx, cancel := context.WithCancel(uih.ctx)
			if len(uih.tag) > 0 {
				ctx = proxy.ContextWithInboundTag(ctx, uih.tag)
			}
			if err := uih.proxy.Process(ctx, net.Network_TCP, conn, uih.mux); err != nil {
				newError("connection ends").Base(err).WriteToLog()
			}
			cancel()
			conn.Close()
		}(conn)
	}
}
func (uih *UnixInboundHandler) Close() {
	if uih.listenerHolder != nil {
		uih.listenerHolder.Down()
	} else {
		newError("Called UnixInboundHandler.Close while listenerHolder is nil").AtDebug().WriteToLog()
	}

}
func (uih *UnixInboundHandler) Tag() string {
	return uih.tag
}

func (uih *UnixInboundHandler) GetRandomInboundProxy() (interface{}, net.Port, int) {
	//It makes bo sense to support it
	return nil, 0, 0
}

func NewUnixInboundHandler(ctx context.Context, tag string, receiverConfig *proxyman.UnixReceiverConfig, proxyConfig interface{}) (*UnixInboundHandler, error) {
	rawProxy, err := common.CreateObject(ctx, proxyConfig)
	if err != nil {
		return nil, err
	}
	p, ok := rawProxy.(proxy.Inbound)
	if !ok {
		return nil, newError("not an inbound proxy.")
	}

	h := &UnixInboundHandler{
		proxy: p,
		mux:   mux.NewServer(ctx),
		tag:   tag,
		ctx:   ctx,
		path:  receiverConfig.DomainSockSettings.GetPath(),
	}

	return h, nil

}
<commit_msg>Pass unused data into Receiver<commit_after>package inbound

import (
	"context"

	"v2ray.com/core/app/proxyman"
	"v2ray.com/core/app/proxyman/mux"
	"v2ray.com/core/common"
	"v2ray.com/core/common/net"
	"v2ray.com/core/proxy"
	"v2ray.com/core/transport/internet/domainsocket"
)

type UnixInboundHandler struct {
	tag            string
	listenerHolder *domainsocket.Listener
	ctx            context.Context
	path           string
	proxy          proxy.Inbound
	mux            *mux.Server
	additional     *proxyman.UnixReceiverConfig
}

func (uih *UnixInboundHandler) Start() {
	var err error
	uih.listenerHolder, err = domainsocket.ListenDS(uih.ctx, uih.path)
	if err != nil {
		newError(err).AtError().WriteToLog()
	}
	err = uih.listenerHolder.LowerUP()
	if err != nil {
		newError(err).AtError().WriteToLog()
	}
	nchan := make(chan net.Conn, 2)
	err = uih.listenerHolder.UP(nchan, false)
	if err != nil {
		newError(err).AtError().WriteToLog()
	}
	go uih.progressTraffic(nchan)
	return
}
func (uih *UnixInboundHandler) progressTraffic(rece <-chan net.Conn) {

	for {
		conn, notclosed := <-rece
		if !notclosed {
			return
		}
		go func(conn net.Conn) {
			ctx, cancel := context.WithCancel(uih.ctx)
			if len(uih.tag) > 0 {
				ctx = proxy.ContextWithInboundTag(ctx, uih.tag)
			}
			if err := uih.proxy.Process(ctx, net.Network_TCP, conn, uih.mux); err != nil {
				newError("connection ends").Base(err).WriteToLog()
			}
			cancel()
			conn.Close()
		}(conn)
	}
}
func (uih *UnixInboundHandler) Close() {
	if uih.listenerHolder != nil {
		uih.listenerHolder.Down()
	} else {
		newError("Called UnixInboundHandler.Close while listenerHolder is nil").AtDebug().WriteToLog()
	}

}
func (uih *UnixInboundHandler) Tag() string {
	return uih.tag
}

func (uih *UnixInboundHandler) GetRandomInboundProxy() (interface{}, net.Port, int) {
	//It makes bo sense to support it
	return nil, 0, 0
}

func NewUnixInboundHandler(ctx context.Context, tag string, receiverConfig *proxyman.UnixReceiverConfig, proxyConfig interface{}) (*UnixInboundHandler, error) {
	rawProxy, err := common.CreateObject(ctx, proxyConfig)
	if err != nil {
		return nil, err
	}
	p, ok := rawProxy.(proxy.Inbound)
	if !ok {
		return nil, newError("not an inbound proxy.")
	}

	h := &UnixInboundHandler{
		proxy:      p,
		mux:        mux.NewServer(ctx),
		tag:        tag,
		ctx:        ctx,
		path:       receiverConfig.DomainSockSettings.GetPath(),
		additional: receiverConfig,
	}

	return h, nil

}
<|endoftext|>


<commit_before>package makex

import (
	"bytes"
	"fmt"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"

	"github.com/sourcegraph/rwvfs"
)

type Makefile struct {
	Rules []Rule
}

type BasicRule struct {
	TargetFile  string
	PrereqFiles []string
	RecipeCmds  []string
}

func (r *BasicRule) Target() string    { return r.TargetFile }
func (r *BasicRule) Prereqs() []string { return r.PrereqFiles }
func (r *BasicRule) Recipes() []string { return r.RecipeCmds }

// Rule returns the rule to make the specified target if it exists, or nil
// otherwise.
//
// TODO(sqs): support multiple rules for one target
// (http://www.gnu.org/software/make/manual/html_node/Multiple-Rules.html).
func (mf *Makefile) Rule(target string) Rule {
	for _, rule := range mf.Rules {
		if rule.Target() == target {
			return rule
		}
	}
	return nil
}

type Rule interface {
	Target() string
	Prereqs() []string
	Recipes() []string
}

// DefaultRule is the first rule whose name does not begin with a ".", or nil if
// no such rule exists.
func (mf *Makefile) DefaultRule() Rule {
	for _, rule := range mf.Rules {
		target := rule.Target()
		if !strings.HasPrefix(target, ".") {
			return rule
		}
	}
	return nil
}

// Expand returns a clone of mf with Prereqs filepath globs expanded. If rules
// contain globs, they are replaced with BasicRules with the globs expanded.
//
// Only globs containing "*" are detected.
func (c *Config) Expand(orig *Makefile) (*Makefile, error) {
	var mf Makefile
	mf.Rules = make([]Rule, len(orig.Rules))
	for i, rule := range orig.Rules {
		expandedPrereqs, err := c.globs(rule.Prereqs())
		if err != nil {
			return nil, err
		}
		mf.Rules[i] = &BasicRule{
			TargetFile:  rule.Target(),
			PrereqFiles: expandedPrereqs,
			RecipeCmds:  rule.Recipes(),
		}

	}
	return &mf, nil
}

// globs returns all files in the filesystem that match any of the glob patterns
// (using path/filepath.Match glob syntax). The
func (c *Config) globs(patterns []string) (matches []string, err error) {
	for _, pattern := range patterns {
		if strings.ContainsAny(pattern, "*?[]") {
			files, err := c.glob(pattern)
			if err != nil {
				return nil, err
			}
			matches = append(matches, files...)
		}
	}
	return
}

// glob returns all files in the filesystem that match the glob pattern (using
// path/filepath.Match glob syntax).
func (c *Config) glob(pattern string) (matches []string, err error) {
	return rwvfs.Glob(walkableRWVFS{c.fs()}, globPrefix(pattern), pattern)
}

// globPrefix returns all path components up to (not including) the first path
// component that contains a "*".
func globPrefix(path string) string {
	cs := strings.Split(path, string(filepath.Separator))
	var prefix []string
	for _, c := range cs {
		if strings.Contains(c, "*") {
			break
		}
		prefix = append(prefix, c)
	}
	return filepath.Join(prefix...)
}

// ExpandAutoVars expands the automatic variables $@ (the current target path)
// and $^ (the space-separated list of prereqs) in s.
func ExpandAutoVars(rule Rule, s string) string {
	s = strings.Replace(s, "$@", Quote(rule.Target()), -1)
	s = strings.Replace(s, "$^", strings.Join(QuoteList(rule.Prereqs()), " "), -1)
	return s
}

func Marshal(mf *Makefile) ([]byte, error) {
	var b bytes.Buffer

	for i, rule := range mf.Rules {
		if i != 0 {
			fmt.Fprintln(&b)
		}

		ruleName := rule.Target()
		fmt.Fprintf(&b, "%s:", ruleName)
		for _, prereq := range rule.Prereqs() {
			fmt.Fprintf(&b, " %s", prereq)
		}
		fmt.Fprintln(&b)
		for _, recipe := range rule.Recipes() {
			fmt.Fprintf(&b, "\t%s\n", recipe)
		}
	}

	return b.Bytes(), nil
}

var cleanRE = regexp.MustCompile(`^[\w\d_/.-]+$`)

func Quote(s string) string {
	if cleanRE.MatchString(s) {
		return s
	}
	q := strconv.Quote(s)
	return "'" + strings.Replace(q[1:len(q)-1], "'", "", -1) + "'"
}

func QuoteList(ss []string) []string {
	q := make([]string, len(ss))
	for i, s := range ss {
		q[i] = Quote(s)
	}
	return q
}
<commit_msg>Targets<commit_after>package makex

import (
	"bytes"
	"fmt"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"

	"github.com/sourcegraph/rwvfs"
)

type Makefile struct {
	Rules []Rule
}

type BasicRule struct {
	TargetFile  string
	PrereqFiles []string
	RecipeCmds  []string
}

func (r *BasicRule) Target() string    { return r.TargetFile }
func (r *BasicRule) Prereqs() []string { return r.PrereqFiles }
func (r *BasicRule) Recipes() []string { return r.RecipeCmds }

// Rule returns the rule to make the specified target if it exists, or nil
// otherwise.
//
// TODO(sqs): support multiple rules for one target
// (http://www.gnu.org/software/make/manual/html_node/Multiple-Rules.html).
func (mf *Makefile) Rule(target string) Rule {
	for _, rule := range mf.Rules {
		if rule.Target() == target {
			return rule
		}
	}
	return nil
}

type Rule interface {
	Target() string
	Prereqs() []string
	Recipes() []string
}

// DefaultRule is the first rule whose name does not begin with a ".", or nil if
// no such rule exists.
func (mf *Makefile) DefaultRule() Rule {
	for _, rule := range mf.Rules {
		target := rule.Target()
		if !strings.HasPrefix(target, ".") {
			return rule
		}
	}
	return nil
}

// Expand returns a clone of mf with Prereqs filepath globs expanded. If rules
// contain globs, they are replaced with BasicRules with the globs expanded.
//
// Only globs containing "*" are detected.
func (c *Config) Expand(orig *Makefile) (*Makefile, error) {
	var mf Makefile
	mf.Rules = make([]Rule, len(orig.Rules))
	for i, rule := range orig.Rules {
		expandedPrereqs, err := c.globs(rule.Prereqs())
		if err != nil {
			return nil, err
		}
		mf.Rules[i] = &BasicRule{
			TargetFile:  rule.Target(),
			PrereqFiles: expandedPrereqs,
			RecipeCmds:  rule.Recipes(),
		}

	}
	return &mf, nil
}

// globs returns all files in the filesystem that match any of the glob patterns
// (using path/filepath.Match glob syntax). The
func (c *Config) globs(patterns []string) (matches []string, err error) {
	for _, pattern := range patterns {
		if strings.ContainsAny(pattern, "*?[]") {
			files, err := c.glob(pattern)
			if err != nil {
				return nil, err
			}
			matches = append(matches, files...)
		}
	}
	return
}

// glob returns all files in the filesystem that match the glob pattern (using
// path/filepath.Match glob syntax).
func (c *Config) glob(pattern string) (matches []string, err error) {
	return rwvfs.Glob(walkableRWVFS{c.fs()}, globPrefix(pattern), pattern)
}

// globPrefix returns all path components up to (not including) the first path
// component that contains a "*".
func globPrefix(path string) string {
	cs := strings.Split(path, string(filepath.Separator))
	var prefix []string
	for _, c := range cs {
		if strings.Contains(c, "*") {
			break
		}
		prefix = append(prefix, c)
	}
	return filepath.Join(prefix...)
}

// ExpandAutoVars expands the automatic variables $@ (the current target path)
// and $^ (the space-separated list of prereqs) in s.
func ExpandAutoVars(rule Rule, s string) string {
	s = strings.Replace(s, "$@", Quote(rule.Target()), -1)
	s = strings.Replace(s, "$^", strings.Join(QuoteList(rule.Prereqs()), " "), -1)
	return s
}

func Marshal(mf *Makefile) ([]byte, error) {
	var b bytes.Buffer

	for i, rule := range mf.Rules {
		if i != 0 {
			fmt.Fprintln(&b)
		}

		ruleName := rule.Target()
		fmt.Fprintf(&b, "%s:", ruleName)
		for _, prereq := range rule.Prereqs() {
			fmt.Fprintf(&b, " %s", prereq)
		}
		fmt.Fprintln(&b)
		for _, recipe := range rule.Recipes() {
			fmt.Fprintf(&b, "\t%s\n", recipe)
		}
	}

	return b.Bytes(), nil
}

var cleanRE = regexp.MustCompile(`^[\w\d_/.-]+$`)

func Quote(s string) string {
	if cleanRE.MatchString(s) {
		return s
	}
	q := strconv.Quote(s)
	return "'" + strings.Replace(q[1:len(q)-1], "'", "", -1) + "'"
}

func QuoteList(ss []string) []string {
	q := make([]string, len(ss))
	for i, s := range ss {
		q[i] = Quote(s)
	}
	return q
}

// Targets returns the list of targets defined by rules.
func Targets(rules []Rule) []string {
	targets := make([]string, len(rules))
	for i, rule := range rules {
		targets[i] = rule.Target()
	}
	return targets
}
<|endoftext|>


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

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

package main

type I interface {}
const (
	// assume all types behave similarly to int8/uint8
	Int8 int8 = 101;
	Minus1 int8 = -1;
	Uint8 uint8 = 102;
	Const = 103;

	Float32 float32 = 104.5;
	Float float = 105.5;
	ConstFloat = 106.5;
	Big float64 = 1e300;

	String = "abc";
	Bool = true;
)

var (
	a1 = Int8 * 100;	// ERROR "overflows"
	a2 = Int8 * -1;	// OK
	a3 = Int8 * 1000;	// ERROR "overflows"
	a4 = Int8 * int8(1000);	// ERROR "overflows"
	a5 = int8(Int8 * 1000);	// ERROR "overflows"
	a6 = int8(Int8 * int8(1000));	// ERROR "overflows"
	a7 = Int8 - 2*Int8 - 2*Int8;	// ERROR "overflows"
	a8 = Int8 * Const / 100;	// ERROR "overflows"
	a9 = Int8 * (Const / 100);	// OK

	b1 = Uint8 * Uint8;	// ERROR "overflows"
	b2 = Uint8 * -1;	// ERROR "overflows"
	b3 = Uint8 - Uint8;	// OK
	b4 = Uint8 - Uint8 - Uint8;	// ERROR "overflows"
	b5 = uint8(^0);	// ERROR "overflows"
	b6 = ^uint8(0);	// ERROR "overflows"
	b7 = uint8(Minus1);	// ERROR "overflows"
	b8 = uint8(int8(-1));	// ERROR "overflows"
	b8a = uint8(-1);	// ERROR "overflows"
	b9 byte = (1<<10) >> 8;	// OK
	b10 byte = (1<<10);	// ERROR "overflows"
	b11 byte = (byte(1)<<10) >> 8;	// ERROR "overflows"
	b12 byte = 1000;	// ERROR "overflows"
	b13 byte = byte(1000);	// ERROR "overflows"
	b14 byte = byte(100) * byte(100);	// ERROR "overflows"
	b15 byte = byte(100) * 100;	// ERROR "overflows"
	b16 byte = byte(0) * 1000;	// ERROR "overflows"
	b16a byte = 0 * 1000;	// OK
	b17 byte = byte(0) * byte(1000);	// ERROR "overflows"
	b18 byte = Uint8/0;	// ERROR "division by zero"

	c1 float64 = Big;
	c2 float64 = Big*Big;	// ERROR "overflows"
	c3 float64 = float64(Big)*Big;	// ERROR "overflows"
	c4 = Big*Big;	// ERROR "overflows"
	c5 = Big/0;	// ERROR "division by zero"
)

func f(int);

func main() {
	f(Int8);	// ERROR "convert"
	f(Minus1);	// ERROR "convert"
	f(Uint8);	// ERROR "convert"
	f(Const);	// OK
	f(Float32);	// ERROR "convert"
	f(Float);	// ERROR "convert"
	f(ConstFloat);	// ERROR "truncate"
	f(ConstFloat - 0.5);	// OK
	f(Big);	// ERROR "convert"
	f(String);	// ERROR "convert"
	f(Bool);	// ERROR "convert"
}
<commit_msg>Modify error regexps to match gccgo error messages.<commit_after>// errchk $G -e $F.go

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

package main

type I interface {}
const (
	// assume all types behave similarly to int8/uint8
	Int8 int8 = 101;
	Minus1 int8 = -1;
	Uint8 uint8 = 102;
	Const = 103;

	Float32 float32 = 104.5;
	Float float = 105.5;
	ConstFloat = 106.5;
	Big float64 = 1e300;

	String = "abc";
	Bool = true;
)

var (
	a1 = Int8 * 100;	// ERROR "overflow"
	a2 = Int8 * -1;	// OK
	a3 = Int8 * 1000;	// ERROR "overflow"
	a4 = Int8 * int8(1000);	// ERROR "overflow"
	a5 = int8(Int8 * 1000);	// ERROR "overflow"
	a6 = int8(Int8 * int8(1000));	// ERROR "overflow"
	a7 = Int8 - 2*Int8 - 2*Int8;	// ERROR "overflow"
	a8 = Int8 * Const / 100;	// ERROR "overflow"
	a9 = Int8 * (Const / 100);	// OK

	b1 = Uint8 * Uint8;	// ERROR "overflow"
	b2 = Uint8 * -1;	// ERROR "overflow"
	b3 = Uint8 - Uint8;	// OK
	b4 = Uint8 - Uint8 - Uint8;	// ERROR "overflow"
	b5 = uint8(^0);	// ERROR "overflow"
	b6 = ^uint8(0);	// ERROR "overflow"
	b7 = uint8(Minus1);	// ERROR "overflow"
	b8 = uint8(int8(-1));	// ERROR "overflow"
	b8a = uint8(-1);	// ERROR "overflow"
	b9 byte = (1<<10) >> 8;	// OK
	b10 byte = (1<<10);	// ERROR "overflow"
	b11 byte = (byte(1)<<10) >> 8;	// ERROR "overflow"
	b12 byte = 1000;	// ERROR "overflow"
	b13 byte = byte(1000);	// ERROR "overflow"
	b14 byte = byte(100) * byte(100);	// ERROR "overflow"
	b15 byte = byte(100) * 100;	// ERROR "overflow"
	b16 byte = byte(0) * 1000;	// ERROR "overflow"
	b16a byte = 0 * 1000;	// OK
	b17 byte = byte(0) * byte(1000);	// ERROR "overflow"
	b18 byte = Uint8/0;	// ERROR "division by zero"

	c1 float64 = Big;
	c2 float64 = Big*Big;	// ERROR "overflow"
	c3 float64 = float64(Big)*Big;	// ERROR "overflow"
	c4 = Big*Big;	// ERROR "overflow"
	c5 = Big/0;	// ERROR "division by zero"
)

func f(int);

func main() {
	f(Int8);	// ERROR "convert|wrong type"
	f(Minus1);	// ERROR "convert|wrong type"
	f(Uint8);	// ERROR "convert|wrong type"
	f(Const);	// OK
	f(Float32);	// ERROR "convert|wrong type"
	f(Float);	// ERROR "convert|wrong type"
	f(ConstFloat);	// ERROR "truncate"
	f(ConstFloat - 0.5);	// OK
	f(Big);	// ERROR "convert|wrong type"
	f(String);	// ERROR "convert|wrong type"
	f(Bool);	// ERROR "convert|wrong type"
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Thomas de Zeeuw.
//
// Licensed under the MIT license that can be found in the LICENSE file.

package logger

import (
	"bytes"
	"errors"
	"fmt"
	"reflect"
	"runtime"
	"testing"
	"time"
)

// Time returned in calling now(), setup and test in init.
var t1 = time.Date(2015, 9, 1, 14, 22, 36, 0, time.UTC)

func init() {
	margin := time.Millisecond
	t, t2 := now(), time.Now()
	if !t.Truncate(margin).Equal(t2.Truncate(margin)) {
		panic(fmt.Sprintf("now() doesn't return time.Now()! Expected %s, got %s",
			t2, t))
	}

	now = func() time.Time {
		return t1
	}
}

// EventWriter that collects the events and errors.
type eventWriter struct {
	events []Event
	errors []error
	closed bool
}

func (ew *eventWriter) Write(event Event) error {
	ew.events = append(ew.events, event)
	return nil
}

func (ew *eventWriter) HandleError(err error) {
	ew.errors = append(ew.errors, err)
}

func (ew *eventWriter) Close() error {
	ew.closed = true
	return nil
}

// A data type to be used in calling Log.
type user struct {
	ID   int
	Name string
}

func TestLog(t *testing.T) {
	defer reset()
	var ew eventWriter
	Start(&ew)

	tags := Tags{"my", "tags"}
	eventType := NewEventType("my-event-type")
	data := user{1, "Thomas"}
	event := Event{
		Type:    eventType,
		Tags:    tags,
		Message: "My event",
		Data:    data,
	}

	Debug(tags, "Debug message")
	Debugf(tags, "Debug %s message", "formatted")
	Info(tags, "Info message")
	Infof(tags, "Info %s message", "formatted")
	Warn(tags, "Warn message")
	Warnf(tags, "Warn %s message", "formatted")
	Error(tags, errors.New("Error message"))
	Errorf(tags, "Error %s message", "formatted")

	defer func() {
		recv := recover()
		Fatal(tags, recv)
		testThumstone(tags)
		Log(event)

		if err := Close(); err != nil {
			t.Fatal("Unexpected error closing: " + err.Error())
		}

		if len(ew.errors) != 0 {
			t.Fatalf("Unexpected error(s): %v", ew.errors)
		}

		pc, file, _, _ := runtime.Caller(0)
		fn := runtime.FuncForPC(pc)

		expected := []Event{
			Event{Type: DebugEvent, Tags: tags, Message: "Debug message"},
			Event{Type: DebugEvent, Tags: tags, Message: "Debug formatted message"},
			Event{Type: InfoEvent, Tags: tags, Message: "Info message"},
			Event{Type: InfoEvent, Tags: tags, Message: "Info formatted message"},
			Event{Type: WarnEvent, Tags: tags, Message: "Warn message"},
			Event{Type: WarnEvent, Tags: tags, Message: "Warn formatted message"},
			Event{Type: ErrorEvent, Tags: tags, Message: "Error message"},
			Event{Type: ErrorEvent, Tags: tags, Message: "Error formatted message"},
			Event{Type: FatalEvent, Tags: tags, Message: "Fatal message"},
			Event{Type: ThumbEvent, Tags: tags, Message: "Function testThumstone called by " + fn.Name() + ", from file " + file +
				" on line 87"},
			event,
		}

		if len(ew.events) != len(expected) {
			t.Fatalf("Expected to have %d events, but got %d",
				len(expected), len(ew.events))
		}

		for i, event := range ew.events {
			expectedEvent := expected[i]

			if expected, got := expectedEvent.Type, event.Type; expected != got {
				t.Errorf("Expected event #%d to have type %q, but got %q",
					i, expected, got)
			}

			if expected, got := t1, event.Timestamp; !expected.Equal(got) {
				t.Errorf("Expected event #%d to have timestamp %q, but got %q",
					i, expected, got)
			}

			if expected, got := expectedEvent.Tags, event.Tags; !reflect.DeepEqual(expected, got) {
				t.Errorf("Expected event #%d to have tags %q, but got %q",
					i, expected, got)
			}

			if expected, got := expectedEvent.Message, event.Message; expected != got {
				t.Errorf("Expected event #%d to have message %q, but got %q",
					i, expected, got)
			}

			if expectedEvent.Type == FatalEvent {
				// sortof test the stacktrace, best we can do.
				stacktrace := event.Data.([]byte)
				if !bytes.HasPrefix(stacktrace, []byte("goroutine")) {
					t.Errorf("Expected a stacktrace as data for a Fatal event, but got %s ",
						string(stacktrace))
				}
				event.Data = nil
			}

			if expected, got := expectedEvent.Data, event.Data; !reflect.DeepEqual(expected, got) {
				t.Errorf("Expected event #%d to have data %v, but got %v",
					i, expected, got)
			}
		}
	}()
	panic("Fatal message")
}

func TestStartTwice(t *testing.T) {
	defer reset()
	var ew eventWriter
	Start(&ew)
	if err := Close(); err != nil {
		t.Fatal("Unexpected error closing initial log: " + err.Error())
	}

	defer func() {
		recv := recover()
		if recv == nil {
			t.Fatal("Expected a second call to Start to panic, but it didn't")
		}

		const expected = "logger: can only Start once"
		got := interfaceToString(recv)
		if expected != got {
			t.Fatalf("Expected to panic with %q, but paniced with %q", expected, got)
		}
	}()
	Start(&ew)
}

func TestStartNoEventWriter(t *testing.T) {
	defer reset()
	defer func() {
		recv := recover()
		if recv == nil {
			t.Fatal("Expected a call to Start without any EventWriters to panic, but it didn't")
		}

		const expected = "logger: need atleast a single EventWriter to write to"
		got := interfaceToString(recv)
		if expected != got {
			t.Fatalf("Expected to panic with %q, but paniced with %q", expected, got)
		}
	}()
	Start()
}

// EventWriter that always returns a write error with the event message in it.
type errorEventWriter struct {
	closeError error
	errors     []error
}

func (eew *errorEventWriter) Write(event Event) error {
	return errors.New("Write error: " + event.Message)
}

func (eew *errorEventWriter) HandleError(err error) {
	eew.errors = append(eew.errors, err)
}

func (eew *errorEventWriter) Close() error {
	return eew.closeError
}

func TestErrorEventWriter(t *testing.T) {
	closeError := errors.New("Close error")

	defer reset()
	eew := errorEventWriter{
		closeError: closeError,
	}
	Start(&eew)

	tags := Tags{"my", "tags"}
	Info(tags, "Info message1")
	Info(tags, "Info message2")
	Info(tags, "Info message3")
	Info(tags, "Info message4")
	Info(tags, "Info message5")
	Info(tags, "Won't be written to the writer")

	if err := Close(); err == nil {
		t.Fatal("Expected a closing error, but didn't get one")
	} else if err != closeError {
		t.Fatalf("Expceted the closing error to be %q, but got %q",
			closeError.Error(), err.Error())
	}

	// 10 = 5 bad write errors + 4 rewrite error of the first event + 1 bad
	// EventWriter error.
	if expected, got := 10, len(eew.errors); got != expected {
		t.Fatalf("Expected %d errors, but only got %d", expected, got)
	}

	// Expected errors:
	// 0 - write event 1
	// 1 - rewrite event 1
	// 2 - write event 2
	// 3 - rewrite event 1
	// 4 - write event 3
	// 5 - rewrite event 1
	// 6 - write event 4
	// 7 - rewrite event 1
	// 8 - write event 5
	// 9 - EventWriter is bad, more then 5 faulty writes, EventWriter will be dropped

	for i, got := range eew.errors {
		var expected error
		if i == 9 {
			expected = ErrBadEventWriter
		} else {
			d := 1
			switch i {
			case 2:
				d = 2
			case 4:
				d = 3
			case 6:
				d = 4
			case 8:
				d = 5
			}
			expected = fmt.Errorf("Write error: Info message%d", d)
		}

		if got.Error() != expected.Error() {
			t.Errorf("Expected error #%d to be %q, but got %q",
				i, expected.Error(), got.Error())
		}
	}
}

// todo: test with flaky writter, return nil, error, nil, error etc.
// todo: test with both good and bad Writer
// todo: test Thumbstone called from main, create a new sub proces and calling
// it and log to the stdout. Then parse the event and check it.

func testThumstone(tags Tags) {
	Thumbstone(tags, "testThumstone")
}

func reset() {
	eventChannel = make(chan Event, 1)
	eventChannelClosed = make(chan struct{}, 1)
	eventWriters = []EventWriter{}
	started = false
}
<commit_msg>Cleanup log_test<commit_after>// Copyright (C) 2015 Thomas de Zeeuw.
//
// Licensed under the MIT license that can be found in the LICENSE file.

package logger

import (
	"bytes"
	"errors"
	"fmt"
	"reflect"
	"runtime"
	"testing"
	"time"
)

// Time returned in calling now(), setup and test in init.
var t1 = time.Date(2015, 9, 1, 14, 22, 36, 0, time.UTC)

func init() {
	margin := time.Millisecond
	t, t2 := now(), time.Now()
	if !t.Truncate(margin).Equal(t2.Truncate(margin)) {
		panic(fmt.Sprintf("now() doesn't return time.Now()! Expected %s, got %s",
			t2, t))
	}

	now = func() time.Time {
		return t1
	}
}

// EventWriter that collects the events and errors.
type eventWriter struct {
	events []Event
	errors []error
	closed bool
}

func (ew *eventWriter) Write(event Event) error {
	ew.events = append(ew.events, event)
	return nil
}

func (ew *eventWriter) HandleError(err error) {
	ew.errors = append(ew.errors, err)
}

func (ew *eventWriter) Close() error {
	ew.closed = true
	return nil
}

// A data type to be used in calling Log.
type user struct {
	ID   int
	Name string
}

func TestLog(t *testing.T) {
	defer reset()
	var ew eventWriter
	Start(&ew)

	tags := Tags{"my", "tags"}
	eventType := NewEventType("my-event-type")
	data := user{1, "Thomas"}
	event := Event{
		Type:    eventType,
		Tags:    tags,
		Message: "My event",
		Data:    data,
	}

	Debug(tags, "Debug message")
	Debugf(tags, "Debug %s message", "formatted")
	Info(tags, "Info message")
	Infof(tags, "Info %s message", "formatted")
	Warn(tags, "Warn message")
	Warnf(tags, "Warn %s message", "formatted")
	Error(tags, errors.New("Error message"))
	Errorf(tags, "Error %s message", "formatted")

	defer func() {
		recv := recover()
		Fatal(tags, recv)
		testThumstone(tags)
		Log(event)

		if err := Close(); err != nil {
			t.Fatal("Unexpected error closing: " + err.Error())
		}

		if len(ew.errors) != 0 {
			t.Fatalf("Unexpected error(s): %v", ew.errors)
		}

		pc, file, _, _ := runtime.Caller(0)
		fn := runtime.FuncForPC(pc)

		expected := []Event{
			Event{Type: DebugEvent, Tags: tags, Message: "Debug message"},
			Event{Type: DebugEvent, Tags: tags, Message: "Debug formatted message"},
			Event{Type: InfoEvent, Tags: tags, Message: "Info message"},
			Event{Type: InfoEvent, Tags: tags, Message: "Info formatted message"},
			Event{Type: WarnEvent, Tags: tags, Message: "Warn message"},
			Event{Type: WarnEvent, Tags: tags, Message: "Warn formatted message"},
			Event{Type: ErrorEvent, Tags: tags, Message: "Error message"},
			Event{Type: ErrorEvent, Tags: tags, Message: "Error formatted message"},
			Event{Type: FatalEvent, Tags: tags, Message: "Fatal message"},
			Event{Type: ThumbEvent, Tags: tags, Message: "Function testThumstone called by " + fn.Name() + ", from file " + file +
				" on line 87"},
			event,
		}

		if len(ew.events) != len(expected) {
			t.Fatalf("Expected to have %d events, but got %d",
				len(expected), len(ew.events))
		}

		for i, event := range ew.events {
			expectedEvent := expected[i]

			if expected, got := expectedEvent.Type, event.Type; expected != got {
				t.Errorf("Expected event #%d to have type %q, but got %q",
					i, expected, got)
			}

			if expected, got := t1, event.Timestamp; !expected.Equal(got) {
				t.Errorf("Expected event #%d to have timestamp %q, but got %q",
					i, expected, got)
			}

			if expected, got := expectedEvent.Tags, event.Tags; !reflect.DeepEqual(expected, got) {
				t.Errorf("Expected event #%d to have tags %q, but got %q",
					i, expected, got)
			}

			if expected, got := expectedEvent.Message, event.Message; expected != got {
				t.Errorf("Expected event #%d to have message %q, but got %q",
					i, expected, got)
			}

			if expectedEvent.Type == FatalEvent {
				// sortof test the stacktrace, best we can do.
				stacktrace := event.Data.([]byte)
				if !bytes.HasPrefix(stacktrace, []byte("goroutine")) {
					t.Errorf("Expected a stacktrace as data for a Fatal event, but got %s ",
						string(stacktrace))
				}
				event.Data = nil
			}

			if expected, got := expectedEvent.Data, event.Data; !reflect.DeepEqual(expected, got) {
				t.Errorf("Expected event #%d to have data %v, but got %v",
					i, expected, got)
			}
		}
	}()
	panic("Fatal message")
}

func TestStartTwice(t *testing.T) {
	defer reset()
	var ew eventWriter
	Start(&ew)
	if err := Close(); err != nil {
		t.Fatal("Unexpected error closing initial log: " + err.Error())
	}

	defer func() {
		recv := recover()
		if recv == nil {
			t.Fatal("Expected a second call to Start to panic, but it didn't")
		}

		const expected = "logger: can only Start once"
		if got := interfaceToString(recv); expected != got {
			t.Fatalf("Expected to panic with %q, but paniced with %q", expected, got)
		}
	}()
	Start(&ew)
}

func TestStartNoEventWriter(t *testing.T) {
	defer reset()
	defer func() {
		recv := recover()
		if recv == nil {
			t.Fatal("Expected a call to Start without any EventWriters to panic, but it didn't")
		}

		const expected = "logger: need atleast a single EventWriter to write to"
		if got := interfaceToString(recv); expected != got {
			t.Fatalf("Expected to panic with %q, but paniced with %q", expected, got)
		}
	}()
	Start()
}

// EventWriter that always returns a write error with the event message in it.
type errorEventWriter struct {
	closeError error
	errors     []error
}

func (eew *errorEventWriter) Write(event Event) error {
	return errors.New("Write error: " + event.Message)
}

func (eew *errorEventWriter) HandleError(err error) {
	eew.errors = append(eew.errors, err)
}

func (eew *errorEventWriter) Close() error {
	return eew.closeError
}

func TestErrorEventWriter(t *testing.T) {
	closeError := errors.New("Close error")

	defer reset()
	eew := errorEventWriter{
		closeError: closeError,
	}
	Start(&eew)

	tags := Tags{"my", "tags"}
	Info(tags, "Info message1")
	Info(tags, "Info message2")
	Info(tags, "Info message3")
	Info(tags, "Info message4")
	Info(tags, "Info message5")
	Info(tags, "Won't be written to the writer")

	if err := Close(); err == nil {
		t.Fatal("Expected a closing error, but didn't get one")
	} else if err != closeError {
		t.Fatalf("Expceted the closing error to be %q, but got %q",
			closeError.Error(), err.Error())
	}

	// 10 = 5 bad write errors + 4 rewrite error of the first event + 1 bad
	// EventWriter error.
	if expected, got := 10, len(eew.errors); got != expected {
		t.Fatalf("Expected %d errors, but only got %d", expected, got)
	}

	// Expected errors:
	// 0 - write event 1
	// 1 - rewrite event 1
	// 2 - write event 2
	// 3 - rewrite event 1
	// 4 - write event 3
	// 5 - rewrite event 1
	// 6 - write event 4
	// 7 - rewrite event 1
	// 8 - write event 5
	// 9 - EventWriter is bad, more then 5 faulty writes, EventWriter will be dropped

	for i, got := range eew.errors {
		var expected error
		if i == 9 {
			expected = ErrBadEventWriter
		} else {
			d := 1
			switch i {
			case 2:
				d = 2
			case 4:
				d = 3
			case 6:
				d = 4
			case 8:
				d = 5
			}
			expected = fmt.Errorf("Write error: Info message%d", d)
		}

		if got.Error() != expected.Error() {
			t.Errorf("Expected error #%d to be %q, but got %q",
				i, expected.Error(), got.Error())
		}
	}
}

// todo: test with flaky writter, return nil, error, nil, error etc.
// todo: test with both good and bad Writer
// todo: test Thumbstone called from main, create a new sub proces and calling
// it and log to the stdout. Then parse the event and check it.

func testThumstone(tags Tags) {
	Thumbstone(tags, "testThumstone")
}

func reset() {
	eventChannel = make(chan Event, defaultEventChannelSize)
	eventChannelClosed = make(chan struct{}, 1)
	eventWriters = []EventWriter{}
	started = false
}
<|endoftext|>


<commit_before>package fizzbuzz

import (
	"strconv"
)

const (
	FIZZ = "FIZZ"
	BUZZ = "BUZZ"
	FIZZ_NUMBER = 3
)

type FizzBuzz struct {
}

func (self *FizzBuzz) IsFizz(number int) bool {
	return (number % FIZZ_NUMBER == 0)
}

func (self *FizzBuzz) Process(number int) (string, error) {
	if ok :=  self.IsFizz(number); ok {
		return FIZZ, nil
	}

	return strconv.Itoa(number), nil
}

func NewFizzBuzz() *FizzBuzz {
	return &FizzBuzz{}
}
<commit_msg> #1 Added functional for getting BUZZ    * Fixed failing test<commit_after>package fizzbuzz

import (
	"strconv"
)

const (
	FIZZ = "FIZZ"
	BUZZ = "BUZZ"
	FIZZ_NUMBER = 3
	BUZZ_NUMBER = 5
)

type FizzBuzz struct {
}

func (self *FizzBuzz) IsFizz(number int) bool {
	return (number % FIZZ_NUMBER == 0)
}

func (self *FizzBuzz) IsBuzz(number int) bool {
	return (number % BUZZ_NUMBER == 0)
}

func (self *FizzBuzz) Process(number int) (string, error) {
	if ok :=  self.IsFizz(number); ok {
		return FIZZ, nil
	}

	if ok := self.IsBuzz(number); ok {
		return BUZZ, nil
	}

	return strconv.Itoa(number), nil
}

func NewFizzBuzz() *FizzBuzz {
	return &FizzBuzz{}
}
<|endoftext|>


<commit_before>// Obdi - a REST interface and GUI for deploying software
// Copyright (C) 2014  Mark Clarkson
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"regexp"
	"syscall"
	"time"
	//"encoding/json"
	//"strings"
)

func (api *Api) execCmd(job JobIn) {

	// TODO :: Put this logic in login/logout and reference count
	//defer api.Logout( )

	// Need to set the PATH to run the script from the script dir
	os.Setenv("PATH", config.ScriptDir)

	scriptfile := ""

	// Write ScriptSource to disk
	if file, err := ioutil.TempFile(os.TempDir(), "smworker_"); err != nil {
		if err := api.sendStatus(job, JobOut{
			Status:        STATUS_SYSCANCELLED,
			StatusReason:  fmt.Sprintf("TempFile error ('%s')", err.Error()),
			StatusPercent: 0,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: %s", err.Error()))
		}
		return
	} else {
		if _, err := file.Write(job.ScriptSource); err != nil {
			if err := api.sendStatus(job, JobOut{
				Status:        STATUS_SYSCANCELLED,
				StatusReason:  fmt.Sprintf("Write error ('%s')", err.Error()),
				StatusPercent: 0,
				Errors:        0,
			}); err != nil {
				logit(fmt.Sprintf("Error: %s", err.Error()))
			}
			return
		}
		file.Close()
		os.Chmod(file.Name(), 0755)
		scriptfile = file.Name()
	}
	defer os.Remove(scriptfile)

	// Set up command, split on spaces but preserve quoted strings
	head := scriptfile
	r := regexp.MustCompile("'.+'|\".+\"|\\S+")
	parts := r.FindAllString(job.Args, -1)
	cmd := &exec.Cmd{}
	cmd = exec.Command(head, parts...)

	// Apply the sent environment variables, split on spaces
	// but preserve quoted strings
	if len(job.EnvVars) > 0 {
		r = regexp.MustCompile("[^ ]*='[^']+'|[^ ]*=\"[^']+\"|\\S+")
		cmd.Env = r.FindAllString(job.EnvVars, -1)
		// Remove speech marks around the value of quoted strings. Matches, for
		// example, `var="val val"`, and changes to `var=val val`
		for i, j := range cmd.Env {
			r := regexp.MustCompile(`(?s)([^ ]+=)["'](.*)["']`)
			if r.Match([]byte(j)) {
				k := r.ReplaceAll([]byte(j), []byte(`$1$2`))
				cmd.Env[i] = string(k)
			}
		}
	} else {
		cmd.Env = []string{}
	}

	// Add the system scripts directory to Env.SYSSCRIPTDIR
	cmd.Env = append(cmd.Env, "SYSSCRIPTDIR="+config.SysScriptDir)

	cmd.Dir = os.TempDir()

	// Set up buffer for stdout
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		if err := api.sendStatus(job, JobOut{
			Status:        STATUS_SYSCANCELLED,
			StatusReason:  fmt.Sprintf("Pipe error ('%s')", err.Error()),
			StatusPercent: 0,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: %s", err.Error()))
		}
		return
	}
	rdr := bufio.NewReader(stdout)
	stderr, err := cmd.StderrPipe()
	if err != nil {
		if err := api.sendStatus(job, JobOut{
			Status:        STATUS_SYSCANCELLED,
			StatusReason:  fmt.Sprintf("Pipe error ('%s')", err.Error()),
			StatusPercent: 0,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: %s", err.Error()))
		}
		return
	}
	rdr_stderr := bufio.NewReader(stderr)

	/*
	   data := JobOut{}
	   jsondata, err := json.Marshal(data)
	*/

	// Get child processes to run in a process group so they
	// can all be killed as a group.
	cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true}

	// Run command in the background (fork)
	err = cmd.Start()
	if err != nil {
		if err := api.sendStatus(job, JobOut{
			Status:        STATUS_SYSCANCELLED,
			StatusReason:  fmt.Sprintf("Fork error ('%s')", err.Error()),
			StatusPercent: 0,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: %s", err.Error()))
		}
		return
	}

	if err := api.sendStatus(job, JobOut{
		Status:        STATUS_INPROGRESS,
		StatusReason:  "Script started",
		StatusPercent: 0,
		Errors:        0,
	}); err != nil {
		logit(fmt.Sprintf("Error: %s", err.Error()))
	}

	// Save the pid so it can be killed
	api.SetPid(job.JobID, int64(cmd.Process.Pid))

	// Process the output
	serial := int64(1)
	line := ""
	if job.Type != 2 {
		// A user job (the default, should be type=1)
		line, err = rdr.ReadString('\n')
		api.sendOutputLine(job, line, serial)
		for err == nil {
			serial++
			a := ""
			starttime := time.Now()
			// Up to 50 lines can be read in one hit
			for i := 0; i < 50; i++ {
				if time.Duration(time.Since(starttime)) > time.Second {
					break
				}
				line, err = rdr.ReadString('\n')
				a = a + line
			}
			api.sendOutputLine(job, a, serial)
		}
	} else {
		// A system job. Send all output in a single output line
		a := ""
		for err == nil {
			line, err = rdr.ReadString('\n')
			a = a + line
		}
		api.sendOutputLine(job, a, 1)
	}

	serial++

	// Read anything in stderr, but don't send it.
	// It will be sent later if the script has non-zero exit status
	error_output := ""
	err = nil
	for err == nil {
		line, err = rdr_stderr.ReadString('\n')
		error_output = error_output + line
	}

	// Process exit status
	err = cmd.Wait()
	if err != nil {
		api.sendOutputLine(job, error_output, serial)
		status := int64(0)
		if api.UserCancel(job.JobID) == true {
			status = STATUS_USERCANCELLED
		} else {
			status = STATUS_ERROR
		}
		if err := api.sendStatus(job, JobOut{
			Status: status,
			StatusReason: fmt.Sprintf("Script, '%s', exited with error status ('%s')",
				job.ScriptName, err.Error()),
			StatusPercent: 0,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: (Script: '%s') %s", job.ScriptName,
				err.Error()))
		}
		api.RemoveJob(job.JobID)
		return
	}

	status := cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
	if status == 0 {
		if err := api.sendStatus(job, JobOut{
			Status:        STATUS_OK,
			StatusReason:  "Script finished successfully",
			StatusPercent: 100,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: %s", err.Error()))
		}
	} else {
		if err := api.sendStatus(job, JobOut{
			Status:        STATUS_ERROR,
			StatusReason:  "Non-zero exit status. Check the log.",
			StatusPercent: 100,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: %s", err.Error()))
		}
	}

	api.RemoveJob(int64(job.JobID))

	// logout
}

/*
func main() {
    exec_cmd ( os.Args[1:]... )
}
*/
<commit_msg>Use PRE for output (fixed typo)<commit_after>// Obdi - a REST interface and GUI for deploying software
// Copyright (C) 2014  Mark Clarkson
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"regexp"
	"syscall"
	"time"
	//"encoding/json"
	//"strings"
)

func (api *Api) execCmd(job JobIn) {

	// TODO :: Put this logic in login/logout and reference count
	//defer api.Logout( )

	// Need to set the PATH to run the script from the script dir
	os.Setenv("PATH", config.ScriptDir)

	scriptfile := ""

	// Write ScriptSource to disk
	if file, err := ioutil.TempFile(os.TempDir(), "smworker_"); err != nil {
		if err := api.sendStatus(job, JobOut{
			Status:        STATUS_SYSCANCELLED,
			StatusReason:  fmt.Sprintf("TempFile error ('%s')", err.Error()),
			StatusPercent: 0,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: %s", err.Error()))
		}
		return
	} else {
		if _, err := file.Write(job.ScriptSource); err != nil {
			if err := api.sendStatus(job, JobOut{
				Status:        STATUS_SYSCANCELLED,
				StatusReason:  fmt.Sprintf("Write error ('%s')", err.Error()),
				StatusPercent: 0,
				Errors:        0,
			}); err != nil {
				logit(fmt.Sprintf("Error: %s", err.Error()))
			}
			return
		}
		file.Close()
		os.Chmod(file.Name(), 0755)
		scriptfile = file.Name()
	}
	defer os.Remove(scriptfile)

	// Set up command, split on spaces but preserve quoted strings
	head := scriptfile
	r := regexp.MustCompile("'.+'|\".+\"|\\S+")
	parts := r.FindAllString(job.Args, -1)
	cmd := &exec.Cmd{}
	cmd = exec.Command(head, parts...)

	// Apply the sent environment variables, split on spaces
	// but preserve quoted strings
	if len(job.EnvVars) > 0 {
		r = regexp.MustCompile(`[^ ]*='[^']+'|[^ ]*="[^"]+"|\S+`)
		cmd.Env = r.FindAllString(job.EnvVars, -1)
		// Remove speech marks around the value of quoted strings. Matches, for
		// example, `var="val val"`, and changes to `var=val val`
		for i, j := range cmd.Env {
			r := regexp.MustCompile(`(?s)([^ ]+=)["'](.*)["']`)
			if r.Match([]byte(j)) {
				k := r.ReplaceAll([]byte(j), []byte(`$1$2`))
				cmd.Env[i] = string(k)
			}
		}
	} else {
		cmd.Env = []string{}
	}

	// Add the system scripts directory to Env.SYSSCRIPTDIR
	cmd.Env = append(cmd.Env, "SYSSCRIPTDIR="+config.SysScriptDir)

	cmd.Dir = os.TempDir()

	// Set up buffer for stdout
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		if err := api.sendStatus(job, JobOut{
			Status:        STATUS_SYSCANCELLED,
			StatusReason:  fmt.Sprintf("Pipe error ('%s')", err.Error()),
			StatusPercent: 0,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: %s", err.Error()))
		}
		return
	}
	rdr := bufio.NewReader(stdout)
	stderr, err := cmd.StderrPipe()
	if err != nil {
		if err := api.sendStatus(job, JobOut{
			Status:        STATUS_SYSCANCELLED,
			StatusReason:  fmt.Sprintf("Pipe error ('%s')", err.Error()),
			StatusPercent: 0,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: %s", err.Error()))
		}
		return
	}
	rdr_stderr := bufio.NewReader(stderr)

	/*
	   data := JobOut{}
	   jsondata, err := json.Marshal(data)
	*/

	// Get child processes to run in a process group so they
	// can all be killed as a group.
	cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true}

	// Run command in the background (fork)
	err = cmd.Start()
	if err != nil {
		if err := api.sendStatus(job, JobOut{
			Status:        STATUS_SYSCANCELLED,
			StatusReason:  fmt.Sprintf("Fork error ('%s')", err.Error()),
			StatusPercent: 0,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: %s", err.Error()))
		}
		return
	}

	if err := api.sendStatus(job, JobOut{
		Status:        STATUS_INPROGRESS,
		StatusReason:  "Script started",
		StatusPercent: 0,
		Errors:        0,
	}); err != nil {
		logit(fmt.Sprintf("Error: %s", err.Error()))
	}

	// Save the pid so it can be killed
	api.SetPid(job.JobID, int64(cmd.Process.Pid))

	// Process the output
	serial := int64(1)
	line := ""
	if job.Type != 2 {
		// A user job (the default, should be type=1)
		line, err = rdr.ReadString('\n')
		api.sendOutputLine(job, line, serial)
		for err == nil {
			serial++
			a := ""
			starttime := time.Now()
			// Up to 50 lines can be read in one hit
			for i := 0; i < 50; i++ {
				if time.Duration(time.Since(starttime)) > time.Second {
					break
				}
				line, err = rdr.ReadString('\n')
				a = a + line
			}
			api.sendOutputLine(job, a, serial)
		}
	} else {
		// A system job. Send all output in a single output line
		a := ""
		for err == nil {
			line, err = rdr.ReadString('\n')
			a = a + line
		}
		api.sendOutputLine(job, a, 1)
	}

	serial++

	// Read anything in stderr, but don't send it.
	// It will be sent later if the script has non-zero exit status
	error_output := ""
	err = nil
	for err == nil {
		line, err = rdr_stderr.ReadString('\n')
		error_output = error_output + line
	}

	// Process exit status
	err = cmd.Wait()
	if err != nil {
		api.sendOutputLine(job, error_output, serial)
		status := int64(0)
		if api.UserCancel(job.JobID) == true {
			status = STATUS_USERCANCELLED
		} else {
			status = STATUS_ERROR
		}
		if err := api.sendStatus(job, JobOut{
			Status: status,
			StatusReason: fmt.Sprintf("Script, '%s', exited with error status ('%s')",
				job.ScriptName, err.Error()),
			StatusPercent: 0,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: (Script: '%s') %s", job.ScriptName,
				err.Error()))
		}
		api.RemoveJob(job.JobID)
		return
	}

	status := cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
	if status == 0 {
		if err := api.sendStatus(job, JobOut{
			Status:        STATUS_OK,
			StatusReason:  "Script finished successfully",
			StatusPercent: 100,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: %s", err.Error()))
		}
	} else {
		if err := api.sendStatus(job, JobOut{
			Status:        STATUS_ERROR,
			StatusReason:  "Non-zero exit status. Check the log.",
			StatusPercent: 100,
			Errors:        0,
		}); err != nil {
			logit(fmt.Sprintf("Error: %s", err.Error()))
		}
	}

	api.RemoveJob(int64(job.JobID))

	// logout
}

/*
func main() {
    exec_cmd ( os.Args[1:]... )
}
*/
<|endoftext|>