<commit_before>package s3_test

import (
	"context"
	"crypto/rand"
	"encoding/hex"
	"errors"
	"fmt"
	"io"
	"net"
	"os"
	"os/exec"
	"path/filepath"
	"restic"
	"testing"
	"time"

	"restic/backend/s3"
	"restic/backend/test"
	. "restic/test"
)

func mkdir(t testing.TB, dir string) {
	err := os.MkdirAll(dir, 0700)
	if err != nil {
		t.Fatal(err)
	}
}

func runMinio(ctx context.Context, t testing.TB, dir, key, secret string) func() {
	mkdir(t, filepath.Join(dir, "config"))
	mkdir(t, filepath.Join(dir, "root"))

	cmd := exec.CommandContext(ctx, "minio",
		"server",
		"--address", "127.0.0.1:9000",
		"--config-dir", filepath.Join(dir, "config"),
		filepath.Join(dir, "root"))
	cmd.Env = append(os.Environ(),
		"MINIO_ACCESS_KEY="+key,
		"MINIO_SECRET_KEY="+secret,
	)
	cmd.Stderr = os.Stderr

	err := cmd.Start()
	if err != nil {
		t.Fatal(err)
	}

	// wait until the TCP port is reachable
	var success bool
	for i := 0; i < 10; i++ {
		time.Sleep(200 * time.Millisecond)

		c, err := net.Dial("tcp", "localhost:9000")
		if err != nil {
			continue
		}

		success = true
		if err := c.Close(); err != nil {
			t.Fatal(err)
		}
	}

	if !success {
		t.Fatal("unable to connect to minio server")
		return nil
	}

	return func() {
		err = cmd.Process.Kill()
		if err != nil {
			t.Fatal(err)
		}

		// ignore errors, we've killed the process
		_ = cmd.Wait()
	}
}

func newCredentials(t testing.TB) (key, secret string) {
	buf := make([]byte, 10)
	_, err := io.ReadFull(rand.Reader, buf)
	if err != nil {
		t.Fatal(err)
	}
	key = hex.EncodeToString(buf)

	_, err = io.ReadFull(rand.Reader, buf)
	if err != nil {
		t.Fatal(err)
	}
	secret = hex.EncodeToString(buf)

	return key, secret
}

