<commit_before>package acl

import (
	"github.com/MG-RAST/Shock/shock-server/user"
)

// Node.Acl struct
type Acl struct {
	Owner  string   `bson:"owner" json:"owner"`
	Read   []string `bson:"read" json:"read"`
	Write  []string `bson:"write" json:"write"`
	Delete []string `bson:"delete" json:"delete"`
}

// struct for public status of ACL's
type publicAcl struct {
	Read   bool `bson:"read" json:"read"`
	Write  bool `bson:"write" json:"write"`
	Delete bool `bson:"delete" json:"delete"`
}

// ACL struct that is returned to user for verbosity = minimal (default)
type DisplayAcl struct {
	Owner  string    `bson:"owner" json:"owner"`
	Read   []string  `bson:"read" json:"read"`
	Write  []string  `bson:"write" json:"write"`
	Delete []string  `bson:"delete" json:"delete"`
	Public publicAcl `bson:"public" json:"public"`
}

// ACL struct that is returned to user for verbosity = full
type DisplayVerboseAcl struct {
	Owner  user.User   `bson:"owner" json:"owner"`
	Read   []user.User `bson:"read" json:"read"`
	Write  []user.User `bson:"write" json:"write"`
	Delete []user.User `bson:"delete" json:"delete"`
	Public publicAcl   `bson:"public" json:"public"`
}

type Rights map[string]bool

func (a *Acl) FormatDisplayAcl(verbosity string) (i interface{}) {
	if verbosity == "full" {
		dAcl := new(DisplayVerboseAcl)
		if u, err := user.FindByUuid(a.Owner); err == nil {
			dAcl.Owner = *u
		}
		dAcl.Public.Read = false
		dAcl.Public.Write = false
		dAcl.Public.Delete = false
		for _, v := range a.Read {
			if v == "public" {
				dAcl.Public.Read = true
			} else {
				if u, err := user.FindByUuid(v); err == nil {
					dAcl.Read = insertUser(dAcl.Read, *u)
				}
			}
		}
		for _, v := range a.Write {
			if v == "public" {
				dAcl.Public.Write = true
			} else {
				if u, err := user.FindByUuid(v); err == nil {
					dAcl.Write = insertUser(dAcl.Write, *u)
				}
			}
		}
		for _, v := range a.Delete {
			if v == "public" {
				dAcl.Public.Delete = true
			} else {
				if u, err := user.FindByUuid(v); err == nil {
					dAcl.Delete = insertUser(dAcl.Delete, *u)
				}
			}
		}
		i = dAcl
	} else {
		dAcl := new(DisplayAcl)
		dAcl.Owner = a.Owner
		dAcl.Read = []string{}
		dAcl.Write = []string{}
		dAcl.Delete = []string{}
		dAcl.Public.Read = false
		dAcl.Public.Write = false
		dAcl.Public.Delete = false
		for _, v := range a.Read {
			if v == "public" {
				dAcl.Public.Read = true
			} else {
				dAcl.Read = insert(dAcl.Read, v)
			}
		}
		for _, v := range a.Write {
			if v == "public" {
				dAcl.Public.Write = true
			} else {
				dAcl.Write = insert(dAcl.Write, v)
			}
		}
		for _, v := range a.Delete {
			if v == "public" {
				dAcl.Public.Delete = true
			} else {
				dAcl.Delete = insert(dAcl.Delete, v)
			}
		}
		i = dAcl
	}
	return
}

func (a *Acl) SetOwner(str string) {
	a.Owner = str
	return
}

func (a *Acl) UnSet(str string, r Rights) {
	if r["read"] {
		a.Read = del(a.Read, str)
	}
	if r["write"] {
		a.Write = del(a.Write, str)
	}
	if r["delete"] {
		a.Delete = del(a.Delete, str)
	}
	return
}

func (a *Acl) Set(str string, r Rights) {
	if r["read"] {
		a.Read = insert(a.Read, str)
	}
	if r["write"] {
		a.Write = insert(a.Write, str)
	}
	if r["delete"] {
		a.Delete = insert(a.Delete, str)
	}
	return
}

func (a *Acl) Check(str string) (r Rights) {
	r = Rights{"read": false, "write": false, "delete": false}
	acls := map[string][]string{"read": a.Read, "write": a.Write, "delete": a.Delete}
	for k, v := range acls {
		if len(v) == 0 {
			r[k] = true
		} else {
			for _, id := range v {
				if str == id {
					r[k] = true
					break
				}
			}
		}
	}
	return
}

func del(arr []string, s string) (narr []string) {
	narr = []string{}
	for i, item := range arr {
		if item != s {
			narr = append(narr, item)
		} else {
			narr = append(narr, arr[i+1:]...)
			break
		}
	}
	return
}

func insert(arr []string, s string) []string {
	for _, item := range arr {
		if item == s {
			return arr
		}
	}
	return append(arr, s)
}

func insertUser(arr []user.User, s user.User) []user.User {
	for _, item := range arr {
		if item == s {
			return arr
		}
	}
	return append(arr, s)
}
<commit_msg>Fix to permissions.<commit_after>package acl

import (
	"github.com/MG-RAST/Shock/shock-server/user"
)

// Node.Acl struct
type Acl struct {
	Owner  string   `bson:"owner" json:"owner"`
	Read   []string `bson:"read" json:"read"`
	Write  []string `bson:"write" json:"write"`
	Delete []string `bson:"delete" json:"delete"`
}

// struct for public status of ACL's
type publicAcl struct {
	Read   bool `bson:"read" json:"read"`
	Write  bool `bson:"write" json:"write"`
	Delete bool `bson:"delete" json:"delete"`
}

// ACL struct that is returned to user for verbosity = minimal (default)
type DisplayAcl struct {
	Owner  string    `bson:"owner" json:"owner"`
	Read   []string  `bson:"read" json:"read"`
	Write  []string  `bson:"write" json:"write"`
	Delete []string  `bson:"delete" json:"delete"`
	Public publicAcl `bson:"public" json:"public"`
}

// ACL struct that is returned to user for verbosity = full
type DisplayVerboseAcl struct {
	Owner  user.User   `bson:"owner" json:"owner"`
	Read   []user.User `bson:"read" json:"read"`
	Write  []user.User `bson:"write" json:"write"`
	Delete []user.User `bson:"delete" json:"delete"`
	Public publicAcl   `bson:"public" json:"public"`
}

type Rights map[string]bool

func (a *Acl) FormatDisplayAcl(verbosity string) (i interface{}) {
	if verbosity == "full" {
		dAcl := new(DisplayVerboseAcl)
		if u, err := user.FindByUuid(a.Owner); err == nil {
			dAcl.Owner = *u
		}
		dAcl.Public.Read = false
		dAcl.Public.Write = false
		dAcl.Public.Delete = false
		for _, v := range a.Read {
			if v == "public" {
				dAcl.Public.Read = true
			} else {
				if u, err := user.FindByUuid(v); err == nil {
					dAcl.Read = insertUser(dAcl.Read, *u)
				}
			}
		}
		for _, v := range a.Write {
			if v == "public" {
				dAcl.Public.Write = true
			} else {
				if u, err := user.FindByUuid(v); err == nil {
					dAcl.Write = insertUser(dAcl.Write, *u)
				}
			}
		}
		for _, v := range a.Delete {
			if v == "public" {
				dAcl.Public.Delete = true
			} else {
				if u, err := user.FindByUuid(v); err == nil {
					dAcl.Delete = insertUser(dAcl.Delete, *u)
				}
			}
		}
		i = dAcl
	} else {
		dAcl := new(DisplayAcl)
		dAcl.Owner = a.Owner
		dAcl.Read = []string{}
		dAcl.Write = []string{}
		dAcl.Delete = []string{}
		dAcl.Public.Read = false
		dAcl.Public.Write = false
		dAcl.Public.Delete = false
		for _, v := range a.Read {
			if v == "public" {
				dAcl.Public.Read = true
			} else {
				dAcl.Read = insert(dAcl.Read, v)
			}
		}
		for _, v := range a.Write {
			if v == "public" {
				dAcl.Public.Write = true
			} else {
				dAcl.Write = insert(dAcl.Write, v)
			}
		}
		for _, v := range a.Delete {
			if v == "public" {
				dAcl.Public.Delete = true
			} else {
				dAcl.Delete = insert(dAcl.Delete, v)
			}
		}
		i = dAcl
	}
	return
}

func (a *Acl) SetOwner(str string) {
	a.Owner = str
	return
}

func (a *Acl) UnSet(str string, r Rights) {
	if r["read"] {
		a.Read = del(a.Read, str)
	}
	if r["write"] {
		a.Write = del(a.Write, str)
	}
	if r["delete"] {
		a.Delete = del(a.Delete, str)
	}
	return
}

func (a *Acl) Set(str string, r Rights) {
	if r["read"] {
		a.Read = insert(a.Read, str)
	}
	if r["write"] {
		a.Write = insert(a.Write, str)
	}
	if r["delete"] {
		a.Delete = insert(a.Delete, str)
	}
	return
}

func (a *Acl) Check(str string) (r Rights) {
	r = Rights{"read": false, "write": false, "delete": false}
	acls := map[string][]string{"read": a.Read, "write": a.Write, "delete": a.Delete}
	for k, v := range acls {
		for _, id := range v {
			if str == id {
				r[k] = true
				break
			}
		}
	}
	return
}

func del(arr []string, s string) (narr []string) {
	narr = []string{}
	for i, item := range arr {
		if item != s {
			narr = append(narr, item)
		} else {
			narr = append(narr, arr[i+1:]...)
			break
		}
	}
	return
}

func insert(arr []string, s string) []string {
	for _, item := range arr {
		if item == s {
			return arr
		}
	}
	return append(arr, s)
}

func insertUser(arr []user.User, s user.User) []user.User {
	for _, item := range arr {
		if item == s {
			return arr
		}
	}
	return append(arr, s)
}
<|endoftext|>


<commit_before>package martini

import (
	"log"
	"net/http"
	"path/filepath"
)

// Static returns a middleware handler that serves static files in the given path.
func Static(path string) Handler {
	dir := http.Dir(path)
	return func(res http.ResponseWriter, req *http.Request, log *log.Logger) {
		file := req.URL.Path
		f, err := dir.Open(file)
		if err != nil {
			// discard the error?
			return
		}
		defer f.Close()

		fi, err := f.Stat()
		if err != nil {
			return
		}

		// Try to serve index.html
		if fi.IsDir() {
			file += "/index.html"
			f, err = dir.Open(file)
			if err != nil {
				return
			}
			defer f.Close()

			fi, err = f.Stat()
			if err != nil || fi.IsDir() {
				return
			}
		}

		log.Println("[Static] Serving " + file)
		http.ServeContent(res, req, file, fi.ModTime(), f)
	}
}
<commit_msg>Remove filepath join<commit_after>package martini

import (
	"log"
	"net/http"
)

// Static returns a middleware handler that serves static files in the given path.
func Static(path string) Handler {
	dir := http.Dir(path)
	return func(res http.ResponseWriter, req *http.Request, log *log.Logger) {
		file := req.URL.Path
		f, err := dir.Open(file)
		if err != nil {
			// discard the error?
			return
		}
		defer f.Close()

		fi, err := f.Stat()
		if err != nil {
			return
		}

		// Try to serve index.html
		if fi.IsDir() {
			file += "/index.html"
			f, err = dir.Open(file)
			if err != nil {
				return
			}
			defer f.Close()

			fi, err = f.Stat()
			if err != nil || fi.IsDir() {
				return
			}
		}

		log.Println("[Static] Serving " + file)
		http.ServeContent(res, req, file, fi.ModTime(), f)
	}
}
<|endoftext|>


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

// Package contains a program that generates code to register
// a directory and its contents as zip data for statik file system.
package main

import (
	"archive/zip"
	"bytes"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"
)

const (
	namePackage    = "statik"
	nameSourceFile = "statik.go"
)

var (
	flagSrc  = flag.String("src", path.Join(".", "public"), "The path of the source directory.")
	flagDest = flag.String("dest", ".", "The destination path of the generated package.")
)

func main() {
	flag.Parse()

	file, err := generateSource(*flagSrc)
	if err != nil {
		exitWithError(err)
	}

	destDir := path.Join(*flagDest, namePackage)
	err = os.MkdirAll(destDir, 0755)
	if err != nil {
		exitWithError(err)
	}

	err = copy(file.Name(), path.Join(destDir, nameSourceFile))
	if err != nil {
		exitWithError(err)
	}
}

