<commit_before>// Copyright 2012 Google, Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree.

// +build darwin dragonfly freebsd netbsd openbsd

package bsdbpf

import (
	"github.com/google/gopacket"
	"golang.org/x/sys/unix"

	"fmt"
	"syscall"
	"time"
	"unsafe"
)

const wordSize = int(unsafe.Sizeof(uintptr(0)))

func bpfWordAlign(x int) int {
	return (((x) + (wordSize - 1)) &^ (wordSize - 1))
}

// Options is used to configure various properties of the BPF sniffer.
// Default values are used when a nil Options pointer is passed to NewBPFSniffer.
type Options struct {
	// BPFDeviceName is name of the bpf device to use for sniffing
	// the network device. The default value of BPFDeviceName is empty string
	// which causes the first available BPF device file /dev/bpfX to be used.
	BPFDeviceName string
	// ReadBufLen specifies the size of the buffer used to read packets
	// off the wire such that multiple packets are buffered with each read syscall.
	// The packet will be clipped if it's size exceeds the buffer size.
	// A larger buffer should increase performance because fewer read syscalls would be made.
	// If zero is used the system's default buffer length will be used.
	// ReadBufLen defaults to 32767.
	ReadBufLen int
	// Timeout is the length of time to wait before timing out on a read request.
	// Timeout defaults to nil which means no timeout is used.
	Timeout *syscall.Timeval
	// Promisc is set to true for promiscuous mode ethernet sniffing.
	// Promisc defaults to true.
	Promisc bool
	// Immediate is set to true to make our read requests return as soon as a packet becomes available.
	// Otherwise, a read will block until either the kernel buffer becomes full or a timeout occurs.
	// The default is true.
	Immediate bool
	// PreserveLinkAddr is set to false if the link level source address should be filled in automatically
	// by the interface output routine. Set to true if the link level source address will be written,
	// as provided, to the wire.
	// The default is true.
	PreserveLinkAddr bool
}

var defaultOptions = Options{
	BPFDeviceName:    "",
	ReadBufLen:       32767,
	Timeout:          nil,
	Promisc:          true,
	Immediate:        true,
	PreserveLinkAddr: true,
}

// BPFSniffer is a struct used to track state of a BSD BPF ethernet sniffer
// such that gopacket's PacketDataSource interface is implemented.
type BPFSniffer struct {
	options           *Options
	sniffDeviceName   string
	fd                int
	readBuffer        []byte
	lastReadLen       int
	readBytesConsumed int
}

// NewBPFSniffer is used to create BSD-only BPF ethernet sniffer
// iface is the network interface device name that you wish to sniff
// options can set to nil in order to utilize default values for everything.
// Each field of Options also have a default setting if left unspecified by
// the user's custome Options struct.
func NewBPFSniffer(iface string, options *Options) *BPFSniffer {
	sniffer := BPFSniffer{
		sniffDeviceName: iface,
	}
	if options == nil {
		sniffer.options = &defaultOptions
	} else {
		sniffer.options = options
	}
	return &sniffer
}

// Close is used to close the file-descriptor of the BPF device file.
func (b *BPFSniffer) Close() error {
	return syscall.Close(b.fd)
}

func (b *BPFSniffer) pickBpfDevice() {
	var err error
	for i := 0; i < 99; i++ {
		b.options.BPFDeviceName = fmt.Sprintf("/dev/bpf%d", i)
		b.fd, err = syscall.Open(b.options.BPFDeviceName, syscall.O_RDWR, 0)
		if err == nil {
			break
		}
	}
}

// Init is used to initialize a BPF device for promiscuous sniffing.
// It also starts a goroutine to continuously read frames.
func (b *BPFSniffer) Init() error {
	var err error
	enable := 1

	if b.options.BPFDeviceName == "" {
		b.pickBpfDevice()
	}

	// setup our read buffer
	if b.options.ReadBufLen == 0 {
		b.options.ReadBufLen, err = syscall.BpfBuflen(b.fd)
		if err != nil {
			panic(err)
		}
	} else {
		b.options.ReadBufLen, err = syscall.SetBpfBuflen(b.fd, b.options.ReadBufLen)
		if err != nil {
			panic(err)
		}
	}
	b.readBuffer = make([]byte, b.options.ReadBufLen)

	err = syscall.SetBpfInterface(b.fd, b.sniffDeviceName)
	if err != nil {
		return err
	}

	if b.options.Immediate {
		// turn immediate mode on. This makes the snffer non-blocking.
		err = syscall.SetBpfImmediate(b.fd, enable)
		if err != nil {
			return err
		}
	}

	// the above call to syscall.SetBpfImmediate needs to be made
	// before setting a timer otherwise the reads will block for the
	// entire timer duration even if there are packets to return.
	if b.options.Timeout != nil {
		err = syscall.SetBpfTimeout(b.fd, b.options.Timeout)
		if err != nil {
			panic(err)
		}
	}

	if b.options.PreserveLinkAddr {
		// preserves the link level source address...
		// higher level protocol analyzers will not need this
		err = syscall.SetBpfHeadercmpl(b.fd, enable)
		if err != nil {
			return err
		}
	}

	if b.options.Promisc {
		// forces the interface into promiscuous mode
		err = syscall.SetBpfPromisc(b.fd, enable)
		if err != nil {
			return err
		}
	}

	return nil
}

func (b *BPFSniffer) ReadPacketData() ([]byte, gopacket.CaptureInfo, error) {
	var err error
	if b.readBytesConsumed >= b.lastReadLen {
		b.readBytesConsumed = 0
		b.readBuffer = make([]byte, b.options.ReadBufLen)
		b.lastReadLen, err = syscall.Read(b.fd, b.readBuffer)
		if err != nil {
			b.lastReadLen = 0
			return nil, gopacket.CaptureInfo{}, err
		}
	}
	hdr := (*unix.BpfHdr)(unsafe.Pointer(&b.readBuffer[b.readBytesConsumed]))
	frameStart := b.readBytesConsumed + int(hdr.Hdrlen)
	b.readBytesConsumed += bpfWordAlign(int(hdr.Hdrlen) + int(hdr.Caplen))
	rawFrame := b.readBuffer[frameStart : frameStart+int(hdr.Caplen)]
	captureInfo := gopacket.CaptureInfo{
		Timestamp:     time.Unix(int64(hdr.Tstamp.Sec), int64(hdr.Tstamp.Usec)*1000),
		CaptureLength: len(rawFrame),
		Length:        len(rawFrame),
	}
	return rawFrame, captureInfo, nil
}
<commit_msg>Add GetReadBufLen and update comments<commit_after>// Copyright 2012 Google, Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree.

// +build darwin dragonfly freebsd netbsd openbsd

package bsdbpf

import (
	"github.com/google/gopacket"
	"golang.org/x/sys/unix"

	"fmt"
	"syscall"
	"time"
	"unsafe"
)

const wordSize = int(unsafe.Sizeof(uintptr(0)))

func bpfWordAlign(x int) int {
	return (((x) + (wordSize - 1)) &^ (wordSize - 1))
}

// Options is used to configure various properties of the BPF sniffer.
// Default values are used when a nil Options pointer is passed to NewBPFSniffer.
type Options struct {
	// BPFDeviceName is name of the bpf device to use for sniffing
	// the network device. The default value of BPFDeviceName is empty string
	// which causes the first available BPF device file /dev/bpfX to be used.
	BPFDeviceName string
	// ReadBufLen specifies the size of the buffer used to read packets
	// off the wire such that multiple packets are buffered with each read syscall.
	// Note that an individual packet larger than the buffer size is necessarily truncated.
	// A larger buffer should increase performance because fewer read syscalls would be made.
	// If zero is used, the system's default buffer length will be used which depending on the
	// system may default to 4096 bytes which is not big enough to accomodate some link layers
	// such as WLAN (802.11).
	// ReadBufLen defaults to 32767... however typical BSD manual pages for BPF indicate that
	// if the requested buffer size cannot be accommodated, the closest allowable size will be
	// set and returned... hence our GetReadBufLen method.
	ReadBufLen int
	// Timeout is the length of time to wait before timing out on a read request.
	// Timeout defaults to nil which means no timeout is used.
	Timeout *syscall.Timeval
	// Promisc is set to true for promiscuous mode ethernet sniffing.
	// Promisc defaults to true.
	Promisc bool
	// Immediate is set to true to make our read requests return as soon as a packet becomes available.
	// Otherwise, a read will block until either the kernel buffer becomes full or a timeout occurs.
	// The default is true.
	Immediate bool
	// PreserveLinkAddr is set to false if the link level source address should be filled in automatically
	// by the interface output routine. Set to true if the link level source address will be written,
	// as provided, to the wire.
	// The default is true.
	PreserveLinkAddr bool
}

var defaultOptions = Options{
	BPFDeviceName:    "",
	ReadBufLen:       32767,
	Timeout:          nil,
	Promisc:          true,
	Immediate:        true,
	PreserveLinkAddr: true,
}

// BPFSniffer is a struct used to track state of a BSD BPF ethernet sniffer
// such that gopacket's PacketDataSource interface is implemented.
type BPFSniffer struct {
	options           *Options
	sniffDeviceName   string
	fd                int
	readBuffer        []byte
	lastReadLen       int
	readBytesConsumed int
}

// NewBPFSniffer is used to create BSD-only BPF ethernet sniffer
// iface is the network interface device name that you wish to sniff
// options can set to nil in order to utilize default values for everything.
// Each field of Options also have a default setting if left unspecified by
// the user's custome Options struct.
func NewBPFSniffer(iface string, options *Options) *BPFSniffer {
	sniffer := BPFSniffer{
		sniffDeviceName: iface,
	}
	if options == nil {
		sniffer.options = &defaultOptions
	} else {
		sniffer.options = options
	}
	return &sniffer
}

// Close is used to close the file-descriptor of the BPF device file.
func (b *BPFSniffer) Close() error {
	return syscall.Close(b.fd)
}

func (b *BPFSniffer) pickBpfDevice() {
	var err error
	for i := 0; i < 99; i++ {
		b.options.BPFDeviceName = fmt.Sprintf("/dev/bpf%d", i)
		b.fd, err = syscall.Open(b.options.BPFDeviceName, syscall.O_RDWR, 0)
		if err == nil {
			break
		}
	}
}

// Init is used to initialize a BPF device for promiscuous sniffing.
// It also starts a goroutine to continuously read frames.
func (b *BPFSniffer) Init() error {
	var err error
	enable := 1

	if b.options.BPFDeviceName == "" {
		b.pickBpfDevice()
	}

	// setup our read buffer
	if b.options.ReadBufLen == 0 {
		b.options.ReadBufLen, err = syscall.BpfBuflen(b.fd)
		if err != nil {
			panic(err)
		}
	} else {
		b.options.ReadBufLen, err = syscall.SetBpfBuflen(b.fd, b.options.ReadBufLen)
		if err != nil {
			panic(err)
		}
	}
	b.readBuffer = make([]byte, b.options.ReadBufLen)

	err = syscall.SetBpfInterface(b.fd, b.sniffDeviceName)
	if err != nil {
		return err
	}

	if b.options.Immediate {
		// turn immediate mode on. This makes the snffer non-blocking.
		err = syscall.SetBpfImmediate(b.fd, enable)
		if err != nil {
			return err
		}
	}

	// the above call to syscall.SetBpfImmediate needs to be made
	// before setting a timer otherwise the reads will block for the
	// entire timer duration even if there are packets to return.
	if b.options.Timeout != nil {
		err = syscall.SetBpfTimeout(b.fd, b.options.Timeout)
		if err != nil {
			panic(err)
		}
	}

	if b.options.PreserveLinkAddr {
		// preserves the link level source address...
		// higher level protocol analyzers will not need this
		err = syscall.SetBpfHeadercmpl(b.fd, enable)
		if err != nil {
			return err
		}
	}

	if b.options.Promisc {
		// forces the interface into promiscuous mode
		err = syscall.SetBpfPromisc(b.fd, enable)
		if err != nil {
			return err
		}
	}

	return nil
}

func (b *BPFSniffer) ReadPacketData() ([]byte, gopacket.CaptureInfo, error) {
	var err error
	if b.readBytesConsumed >= b.lastReadLen {
		b.readBytesConsumed = 0
		b.readBuffer = make([]byte, b.options.ReadBufLen)
		b.lastReadLen, err = syscall.Read(b.fd, b.readBuffer)
		if err != nil {
			b.lastReadLen = 0
			return nil, gopacket.CaptureInfo{}, err
		}
	}
	hdr := (*unix.BpfHdr)(unsafe.Pointer(&b.readBuffer[b.readBytesConsumed]))
	frameStart := b.readBytesConsumed + int(hdr.Hdrlen)
	b.readBytesConsumed += bpfWordAlign(int(hdr.Hdrlen) + int(hdr.Caplen))
	rawFrame := b.readBuffer[frameStart : frameStart+int(hdr.Caplen)]
	captureInfo := gopacket.CaptureInfo{
		Timestamp:     time.Unix(int64(hdr.Tstamp.Sec), int64(hdr.Tstamp.Usec)*1000),
		CaptureLength: len(rawFrame),
		Length:        len(rawFrame),
	}
	return rawFrame, captureInfo, nil
}