func TestBackendMinio(t *testing.T) {
	// try to find a minio binary
	_, err := exec.LookPath("minio")
	if err != nil {
		t.Skip(err)
		return
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	type Config struct {
		s3.Config

		tempdir       string
		removeTempdir func()
		stopServer    func()
	}

	suite := test.Suite{
		// NewConfig returns a config for a new temporary backend that will be used in tests.
		NewConfig: func() (interface{}, error) {
			cfg := Config{}

			cfg.tempdir, cfg.removeTempdir = TempDir(t)
			key, secret := newCredentials(t)
			cfg.stopServer = runMinio(ctx, t, cfg.tempdir, key, secret)

			cfg.Config = s3.Config{
				Endpoint: "localhost:9000",
				Bucket:   "restictestbucket",
				Prefix:   fmt.Sprintf("test-%d", time.Now().UnixNano()),
				UseHTTP:  true,
				KeyID:    key,
				Secret:   secret,
			}
			return cfg, nil
		},

		// CreateFn is a function that creates a temporary repository for the tests.
		Create: func(config interface{}) (restic.Backend, error) {
			cfg := config.(Config)

			be, err := s3.Open(cfg.Config)
			if err != nil {
				return nil, err
			}

			exists, err := be.Test(restic.Handle{Type: restic.ConfigFile})
			if err != nil {
				return nil, err
			}

			if exists {
				return nil, errors.New("config already exists")
			}

			return be, nil
		},

		// OpenFn is a function that opens a previously created temporary repository.
		Open: func(config interface{}) (restic.Backend, error) {
			cfg := config.(Config)
			return s3.Open(cfg.Config)
		},

		// CleanupFn removes data created during the tests.
		Cleanup: func(config interface{}) error {
			cfg := config.(Config)
			if cfg.stopServer != nil {
				cfg.stopServer()
			}
			if cfg.removeTempdir != nil {
				t.Logf("removeTempdir %v", config)
				cfg.removeTempdir()
			}
			return nil
		},
	}

	suite.RunTests(t)
}

func TestBackendS3(t *testing.T) {
	vars := []string{
		"RESTIC_TEST_S3_KEY",
		"RESTIC_TEST_S3_SECRET",
		"RESTIC_TEST_S3_REPOSITORY",
	}

	for _, v := range vars {
		if os.Getenv(v) == "" {
			t.Skipf("environment variable %v not set", v)
			return
		}
	}

	suite := test.Suite{
		// do not use excessive data
		MinimalData: true,

		// NewConfig returns a config for a new temporary backend that will be used in tests.
		NewConfig: func() (interface{}, error) {
			s3cfg, err := s3.ParseConfig(os.Getenv("RESTIC_TEST_S3_REPOSITORY"))
			if err != nil {
				return nil, err
			}

			cfg := s3cfg.(s3.Config)
			cfg.KeyID = os.Getenv("RESTIC_TEST_S3_KEY")
			cfg.Secret = os.Getenv("RESTIC_TEST_S3_SECRET")
			cfg.Prefix = fmt.Sprintf("test-%d", time.Now().UnixNano())
			return cfg, nil
		},

		// CreateFn is a function that creates a temporary repository for the tests.
		Create: func(config interface{}) (restic.Backend, error) {
			cfg := config.(s3.Config)

			be, err := s3.Open(cfg)
			if err != nil {
				return nil, err
			}

			exists, err := be.Test(restic.Handle{Type: restic.ConfigFile})
			if err != nil {
				return nil, err
			}

			if exists {
				return nil, errors.New("config already exists")
			}

			return be, nil
		},

		// OpenFn is a function that opens a previously created temporary repository.
		Open: func(config interface{}) (restic.Backend, error) {
			cfg := config.(s3.Config)
			return s3.Open(cfg)
		},

		// CleanupFn removes data created during the tests.
		Cleanup: func(config interface{}) error {
			cfg := config.(s3.Config)

			be, err := s3.Open(cfg)
			if err != nil {
				return err
			}

			if err := be.(restic.Deleter).Delete(); err != nil {
				return err
			}

			return nil
		},
	}

	t.Logf("run tests")
	suite.RunTests(t)
}
<commit_msg>s3: Remove log line<commit_after>package s3_test

import (
	"context"
	"crypto/rand"
	"encoding/hex"
	"errors"
	"fmt"
	"io"
	"net"
	"os"
	"os/exec"
	"path/filepath"
	"restic"
	"testing"
	"time"

	"restic/backend/s3"
	"restic/backend/test"
	. "restic/test"
)

func mkdir(t testing.TB, dir string) {
	err := os.MkdirAll(dir, 0700)
	if err != nil {
		t.Fatal(err)
	}
}

func runMinio(ctx context.Context, t testing.TB, dir, key, secret string) func() {
	mkdir(t, filepath.Join(dir, "config"))
	mkdir(t, filepath.Join(dir, "root"))

	cmd := exec.CommandContext(ctx, "minio",
		"server",
		"--address", "127.0.0.1:9000",
		"--config-dir", filepath.Join(dir, "config"),
		filepath.Join(dir, "root"))
	cmd.Env = append(os.Environ(),
		"MINIO_ACCESS_KEY="+key,
		"MINIO_SECRET_KEY="+secret,
	)
	cmd.Stderr = os.Stderr

	err := cmd.Start()
	if err != nil {
		t.Fatal(err)
	}

	// wait until the TCP port is reachable
	var success bool
	for i := 0; i < 10; i++ {
		time.Sleep(200 * time.Millisecond)

		c, err := net.Dial("tcp", "localhost:9000")
		if err != nil {
			continue
		}

		success = true
		if err := c.Close(); err != nil {
			t.Fatal(err)
		}
	}

	if !success {
		t.Fatal("unable to connect to minio server")
		return nil
	}

	return func() {
		err = cmd.Process.Kill()
		if err != nil {
			t.Fatal(err)
		}

		// ignore errors, we've killed the process
		_ = cmd.Wait()
	}
}

func newCredentials(t testing.TB) (key, secret string) {
	buf := make([]byte, 10)
	_, err := io.ReadFull(rand.Reader, buf)
	if err != nil {
		t.Fatal(err)
	}
	key = hex.EncodeToString(buf)

	_, err = io.ReadFull(rand.Reader, buf)
	if err != nil {
		t.Fatal(err)
	}
	secret = hex.EncodeToString(buf)

	return key, secret
}

func TestBackendMinio(t *testing.T) {
	// try to find a minio binary
	_, err := exec.LookPath("minio")
	if err != nil {
		t.Skip(err)
		return
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	type Config struct {
		s3.Config

		tempdir       string
		removeTempdir func()
		stopServer    func()
	}

	suite := test.Suite{
		// NewConfig returns a config for a new temporary backend that will be used in tests.
		NewConfig: func() (interface{}, error) {
			cfg := Config{}

			cfg.tempdir, cfg.removeTempdir = TempDir(t)
			key, secret := newCredentials(t)
			cfg.stopServer = runMinio(ctx, t, cfg.tempdir, key, secret)

			cfg.Config = s3.Config{
				Endpoint: "localhost:9000",
				Bucket:   "restictestbucket",
				Prefix:   fmt.Sprintf("test-%d", time.Now().UnixNano()),
				UseHTTP:  true,
				KeyID:    key,
				Secret:   secret,
			}
			return cfg, nil
		},

		// CreateFn is a function that creates a temporary repository for the tests.
		Create: func(config interface{}) (restic.Backend, error) {
			cfg := config.(Config)

			be, err := s3.Open(cfg.Config)
			if err != nil {
				return nil, err
			}

			exists, err := be.Test(restic.Handle{Type: restic.ConfigFile})
			if err != nil {
				return nil, err
			}

			if exists {
				return nil, errors.New("config already exists")
			}

			return be, nil
		},

		// OpenFn is a function that opens a previously created temporary repository.
		Open: func(config interface{}) (restic.Backend, error) {
			cfg := config.(Config)
			return s3.Open(cfg.Config)
		},

		// CleanupFn removes data created during the tests.
		Cleanup: func(config interface{}) error {
			cfg := config.(Config)
			if cfg.stopServer != nil {
				cfg.stopServer()
			}
			if cfg.removeTempdir != nil {
				cfg.removeTempdir()
			}
			return nil
		},
	}

	suite.RunTests(t)
}

func TestBackendS3(t *testing.T) {
	vars := []string{
		"RESTIC_TEST_S3_KEY",
		"RESTIC_TEST_S3_SECRET",
		"RESTIC_TEST_S3_REPOSITORY",
	}

	for _, v := range vars {
		if os.Getenv(v) == "" {
			t.Skipf("environment variable %v not set", v)
			return
		}
	}

	suite := test.Suite{
		// do not use excessive data
		MinimalData: true,

		// NewConfig returns a config for a new temporary backend that will be used in tests.
		NewConfig: func() (interface{}, error) {
			s3cfg, err := s3.ParseConfig(os.Getenv("RESTIC_TEST_S3_REPOSITORY"))
			if err != nil {
				return nil, err
			}

			cfg := s3cfg.(s3.Config)
			cfg.KeyID = os.Getenv("RESTIC_TEST_S3_KEY")
			cfg.Secret = os.Getenv("RESTIC_TEST_S3_SECRET")
			cfg.Prefix = fmt.Sprintf("test-%d", time.Now().UnixNano())
			return cfg, nil
		},

		// CreateFn is a function that creates a temporary repository for the tests.
		Create: func(config interface{}) (restic.Backend, error) {
			cfg := config.(s3.Config)

			be, err := s3.Open(cfg)
			if err != nil {
				return nil, err
			}

			exists, err := be.Test(restic.Handle{Type: restic.ConfigFile})
			if err != nil {
				return nil, err
			}

			if exists {
				return nil, errors.New("config already exists")
			}

			return be, nil
		},

		// OpenFn is a function that opens a previously created temporary repository.
		Open: func(config interface{}) (restic.Backend, error) {
			cfg := config.(s3.Config)
			return s3.Open(cfg)
		},

		// CleanupFn removes data created during the tests.
		Cleanup: func(config interface{}) error {
			cfg := config.(s3.Config)

			be, err := s3.Open(cfg)
			if err != nil {
				return err
			}

			if err := be.(restic.Deleter).Delete(); err != nil {
				return err
			}

			return nil
		},
	}

	t.Logf("run tests")
	suite.RunTests(t)
}
<|endoftext|>


<commit_before>// Package orderedlist is a basic wrapper around container/list.
package orderedlist

import (
	"container/list"
	"fmt"
)

type Comparable interface {
	Compare(c Comparable) int
}

// OrderedList is an ordered linked list.
type OrderedList struct {
	linkedlist *list.List
}

// New returns an initialized OrderedList.
func New() *OrderedList {
	return &OrderedList{
		linkedlist: list.New(),
	}
}

// Insert inserts a key string into the ordered list.
func (l *OrderedList) Insert(c Comparable) {
	// Empty list or greatest key
	if l.linkedlist.Len() == 0 || l.linkedlist.Back().Value.(Comparable).Compare(c) < 0 {
		l.linkedlist.PushBack(c)
		return
	}

	// Insert in O(n) time
	for e := l.linkedlist.Front(); e != nil; e = e.Next() {
		if e.Value.(Comparable).Compare(c) > 0 {
			l.linkedlist.InsertBefore(c, e)
			return
		}
	}
}

// Remove removes a key from the ordered list.
func (l *OrderedList) Remove(c Comparable) {
	for e := l.linkedlist.Front(); e != nil; e = e.Next() {
		if e.Value.(Comparable).Compare(c) == 0 {
			l.linkedlist.Remove(e)
			return
		}
	}
}

// firstGreaterThanOrEqual returns the first Element
// greater-than or equal-to the given key.
func (l *OrderedList) firstGreaterThanOrEqual(c Comparable) *list.Element {
	elem := l.linkedlist.Front()
	for e := elem; e != nil; e = e.Next() {
		if e.Value.(Comparable).Compare(c) >= 0 {
			return e
		}
	}

	return elem
}

func (l *OrderedList) GetRange(start Comparable, end Comparable) (keys []Comparable) {
	keys = make([]Comparable, 0)
	startElem := l.firstGreaterThanOrEqual(start)
	for e := startElem; e != nil; e = e.Next() {
		if e.Value.(Comparable).Compare(end) < 0 {
			keys = append(keys, e.Value.(Comparable))
		}
	}
	return
}

// Print prints the values stored in the list.
func (l *OrderedList) Print() {
	for e := l.linkedlist.Front(); e != nil; e = e.Next() {
		fmt.Println(e.Value)
	}
}
<commit_msg>Add description for GetRange<commit_after>// Package orderedlist is a basic wrapper around container/list.
package orderedlist

import (
	"container/list"
	"fmt"
)

type Comparable interface {
	Compare(c Comparable) int
}

// OrderedList is an ordered linked list.
type OrderedList struct {
	linkedlist *list.List
}

// New returns an initialized OrderedList.
func New() *OrderedList {
	return &OrderedList{
		linkedlist: list.New(),
	}
}

// Insert inserts a key string into the ordered list.
func (l *OrderedList) Insert(c Comparable) {
	// Empty list or greatest key
	if l.linkedlist.Len() == 0 || l.linkedlist.Back().Value.(Comparable).Compare(c) < 0 {
		l.linkedlist.PushBack(c)
		return
	}

	// Insert in O(n) time
	for e := l.linkedlist.Front(); e != nil; e = e.Next() {
		if e.Value.(Comparable).Compare(c) > 0 {
			l.linkedlist.InsertBefore(c, e)
			return
		}
	}
}

// Remove removes a key from the ordered list.
func (l *OrderedList) Remove(c Comparable) {
	for e := l.linkedlist.Front(); e != nil; e = e.Next() {
		if e.Value.(Comparable).Compare(c) == 0 {
			l.linkedlist.Remove(e)
			return
		}
	}
}

// firstGreaterThanOrEqual returns the first Element
// greater-than or equal-to the given key.
func (l *OrderedList) firstGreaterThanOrEqual(c Comparable) *list.Element {
	elem := l.linkedlist.Front()
	for e := elem; e != nil; e = e.Next() {
		if e.Value.(Comparable).Compare(c) >= 0 {
			return e
		}
	}

	return elem
}

// GetRange returns a slice of Comparables in the range [start, end).
func (l *OrderedList) GetRange(start Comparable, end Comparable) (keys []Comparable) {
	keys = make([]Comparable, 0)
	startElem := l.firstGreaterThanOrEqual(start)
	for e := startElem; e != nil; e = e.Next() {
		if e.Value.(Comparable).Compare(end) < 0 {
			keys = append(keys, e.Value.(Comparable))
		}
	}
	return
}

// Print prints the values stored in the list.
func (l *OrderedList) Print() {
	for e := l.linkedlist.Front(); e != nil; e = e.Next() {
		fmt.Println(e.Value)
	}
}
<|endoftext|>


<commit_before>package adtelligent

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

	"github.com/mxmCherry/openrtb"
	"github.com/prebid/prebid-server/adapters"
	"github.com/prebid/prebid-server/openrtb_ext"
)

const uri = "http://hb.adtelligent.com/auction"

type AdtelligentAdapter struct {
}

type adtelligentImpExt struct {
	Adtelligent openrtb_ext.ExtImpAdtelligent `json:"adtelligent"`
}

func (a *AdtelligentAdapter) MakeRequests(request *openrtb.BidRequest) ([]*adapters.RequestData, []error) {

	totalImps := len(request.Imp)
	errors := make([]error, 0, totalImps)
	imp2source := make(map[int][]int)

	for i := 0; i < totalImps; i++ {

		sourceId, err := validateImpression(&request.Imp[i])

		if err != nil {
			errors = append(errors, err)
			continue
		}

		if _, ok := imp2source[sourceId]; !ok {
			imp2source[sourceId] = make([]int, 0, totalImps-i)
		}

		imp2source[sourceId] = append(imp2source[sourceId], i)

	}

	totalReqs := len(imp2source)
	if 0 == totalReqs {
		return nil, errors
	}

	headers := http.Header{}
	headers.Add("Content-Type", "application/json;charset=utf-8")
	headers.Add("Accept", "application/json")

	reqs := make([]*adapters.RequestData, 0, totalReqs)

	imps := request.Imp
	request.Imp = make([]openrtb.Imp, 0, len(imps))

	for sourceId, impIds := range imp2source {
		request.Imp = request.Imp[:0]

		for i := 0; i < len(impIds); i++ {
			request.Imp = append(request.Imp, imps[impIds[i]])
		}

		body, err := json.Marshal(request)
		if err != nil {
			errors = append(errors, fmt.Errorf("error while encoding bidRequest, err: %s", err))
			return nil, errors
		}

		reqs = append(reqs, &adapters.RequestData{
			Method:  "POST",
			Uri:     uri + fmt.Sprintf("?aid=%d", sourceId),
			Body:    body,
			Headers: headers,
		})
	}

	if 0 == len(reqs) {
		return nil, errors
	}

	return reqs, errors

}

func (a *AdtelligentAdapter) MakeBids(bidReq *openrtb.BidRequest, unused *adapters.RequestData, httpRes *adapters.ResponseData) ([]*adapters.TypedBid, []error) {

	if httpRes.StatusCode == http.StatusNoContent {
		return nil, nil
	}

	var bidResp openrtb.BidResponse
	if err := json.Unmarshal(httpRes.Body, &bidResp); err != nil {
		return nil, []error{fmt.Errorf("error while decoding response, err: %s", err)}
	}

	var bids []*adapters.TypedBid
	var errors []error

	var impOK bool
	for _, sb := range bidResp.SeatBid {
		for _, bid := range sb.Bid {

			impOK = false
			mediaType := openrtb_ext.BidTypeBanner
			for _, imp := range bidReq.Imp {
				if imp.ID == bid.ImpID {

					impOK = true

					if imp.Video != nil {
						mediaType = openrtb_ext.BidTypeVideo
						break

					}
				}
			}

			if !impOK {
				errors = append(errors, fmt.Errorf("ignoring bid id=%s, request doesn't contain any impression with id=%s", bid.ID, bid.ImpID))
				continue
			}

			bids = append(bids, &adapters.TypedBid{
				Bid:     &bid,
				BidType: mediaType,
			})
		}
	}

	return bids, errors
}

func validateImpression(imp *openrtb.Imp) (int, error) {

	if imp.Banner == nil && imp.Video == nil {
		return 0, fmt.Errorf("ignoring imp id=%s, Adtelligent supports only Video and Banner", imp.ID)
	}

	if 0 == len(imp.Ext) {
		return 0, fmt.Errorf("ignoring imp id=%s, extImpBidder is empty", imp.ID)
	}

	var bidderExt adapters.ExtImpBidder

	if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
		return 0, fmt.Errorf("ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err)
	}

	impExt := openrtb_ext.ExtImpAdtelligent{}
	err := json.Unmarshal(bidderExt.Bidder, &impExt)
	if err != nil {
		return 0, fmt.Errorf("ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err)
	}

	// common extension for all impressions
	var impExtBuffer []byte

	impExtBuffer, err = json.Marshal(&adtelligentImpExt{
		Adtelligent: impExt,
	})

	if impExt.BidFloor > 0 {
		imp.BidFloor = impExt.BidFloor
	}

	imp.Ext = impExtBuffer

	return impExt.SourceId, nil
}

func NewAdtelligentBidder(client *http.Client) *AdtelligentAdapter {
	return &AdtelligentAdapter{}
}
<commit_msg>BUG: loop by the array of bids and a reference to the same object (#413)<commit_after>package adtelligent

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

	"github.com/mxmCherry/openrtb"
	"github.com/prebid/prebid-server/adapters"
	"github.com/prebid/prebid-server/openrtb_ext"
)

const uri = "http://hb.adtelligent.com/auction"

type AdtelligentAdapter struct {
}

type adtelligentImpExt struct {
	Adtelligent openrtb_ext.ExtImpAdtelligent `json:"adtelligent"`
}

func (a *AdtelligentAdapter) MakeRequests(request *openrtb.BidRequest) ([]*adapters.RequestData, []error) {

	totalImps := len(request.Imp)
	errors := make([]error, 0, totalImps)
	imp2source := make(map[int][]int)

	for i := 0; i < totalImps; i++ {

		sourceId, err := validateImpression(&request.Imp[i])

		if err != nil {
			errors = append(errors, err)
			continue
		}

		if _, ok := imp2source[sourceId]; !ok {
			imp2source[sourceId] = make([]int, 0, totalImps-i)
		}

		imp2source[sourceId] = append(imp2source[sourceId], i)

	}

	totalReqs := len(imp2source)
	if 0 == totalReqs {
		return nil, errors
	}

	headers := http.Header{}
	headers.Add("Content-Type", "application/json;charset=utf-8")
	headers.Add("Accept", "application/json")

	reqs := make([]*adapters.RequestData, 0, totalReqs)

	imps := request.Imp
	request.Imp = make([]openrtb.Imp, 0, len(imps))

	for sourceId, impIds := range imp2source {
		request.Imp = request.Imp[:0]

		for i := 0; i < len(impIds); i++ {
			request.Imp = append(request.Imp, imps[impIds[i]])
		}

		body, err := json.Marshal(request)
		if err != nil {
			errors = append(errors, fmt.Errorf("error while encoding bidRequest, err: %s", err))
			return nil, errors
		}

		reqs = append(reqs, &adapters.RequestData{
			Method:  "POST",
			Uri:     uri + fmt.Sprintf("?aid=%d", sourceId),
			Body:    body,
			Headers: headers,
		})
	}

	if 0 == len(reqs) {
		return nil, errors
	}

	return reqs, errors

}

func (a *AdtelligentAdapter) MakeBids(bidReq *openrtb.BidRequest, unused *adapters.RequestData, httpRes *adapters.ResponseData) ([]*adapters.TypedBid, []error) {

	if httpRes.StatusCode == http.StatusNoContent {
		return nil, nil
	}

	var bidResp openrtb.BidResponse
	if err := json.Unmarshal(httpRes.Body, &bidResp); err != nil {
		return nil, []error{fmt.Errorf("error while decoding response, err: %s", err)}
	}

	var bids []*adapters.TypedBid
	var errors []error

	var impOK bool
	for _, sb := range bidResp.SeatBid {
		for i := 0; i < len(sb.Bid); i++ {

			bid := sb.Bid[i]

			impOK = false
			mediaType := openrtb_ext.BidTypeBanner
			for _, imp := range bidReq.Imp {
				if imp.ID == bid.ImpID {

					impOK = true

					if imp.Video != nil {
						mediaType = openrtb_ext.BidTypeVideo
						break

					}
				}
			}

			if !impOK {
				errors = append(errors, fmt.Errorf("ignoring bid id=%s, request doesn't contain any impression with id=%s", bid.ID, bid.ImpID))
				continue
			}

			bids = append(bids, &adapters.TypedBid{
				Bid:     &bid,
				BidType: mediaType,
			})
		}
	}

	return bids, errors
}

func validateImpression(imp *openrtb.Imp) (int, error) {

	if imp.Banner == nil && imp.Video == nil {
		return 0, fmt.Errorf("ignoring imp id=%s, Adtelligent supports only Video and Banner", imp.ID)
	}

	if 0 == len(imp.Ext) {
		return 0, fmt.Errorf("ignoring imp id=%s, extImpBidder is empty", imp.ID)
	}

	var bidderExt adapters.ExtImpBidder

	if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
		return 0, fmt.Errorf("ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err)
	}

	impExt := openrtb_ext.ExtImpAdtelligent{}
	err := json.Unmarshal(bidderExt.Bidder, &impExt)
	if err != nil {
		return 0, fmt.Errorf("ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err)
	}

	// common extension for all impressions
	var impExtBuffer []byte

	impExtBuffer, err = json.Marshal(&adtelligentImpExt{
		Adtelligent: impExt,
	})

	if impExt.BidFloor > 0 {
		imp.BidFloor = impExt.BidFloor
	}

	imp.Ext = impExtBuffer

	return impExt.SourceId, nil
}

func NewAdtelligentBidder(client *http.Client) *AdtelligentAdapter {
	return &AdtelligentAdapter{}
}
<|endoftext|>


<commit_before>// +build !js

package dfhack

import (
	"net"
	"os"
	"strconv"
)

func Connect() (*Conn, error) {
	port, err := strconv.Atoi(os.Getenv("DFHACK_PORT"))
	if err != nil {
		port = 5000
	}

	return Dial(net.JoinHostPort("localhost", strconv.Itoa(port)))
}

func Dial(addr string) (*Conn, error) {
	sock, err := net.Dial("tcp", addr)
	if err != nil {
		return nil, err
	}

	return (&Conn{sock: sock}).init()
}
<commit_msg>use IPv4 loopback even on systems with IPv6 as the default<commit_after>// +build !js

package dfhack

import (
	"net"
	"os"
	"strconv"
)

func Connect() (*Conn, error) {
	port, err := strconv.Atoi(os.Getenv("DFHACK_PORT"))
	if err != nil {
		port = 5000
	}

	return Dial(net.JoinHostPort("127.0.0.1", strconv.Itoa(port)))
}

func Dial(addr string) (*Conn, error) {
	sock, err := net.Dial("tcp", addr)
	if err != nil {
		return nil, err
	}

	return (&Conn{sock: sock}).init()
}
<|endoftext|>


<commit_before>/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

// +build darwin dragonfly freebsd linux netbsd openbsd

package osutil

import (
	"os"
)

func addWritable(file *os.File) error {
	return handleWritable(func(v os.FileMode) uint32 { return v | 0222 })
}

func removeWritable(file *os.File) error {
	return handleWritable(func(v os.FileMode) uint32 { return v ^ 0222 })
}

func handleWritable(file *os.File, fn func(perm os.FileMode) uint32) error {
	if info, err := os.Lstat(file.Name()); err != nil {
		return err
	} else {
		return file.Chmod(fn(info.Mode()))
	}
}
<commit_msg>fix build error.<commit_after>// +build darwin dragonfly freebsd linux netbsd openbsd

/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 osutil

import (
	"os"
)

func addWritable(file *os.File) error {
	return handleWritable(file, func(v os.FileMode) os.FileMode { return v | 0222 })
}

func removeWritable(file *os.File) error {
	return handleWritable(file, func(v os.FileMode) os.FileMode { return v ^ 0222 })
}

func handleWritable(file *os.File, fn func(perm os.FileMode) os.FileMode) error {
	if info, err := os.Lstat(file.Name()); err != nil {
		return err
	} else {
		return file.Chmod(fn(info.Mode()))
	}
}
<|endoftext|>


<commit_before>// 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.

// The srv package provides definitions and functions used to implement
// a 9P2000 file client.
package clnt

import (
	"fmt"
	"log"
	"net"
	"sync"
	"syscall"
	"go9p.googlecode.com/hg/p"
)

// Debug flags
const (
	DbgPrintFcalls  = (1 << iota) // print all 9P messages on stderr
	DbgPrintPackets               // print the raw packets on stderr
	DbgLogFcalls                  // keep the last N 9P messages (can be accessed over http)
	DbgLogPackets                 // keep the last N 9P messages (can be accessed over http)
)

// The Clnt type represents a 9P2000 client. The client is connected to
// a 9P2000 file server and its methods can be used to access and manipulate
// the files exported by the server.
type Clnt struct {
	sync.Mutex
	Finished   bool   // client is no longer connected to server
	Debuglevel int    // =0 don't print anything, >0 print Fcalls, >1 print raw packets
	Msize      uint32 // Maximum size of the 9P messages
	Dotu       bool   // If true, 9P2000.u protocol is spoken
	Root       *Fid   // Fid that points to the rood directory
	Id         string // Used when printing debug messages
	Log        *p.Logger

	conn     net.Conn
	tagpool  *pool
	fidpool  *pool
	reqout   chan *Req
	done     chan bool
	reqfirst *Req
	reqlast  *Req
	err      *p.Error

	reqchan chan *Req
	tchan   chan *p.Fcall

	next, prev *Clnt
}

// A Fid type represents a file on the server. Fids are used for the
// low level methods that correspond directly to the 9P2000 message requests
type Fid struct {
	sync.Mutex
	Clnt   *Clnt // Client the fid belongs to
	Iounit uint32
	p.Qid         // The Qid description for the file
	Mode   uint8  // Open mode (one of p.O* values) (if file is open)
	Fid    uint32 // Fid number
	p.User        // The user the fid belongs to
	walked bool   // true if the fid points to a walked file on the server
}

// The file is similar to the Fid, but is used in the high-level client
// interface.
type File struct {
	fid    *Fid
	offset uint64
}

type pool struct {
	sync.Mutex
	need  int
	nchan chan uint32
	maxid uint32
	imap  []byte
}

type Req struct {
	sync.Mutex
	Clnt       *Clnt
	Tc         *p.Fcall
	Rc         *p.Fcall
	Err        *p.Error
	Done       chan *Req
	tag        uint16
	prev, next *Req
}

var DefaultDebuglevel int
var DefaultLogger *p.Logger

var clntLock sync.Mutex
var clntList, clntLast *Clnt

func (clnt *Clnt) Rpcnb(r *Req) *p.Error {
	var tag uint16

	if clnt.Finished {
		return &p.Error{"Client no longer connected", 0}
	}
	if r.Tc.Type == p.Tversion {
		tag = p.NOTAG
	} else {
		tag = r.tag
	}

	p.SetTag(r.Tc, tag)
	clnt.Lock()
	if clnt.err != nil {
		clnt.Unlock()
		return clnt.err
	}

	if clnt.reqlast != nil {
		clnt.reqlast.next = r
	} else {
		clnt.reqfirst = r
	}

	r.prev = clnt.reqlast
	clnt.reqlast = r
	clnt.Unlock()

	clnt.reqout <- r
	return nil
}

func (clnt *Clnt) Rpc(tc *p.Fcall) (rc *p.Fcall, err *p.Error) {
	r := clnt.ReqAlloc()
	r.Tc = tc
	r.Done = make(chan *Req)
	err = clnt.Rpcnb(r)
	if err != nil {
		return
	}

	<-r.Done
	rc = r.Rc
	err = r.Err
	clnt.ReqFree(r)
	return
}

func (clnt *Clnt) recv() {
	var err *p.Error

	err = nil
	buf := make([]byte, clnt.Msize*8)
	pos := 0
	for {
		if len(buf) < int(clnt.Msize) {
		resize:
			b := make([]byte, clnt.Msize*8)
			copy(b, buf[0:pos])
			buf = b
			b = nil
		}

		n, oerr := clnt.conn.Read(buf[pos:len(buf)])
		if oerr != nil || n == 0 {
			err = &p.Error{oerr.String(), syscall.EIO}
			goto closed
		}

		pos += n
		for pos > 4 {
			sz, _ := p.Gint32(buf)
			if pos < int(sz) {
				if len(buf) < int(sz) {
					goto resize
				}

				break
			}

			fc, err, fcsize := p.Unpack(buf, clnt.Dotu)
			clnt.Lock()
			if err != nil {
				clnt.err = err
				clnt.conn.Close()
				clnt.Unlock()
				goto closed
			}

			if clnt.Debuglevel > 0 {
				clnt.logFcall(fc)
				if clnt.Debuglevel&DbgPrintPackets != 0 {
					log.Println("}-}", clnt.Id, fmt.Sprint(fc.Pkt))
				}

				if clnt.Debuglevel&DbgPrintFcalls != 0 {
					log.Println("}}}", clnt.Id, fc.String())
				}
			}

			var r *Req = nil
			for r = clnt.reqfirst; r != nil; r = r.next {
				if r.Tc.Tag == fc.Tag {
					break
				}
			}

			if r == nil {
				clnt.err = &p.Error{"unexpected response", syscall.EINVAL}
				clnt.conn.Close()
				clnt.Unlock()
				goto closed
			}

			r.Rc = fc
			if r.prev != nil {
				r.prev.next = r.next
			} else {
				clnt.reqfirst = r.next
			}

			if r.next != nil {
				r.next.prev = r.prev
			} else {
				clnt.reqlast = r.prev
			}
			clnt.Unlock()

			if r.Tc.Type != r.Rc.Type-1 {
				if r.Rc.Type != p.Rerror {
					r.Err = &p.Error{"invalid response", syscall.EINVAL}
					log.Println(fmt.Sprintf("TTT %v", r.Tc))
					log.Println(fmt.Sprintf("RRR %v", r.Rc))
				} else {
					if r.Err != nil {
						r.Err = &p.Error{r.Rc.Error, int(r.Rc.Errornum)}
					}
				}
			}

			if r.Done != nil {
				r.Done <- r
			}

			pos -= fcsize
			buf = buf[fcsize:]
		}
	}

closed:
	clnt.done <- true

	/* send error to all pending requests */
	clnt.Lock()
	r := clnt.reqfirst
	clnt.reqfirst = nil
	clnt.reqlast = nil
	if err == nil {
		err = clnt.err
	}
	clnt.Unlock()
	for ; r != nil; r = r.next {
		r.Err = err
		if r.Done != nil {
			r.Done <- r
		}
	}

	clntLock.Lock()
	if clnt.prev != nil {
		clnt.prev.next = clnt.next
	} else {
		clntList = clnt.next
	}

	if clnt.next != nil {
		clnt.next.prev = clnt.prev
	} else {
		clntLast = clnt.prev
	}
	clntLock.Unlock()
}

func (clnt *Clnt) send() {
	for {
		select {
		case <-clnt.done:
			clnt.Finished = true
			return

		case req := <-clnt.reqout:
			if clnt.Debuglevel > 0 {
				clnt.logFcall(req.Tc)
				if clnt.Debuglevel&DbgPrintPackets != 0 {
					log.Println("{-{", clnt.Id, fmt.Sprint(req.Tc.Pkt))
				}

				if clnt.Debuglevel&DbgPrintFcalls != 0 {
					log.Println("{{{", clnt.Id, req.Tc.String())
				}
			}

			for buf := req.Tc.Pkt; len(buf) > 0; {
				n, err := clnt.conn.Write(buf)
				if err != nil {
					/* just close the socket, will get signal on clnt.done */
					clnt.conn.Close()
					break
				}

				buf = buf[n:len(buf)]
			}
		}
	}
}

// Creates and initializes a new Clnt object. Doesn't send any data
// on the wire.
func NewClnt(c net.Conn, msize uint32, dotu bool) *Clnt {
	clnt := new(Clnt)
	clnt.conn = c
	clnt.Msize = msize
	clnt.Dotu = dotu
	clnt.Debuglevel = DefaultDebuglevel
	clnt.Log = DefaultLogger
	clnt.tagpool = newPool(uint32(p.NOTAG))
	clnt.fidpool = newPool(p.NOFID)
	clnt.reqout = make(chan *Req)
	clnt.done = make(chan bool)
	clnt.reqchan = make(chan *Req, 16)
	clnt.tchan = make(chan *p.Fcall, 16)

	go clnt.recv()
	go clnt.send()

	clntLock.Lock()
	if clntLast != nil {
		clntLast.next = clnt
	} else {
		clntList = clnt
	}

	clnt.prev = clntLast
	clntLast = clnt
	clntLock.Unlock()

	return clnt
}

// Establishes a new socket connection to the 9P server and creates
// a client object for it. Negotiates the dialect and msize for the
// connection. Returns a Clnt object, or Error.
func Connect(ntype, addr string, msize uint32, dotu bool) (*Clnt, *p.Error) {
	c, e := net.Dial(ntype, "", addr)
	if e != nil {
		return nil, &p.Error{e.String(), syscall.EIO}
	}

	clnt := NewClnt(c, msize, dotu)
	clnt.Id = addr + ":"
	ver := "9P2000"
	if clnt.Dotu {
		ver = "9P2000.u"
	}

	tc := p.NewFcall(clnt.Msize)
	err := p.PackTversion(tc, clnt.Msize, ver)
	if err != nil {
		return nil, err
	}

	rc, err := clnt.Rpc(tc)
	if err != nil {
		return nil, err
	}

	if rc.Msize < clnt.Msize {
		clnt.Msize = rc.Msize
	}

	clnt.Dotu = rc.Version == "9P2000.u" && clnt.Dotu
	return clnt, nil
}

// Creates a new Fid object for the client
func (clnt *Clnt) FidAlloc() *Fid {
	fid := new(Fid)
	fid.Fid = clnt.fidpool.getId()
	fid.Clnt = clnt

	return fid
}

func (clnt *Clnt) NewFcall() *p.Fcall {
	tc, ok := <-clnt.tchan
	if !ok {
		tc = p.NewFcall(clnt.Msize)
	}

	return tc
}

func (clnt *Clnt) ReqAlloc() *Req {
	req, ok := <-clnt.reqchan
	if !ok {
		req = new(Req)
		req.Clnt = clnt
		req.tag = uint16(clnt.tagpool.getId())
	}

	return req
}

func (clnt *Clnt) ReqFree(req *Req) {
	if req.Tc != nil && len(req.Tc.Buf) >= int(clnt.Msize) {
		_ = clnt.tchan <- req.Tc
	}

	req.Tc = nil
	req.Rc = nil
	req.Err = nil
	req.Done = nil
	req.next = nil
	req.prev = nil

	if ok := clnt.reqchan <- req; !ok {
		clnt.tagpool.putId(uint32(req.tag))
	}
}

func (clnt *Clnt) logFcall(fc *p.Fcall) {
	if clnt.Debuglevel&DbgLogPackets != 0 {
		pkt := make([]byte, len(fc.Pkt))
		copy(pkt, fc.Pkt)
		clnt.Log.Log(pkt, clnt, DbgLogPackets)
	}

	if clnt.Debuglevel&DbgLogFcalls != 0 {
		f := new(p.Fcall)
		*f = *fc
		f.Pkt = nil
		clnt.Log.Log(f, clnt, DbgLogFcalls)
	}
}

func init() {
	statsRegister()
}
<commit_msg>Remove Clnt.Finished, it is not needed and causes race conditions.<commit_after>// 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.

// The srv package provides definitions and functions used to implement
// a 9P2000 file client.
package clnt

import (
	"fmt"
	"log"
	"net"
	"sync"
	"syscall"
	"go9p.googlecode.com/hg/p"
)

// Debug flags
const (
	DbgPrintFcalls  = (1 << iota) // print all 9P messages on stderr
	DbgPrintPackets               // print the raw packets on stderr
	DbgLogFcalls                  // keep the last N 9P messages (can be accessed over http)
	DbgLogPackets                 // keep the last N 9P messages (can be accessed over http)
)

// The Clnt type represents a 9P2000 client. The client is connected to
// a 9P2000 file server and its methods can be used to access and manipulate
// the files exported by the server.
type Clnt struct {
	sync.Mutex
	Debuglevel int    // =0 don't print anything, >0 print Fcalls, >1 print raw packets
	Msize      uint32 // Maximum size of the 9P messages
	Dotu       bool   // If true, 9P2000.u protocol is spoken
	Root       *Fid   // Fid that points to the rood directory
	Id         string // Used when printing debug messages
	Log        *p.Logger

	conn     net.Conn
	tagpool  *pool
	fidpool  *pool
	reqout   chan *Req
	done     chan bool
	reqfirst *Req
	reqlast  *Req
	err      *p.Error

	reqchan chan *Req
	tchan   chan *p.Fcall

	next, prev *Clnt
}

// A Fid type represents a file on the server. Fids are used for the
// low level methods that correspond directly to the 9P2000 message requests
type Fid struct {
	sync.Mutex
	Clnt   *Clnt // Client the fid belongs to
	Iounit uint32
	p.Qid         // The Qid description for the file
	Mode   uint8  // Open mode (one of p.O* values) (if file is open)
	Fid    uint32 // Fid number
	p.User        // The user the fid belongs to
	walked bool   // true if the fid points to a walked file on the server
}

// The file is similar to the Fid, but is used in the high-level client
// interface.
type File struct {
	fid    *Fid
	offset uint64
}

type pool struct {
	sync.Mutex
	need  int
	nchan chan uint32
	maxid uint32
	imap  []byte
}

type Req struct {
	sync.Mutex
	Clnt       *Clnt
	Tc         *p.Fcall
	Rc         *p.Fcall
	Err        *p.Error
	Done       chan *Req
	tag        uint16
	prev, next *Req
}

var DefaultDebuglevel int
var DefaultLogger *p.Logger

var clntLock sync.Mutex
var clntList, clntLast *Clnt

func (clnt *Clnt) Rpcnb(r *Req) *p.Error {
	var tag uint16

	if r.Tc.Type == p.Tversion {
		tag = p.NOTAG
	} else {
		tag = r.tag
	}

	p.SetTag(r.Tc, tag)
	clnt.Lock()
	if clnt.err != nil {
		clnt.Unlock()
		return clnt.err
	}

	if clnt.reqlast != nil {
		clnt.reqlast.next = r
	} else {
		clnt.reqfirst = r
	}

	r.prev = clnt.reqlast
	clnt.reqlast = r
	clnt.Unlock()

	clnt.reqout <- r
	return nil
}

func (clnt *Clnt) Rpc(tc *p.Fcall) (rc *p.Fcall, err *p.Error) {
	r := clnt.ReqAlloc()
	r.Tc = tc
	r.Done = make(chan *Req)
	err = clnt.Rpcnb(r)
	if err != nil {
		return
	}

	<-r.Done
	rc = r.Rc
	err = r.Err
	clnt.ReqFree(r)
	return
}

func (clnt *Clnt) recv() {
	var err *p.Error

	err = nil
	buf := make([]byte, clnt.Msize*8)
	pos := 0
	for {
		if len(buf) < int(clnt.Msize) {
		resize:
			b := make([]byte, clnt.Msize*8)
			copy(b, buf[0:pos])
			buf = b
			b = nil
		}

		n, oerr := clnt.conn.Read(buf[pos:len(buf)])
		if oerr != nil || n == 0 {
			err = &p.Error{oerr.String(), syscall.EIO}
			goto closed
		}

		pos += n
		for pos > 4 {
			sz, _ := p.Gint32(buf)
			if pos < int(sz) {
				if len(buf) < int(sz) {
					goto resize
				}

				break
			}

			fc, err, fcsize := p.Unpack(buf, clnt.Dotu)
			clnt.Lock()
			if err != nil {
				clnt.err = err
				clnt.conn.Close()
				clnt.Unlock()
				goto closed
			}

			if clnt.Debuglevel > 0 {
				clnt.logFcall(fc)
				if clnt.Debuglevel&DbgPrintPackets != 0 {
					log.Println("}-}", clnt.Id, fmt.Sprint(fc.Pkt))
				}

				if clnt.Debuglevel&DbgPrintFcalls != 0 {
					log.Println("}}}", clnt.Id, fc.String())
				}
			}

			var r *Req = nil
			for r = clnt.reqfirst; r != nil; r = r.next {
				if r.Tc.Tag == fc.Tag {
					break
				}
			}

			if r == nil {
				clnt.err = &p.Error{"unexpected response", syscall.EINVAL}
				clnt.conn.Close()
				clnt.Unlock()
				goto closed
			}

			r.Rc = fc
			if r.prev != nil {
				r.prev.next = r.next
			} else {
				clnt.reqfirst = r.next
			}

			if r.next != nil {
				r.next.prev = r.prev
			} else {
				clnt.reqlast = r.prev
			}
			clnt.Unlock()

			if r.Tc.Type != r.Rc.Type-1 {
				if r.Rc.Type != p.Rerror {
					r.Err = &p.Error{"invalid response", syscall.EINVAL}
					log.Println(fmt.Sprintf("TTT %v", r.Tc))
					log.Println(fmt.Sprintf("RRR %v", r.Rc))
				} else {
					if r.Err != nil {
						r.Err = &p.Error{r.Rc.Error, int(r.Rc.Errornum)}
					}
				}
			}

			if r.Done != nil {
				r.Done <- r
			}

			pos -= fcsize
			buf = buf[fcsize:]
		}
	}

closed:
	clnt.done <- true

	/* send error to all pending requests */
	clnt.Lock()
	r := clnt.reqfirst
	clnt.reqfirst = nil
	clnt.reqlast = nil
	if err == nil {
		err = clnt.err
	}
	clnt.Unlock()
	for ; r != nil; r = r.next {
		r.Err = err
		if r.Done != nil {
			r.Done <- r
		}
	}

	clntLock.Lock()
	if clnt.prev != nil {
		clnt.prev.next = clnt.next
	} else {
		clntList = clnt.next
	}

	if clnt.next != nil {
		clnt.next.prev = clnt.prev
	} else {
		clntLast = clnt.prev
	}
	clntLock.Unlock()
}

func (clnt *Clnt) send() {
	for {
		select {
		case <-clnt.done:
			return

		case req := <-clnt.reqout:
			if clnt.Debuglevel > 0 {
				clnt.logFcall(req.Tc)
				if clnt.Debuglevel&DbgPrintPackets != 0 {
					log.Println("{-{", clnt.Id, fmt.Sprint(req.Tc.Pkt))
				}

				if clnt.Debuglevel&DbgPrintFcalls != 0 {
					log.Println("{{{", clnt.Id, req.Tc.String())
				}
			}

			for buf := req.Tc.Pkt; len(buf) > 0; {
				n, err := clnt.conn.Write(buf)
				if err != nil {
					/* just close the socket, will get signal on clnt.done */
					clnt.conn.Close()
					break
				}

				buf = buf[n:len(buf)]
			}
		}
	}
}

// Creates and initializes a new Clnt object. Doesn't send any data
// on the wire.
func NewClnt(c net.Conn, msize uint32, dotu bool) *Clnt {
	clnt := new(Clnt)
	clnt.conn = c
	clnt.Msize = msize
	clnt.Dotu = dotu
	clnt.Debuglevel = DefaultDebuglevel
	clnt.Log = DefaultLogger
	clnt.tagpool = newPool(uint32(p.NOTAG))
	clnt.fidpool = newPool(p.NOFID)
	clnt.reqout = make(chan *Req)
	clnt.done = make(chan bool)
	clnt.reqchan = make(chan *Req, 16)
	clnt.tchan = make(chan *p.Fcall, 16)

	go clnt.recv()
	go clnt.send()

	clntLock.Lock()
	if clntLast != nil {
		clntLast.next = clnt
	} else {
		clntList = clnt
	}

	clnt.prev = clntLast
	clntLast = clnt
	clntLock.Unlock()

	return clnt
}

// Establishes a new socket connection to the 9P server and creates
// a client object for it. Negotiates the dialect and msize for the
// connection. Returns a Clnt object, or Error.
func Connect(ntype, addr string, msize uint32, dotu bool) (*Clnt, *p.Error) {
	c, e := net.Dial(ntype, "", addr)
	if e != nil {
		return nil, &p.Error{e.String(), syscall.EIO}
	}

	clnt := NewClnt(c, msize, dotu)
	clnt.Id = addr + ":"
	ver := "9P2000"
	if clnt.Dotu {
		ver = "9P2000.u"
	}

	tc := p.NewFcall(clnt.Msize)
	err := p.PackTversion(tc, clnt.Msize, ver)
	if err != nil {
		return nil, err
	}

	rc, err := clnt.Rpc(tc)
	if err != nil {
		return nil, err
	}

	if rc.Msize < clnt.Msize {
		clnt.Msize = rc.Msize
	}

	clnt.Dotu = rc.Version == "9P2000.u" && clnt.Dotu
	return clnt, nil
}

// Creates a new Fid object for the client
func (clnt *Clnt) FidAlloc() *Fid {
	fid := new(Fid)
	fid.Fid = clnt.fidpool.getId()
	fid.Clnt = clnt

	return fid
}

func (clnt *Clnt) NewFcall() *p.Fcall {
	tc, ok := <-clnt.tchan
	if !ok {
		tc = p.NewFcall(clnt.Msize)
	}

	return tc
}

func (clnt *Clnt) ReqAlloc() *Req {
	req, ok := <-clnt.reqchan
	if !ok {
		req = new(Req)
		req.Clnt = clnt
		req.tag = uint16(clnt.tagpool.getId())
	}

	return req
}

func (clnt *Clnt) ReqFree(req *Req) {
	if req.Tc != nil && len(req.Tc.Buf) >= int(clnt.Msize) {
		_ = clnt.tchan <- req.Tc
	}

	req.Tc = nil
	req.Rc = nil
	req.Err = nil
	req.Done = nil
	req.next = nil
	req.prev = nil

	if ok := clnt.reqchan <- req; !ok {
		clnt.tagpool.putId(uint32(req.tag))
	}
}

func (clnt *Clnt) logFcall(fc *p.Fcall) {
	if clnt.Debuglevel&DbgLogPackets != 0 {
		pkt := make([]byte, len(fc.Pkt))
		copy(pkt, fc.Pkt)
		clnt.Log.Log(pkt, clnt, DbgLogPackets)
	}

	if clnt.Debuglevel&DbgLogFcalls != 0 {
		f := new(p.Fcall)
		*f = *fc
		f.Pkt = nil
		clnt.Log.Log(f, clnt, DbgLogFcalls)
	}
}

func init() {
	statsRegister()
}
<|endoftext|>


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

package stop

import (
	"fmt"
	"log"
	"sort"
	"strings"
	"sync"

	"github.com/cockroachdb/cockroach/util/caller"
)

// Closer is an interface for objects to attach to the stopper to
// be closed once the stopper completes.
type Closer interface {
	Close()
}

// CloserFn is type that allows any function to be a Closer.
type CloserFn func()

// Close implements the Closer interface.
func (f CloserFn) Close() {
	f()
}

// A Stopper provides a channel-based mechanism to stop an arbitrary
// array of workers. Each worker is registered with the stopper via
// the RunWorker() method. The system further allows execution of functions
// through RunTask() and RunAsyncTask().
//
// Stopping occurs in two phases: the first is the request to stop, which moves
// the stopper into a draining phase. While draining, calls to RunTask() &
// RunAsyncTask() don't execute the function passed in and return false.
// When all outstanding tasks have been completed, the stopper
// closes its stopper channel, which signals all live workers that it's safe to
// shut down. When all workers have shutdown, the stopper is complete.
//
// An arbitrary list of objects implementing the Closer interface may
// be added to the stopper via AddCloser(), to be closed after the
// stopper has stopped.
type Stopper struct {
	stopper  chan struct{}  // Closed when stopping
	stopped  chan struct{}  // Closed when stopped completely
	stop     sync.WaitGroup // Incremented for outstanding workers
	mu       sync.Mutex     // Protects the fields below
	drain    *sync.Cond     // Conditional variable to wait for outstanding tasks
	draining bool           // true when Stop() has been called
	numTasks int            // number of outstanding tasks
	tasks    map[string]int
	closers  []Closer
}

// NewStopper returns an instance of Stopper.
func NewStopper() *Stopper {
	s := &Stopper{
		stopper: make(chan struct{}),
		stopped: make(chan struct{}),
		tasks:   map[string]int{},
	}
	s.drain = sync.NewCond(&s.mu)
	return s
}

// RunWorker runs the supplied function as a "worker" to be stopped
// by the stopper. The function <f> is run in a goroutine.
func (s *Stopper) RunWorker(f func()) {
	s.stop.Add(1)
	go func() {
		defer s.stop.Done()
		f()
	}()
}

// AddCloser adds an object to close after the stopper has been stopped.
func (s *Stopper) AddCloser(c Closer) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.closers = append(s.closers, c)
}

// RunTask adds one to the count of tasks left to drain in the system. Any
// worker which is a "first mover" when starting tasks must call this method
// before starting work on a new task. First movers include
// goroutines launched to do periodic work and the kv/db.go gateway which
// accepts external client requests.
//
// Returns false to indicate that the system is currently draining and
// function f was not called.
func (s *Stopper) RunTask(f func()) bool {
	file, line, _ := caller.Lookup(1)
	taskKey := fmt.Sprintf("%s:%d", file, line)
	if !s.runPrelude(taskKey) {
		return false
	}
	// Call f.
	defer s.runPostlude(taskKey)
	f()
	return true
}

// RunAsyncTask runs function f in a goroutine. It returns false when the
// Stopper is draining and the function is not executed.
func (s *Stopper) RunAsyncTask(f func()) bool {
	file, line, _ := caller.Lookup(1)
	taskKey := fmt.Sprintf("%s:%d", file, line)
	if !s.runPrelude(taskKey) {
		return false
	}
	// Call f.
	go func() {
		defer s.runPostlude(taskKey)
		f()
	}()
	return true
}

func (s *Stopper) runPrelude(taskKey string) bool {
	s.mu.Lock()
	defer s.mu.Unlock()
	if s.draining {
		return false
	}
	s.numTasks++
	s.tasks[taskKey]++
	return true
}

func (s *Stopper) runPostlude(taskKey string) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.numTasks--
	s.tasks[taskKey]--
	s.drain.Broadcast()
}

// NumTasks returns the number of active tasks.
func (s *Stopper) NumTasks() int {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.numTasks
}

// A TaskMap is returned by RunningTasks().
type TaskMap map[string]int

// String implements fmt.Stringer and returns a sorted multi-line listing of
// the TaskMap.
func (tm TaskMap) String() string {
	var lines []string
	for location, num := range tm {
		lines = append(lines, fmt.Sprintf("%-6d %s", num, location))
	}
	sort.Sort(sort.Reverse(sort.StringSlice(lines)))
	return strings.Join(lines, "\n")
}

// RunningTasks returns a map containing the count of running tasks keyed by
// callsite.
func (s *Stopper) RunningTasks() TaskMap {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.runningTasksLocked()
}

func (s *Stopper) runningTasksLocked() TaskMap {
	m := map[string]int{}
	for k := range s.tasks {
		if s.tasks[k] == 0 {
			continue
		}
		m[k] = s.tasks[k]
	}
	return m
}

// Stop signals all live workers to stop and then waits for each to
// confirm it has stopped.
func (s *Stopper) Stop() {
	s.Quiesce()
	close(s.stopper)
	s.stop.Wait()
	s.mu.Lock()
	defer s.mu.Unlock()
	for _, c := range s.closers {
		c.Close()
	}
	close(s.stopped)
}

// ShouldStop returns a channel which will be closed when Stop() has been
// invoked and outstanding tasks have drained.
func (s *Stopper) ShouldStop() <-chan struct{} {
	if s == nil {
		// A nil stopper will never signal ShouldStop, but will also never panic.
		return nil
	}
	return s.stopper
}

// IsStopped returns a channel which will be closed after Stop() has
// been invoked to full completion, meaning all workers have completed
// and all closers have been closed.
func (s *Stopper) IsStopped() <-chan struct{} {
	if s == nil {
		return nil
	}
	return s.stopped
}

// Quiesce moves the stopper to state draining and waits until all
// tasks complete. This is used from Stop() and unittests.
func (s *Stopper) Quiesce() {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.draining = true
	for s.numTasks > 0 {
		// Use stdlib "log" instead of "cockroach/util/log" due to import cycles.
		log.Print("draining; tasks left:\n", s.runningTasksLocked())
		// Unlock s.mu, wait for the signal, and lock s.mu.
		s.drain.Wait()
	}
}
<commit_msg>util/stop: don't bother stopping if we're panicking<commit_after>// Copyright 2014 The Cockroach Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License. See the AUTHORS file
// for names of contributors.
//
// Author: Spencer Kimball (spencer.kimball@gmail.com)

package stop

import (
	"fmt"
	"log"
	"sort"
	"strings"
	"sync"

	"github.com/cockroachdb/cockroach/util/caller"
)

// Closer is an interface for objects to attach to the stopper to
// be closed once the stopper completes.
type Closer interface {
	Close()
}

// CloserFn is type that allows any function to be a Closer.
type CloserFn func()

// Close implements the Closer interface.
func (f CloserFn) Close() {
	f()
}

// A Stopper provides a channel-based mechanism to stop an arbitrary
// array of workers. Each worker is registered with the stopper via
// the RunWorker() method. The system further allows execution of functions
// through RunTask() and RunAsyncTask().
//
// Stopping occurs in two phases: the first is the request to stop, which moves
// the stopper into a draining phase. While draining, calls to RunTask() &
// RunAsyncTask() don't execute the function passed in and return false.
// When all outstanding tasks have been completed, the stopper
// closes its stopper channel, which signals all live workers that it's safe to
// shut down. When all workers have shutdown, the stopper is complete.
//
// An arbitrary list of objects implementing the Closer interface may
// be added to the stopper via AddCloser(), to be closed after the
// stopper has stopped.
type Stopper struct {
	stopper  chan struct{}  // Closed when stopping
	stopped  chan struct{}  // Closed when stopped completely
	stop     sync.WaitGroup // Incremented for outstanding workers
	mu       sync.Mutex     // Protects the fields below
	drain    *sync.Cond     // Conditional variable to wait for outstanding tasks
	draining bool           // true when Stop() has been called
	numTasks int            // number of outstanding tasks
	tasks    map[string]int
	closers  []Closer
}

// NewStopper returns an instance of Stopper.
func NewStopper() *Stopper {
	s := &Stopper{
		stopper: make(chan struct{}),
		stopped: make(chan struct{}),
		tasks:   map[string]int{},
	}
	s.drain = sync.NewCond(&s.mu)
	return s
}

// RunWorker runs the supplied function as a "worker" to be stopped
// by the stopper. The function <f> is run in a goroutine.
func (s *Stopper) RunWorker(f func()) {
	s.stop.Add(1)
	go func() {
		defer s.stop.Done()
		f()
	}()
}

// AddCloser adds an object to close after the stopper has been stopped.
func (s *Stopper) AddCloser(c Closer) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.closers = append(s.closers, c)
}