func copy(src, dest string) error {
	// Try to rename generated source ...
	if err := os.Rename(src, dest); err == nil {
		return nil
	}

	// ... if the rename failed (might do so due to temporary file residing on a
	// different device) try to copy byte by byte.

	rc, err := os.Open(src)
	if err != nil {
		return err
	}
	defer rc.Close()

	if _, err = os.Stat(dest); !os.IsNotExist(err) {
		return fmt.Errorf("file %q already exists", dest)
	}

	wc, err := os.Create(dest)
	if err != nil {
		return err
	}
	defer wc.Close()

	if _, err = io.Copy(wc, rc); err != nil {
		// Delete remains of failed copy attempt.
		_ = os.Remove(dest)
	}
	return err
}

// Walks on the source path and generates source code
// that contains source directory's contents as zip contents.
// Generates source registers generated zip contents data to
// be read by the statik/fs HTTP file system.
func generateSource(srcPath string) (file *os.File, err error) {
	var (
		buffer    bytes.Buffer
		zipWriter io.Writer
	)

	zipWriter = &buffer
	f, err := ioutil.TempFile("", namePackage)
	if err != nil {
		return
	}

	zipWriter = io.MultiWriter(zipWriter, f)
	defer f.Close()

	w := zip.NewWriter(zipWriter)
	if err = filepath.Walk(srcPath, func(path string, fi os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		// Ignore directories and hidden files.
		// No entry is needed for directories in a zip file.
		// Each file is represented with a path, no directory
		// entities are required to build the hierarchy.
		if fi.IsDir() || strings.HasPrefix(fi.Name(), ".") {
			return nil
		}
		relPath, err := filepath.Rel(srcPath, path)
		if err != nil {
			return err
		}
		b, err := ioutil.ReadFile(path)
		if err != nil {
			return err
		}
		fHeader, err := zip.FileInfoHeader(fi)
		if err != nil {
			return err
		}
		fHeader.Name = relPath
		f, err := w.CreateHeader(fHeader)
		if err != nil {
			return err
		}
		_, err = f.Write(b)
		return err
	}); err != nil {
		return
	}
	if err = w.Close(); err != nil {
		return
	}

	// then embed it as a quoted string
	var qb bytes.Buffer
	fmt.Fprintf(&qb, `package %s

import (
		"github.com/rakyll/statik/fs"
)

func init() {
	data := "`, namePackage)
	FprintZipData(&qb, buffer.Bytes())
	fmt.Fprint(&qb, `"
	fs.Register(data)
}
`)

	if err = ioutil.WriteFile(f.Name(), qb.Bytes(), 0644); err != nil {
		return
	}
	return f, nil
}

// Converts zip binary contents to a string literal.
func FprintZipData(dest *bytes.Buffer, zipData []byte) {
	for _, b := range zipData {
		if b == '\n' {
			dest.WriteString(`\n`)
			continue
		}
		if b == '\\' {
			dest.WriteString(`\\`)
			continue
		}
		if b == '"' {
			dest.WriteString(`\"`)
			continue
		}
		if (b >= 32 && b <= 126) || b == '\t' {
			dest.WriteByte(b)
			continue
		}
		fmt.Fprintf(dest, "\\x%02x", b)
	}
}

// Prints out the error message and exists with a non-success signal.
func exitWithError(err error) {
	fmt.Println(err)
	os.Exit(1)
}
<commit_msg>remove the temporary source file if we copied byte by byte.<commit_after>// Copyright 2014 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package contains a program that generates code to register
// a directory and its contents as zip data for statik file system.
package main

import (
	"archive/zip"
	"bytes"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"
)

const (
	namePackage    = "statik"
	nameSourceFile = "statik.go"
)

var (
	flagSrc  = flag.String("src", path.Join(".", "public"), "The path of the source directory.")
	flagDest = flag.String("dest", ".", "The destination path of the generated package.")
)

func main() {
	flag.Parse()

	file, err := generateSource(*flagSrc)
	if err != nil {
		exitWithError(err)
	}

	destDir := path.Join(*flagDest, namePackage)
	err = os.MkdirAll(destDir, 0755)
	if err != nil {
		exitWithError(err)
	}

	err = copy(file.Name(), path.Join(destDir, nameSourceFile))
	if err != nil {
		exitWithError(err)
	}
}

func copy(src, dest string) error {
	// Try to rename generated source.
	if err := os.Rename(src, dest); err == nil {
		return nil
	}
	// If the rename failed (might do so due to temporary file residing on a
	// different device), try to copy byte by byte.
	rc, err := os.Open(src)
	if err != nil {
		return err
	}
	defer func() {
		rc.Close()
		os.Remove(src) // ignore the error, source is in tmp.
	}()

	if _, err = os.Stat(dest); !os.IsNotExist(err) {
		return fmt.Errorf("file %q already exists", dest)
	}

	wc, err := os.Create(dest)
	if err != nil {
		return err
	}
	defer wc.Close()

	if _, err = io.Copy(wc, rc); err != nil {
		// Delete remains of failed copy attempt.
		os.Remove(dest)
	}
	return err
}

// Walks on the source path and generates source code
// that contains source directory's contents as zip contents.
// Generates source registers generated zip contents data to
// be read by the statik/fs HTTP file system.
func generateSource(srcPath string) (file *os.File, err error) {
	var (
		buffer    bytes.Buffer
		zipWriter io.Writer
	)

	zipWriter = &buffer
	f, err := ioutil.TempFile("", namePackage)
	if err != nil {
		return
	}

	zipWriter = io.MultiWriter(zipWriter, f)
	defer f.Close()

	w := zip.NewWriter(zipWriter)
	if err = filepath.Walk(srcPath, func(path string, fi os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		// Ignore directories and hidden files.
		// No entry is needed for directories in a zip file.
		// Each file is represented with a path, no directory
		// entities are required to build the hierarchy.
		if fi.IsDir() || strings.HasPrefix(fi.Name(), ".") {
			return nil
		}
		relPath, err := filepath.Rel(srcPath, path)
		if err != nil {
			return err
		}
		b, err := ioutil.ReadFile(path)
		if err != nil {
			return err
		}
		fHeader, err := zip.FileInfoHeader(fi)
		if err != nil {
			return err
		}
		fHeader.Name = relPath
		f, err := w.CreateHeader(fHeader)
		if err != nil {
			return err
		}
		_, err = f.Write(b)
		return err
	}); err != nil {
		return
	}
	if err = w.Close(); err != nil {
		return
	}

	// then embed it as a quoted string
	var qb bytes.Buffer
	fmt.Fprintf(&qb, `package %s

import (
		"github.com/rakyll/statik/fs"
)

func init() {
	data := "`, namePackage)
	FprintZipData(&qb, buffer.Bytes())
	fmt.Fprint(&qb, `"
	fs.Register(data)
}
`)

	if err = ioutil.WriteFile(f.Name(), qb.Bytes(), 0644); err != nil {
		return
	}
	return f, nil
}

// Converts zip binary contents to a string literal.
func FprintZipData(dest *bytes.Buffer, zipData []byte) {
	for _, b := range zipData {
		if b == '\n' {
			dest.WriteString(`\n`)
			continue
		}
		if b == '\\' {
			dest.WriteString(`\\`)
			continue
		}
		if b == '"' {
			dest.WriteString(`\"`)
			continue
		}
		if (b >= 32 && b <= 126) || b == '\t' {
			dest.WriteByte(b)
			continue
		}
		fmt.Fprintf(dest, "\\x%02x", b)
	}
}

// Prints out the error message and exists with a non-success signal.
func exitWithError(err error) {
	fmt.Println(err)
	os.Exit(1)
}
<|endoftext|>


<commit_before>package gop

import (
	"github.com/cactus/go-statsd-client/statsd"
	"os"
	"strings"
)

type StatsdClient struct {
	client *statsd.Client
	rate   float32
	app    *App
}

func (a *App) initStatsd() {
	statsdHostport, _ := a.Cfg.Get("gop", "statsd_hostport", "localhost:8125")
	hostname, _ := os.Hostname()
	statsdPrefix := strings.Join([]string{a.ProjectName, a.AppName, strings.Replace(hostname, ".", "_", -1)}, ".")
	client, err := statsd.New(statsdHostport, statsdPrefix)
	if err != nil {
		// App will probably fall over due to nil client. That's OK.
		// We *could* panic below, but lets try and continue at least
		a.Error("Failed to create statsd client: " + err.Error())
		return
	}

	rate, _ := a.Cfg.GetFloat32("gop", "statsd_rate", 1.0)
	a.Stats = StatsdClient{
		client: client,
		rate:   rate,
		app:    a,
	}
}

func (s *StatsdClient) Dec(stat string, value int64) {
	s.app.Debug("STATSD DEC %s %d", stat, value)
	_ = s.client.Dec(stat, value, s.rate)
}

func (s *StatsdClient) Gauge(stat string, value int64) {
	s.app.Debug("STATSD GAUGE %s %d", stat, value)
	_ = s.client.Gauge(stat, value, s.rate)
}

func (s *StatsdClient) GaugeDelta(stat string, value int64) {
	s.app.Debug("STATSD GAUGEDELTA %s %d", stat, value)
	_ = s.client.GaugeDelta(stat, value, s.rate)
}

func (s *StatsdClient) Inc(stat string, value int64) {
	s.app.Debug("STATSD INC %s %d", stat, value)
	_ = s.client.Inc(stat, value, s.rate)
}

func (s *StatsdClient) Timing(stat string, delta int64) {
	s.app.Debug("STATSD TIMING %s %d", stat, delta)
	_ = s.client.Timing(stat, delta, s.rate)
}
<commit_msg>compilation fix for incompatible dependency change<commit_after>package gop

import (
	"os"
	"strings"

	"github.com/cactus/go-statsd-client/statsd"
)

type StatsdClient struct {
	client statsd.Statter
	rate   float32
	app    *App
}

func (a *App) initStatsd() {
	statsdHostport, _ := a.Cfg.Get("gop", "statsd_hostport", "localhost:8125")
	hostname, _ := os.Hostname()
	statsdPrefix := strings.Join([]string{a.ProjectName, a.AppName, strings.Replace(hostname, ".", "_", -1)}, ".")
	client, err := statsd.New(statsdHostport, statsdPrefix)
	if err != nil {
		// App will probably fall over due to nil client. That's OK.
		// We *could* panic below, but lets try and continue at least
		a.Error("Failed to create statsd client: " + err.Error())
		return
	}

	rate, _ := a.Cfg.GetFloat32("gop", "statsd_rate", 1.0)
	a.Stats = StatsdClient{
		client: client,
		rate:   rate,
		app:    a,
	}
}

func (s *StatsdClient) Dec(stat string, value int64) {
	s.app.Debug("STATSD DEC %s %d", stat, value)
	_ = s.client.Dec(stat, value, s.rate)
}

func (s *StatsdClient) Gauge(stat string, value int64) {
	s.app.Debug("STATSD GAUGE %s %d", stat, value)
	_ = s.client.Gauge(stat, value, s.rate)
}

func (s *StatsdClient) GaugeDelta(stat string, value int64) {
	s.app.Debug("STATSD GAUGEDELTA %s %d", stat, value)
	_ = s.client.GaugeDelta(stat, value, s.rate)
}

func (s *StatsdClient) Inc(stat string, value int64) {
	s.app.Debug("STATSD INC %s %d", stat, value)
	_ = s.client.Inc(stat, value, s.rate)
}

func (s *StatsdClient) Timing(stat string, delta int64) {
	s.app.Debug("STATSD TIMING %s %d", stat, delta)
	_ = s.client.Timing(stat, delta, s.rate)
}
<|endoftext|>


<commit_before>package ftp

const (
	StatusInitiating = 100
	StatusRestartMarker = 110
	StatusReadyMinute = 120
	StatusAlreadyOpen = 125
	StatusAboutToSend = 150

	StatusCommandOK = 200
	StatusCommandNotImplemented = 202
	StatusSystem = 211
	StatusDirectory = 212
	StatusFile = 213
	StatusHelp = 214
	StatusName = 215
	StatusReady = 220
	StatusClosing = 221
	StatusDataConnectionOpen = 225
	StatusClosingDataConnection = 226
	StatusPassiveMode = 227
	StatusLongPassiveMode = 228
	StatusExtendedPassiveMode = 229
	StatusLoggedIn = 230
	StatusLoggedOut = 231
	StatusLogoutAck = 232
	StatusRequestedFileActionOK = 250
	StatusPathCreated = 257

	StatusUserOK = 331
	StatusLoginNeedAccount = 332
	StatusRequestFilePending = 350

	StatusNotAvailable = 421
	StatusCanNotOpenDataConnection = 425
	StatusTransfertAborted = 426
	StatusInvalidCredentials = 430
	StatusHostUnavailable = 434
	StatusFileActionIgnored = 450
	StatusActionAborted = 451
	Status452 = 452

	StatusBadCommand = 500
	StatusBadArguments = 501
	StatusNotImplemented = 502
	StatusBadSequence = 503
	StatusNotImplementedParameter = 504
	StatusNotLoggedIn = 530
	StatusStorNeedAccount = 532
	StatusFileUnavailable = 550
	StatusPageTypeUnknown = 551
	StatusExceededStorage = 552
	StatusBadFileName = 553
)