func (b *BPFSniffer) GetReadBufLen() int {
	return b.options.ReadBufLen
}
<|endoftext|>


<commit_before><commit_msg>Partial fix to issue #1<commit_after><|endoftext|>


<commit_before>package main

import (
	"sort"
	"unicode/utf8"

	log "github.com/Sirupsen/logrus"
	"github.com/fsouza/go-dockerclient"

	"github.com/camptocamp/conplicity/handler"
	"github.com/camptocamp/conplicity/providers"
	"github.com/camptocamp/conplicity/util"
)

const labelPrefix string = "io.conplicity"

func main() {
	log.Infof("Starting backup...")

	var err error

	c := &handler.Conplicity{}
	err = c.Setup()
	util.CheckErr(err, "Failed to setup Conplicity handler: %v", 1)

	vols, err := c.ListVolumes(docker.ListVolumesOptions{})
	util.CheckErr(err, "Failed to list Docker volumes: %v", 1)

	var metrics []string
	for _, vol := range vols {
		voll, err := c.InspectVolume(vol.Name)
		util.CheckErr(err, "Failed to inspect volume "+vol.Name+": %v", -1)

		_metrics, err := backupVolume(c, voll)
		util.CheckErr(err, "Failed to process volume "+vol.Name+": %v", -1)
		metrics = append(metrics, _metrics...)
	}

	log.Infof("End backup...")
}

func backupVolume(c *handler.Conplicity, vol *docker.Volume) (metrics []string, err error) {
	if utf8.RuneCountInString(vol.Name) == 64 || vol.Name == "duplicity_cache" {
		log.Infof("Ignoring unnamed volume " + vol.Name)
		return
	}

	list := c.VolumesBlacklist
	i := sort.SearchStrings(list, vol.Name)
	if i < len(list) && list[i] == vol.Name {
		log.Infof("Ignoring blacklisted volume " + vol.Name)
		return
	}

	if getVolumeLabel(vol, ".ignore") == "true" {
		log.Infof("Ignoring blacklisted volume " + vol.Name)
		return
	}

	p := providers.GetProvider(c, vol)
	log.Infof("Using provider %v to backup %v", p.GetName(), vol.Name)
	err = providers.PrepareBackup(p)
	util.CheckErr(err, "Failed to prepare backup for volume "+vol.Name+": %v", -1)
	metrics, err = providers.BackupVolume(p, vol)
	util.CheckErr(err, "Failed to backup volume "+vol.Name+": %v", -1)
	return
}

func getVolumeLabel(vol *docker.Volume, key string) (value string) {
	value = vol.Labels[labelPrefix+key]
	return
}
<commit_msg>Post metrics to Prometheurs Pushgateway<commit_after>package main

import (
	"bytes"
	"net/http"
	"sort"
	"strings"
	"unicode/utf8"

	log "github.com/Sirupsen/logrus"
	"github.com/fsouza/go-dockerclient"

	"github.com/camptocamp/conplicity/handler"
	"github.com/camptocamp/conplicity/providers"
	"github.com/camptocamp/conplicity/util"
)

const labelPrefix string = "io.conplicity"

func main() {
	log.Infof("Starting backup...")

	var err error

	c := &handler.Conplicity{}
	err = c.Setup()
	util.CheckErr(err, "Failed to setup Conplicity handler: %v", 1)

	vols, err := c.ListVolumes(docker.ListVolumesOptions{})
	util.CheckErr(err, "Failed to list Docker volumes: %v", 1)

	var metrics []string
	for _, vol := range vols {
		voll, err := c.InspectVolume(vol.Name)
		util.CheckErr(err, "Failed to inspect volume "+vol.Name+": %v", -1)

		_metrics, err := backupVolume(c, voll)
		util.CheckErr(err, "Failed to process volume "+vol.Name+": %v", -1)
		metrics = append(metrics, _metrics...)
	}
	if c.PushgatewayURL != "" {
		log.Infof("Sending metrics to Prometheurs Pushgateway: %v", strings.Join(metrics, "\n"))
		resp, err := http.Post(
			c.PushgatewayURL+"/metrics/job/conplicity/instance/"+c.Hostname,
			"text/plain",
			bytes.NewBufferString(strings.Join(metrics, "\n")),
		)
		log.Infof("resp = %v", resp)
		util.CheckErr(err, "Failed post data to Prometheus Pushgateway: %v", 1)
	}

	log.Infof("End backup...")
}

func backupVolume(c *handler.Conplicity, vol *docker.Volume) (metrics []string, err error) {
	if utf8.RuneCountInString(vol.Name) == 64 || vol.Name == "duplicity_cache" {
		log.Infof("Ignoring unnamed volume " + vol.Name)
		return
	}

	list := c.VolumesBlacklist
	i := sort.SearchStrings(list, vol.Name)
	if i < len(list) && list[i] == vol.Name {
		log.Infof("Ignoring blacklisted volume " + vol.Name)
		return
	}

	if getVolumeLabel(vol, ".ignore") == "true" {
		log.Infof("Ignoring blacklisted volume " + vol.Name)
		return
	}

	p := providers.GetProvider(c, vol)
	log.Infof("Using provider %v to backup %v", p.GetName(), vol.Name)
	err = providers.PrepareBackup(p)
	util.CheckErr(err, "Failed to prepare backup for volume "+vol.Name+": %v", -1)
	metrics, err = providers.BackupVolume(p, vol)
	util.CheckErr(err, "Failed to backup volume "+vol.Name+": %v", -1)
	return
}

func getVolumeLabel(vol *docker.Volume, key string) (value string) {
	value = vol.Labels[labelPrefix+key]
	return
}
<|endoftext|>


<commit_before>package flow

import (
	"time"

	"github.com/go-kit/kit/log"
)

type loggingService struct {
	logger log.Logger
	Service Service
}

// NewLoggingService returns a new instance of a logging Service.
func NewLoggingService(logger log.Logger, s Service) Service {
	return &loggingService{logger, s}
}