// RunTask adds one to the count of tasks left to drain in the system. Any
// worker which is a "first mover" when starting tasks must call this method
// before starting work on a new task. First movers include
// goroutines launched to do periodic work and the kv/db.go gateway which
// accepts external client requests.
//
// Returns false to indicate that the system is currently draining and
// function f was not called.
func (s *Stopper) RunTask(f func()) bool {
	file, line, _ := caller.Lookup(1)
	taskKey := fmt.Sprintf("%s:%d", file, line)
	if !s.runPrelude(taskKey) {
		return false
	}
	// Call f.
	defer s.runPostlude(taskKey)
	f()
	return true
}

// RunAsyncTask runs function f in a goroutine. It returns false when the
// Stopper is draining and the function is not executed.
func (s *Stopper) RunAsyncTask(f func()) bool {
	file, line, _ := caller.Lookup(1)
	taskKey := fmt.Sprintf("%s:%d", file, line)
	if !s.runPrelude(taskKey) {
		return false
	}
	// Call f.
	go func() {
		defer s.runPostlude(taskKey)
		f()
	}()
	return true
}

func (s *Stopper) runPrelude(taskKey string) bool {
	s.mu.Lock()
	defer s.mu.Unlock()
	if s.draining {
		return false
	}
	s.numTasks++
	s.tasks[taskKey]++
	return true
}