var statusText = map[int]string{
	StatusCommandOK:		"Command okay",
	StatusCommandNotImplemented:	"Command not implemented, superfluous at this site",
	StatusSystem:			"System status, or system help reply",
	StatusDirectory:		"Directory status",
	StatusFile:			"File status",
	StatusHelp:			"Help message",
	StatusName:			"",
	StatusReady:			"Service ready for new user",
	StatusClosing:			"Service closing control connection",
	StatusDataConnectionOpen:	"Data connection open; no transfer in progress",
	StatusClosingDataConnection:	"Closing data connection. Requested file action successful",
	StatusPassiveMode:		"Entering Passive Mode",
	StatusLongPassiveMode:		"Entering Long Passive Mode",
	StatusExtendedPassiveMode:	"Entering Extended Passive Mode",
	StatusLoggedIn:			"User logged in, proceed",
	StatusLoggedOut:		"User logged out; service terminated",
	StatusLogoutAck:		"Logout command noted, will complete when transfer done",
	StatusRequestedFileActionOK:	"Requested file action okay, completed",
	StatusPathCreated:		"Path created",

	StatusUserOK:			"",
	StatusLoginNeedAccount:		"",
	StatusRequestFilePending:	"",

	StatusNotAvailable:		"",
	StatusCanNotOpenDataConnection:	"",
	StatusTransfertAborted:		"",
	StatusInvalidCredentials:	"",
	StatusHostUnavailable:		"",
	StatusFileActionIgnored:	"",
	StatusActionAborted:		"",
	Status452:			"",

	StatusBadCommand:		"",
	StatusBadArguments:		"",
	StatusNotImplemented:		"",
	StatusBadSequence:		"",
	StatusNotImplementedParameter:	"",
	StatusNotLoggedIn:		"",
	StatusStorNeedAccount:		"",
	StatusFileUnavailable:		"",
	StatusPageTypeUnknown:		"",
	StatusExceededStorage:		"",
	StatusBadFileName:		"",
}
<commit_msg>More status code texts.<commit_after>package ftp

const (
	// Positive Preliminary reply
	StatusInitiating = 100
	StatusRestartMarker = 110
	StatusReadyMinute = 120
	StatusAlreadyOpen = 125
	StatusAboutToSend = 150
	// Positive Completion reply
	StatusCommandOK = 200
	StatusCommandNotImplemented = 202
	StatusSystem = 211
	StatusDirectory = 212
	StatusFile = 213
	StatusHelp = 214
	StatusName = 215
	StatusReady = 220
	StatusClosing = 221
	StatusDataConnectionOpen = 225
	StatusClosingDataConnection = 226
	StatusPassiveMode = 227
	StatusLongPassiveMode = 228
	StatusExtendedPassiveMode = 229
	StatusLoggedIn = 230
	StatusLoggedOut = 231
	StatusLogoutAck = 232
	StatusRequestedFileActionOK = 250
	StatusPathCreated = 257
	// Positive Intermediate reply
	StatusUserOK = 331
	StatusLoginNeedAccount = 332
	StatusRequestFilePending = 350
	// Transient Negative Completion reply
	StatusNotAvailable = 421
	StatusCanNotOpenDataConnection = 425
	StatusTransfertAborted = 426
	StatusInvalidCredentials = 430
	StatusHostUnavailable = 434
	StatusFileActionIgnored = 450
	StatusActionAborted = 451
	Status452 = 452
	// Permanent Negative Completion reply
	StatusBadCommand = 500
	StatusBadArguments = 501
	StatusNotImplemented = 502
	StatusBadSequence = 503
	StatusNotImplementedParameter = 504
	StatusNotLoggedIn = 530
	StatusStorNeedAccount = 532
	StatusFileUnavailable = 550
	StatusPageTypeUnknown = 551
	StatusExceededStorage = 552
	StatusBadFileName = 553
)

var statusText = map[int]string{
	// 200
	StatusCommandOK:		"Command okay.",
	StatusCommandNotImplemented:	"Command not implemented, superfluous at this site.",
	StatusSystem:			"System status, or system help reply.",
	StatusDirectory:		"Directory status.",
	StatusFile:			"File status.",
	StatusHelp:			"Help message.",
	StatusName:			"",
	StatusReady:			"Service ready for new user.",
	StatusClosing:			"Service closing control connection.",
	StatusDataConnectionOpen:	"Data connection open; no transfer in progress.",
	StatusClosingDataConnection:	"Closing data connection. Requested file action successful.",
	StatusPassiveMode:		"Entering Passive Mode.",
	StatusLongPassiveMode:		"Entering Long Passive Mode.",
	StatusExtendedPassiveMode:	"Entering Extended Passive Mode.",
	StatusLoggedIn:			"User logged in, proceed.",
	StatusLoggedOut:		"User logged out; service terminated.",
	StatusLogoutAck:		"Logout command noted, will complete when transfer done.",
	StatusRequestedFileActionOK:	"Requested file action okay, completed.",
	StatusPathCreated:		"Path created.",
	// 300
	StatusUserOK:			"User name okay, need password.",
	StatusLoginNeedAccount:		"Need account for login.",
	StatusRequestFilePending:	"Requested file action pending further information.",
	// 400
	StatusNotAvailable:		"Service not available, closing control connection.",
	StatusCanNotOpenDataConnection:	"Can't open data connection.",
	StatusTransfertAborted:		"Connection closed; transfer aborted.",
	StatusInvalidCredentials:	"Invalid username or password.",
	StatusHostUnavailable:		"Requested host unavailable.",
	StatusFileActionIgnored:	"Requested file action not taken.",
	StatusActionAborted:		"Requested action aborted. Local error in processing.",
	Status452:			"Insufficient storage space in system.",
	// 500
	StatusBadCommand:		"Command unrecognized.",
	StatusBadArguments:		"Syntax error in parameters or arguments.",
	StatusNotImplemented:		"Command not implemented.",
	StatusBadSequence:		"Bad sequence of commands.",
	StatusNotImplementedParameter:	"Command not implemented for that parameter.",
	StatusNotLoggedIn:		"Not logged in.",
	StatusStorNeedAccount:		"Need account for storing files.",
	StatusFileUnavailable:		"File unavailable.",
	StatusPageTypeUnknown:		"Page type unknown.",
	StatusExceededStorage:		"Exceeded storage allocation.",
	StatusBadFileName:		"File name not allowed.",
}
<|endoftext|>


<commit_before>// Copyright 2015 Matthew Collins
//
// 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 steven

import (
	"fmt"
	"math"
	"runtime"
	"time"

	"github.com/go-gl/glfw/v3.1/glfw"
	"github.com/thinkofdeath/steven/protocol/mojang"
	"github.com/thinkofdeath/steven/render"
	"github.com/thinkofdeath/steven/ui"
)

var (
	profile       mojang.Profile
	server        string
	loadChan      = make(chan struct{})
	currentScreen screen
)

type screen interface {
	tick(delta float64)
	hover(x, y float64, w, h int)
	click(x, y float64, w, h int)
	remove()
}

func setScreen(s screen) {
	if currentScreen != nil {
		currentScreen.remove()
	}
	currentScreen = s
	if s != nil {
		lockMouse = false
		window.SetInputMode(glfw.CursorMode, glfw.CursorNormal)
	}
}

func Main(username, uuid, accessToken, s string) {
	profile = mojang.Profile{
		Username:    username,
		ID:          uuid,
		AccessToken: accessToken,
	}
	server = s

	go func() {
		render.LoadTextures()
		initBlocks()
		loadChan <- struct{}{}
	}()

	if profile.IsComplete() && server != "" {
		// Start connecting whilst starting the renderer
		connect()
	} else {
		Client.valid = false
	}

	startWindow()
}

func connect() {
	go startConnection(mojang.Profile{
		Username:    profile.Username,
		ID:          profile.ID,
		AccessToken: profile.AccessToken,
	}, server)
	server = ""
}

func start() {
	<-loadChan
	if Client.valid {
		Client.init()
	} else {
		fakeGen()
		if !profile.IsComplete() {
			setScreen(newLoginScreen())
		} else {
			setScreen(newServerList())
		}
	}
	render.Start()
}

func rotate(x, y float64) {
	Client.Yaw -= x
	Client.Pitch -= y
}

var maxBuilders = runtime.NumCPU() * 2

var (
	ready            bool
	freeBuilders     = maxBuilders
	completeBuilders = make(chan buildPos, maxBuilders)
	syncChan         = make(chan func(), 200)
	ticker           = time.NewTicker(time.Second / 20)
	lastFrame        = time.Now()
)

func draw() {
	now := time.Now()
	diff := now.Sub(lastFrame)
	lastFrame = now
	delta := float64(diff.Nanoseconds()) / (float64(time.Second) / 60)
	delta = math.Min(math.Max(delta, 0.3), 1.6)
handle:
	for {
		select {
		case err := <-errorChan:
			conn.Close()
			fmt.Printf("Disconnected: %s\n", err)
			ready = false
			setScreen(newServerList())
		case packet := <-readChan:
			defaultHandler.Handle(packet)
		case pos := <-completeBuilders:
			c := chunkMap[chunkPosition{pos.X, pos.Z}]
			freeBuilders++
			if c != nil {
				s := c.Sections[pos.Y]
				if s != nil {
					s.building = false
				}
			}
		case f := <-syncChan:
			f()
		default:
			break handle
		}
	}

	width, height := window.GetFramebufferSize()

	if currentScreen != nil {
		currentScreen.tick(delta)
	}

	if ready && Client.valid {
		Client.renderTick(delta)
		select {
		case <-ticker.C:
			tick()
		default:
		}
	} else if !Client.valid {
		render.Camera.Yaw += 0.005
		if render.Camera.Yaw > math.Pi*2 {
			render.Camera.Yaw = 0
		}
	}
	ui.Draw(width, height, delta)

	render.Draw(width, height, delta)
	chunks := sortedChunks()

	// Search for 'dirty' chunk sections and start building
	// them if we have any builders free. To prevent race conditions
	// two flags are used, dirty and building, to allow a second
	// build to be requested whilst the chunk is still building
	// without either losing the change or having two builds
	// for the same section going on at once (where the second
	// could finish quicker causing the old version to be
	// displayed.
dirtyClean:
	for _, c := range chunks {
		for _, s := range c.Sections {
			if s == nil {
				continue
			}
			if freeBuilders <= 0 {
				break dirtyClean
			}
			if s.dirty && !s.building {
				freeBuilders--
				s.dirty = false
				s.building = true
				s.build(completeBuilders)
			}
		}
	}
}

// tick is called 20 times a second (bar any preformance issues).
// Minecraft is built around this fact so we have to follow it
// as well.
func tick() {
	Client.tick()
}
<commit_msg>steven: fix the menu rotation being tied to framerate<commit_after>// Copyright 2015 Matthew Collins
//
// 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 steven

import (
	"fmt"
	"math"
	"runtime"
	"time"

	"github.com/go-gl/glfw/v3.1/glfw"
	"github.com/thinkofdeath/steven/protocol/mojang"
	"github.com/thinkofdeath/steven/render"
	"github.com/thinkofdeath/steven/ui"
)

var (
	profile       mojang.Profile
	server        string
	loadChan      = make(chan struct{})
	currentScreen screen
)

type screen interface {
	tick(delta float64)
	hover(x, y float64, w, h int)
	click(x, y float64, w, h int)
	remove()
}

func setScreen(s screen) {
	if currentScreen != nil {
		currentScreen.remove()
	}
	currentScreen = s
	if s != nil {
		lockMouse = false
		window.SetInputMode(glfw.CursorMode, glfw.CursorNormal)
	}
}