func (mw *loggingService) FlowDirectoryTreeGet() (treeState string, err error) {
	defer func(begin time.Time) {
		_ = mw.logger.Log(
			"method", "FlowDirectoryTreeGet",
			"output", treeState,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return mw.Service.FlowDirectoryTreeGet()
}

func (mw *loggingService) FlowDirectoryTreeSave(treeState string) (err error) {
	defer func(begin time.Time) {
		_ = mw.logger.Log(
			"method", "FlowDirectoryTreeSave",
			"input", treeState,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return mw.Service.FlowDirectoryTreeSave(treeState)
}

func (mw *loggingService) FlowsDirectoryDelete(request flowsDirectoryDeleteRequest) (output bool, err error) {
	defer func(begin time.Time) {
		_ = mw.logger.Log(
			"method", "FlowsDirectoryDelete",
			"input.Path", request.Path,
			"output", output,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return mw.Service.FlowsDirectoryDelete(request)
}

func (mw *loggingService) FlowDelete(request flowDeleteRequest) (output bool, err error) {
	defer func(begin time.Time) {
		_ = mw.logger.Log(
			"method", "FlowDelete",
			"input.id", request.Id,
			"output", output,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return mw.Service.FlowDelete(request)
}

func (mw *loggingService) FlowPost(request flowPostRequest) (output bool, err error) {
	defer func(begin time.Time) {
		_ = mw.logger.Log(
			"method", "FlowPost",
			"input.id", request.Id,
			"input.config", request.Config,
			"output", output,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return mw.Service.FlowPost(request)
}

func (mw *loggingService) FlowPut(request flowPutRequest) (output bool, err error) {
	defer func(begin time.Time) {
		_ = mw.logger.Log(
			"method", "FlowPut",
			"input.id", request.Id,
			"input.config", request.Config,
			"output", output,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return mw.Service.FlowPut(request)
}

func (mw *loggingService) FlowGet(id string) (config string, err error) {
	defer func(begin time.Time) {
		_ = mw.logger.Log(
			"method", "FlowGet",
			"configId", id,
			"config", config,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return  mw.Service.FlowGet(id)
}
<commit_msg>remove '_ =' in loading functions<commit_after>package flow

import (
	"time"

	"github.com/go-kit/kit/log"
)

type loggingService struct {
	logger  log.Logger
	Service Service
}

// NewLoggingService returns a new instance of a logging Service.
func NewLoggingService(logger log.Logger, s Service) Service {
	return &loggingService{logger, s}
}

func (mw *loggingService) FlowDirectoryTreeGet() (treeState string, err error) {
	defer func(begin time.Time) {
		mw.logger.Log(
			"method", "FlowDirectoryTreeGet",
			"output", treeState,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return mw.Service.FlowDirectoryTreeGet()
}

func (mw *loggingService) FlowDirectoryTreeSave(treeState string) (err error) {
	defer func(begin time.Time) {
		mw.logger.Log(
			"method", "FlowDirectoryTreeSave",
			"input", treeState,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return mw.Service.FlowDirectoryTreeSave(treeState)
}

func (mw *loggingService) FlowsDirectoryDelete(request flowsDirectoryDeleteRequest) (output bool, err error) {
	defer func(begin time.Time) {
		mw.logger.Log(
			"method", "FlowsDirectoryDelete",
			"input.Path", request.Path,
			"output", output,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return mw.Service.FlowsDirectoryDelete(request)
}

func (mw *loggingService) FlowDelete(request flowDeleteRequest) (output bool, err error) {
	defer func(begin time.Time) {
		mw.logger.Log(
			"method", "FlowDelete",
			"input.id", request.Id,
			"output", output,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return mw.Service.FlowDelete(request)
}

func (mw *loggingService) FlowPost(request flowPostRequest) (output bool, err error) {
	defer func(begin time.Time) {
		mw.logger.Log(
			"method", "FlowPost",
			"input.id", request.Id,
			"input.config", request.Config,
			"output", output,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return mw.Service.FlowPost(request)
}

func (mw *loggingService) FlowPut(request flowPutRequest) (output bool, err error) {
	defer func(begin time.Time) {
		mw.logger.Log(
			"method", "FlowPut",
			"input.id", request.Id,
			"input.config", request.Config,
			"output", output,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return mw.Service.FlowPut(request)
}

func (mw *loggingService) FlowGet(id string) (config string, err error) {
	defer func(begin time.Time) {
		mw.logger.Log(
			"method", "FlowGet",
			"configId", id,
			"config", config,
			"err", err,
			"took", time.Since(begin),
		)
	}(time.Now())
	return mw.Service.FlowGet(id)
}
<|endoftext|>


<commit_before>package node

import (
	"reflect"
	"github.com/c2stack/c2g/meta"
)

// Uses reflection to marshal data into go structs.  If you want to override
// then use:
//     data.Extend{
//         Node:MarshalContainer(obj),
//         OnSelect:...
//     }
func MarshalContainer(Obj interface{}) Node {
	s := &MyNode{
		Label:"MarshalContainer " + reflect.TypeOf(Obj).Name(),
		Peekable: Obj,
	}
	s.OnSelect = func(r ContainerRequest) (Node, error) {
		objVal := reflect.ValueOf(Obj)
		if objVal.Kind() == reflect.Interface || objVal.Kind() == reflect.Ptr {
			objVal = objVal.Elem()
		}
		fieldName := meta.MetaNameToFieldName(r.Meta.GetIdent())
		value := objVal.FieldByName(fieldName)
		if meta.IsList(r.Meta) {
			if value.Kind() == reflect.Map {
				marshal := &MarshalMap{
					Map:value.Interface(),
				}
				return marshal.Node(), nil
			} else {
				marshal := &MarshalArray{
					ArrayValue: &value,
				}
				return marshal.Node(), nil
			}
		} else {
			if value.Kind() == reflect.Struct {
				return MarshalContainer(value.Addr().Interface()), nil
			} else if value.CanAddr() {
				var child interface{}
				if r.New {
					childValue := reflect.New(value.Type().Elem())
					value.Set(childValue)
					child = childValue.Interface()
				} else {
					if value.IsNil() {
						return nil, nil
					}
					child = value.Interface()
				}
				if child != nil {
					return MarshalContainer(child), nil
				}
				return nil, nil
			}
		}
		return nil, nil
	}
	s.OnField = func(r FieldRequest, hnd *ValueHandle) (err error) {
		if r.Write {
			err = WriteField(r.Meta, Obj, hnd.Val)
		} else {
			hnd.Val, err = ReadField(r.Meta, Obj)
		}
		return
	}
	return s
}

type MarshalArray struct {
	ArrayValue   *reflect.Value
	OnNewItem    func() interface{}
	OnSelectItem func(item interface{}) Node
}

func (self *MarshalArray) Node() Node {
	n := &MyNode{
		Label: "MarshalArray " + self.ArrayValue.Type().Name(),
		Peekable: self.ArrayValue.Interface(),
	}
	n.OnNext = func(r ListRequest) (next Node, key []*Value, err error) {
		var item interface{}
		if r.New {
			var itemValue reflect.Value
			if self.OnNewItem != nil {
				item = self.OnNewItem()
				itemValue = reflect.ValueOf(item)
			} else {
				itemValue = reflect.New(self.ArrayValue.Type().Elem().Elem())
				item = itemValue.Interface()
			}
			self.ArrayValue.Set(reflect.Append(*self.ArrayValue, itemValue))
		} else if len(r.Key) > 0 {
			// Not implemented, but could be...
			panic("Keys only implemented on MarshalMap, not MarshalArray")
		} else {
			if r.Row < self.ArrayValue.Len() {
				item = self.ArrayValue.Index(r.Row).Interface()
			}
		}
		if item != nil {
			if self.OnSelectItem != nil {
				return self.OnSelectItem(item), nil, nil
			}
			return MarshalContainer(item), nil, nil
		}
		return nil, nil, nil
	}
	return n
}

type MarshalMap struct {
	Map          interface{}
	OnNewItem    func(r ListRequest) interface{}
	OnSelectItem func(item interface{}) Node
}

func (self *MarshalMap) Node() Node {
	mapReflect := reflect.ValueOf(self.Map)
	n := &MyNode{
		Label: "MarshalMap " + mapReflect.Type().Name(),
		Peekable: self.Map,
	}
	index := NewIndex(self.Map)
	n.OnNext = func(r ListRequest) (next Node, key []*Value, err error) {
		var item interface{}
		key = r.Key
		if r.New {
			item = self.OnNewItem(r)
			mapKey := reflect.ValueOf(r.Key[0].Value())
			mapReflect.SetMapIndex(mapKey, reflect.ValueOf(item))
		} else if len(r.Key) > 0 {
			mapKey := reflect.ValueOf(r.Key[0].Value())
			itemVal := mapReflect.MapIndex(mapKey)
			if itemVal.IsValid() {
				item = itemVal.Interface()
			}
		} else {
			nextKey := index.NextKey(r.Row)
			if nextKey != NO_VALUE {
				key = SetValues(r.Meta.KeyMeta(), nextKey.Interface())
				itemVal := mapReflect.MapIndex(nextKey)
				item = itemVal.Interface()
			}
		}
		if item != nil {
			if self.OnSelectItem != nil {
				return self.OnSelectItem(item), key, nil
			}
			return MarshalContainer(item), key, nil
		}
		return nil, nil, nil
	}
	return n
}
<commit_msg>Allow extenstions of MarshalArray to know the index number, do not pass in structs, but struct pointers<commit_after>package node

import (
	"reflect"
	"github.com/c2stack/c2g/meta"
)

// Uses reflection to marshal data into go structs.  If you want to override
// then use:
//     data.Extend{
//         Node:MarshalContainer(obj),
//         OnSelect:...
//     }
func MarshalContainer(Obj interface{}) Node {
	s := &MyNode{
		Label:"MarshalContainer " + reflect.TypeOf(Obj).Name(),
		Peekable: Obj,
	}
	s.OnSelect = func(r ContainerRequest) (Node, error) {
		objVal := reflect.ValueOf(Obj)
		if objVal.Kind() == reflect.Interface || objVal.Kind() == reflect.Ptr {
			objVal = objVal.Elem()
		}
		fieldName := meta.MetaNameToFieldName(r.Meta.GetIdent())
		value := objVal.FieldByName(fieldName)
		if meta.IsList(r.Meta) {
			if value.Kind() == reflect.Map {
				marshal := &MarshalMap{
					Map:value.Interface(),
				}
				return marshal.Node(), nil
			} else {
				marshal := &MarshalArray{
					ArrayValue: &value,
				}
				return marshal.Node(), nil
			}
		} else {
			if value.Kind() == reflect.Struct {
				return MarshalContainer(value.Addr().Interface()), nil
			} else if value.CanAddr() {
				var child interface{}
				if r.New {
					childValue := reflect.New(value.Type().Elem())
					value.Set(childValue)
					child = childValue.Interface()
				} else {
					if value.IsNil() {
						return nil, nil
					}
					child = value.Interface()
				}
				if child != nil {
					return MarshalContainer(child), nil
				}
				return nil, nil
			}
		}
		return nil, nil
	}
	s.OnField = func(r FieldRequest, hnd *ValueHandle) (err error) {
		if r.Write {
			err = WriteField(r.Meta, Obj, hnd.Val)
		} else {
			hnd.Val, err = ReadField(r.Meta, Obj)
		}
		return
	}
	return s
}

type MarshalArray struct {
	ArrayValue   *reflect.Value
	OnNewItem    func() interface{}
	OnSelectItem func(item interface{}, index int) Node
}

func (self *MarshalArray) Node() Node {
	n := &MyNode{
		Label: "MarshalArray " + self.ArrayValue.Type().Name(),
		Peekable: self.ArrayValue.Interface(),
	}
	n.OnNext = func(r ListRequest) (next Node, key []*Value, err error) {
		var item interface{}
		var index int
		if r.New {
			var itemValue reflect.Value
			if self.OnNewItem != nil {
				item = self.OnNewItem()
				itemValue = reflect.ValueOf(item)
			} else {
				itemValue = reflect.New(self.ArrayValue.Type().Elem().Elem())
				item = itemValue.Interface()
			}
			self.ArrayValue.Set(reflect.Append(*self.ArrayValue, itemValue))
			index = self.ArrayValue.Len() - 1
		} else if len(r.Key) > 0 {
			// TODO: Should we hook into OnKey ?  Can default assume key in
			// array index which is, i feel, 90% of use cases?
			panic("Keys only implemented on MarshalMap, not MarshalArray")
		} else {
			if r.Row < self.ArrayValue.Len() {
				itemValue := self.ArrayValue.Index(r.Row)
				if itemValue.CanAddr() {
					// If we don't pass pointer, we will make edits on a copy
					item = itemValue.Addr().Interface()
				} else {
					item = itemValue.Interface()
				}
				index = r.Row
			}
		}
		if item != nil {
			if self.OnSelectItem != nil {
				return self.OnSelectItem(item, index), nil, nil
			}
			return MarshalContainer(item), nil, nil
		}
		return nil, nil, nil
	}
	return n
}

type MarshalMap struct {
	Map          interface{}
	OnNewItem    func(r ListRequest) interface{}
	OnSelectItem func(item interface{}) Node
}

func (self *MarshalMap) Node() Node {
	mapReflect := reflect.ValueOf(self.Map)
	n := &MyNode{
		Label: "MarshalMap " + mapReflect.Type().Name(),
		Peekable: self.Map,
	}
	index := NewIndex(self.Map)
	n.OnNext = func(r ListRequest) (next Node, key []*Value, err error) {
		var item interface{}
		key = r.Key
		if r.New {
			item = self.OnNewItem(r)
			mapKey := reflect.ValueOf(r.Key[0].Value())
			mapReflect.SetMapIndex(mapKey, reflect.ValueOf(item))
		} else if len(r.Key) > 0 {
			mapKey := reflect.ValueOf(r.Key[0].Value())
			itemVal := mapReflect.MapIndex(mapKey)
			if itemVal.IsValid() {
				item = itemVal.Interface()
			}
		} else {
			nextKey := index.NextKey(r.Row)
			if nextKey != NO_VALUE {
				key = SetValues(r.Meta.KeyMeta(), nextKey.Interface())
				itemVal := mapReflect.MapIndex(nextKey)
				item = itemVal.Interface()
			}
		}
		if item != nil {
			if self.OnSelectItem != nil {
				return self.OnSelectItem(item), key, nil
			}
			return MarshalContainer(item), key, nil
		}
		return nil, nil, nil
	}
	return n
}
<|endoftext|>


<commit_before>/*
 * Description: Behaviour tree in Go.
 * Copyright (c) 2014-2015 ShionRyuu <shionryuu@outlook.com>.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package node

/*
 * Wrapper for Selector
 * https://groups.google.com/d/msg/golang-nuts/BKztgPqN87M/iUfZQIcNYfYJ
 */
type IBevSelector interface {
	IBevNode
}

type BevSelector struct {
	IBevSelector
}

func NewSelector(node IBevSelector) *BevSelector {
	return &BevSelector{node}
}

func (w *BevSelector) Evaluate(input interface{}) bool {
	nodePrecondition := w.IBevSelector.GetNodePrecondition()
	return (nodePrecondition == nil || nodePrecondition.ExternalCondition(input)) && w.IBevSelector.Evaluate(input)
}

/*
 * Wrapper for Terminal
 */
type IBevTerminal interface {
	IBevSelector
	Enter(input interface{})
	Execute(input interface{}, output interface{}) BevRunningStatus
	Exit(input interface{}, exitStatus BevRunningStatus)
}

type BevTerminal struct {
	IBevTerminal
	nodeStatus TerminalNodeStaus
	needExit   bool
}

func NewTerminal(node IBevTerminal) *BevTerminal {
	return &BevTerminal{node, NodeReady, false}
}

func (w *BevTerminal) Evaluate(input interface{}) bool {
	nodePrecondition := w.IBevTerminal.GetNodePrecondition()
	return (nodePrecondition == nil || nodePrecondition.ExternalCondition(input)) && w.IBevTerminal.Evaluate(input)
}

func (node *BevTerminal) Transition(input interface{}) {
	if node.needExit {
		node.Exit(input, StateTransition)
	}

	node.SetActiveNode(nil)
	node.nodeStatus = NodeReady
	node.needExit = false
}

func (node *BevTerminal) Tick(input interface{}, output interface{}) BevRunningStatus {
	var bIsFinish BevRunningStatus = StateFinish

	if node.nodeStatus == NodeReady {
		node.Enter(input)
		node.needExit = true
		node.nodeStatus = NodeRunning
		node.SetActiveNode(node)
	}

	if node.nodeStatus == NodeRunning {
		bIsFinish = node.Execute(input, output)
		node.SetActiveNode(node)
		if bIsFinish == StateFinish || bIsFinish < 0 {
			node.nodeStatus = NodeFinish
		}
	}

	if node.nodeStatus == NodeFinish {
		if node.needExit {
			node.Exit(input, bIsFinish)
		}

		node.nodeStatus = NodeReady
		node.needExit = false
		node.SetActiveNode(nil)
	}

	return bIsFinish
}
<commit_msg>add reverse wrapper<commit_after>/*
 * Description: Behaviour tree in Go.
 * Copyright (c) 2014-2015 ShionRyuu <shionryuu@outlook.com>.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package node

/*
 * Wrapper for Selector
 * https://groups.google.com/d/msg/golang-nuts/BKztgPqN87M/iUfZQIcNYfYJ
 */
type IBevSelector interface {
	IBevNode
}

type BevSelector struct {
	IBevSelector
}

func NewSelector(node IBevSelector) *BevSelector {
	return &BevSelector{node}
}

func (w *BevSelector) Evaluate(input interface{}) bool {
	nodePrecondition := w.IBevSelector.GetNodePrecondition()
	return (nodePrecondition == nil || nodePrecondition.ExternalCondition(input)) && w.IBevSelector.Evaluate(input)
}

/*
 * Wrapper for Terminal
 */
type IBevTerminal interface {
	IBevNode
	Enter(input interface{})
	Execute(input interface{}, output interface{}) BevRunningStatus
	Exit(input interface{}, exitStatus BevRunningStatus)
}

type BevTerminal struct {
	IBevTerminal
	nodeStatus TerminalNodeStaus
	needExit   bool
}

func NewTerminal(node IBevTerminal) *BevTerminal {
	return &BevTerminal{node, NodeReady, false}
}

func (w *BevTerminal) Evaluate(input interface{}) bool {
	nodePrecondition := w.IBevTerminal.GetNodePrecondition()
	return (nodePrecondition == nil || nodePrecondition.ExternalCondition(input)) && w.IBevTerminal.Evaluate(input)
}

func (node *BevTerminal) Transition(input interface{}) {
	if node.needExit {
		node.Exit(input, StateTransition)
	}

	node.SetActiveNode(nil)
	node.nodeStatus = NodeReady
	node.needExit = false
}

func (node *BevTerminal) Tick(input interface{}, output interface{}) BevRunningStatus {
	var bIsFinish BevRunningStatus = StateFinish

	if node.nodeStatus == NodeReady {
		node.Enter(input)
		node.needExit = true
		node.nodeStatus = NodeRunning
		node.SetActiveNode(node)
	}

	if node.nodeStatus == NodeRunning {
		bIsFinish = node.Execute(input, output)
		node.SetActiveNode(node)
		if bIsFinish == StateFinish || bIsFinish < 0 {
			node.nodeStatus = NodeFinish
		}
	}

	if node.nodeStatus == NodeFinish {
		if node.needExit {
			node.Exit(input, bIsFinish)
		}

		node.nodeStatus = NodeReady
		node.needExit = false
		node.SetActiveNode(nil)
	}

	return bIsFinish
}

/*
 * Wrapper used to reverse the evaluate result of node
 */
type BevReverse struct {
	IBevNode
}

func NewReverse(node IBevNode) *BevReverse {
	return &BevReverse{node}
}

func (w *BevReverse) Evaluate(input interface{}) bool {
	return !w.IBevNode.Evaluate(input)
}
<|endoftext|>


<commit_before>/*
Copyright 2015 Nodetemple <hostmaster@nodetemple.com>

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 main

import (
	"os"
	"strings"

	"github.com/codegangsta/cli"
	"github.com/nodetemple/nodetemple/common"
	"github.com/nodetemple/nodetemple/nodectl/util"
	"github.com/nodetemple/nodetemple/nodectl/command"
)

func main() {
	app := cli.NewApp()
	app.Name = "nodectl"
	app.Usage = "CLI for an orchestration of CoreOS and Kubernetes cluster"
	app.Version = common.Version
	app.Flags = []cli.Flag{
		cli.StringFlag{Name: "providers, p", Usage: "A comma-separated list of providers ("+strings.Join(common.AvailableProviders, ",")+") to use when managing a cluster (format: 'provider:api-key', e.g.: do:54c4d6e7...,gce:7d63w9r4...)", EnvVar: util.EnvVarConv(app.Name, "providers"),},
		cli.BoolFlag{Name: "debug", Usage: "Print out more debug information to stderr"},
	}
	/*app.Before = func(c *cli.Context) error {
		if c.String("api-key") != "" {
			APIKey = c.String("api-key")
		}

		if APIKey == "" && !c.Bool("help") && !c.Bool("version") {
			return errors.New("must provide API Key via NODECTL_PROVIDERS environment variable or via CLI argument.")
		}

		switch c.String("format") {
		case "json":
			OutputFormat = c.String("format")
		case "yaml":
			OutputFormat = c.String("format")
		default:
			return fmt.Errorf("invalid output format: %q, available output options: json, yaml.", c.String("format"))
		}

		return nil
	}*/
	app.Commands = []cli.Command{
		command.DemoCmd(),
	}
	app.CommandNotFound = func(c *cli.Context, command string) {
		util.Err("unknown command '%v'\nRun '%v help [command]' for usage information", command, c.App.Name)
	}

	app.Run(os.Args)
}
<commit_msg>Simplify api usage<commit_after>/*
Copyright 2015 Nodetemple <hostmaster@nodetemple.com>

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 main

import (
	"os"
	"strings"

	"github.com/codegangsta/cli"
	"github.com/nodetemple/nodetemple/common"
	"github.com/nodetemple/nodetemple/nodectl/util"
	"github.com/nodetemple/nodetemple/nodectl/command"
)

func main() {
	app := cli.NewApp()
	app.Name = "nodectl"
	app.Usage = "CLI for an orchestration of CoreOS and Kubernetes cluster"
	app.Version = common.Version
	app.Flags = []cli.Flag{
		cli.StringFlag{Name: "providers, p", Usage: "A comma-separated list of IaaS providers ("+strings.Join(common.AvailableProviders, ",")+"), e.g.: do:do-api-key,gce:gce-api-key", EnvVar: util.EnvVarConv(app.Name, "providers"),},
		cli.BoolFlag{Name: "debug", Usage: "Print out more debug information to stderr"},
	}
	/*app.Before = func(c *cli.Context) error {
		if c.String("api-key") != "" {
			APIKey = c.String("api-key")
		}

		if APIKey == "" && !c.Bool("help") && !c.Bool("version") {
			return errors.New("must provide API Key via NODECTL_PROVIDERS environment variable or via CLI argument.")
		}

		switch c.String("format") {
		case "json":
			OutputFormat = c.String("format")
		case "yaml":
			OutputFormat = c.String("format")
		default:
			return fmt.Errorf("invalid output format: %q, available output options: json, yaml.", c.String("format"))
		}

		return nil
	}*/
	app.Commands = []cli.Command{
		command.DemoCmd(),
	}
	app.CommandNotFound = func(c *cli.Context, command string) {
		util.Err("unknown command '%v'\nRun '%v help [command]' for usage information", command, c.App.Name)
	}

	app.Run(os.Args)
}
<|endoftext|>


<commit_before>/*

A PWM example by @Drahoslav7, using the go-rpio library

Toggles a LED on physical pin 19 (mcu pin 10)
Connect a LED with resistor from pin 19 to ground.

*/

package main

import (
        "os"
        "time"
        "github.com/stianeikeland/go-rpio"
)

func main() {
        err := rpio.Open()
        if err != nil {
                os.Exit(1)
        }
        defer rpio.Close()

        pin := rpio.Pin(19)
        pin.Mode(rpio.Pwm)
        pin.Freq(64000)
        pin.DutyCycle(0, 32)
        // the LED will be blinking at 2000Hz
        // (source frequency divided by cycle length => 64000/32 = 2000)

        // five times smoothly fade in and out
        for i := 0; i < 5; i++ {
                for i := uint32(0); i < 32; i++ { // increasing brightness
                        pin.DutyCycle(i, 32)
                        time.Sleep(time.Second/32)
                }
                for i := uint32(32); i > 0; i-- { // decreasing brightness
                        pin.DutyCycle(i, 32)
                        time.Sleep(time.Second/32)
                }
        }
}<commit_msg>Use correct pin in the instructions<commit_after>/*

A PWM example by @Drahoslav7, using the go-rpio library

Toggles a LED on physical pin 35 (GPIO pin 19)
Connect a LED with resistor from pin 35 to ground.

*/

package main

import (
        "os"
        "time"
        "github.com/stianeikeland/go-rpio"
)

func main() {
        err := rpio.Open()
        if err != nil {
                os.Exit(1)
        }
        defer rpio.Close()

        pin := rpio.Pin(19)
        pin.Mode(rpio.Pwm)
        pin.Freq(64000)
        pin.DutyCycle(0, 32)
        // the LED will be blinking at 2000Hz
        // (source frequency divided by cycle length => 64000/32 = 2000)

        // five times smoothly fade in and out
        for i := 0; i < 5; i++ {
                for i := uint32(0); i < 32; i++ { // increasing brightness
                        pin.DutyCycle(i, 32)
                        time.Sleep(time.Second/32)
                }
                for i := uint32(32); i > 0; i-- { // decreasing brightness
                        pin.DutyCycle(i, 32)
                        time.Sleep(time.Second/32)
                }
        }
}
<|endoftext|>


<commit_before>package freetds

import ("testing"; "os";"fmt")

const CREATE_DB_SCRIPT = `
if exists(select * from sys.tables where name = 'freetds_types')
drop table freetds_types
;
create table freetds_types (
  int int null,
  long bigint null,
  smallint smallint null,
  tinyint tinyint null,
  varchar varchar(255) null,
  nvarchar nvarchar(255) null,
  char char(255) null,
  nchar nchar(255) null,
  text text null,
  ntext ntext null,
  datetime datetime null,
  smalldatetime smalldatetime null,
  money money null,
  smallmoney smallmoney null,
  real real null,
  float float(53) null,
  bit bit null,
  timestamp timestamp null,
  binary binary(10) null
)
;

insert into freetds_types (int, long, smallint, tinyint, varchar, nvarchar, char, nchar, text, ntext, datetime, smalldatetime, money, smallmoney, real, float, bit, binary)
values (2147483647,   9223372036854775807, 32767, 255, 'išo medo u dućan   ','išo medo u dućan    2','išo medo u dućan    3','išo medo u dućan    4','išo medo u dućan    5','išo medo u dućan    6', '1972-08-08T10:11:12','1972-08-08T10:11:12', 1234.5678,   1234.5678,  1234.5678,  1234.5678, 0, 0x123567890)

insert into freetds_types (int, long, smallint, tinyint, varchar, nvarchar, char, nchar, text, ntext, datetime, smalldatetime, money, smallmoney, real, float, bit, binary)
values (-2147483648, -9223372036854775808, -32768,  0, 'nije reko dobar dan','nije reko dobar dan 2','nije reko dobar dan 3','nije reko dobar dan 4','nije reko dobar dan 5','nije reko dobar dan 6', '1998-10-10T16:17:18','1998-10-10T16:17:18', -1234.5678, -1234.5678, -1234.5678, -1234.5678, 1, 0x0987654321abcd)

insert into freetds_types (int) values (3)
;

`

func ConnectToTestDb(t *testing.T) (*Conn) {
  db   := os.Getenv("GOFREETDS_DB")
  user := os.Getenv("GOFREETDS_USER")
  pwd  := os.Getenv("GOFREETDS_PWD")
  host := os.Getenv("GOFREETDS_HOST")
  conn, err := Connect(user, pwd, host, db)
  if err != nil {
    t.Errorf("can't connect to the test database")
    return nil
  }
  return conn
}

func TestConnect(t *testing.T) {
  conn := ConnectToTestDb(t)
  if conn != nil {
    defer conn.Close()
  }
}

func TestCreateTable(t *testing.T) {
  conn := ConnectToTestDb(t)
  if conn == nil {
    return
  }
  defer conn.Close()
  _, err := conn.Exec(CREATE_DB_SCRIPT)
  if err != nil {
    t.Error(err)
  }
}

func TestReading(t *testing.T) {
  conn := ConnectToTestDb(t)
  if conn == nil {
    return
  }
  defer conn.Close()

  results, err := conn.Exec("select * from freetds_types")
  if err != nil {
    fmt.Printf("error: %s\n%s\n%s", err, conn.Message, conn.Error)
    return
  }
  fmt.Printf("results %v", results)
  for _, r := range results {
    fmt.Printf("\n\nColums:\n")
    for j, c := range r.Columns {
      fmt.Printf("\t%3d%20s%10d%10d\n", j, c.Name, c.DbType, c.DbSize)
    }
    for i, _ := range r.Rows {
      for j, _ := range r.Columns {
        fmt.Printf("value[%2d, %2d]: %v\n", i, j, r.Rows[i][j])
//        fmt.Printf("%20v", r.Rows[i][j])
      }
      fmt.Printf("\n")
    }
    fmt.Printf("rows affected: %d\n", r.RowsAffected)
    fmt.Printf("return value: %d\n", r.ReturnValue)
  }

}
<commit_msg>testing stored procedure return value<commit_after>package freetds

import ("testing"; "os";"fmt")

var CREATE_DB_SCRIPTS = [...]string{`
if exists(select * from sys.tables where name = 'freetds_types')
drop table freetds_types
;
create table freetds_types (
  int int null,
  long bigint null,
  smallint smallint null,
  tinyint tinyint null,
  varchar varchar(255) null,
  nvarchar nvarchar(255) null,
  char char(255) null,
  nchar nchar(255) null,
  text text null,
  ntext ntext null,
  datetime datetime null,
  smalldatetime smalldatetime null,
  money money null,
  smallmoney smallmoney null,
  real real null,
  float float(53) null,
  bit bit null,
  timestamp timestamp null,
  binary binary(10) null
)
;

insert into freetds_types (int, long, smallint, tinyint, varchar, nvarchar, char, nchar, text, ntext, datetime, smalldatetime, money, smallmoney, real, float, bit, binary)
values (2147483647,   9223372036854775807, 32767, 255, 'išo medo u dućan   ','išo medo u dućan    2','išo medo u dućan    3','išo medo u dućan    4','išo medo u dućan    5','išo medo u dućan    6', '1972-08-08T10:11:12','1972-08-08T10:11:12', 1234.5678,   1234.5678,  1234.5678,  1234.5678, 0, 0x123567890)

insert into freetds_types (int, long, smallint, tinyint, varchar, nvarchar, char, nchar, text, ntext, datetime, smalldatetime, money, smallmoney, real, float, bit, binary)
values (-2147483648, -9223372036854775808, -32768,  0, 'nije reko dobar dan','nije reko dobar dan 2','nije reko dobar dan 3','nije reko dobar dan 4','nije reko dobar dan 5','nije reko dobar dan 6', '1998-10-10T16:17:18','1998-10-10T16:17:18', -1234.5678, -1234.5678, -1234.5678, -1234.5678, 1, 0x0987654321abcd)

insert into freetds_types (int) values (3)
`,`
if exists(select * from sys.procedures where name = 'freetds_return_value')
  drop procedure freetds_return_value
`,`
create procedure freetds_return_value as
  return -5`}

func ConnectToTestDb(t *testing.T) (*Conn) {
  db   := os.Getenv("GOFREETDS_DB")
  user := os.Getenv("GOFREETDS_USER")
  pwd  := os.Getenv("GOFREETDS_PWD")
  host := os.Getenv("GOFREETDS_HOST")
  conn, err := Connect(user, pwd, host, db)
  if err != nil {
    t.Errorf("can't connect to the test database")
    return nil
  }
  return conn
}

func TestConnect(t *testing.T) {
  conn := ConnectToTestDb(t)
  if conn != nil {
    defer conn.Close()
  }
}

func TestCreateTable(t *testing.T) {
  conn := ConnectToTestDb(t)
  if conn == nil {
    return
  }
  defer conn.Close()
  for _, s := range CREATE_DB_SCRIPTS {
    _, err := conn.Exec(s)
    if err != nil {
      t.Error(err)
    }
  }
}

func TestStoredProcedureReturnValue(t *testing.T) {
  conn := ConnectToTestDb(t)
  if conn == nil {
    return
  }
  defer conn.Close()
  results, err := conn.Exec("exec freetds_return_value")
  if err != nil {
    t.Error(err)
  }
  if results[0].ReturnValue != -5 {
    t.Errorf("expected return value was -5 got %d", results[0].ReturnValue)
  }
}

func TestReading(t *testing.T) {
  conn := ConnectToTestDb(t)
  if conn == nil {
    return
  }
  defer conn.Close()

  results, err := conn.Exec("select * from freetds_types")
  if err != nil {
    fmt.Printf("error: %s\n%s\n%s", err, conn.Message, conn.Error)
    return
  }
  fmt.Printf("results %v", results)
  for _, r := range results {
    fmt.Printf("\n\nColums:\n")
    for j, c := range r.Columns {
      fmt.Printf("\t%3d%20s%10d%10d\n", j, c.Name, c.DbType, c.DbSize)
    }
    for i, _ := range r.Rows {
      for j, _ := range r.Columns {
        fmt.Printf("value[%2d, %2d]: %v\n", i, j, r.Rows[i][j])
//        fmt.Printf("%20v", r.Rows[i][j])
      }
      fmt.Printf("\n")
    }
    fmt.Printf("rows affected: %d\n", r.RowsAffected)
    fmt.Printf("return value: %d\n", r.ReturnValue)
  }

}
<|endoftext|>


<commit_before>// Copyright 2017 Jeff Foley. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

package format

import (
	"fmt"
	"io"
	"net"
	"strconv"
	"strings"

	amassnet "github.com/OWASP/Amass/v3/net"
	"github.com/OWASP/Amass/v3/requests"
	"github.com/fatih/color"
)

// Banner is the ASCII art logo used within help output.
const Banner = `
        .+++:.            :                             .+++.
      +W@@@@@@8        &+W@#               o8W8:      +W@@@@@@#.   oW@@@W#+
     &@#+   .o@##.    .@@@o@W.o@@o       :@@#&W8o    .@#:  .:oW+  .@#+++&#&
    +@&        &@&     #@8 +@W@&8@+     :@W.   +@8   +@:          .@8
    8@          @@     8@o  8@8  WW    .@W      W@+  .@W.          o@#:
    WW          &@o    &@:  o@+  o@+   #@.      8@o   +W@#+.        +W@8:
    #@          :@W    &@+  &@+   @8  :@o       o@o     oW@@W+        oW@8
    o@+          @@&   &@+  &@+   #@  &@.      .W@W       .+#@&         o@W.
     WW         +@W@8. &@+  :&    o@+ #@      :@W&@&         &@:  ..     :@o
     :@W:      o@# +Wo &@+        :W: +@W&o++o@W. &@&  8@#o+&@W.  #@:    o@+
      :W@@WWWW@@8       +              :&W@@@@&    &W  .o#@@W&.   :W@WWW@@&
        +o&&&&+.                                                    +oooo.
`

const (
	// Version is used to display the current version of Amass.
	Version = "v3.11.9"

	// Author is used to display the Amass Project Team.
	Author = "OWASP Amass Project - @owaspamass"

	// Description is the slogan for the Amass Project.
	Description = "In-depth Attack Surface Mapping and Asset Discovery"
)

var (
	// Colors used to ease the reading of program output
	g      = color.New(color.FgHiGreen)
	b      = color.New(color.FgHiBlue)
	yellow = color.New(color.FgHiYellow).SprintFunc()
	green  = color.New(color.FgHiGreen).SprintFunc()
	blue   = color.New(color.FgHiBlue).SprintFunc()
)

// ASNSummaryData stores information related to discovered ASs and netblocks.
type ASNSummaryData struct {
	Name      string
	Netblocks map[string]int
}

// UpdateSummaryData updates the summary maps using the provided requests.Output data.
func UpdateSummaryData(output *requests.Output, tags map[string]int, asns map[int]*ASNSummaryData) {
	tags[output.Tag]++

	for _, addr := range output.Addresses {
		if addr.CIDRStr == "" {
			continue
		}

		data, found := asns[addr.ASN]
		if !found {
			asns[addr.ASN] = &ASNSummaryData{
				Name:      addr.Description,
				Netblocks: make(map[string]int),
			}
			data = asns[addr.ASN]
		}
		// Increment how many IPs were in this netblock
		data.Netblocks[addr.CIDRStr]++
	}
}

// PrintEnumerationSummary outputs the summary information utilized by the command-line tools.
func PrintEnumerationSummary(total int, tags map[string]int, asns map[int]*ASNSummaryData, demo bool) {
	FprintEnumerationSummary(color.Error, total, tags, asns, demo)
}

// FprintEnumerationSummary outputs the summary information utilized by the command-line tools.
func FprintEnumerationSummary(out io.Writer, total int, tags map[string]int, asns map[int]*ASNSummaryData, demo bool) {
	pad := func(num int, chr string) {
		for i := 0; i < num; i++ {
			b.Fprint(out, chr)
		}
	}

	fmt.Fprintln(out)
	// Print the header information
	title := "OWASP Amass "
	site := "https://github.com/OWASP/Amass"
	b.Fprint(out, title+Version)
	num := 80 - (len(title) + len(Version) + len(site))
	pad(num, " ")
	b.Fprintf(out, "%s\n", site)
	pad(8, "----------")
	fmt.Fprintf(out, "\n%s%s", yellow(strconv.Itoa(total)), green(" names discovered - "))
	// Print the stats using tag information
	num, length := 1, len(tags)
	for k, v := range tags {
		fmt.Fprintf(out, "%s: %s", green(k), yellow(strconv.Itoa(v)))
		if num < length {
			g.Fprint(out, ", ")
		}
		num++
	}
	fmt.Fprintln(out)

	if len(asns) == 0 {
		return
	}
	// Another line gets printed
	pad(8, "----------")
	fmt.Fprintln(out)
	// Print the ASN and netblock information
	for asn, data := range asns {
		asnstr := strconv.Itoa(asn)
		datastr := data.Name

		if demo && asn > 0 {
			asnstr = censorString(asnstr, 0, len(asnstr))
			datastr = censorString(datastr, 0, len(datastr))
		}
		fmt.Fprintf(out, "%s%s %s %s\n", blue("ASN: "), yellow(asnstr), green("-"), green(datastr))

		for cidr, ips := range data.Netblocks {
			countstr := strconv.Itoa(ips)
			cidrstr := cidr

			if demo {
				cidrstr = censorNetBlock(cidrstr)
			}

			countstr = fmt.Sprintf("\t%-4s", countstr)
			cidrstr = fmt.Sprintf("\t%-18s", cidrstr)
			fmt.Fprintf(out, "%s%s %s\n", yellow(cidrstr), yellow(countstr), blue("Subdomain Name(s)"))
		}
	}
}

// PrintBanner outputs the Amass banner the same for all tools.
func PrintBanner() {
	FprintBanner(color.Error)
}

// FprintBanner outputs the Amass banner the same for all tools.
func FprintBanner(out io.Writer) {
	y := color.New(color.FgHiYellow)
	r := color.New(color.FgHiRed)
	rightmost := 76

	pad := func(num int) {
		for i := 0; i < num; i++ {
			fmt.Fprint(out, " ")
		}
	}
	r.Fprintln(out, Banner)
	pad(rightmost - len(Version))
	y.Fprintln(out, Version)
	pad(rightmost - len(Author))
	y.Fprintln(out, Author)
	pad(rightmost - len(Description))
	y.Fprintf(out, "%s\n\n\n", Description)
}

func censorDomain(input string) string {
	return censorString(input, strings.Index(input, "."), len(input))
}

func censorIP(input string) string {
	return censorString(input, 0, strings.LastIndex(input, "."))
}

func censorNetBlock(input string) string {
	return censorString(input, 0, strings.Index(input, "/"))
}

func censorString(input string, start, end int) string {
	runes := []rune(input)
	for i := start; i < end; i++ {
		if runes[i] == '.' ||
			runes[i] == '/' ||
			runes[i] == '-' ||
			runes[i] == ' ' {
			continue
		}
		runes[i] = 'x'
	}
	return string(runes)
}

// OutputLineParts returns the parts of a line to be printed for a requests.Output.
func OutputLineParts(out *requests.Output, src, addrs, demo bool) (source, name, ips string) {
	if src {
		source = fmt.Sprintf("%-18s", "["+out.Sources[0]+"] ")
	}
	if addrs {
		for i, a := range out.Addresses {
			if i != 0 {
				ips += ","
			}
			if demo {
				ips += censorIP(a.Address.String())
			} else {
				ips += a.Address.String()
			}
		}
		if ips == "" {
			ips = "N/A"
		}
	}
	name = out.Name
	if demo {
		name = censorDomain(name)
	}
	return
}

// DesiredAddrTypes removes undesired address types from the AddressInfo slice.
func DesiredAddrTypes(addrs []requests.AddressInfo, ipv4, ipv6 bool) []requests.AddressInfo {
	if !ipv4 && !ipv6 {
		return addrs
	}

	var keep []requests.AddressInfo
	for _, addr := range addrs {
		if amassnet.IsIPv4(addr.Address) && !ipv4 {
			continue
		} else if amassnet.IsIPv6(addr.Address) && !ipv6 {
			continue
		}
		keep = append(keep, addr)
	}
	return keep
}

// InterfaceInfo returns network interface information specific to the current host.
func InterfaceInfo() string {
	var output string

	if ifaces, err := net.Interfaces(); err == nil {
		for _, i := range ifaces {
			addrs, err := i.Addrs()
			if err != nil {
				continue
			}
			output += fmt.Sprintf("%s%s%s\n", blue(i.Name+": "), green("flags="), yellow("<"+strings.ToUpper(i.Flags.String()+">")))
			if i.HardwareAddr.String() != "" {
				output += fmt.Sprintf("\t%s%s\n", green("ether: "), yellow(i.HardwareAddr.String()))
			}
			for _, addr := range addrs {
				inet := "inet"
				if a, ok := addr.(*net.IPNet); ok && amassnet.IsIPv6(a.IP) {
					inet += "6"
				}
				inet += ": "
				output += fmt.Sprintf("\t%s%s\n", green(inet), yellow(addr.String()))
			}
		}
	}

	return output
}
<commit_msg>v3.11.10 release<commit_after>// Copyright 2017-2021 Jeff Foley. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

package format

import (
	"fmt"
	"io"
	"net"
	"strconv"
	"strings"

	amassnet "github.com/OWASP/Amass/v3/net"
	"github.com/OWASP/Amass/v3/requests"
	"github.com/fatih/color"
)

// Banner is the ASCII art logo used within help output.
const Banner = `
        .+++:.            :                             .+++.
      +W@@@@@@8        &+W@#               o8W8:      +W@@@@@@#.   oW@@@W#+
     &@#+   .o@##.    .@@@o@W.o@@o       :@@#&W8o    .@#:  .:oW+  .@#+++&#&
    +@&        &@&     #@8 +@W@&8@+     :@W.   +@8   +@:          .@8
    8@          @@     8@o  8@8  WW    .@W      W@+  .@W.          o@#:
    WW          &@o    &@:  o@+  o@+   #@.      8@o   +W@#+.        +W@8:
    #@          :@W    &@+  &@+   @8  :@o       o@o     oW@@W+        oW@8
    o@+          @@&   &@+  &@+   #@  &@.      .W@W       .+#@&         o@W.
     WW         +@W@8. &@+  :&    o@+ #@      :@W&@&         &@:  ..     :@o
     :@W:      o@# +Wo &@+        :W: +@W&o++o@W. &@&  8@#o+&@W.  #@:    o@+
      :W@@WWWW@@8       +              :&W@@@@&    &W  .o#@@W&.   :W@WWW@@&
        +o&&&&+.                                                    +oooo.
`

const (
	// Version is used to display the current version of Amass.
	Version = "v3.11.10"

	// Author is used to display the Amass Project Team.
	Author = "OWASP Amass Project - @owaspamass"

	// Description is the slogan for the Amass Project.
	Description = "In-depth Attack Surface Mapping and Asset Discovery"
)

var (
	// Colors used to ease the reading of program output
	g      = color.New(color.FgHiGreen)
	b      = color.New(color.FgHiBlue)
	yellow = color.New(color.FgHiYellow).SprintFunc()
	green  = color.New(color.FgHiGreen).SprintFunc()
	blue   = color.New(color.FgHiBlue).SprintFunc()
)

// ASNSummaryData stores information related to discovered ASs and netblocks.
type ASNSummaryData struct {
	Name      string
	Netblocks map[string]int
}

// UpdateSummaryData updates the summary maps using the provided requests.Output data.
func UpdateSummaryData(output *requests.Output, tags map[string]int, asns map[int]*ASNSummaryData) {
	tags[output.Tag]++

	for _, addr := range output.Addresses {
		if addr.CIDRStr == "" {
			continue
		}

		data, found := asns[addr.ASN]
		if !found {
			asns[addr.ASN] = &ASNSummaryData{
				Name:      addr.Description,
				Netblocks: make(map[string]int),
			}
			data = asns[addr.ASN]
		}
		// Increment how many IPs were in this netblock
		data.Netblocks[addr.CIDRStr]++
	}
}

// PrintEnumerationSummary outputs the summary information utilized by the command-line tools.
func PrintEnumerationSummary(total int, tags map[string]int, asns map[int]*ASNSummaryData, demo bool) {
	FprintEnumerationSummary(color.Error, total, tags, asns, demo)
}

// FprintEnumerationSummary outputs the summary information utilized by the command-line tools.
func FprintEnumerationSummary(out io.Writer, total int, tags map[string]int, asns map[int]*ASNSummaryData, demo bool) {
	pad := func(num int, chr string) {
		for i := 0; i < num; i++ {
			b.Fprint(out, chr)
		}
	}

	fmt.Fprintln(out)
	// Print the header information
	title := "OWASP Amass "
	site := "https://github.com/OWASP/Amass"
	b.Fprint(out, title+Version)
	num := 80 - (len(title) + len(Version) + len(site))
	pad(num, " ")
	b.Fprintf(out, "%s\n", site)
	pad(8, "----------")
	fmt.Fprintf(out, "\n%s%s", yellow(strconv.Itoa(total)), green(" names discovered - "))
	// Print the stats using tag information
	num, length := 1, len(tags)
	for k, v := range tags {
		fmt.Fprintf(out, "%s: %s", green(k), yellow(strconv.Itoa(v)))
		if num < length {
			g.Fprint(out, ", ")
		}
		num++
	}
	fmt.Fprintln(out)

	if len(asns) == 0 {
		return
	}
	// Another line gets printed
	pad(8, "----------")
	fmt.Fprintln(out)
	// Print the ASN and netblock information
	for asn, data := range asns {
		asnstr := strconv.Itoa(asn)
		datastr := data.Name

		if demo && asn > 0 {
			asnstr = censorString(asnstr, 0, len(asnstr))
			datastr = censorString(datastr, 0, len(datastr))
		}
		fmt.Fprintf(out, "%s%s %s %s\n", blue("ASN: "), yellow(asnstr), green("-"), green(datastr))

		for cidr, ips := range data.Netblocks {
			countstr := strconv.Itoa(ips)
			cidrstr := cidr

			if demo {
				cidrstr = censorNetBlock(cidrstr)
			}

			countstr = fmt.Sprintf("\t%-4s", countstr)
			cidrstr = fmt.Sprintf("\t%-18s", cidrstr)
			fmt.Fprintf(out, "%s%s %s\n", yellow(cidrstr), yellow(countstr), blue("Subdomain Name(s)"))
		}
	}
}

// PrintBanner outputs the Amass banner the same for all tools.
func PrintBanner() {
	FprintBanner(color.Error)
}

// FprintBanner outputs the Amass banner the same for all tools.
func FprintBanner(out io.Writer) {
	y := color.New(color.FgHiYellow)
	r := color.New(color.FgHiRed)
	rightmost := 76

	pad := func(num int) {
		for i := 0; i < num; i++ {
			fmt.Fprint(out, " ")
		}
	}
	r.Fprintln(out, Banner)
	pad(rightmost - len(Version))
	y.Fprintln(out, Version)
	pad(rightmost - len(Author))
	y.Fprintln(out, Author)
	pad(rightmost - len(Description))
	y.Fprintf(out, "%s\n\n\n", Description)
}

func censorDomain(input string) string {
	return censorString(input, strings.Index(input, "."), len(input))
}

func censorIP(input string) string {
	return censorString(input, 0, strings.LastIndex(input, "."))
}

func censorNetBlock(input string) string {
	return censorString(input, 0, strings.Index(input, "/"))
}

func censorString(input string, start, end int) string {
	runes := []rune(input)
	for i := start; i < end; i++ {
		if runes[i] == '.' ||
			runes[i] == '/' ||
			runes[i] == '-' ||
			runes[i] == ' ' {
			continue
		}
		runes[i] = 'x'
	}
	return string(runes)
}

// OutputLineParts returns the parts of a line to be printed for a requests.Output.
func OutputLineParts(out *requests.Output, src, addrs, demo bool) (source, name, ips string) {
	if src {
		source = fmt.Sprintf("%-18s", "["+out.Sources[0]+"] ")
	}
	if addrs {
		for i, a := range out.Addresses {
			if i != 0 {
				ips += ","
			}
			if demo {
				ips += censorIP(a.Address.String())
			} else {
				ips += a.Address.String()
			}
		}
		if ips == "" {
			ips = "N/A"
		}
	}
	name = out.Name
	if demo {
		name = censorDomain(name)
	}
	return
}

// DesiredAddrTypes removes undesired address types from the AddressInfo slice.
func DesiredAddrTypes(addrs []requests.AddressInfo, ipv4, ipv6 bool) []requests.AddressInfo {
	if !ipv4 && !ipv6 {
		return addrs
	}

	var keep []requests.AddressInfo
	for _, addr := range addrs {
		if amassnet.IsIPv4(addr.Address) && !ipv4 {
			continue
		} else if amassnet.IsIPv6(addr.Address) && !ipv6 {
			continue
		}
		keep = append(keep, addr)
	}
	return keep
}

// InterfaceInfo returns network interface information specific to the current host.
func InterfaceInfo() string {
	var output string

	if ifaces, err := net.Interfaces(); err == nil {
		for _, i := range ifaces {
			addrs, err := i.Addrs()
			if err != nil {
				continue
			}
			output += fmt.Sprintf("%s%s%s\n", blue(i.Name+": "), green("flags="), yellow("<"+strings.ToUpper(i.Flags.String()+">")))
			if i.HardwareAddr.String() != "" {
				output += fmt.Sprintf("\t%s%s\n", green("ether: "), yellow(i.HardwareAddr.String()))
			}
			for _, addr := range addrs {
				inet := "inet"
				if a, ok := addr.(*net.IPNet); ok && amassnet.IsIPv6(a.IP) {
					inet += "6"
				}
				inet += ": "
				output += fmt.Sprintf("\t%s%s\n", green(inet), yellow(addr.String()))
			}
		}
	}

	return output
}
<|endoftext|>


<commit_before>// +build linux

package nsinit

import (
	"fmt"
	"github.com/dotcloud/docker/pkg/label"
	"github.com/dotcloud/docker/pkg/libcontainer"
	"github.com/dotcloud/docker/pkg/system"
	"io/ioutil"
	"os"
	"path/filepath"
	"syscall"
)

// default mount point flags
const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV

// setupNewMountNamespace is used to initialize a new mount namespace for an new
// container in the rootfs that is specified.
//
// There is no need to unmount the new mounts because as soon as the mount namespace
// is no longer in use, the mounts will be removed automatically
func setupNewMountNamespace(rootfs string, bindMounts []libcontainer.Mount, console string, readonly, noPivotRoot bool, mountLabel string) error {
	flag := syscall.MS_PRIVATE
	if noPivotRoot {
		flag = syscall.MS_SLAVE
	}
	if err := system.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil {
		return fmt.Errorf("mounting / as slave %s", err)
	}
	if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
		return fmt.Errorf("mouting %s as bind %s", rootfs, err)
	}
	if err := mountSystem(rootfs, mountLabel); err != nil {
		return fmt.Errorf("mount system %s", err)
	}

	for _, m := range bindMounts {
		flags := syscall.MS_BIND | syscall.MS_REC
		if !m.Writable {
			flags = flags | syscall.MS_RDONLY
		}
		dest := filepath.Join(rootfs, m.Destination)
		if err := system.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil {
			return fmt.Errorf("mounting %s into %s %s", m.Source, dest, err)
		}
		if m.Private {
			if err := system.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil {
				return fmt.Errorf("mounting %s private %s", dest, err)
			}
		}
	}

	if err := copyDevNodes(rootfs); err != nil {
		return fmt.Errorf("copy dev nodes %s", err)
	}
	// In non-privileged mode, this fails. Discard the error.
	setupLoopbackDevices(rootfs)
	if err := setupPtmx(rootfs, console, mountLabel); err != nil {
		return err
	}
	if err := system.Chdir(rootfs); err != nil {
		return fmt.Errorf("chdir into %s %s", rootfs, err)
	}

	if noPivotRoot {
		if err := rootMsMove(rootfs); err != nil {
			return err
		}
	} else {
		if err := rootPivot(rootfs); err != nil {
			return err
		}
	}

	if readonly {
		if err := system.Mount("/", "/", "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, ""); err != nil {
			return fmt.Errorf("mounting %s as readonly %s", rootfs, err)
		}
	}

	system.Umask(0022)

	return nil
}

// use a pivot root to setup the rootfs
func rootPivot(rootfs string) error {
	pivotDir, err := ioutil.TempDir(rootfs, ".pivot_root")
	if err != nil {
		return fmt.Errorf("can't create pivot_root dir %s", pivotDir, err)
	}
	if err := system.Pivotroot(rootfs, pivotDir); err != nil {
		return fmt.Errorf("pivot_root %s", err)
	}
	if err := system.Chdir("/"); err != nil {
		return fmt.Errorf("chdir / %s", err)
	}
	// path to pivot dir now changed, update
	pivotDir = filepath.Join("/", filepath.Base(pivotDir))
	if err := system.Unmount(pivotDir, syscall.MNT_DETACH); err != nil {
		return fmt.Errorf("unmount pivot_root dir %s", err)
	}
	if err := os.Remove(pivotDir); err != nil {
		return fmt.Errorf("remove pivot_root dir %s", err)
	}
	return nil
}

// use MS_MOVE and chroot to setup the rootfs
func rootMsMove(rootfs string) error {
	if err := system.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil {
		return fmt.Errorf("mount move %s into / %s", rootfs, err)
	}
	if err := system.Chroot("."); err != nil {
		return fmt.Errorf("chroot . %s", err)
	}
	if err := system.Chdir("/"); err != nil {
		return fmt.Errorf("chdir / %s", err)
	}
	return nil
}

// copyDevNodes mknods the hosts devices so the new container has access to them
func copyDevNodes(rootfs string) error {
	oldMask := system.Umask(0000)
	defer system.Umask(oldMask)

	for _, node := range []string{
		"null",
		"zero",
		"full",
		"random",
		"urandom",
		"tty",
	} {
		if err := copyDevNode(rootfs, node); err != nil {
			return err
		}
	}
	return nil
}

func setupLoopbackDevices(rootfs string) error {
	for i := 0; ; i++ {
		if err := copyDevNode(rootfs, fmt.Sprintf("loop%d", i)); err != nil {
			if !os.IsNotExist(err) {
				return err
			}
			break
		}

	}
	return nil
}

func copyDevNode(rootfs, node string) error {
	stat, err := os.Stat(filepath.Join("/dev", node))
	if err != nil {
		return err
	}
	var (
		dest = filepath.Join(rootfs, "dev", node)
		st   = stat.Sys().(*syscall.Stat_t)
	)
	if err := system.Mknod(dest, st.Mode, int(st.Rdev)); err != nil && !os.IsExist(err) {
		return fmt.Errorf("copy %s %s", node, err)
	}
	return nil
}

// setupConsole ensures that the container has a proper /dev/console setup
func setupConsole(rootfs, console string, mountLabel string) error {
	oldMask := system.Umask(0000)
	defer system.Umask(oldMask)

	stat, err := os.Stat(console)
	if err != nil {
		return fmt.Errorf("stat console %s %s", console, err)
	}
	var (
		st   = stat.Sys().(*syscall.Stat_t)
		dest = filepath.Join(rootfs, "dev/console")
	)
	if err := os.Remove(dest); err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("remove %s %s", dest, err)
	}
	if err := os.Chmod(console, 0600); err != nil {
		return err
	}
	if err := os.Chown(console, 0, 0); err != nil {
		return err
	}
	if err := system.Mknod(dest, (st.Mode&^07777)|0600, int(st.Rdev)); err != nil {
		return fmt.Errorf("mknod %s %s", dest, err)
	}
	if err := label.SetFileLabel(console, mountLabel); err != nil {
		return fmt.Errorf("SetFileLabel Failed %s %s", dest, err)
	}
	if err := system.Mount(console, dest, "bind", syscall.MS_BIND, ""); err != nil {
		return fmt.Errorf("bind %s to %s %s", console, dest, err)
	}
	return nil
}

// mountSystem sets up linux specific system mounts like sys, proc, shm, and devpts
// inside the mount namespace
func mountSystem(rootfs string, mountLabel string) error {
	for _, m := range []struct {
		source string
		path   string
		device string
		flags  int
		data   string
	}{
		{source: "proc", path: filepath.Join(rootfs, "proc"), device: "proc", flags: defaultMountFlags},
		{source: "sysfs", path: filepath.Join(rootfs, "sys"), device: "sysfs", flags: defaultMountFlags},
		{source: "shm", path: filepath.Join(rootfs, "dev", "shm"), device: "tmpfs", flags: defaultMountFlags, data: label.FormatMountLabel("mode=1755,size=65536k", mountLabel)},
		{source: "devpts", path: filepath.Join(rootfs, "dev", "pts"), device: "devpts", flags: syscall.MS_NOSUID | syscall.MS_NOEXEC, data: label.FormatMountLabel("newinstance,ptmxmode=0666,mode=620,gid=5", mountLabel)},
	} {
		if err := os.MkdirAll(m.path, 0755); err != nil && !os.IsExist(err) {
			return fmt.Errorf("mkdirall %s %s", m.path, err)
		}
		if err := system.Mount(m.source, m.path, m.device, uintptr(m.flags), m.data); err != nil {
			return fmt.Errorf("mounting %s into %s %s", m.source, m.path, err)
		}
	}
	return nil
}

// setupPtmx adds a symlink to pts/ptmx for /dev/ptmx and
// finishes setting up /dev/console
func setupPtmx(rootfs, console string, mountLabel string) error {
	ptmx := filepath.Join(rootfs, "dev/ptmx")
	if err := os.Remove(ptmx); err != nil && !os.IsNotExist(err) {
		return err
	}
	if err := os.Symlink("pts/ptmx", ptmx); err != nil {
		return fmt.Errorf("symlink dev ptmx %s", err)
	}
	if console != "" {
		if err := setupConsole(rootfs, console, mountLabel); err != nil {
			return err
		}
	}
	return nil
}

// remountProc is used to detach and remount the proc filesystem
// commonly needed with running a new process inside an existing container
func remountProc() error {
	if err := system.Unmount("/proc", syscall.MNT_DETACH); err != nil {
		return err
	}
	if err := system.Mount("proc", "/proc", "proc", uintptr(defaultMountFlags), ""); err != nil {
		return err
	}
	return nil
}

func remountSys() error {
	if err := system.Unmount("/sys", syscall.MNT_DETACH); err != nil {
		if err != syscall.EINVAL {
			return err
		}
	} else {
		if err := system.Mount("sysfs", "/sys", "sysfs", uintptr(defaultMountFlags), ""); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>Remove loopback setup for native driver Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)<commit_after>// +build linux

package nsinit

import (
	"fmt"
	"github.com/dotcloud/docker/pkg/label"
	"github.com/dotcloud/docker/pkg/libcontainer"
	"github.com/dotcloud/docker/pkg/system"
	"io/ioutil"
	"os"
	"path/filepath"
	"syscall"
)

// default mount point flags
const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV

// setupNewMountNamespace is used to initialize a new mount namespace for an new
// container in the rootfs that is specified.
//
// There is no need to unmount the new mounts because as soon as the mount namespace
// is no longer in use, the mounts will be removed automatically
func setupNewMountNamespace(rootfs string, bindMounts []libcontainer.Mount, console string, readonly, noPivotRoot bool, mountLabel string) error {
	flag := syscall.MS_PRIVATE
	if noPivotRoot {
		flag = syscall.MS_SLAVE
	}
	if err := system.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil {
		return fmt.Errorf("mounting / as slave %s", err)
	}
	if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
		return fmt.Errorf("mouting %s as bind %s", rootfs, err)
	}
	if err := mountSystem(rootfs, mountLabel); err != nil {
		return fmt.Errorf("mount system %s", err)
	}

	for _, m := range bindMounts {
		flags := syscall.MS_BIND | syscall.MS_REC
		if !m.Writable {
			flags = flags | syscall.MS_RDONLY
		}
		dest := filepath.Join(rootfs, m.Destination)
		if err := system.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil {
			return fmt.Errorf("mounting %s into %s %s", m.Source, dest, err)
		}
		if m.Private {
			if err := system.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil {
				return fmt.Errorf("mounting %s private %s", dest, err)
			}
		}
	}

	if err := copyDevNodes(rootfs); err != nil {
		return fmt.Errorf("copy dev nodes %s", err)
	}
	if err := setupPtmx(rootfs, console, mountLabel); err != nil {
		return err
	}
	if err := system.Chdir(rootfs); err != nil {
		return fmt.Errorf("chdir into %s %s", rootfs, err)
	}

	if noPivotRoot {
		if err := rootMsMove(rootfs); err != nil {
			return err
		}
	} else {
		if err := rootPivot(rootfs); err != nil {
			return err
		}
	}

	if readonly {
		if err := system.Mount("/", "/", "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, ""); err != nil {
			return fmt.Errorf("mounting %s as readonly %s", rootfs, err)
		}
	}

	system.Umask(0022)

	return nil
}

// use a pivot root to setup the rootfs
func rootPivot(rootfs string) error {
	pivotDir, err := ioutil.TempDir(rootfs, ".pivot_root")
	if err != nil {
		return fmt.Errorf("can't create pivot_root dir %s", pivotDir, err)
	}
	if err := system.Pivotroot(rootfs, pivotDir); err != nil {
		return fmt.Errorf("pivot_root %s", err)
	}
	if err := system.Chdir("/"); err != nil {
		return fmt.Errorf("chdir / %s", err)
	}
	// path to pivot dir now changed, update
	pivotDir = filepath.Join("/", filepath.Base(pivotDir))
	if err := system.Unmount(pivotDir, syscall.MNT_DETACH); err != nil {
		return fmt.Errorf("unmount pivot_root dir %s", err)
	}
	if err := os.Remove(pivotDir); err != nil {
		return fmt.Errorf("remove pivot_root dir %s", err)
	}
	return nil
}

// use MS_MOVE and chroot to setup the rootfs
func rootMsMove(rootfs string) error {
	if err := system.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil {
		return fmt.Errorf("mount move %s into / %s", rootfs, err)
	}
	if err := system.Chroot("."); err != nil {
		return fmt.Errorf("chroot . %s", err)
	}
	if err := system.Chdir("/"); err != nil {
		return fmt.Errorf("chdir / %s", err)
	}
	return nil
}

// copyDevNodes mknods the hosts devices so the new container has access to them
func copyDevNodes(rootfs string) error {
	oldMask := system.Umask(0000)
	defer system.Umask(oldMask)

	for _, node := range []string{
		"null",
		"zero",
		"full",
		"random",
		"urandom",
		"tty",
	} {
		if err := copyDevNode(rootfs, node); err != nil {
			return err
		}
	}
	return nil
}

func copyDevNode(rootfs, node string) error {
	stat, err := os.Stat(filepath.Join("/dev", node))
	if err != nil {
		return err
	}
	var (
		dest = filepath.Join(rootfs, "dev", node)
		st   = stat.Sys().(*syscall.Stat_t)
	)
	if err := system.Mknod(dest, st.Mode, int(st.Rdev)); err != nil && !os.IsExist(err) {
		return fmt.Errorf("copy %s %s", node, err)
	}
	return nil
}

// setupConsole ensures that the container has a proper /dev/console setup
func setupConsole(rootfs, console string, mountLabel string) error {
	oldMask := system.Umask(0000)
	defer system.Umask(oldMask)

	stat, err := os.Stat(console)
	if err != nil {
		return fmt.Errorf("stat console %s %s", console, err)
	}
	var (
		st   = stat.Sys().(*syscall.Stat_t)
		dest = filepath.Join(rootfs, "dev/console")
	)
	if err := os.Remove(dest); err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("remove %s %s", dest, err)
	}
	if err := os.Chmod(console, 0600); err != nil {
		return err
	}
	if err := os.Chown(console, 0, 0); err != nil {
		return err
	}
	if err := system.Mknod(dest, (st.Mode&^07777)|0600, int(st.Rdev)); err != nil {
		return fmt.Errorf("mknod %s %s", dest, err)
	}
	if err := label.SetFileLabel(console, mountLabel); err != nil {
		return fmt.Errorf("SetFileLabel Failed %s %s", dest, err)
	}
	if err := system.Mount(console, dest, "bind", syscall.MS_BIND, ""); err != nil {
		return fmt.Errorf("bind %s to %s %s", console, dest, err)
	}
	return nil
}

// mountSystem sets up linux specific system mounts like sys, proc, shm, and devpts
// inside the mount namespace
func mountSystem(rootfs string, mountLabel string) error {
	for _, m := range []struct {
		source string
		path   string
		device string
		flags  int
		data   string
	}{
		{source: "proc", path: filepath.Join(rootfs, "proc"), device: "proc", flags: defaultMountFlags},
		{source: "sysfs", path: filepath.Join(rootfs, "sys"), device: "sysfs", flags: defaultMountFlags},
		{source: "shm", path: filepath.Join(rootfs, "dev", "shm"), device: "tmpfs", flags: defaultMountFlags, data: label.FormatMountLabel("mode=1755,size=65536k", mountLabel)},
		{source: "devpts", path: filepath.Join(rootfs, "dev", "pts"), device: "devpts", flags: syscall.MS_NOSUID | syscall.MS_NOEXEC, data: label.FormatMountLabel("newinstance,ptmxmode=0666,mode=620,gid=5", mountLabel)},
	} {
		if err := os.MkdirAll(m.path, 0755); err != nil && !os.IsExist(err) {
			return fmt.Errorf("mkdirall %s %s", m.path, err)
		}
		if err := system.Mount(m.source, m.path, m.device, uintptr(m.flags), m.data); err != nil {
			return fmt.Errorf("mounting %s into %s %s", m.source, m.path, err)
		}
	}
	return nil
}

// setupPtmx adds a symlink to pts/ptmx for /dev/ptmx and
// finishes setting up /dev/console
func setupPtmx(rootfs, console string, mountLabel string) error {
	ptmx := filepath.Join(rootfs, "dev/ptmx")
	if err := os.Remove(ptmx); err != nil && !os.IsNotExist(err) {
		return err
	}
	if err := os.Symlink("pts/ptmx", ptmx); err != nil {
		return fmt.Errorf("symlink dev ptmx %s", err)
	}
	if console != "" {
		if err := setupConsole(rootfs, console, mountLabel); err != nil {
			return err
		}
	}
	return nil
}

// remountProc is used to detach and remount the proc filesystem
// commonly needed with running a new process inside an existing container
func remountProc() error {
	if err := system.Unmount("/proc", syscall.MNT_DETACH); err != nil {
		return err
	}
	if err := system.Mount("proc", "/proc", "proc", uintptr(defaultMountFlags), ""); err != nil {
		return err
	}
	return nil
}

func remountSys() error {
	if err := system.Unmount("/sys", syscall.MNT_DETACH); err != nil {
		if err != syscall.EINVAL {
			return err
		}
	} else {
		if err := system.Mount("sysfs", "/sys", "sysfs", uintptr(defaultMountFlags), ""); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package cli_test

import (
	"time"

	. "github.com/jwaldrip/odin/cli"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("CLI Start", func() {

	var cli *CLI
	var cmd Command
	var didRun bool

	BeforeEach(func() {
		didRun = false
		runFn := func(c Command) {
			cmd = c
			didRun = true
		}
		cli = NewCLI("v1.0.0", "sample description", runFn)
		cli.ErrorHandling = PanicOnError
		cli.Mute()
	})

	Describe("flag definitions", func() {
		Describe("BoolFlag", func() {

			It("should set and parse", func() {
				cli.DefineBoolFlag("boolflag", false, "desc")
				cli.Start("cmd", "--boolflag")
				Expect(cmd.Flag("boolflag").Get()).To(Equal(true))
			})

			It("should set and parse from var", func() {
				var val bool
				cli.DefineBoolFlagVar(&val, "boolflag", false, "desc")
				cli.DefineBoolFlagVar(&val, "boolflag2", false, "desc")
				cli.Start("cmd", "--boolflag")
				Expect(cmd.Flag("boolflag2").Get()).To(Equal(true))
			})
		})

		Describe("DurationFlag", func() {

			It("should set and parse", func() {
				cli.DefineDurationFlag("durflag", time.Duration(60)*time.Second, "desc")
				cli.Start("cmd", "--durflag=30s")
				Expect(cmd.Flag("durflag").Get()).To(Equal(time.Duration(30) * time.Second))
			})

			It("should set and parse from var", func() {
				var val time.Duration
				cli.DefineDurationFlagVar(&val, "durflag", time.Duration(60)*time.Second, "desc")
				cli.DefineDurationFlagVar(&val, "durflag2", time.Duration(45)*time.Second, "desc")
				cli.Start("cmd", "--durflag=100s")
				Expect(cmd.Flag("durflag2").Get()).To(Equal(time.Duration(100) * time.Second))
			})
		})

		Describe("Float64Flag", func() {

			It("should set and parse", func() {
				cli.DefineFloat64Flag("float64flag", 10.1, "desc")
				cli.Start("cmd", "--float64flag=9.9")
				Expect(cmd.Flag("float64flag").Get()).To(Equal(9.9))
			})

			It("should set and parse from var", func() {
				var val float64
				cli.DefineFloat64FlagVar(&val, "float64flag", 10.10, "desc")
				cli.DefineFloat64FlagVar(&val, "float64flag2", 9.9, "desc")
				cli.Start("cmd", "--float64flag=8.8")
				Expect(cmd.Flag("float64flag2").Get()).To(Equal(8.8))
			})
		})

		Describe("Int64Flag", func() {

			It("should set and parse", func() {
				cli.DefineInt64Flag("int64flag", 10, "desc")
				cli.Start("cmd", "--int64flag=9")
				Expect(cmd.Flag("int64flag").Get()).To(Equal(int64(9)))
			})

			It("should set and parse from var", func() {
				var val int64
				cli.DefineInt64FlagVar(&val, "int64flag", 10, "desc")
				cli.DefineInt64FlagVar(&val, "int64flag2", 9, "desc")
				cli.Start("cmd", "--int64flag=8")
				Expect(cmd.Flag("int64flag2").Get()).To(Equal(int64(8)))
			})
		})

		Describe("IntFlag", func() {

			It("should set and parse", func() {
				cli.DefineIntFlag("intflag", 10, "desc")
				cli.Start("cmd", "--intflag=9")
				Expect(cmd.Flag("intflag").Get()).To(Equal(int(9)))
			})

			It("should set and parse from var", func() {
				var val int
				cli.DefineIntFlagVar(&val, "intflag", 10, "desc")
				cli.DefineIntFlagVar(&val, "intflag2", 9, "desc")
				cli.Start("cmd", "--intflag=8")
				Expect(cmd.Flag("intflag2").Get()).To(Equal(int(8)))
			})
		})

		Describe("Uint64Flag", func() {

			It("should set and parse", func() {
				cli.DefineUint64Flag("uint64flag", uint64(10), "desc")
				cli.Start("cmd", "--uint64flag=9")
				Expect(cmd.Flag("uint64flag").Get()).To(Equal(uint64(9)))
			})

			It("should set and parse from var", func() {
				var val uint64
				cli.DefineUint64FlagVar(&val, "uint64flag", uint64(10), "desc")
				cli.DefineUint64FlagVar(&val, "uint64flag2", uint64(9), "desc")
				cli.Start("cmd", "--uint64flag=8")
				Expect(cmd.Flag("uint64flag2").Get()).To(Equal(uint64(8)))
			})
		})

		Describe("UintFlag", func() {

			It("should set and parse", func() {
				cli.DefineUintFlag("uintflag", uint(10), "desc")
				cli.Start("cmd", "--uintflag=9")
				Expect(cmd.Flag("uintflag").Get()).To(Equal(uint(9)))
			})

			It("should set and parse from var", func() {
				var val uint
				cli.DefineUintFlagVar(&val, "uintflag", uint(10), "desc")
				cli.DefineUintFlagVar(&val, "uintflag2", uint(9), "desc")
				cli.Start("cmd", "--uintflag=8")
				Expect(cmd.Flag("uintflag2").Get()).To(Equal(uint(8)))
			})
		})

	})

})
<commit_msg>string flags<commit_after>package cli_test

import (
	"time"

	. "github.com/jwaldrip/odin/cli"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("CLI Start", func() {

	var cli *CLI
	var cmd Command
	var didRun bool

	BeforeEach(func() {
		didRun = false
		runFn := func(c Command) {
			cmd = c
			didRun = true
		}
		cli = NewCLI("v1.0.0", "sample description", runFn)
		cli.ErrorHandling = PanicOnError
		cli.Mute()
	})

	Describe("flag definitions", func() {
		Describe("BoolFlag", func() {

			It("should set and parse", func() {
				cli.DefineBoolFlag("boolflag", false, "desc")
				cli.Start("cmd", "--boolflag")
				Expect(cmd.Flag("boolflag").Get()).To(Equal(true))
			})

			It("should set and parse from var", func() {
				var val bool
				cli.DefineBoolFlagVar(&val, "boolflag", false, "desc")
				cli.DefineBoolFlagVar(&val, "boolflag2", false, "desc")
				cli.Start("cmd", "--boolflag")
				Expect(cmd.Flag("boolflag2").Get()).To(Equal(true))
			})
		})

		Describe("DurationFlag", func() {

			It("should set and parse", func() {
				cli.DefineDurationFlag("durflag", time.Duration(60)*time.Second, "desc")
				cli.Start("cmd", "--durflag=30s")
				Expect(cmd.Flag("durflag").Get()).To(Equal(time.Duration(30) * time.Second))
			})

			It("should set and parse from var", func() {
				var val time.Duration
				cli.DefineDurationFlagVar(&val, "durflag", time.Duration(60)*time.Second, "desc")
				cli.DefineDurationFlagVar(&val, "durflag2", time.Duration(45)*time.Second, "desc")
				cli.Start("cmd", "--durflag=100s")
				Expect(cmd.Flag("durflag2").Get()).To(Equal(time.Duration(100) * time.Second))
			})
		})

		Describe("Float64Flag", func() {

			It("should set and parse", func() {
				cli.DefineFloat64Flag("float64flag", 10.1, "desc")
				cli.Start("cmd", "--float64flag=9.9")
				Expect(cmd.Flag("float64flag").Get()).To(Equal(9.9))
			})

			It("should set and parse from var", func() {
				var val float64
				cli.DefineFloat64FlagVar(&val, "float64flag", 10.10, "desc")
				cli.DefineFloat64FlagVar(&val, "float64flag2", 9.9, "desc")
				cli.Start("cmd", "--float64flag=8.8")
				Expect(cmd.Flag("float64flag2").Get()).To(Equal(8.8))
			})
		})

		Describe("Int64Flag", func() {

			It("should set and parse", func() {
				cli.DefineInt64Flag("int64flag", 10, "desc")
				cli.Start("cmd", "--int64flag=9")
				Expect(cmd.Flag("int64flag").Get()).To(Equal(int64(9)))
			})

			It("should set and parse from var", func() {
				var val int64
				cli.DefineInt64FlagVar(&val, "int64flag", 10, "desc")
				cli.DefineInt64FlagVar(&val, "int64flag2", 9, "desc")
				cli.Start("cmd", "--int64flag=8")
				Expect(cmd.Flag("int64flag2").Get()).To(Equal(int64(8)))
			})
		})

		Describe("IntFlag", func() {

			It("should set and parse", func() {
				cli.DefineIntFlag("intflag", 10, "desc")
				cli.Start("cmd", "--intflag=9")
				Expect(cmd.Flag("intflag").Get()).To(Equal(int(9)))
			})

			It("should set and parse from var", func() {
				var val int
				cli.DefineIntFlagVar(&val, "intflag", 10, "desc")
				cli.DefineIntFlagVar(&val, "intflag2", 9, "desc")
				cli.Start("cmd", "--intflag=8")
				Expect(cmd.Flag("intflag2").Get()).To(Equal(int(8)))
			})
		})

		Describe("StringFlag", func() {

			It("should set and parse", func() {
				cli.DefineStringFlag("stringflag", "foo", "desc")
				cli.Start("cmd", "--stringflag=bar")
				Expect(cmd.Flag("stringflag").Get()).To(Equal("bar"))
			})

			It("should set and parse from var", func() {
				var val string
				cli.DefineStringFlagVar(&val, "stringflag", "foo", "desc")
				cli.DefineStringFlagVar(&val, "stringflag2", "bar", "desc")
				cli.Start("cmd", "--stringflag=baz")
				Expect(cmd.Flag("stringflag2").Get()).To(Equal("baz"))
			})
		})

		Describe("Uint64Flag", func() {

			It("should set and parse", func() {
				cli.DefineUint64Flag("uint64flag", uint64(10), "desc")
				cli.Start("cmd", "--uint64flag=9")
				Expect(cmd.Flag("uint64flag").Get()).To(Equal(uint64(9)))
			})

			It("should set and parse from var", func() {
				var val uint64
				cli.DefineUint64FlagVar(&val, "uint64flag", uint64(10), "desc")
				cli.DefineUint64FlagVar(&val, "uint64flag2", uint64(9), "desc")
				cli.Start("cmd", "--uint64flag=8")
				Expect(cmd.Flag("uint64flag2").Get()).To(Equal(uint64(8)))
			})
		})

		Describe("UintFlag", func() {

			It("should set and parse", func() {
				cli.DefineUintFlag("uintflag", uint(10), "desc")
				cli.Start("cmd", "--uintflag=9")
				Expect(cmd.Flag("uintflag").Get()).To(Equal(uint(9)))
			})

			It("should set and parse from var", func() {
				var val uint
				cli.DefineUintFlagVar(&val, "uintflag", uint(10), "desc")
				cli.DefineUintFlagVar(&val, "uintflag2", uint(9), "desc")
				cli.Start("cmd", "--uintflag=8")
				Expect(cmd.Flag("uintflag2").Get()).To(Equal(uint(8)))
			})
		})

	})

})
<|endoftext|>


<commit_before>// Package selfsign implements the selfsign command.
package selfsign

import (
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"time"

	"github.com/cloudflare/cfssl/cli"
	"github.com/cloudflare/cfssl/cli/genkey"
	"github.com/cloudflare/cfssl/config"
	"github.com/cloudflare/cfssl/csr"
	"github.com/cloudflare/cfssl/helpers"
	"github.com/cloudflare/cfssl/selfsign"
)

var selfSignUsageText = `cfssl selfsign -- generate a new self-signed key and signed certificate

Usage of gencert:
        cfssl selfsign HOSTNAME CSRJSON

WARNING: this should ONLY be used for testing. This should never be
used in production.

WARNING: self-signed certificates are insecure; they do not provide
the authentication required for secure systems. Use these at your own
risk.

Arguments:
        HOSTNAME:   Hostname for the cert
        CSRJSON:    JSON file containing the request, use '-' for reading JSON from stdin

Flags:
`

var selfSignFlags = []string{"config"}

func selfSignMain(args []string, c cli.Config) (err error) {
	if c.Hostname == "" && !c.IsCA {
		c.Hostname, args, err = cli.PopFirstArgument(args)
		if err != nil {
			return
		}
	}

	csrFile, args, err := cli.PopFirstArgument(args)
	if err != nil {
		return
	}

	if len(args) > 0 {
		return errors.New("too many arguments are provided, please check with usage")
	}

	csrFileBytes, err := cli.ReadStdin(csrFile)
	if err != nil {
		return
	}

	var req = csr.New()
	err = json.Unmarshal(csrFileBytes, req)
	if err != nil {
		return
	}

	var key, csrPEM []byte
	g := &csr.Generator{Validator: genkey.Validator}
	csrPEM, key, err = g.ProcessRequest(req)
	if err != nil {
		key = nil
		return
	}

	priv, err := helpers.ParsePrivateKeyPEM(key)
	if err != nil {
		key = nil
		return
	}

	var profile *config.SigningProfile

	// If there is a config, use its signing policy. Otherwise, leave policy == nil
	// and NewSigner will use DefaultConfig().
	if c.CFG != nil {
		if c.Profile != "" && c.CFG.Signing.Profiles != nil {
			profile = c.CFG.Signing.Profiles[c.Profile]
		}
	}

	if profile == nil {
		profile = config.DefaultConfig()
		profile.Expiry = 2190 * time.Hour
	}

	cert, err := selfsign.Sign(priv, csrPEM, profile)
	if err != nil {
		key = nil
		priv = nil
		return
	}

	fmt.Fprintf(os.Stderr, `*** WARNING ***

Self-signed certificates are dangerous. Use this self-signed
certificate at your own risk.

It is strongly recommended that these certificates NOT be used
in production.

*** WARNING ***

`)
	cli.PrintCert(key, csrPEM, cert)
	return
}

// Command assembles the definition of Command 'selfsign'
var Command = &cli.Command{UsageText: selfSignUsageText, Flags: selfSignFlags, Main: selfSignMain}
<commit_msg>Fix bug causing selfsign to ignore the default profile<commit_after>// Package selfsign implements the selfsign command.
package selfsign

import (
	"encoding/json"
	"errors"
	"fmt"
	"os"
	"time"

	"github.com/cloudflare/cfssl/cli"
	"github.com/cloudflare/cfssl/cli/genkey"
	"github.com/cloudflare/cfssl/config"
	"github.com/cloudflare/cfssl/csr"
	"github.com/cloudflare/cfssl/helpers"
	"github.com/cloudflare/cfssl/selfsign"
)

var selfSignUsageText = `cfssl selfsign -- generate a new self-signed key and signed certificate

Usage of gencert:
        cfssl selfsign HOSTNAME CSRJSON

WARNING: this should ONLY be used for testing. This should never be
used in production.

WARNING: self-signed certificates are insecure; they do not provide
the authentication required for secure systems. Use these at your own
risk.

Arguments:
        HOSTNAME:   Hostname for the cert
        CSRJSON:    JSON file containing the request, use '-' for reading JSON from stdin

Flags:
`

var selfSignFlags = []string{"config"}

func selfSignMain(args []string, c cli.Config) (err error) {
	if c.Hostname == "" && !c.IsCA {
		c.Hostname, args, err = cli.PopFirstArgument(args)
		if err != nil {
			return
		}
	}

	csrFile, args, err := cli.PopFirstArgument(args)
	if err != nil {
		return
	}

	if len(args) > 0 {
		return errors.New("too many arguments are provided, please check with usage")
	}

	csrFileBytes, err := cli.ReadStdin(csrFile)
	if err != nil {
		return
	}

	var req = csr.New()
	err = json.Unmarshal(csrFileBytes, req)
	if err != nil {
		return
	}

	var key, csrPEM []byte
	g := &csr.Generator{Validator: genkey.Validator}
	csrPEM, key, err = g.ProcessRequest(req)
	if err != nil {
		key = nil
		return
	}

	priv, err := helpers.ParsePrivateKeyPEM(key)
	if err != nil {
		key = nil
		return
	}

	var profile *config.SigningProfile

	// If there is a config, use its signing policy. Otherwise, leave policy == nil
	// and NewSigner will use DefaultConfig().
	if c.CFG != nil {
		if c.Profile != "" && c.CFG.Signing.Profiles != nil {
			profile = c.CFG.Signing.Profiles[c.Profile]
		}
		if profile == nil {
			profile = c.CFG.Signing.Default
		}
	}

	if profile == nil {
		profile = config.DefaultConfig()
		profile.Expiry = 2190 * time.Hour
	}

	cert, err := selfsign.Sign(priv, csrPEM, profile)
	if err != nil {
		key = nil
		priv = nil
		return
	}

	fmt.Fprintf(os.Stderr, `*** WARNING ***

Self-signed certificates are dangerous. Use this self-signed
certificate at your own risk.

It is strongly recommended that these certificates NOT be used
in production.

*** WARNING ***

`)
	cli.PrintCert(key, csrPEM, cert)
	return
}

// Command assembles the definition of Command 'selfsign'
var Command = &cli.Command{UsageText: selfSignUsageText, Flags: selfSignFlags, Main: selfSignMain}
<|endoftext|>