func (s *Stopper) runPostlude(taskKey string) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.numTasks--
	s.tasks[taskKey]--
	s.drain.Broadcast()
}

// NumTasks returns the number of active tasks.
func (s *Stopper) NumTasks() int {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.numTasks
}

// A TaskMap is returned by RunningTasks().
type TaskMap map[string]int

// String implements fmt.Stringer and returns a sorted multi-line listing of
// the TaskMap.
func (tm TaskMap) String() string {
	var lines []string
	for location, num := range tm {
		lines = append(lines, fmt.Sprintf("%-6d %s", num, location))
	}
	sort.Sort(sort.Reverse(sort.StringSlice(lines)))
	return strings.Join(lines, "\n")
}

// RunningTasks returns a map containing the count of running tasks keyed by
// callsite.
func (s *Stopper) RunningTasks() TaskMap {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.runningTasksLocked()
}

func (s *Stopper) runningTasksLocked() TaskMap {
	m := map[string]int{}
	for k := range s.tasks {
		if s.tasks[k] == 0 {
			continue
		}
		m[k] = s.tasks[k]
	}
	return m
}

// Stop signals all live workers to stop and then waits for each to
// confirm it has stopped.
func (s *Stopper) Stop() {
	// Don't bother doing stuff if we're panicking, just die.
	if r := recover(); r != nil {
		panic(r)
	}

	s.Quiesce()
	close(s.stopper)
	s.stop.Wait()
	s.mu.Lock()
	defer s.mu.Unlock()
	for _, c := range s.closers {
		c.Close()
	}
	close(s.stopped)
}