func Main(username, uuid, accessToken, s string) {
	profile = mojang.Profile{
		Username:    username,
		ID:          uuid,
		AccessToken: accessToken,
	}
	server = s

	go func() {
		render.LoadTextures()
		initBlocks()
		loadChan <- struct{}{}
	}()

	if profile.IsComplete() && server != "" {
		// Start connecting whilst starting the renderer
		connect()
	} else {
		Client.valid = false
	}

	startWindow()
}

func connect() {
	go startConnection(mojang.Profile{
		Username:    profile.Username,
		ID:          profile.ID,
		AccessToken: profile.AccessToken,
	}, server)
	server = ""
}

func start() {
	<-loadChan
	if Client.valid {
		Client.init()
	} else {
		fakeGen()
		if !profile.IsComplete() {
			setScreen(newLoginScreen())
		} else {
			setScreen(newServerList())
		}
	}
	render.Start()
}

func rotate(x, y float64) {
	Client.Yaw -= x
	Client.Pitch -= y
}

var maxBuilders = runtime.NumCPU() * 2

var (
	ready            bool
	freeBuilders     = maxBuilders
	completeBuilders = make(chan buildPos, maxBuilders)
	syncChan         = make(chan func(), 200)
	ticker           = time.NewTicker(time.Second / 20)
	lastFrame        = time.Now()
)

func draw() {
	now := time.Now()
	diff := now.Sub(lastFrame)
	lastFrame = now
	delta := float64(diff.Nanoseconds()) / (float64(time.Second) / 60)
	delta = math.Min(delta, 1.6)
handle:
	for {
		select {
		case err := <-errorChan:
			conn.Close()
			fmt.Printf("Disconnected: %s\n", err)
			ready = false
			setScreen(newServerList())
		case packet := <-readChan:
			defaultHandler.Handle(packet)
		case pos := <-completeBuilders:
			c := chunkMap[chunkPosition{pos.X, pos.Z}]
			freeBuilders++
			if c != nil {
				s := c.Sections[pos.Y]
				if s != nil {
					s.building = false
				}
			}
		case f := <-syncChan:
			f()
		default:
			break handle
		}
	}

	width, height := window.GetFramebufferSize()

	if currentScreen != nil {
		currentScreen.tick(delta)
	}

	if ready && Client.valid {
		Client.renderTick(delta)
		select {
		case <-ticker.C:
			tick()
		default:
		}
	} else if !Client.valid {
		render.Camera.Yaw += 0.005 * delta
		if render.Camera.Yaw > math.Pi*2 {
			render.Camera.Yaw = 0
		}
	}
	ui.Draw(width, height, delta)

	render.Draw(width, height, delta)
	chunks := sortedChunks()

	// Search for 'dirty' chunk sections and start building
	// them if we have any builders free. To prevent race conditions
	// two flags are used, dirty and building, to allow a second
	// build to be requested whilst the chunk is still building
	// without either losing the change or having two builds
	// for the same section going on at once (where the second
	// could finish quicker causing the old version to be
	// displayed.
dirtyClean:
	for _, c := range chunks {
		for _, s := range c.Sections {
			if s == nil {
				continue
			}
			if freeBuilders <= 0 {
				break dirtyClean
			}
			if s.dirty && !s.building {
				freeBuilders--
				s.dirty = false
				s.building = true
				s.build(completeBuilders)
			}
		}
	}
}

// tick is called 20 times a second (bar any preformance issues).
// Minecraft is built around this fact so we have to follow it
// as well.
func tick() {
	Client.tick()
}
<|endoftext|>


<commit_before>package tesla

import (
	"bufio"
	"net/http"
	"strconv"
	"strings"
	"time"
)

var (
	StreamParams = "speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power,shift_state,range,est_range,heading"
	StreamingURL = "https://streaming.vn.teslamotors.com"
)

type StreamEvent struct {
	Timestamp  time.Time `json:"timestamp"`
	Speed      int       `json:"speed"`
	Odometer   float64   `json:"odometer"`
	Soc        int       `json:"soc"`
	Elevation  int       `json:"elevation"`
	EstHeading int       `json:"est_heading"`
	EstLat     float64   `json:"est_lat"`
	EstLng     float64   `json:"est_lng"`
	Power      int       `json:"power"`
	ShiftState string    `json:"shift_state"`
	Range      int       `json:"range"`
	EstRange   int       `json:"est_range"`
	Heading    int       `json:"heading"`
}

func (v Vehicle) Stream() (chan *StreamEvent, error) {
	url := StreamingURL + "/stream/" + strconv.Itoa(v.VehicleID) + "/?values=" + StreamParams
	req, _ := http.NewRequest("GET", url, nil)
	req.SetBasicAuth(ActiveClient.Auth.Email, v.Tokens[0])
	resp, err := ActiveClient.HTTP.Do(req)
	if err != nil {
		return nil, err
	}

	eventChan := make(chan *StreamEvent)
	go readStream(resp, eventChan)
	return eventChan, nil
}

func readStream(resp *http.Response, eventChan chan *StreamEvent) {
	reader := bufio.NewReader(resp.Body)
	for {
		line, err := reader.ReadBytes('\n')
		if err != nil {
			eventChan <- nil
			break
		} else {
			streamEvent := parseStreamEvent(string(line))
			eventChan <- streamEvent
		}
	}
}

func parseStreamEvent(event string) *StreamEvent {
	data := strings.Split(event, ",")
	streamEvent := &StreamEvent{}
	timestamp, _ := strconv.ParseInt(data[0], 10, 64)
	streamEvent.Timestamp = time.Unix(0, timestamp*int64(time.Millisecond))
	streamEvent.Speed, _ = strconv.Atoi(data[1])
	streamEvent.Odometer, _ = strconv.ParseFloat(data[2], 64)
	streamEvent.Soc, _ = strconv.Atoi(data[3])
	streamEvent.Elevation, _ = strconv.Atoi(data[4])
	streamEvent.EstHeading, _ = strconv.Atoi(data[5])
	streamEvent.EstLat, _ = strconv.ParseFloat(data[6], 64)
	streamEvent.EstLng, _ = strconv.ParseFloat(data[7], 64)
	streamEvent.Power, _ = strconv.Atoi(data[8])
	streamEvent.ShiftState = data[9]
	streamEvent.Range, _ = strconv.Atoi(data[10])
	streamEvent.EstRange, _ = strconv.Atoi(data[11])
	streamEvent.Heading, _ = strconv.Atoi(data[12])
	return streamEvent
}
<commit_msg>Added more comments for the auto generated docs<commit_after>package tesla

import (
	"bufio"
	"net/http"
	"strconv"
	"strings"
	"time"
)

var (
	StreamParams = "speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power,shift_state,range,est_range,heading"
	StreamingURL = "https://streaming.vn.teslamotors.com"
)

// The event returned by the vehicle by the Tesla API
type StreamEvent struct {
	Timestamp  time.Time `json:"timestamp"`
	Speed      int       `json:"speed"`
	Odometer   float64   `json:"odometer"`
	Soc        int       `json:"soc"`
	Elevation  int       `json:"elevation"`
	EstHeading int       `json:"est_heading"`
	EstLat     float64   `json:"est_lat"`
	EstLng     float64   `json:"est_lng"`
	Power      int       `json:"power"`
	ShiftState string    `json:"shift_state"`
	Range      int       `json:"range"`
	EstRange   int       `json:"est_range"`
	Heading    int       `json:"heading"`
}

// Requests a stream from the vehicle and returns a Go channel
func (v Vehicle) Stream() (chan *StreamEvent, error) {
	url := StreamingURL + "/stream/" + strconv.Itoa(v.VehicleID) + "/?values=" + StreamParams
	req, _ := http.NewRequest("GET", url, nil)
	req.SetBasicAuth(ActiveClient.Auth.Email, v.Tokens[0])
	resp, err := ActiveClient.HTTP.Do(req)
	if err != nil {
		return nil, err
	}

	eventChan := make(chan *StreamEvent)
	go readStream(resp, eventChan)
	return eventChan, nil
}

// Reads the stream itself from the vehicle
func readStream(resp *http.Response, eventChan chan *StreamEvent) {
	reader := bufio.NewReader(resp.Body)
	for {
		line, err := reader.ReadBytes('\n')
		if err != nil {
			eventChan <- nil
			break
		} else {
			streamEvent := parseStreamEvent(string(line))
			eventChan <- streamEvent
		}
	}
}

// Parses the stream event, setting all of the appropriate data types
func parseStreamEvent(event string) *StreamEvent {
	data := strings.Split(event, ",")
	streamEvent := &StreamEvent{}
	timestamp, _ := strconv.ParseInt(data[0], 10, 64)
	streamEvent.Timestamp = time.Unix(0, timestamp*int64(time.Millisecond))
	streamEvent.Speed, _ = strconv.Atoi(data[1])
	streamEvent.Odometer, _ = strconv.ParseFloat(data[2], 64)
	streamEvent.Soc, _ = strconv.Atoi(data[3])
	streamEvent.Elevation, _ = strconv.Atoi(data[4])
	streamEvent.EstHeading, _ = strconv.Atoi(data[5])
	streamEvent.EstLat, _ = strconv.ParseFloat(data[6], 64)
	streamEvent.EstLng, _ = strconv.ParseFloat(data[7], 64)
	streamEvent.Power, _ = strconv.Atoi(data[8])
	streamEvent.ShiftState = data[9]
	streamEvent.Range, _ = strconv.Atoi(data[10])
	streamEvent.EstRange, _ = strconv.Atoi(data[11])
	streamEvent.Heading, _ = strconv.Atoi(data[12])
	return streamEvent
}
<|endoftext|>


<commit_before>package muta

import "errors"

type Stream struct {
	Streamers []Streamer
}

func (s *Stream) Pipe(f Streamer) *Stream {
	s.Streamers = append(s.Streamers, f)
	return s
}

func (s *Stream) Start() {
	for i, fn := range s.Streamers {
		// In the near future, we need to check for errors returned by
		// the Streamer. Ignoring them for now.
		s.startGenerator(fn, s.Streamers[i+1:])
	}
}

func (s *Stream) startGenerator(generator Streamer,
	receivers []Streamer) (err error) {
	for true {
		genFi, genChunk, err := generator(nil, nil)
		if err != nil {
			return err
		}

		// Generator signalled EOS
		if genFi == nil {
			return nil
		}

		var fi *FileInfo
		var chunk []byte
		var streamed bool

		var fn Streamer
		for i := 0; i < len(receivers); i++ {
			if i == 0 {
				fi = genFi
				chunk = genChunk
				streamed = false
			}

			fn = receivers[i]
			fi, chunk, err = fn(fi, chunk)
			if err != nil {
				return err
			}

			// If any receiver streamed data, set streamed = true
			if chunk != nil {
				streamed = true
			}

			// Receiver signaled EOS
			if fi == nil {
				if streamed && genChunk == nil {
					// If any Receiver returned any data, we need to repeat
					// the stream until they all (up until EOS atleast) return
					// EOF
					// Repeat the stream
					i = -1
					continue
				} else if chunk == nil || genChunk != nil {
					// chunk == nil:
					// Receiver signaled EOS and EOF
					//
					// genChunk != nil
					// Receiver signaled EOS but not EOF, **and** the Generator
					// is not signaling EOF (ie, it's still streaming) data.
					// Repeating here would be bad, since it would repeat
					// the generator data.
					//
					// Stop the stream
					break
				} else {
					// Receiver signaled EOS and but not EOF
					// Repeat the stream
					i = -1
					continue
				}
			}

			// For now, if the receiver returns a different file than the
			// generator, error out. We're not yet supporting receiver->gen
			// converting.
			if fi != genFi {
				return errors.New("Receivers turning into Generators is not " +
					"yet implemented")
			}
		}
	}
	return nil
}

func Src(srcs ...string) *Stream {
	s := &Stream{}
	return s.Pipe(SrcStreamer(srcs, SrcOpts{}))
}
<commit_msg>Added small todo<commit_after>package muta

import "errors"

type Stream struct {
	Streamers []Streamer
}

func (s *Stream) Pipe(f Streamer) *Stream {
	s.Streamers = append(s.Streamers, f)
	return s
}

func (s *Stream) Start() {
	for i, fn := range s.Streamers {
		// In the near future, we need to check for errors returned by
		// the Streamer. Ignoring them for now.
		s.startGenerator(fn, s.Streamers[i+1:])
	}
}