// ShouldStop returns a channel which will be closed when Stop() has been
// invoked and outstanding tasks have drained.
func (s *Stopper) ShouldStop() <-chan struct{} {
	if s == nil {
		// A nil stopper will never signal ShouldStop, but will also never panic.
		return nil
	}
	return s.stopper
}

// IsStopped returns a channel which will be closed after Stop() has
// been invoked to full completion, meaning all workers have completed
// and all closers have been closed.
func (s *Stopper) IsStopped() <-chan struct{} {
	if s == nil {
		return nil
	}
	return s.stopped
}

// Quiesce moves the stopper to state draining and waits until all
// tasks complete. This is used from Stop() and unittests.
func (s *Stopper) Quiesce() {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.draining = true
	for s.numTasks > 0 {
		// Use stdlib "log" instead of "cockroach/util/log" due to import cycles.
		log.Print("draining; tasks left:\n", s.runningTasksLocked())
		// Unlock s.mu, wait for the signal, and lock s.mu.
		s.drain.Wait()
	}
}
<|endoftext|>


<commit_before>// +build windows

package util

import (
	"fmt"
	"os"
	"os/exec"
	"strings"

	"github.com/jcelliott/lumber"
	"github.com/nanobox-io/nanobox-golang-stylish"
)

// PrivilegeExec runs a command, but assumes your already running as adminsitrator
func PrivilegeExec(command, msg string) {
	fmt.Printf(stylish.Bullet(msg))

	//
	cmd := exec.Command(os.Args[0], strings.Split(command, " ")...)

	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	// run command
	if err := cmd.Run(); err != nil {
		lumber.Fatal("[commands/commands_windows]", err.Error())
	}
}
<commit_msg>Add privilege exec for windows. Needs tested<commit_after>// +build windows

package util

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
)

// PrivilegeExec will run the requested command
func PrivilegeExec(command string) error {

	// Windows is tricky. Unfortunately we can't just prefix the command with sudo
	// Instead, we have to use powershell to create a profile, and then create
	// a process within powershell requesting Administrative permissions.
	//
	// Generating the command is complicated.
	// The following resources were used as documentation for the logic below:
	// https://msdn.microsoft.com/en-us/powershell/scripting/core-powershell/console/powershell.exe-command-line-help
	// http://ss64.com/ps/start-process.html
	// http://www.howtogeek.com/204088/how-to-use-a-batch-file-to-make-powershell-scripts-easier-to-run/

	// The process is constructed by passing the executable as a single argument
	// and the argument list as a space-delimited string in a single argument.
	//
	// Since the command is provided as a space-delimited string containing both
	// the executable and the argument list (just like a command would be entered
	// on the command prompt), we need to pop off the executable.

	// split the command into pieces using a space delimiter
	parts := strings.Split(command, " ")

	// extract the executable (the first item)
	executable := parts[0]

	// assemble the argument list from the rest of the parts
	arguments := strings.Join(parts[1:], " ")

	// generate the powershell process
	process := fmt.Sprintf("\"& {Start-Process %s -ArgumentList '%s' -Verb RunAs}\"", executable, arguments)

	// now we can generate a command to exec
	cmd := exec.Command("PowerShell.exe", "-NoProfile", "-Command", process)

	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	// run command
	if err := cmd.Run(); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package hawk

import (
	"regexp"
	"strings"
)

type Credential struct {
	ID  string
	Key string
	Alg Alg
}

type Option struct {
	TimeStamp   int64
	Nonce       string
	Payload     string
	ContentType string
	Hash        string
	Ext         string
	App         string
	Dlg         string
}

type Alg int

const (
	_ Alg = iota
	SHA256
	SHA512
)
<commit_msg>Remove unused import<commit_after>package hawk

type Credential struct {
	ID  string
	Key string
	Alg Alg
}

type Option struct {
	TimeStamp   int64
	Nonce       string
	Payload     string
	ContentType string
	Hash        string
	Ext         string
	App         string
	Dlg         string
}

type Alg int

const (
	_ Alg = iota
	SHA256
	SHA512
)
<|endoftext|>


<commit_before>// +build freebsd

package gopsutil

import (
	"syscall"
	"unsafe"
)

func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
	var ret []DiskPartitionStat

	// get length
	count, err := syscall.Getfsstat(nil, MntWait)
	if err != nil {
		return ret, err
	}

	fs := make([]Statfs, count)
	_, err = Getfsstat(fs, MntWait)

	for _, stat := range fs {
		opts := "rw"
		if stat.FFlags&MntReadOnly != 0 {
			opts = "ro"
		}
		if stat.FFlags&MntSynchronous != 0 {
			opts += ",sync"
		}
		if stat.FFlags&MntNoExec != 0 {
			opts += ",noexec"
		}
		if stat.FFlags&MntNoSuid != 0 {
			opts += ",nosuid"
		}
		if stat.FFlags&MntUnion != 0 {
			opts += ",union"
		}
		if stat.FFlags&MntAsync != 0 {
			opts += ",async"
		}
		if stat.FFlags&MntSuidDir != 0 {
			opts += ",suiddir"
		}
		if stat.FFlags&MntSoftDep != 0 {
			opts += ",softdep"
		}
		if stat.FFlags&MntNoSymFollow != 0 {
			opts += ",nosymfollow"
		}
		if stat.FFlags&MntGEOMJournal != 0 {
			opts += ",gjounalc"
		}
		if stat.FFlags&MntMultilabel != 0 {
			opts += ",multilabel"
		}
		if stat.FFlags&MntACLs != 0 {
			opts += ",acls"
		}
		if stat.FFlags&MntNoATime != 0 {
			opts += ",noattime"
		}
		if stat.FFlags&MntClusterRead != 0 {
			opts += ",nocluster"
		}
		if stat.FFlags&MntClusterWrite != 0 {
			opts += ",noclusterw"
		}
		if stat.FFlags&MntNFS4ACLs != 0 {
			opts += ",nfs4acls"
		}

		d := DiskPartitionStat{
			Mountpoint: byteToString(stat.FMntonname[:]),
			Fstype:     byteToString(stat.FFstypename[:]),
			Opts:       opts,
		}
		ret = append(ret, d)
	}

	return ret, nil
}