// TODO: Split this function into smaller logical sections, for ease
// of debugging
func (s *Stream) startGenerator(generator Streamer,
	receivers []Streamer) (err error) {
	for true {
		genFi, genChunk, err := generator(nil, nil)
		if err != nil {
			return err
		}

		// Generator signalled EOS
		if genFi == nil {
			return nil
		}

		var fi *FileInfo
		var chunk []byte
		var streamed bool

		var fn Streamer
		for i := 0; i < len(receivers); i++ {
			if i == 0 {
				fi = genFi
				chunk = genChunk
				streamed = false
			}

			fn = receivers[i]
			fi, chunk, err = fn(fi, chunk)
			if err != nil {
				return err
			}

			// If any receiver streamed data, set streamed = true
			if chunk != nil {
				streamed = true
			}

			// Receiver signaled EOS
			if fi == nil {
				if streamed && genChunk == nil {
					// If any Receiver returned any data, we need to repeat
					// the stream until they all (up until EOS atleast) return
					// EOF
					// Repeat the stream
					i = -1
					continue
				} else if chunk == nil || genChunk != nil {
					// chunk == nil:
					// Receiver signaled EOS and EOF
					//
					// genChunk != nil
					// Receiver signaled EOS but not EOF, **and** the Generator
					// is not signaling EOF (ie, it's still streaming) data.
					// Repeating here would be bad, since it would repeat
					// the generator data.
					//
					// Stop the stream
					break
				} else {
					// Receiver signaled EOS and but not EOF
					// Repeat the stream
					i = -1
					continue
				}
			}

			// For now, if the receiver returns a different file than the
			// generator, error out. We're not yet supporting receiver->gen
			// converting.
			if fi != genFi {
				return errors.New("Receivers turning into Generators is not " +
					"yet implemented")
			}
		}
	}
	return nil
}

func Src(srcs ...string) *Stream {
	s := &Stream{}
	return s.Pipe(SrcStreamer(srcs, SrcOpts{}))
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"github.com/gophergala2016/goad/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws"
	"github.com/gophergala2016/goad/queue"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"
)

func main() {
	address := os.Args[1]
	concurrencycount, err := strconv.Atoi(os.Args[2])
	if err != nil {
		fmt.Printf("Error reading concurrency level: %s\n", err)
		return
	}
	maxRequestCount, err := strconv.Atoi(os.Args[3])
	sqsurl := os.Args[4]
	awsregion := os.Args[5]
	clientTimeout, _ := time.ParseDuration("1s")
	if len(os.Args) > 6 {
		newClientTimeout, err := time.ParseDuration(os.Args[6])
		if err == nil {
			clientTimeout = newClientTimeout
		} else {
			fmt.Printf("Error parsing timeout: %s\n", err)
			return
		}
	}
	fmt.Printf("Using a timeout of %s\n", clientTimeout)
	reportingFrequency, _ := time.ParseDuration("1s")
	if len(os.Args) > 7 {
		newReportingFrequency, err := time.ParseDuration(os.Args[7])
		if err == nil {
			reportingFrequency = newReportingFrequency
		} else {
			fmt.Printf("Error parsing reporting frequency: %s\n", err)
			return
		}
	}
	fmt.Printf("Using a reporting frequency of %s\n", reportingFrequency)

	client := &http.Client{}
	client.Timeout = clientTimeout
	client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
		return errors.New("redirect")
	}
	fmt.Printf("Will spawn %d workers making %d requests to %s\n", concurrencycount, maxRequestCount, address)
	runLoadTest(client, sqsurl, address, maxRequestCount, concurrencycount, awsregion, reportingFrequency)
}

type RequestResult struct {
	Time             int64  `json:"time"`
	Host             string `json:"host"`
	Type             string `json:"type"`
	Status           int    `json:"status"`
	ElapsedFirstByte int64  `json:"elapsed-first-byte"`
	ElapsedLastByte  int64  `json:"elapsed-last-byte"`
	Elapsed          int64  `json:"elapsed"`
	Bytes            int    `json:"bytes"`
	Timeout          bool   `json:"timeout"`
	ConnectionError  bool   `json:"connection-error"`
	State            string `json:"state"`
}

func runLoadTest(client *http.Client, sqsurl string, url string, totalRequests int, concurrencycount int, awsregion string, reportingFrequency time.Duration) {
	awsConfig := aws.NewConfig().WithRegion(awsregion)
	sqsAdaptor := queue.NewSQSAdaptor(awsConfig, sqsurl)
	//sqsAdaptor := queue.NewDummyAdaptor(sqsurl)
	jobs := make(chan struct{}, totalRequests)
	ch := make(chan RequestResult, totalRequests)
	var wg sync.WaitGroup
	loadTestStartTime := time.Now()
	var requestsSoFar int
	for i := 0; i < totalRequests; i++ {
		jobs <- struct{}{}
	}
	close(jobs)
	fmt.Print("Spawning workers…")
	for i := 0; i < concurrencycount; i++ {
		wg.Add(1)
		go fetch(loadTestStartTime, client, url, totalRequests, jobs, ch, &wg, awsregion)
		fmt.Print(".")
	}
	fmt.Println(" done.\nWaiting for results…")

	ticker := time.NewTicker(reportingFrequency)
	quit := make(chan struct{})
	quitting := false

	for requestsSoFar < totalRequests && !quitting {
		i := 0

		var timeToFirstTotal int64
		var requestTimeTotal int64
		totBytesRead := 0
		statuses := make(map[string]int)
		var firstRequestTime int64
		var lastRequestTime int64
		var slowest int64
		var fastest int64
		var totalTimedOut int
		var totalConnectionError int

		resetStats := false
		for requestsSoFar < totalRequests && !quitting && !resetStats {
			aggregate := false
			select {
			case r := <-ch:
				i++
				requestsSoFar++
				if requestsSoFar%10 == 0 || requestsSoFar == totalRequests {
					fmt.Printf("\r%.2f%% done (%d requests out of %d)", (float64(requestsSoFar)/float64(totalRequests))*100.0, requestsSoFar, totalRequests)
				}
				if firstRequestTime == 0 {
					firstRequestTime = r.Time
				}

				lastRequestTime = r.Time

				if r.Timeout {
					totalTimedOut++
					continue
				}
				if r.ConnectionError {
					totalConnectionError++
					continue
				}

				if r.ElapsedLastByte > slowest {
					slowest = r.ElapsedLastByte
				}
				if fastest == 0 {
					fastest = r.ElapsedLastByte
				} else {
					if r.ElapsedLastByte < fastest {
						fastest = r.ElapsedLastByte
					}
				}

				timeToFirstTotal += r.ElapsedFirstByte
				totBytesRead += r.Bytes
				statusStr := strconv.Itoa(r.Status)
				_, ok := statuses[statusStr]
				if !ok {
					statuses[statusStr] = 1
				} else {
					statuses[statusStr]++
				}
				requestTimeTotal += r.Elapsed
				if requestsSoFar == totalRequests {
					quitting = true
				}
			case <-ticker.C:
				if i == 0 {
					continue
				}
				aggregate = true
			case <-quit:
				ticker.Stop()
				quitting = true
			}
			if aggregate || quitting {
				durationNanoSeconds := lastRequestTime - firstRequestTime
				durationSeconds := float32(durationNanoSeconds) / float32(1000000000)
				fatalError := ""
				if (totalTimedOut + totalConnectionError) > i/2 {
					fatalError = "Over 50% of requests failed, aborting"
					quitting = true
				}
				aggData := queue.AggData{
					i,
					totalTimedOut,
					totalConnectionError,
					timeToFirstTotal / int64(i),
					totBytesRead,
					statuses,
					requestTimeTotal / int64(i),
					float32(i) / durationSeconds,
					(float32(totBytesRead) / durationSeconds) / 1024.0,
					slowest,
					fastest,
					awsregion,
					fatalError,
				}
				sqsAdaptor.SendResult(aggData)
				resetStats = true
			}
		}
	}
	fmt.Printf("\nYay🎈  - %d requests completed\n", requestsSoFar)

}

func fetch(loadTestStartTime time.Time, client *http.Client, address string, requestcount int, jobs <-chan struct{}, ch chan RequestResult, wg *sync.WaitGroup, awsregion string) {
	defer wg.Done()
	for _ = range jobs {
		start := time.Now()
		req, err := http.NewRequest("GET", address, nil)
		req.Header.Add("User-Agent", "Mozilla/5.0 (compatible; Goad/1.0; +https://goad.io)")
		req.Header.Add("Accept-Encoding", "gzip")
		response, err := client.Do(req)
		var status string
		var elapsedFirstByte time.Duration
		var elapsedLastByte time.Duration
		var elapsed time.Duration
		var statusCode int
		var bytesRead int
		buf := []byte(" ")
		timedOut := false
		connectionError := false
		if err != nil && !strings.Contains(err.Error(), "redirect") {
			status = fmt.Sprintf("ERROR: %s\n", err)
			switch err := err.(type) {
			case *url.Error:
				if err, ok := err.Err.(net.Error); ok && err.Timeout() {
					timedOut = true
				}
			case net.Error:
				if err.Timeout() {
					timedOut = true
				}
			}

			if !timedOut {
				connectionError = true
			}
		} else {
			statusCode = response.StatusCode
			_, err = response.Body.Read(buf)
			firstByteRead := true
			if err != nil {
				status = fmt.Sprintf("reading first byte failed: %s\n", err)
				firstByteRead = false
			}
			elapsedFirstByte = time.Since(start)
			body, err := ioutil.ReadAll(response.Body)
			response.Body.Close()
			if firstByteRead {
				bytesRead = len(body) + 1
			}
			elapsedLastByte = time.Since(start)
			if err != nil {
				status = fmt.Sprintf("reading response body failed: %s\n", err)
			} else {
				status = "Success"
			}
			elapsed = time.Since(start)
		}
		result := RequestResult{
			start.Sub(loadTestStartTime).Nanoseconds(),
			req.URL.Host,
			req.Method,
			statusCode,
			elapsed.Nanoseconds(),
			elapsedFirstByte.Nanoseconds(),
			elapsedLastByte.Nanoseconds(),
			bytesRead,
			timedOut,
			connectionError,
			status,
		}
		ch <- result
	}
}
<commit_msg>Don’t try to count average if duration is zero<commit_after>package main

import (
	"errors"
	"fmt"
	"github.com/gophergala2016/goad/Godeps/_workspace/src/github.com/aws/aws-sdk-go/aws"
	"github.com/gophergala2016/goad/queue"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"
)

func main() {
	address := os.Args[1]
	concurrencycount, err := strconv.Atoi(os.Args[2])
	if err != nil {
		fmt.Printf("Error reading concurrency level: %s\n", err)
		return
	}
	maxRequestCount, err := strconv.Atoi(os.Args[3])
	sqsurl := os.Args[4]
	awsregion := os.Args[5]
	clientTimeout, _ := time.ParseDuration("1s")
	if len(os.Args) > 6 {
		newClientTimeout, err := time.ParseDuration(os.Args[6])
		if err == nil {
			clientTimeout = newClientTimeout
		} else {
			fmt.Printf("Error parsing timeout: %s\n", err)
			return
		}
	}
	fmt.Printf("Using a timeout of %s\n", clientTimeout)
	reportingFrequency, _ := time.ParseDuration("1s")
	if len(os.Args) > 7 {
		newReportingFrequency, err := time.ParseDuration(os.Args[7])
		if err == nil {
			reportingFrequency = newReportingFrequency
		} else {
			fmt.Printf("Error parsing reporting frequency: %s\n", err)
			return
		}
	}
	fmt.Printf("Using a reporting frequency of %s\n", reportingFrequency)

	client := &http.Client{}
	client.Timeout = clientTimeout
	client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
		return errors.New("redirect")
	}
	fmt.Printf("Will spawn %d workers making %d requests to %s\n", concurrencycount, maxRequestCount, address)
	runLoadTest(client, sqsurl, address, maxRequestCount, concurrencycount, awsregion, reportingFrequency)
}

type RequestResult struct {
	Time             int64  `json:"time"`
	Host             string `json:"host"`
	Type             string `json:"type"`
	Status           int    `json:"status"`
	ElapsedFirstByte int64  `json:"elapsed-first-byte"`
	ElapsedLastByte  int64  `json:"elapsed-last-byte"`
	Elapsed          int64  `json:"elapsed"`
	Bytes            int    `json:"bytes"`
	Timeout          bool   `json:"timeout"`
	ConnectionError  bool   `json:"connection-error"`
	State            string `json:"state"`
}