func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
	return nil, NotImplementedError

	// statinfo->devinfo->devstat
	// /usr/include/devinfo.h

	// get length
	count, err := Getfsstat(nil, MntWait)
	if err != nil {
		return nil, err
	}

	fs := make([]Statfs, count)
	_, err = Getfsstat(fs, MntWait)

	ret := make(map[string]DiskIOCountersStat, 0)
	for _, stat := range fs {
		name := byteToString(stat.FMntonname[:])
		d := DiskIOCountersStat{
			Name:       name,
			ReadCount:  stat.FSyncwrites + stat.FAsyncwrites,
			WriteCount: stat.FSyncreads + stat.FAsyncreads,
		}

		ret[name] = d
	}

	return ret, nil
}

// Getfsstat is borrowed from pkg/syscall/syscall_freebsd.go
// change Statfs_t to Statfs in order to get more information
func Getfsstat(buf []Statfs, flags int) (n int, err error) {
	var _p0 unsafe.Pointer
	var bufsize uintptr
	if len(buf) > 0 {
		_p0 = unsafe.Pointer(&buf[0])
		bufsize = unsafe.Sizeof(Statfs{}) * uintptr(len(buf))
	}
	r0, _, e1 := syscall.Syscall(syscall.SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
	n = int(r0)
	if e1 != 0 {
		err = e1
	}
	return
}
<commit_msg>fill DiskPartitionStat.Device on freebsd<commit_after>// +build freebsd

package gopsutil

import (
	"syscall"
	"unsafe"
)

func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
	var ret []DiskPartitionStat

	// get length
	count, err := syscall.Getfsstat(nil, MntWait)
	if err != nil {
		return ret, err
	}

	fs := make([]Statfs, count)
	_, err = Getfsstat(fs, MntWait)

	for _, stat := range fs {
		opts := "rw"
		if stat.FFlags&MntReadOnly != 0 {
			opts = "ro"
		}
		if stat.FFlags&MntSynchronous != 0 {
			opts += ",sync"
		}
		if stat.FFlags&MntNoExec != 0 {
			opts += ",noexec"
		}
		if stat.FFlags&MntNoSuid != 0 {
			opts += ",nosuid"
		}
		if stat.FFlags&MntUnion != 0 {
			opts += ",union"
		}
		if stat.FFlags&MntAsync != 0 {
			opts += ",async"
		}
		if stat.FFlags&MntSuidDir != 0 {
			opts += ",suiddir"
		}
		if stat.FFlags&MntSoftDep != 0 {
			opts += ",softdep"
		}
		if stat.FFlags&MntNoSymFollow != 0 {
			opts += ",nosymfollow"
		}
		if stat.FFlags&MntGEOMJournal != 0 {
			opts += ",gjounalc"
		}
		if stat.FFlags&MntMultilabel != 0 {
			opts += ",multilabel"
		}
		if stat.FFlags&MntACLs != 0 {
			opts += ",acls"
		}
		if stat.FFlags&MntNoATime != 0 {
			opts += ",noattime"
		}
		if stat.FFlags&MntClusterRead != 0 {
			opts += ",nocluster"
		}
		if stat.FFlags&MntClusterWrite != 0 {
			opts += ",noclusterw"
		}
		if stat.FFlags&MntNFS4ACLs != 0 {
			opts += ",nfs4acls"
		}

		d := DiskPartitionStat{
			Device:     byteToString(stat.FMntfromname[:]),
			Mountpoint: byteToString(stat.FMntonname[:]),
			Fstype:     byteToString(stat.FFstypename[:]),
			Opts:       opts,
		}
		ret = append(ret, d)
	}

	return ret, nil
}

func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
	return nil, NotImplementedError

	// statinfo->devinfo->devstat
	// /usr/include/devinfo.h

	// get length
	count, err := Getfsstat(nil, MntWait)
	if err != nil {
		return nil, err
	}

	fs := make([]Statfs, count)
	_, err = Getfsstat(fs, MntWait)

	ret := make(map[string]DiskIOCountersStat, 0)
	for _, stat := range fs {
		name := byteToString(stat.FMntonname[:])
		d := DiskIOCountersStat{
			Name:       name,
			ReadCount:  stat.FSyncwrites + stat.FAsyncwrites,
			WriteCount: stat.FSyncreads + stat.FAsyncreads,
		}

		ret[name] = d
	}

	return ret, nil
}