func runLoadTest(client *http.Client, sqsurl string, url string, totalRequests int, concurrencycount int, awsregion string, reportingFrequency time.Duration) {
	awsConfig := aws.NewConfig().WithRegion(awsregion)
	sqsAdaptor := queue.NewSQSAdaptor(awsConfig, sqsurl)
	//sqsAdaptor := queue.NewDummyAdaptor(sqsurl)
	jobs := make(chan struct{}, totalRequests)
	ch := make(chan RequestResult, totalRequests)
	var wg sync.WaitGroup
	loadTestStartTime := time.Now()
	var requestsSoFar int
	for i := 0; i < totalRequests; i++ {
		jobs <- struct{}{}
	}
	close(jobs)
	fmt.Print("Spawning workers…")
	for i := 0; i < concurrencycount; i++ {
		wg.Add(1)
		go fetch(loadTestStartTime, client, url, totalRequests, jobs, ch, &wg, awsregion)
		fmt.Print(".")
	}
	fmt.Println(" done.\nWaiting for results…")

	ticker := time.NewTicker(reportingFrequency)
	quit := make(chan struct{})
	quitting := false

	for requestsSoFar < totalRequests && !quitting {
		i := 0

		var timeToFirstTotal int64
		var requestTimeTotal int64
		totBytesRead := 0
		statuses := make(map[string]int)
		var firstRequestTime int64
		var lastRequestTime int64
		var slowest int64
		var fastest int64
		var totalTimedOut int
		var totalConnectionError int

		resetStats := false
		for requestsSoFar < totalRequests && !quitting && !resetStats {
			aggregate := false
			select {
			case r := <-ch:
				i++
				requestsSoFar++
				if requestsSoFar%10 == 0 || requestsSoFar == totalRequests {
					fmt.Printf("\r%.2f%% done (%d requests out of %d)", (float64(requestsSoFar)/float64(totalRequests))*100.0, requestsSoFar, totalRequests)
				}
				if firstRequestTime == 0 {
					firstRequestTime = r.Time
				}

				lastRequestTime = r.Time

				if r.Timeout {
					totalTimedOut++
					continue
				}
				if r.ConnectionError {
					totalConnectionError++
					continue
				}

				if r.ElapsedLastByte > slowest {
					slowest = r.ElapsedLastByte
				}
				if fastest == 0 {
					fastest = r.ElapsedLastByte
				} else {
					if r.ElapsedLastByte < fastest {
						fastest = r.ElapsedLastByte
					}
				}

				timeToFirstTotal += r.ElapsedFirstByte
				totBytesRead += r.Bytes
				statusStr := strconv.Itoa(r.Status)
				_, ok := statuses[statusStr]
				if !ok {
					statuses[statusStr] = 1
				} else {
					statuses[statusStr]++
				}
				requestTimeTotal += r.Elapsed
				if requestsSoFar == totalRequests {
					quitting = true
				}
			case <-ticker.C:
				if i == 0 {
					continue
				}
				aggregate = true
			case <-quit:
				ticker.Stop()
				quitting = true
			}
			if aggregate || quitting {
				durationNanoSeconds := lastRequestTime - firstRequestTime
				durationSeconds := float32(durationNanoSeconds) / float32(1000000000)
				var reqPerSec float32
				var kbPerSec float32
				if durationSeconds > 0 {
					reqPerSec = float32(i) / durationSeconds
					kbPerSec = (float32(totBytesRead) / durationSeconds) / 1024.0
				} else {
					reqPerSec = 0
					kbPerSec = 0
				}

				fatalError := ""
				if (totalTimedOut + totalConnectionError) > i/2 {
					fatalError = "Over 50% of requests failed, aborting"
					quitting = true
				}
				aggData := queue.AggData{
					i,
					totalTimedOut,
					totalConnectionError,
					timeToFirstTotal / int64(i),
					totBytesRead,
					statuses,
					requestTimeTotal / int64(i),
					reqPerSec,
					kbPerSec,
					slowest,
					fastest,
					awsregion,
					fatalError,
				}
				sqsAdaptor.SendResult(aggData)
				resetStats = true
			}
		}
	}
	fmt.Printf("\nYay🎈  - %d requests completed\n", requestsSoFar)

}

func fetch(loadTestStartTime time.Time, client *http.Client, address string, requestcount int, jobs <-chan struct{}, ch chan RequestResult, wg *sync.WaitGroup, awsregion string) {
	defer wg.Done()
	for _ = range jobs {
		start := time.Now()
		req, err := http.NewRequest("GET", address, nil)
		req.Header.Add("User-Agent", "Mozilla/5.0 (compatible; Goad/1.0; +https://goad.io)")
		req.Header.Add("Accept-Encoding", "gzip")
		response, err := client.Do(req)
		var status string
		var elapsedFirstByte time.Duration
		var elapsedLastByte time.Duration
		var elapsed time.Duration
		var statusCode int
		var bytesRead int
		buf := []byte(" ")
		timedOut := false
		connectionError := false
		if err != nil && !strings.Contains(err.Error(), "redirect") {
			status = fmt.Sprintf("ERROR: %s\n", err)
			switch err := err.(type) {
			case *url.Error:
				if err, ok := err.Err.(net.Error); ok && err.Timeout() {
					timedOut = true
				}
			case net.Error:
				if err.Timeout() {
					timedOut = true
				}
			}

			if !timedOut {
				connectionError = true
			}
		} else {
			statusCode = response.StatusCode
			elapsedFirstByte = time.Since(start)
			_, err = response.Body.Read(buf)
			firstByteRead := true
			if err != nil {
				status = fmt.Sprintf("reading first byte failed: %s\n", err)
				firstByteRead = false
			}
			body, err := ioutil.ReadAll(response.Body)
			response.Body.Close()
			if firstByteRead {
				bytesRead = len(body) + 1
			}
			elapsedLastByte = time.Since(start)
			if err != nil {
				// todo: detect timeout here as well
				status = fmt.Sprintf("reading response body failed: %s\n", err)
				connectionError = true
			} else {
				status = "Success"
			}
			elapsed = time.Since(start)
		}
		//fmt.Printf("Request end: %d, elapsed: %d\n", time.Now().Sub(loadTestStartTime).Nanoseconds(), elapsed.Nanoseconds())
		result := RequestResult{
			start.Sub(loadTestStartTime).Nanoseconds(),
			req.URL.Host,
			req.Method,
			statusCode,
			elapsed.Nanoseconds(),
			elapsedFirstByte.Nanoseconds(),
			elapsedLastByte.Nanoseconds(),
			bytesRead,
			timedOut,
			connectionError,
			status,
		}
		ch <- result
	}
}
<|endoftext|>


<commit_before>package main

import (
	"cf"
	"cf/api"
	"cf/app"
	"cf/commands"
	"cf/configuration"
	"cf/manifest"
	"cf/net"
	"cf/requirements"
	"cf/terminal"
	"fileutils"
	"fmt"
	"github.com/codegangsta/cli"
	"os"
	"runtime/debug"
	"strings"
)

func main() {
	defer func() {
		maybeSomething := recover()

		if maybeSomething != nil {
			displayCrashDialog()
		}
	}()

	fileutils.SetTmpPathPrefix("cf")

	if os.Getenv("CF_COLOR") == "" {
		os.Setenv("CF_COLOR", "true")
	}

	termUI := terminal.NewUI()
	configRepo := configuration.NewConfigurationDiskRepository()
	config := loadConfig(termUI, configRepo)
	manifestRepo := manifest.NewManifestDiskRepository()
	repoLocator := api.NewRepositoryLocator(config, configRepo, map[string]net.Gateway{
		"auth":             net.NewUAAGateway(),
		"cloud-controller": net.NewCloudControllerGateway(),
		"curl": 			net.NewCurlGateway(),
		"uaa":              net.NewUAAGateway(),
	})

	cmdFactory := commands.NewFactory(termUI, config, configRepo, manifestRepo, repoLocator)
	reqFactory := requirements.NewFactory(termUI, config, repoLocator)
	cmdRunner := commands.NewRunner(cmdFactory, reqFactory)

	app, err := app.NewApp(cmdRunner)
	if err != nil {
		return
	}
	app.Run(os.Args)
}

func init() {
	cli.AppHelpTemplate = `NAME:
   {{.Name}} - {{.Usage}}

USAGE:
   [environment variables] {{.Name}} [global options] command [arguments...] [command options]

VERSION:
   {{.Version}}

COMMANDS:
   {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Description}}
   {{end}}
GLOBAL OPTIONS:
   {{range .Flags}}{{.}}
   {{end}}
ENVIRONMENT VARIABLES:
   CF_TRACE=true - will output HTTP requests and responses during command
   HTTP_PROXY=http://proxy.example.com:8080 - set to your proxy
`

	cli.CommandHelpTemplate = `NAME:
   {{.Name}} - {{.Description}}
{{with .ShortName}}
ALIAS:
   {{.}}
{{end}}
USAGE:
   {{.Usage}}{{with .Flags}}

OPTIONS:
   {{range .}}{{.}}
   {{end}}{{else}}
{{end}}`

}

func loadConfig(termUI terminal.UI, configRepo configuration.ConfigurationRepository) (config *configuration.Configuration) {
	config, err := configRepo.Get()
	if err != nil {
		termUI.Failed(fmt.Sprintf(
			"Error loading config. Please reset target (%s) and log in (%s).",
			terminal.CommandColor(fmt.Sprintf("%s target", cf.Name())),
			terminal.CommandColor(fmt.Sprintf("%s login", cf.Name())),
		))
		configRepo.Delete()
		os.Exit(1)
		return
	}
	return
}

func displayCrashDialog() {
	formattedString := `

       d8888 888       888 888       888        .d8888b.  888    888 888     888  .d8888b.  888    d8P   .d8888b.
      d88888 888   o   888 888   o   888       d88P  Y88b 888    888 888     888 d88P  Y88b 888   d8P   d88P  Y88b
     d88P888 888  d8b  888 888  d8b  888       Y88b.      888    888 888     888 888    888 888  d8P    Y88b.
    d88P 888 888 d888b 888 888 d888b 888        "Y888b.   8888888888 888     888 888        888d88K      "Y888b.
   d88P  888 888d88888b888 888d88888b888           "Y88b. 888    888 888     888 888        8888888b        "Y88b.
  d88P   888 88888P Y88888 88888P Y88888             "888 888    888 888     888 888    888 888  Y88b         "888
 d8888888888 8888P   Y8888 8888P   Y8888       Y88b  d88P 888    888 Y88b. .d88P Y88b  d88P 888   Y88b  Y88b  d88P d8b
d88P     888 888P     Y888 888P     Y888        "Y8888P"  888    888  "Y88888P"   "Y8888P"  888    Y88b  "Y8888P"  Y8P

Something completely unexpected happened. This is a bug in %s.
Please file this bug : https://github.com/cloudfoundry/cli/issues
Tell us that you ran this command:

	%s

and got this stack trace:

%s
	`

	stackTrace := "\t" + strings.Replace(string(debug.Stack()), "\n", "\n\t", -1)
	println(fmt.Sprintf(formattedString, cf.Name(), strings.Join(os.Args, " "), stackTrace))
	os.Exit(1)
}
<commit_msg>add help for CF_COLOR env var<commit_after>package main

import (
	"cf"
	"cf/api"
	"cf/app"
	"cf/commands"
	"cf/configuration"
	"cf/manifest"
	"cf/net"
	"cf/requirements"
	"cf/terminal"
	"fileutils"
	"fmt"
	"github.com/codegangsta/cli"
	"os"
	"runtime/debug"
	"strings"
)

func main() {
	defer func() {
		maybeSomething := recover()

		if maybeSomething != nil {
			displayCrashDialog()
		}
	}()

	fileutils.SetTmpPathPrefix("cf")

	if os.Getenv("CF_COLOR") == "" {
		os.Setenv("CF_COLOR", "true")
	}

	termUI := terminal.NewUI()
	configRepo := configuration.NewConfigurationDiskRepository()
	config := loadConfig(termUI, configRepo)
	manifestRepo := manifest.NewManifestDiskRepository()
	repoLocator := api.NewRepositoryLocator(config, configRepo, map[string]net.Gateway{
		"auth":             net.NewUAAGateway(),
		"cloud-controller": net.NewCloudControllerGateway(),
		"curl": 			net.NewCurlGateway(),
		"uaa":              net.NewUAAGateway(),
	})

	cmdFactory := commands.NewFactory(termUI, config, configRepo, manifestRepo, repoLocator)
	reqFactory := requirements.NewFactory(termUI, config, repoLocator)
	cmdRunner := commands.NewRunner(cmdFactory, reqFactory)

	app, err := app.NewApp(cmdRunner)
	if err != nil {
		return
	}
	app.Run(os.Args)
}

func init() {
	cli.AppHelpTemplate = `NAME:
   {{.Name}} - {{.Usage}}

USAGE:
   [environment variables] {{.Name}} [global options] command [arguments...] [command options]

VERSION:
   {{.Version}}

COMMANDS:
   {{range .Commands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Description}}
   {{end}}
GLOBAL OPTIONS:
   {{range .Flags}}{{.}}
   {{end}}
ENVIRONMENT VARIABLES:
   CF_TRACE=true - will output HTTP requests and responses during command
   CF_COLOR=false - will not colorize output
   HTTP_PROXY=http://proxy.example.com:8080 - set to your proxy
`

	cli.CommandHelpTemplate = `NAME:
   {{.Name}} - {{.Description}}
{{with .ShortName}}
ALIAS:
   {{.}}
{{end}}
USAGE:
   {{.Usage}}{{with .Flags}}

OPTIONS:
   {{range .}}{{.}}
   {{end}}{{else}}
{{end}}`

}

func loadConfig(termUI terminal.UI, configRepo configuration.ConfigurationRepository) (config *configuration.Configuration) {
	config, err := configRepo.Get()
	if err != nil {
		termUI.Failed(fmt.Sprintf(
			"Error loading config. Please reset target (%s) and log in (%s).",
			terminal.CommandColor(fmt.Sprintf("%s target", cf.Name())),
			terminal.CommandColor(fmt.Sprintf("%s login", cf.Name())),
		))
		configRepo.Delete()
		os.Exit(1)
		return
	}
	return
}

func displayCrashDialog() {
	formattedString := `

Aww shucks.

Something completely unexpected happened. This is a bug in %s.
Please file this bug : https://github.com/cloudfoundry/cli/issues
Tell us that you ran this command:

	%s

and got this stack trace:

%s
	`

	stackTrace := "\t" + strings.Replace(string(debug.Stack()), "\n", "\n\t", -1)
	println(fmt.Sprintf(formattedString, cf.Name(), strings.Join(os.Args, " "), stackTrace))
	os.Exit(1)
}
<|endoftext|>


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

// +build windows

package winfsnotify

import (
	"os"
	"testing"
	"time"
)

func expect(t *testing.T, eventstream <-chan *Event, name string, mask uint32) {
	t.Logf(`expected: "%s": 0x%x`, name, mask)
	select {
	case event := <-eventstream:
		if event == nil {
			t.Fatal("nil event received")
		}
		t.Logf("received: %s", event)
		if event.Name != name || event.Mask != mask {
			t.Fatal("did not receive expected event")
		}
	case <-time.After(1 * time.Second):
		t.Fatal("timed out waiting for event")
	}
}

func TestNotifyEvents(t *testing.T) {
	watcher, err := NewWatcher()
	if err != nil {
		t.Fatalf("NewWatcher() failed: %s", err)
	}

	testDir := "TestNotifyEvents.testdirectory"
	testFile := testDir + "/TestNotifyEvents.testfile"
	testFile2 := testFile + ".new"
	const mask = FS_ALL_EVENTS & ^(FS_ATTRIB|FS_CLOSE) | FS_IGNORED

	// Add a watch for testDir
	os.RemoveAll(testDir)
	if err = os.Mkdir(testDir, 0777); err != nil {
		t.Fatalf("Failed to create test directory: %s", err)
	}
	defer os.RemoveAll(testDir)
	err = watcher.AddWatch(testDir, mask)
	if err != nil {
		t.Fatalf("Watcher.Watch() failed: %s", err)
	}

	// Receive errors on the error channel on a separate goroutine
	go func() {
		for err := range watcher.Error {
			t.Fatalf("error received: %s", err)
		}
	}()

	// Create a file
	file, err := os.Create(testFile)
	if err != nil {
		t.Fatalf("creating test file failed: %s", err)
	}
	expect(t, watcher.Event, testFile, FS_CREATE)

	err = watcher.AddWatch(testFile, mask)
	if err != nil {
		t.Fatalf("Watcher.Watch() failed: %s", err)
	}

	if _, err = file.WriteString("hello, world"); err != nil {
		t.Fatalf("failed to write to test file: %s", err)
	}
	if err = file.Close(); err != nil {
		t.Fatalf("failed to close test file: %s", err)
	}
	expect(t, watcher.Event, testFile, FS_MODIFY)
	expect(t, watcher.Event, testFile, FS_MODIFY)

	if err = os.Rename(testFile, testFile2); err != nil {
		t.Fatalf("failed to rename test file: %s", err)
	}
	expect(t, watcher.Event, testFile, FS_MOVED_FROM)
	expect(t, watcher.Event, testFile2, FS_MOVED_TO)
	expect(t, watcher.Event, testFile, FS_MOVE_SELF)

	if err = os.RemoveAll(testDir); err != nil {
		t.Fatalf("failed to remove test directory: %s", err)
	}
	expect(t, watcher.Event, testFile2, FS_DELETE_SELF)
	expect(t, watcher.Event, testFile2, FS_IGNORED)
	expect(t, watcher.Event, testFile2, FS_DELETE)
	expect(t, watcher.Event, testDir, FS_DELETE_SELF)
	expect(t, watcher.Event, testDir, FS_IGNORED)

	t.Log("calling Close()")
	if err = watcher.Close(); err != nil {
		t.Fatalf("failed to close watcher: %s", err)
	}
}

func TestNotifyClose(t *testing.T) {
	watcher, _ := NewWatcher()
	watcher.Close()

	done := false
	go func() {
		watcher.Close()
		done = true
	}()

	time.Sleep(50 * time.Millisecond)
	if !done {
		t.Fatal("double Close() test failed: second Close() call didn't return")
	}

	dir, err := ioutil.TempDir("", "wininotify")
	if err != nil {
		t.Fatalf("TempDir failed: %s", err)
	}
	defer os.RemoveAll(dir)

	err = watcher.Watch(dir)
	if err == nil {
		t.Fatal("expected error on Watch() after Close(), got nil")
	}
}
<commit_msg>windows: fix build<commit_after>// Copyright 2011 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.

// +build windows

package winfsnotify

import (
	"io/ioutil"
	"os"
	"testing"
	"time"
)

func expect(t *testing.T, eventstream <-chan *Event, name string, mask uint32) {
	t.Logf(`expected: "%s": 0x%x`, name, mask)
	select {
	case event := <-eventstream:
		if event == nil {
			t.Fatal("nil event received")
		}
		t.Logf("received: %s", event)
		if event.Name != name || event.Mask != mask {
			t.Fatal("did not receive expected event")
		}
	case <-time.After(1 * time.Second):
		t.Fatal("timed out waiting for event")
	}
}

func TestNotifyEvents(t *testing.T) {
	watcher, err := NewWatcher()
	if err != nil {
		t.Fatalf("NewWatcher() failed: %s", err)
	}

	testDir := "TestNotifyEvents.testdirectory"
	testFile := testDir + "/TestNotifyEvents.testfile"
	testFile2 := testFile + ".new"
	const mask = FS_ALL_EVENTS & ^(FS_ATTRIB|FS_CLOSE) | FS_IGNORED

	// Add a watch for testDir
	os.RemoveAll(testDir)
	if err = os.Mkdir(testDir, 0777); err != nil {
		t.Fatalf("Failed to create test directory: %s", err)
	}
	defer os.RemoveAll(testDir)
	err = watcher.AddWatch(testDir, mask)
	if err != nil {
		t.Fatalf("Watcher.Watch() failed: %s", err)
	}

	// Receive errors on the error channel on a separate goroutine
	go func() {
		for err := range watcher.Error {
			t.Fatalf("error received: %s", err)
		}
	}()

	// Create a file
	file, err := os.Create(testFile)
	if err != nil {
		t.Fatalf("creating test file failed: %s", err)
	}
	expect(t, watcher.Event, testFile, FS_CREATE)

	err = watcher.AddWatch(testFile, mask)
	if err != nil {
		t.Fatalf("Watcher.Watch() failed: %s", err)
	}

	if _, err = file.WriteString("hello, world"); err != nil {
		t.Fatalf("failed to write to test file: %s", err)
	}
	if err = file.Close(); err != nil {
		t.Fatalf("failed to close test file: %s", err)
	}
	expect(t, watcher.Event, testFile, FS_MODIFY)
	expect(t, watcher.Event, testFile, FS_MODIFY)

	if err = os.Rename(testFile, testFile2); err != nil {
		t.Fatalf("failed to rename test file: %s", err)
	}
	expect(t, watcher.Event, testFile, FS_MOVED_FROM)
	expect(t, watcher.Event, testFile2, FS_MOVED_TO)
	expect(t, watcher.Event, testFile, FS_MOVE_SELF)

	if err = os.RemoveAll(testDir); err != nil {
		t.Fatalf("failed to remove test directory: %s", err)
	}
	expect(t, watcher.Event, testFile2, FS_DELETE_SELF)
	expect(t, watcher.Event, testFile2, FS_IGNORED)
	expect(t, watcher.Event, testFile2, FS_DELETE)
	expect(t, watcher.Event, testDir, FS_DELETE_SELF)
	expect(t, watcher.Event, testDir, FS_IGNORED)

	t.Log("calling Close()")
	if err = watcher.Close(); err != nil {
		t.Fatalf("failed to close watcher: %s", err)
	}
}

func TestNotifyClose(t *testing.T) {
	watcher, _ := NewWatcher()
	watcher.Close()

	done := false
	go func() {
		watcher.Close()
		done = true
	}()

	time.Sleep(50 * time.Millisecond)
	if !done {
		t.Fatal("double Close() test failed: second Close() call didn't return")
	}

	dir, err := ioutil.TempDir("", "wininotify")
	if err != nil {
		t.Fatalf("TempDir failed: %s", err)
	}
	defer os.RemoveAll(dir)

	err = watcher.Watch(dir)
	if err == nil {
		t.Fatal("expected error on Watch() after Close(), got nil")
	}
}
<|endoftext|>


<commit_before><commit_msg>Add in some example code for upload that just prints what it is doing.<commit_after><|endoftext|>


<commit_before>package openvpn

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"os/exec"
	"os/user"
	"path"
	"regexp"
	"strconv"
	"syscall"

	"github.com/subgraph/oz"
)

func StartOpenVPN(c *oz.Config, conf string, ip *net.IP, table, dev, auth, runtoken string) (cmd *exec.Cmd, err error) {

	confFile := path.Join(c.OpenVPNConfDir, conf)
	cmdArgs, err := parseOpenVPNConf(c, confFile, ip, table, dev, auth, runtoken)
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error %v\n", err)
		return nil, err
	}

	runcmd := exec.Command("/usr/sbin/openvpn", cmdArgs...)
	runcmd.Stdin = os.Stdin
	runcmd.Stderr = os.Stderr

	/*
		cmdReader, err := runcmd.StdoutPipe()
		if err != nil {
			fmt.Fprintln(os.Stderr, "Error runcmd.StdoutPipe(): %v\n", err)
		}
		scanner := bufio.NewScanner(cmdReader)

		go func() {
			for scanner.Scan() {
				fmt.Printf("Output: %s\n", scanner.Text())
			}
		}()
	*/

	ovpngroup, err := user.LookupGroup(c.OpenVPNGroup)
	if err != nil {
		fmt.Fprintln(os.Stderr, "[FATAL] OpenVPN group: %v", err)
		return nil, err
	}
	ovpngid, err := strconv.Atoi(ovpngroup.Gid)
	if err != nil {
		fmt.Fprintln(os.Stderr, "[FATAL] OpenVPN group: %v", err)
		return nil, err
	}
	runcmd.SysProcAttr = &syscall.SysProcAttr{}
	runcmd.SysProcAttr.Credential = &syscall.Credential{
		Gid: uint32(ovpngid),
	}
	err = runcmd.Start()
	if err != nil {
		fmt.Fprintf(os.Stderr, "[FATAL] Error (exec): %v %s\n", err, cmdArgs[0])
		os.Exit(1)
	}
	return runcmd, nil

}