// Getfsstat is borrowed from pkg/syscall/syscall_freebsd.go
// change Statfs_t to Statfs in order to get more information
func Getfsstat(buf []Statfs, flags int) (n int, err error) {
	var _p0 unsafe.Pointer
	var bufsize uintptr
	if len(buf) > 0 {
		_p0 = unsafe.Pointer(&buf[0])
		bufsize = unsafe.Sizeof(Statfs{}) * uintptr(len(buf))
	}
	r0, _, e1 := syscall.Syscall(syscall.SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
	n = int(r0)
	if e1 != 0 {
		err = e1
	}
	return
}
<|endoftext|>


<commit_before>package tree // import "kego.io/editor/client/tree"

// ke: {"package": {"jstest": true}}

import (
	"golang.org/x/net/context"
	"honnef.co/go/js/dom"
	"kego.io/editor/client/connection"
	"kego.io/editor/client_old"
)

type Tree struct {
	Root     *Root
	Conn     *connection.Conn
	Fail     chan error
	Selected BranchInterface
	Editor   editor.EditorInterface
	Content  *dom.HTMLDivElement
	ctx      context.Context
}

func New(ctx context.Context, content *dom.HTMLDivElement, conn *connection.Conn, fail chan error) *Tree {
	return &Tree{Content: content, Conn: conn, Fail: fail, ctx: ctx}
}

func (t *Tree) KeyboardEvent(e *dom.KeyboardEvent) {
	switch e.KeyCode {
	case 38: // up
		e.PreventDefault()
		if t.Selected == nil {
			t.Root.KeyboardSelectLast()
			return
		}
		t.Selected.KeyboardSelectPrev()
	case 40: // down
		e.PreventDefault()
		if t.Selected == nil {
			t.Root.KeyboardSelectFirst()
			return
		}
		t.Selected.KeyboardSelectNext()
	case 37: // left
		e.PreventDefault()
		if t.Selected == nil {
			return
		}
		if success := t.Selected.KeyboardClose(); !success {
			t.Selected.KeyboardSelectParent()
		}
	case 39: // right
		e.PreventDefault()
		if t.Selected == nil {
			return
		}
		t.Selected.KeyboardOpen()
	}
}
<commit_msg>Fixed vanity import path<commit_after>package tree // import "kego.io/editor/client_old/tree"

// ke: {"package": {"jstest": true}}

import (
	"golang.org/x/net/context"
	"honnef.co/go/js/dom"
	"kego.io/editor/client/connection"
	"kego.io/editor/client_old"
)

type Tree struct {
	Root     *Root
	Conn     *connection.Conn
	Fail     chan error
	Selected BranchInterface
	Editor   editor.EditorInterface
	Content  *dom.HTMLDivElement
	ctx      context.Context
}

func New(ctx context.Context, content *dom.HTMLDivElement, conn *connection.Conn, fail chan error) *Tree {
	return &Tree{Content: content, Conn: conn, Fail: fail, ctx: ctx}
}

func (t *Tree) KeyboardEvent(e *dom.KeyboardEvent) {
	switch e.KeyCode {
	case 38: // up
		e.PreventDefault()
		if t.Selected == nil {
			t.Root.KeyboardSelectLast()
			return
		}
		t.Selected.KeyboardSelectPrev()
	case 40: // down
		e.PreventDefault()
		if t.Selected == nil {
			t.Root.KeyboardSelectFirst()
			return
		}
		t.Selected.KeyboardSelectNext()
	case 37: // left
		e.PreventDefault()
		if t.Selected == nil {
			return
		}
		if success := t.Selected.KeyboardClose(); !success {
			t.Selected.KeyboardSelectParent()
		}
	case 39: // right
		e.PreventDefault()
		if t.Selected == nil {
			return
		}
		t.Selected.KeyboardOpen()
	}
}
<|endoftext|>


<commit_before>// Copyright 2021 Google LLC
//
// 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 resolver

import (
	"github.com/GoogleContainerTools/kpt/internal/cmdliveinit"
	"github.com/GoogleContainerTools/kpt/internal/cmdutil"
	"github.com/GoogleContainerTools/kpt/internal/errors"
	"github.com/GoogleContainerTools/kpt/pkg/live"
	"sigs.k8s.io/cli-utils/pkg/apply/taskrunner"
	"sigs.k8s.io/cli-utils/pkg/inventory"
)

//nolint:gochecknoinits
func init() {
	AddErrorResolver(&liveErrorResolver{})
}

const (
	noInventoryObjErrorMsg = `
Error: Package uninitialized. Please run "kpt live init" command.

The package needs to be initialized to generate the template
which will store state for resource sets. This state is
necessary to perform functionality such as deleting an entire
package or automatically deleting omitted resources (pruning).
`
	multipleInventoryObjErrorMsg = `
Error: Package has multiple inventory object templates.

The package should have one and only one inventory object template.
`
	//nolint:lll
	timeoutErrorMsg = `
Error: Timeout after {{printf "%.0f" .err.Timeout.Seconds}} seconds waiting for {{printf "%d" (len .err.TimedOutResources)}} out of {{printf "%d" (len .err.Identifiers)}} resources to reach condition {{ .err.Condition}}:{{ printf "\n" }}

{{- range .err.TimedOutResources}}
{{printf "%s/%s %s %s" .Identifier.GroupKind.Kind .Identifier.Name .Status .Message }}
{{- end}}
`

	resourceGroupCRDInstallErrorMsg = `
Error: Unable to install the ResourceGroup CRD.

{{- if gt (len .cause) 0 }}
{{ printf "\nDetails:" }}
{{ printf "%s" .cause }}
{{- end }}
`
	//nolint:lll
	noResourceGroupCRDMsg = `
Error: The ResourceGroup CRD was not found in the cluster. Please install it either by using the '--install-resource-group' flag or the 'kpt live install-resource-group' command.
`

	//nolint:lll
	invInfoAlreadyExistsMsg = `
Error: Inventory information has already been added to the package Kptfile. Changing it after a package has been applied to the cluster can lead to undesired results. Use the --force flag to suppress this error.
`

	multipleInvInfoMsg = `
Error: Multiple Kptfile resources with inventory information found. Please make sure at most one Kptfile resource contains inventory information.
`

	//nolint:lll
	inventoryInfoValidationMsg = `
Error: The inventory information is not valid. Please update the information in the Kptfile or provide information with the command line flags. To generate the inventory information the first time, use the 'kpt live init' command.

Details:
{{- range .err.Violations}}
{{printf "%s" .Reason }}
{{- end}}
`

	TimeoutErrorExitCode = 3
)

// liveErrorResolver is an implementation of the ErrorResolver interface
// that can resolve error types used in the live functionality.
type liveErrorResolver struct{}

func (*liveErrorResolver) Resolve(err error) (ResolvedResult, bool) {
	tmplArgs := map[string]interface{}{
		"err": err,
	}

	var noInventoryObjError *inventory.NoInventoryObjError
	if errors.As(err, &noInventoryObjError) {
		return ResolvedResult{
			Message: ExecuteTemplate(noInventoryObjErrorMsg, tmplArgs),
		}, true
	}

	var multipleInventoryObjError *inventory.MultipleInventoryObjError
	if errors.As(err, &multipleInventoryObjError) {
		return ResolvedResult{
			Message: ExecuteTemplate(multipleInventoryObjErrorMsg, tmplArgs),
		}, true
	}

	var timeoutError *taskrunner.TimeoutError
	if errors.As(err, &timeoutError) {
		return ResolvedResult{
			Message:  ExecuteTemplate(timeoutErrorMsg, tmplArgs),
			ExitCode: TimeoutErrorExitCode,
		}, true
	}

	var resourceGroupCRDInstallError *cmdutil.ResourceGroupCRDInstallError
	if errors.As(err, &resourceGroupCRDInstallError) {
		return ResolvedResult{
			Message: ExecuteTemplate(resourceGroupCRDInstallErrorMsg, map[string]interface{}{
				"cause": resourceGroupCRDInstallError.Err.Error(),
			}),
		}, true
	}

	var noResourceGroupCRDError *cmdutil.NoResourceGroupCRDError
	if errors.As(err, &noResourceGroupCRDError) {
		return ResolvedResult{
			Message: ExecuteTemplate(noResourceGroupCRDMsg, tmplArgs),
		}, true
	}

	var invExistsError *cmdliveinit.InvExistsError
	if errors.As(err, &invExistsError) {
		return ResolvedResult{
			Message: ExecuteTemplate(invInfoAlreadyExistsMsg, tmplArgs),
		}, true
	}

	var multipleInvInfoError *live.MultipleInventoryInfoError
	if errors.As(err, &multipleInvInfoError) {
		return ResolvedResult{
			Message: ExecuteTemplate(multipleInvInfoMsg, tmplArgs),
		}, true
	}

	var inventoryInfoValidationError *live.InventoryInfoValidationError
	if errors.As(err, &inventoryInfoValidationError) {
		return ResolvedResult{
			Message: ExecuteTemplate(inventoryInfoValidationMsg, tmplArgs),
		}, true
	}
	return ResolvedResult{}, false
}
<commit_msg>Improve the error message when apply can't find type (#2189)<commit_after>// Copyright 2021 Google LLC
//
// 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 resolver

import (
	"github.com/GoogleContainerTools/kpt/internal/cmdliveinit"
	"github.com/GoogleContainerTools/kpt/internal/cmdutil"
	"github.com/GoogleContainerTools/kpt/internal/errors"
	"github.com/GoogleContainerTools/kpt/pkg/live"
	"sigs.k8s.io/cli-utils/pkg/apply/taskrunner"
	"sigs.k8s.io/cli-utils/pkg/inventory"
	"sigs.k8s.io/cli-utils/pkg/manifestreader"
)

//nolint:gochecknoinits
func init() {
	AddErrorResolver(&liveErrorResolver{})
}

const (
	noInventoryObjErrorMsg = `
Error: Package uninitialized. Please run "kpt live init" command.

The package needs to be initialized to generate the template
which will store state for resource sets. This state is
necessary to perform functionality such as deleting an entire
package or automatically deleting omitted resources (pruning).
`
	multipleInventoryObjErrorMsg = `
Error: Package has multiple inventory object templates.

The package should have one and only one inventory object template.
`
	//nolint:lll
	timeoutErrorMsg = `
Error: Timeout after {{printf "%.0f" .err.Timeout.Seconds}} seconds waiting for {{printf "%d" (len .err.TimedOutResources)}} out of {{printf "%d" (len .err.Identifiers)}} resources to reach condition {{ .err.Condition}}:{{ printf "\n" }}

{{- range .err.TimedOutResources}}
{{printf "%s/%s %s %s" .Identifier.GroupKind.Kind .Identifier.Name .Status .Message }}
{{- end}}
`

	resourceGroupCRDInstallErrorMsg = `
Error: Unable to install the ResourceGroup CRD.

{{- if gt (len .cause) 0 }}
{{ printf "\nDetails:" }}
{{ printf "%s" .cause }}
{{- end }}
`
	//nolint:lll
	noResourceGroupCRDMsg = `
Error: The ResourceGroup CRD was not found in the cluster. Please install it either by using the '--install-resource-group' flag or the 'kpt live install-resource-group' command.
`

	//nolint:lll
	invInfoAlreadyExistsMsg = `
Error: Inventory information has already been added to the package Kptfile. Changing it after a package has been applied to the cluster can lead to undesired results. Use the --force flag to suppress this error.
`

	multipleInvInfoMsg = `
Error: Multiple Kptfile resources with inventory information found. Please make sure at most one Kptfile resource contains inventory information.
`

	//nolint:lll
	inventoryInfoValidationMsg = `
Error: The inventory information is not valid. Please update the information in the Kptfile or provide information with the command line flags. To generate the inventory information the first time, use the 'kpt live init' command.

Details:
{{- range .err.Violations}}
{{printf "%s" .Reason }}
{{- end}}
`

	unknownTypesMsg = `
Error: {{ printf "%d" (len .err.GroupKinds) }} resource types could not be found in the cluster or as CRDs among the applied resources.

Resource types:
{{- range .err.GroupKinds}}
{{ printf "%s" .String }}
{{- end}}
`

	TimeoutErrorExitCode = 3
)

// liveErrorResolver is an implementation of the ErrorResolver interface
// that can resolve error types used in the live functionality.
type liveErrorResolver struct{}

func (*liveErrorResolver) Resolve(err error) (ResolvedResult, bool) {
	tmplArgs := map[string]interface{}{
		"err": err,
	}

	var noInventoryObjError *inventory.NoInventoryObjError
	if errors.As(err, &noInventoryObjError) {
		return ResolvedResult{
			Message: ExecuteTemplate(noInventoryObjErrorMsg, tmplArgs),
		}, true
	}

	var multipleInventoryObjError *inventory.MultipleInventoryObjError
	if errors.As(err, &multipleInventoryObjError) {
		return ResolvedResult{
			Message: ExecuteTemplate(multipleInventoryObjErrorMsg, tmplArgs),
		}, true
	}

	var timeoutError *taskrunner.TimeoutError
	if errors.As(err, &timeoutError) {
		return ResolvedResult{
			Message:  ExecuteTemplate(timeoutErrorMsg, tmplArgs),
			ExitCode: TimeoutErrorExitCode,
		}, true
	}

	var resourceGroupCRDInstallError *cmdutil.ResourceGroupCRDInstallError
	if errors.As(err, &resourceGroupCRDInstallError) {
		return ResolvedResult{
			Message: ExecuteTemplate(resourceGroupCRDInstallErrorMsg, map[string]interface{}{
				"cause": resourceGroupCRDInstallError.Err.Error(),
			}),
		}, true
	}

	var noResourceGroupCRDError *cmdutil.NoResourceGroupCRDError
	if errors.As(err, &noResourceGroupCRDError) {
		return ResolvedResult{
			Message: ExecuteTemplate(noResourceGroupCRDMsg, tmplArgs),
		}, true
	}

	var invExistsError *cmdliveinit.InvExistsError
	if errors.As(err, &invExistsError) {
		return ResolvedResult{
			Message: ExecuteTemplate(invInfoAlreadyExistsMsg, tmplArgs),
		}, true
	}

	var multipleInvInfoError *live.MultipleInventoryInfoError
	if errors.As(err, &multipleInvInfoError) {
		return ResolvedResult{
			Message: ExecuteTemplate(multipleInvInfoMsg, tmplArgs),
		}, true
	}

	var inventoryInfoValidationError *live.InventoryInfoValidationError
	if errors.As(err, &inventoryInfoValidationError) {
		return ResolvedResult{
			Message: ExecuteTemplate(inventoryInfoValidationMsg, tmplArgs),
		}, true
	}

	var unknownTypesError *manifestreader.UnknownTypesError
	if errors.As(err, &unknownTypesError) {
		return ResolvedResult{
			Message: ExecuteTemplate(unknownTypesMsg, tmplArgs),
		}, true
	}
	return ResolvedResult{}, false
}
<|endoftext|>


<commit_before>package docker

import (
	"context"
	"github.com/docker/docker/api/types"
	"github.com/gorilla/websocket"
	"io"
	"log"
	"net/http"
	"regexp"
)

var logWebsocketRequest = regexp.MustCompile(`/containers/([^/]+)/logs`)
var hostCheck = regexp.MustCompile(`vibioh\.fr$`)

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin: func(r *http.Request) bool {
		log.Print(r.Host)
		return hostCheck.MatchString(r.Host)
	},
}

func logsContainerWebsocketHandler(w http.ResponseWriter, r *http.Request, containerID []byte) {
	logs, err := docker.ContainerLogs(context.Background(), string(containerID), types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true, Follow: true})
	if err != nil {
		log.Print(err)
		return
	}

	defer logs.Close()

	ws, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Print(err)
		return
	}

	defer ws.Close()

	socketWrite, err := ws.NextWriter(websocket.BinaryMessage)
	if err != nil {
		log.Print(err)
		return
	}

	if _, err := io.Copy(socketWrite, logs); err != nil {
		log.Print(err)
	}
}

func handleWebsocket(w http.ResponseWriter, r *http.Request) {
	urlPath := []byte(r.URL.Path)

	if logWebsocketRequest.Match(urlPath) {
		logsContainerWebsocketHandler(w, r, logWebsocketRequest.FindSubmatch(urlPath)[1])
	}
}
<commit_msg>Changing message type<commit_after>package docker

import (
	"context"
	"github.com/docker/docker/api/types"
	"github.com/gorilla/websocket"
	"io"
	"log"
	"net/http"
	"regexp"
)

var logWebsocketRequest = regexp.MustCompile(`/containers/([^/]+)/logs`)
var hostCheck = regexp.MustCompile(`vibioh\.fr$`)

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin: func(r *http.Request) bool {
		return hostCheck.MatchString(r.Host)
	},
}

func logsContainerWebsocketHandler(w http.ResponseWriter, r *http.Request, containerID []byte) {
	logs, err := docker.ContainerLogs(context.Background(), string(containerID), types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true, Follow: true})
	if err != nil {
		log.Print(err)
		return
	}

	defer logs.Close()

	ws, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Print(err)
		return
	}

	defer ws.Close()

	socketWrite, err := ws.NextWriter(websocket.TextMessage)
	if err != nil {
		log.Print(err)
		return
	}

	if _, err := io.Copy(socketWrite, logs); err != nil {
		log.Print(err)
		return
	}
}

func handleWebsocket(w http.ResponseWriter, r *http.Request) {
	urlPath := []byte(r.URL.Path)

	if logWebsocketRequest.Match(urlPath) {
		logsContainerWebsocketHandler(w, r, logWebsocketRequest.FindSubmatch(urlPath)[1])
	}
}
<|endoftext|>