func parseOpenVPNConf(c *oz.Config, filename string, ip *net.IP, table, dev, auth, runtoken string) (cmdargs []string, err error) {

	var cmd []string
	var certpath, capath, keypath, tlsauthpath string
	pidfilepath := path.Join(c.OpenVPNRunPath, runtoken+".pid")

	file, err := os.Open(filename)
	if err != nil {
		return []string{}, err
	}

	defer file.Close()

	r := regexp.MustCompile("[^\\s]+")
	reader := bufio.NewReader(file)
	scanner := bufio.NewScanner(reader)
	scanner.Split(bufio.ScanLines)
	for scanner.Scan() {
		x := r.FindAllString(scanner.Text(), -1)
		if len(x) == 0 {
			continue
		}

		switch x[0] {

		/* TODO: Need to review all OpenVPN client params and filter here */

		case "auth-user-pass":
			cmd = append(cmd, []string{"--auth-user-pass", path.Join(c.OpenVPNConfDir, auth)}...)
			continue
		case "route-up":
			continue
		case "route-pre-down":
			continue
		case "down":
			continue
		case "script-security":
			continue
		case "ipchange":
			continue
		case "up":
			continue
		case "cd":
			continue
		case "chroot":
			continue
		case "group":
			continue
		case "log":
			continue
		case "log-append":
			continue
		case "echo":
			continue
		case "status":
			continue
		case "management":
			continue
		case "plugin":
			continue
		case "ifconfig":
			continue
		case "ca":
			if len(x) == 2 {
				cmd = append(cmd, []string{"--" + x[0], path.Join(c.OpenVPNConfDir, x[1])}...)
			}
			continue
		case "writepid":
			continue
		case "crl-verify":
			if len(x) == 2 {
				cmd = append(cmd, []string{"--" + x[0], path.Join(c.OpenVPNConfDir, x[1])}...)
			}
			continue
		case "<cert>":
			certpath = path.Join(c.OpenVPNRunPath, runtoken+"-cert.cert")
			f, err := os.Create(certpath)
			if err != nil {
				fmt.Fprintf(os.Stderr, "error writing cert to file: %v", err)
				return cmd, err
			}
			defer f.Close()
			for scanner.Scan() {
				if scanner.Text() == "</cert>" {
					f.Sync()
					break
				}
				_, err := f.WriteString(scanner.Text() + "\n")
				if err != nil {
					fmt.Fprintf(os.Stderr, "error writing cert contents to file: %v", err)
					return cmd, err
				}
			}
			cmd = append(cmd, []string{"--cert", certpath}...)
			continue
		case "<ca>":
			capath = path.Join(c.OpenVPNRunPath, runtoken+"-ca.cert")
			f, err := os.Create(capath)
			if err != nil {
				fmt.Fprintf(os.Stderr, "error writing cert to file: %v", err)
				return cmd, err
			}
			defer f.Close()
			for scanner.Scan() {
				if scanner.Text() == "</ca>" {
					f.Sync()
					break
				}
				_, err := f.WriteString(scanner.Text() + "\n")
				if err != nil {
					fmt.Fprintf(os.Stderr, "error writing cert contents to file: %v", err)
					return cmd, err
				}
			}
			cmd = append(cmd, []string{"--ca", capath}...)
			continue
		case "<key>":
			keypath = path.Join(c.OpenVPNRunPath, runtoken+"-key.key")
			f, err := os.Create(keypath)
			if err != nil {
				fmt.Fprintf(os.Stderr, "error writing key to file: %v", err)
				return cmd, err
			}
			defer f.Close()
			for scanner.Scan() {
				if scanner.Text() == "</key>" {
					f.Sync()
					break
				}
				_, err := f.WriteString(scanner.Text() + "\n")
				if err != nil {
					fmt.Fprintf(os.Stderr, "error writing key contents to file: %v", err)
					return cmd, err
				}
			}
			cmd = append(cmd, []string{"--key", keypath}...)
			continue
		case "<tls-auth>":
			tlsauthpath = path.Join(c.OpenVPNRunPath, runtoken+"-tls-auth.key")
			f, err := os.Create(tlsauthpath)
			if err != nil {
				fmt.Fprintf(os.Stderr, "error writing tls-auth to file: %v", err)
				return cmd, err
			}
			defer f.Close()
			for scanner.Scan() {
				if scanner.Text() == "</tls-auth>" {
					f.Sync()
					break
				}
				_, err := f.WriteString(scanner.Text() + "\n")
				if err != nil {
					fmt.Fprintf(os.Stderr, "error writing contents to file: %v", err)
					return cmd, err
				}
			}
			cmd = append(cmd, []string{"--tls-auth", tlsauthpath}...)
			continue
		default:
		}
		if len(x) == 1 {
			cmd = append(cmd, "--"+x[0])
		} else {
			cmd = append(cmd, "--"+x[0])
			for _, t := range x[1:] {
				cmd = append(cmd, t)
			}
		}
	}
	extra := []string{"--writepid", pidfilepath, "--daemon", "--auth-retry", "nointeract", "--route-noexec", "--route-up", "/usr/bin/oz-ovpn-route-up", "--route-pre-down", "/usr/bin/oz-ovpn-route-down", "--script-security", "2", "--setenv", "bridge_addr", ip.String(), "--setenv", "routing_table", table, "--setenv", "bridge_dev", dev}
	cmd = append(cmd, extra...)

	for _, x := range cmd {
		fmt.Fprintf(os.Stderr, "%s", x)
		fmt.Fprintf(os.Stderr, " ")
	}

	return cmd, nil

}
<commit_msg>Additional client params from conf replaced/filtered, force client mode (still WIP)<commit_after>package openvpn

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"os/exec"
	"os/user"
	"path"
	"regexp"
	"strconv"
	"syscall"

	"github.com/subgraph/oz"
)

func StartOpenVPN(c *oz.Config, conf string, ip *net.IP, table, dev, auth, runtoken string) (cmd *exec.Cmd, err error) {

	confFile := path.Join(c.OpenVPNConfDir, conf)
	cmdArgs, err := parseOpenVPNConf(c, confFile, ip, table, dev, auth, runtoken)
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error %v\n", err)
		return nil, err
	}

	runcmd := exec.Command("/usr/sbin/openvpn", cmdArgs...)
	runcmd.Stdin = os.Stdin
	runcmd.Stderr = os.Stderr

	ovpngroup, err := user.LookupGroup(c.OpenVPNGroup)
	if err != nil {
		fmt.Fprintln(os.Stderr, "[FATAL] OpenVPN group: %v", err)
		return nil, err
	}
	ovpngid, err := strconv.Atoi(ovpngroup.Gid)
	if err != nil {
		fmt.Fprintln(os.Stderr, "[FATAL] OpenVPN group: %v", err)
		return nil, err
	}
	runcmd.SysProcAttr = &syscall.SysProcAttr{}
	runcmd.SysProcAttr.Credential = &syscall.Credential{
		Gid: uint32(ovpngid),
	}
	err = runcmd.Start()
	if err != nil {
		fmt.Fprintf(os.Stderr, "[FATAL] Error (exec): %v %s\n", err, cmdArgs[0])
		os.Exit(1)
	}
	return runcmd, nil

}

func parseOpenVPNConf(c *oz.Config, filename string, ip *net.IP, table, dev, auth, runtoken string) (cmdargs []string, err error) {

	var cmd []string
	var certpath, capath, keypath, tlsauthpath string
	pidfilepath := path.Join(c.OpenVPNRunPath, runtoken+".pid")

	file, err := os.Open(filename)
	if err != nil {
		return []string{}, err
	}

	defer file.Close()

	r := regexp.MustCompile("[^\\s]+")
	reader := bufio.NewReader(file)
	scanner := bufio.NewScanner(reader)
	scanner.Split(bufio.ScanLines)
	cmd = append(cmd, "--client")
	for scanner.Scan() {
		x := r.FindAllString(scanner.Text(), -1)
		if len(x) == 0 {
			continue
		}

		switch x[0] {

		/* TODO: Need to review all OpenVPN client params and filter here */

		case "auth-user-pass":
			cmd = append(cmd, []string{"--auth-user-pass", path.Join(c.OpenVPNConfDir, auth)}...)
			continue
		case "iproute":
			continue
		case "route-up":
			continue
		case "config":
			continue
		case "route-pre-down":
			continue
		case "down":
			continue
		case "script-security":
			continue
		case "ipchange":
			continue
		case "up":
			continue
		case "cd":
			continue
		case "chroot":
			continue
		case "setenv":
			continue
		case "setenv-safe":
			continue
		case "group":
			continue
		case "user":
			continue
		case "daemon":
			continue
		case "syslog":
			continue
		case "log":
			continue
		case "log-append":
			continue
		case "echo":
			continue
		case "status":
			continue
		case "mode":
			continue
		case "client":
			continue
		case "server":
			continue
		case "management":
			continue
		case "plugin":
			continue
		case "ifconfig":
			continue
		case "ca":
			if len(x) == 2 {
				cmd = append(cmd, []string{"--" + x[0], path.Join(c.OpenVPNConfDir, x[1])}...)
			}
			continue
		case "writepid":
			continue
		case "crl-verify":
			if len(x) == 2 {
				cmd = append(cmd, []string{"--" + x[0], path.Join(c.OpenVPNConfDir, x[1])}...)
			}
			continue
		case "<cert>":
			certpath = path.Join(c.OpenVPNRunPath, runtoken+"-cert.cert")
			f, err := os.Create(certpath)
			if err != nil {
				fmt.Fprintf(os.Stderr, "error writing cert to file: %v", err)
				return cmd, err
			}
			defer f.Close()
			for scanner.Scan() {
				if scanner.Text() == "</cert>" {
					f.Sync()
					break
				}
				_, err := f.WriteString(scanner.Text() + "\n")
				if err != nil {
					fmt.Fprintf(os.Stderr, "error writing cert contents to file: %v", err)
					return cmd, err
				}
			}
			cmd = append(cmd, []string{"--cert", certpath}...)
			continue
		case "<ca>":
			capath = path.Join(c.OpenVPNRunPath, runtoken+"-ca.cert")
			f, err := os.Create(capath)
			if err != nil {
				fmt.Fprintf(os.Stderr, "error writing cert to file: %v", err)
				return cmd, err
			}
			defer f.Close()
			for scanner.Scan() {
				if scanner.Text() == "</ca>" {
					f.Sync()
					break
				}
				_, err := f.WriteString(scanner.Text() + "\n")
				if err != nil {
					fmt.Fprintf(os.Stderr, "error writing cert contents to file: %v", err)
					return cmd, err
				}
			}
			cmd = append(cmd, []string{"--ca", capath}...)
			continue
		case "<key>":
			keypath = path.Join(c.OpenVPNRunPath, runtoken+"-key.key")
			f, err := os.Create(keypath)
			if err != nil {
				fmt.Fprintf(os.Stderr, "error writing key to file: %v", err)
				return cmd, err
			}
			defer f.Close()
			for scanner.Scan() {
				if scanner.Text() == "</key>" {
					f.Sync()
					break
				}
				_, err := f.WriteString(scanner.Text() + "\n")
				if err != nil {
					fmt.Fprintf(os.Stderr, "error writing key contents to file: %v", err)
					return cmd, err
				}
			}
			cmd = append(cmd, []string{"--key", keypath}...)
			continue
		case "<tls-auth>":
			tlsauthpath = path.Join(c.OpenVPNRunPath, runtoken+"-tls-auth.key")
			f, err := os.Create(tlsauthpath)
			if err != nil {
				fmt.Fprintf(os.Stderr, "error writing tls-auth to file: %v", err)
				return cmd, err
			}
			defer f.Close()
			for scanner.Scan() {
				if scanner.Text() == "</tls-auth>" {
					f.Sync()
					break
				}
				_, err := f.WriteString(scanner.Text() + "\n")
				if err != nil {
					fmt.Fprintf(os.Stderr, "error writing contents to file: %v", err)
					return cmd, err
				}
			}
			cmd = append(cmd, []string{"--tls-auth", tlsauthpath}...)
			continue
		default:
		}
		if len(x) == 1 {
			cmd = append(cmd, "--"+x[0])
		} else {
			cmd = append(cmd, "--"+x[0])
			for _, t := range x[1:] {
				cmd = append(cmd, t)
			}
		}
	}
	extra := []string{"--writepid", pidfilepath, "--daemon", "--auth-retry", "nointeract", "--route-noexec", "--route-up", "/usr/bin/oz-ovpn-route-up", "--route-pre-down", "/usr/bin/oz-ovpn-route-down", "--script-security", "2", "--setenv", "bridge_addr", ip.String(), "--setenv", "routing_table", table, "--setenv", "bridge_dev", dev}
	cmd = append(cmd, extra...)

	for _, x := range cmd {
		fmt.Fprintf(os.Stderr, "%s", x)
		fmt.Fprintf(os.Stderr, " ")
	}

	return cmd, nil

}
<|endoftext|>


<commit_before><commit_msg>Fix bug in VarintSize<commit_after><|endoftext|>