<commit_before>package provider

import (
	"strings"

	"github.com/docker/machine/libmachine/drivers"
	"github.com/docker/machine/libmachine/drivers/rpc"
	"github.com/docker/machine/libmachine/mcnflag"

	"github.com/docker/machine/drivers/amazonec2"
	"github.com/docker/machine/drivers/azure"
	"github.com/docker/machine/drivers/digitalocean"
	"github.com/docker/machine/drivers/exoscale"
	"github.com/docker/machine/drivers/generic"
	"github.com/docker/machine/drivers/google"
	"github.com/docker/machine/drivers/hyperv"
	"github.com/docker/machine/drivers/none"
	"github.com/docker/machine/drivers/openstack"
	"github.com/docker/machine/drivers/rackspace"
	"github.com/docker/machine/drivers/softlayer"
	"github.com/docker/machine/drivers/virtualbox"
	"github.com/docker/machine/drivers/vmwarefusion"
	"github.com/docker/machine/drivers/vmwarevcloudair"
	"github.com/docker/machine/drivers/vmwarevsphere"

	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resource(driverName string) *schema.Resource {
	drv := getDriver(driverName, "", "")
	resourceSchema := map[string]*schema.Schema{
		"name": {
			Type:     schema.TypeString,
			Required: true,
			ForceNew: true,
		},
		"certs_directory": {
			Type:     schema.TypeString,
			Computed: true,
			ForceNew: true,
		},
		"tls_ca_cert": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"tls_ca_key": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"tls_client_cert": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"tls_client_key": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"tls_server_cert": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"tls_server_key": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"storage_path": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"storage_path_computed": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"tls_san": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"engine_opt": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"engine_env": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"engine_insecure_registry": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"engine_label": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"engine_registry_mirror": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"engine_storage_driver": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"engine_install_url": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"swarm": {
			Type:     schema.TypeBool,
			Optional: true,
			Default:  false,
			ForceNew: true,
		},
		"swarm_master": {
			Type:     schema.TypeBool,
			Optional: true,
			Default:  false,
			ForceNew: true,
		},
		"swarm_image": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"swarm_discovery": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"swarm_addr": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"swarm_host": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"swarm_strategy": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"swarm_opt": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"swarm_join_opt": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"swarm_experimental": {
			Type:     schema.TypeBool,
			Optional: true,
			Default:  false,
			ForceNew: true,
		},
		"ssh_hostname": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"ssh_port": {
			Type:     schema.TypeInt,
			Computed: true,
		},
		"ssh_username": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"ssh_keypath": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"address": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"docker_url": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"docker_version": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"state": {
			Type:         schema.TypeString,
			Optional:     true,
			Default:      "running",
			ValidateFunc: validation.StringInSlice([]string{"running", "stopped"}, false),
		},
	}
	for _, flag := range drv.GetCreateFlags() {
		flagName := strings.Replace(flag.String(), "-", "_", -1)
		switch f := flag.(type) {
		case mcnflag.StringFlag:
			resourceSchema[flagName] = &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Default:  f.Value,
			}
		case mcnflag.StringSliceFlag:
			resourceSchema[flagName] = &schema.Schema{
				Type:     schema.TypeList,
				Optional: true,
				ForceNew: true,
				Elem: &schema.Schema{
					Type: schema.TypeString,
				},
			}
		case mcnflag.IntFlag:
			resourceSchema[flagName] = &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				ForceNew: true,
				Default:  f.Value,
			}
		case mcnflag.BoolFlag:
			resourceSchema[flagName] = &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				ForceNew: true,
			}
		}
	}
	return &schema.Resource{
		Schema: resourceSchema,
		Exists: resourceExists(drv.DriverName()),
		Create: resourceCreate(drv.DriverName()),
		Read:   resourceRead(drv.DriverName()),
		Update: resourceUpdate(drv.DriverName()),
		Delete: resourceDelete(drv.DriverName()),
	}
}

func getDriver(driverName, machineName, storePath string) drivers.Driver {
	switch driverName {
	case "amazonec2":
		return amazonec2.NewDriver(machineName, storePath)
	case "azure":
		return azure.NewDriver(machineName, storePath)
	case "digitalocean":
		return digitalocean.NewDriver(machineName, storePath)
	case "exoscale":
		return exoscale.NewDriver(machineName, storePath)
	case "generic":
		return generic.NewDriver(machineName, storePath)
	case "google":
		return google.NewDriver(machineName, storePath)
	case "hyperv":
		return hyperv.NewDriver(machineName, storePath)
	case "none":
		return none.NewDriver(machineName, storePath)
	case "openstack":
		return openstack.NewDriver(machineName, storePath)
	case "rackspace":
		return rackspace.NewDriver(machineName, storePath)
	case "softlayer":
		return softlayer.NewDriver(machineName, storePath)
	case "virtualbox":
		return virtualbox.NewDriver(machineName, storePath)
	case "vmwarefusion":
		return vmwarefusion.NewDriver(machineName, storePath)
	case "vmwarevcloudair":
		return vmwarevcloudair.NewDriver(machineName, storePath)
	case "vmwarevsphere":
		return vmwarevsphere.NewDriver(machineName, storePath)
	default:
		return nil
	}
}

func getDriverOpts(d *schema.ResourceData, mcnflags []mcnflag.Flag) drivers.DriverOptions {
	driverOpts := rpcdriver.RPCFlags{
		Values: make(map[string]interface{}),
	}

	for _, f := range mcnflags {
		driverOpts.Values[f.String()] = f.Default()

		if f.Default() == nil {
			driverOpts.Values[f.String()] = false
		}

		schemaOpt := strings.Replace(f.String(), "-", "_", -1)
		switch f.(type) {
		case *mcnflag.StringFlag:
			driverOpts.Values[f.String()] = d.Get(schemaOpt).(string)
		case *mcnflag.StringSliceFlag:
			driverOpts.Values[f.String()] = ss2is(d.Get(schemaOpt).([]string))
		case *mcnflag.IntFlag:
			driverOpts.Values[f.String()] = d.Get(schemaOpt).(int)
		case *mcnflag.BoolFlag:
			driverOpts.Values[f.String()] = d.Get(schemaOpt).(bool)
		}
	}

	return driverOpts
}
<commit_msg>Fixed issue #1.<commit_after>package provider

import (
	"strings"

	"github.com/docker/machine/libmachine/drivers"
	"github.com/docker/machine/libmachine/drivers/rpc"
	"github.com/docker/machine/libmachine/mcnflag"

	"github.com/docker/machine/drivers/amazonec2"
	"github.com/docker/machine/drivers/azure"
	"github.com/docker/machine/drivers/digitalocean"
	"github.com/docker/machine/drivers/exoscale"
	"github.com/docker/machine/drivers/generic"
	"github.com/docker/machine/drivers/google"
	"github.com/docker/machine/drivers/hyperv"
	"github.com/docker/machine/drivers/none"
	"github.com/docker/machine/drivers/openstack"
	"github.com/docker/machine/drivers/rackspace"
	"github.com/docker/machine/drivers/softlayer"
	"github.com/docker/machine/drivers/virtualbox"
	"github.com/docker/machine/drivers/vmwarefusion"
	"github.com/docker/machine/drivers/vmwarevcloudair"
	"github.com/docker/machine/drivers/vmwarevsphere"

	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resource(driverName string) *schema.Resource {
	drv := getDriver(driverName, "", "")
	resourceSchema := map[string]*schema.Schema{
		"name": {
			Type:     schema.TypeString,
			Required: true,
			ForceNew: true,
		},
		"certs_directory": {
			Type:     schema.TypeString,
			Computed: true,
			ForceNew: true,
		},
		"tls_ca_cert": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"tls_ca_key": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"tls_client_cert": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"tls_client_key": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"tls_server_cert": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"tls_server_key": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"storage_path": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"storage_path_computed": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"tls_san": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"engine_opt": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"engine_env": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"engine_insecure_registry": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"engine_label": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"engine_registry_mirror": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"engine_storage_driver": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"engine_install_url": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"swarm": {
			Type:     schema.TypeBool,
			Optional: true,
			Default:  false,
			ForceNew: true,
		},
		"swarm_master": {
			Type:     schema.TypeBool,
			Optional: true,
			Default:  false,
			ForceNew: true,
		},
		"swarm_image": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"swarm_discovery": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"swarm_addr": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"swarm_host": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"swarm_strategy": {
			Type:     schema.TypeString,
			Optional: true,
			ForceNew: true,
		},
		"swarm_opt": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"swarm_join_opt": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Schema{
				Type: schema.TypeString,
			},
			ForceNew: true,
		},
		"swarm_experimental": {
			Type:     schema.TypeBool,
			Optional: true,
			Default:  false,
			ForceNew: true,
		},
		"ssh_hostname": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"ssh_port": {
			Type:     schema.TypeInt,
			Computed: true,
		},
		"ssh_username": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"ssh_keypath": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"address": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"docker_url": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"docker_version": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"state": {
			Type:         schema.TypeString,
			Optional:     true,
			Default:      "running",
			ValidateFunc: validation.StringInSlice([]string{"running", "stopped"}, false),
		},
	}
	for _, flag := range drv.GetCreateFlags() {
		flagName := strings.Replace(flag.String(), "-", "_", -1)
		switch f := flag.(type) {
		case mcnflag.StringFlag:
			resourceSchema[flagName] = &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Default:  f.Value,
			}
		case mcnflag.StringSliceFlag:
			resourceSchema[flagName] = &schema.Schema{
				Type:     schema.TypeList,
				Optional: true,
				ForceNew: true,
				Elem: &schema.Schema{
					Type: schema.TypeString,
				},
			}
		case mcnflag.IntFlag:
			resourceSchema[flagName] = &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				ForceNew: true,
				Default:  f.Value,
			}
		case mcnflag.BoolFlag:
			resourceSchema[flagName] = &schema.Schema{
				Type:     schema.TypeBool,
				Optional: true,
				ForceNew: true,
			}
		}
	}
	return &schema.Resource{
		Schema: resourceSchema,
		Exists: resourceExists(drv.DriverName()),
		Create: resourceCreate(drv.DriverName()),
		Read:   resourceRead(drv.DriverName()),
		Update: resourceUpdate(drv.DriverName()),
		Delete: resourceDelete(drv.DriverName()),
	}
}

func getDriver(driverName, machineName, storePath string) drivers.Driver {
	switch driverName {
	case "amazonec2":
		return amazonec2.NewDriver(machineName, storePath)
	case "azure":
		return azure.NewDriver(machineName, storePath)
	case "digitalocean":
		return digitalocean.NewDriver(machineName, storePath)
	case "exoscale":
		return exoscale.NewDriver(machineName, storePath)
	case "generic":
		return generic.NewDriver(machineName, storePath)
	case "google":
		return google.NewDriver(machineName, storePath)
	case "hyperv":
		return hyperv.NewDriver(machineName, storePath)
	case "none":
		return none.NewDriver(machineName, storePath)
	case "openstack":
		return openstack.NewDriver(machineName, storePath)
	case "rackspace":
		return rackspace.NewDriver(machineName, storePath)
	case "softlayer":
		return softlayer.NewDriver(machineName, storePath)
	case "virtualbox":
		return virtualbox.NewDriver(machineName, storePath)
	case "vmwarefusion":
		return vmwarefusion.NewDriver(machineName, storePath)
	case "vmwarevcloudair":
		return vmwarevcloudair.NewDriver(machineName, storePath)
	case "vmwarevsphere":
		return vmwarevsphere.NewDriver(machineName, storePath)
	default:
		return nil
	}
}

func getDriverOpts(d *schema.ResourceData, mcnflags []mcnflag.Flag) drivers.DriverOptions {
	driverOpts := rpcdriver.RPCFlags{
		Values: make(map[string]interface{}),
	}

	for _, f := range mcnflags {
		driverOpts.Values[f.String()] = f.Default()

		if f.Default() == nil {
			driverOpts.Values[f.String()] = false
		}

		schemaOpt := strings.Replace(f.String(), "-", "_", -1)
		switch f.(type) {
		case *mcnflag.StringFlag:
			driverOpts.Values[f.String()] = d.Get(schemaOpt).(string)
		case *mcnflag.StringSliceFlag:
			var slice []string
			for _, s := range d.Get(schemaOpt).([]interface{}) {
				slice = append(slice, s.(string))
			}
			driverOpts.Values[f.String()] = ss2is(slice)
		case *mcnflag.IntFlag:
			driverOpts.Values[f.String()] = d.Get(schemaOpt).(int)
		case *mcnflag.BoolFlag:
			driverOpts.Values[f.String()] = d.Get(schemaOpt).(bool)
		}
	}

	return driverOpts
}
<|endoftext|>


<commit_before><commit_msg>Add a --pvm-attempts flag to `pipelines run` (#31)<commit_after><|endoftext|>


<commit_before>package socks

import (
	"io"
	"net"
	"strconv"
	"sync"

	"github.com/v2ray/v2ray-core"
	"github.com/v2ray/v2ray-core/common/errors"
	"github.com/v2ray/v2ray-core/common/log"
	v2net "github.com/v2ray/v2ray-core/common/net"
	jsonconfig "github.com/v2ray/v2ray-core/proxy/socks/config/json"
	"github.com/v2ray/v2ray-core/proxy/socks/protocol"
)

// SocksServer is a SOCKS 5 proxy server
type SocksServer struct {
	accepting bool
	vPoint    *core.Point
	config    jsonconfig.SocksConfig
}

func NewSocksServer(vp *core.Point, rawConfig []byte) *SocksServer {
	config, err := jsonconfig.Load(rawConfig)
	if err != nil {
		log.Error("Unable to load socks config: %v", err)
		panic(errors.NewConfigurationError())
	}
	return &SocksServer{
		vPoint: vp,
		config: config,
	}
}

func (server *SocksServer) Listen(port uint16) error {
	listener, err := net.Listen("tcp", ":"+strconv.Itoa(int(port)))
	if err != nil {
		log.Error("Socks failed to listen on port %d: %v", port, err)
		return err
	}
	server.accepting = true
	go server.AcceptConnections(listener)
	if server.config.UDPEnabled {
		server.ListenUDP(port)
	}
	return nil
}

func (server *SocksServer) AcceptConnections(listener net.Listener) {
	for server.accepting {
		connection, err := listener.Accept()
		if err != nil {
			log.Error("Socks failed to accept new connection %v", err)
			return
		}
		go server.HandleConnection(connection)
	}
}

func (server *SocksServer) HandleConnection(connection net.Conn) error {
	defer connection.Close()

	reader := v2net.NewTimeOutReader(4, connection)

	auth, auth4, err := protocol.ReadAuthentication(reader)
	if err != nil && !errors.HasCode(err, 1000) {
		log.Error("Socks failed to read authentication: %v", err)
		return err
	}

	if err != nil && errors.HasCode(err, 1000) {
		return server.handleSocks4(reader, connection, auth4)
	} else {
		return server.handleSocks5(reader, connection, auth)
	}
}

func (server *SocksServer) handleSocks5(reader *v2net.TimeOutReader, writer io.Writer, auth protocol.Socks5AuthenticationRequest) error {
	expectedAuthMethod := protocol.AuthNotRequired
	if server.config.IsPassword() {
		expectedAuthMethod = protocol.AuthUserPass
	}

	if !auth.HasAuthMethod(expectedAuthMethod) {
		authResponse := protocol.NewAuthenticationResponse(protocol.AuthNoMatchingMethod)
		err := protocol.WriteAuthentication(writer, authResponse)
		if err != nil {
			log.Error("Socks failed to write authentication: %v", err)
			return err
		}
		log.Warning("Socks client doesn't support allowed any auth methods.")
		return errors.NewInvalidOperationError("Unsupported auth methods.")
	}

	authResponse := protocol.NewAuthenticationResponse(expectedAuthMethod)
	err := protocol.WriteAuthentication(writer, authResponse)
	if err != nil {
		log.Error("Socks failed to write authentication: %v", err)
		return err
	}
	if server.config.IsPassword() {
		upRequest, err := protocol.ReadUserPassRequest(reader)
		if err != nil {
			log.Error("Socks failed to read username and password: %v", err)
			return err
		}
		status := byte(0)
		if !upRequest.IsValid(server.config.Username, server.config.Password) {
			status = byte(0xFF)
		}
		upResponse := protocol.NewSocks5UserPassResponse(status)
		err = protocol.WriteUserPassResponse(writer, upResponse)
		if err != nil {
			log.Error("Socks failed to write user pass response: %v", err)
			return err
		}
		if status != byte(0) {
			err = errors.NewAuthenticationError(upRequest.AuthDetail())
			log.Warning(err.Error())
			return err
		}
	}

	request, err := protocol.ReadRequest(reader)
	if err != nil {
		log.Error("Socks failed to read request: %v", err)
		return err
	}

	response := protocol.NewSocks5Response()

	if request.Command == protocol.CmdUdpAssociate && server.config.UDPEnabled {
		return server.handleUDP(reader, writer)
	}

	if request.Command == protocol.CmdBind || request.Command == protocol.CmdUdpAssociate {
		response := protocol.NewSocks5Response()
		response.Error = protocol.ErrorCommandNotSupported
		err = protocol.WriteResponse(writer, response)
		if err != nil {
			log.Error("Socks failed to write response: %v", err)
			return err
		}
		log.Warning("Unsupported socks command %d", request.Command)
		return errors.NewInvalidOperationError("Socks command " + strconv.Itoa(int(request.Command)))
	}

	response.Error = protocol.ErrorSuccess

	response.Port = request.Port
	response.AddrType = request.AddrType
	switch response.AddrType {
	case protocol.AddrTypeIPv4:
		copy(response.IPv4[:], request.IPv4[:])
	case protocol.AddrTypeIPv6:
		copy(response.IPv6[:], request.IPv6[:])
	case protocol.AddrTypeDomain:
		response.Domain = request.Domain
	}
	err = protocol.WriteResponse(writer, response)
	if err != nil {
		log.Error("Socks failed to write response: %v", err)
		return err
	}

	dest := request.Destination()
	data, err := v2net.ReadFrom(reader)
	if err != nil {
		return err
	}

	packet := v2net.NewPacket(dest, data, true)
	server.transport(reader, writer, packet)
	return nil
}

func (server *SocksServer) handleUDP(reader *v2net.TimeOutReader, writer io.Writer) error {
	response := protocol.NewSocks5Response()
	response.Error = protocol.ErrorSuccess

	udpAddr := server.getUDPAddr()

	response.Port = udpAddr.Port()
	switch {
	case udpAddr.IsIPv4():
		response.AddrType = protocol.AddrTypeIPv4
		copy(response.IPv4[:], udpAddr.IP())
	case udpAddr.IsIPv6():
		response.AddrType = protocol.AddrTypeIPv6
		copy(response.IPv6[:], udpAddr.IP())
	case udpAddr.IsDomain():
		response.AddrType = protocol.AddrTypeDomain
		response.Domain = udpAddr.Domain()
	}
	err := protocol.WriteResponse(writer, response)
	if err != nil {
		log.Error("Socks failed to write response: %v", err)
		return err
	}

	reader.SetTimeOut(300) /* 5 minutes */
	buffer := make([]byte, 1024)
	reader.Read(buffer)

	return nil
}

func (server *SocksServer) handleSocks4(reader io.Reader, writer io.Writer, auth protocol.Socks4AuthenticationRequest) error {
	result := protocol.Socks4RequestGranted
	if auth.Command == protocol.CmdBind {
		result = protocol.Socks4RequestRejected
	}
	socks4Response := protocol.NewSocks4AuthenticationResponse(result, auth.Port, auth.IP[:])
	writer.Write(socks4Response.ToBytes(nil))

	if result == protocol.Socks4RequestRejected {
		return errors.NewInvalidOperationError("Socks4 command " + strconv.Itoa(int(auth.Command)))
	}

	dest := v2net.NewTCPDestination(v2net.IPAddress(auth.IP[:], auth.Port))
	data, err := v2net.ReadFrom(reader)
	if err != nil {
		return err
	}

	packet := v2net.NewPacket(dest, data, true)
	server.transport(reader, writer, packet)
	return nil
}

func (server *SocksServer) transport(reader io.Reader, writer io.Writer, firstPacket v2net.Packet) {
	ray := server.vPoint.DispatchToOutbound(firstPacket)
	input := ray.InboundInput()
	output := ray.InboundOutput()

	var inputFinish, outputFinish sync.Mutex
	inputFinish.Lock()
	outputFinish.Lock()

	go dumpInput(reader, input, &inputFinish)
	go dumpOutput(writer, output, &outputFinish)
	outputFinish.Lock()
}

func dumpInput(reader io.Reader, input chan<- []byte, finish *sync.Mutex) {
	v2net.ReaderToChan(input, reader)
	finish.Unlock()
	close(input)
}

func dumpOutput(writer io.Writer, output <-chan []byte, finish *sync.Mutex) {
	v2net.ChanToWriter(writer, output)
	finish.Unlock()
}
<commit_msg>lazy init of socks5 response<commit_after>package socks

import (
	"io"
	"net"
	"strconv"
	"sync"

	"github.com/v2ray/v2ray-core"
	"github.com/v2ray/v2ray-core/common/errors"
	"github.com/v2ray/v2ray-core/common/log"
	v2net "github.com/v2ray/v2ray-core/common/net"
	jsonconfig "github.com/v2ray/v2ray-core/proxy/socks/config/json"
	"github.com/v2ray/v2ray-core/proxy/socks/protocol"
)

// SocksServer is a SOCKS 5 proxy server
type SocksServer struct {
	accepting bool
	vPoint    *core.Point
	config    jsonconfig.SocksConfig
}

func NewSocksServer(vp *core.Point, rawConfig []byte) *SocksServer {
	config, err := jsonconfig.Load(rawConfig)
	if err != nil {
		log.Error("Unable to load socks config: %v", err)
		panic(errors.NewConfigurationError())
	}
	return &SocksServer{
		vPoint: vp,
		config: config,
	}
}

func (server *SocksServer) Listen(port uint16) error {
	listener, err := net.Listen("tcp", ":"+strconv.Itoa(int(port)))
	if err != nil {
		log.Error("Socks failed to listen on port %d: %v", port, err)
		return err
	}
	server.accepting = true
	go server.AcceptConnections(listener)
	if server.config.UDPEnabled {
		server.ListenUDP(port)
	}
	return nil
}

func (server *SocksServer) AcceptConnections(listener net.Listener) {
	for server.accepting {
		connection, err := listener.Accept()
		if err != nil {
			log.Error("Socks failed to accept new connection %v", err)
			return
		}
		go server.HandleConnection(connection)
	}
}

func (server *SocksServer) HandleConnection(connection net.Conn) error {
	defer connection.Close()

	reader := v2net.NewTimeOutReader(4, connection)

	auth, auth4, err := protocol.ReadAuthentication(reader)
	if err != nil && !errors.HasCode(err, 1000) {
		log.Error("Socks failed to read authentication: %v", err)
		return err
	}

	if err != nil && errors.HasCode(err, 1000) {
		return server.handleSocks4(reader, connection, auth4)
	} else {
		return server.handleSocks5(reader, connection, auth)
	}
}

func (server *SocksServer) handleSocks5(reader *v2net.TimeOutReader, writer io.Writer, auth protocol.Socks5AuthenticationRequest) error {
	expectedAuthMethod := protocol.AuthNotRequired
	if server.config.IsPassword() {
		expectedAuthMethod = protocol.AuthUserPass
	}

	if !auth.HasAuthMethod(expectedAuthMethod) {
		authResponse := protocol.NewAuthenticationResponse(protocol.AuthNoMatchingMethod)
		err := protocol.WriteAuthentication(writer, authResponse)
		if err != nil {
			log.Error("Socks failed to write authentication: %v", err)
			return err
		}
		log.Warning("Socks client doesn't support allowed any auth methods.")
		return errors.NewInvalidOperationError("Unsupported auth methods.")
	}

	authResponse := protocol.NewAuthenticationResponse(expectedAuthMethod)
	err := protocol.WriteAuthentication(writer, authResponse)
	if err != nil {
		log.Error("Socks failed to write authentication: %v", err)
		return err
	}
	if server.config.IsPassword() {
		upRequest, err := protocol.ReadUserPassRequest(reader)
		if err != nil {
			log.Error("Socks failed to read username and password: %v", err)
			return err
		}
		status := byte(0)
		if !upRequest.IsValid(server.config.Username, server.config.Password) {
			status = byte(0xFF)
		}
		upResponse := protocol.NewSocks5UserPassResponse(status)
		err = protocol.WriteUserPassResponse(writer, upResponse)
		if err != nil {
			log.Error("Socks failed to write user pass response: %v", err)
			return err
		}
		if status != byte(0) {
			err = errors.NewAuthenticationError(upRequest.AuthDetail())
			log.Warning(err.Error())
			return err
		}
	}

	request, err := protocol.ReadRequest(reader)
	if err != nil {
		log.Error("Socks failed to read request: %v", err)
		return err
	}

	if request.Command == protocol.CmdUdpAssociate && server.config.UDPEnabled {
		return server.handleUDP(reader, writer)
	}

	response := protocol.NewSocks5Response()
	if request.Command == protocol.CmdBind || request.Command == protocol.CmdUdpAssociate {
		response := protocol.NewSocks5Response()
		response.Error = protocol.ErrorCommandNotSupported
		err = protocol.WriteResponse(writer, response)
		if err != nil {
			log.Error("Socks failed to write response: %v", err)
			return err
		}
		log.Warning("Unsupported socks command %d", request.Command)
		return errors.NewInvalidOperationError("Socks command " + strconv.Itoa(int(request.Command)))
	}

	response.Error = protocol.ErrorSuccess

	response.Port = request.Port
	response.AddrType = request.AddrType
	switch response.AddrType {
	case protocol.AddrTypeIPv4:
		copy(response.IPv4[:], request.IPv4[:])
	case protocol.AddrTypeIPv6:
		copy(response.IPv6[:], request.IPv6[:])
	case protocol.AddrTypeDomain:
		response.Domain = request.Domain
	}
	err = protocol.WriteResponse(writer, response)
	if err != nil {
		log.Error("Socks failed to write response: %v", err)
		return err
	}

	dest := request.Destination()
	data, err := v2net.ReadFrom(reader)
	if err != nil {
		return err
	}

	packet := v2net.NewPacket(dest, data, true)
	server.transport(reader, writer, packet)
	return nil
}

func (server *SocksServer) handleUDP(reader *v2net.TimeOutReader, writer io.Writer) error {
	response := protocol.NewSocks5Response()
	response.Error = protocol.ErrorSuccess

	udpAddr := server.getUDPAddr()

	response.Port = udpAddr.Port()
	switch {
	case udpAddr.IsIPv4():
		response.AddrType = protocol.AddrTypeIPv4
		copy(response.IPv4[:], udpAddr.IP())
	case udpAddr.IsIPv6():
		response.AddrType = protocol.AddrTypeIPv6
		copy(response.IPv6[:], udpAddr.IP())
	case udpAddr.IsDomain():
		response.AddrType = protocol.AddrTypeDomain
		response.Domain = udpAddr.Domain()
	}
	err := protocol.WriteResponse(writer, response)
	if err != nil {
		log.Error("Socks failed to write response: %v", err)
		return err
	}

	reader.SetTimeOut(300) /* 5 minutes */
	buffer := make([]byte, 1024)
	reader.Read(buffer)

	return nil
}

func (server *SocksServer) handleSocks4(reader io.Reader, writer io.Writer, auth protocol.Socks4AuthenticationRequest) error {
	result := protocol.Socks4RequestGranted
	if auth.Command == protocol.CmdBind {
		result = protocol.Socks4RequestRejected
	}
	socks4Response := protocol.NewSocks4AuthenticationResponse(result, auth.Port, auth.IP[:])
	writer.Write(socks4Response.ToBytes(nil))

	if result == protocol.Socks4RequestRejected {
		return errors.NewInvalidOperationError("Socks4 command " + strconv.Itoa(int(auth.Command)))
	}

	dest := v2net.NewTCPDestination(v2net.IPAddress(auth.IP[:], auth.Port))
	data, err := v2net.ReadFrom(reader)
	if err != nil {
		return err
	}

	packet := v2net.NewPacket(dest, data, true)
	server.transport(reader, writer, packet)
	return nil
}

func (server *SocksServer) transport(reader io.Reader, writer io.Writer, firstPacket v2net.Packet) {
	ray := server.vPoint.DispatchToOutbound(firstPacket)
	input := ray.InboundInput()
	output := ray.InboundOutput()

	var inputFinish, outputFinish sync.Mutex
	inputFinish.Lock()
	outputFinish.Lock()

	go dumpInput(reader, input, &inputFinish)
	go dumpOutput(writer, output, &outputFinish)
	outputFinish.Lock()
}

func dumpInput(reader io.Reader, input chan<- []byte, finish *sync.Mutex) {
	v2net.ReaderToChan(input, reader)
	finish.Unlock()
	close(input)
}

func dumpOutput(writer io.Writer, output <-chan []byte, finish *sync.Mutex) {
	v2net.ChanToWriter(writer, output)
	finish.Unlock()
}
<|endoftext|>


<commit_before>package parse

type CType interface {
}

type PrimitiveKind int

const (
	Void PrimitiveKind = iota // type is invalid
	Bool
	Char
	Short
	Int
	Long
	LLong
	Float
	Double
	LDouble
	Enum
)

type Primitive struct {
	Kind     PrimitiveKind
	Size     int
	Align    int
	Unsigned bool
}

type Array struct {
	MemberType CType
	Dim        int
}

type Ptr struct {
	PointsTo CType
}

// Struct or union.
type Struct struct {
	Fields []struct {
		Name string
		Type CType
	}
	IsUnion bool
}

type FunctionType struct {
	RetType  CType
	ArgTypes []CType
	ArgNames []string
	IsVarArg bool
}

type ForwardedType struct {
	Type CType
}

// All the primitive C types.

// Misc
var CVoid *Primitive = &Primitive{Void, 0, 0, false}
var CEnum *Primitive = &Primitive{Enum, 4, 4, false}

// Signed
var CChar *Primitive = &Primitive{Char, 0, 0, false}
var CShort *Primitive = &Primitive{Short, 2, 2, false}
var CInt *Primitive = &Primitive{Int, 4, 4, false}
var CLong *Primitive = &Primitive{Long, 8, 8, false}
var CLLong *Primitive = &Primitive{LLong, 8, 8, false}

// Unsigned
var CBool *Primitive = &Primitive{Bool, 1, 1, true}
var CUChar *Primitive = &Primitive{Char, 1, 1, true}
var CUShort *Primitive = &Primitive{Short, 2, 2, true}
var CUInt *Primitive = &Primitive{Int, 4, 4, true}
var CULong *Primitive = &Primitive{Long, 8, 8, true}
var CULLong *Primitive = &Primitive{LLong, 8, 8, true}

// Floats
var CFloat *Primitive = &Primitive{Float, 4, 4, false}
var CDouble *Primitive = &Primitive{Double, 8, 8, false}
var CLDouble *Primitive = &Primitive{LDouble, 8, 8, false}

func IsPtrType(t CType) bool {
	_, ok := t.(*Ptr)
	return ok
}

func IsIntType(t CType) bool {
	prim, ok := t.(*Primitive)
	if !ok {
		return false
	}
	switch prim.Kind {
	case Bool, Short, Int, Long, LLong:
		return true
	default:
		return false
	}
}
<commit_msg>add size and alignment methods<commit_after>package parse

type CType interface {
	GetSize() int
	GetAlign() int
}

type PrimitiveKind int

const (
	Void PrimitiveKind = iota // type is invalid
	Bool
	Char
	Short
	Int
	Long
	LLong
	Float
	Double
	LDouble
	Enum
)

type Primitive struct {
	Kind     PrimitiveKind
	Size     int
	Align    int
	Unsigned bool
}

func (p *Primitive) GetSize() int  { return p.Size }
func (p *Primitive) GetAlign() int { return p.Align }

type Array struct {
	MemberType CType
	Dim        int
}

func (a *Array) GetSize() int  { return a.MemberType.GetSize() * a.Dim }
func (a *Array) GetAlign() int { return a.MemberType.GetAlign() }

type Ptr struct {
	PointsTo CType
}

func (p *Ptr) GetSize() int  { return 8 }
func (p *Ptr) GetAlign() int { return 8 }

// Struct or union.
type Struct struct {
	Fields []struct {
		Name string
		Type CType
	}
	IsUnion bool
}

func (s *Struct) GetSize() int  { return 8 }
func (s *Struct) GetAlign() int { return 8 }

type FunctionType struct {
	RetType  CType
	ArgTypes []CType
	ArgNames []string
	IsVarArg bool
}

func (f *FunctionType) GetSize() int  { panic("internal error") }
func (f *FunctionType) GetAlign() int { panic("internal error") }

type ForwardedType struct {
	Type CType
}

func (f *ForwardedType) GetSize() int  { return f.Type.GetSize() }
func (f *ForwardedType) GetAlign() int { return f.Type.GetAlign() }

// All the primitive C types.

// Misc
var CVoid *Primitive = &Primitive{Void, 0, 0, false}
var CEnum *Primitive = &Primitive{Enum, 4, 4, false}

// Signed
var CChar *Primitive = &Primitive{Char, 0, 0, false}
var CShort *Primitive = &Primitive{Short, 2, 2, false}
var CInt *Primitive = &Primitive{Int, 4, 4, false}
var CLong *Primitive = &Primitive{Long, 8, 8, false}
var CLLong *Primitive = &Primitive{LLong, 8, 8, false}

// Unsigned
var CBool *Primitive = &Primitive{Bool, 1, 1, true}
var CUChar *Primitive = &Primitive{Char, 1, 1, true}
var CUShort *Primitive = &Primitive{Short, 2, 2, true}
var CUInt *Primitive = &Primitive{Int, 4, 4, true}
var CULong *Primitive = &Primitive{Long, 8, 8, true}
var CULLong *Primitive = &Primitive{LLong, 8, 8, true}

// Floats
var CFloat *Primitive = &Primitive{Float, 4, 4, false}
var CDouble *Primitive = &Primitive{Double, 8, 8, false}
var CLDouble *Primitive = &Primitive{LDouble, 8, 8, false}

func IsPtrType(t CType) bool {
	_, ok := t.(*Ptr)
	return ok
}

func IsIntType(t CType) bool {
	prim, ok := t.(*Primitive)
	if !ok {
		return false
	}
	switch prim.Kind {
	case Bool, Short, Int, Long, LLong:
		return true
	default:
		return false
	}
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"io/ioutil"
	"regexp"
	"strconv"
	"strings"

	"golang.org/x/net/context"
	"golang.org/x/oauth2/google"
	"gopkg.in/Iwark/spreadsheet.v2"
)

// Represents the Board members of a Toastmasters meeting.
type Board struct {
	president string
	vpe       string
	vpm       string
	vppr      string
	secretary string
	treasurer string
	saa       string
}

// Factory function using a spreadsheet to fill in Board members.
func NewBoard(sheet *spreadsheet.Sheet) *Board {
	return &Board{
		president: sheet.Columns[1][0].Value,
		vpe:       sheet.Columns[1][1].Value,
		vpm:       sheet.Columns[1][2].Value,
		vppr:      sheet.Columns[1][3].Value,
		secretary: sheet.Columns[1][4].Value,
		treasurer: sheet.Columns[1][5].Value,
		saa:       sheet.Columns[1][6].Value,
	}
}

// Represents the editable fields on a Toastmasters agenda.
type AgendaRoles struct {
	toastmaster       string
	ge                string
	timer             string
	ahCounter         string
	grammarian        string
	tableTopicsMaster string
	jokeMaster        string
	speakers          []*Speaker
	boardMembers      *Board
	futureWeeks       [][]string
}

// Factory function to create agenda roles from a google doc based on the date of the meeting.
func NewAgendaRoles(agendaDate string) (*AgendaRoles, error) {
	spreadsheets, err := fetchSheet()
	if err != nil {
		return &AgendaRoles{}, err
	}

	agendaRoles := &AgendaRoles{
		boardMembers: NewBoard(spreadsheets.boardSheet),
	}

	const speakerCellStart = 7
	const speakerCellEnd = 13
	rolesSheet := spreadsheets.meetingRoles
	for i := range rolesSheet.Columns {
		if rolesSheet.Columns[i][0].Value == agendaDate {
			agendaRoles.toastmaster = rolesSheet.Columns[i][1].Value
			agendaRoles.jokeMaster = rolesSheet.Columns[i][2].Value
			agendaRoles.ge = rolesSheet.Columns[i][3].Value
			agendaRoles.timer = rolesSheet.Columns[i][4].Value
			agendaRoles.ahCounter = rolesSheet.Columns[i][5].Value
			agendaRoles.grammarian = rolesSheet.Columns[i][6].Value

			for j := speakerCellStart; j <= speakerCellEnd; j += 2 {
				agendaRoles.speakers = append(agendaRoles.speakers, NewSpeaker(rolesSheet.Columns[i][j].Value,
					rolesSheet.Columns[i][j+1].Value))
			}

			agendaRoles.tableTopicsMaster = rolesSheet.Columns[i][16].Value
			agendaRoles.futureWeeks = getFutureWeeks(rolesSheet, i)
			break
		}
	}
	return agendaRoles, nil
}

//  Represents a Speaker in a Toastmasters meeting.
type Speaker struct {
	name string
	*Speech
	evaluator string
}

// Helper method that returns the first name of a Speaker.
func (s *Speaker) firstName() string {
	return strings.Split(s.name, " ")[0]
}

// Find the Speaker name, manual and number from a string that looks like "Ann Addicks\nCC #9".
func parseManualAndNumber(speaker string) (string, string, int) {
	re := regexp.MustCompile(`([a-zA-Z]+ [a-zA-Z]+)\n([a-zA-Z]+) #(\d{1,2})`)
	result := re.FindStringSubmatch(speaker)
	name := speaker
	var manual string
	var speechNum int

	if len(result) > 0 {
		name = result[1]
		manual = result[2]
		speechNum, _ = strconv.Atoi(result[3])
	}
	return name, manual, speechNum
}

// Factory function to create a Speaker based on the spreadsheet Speaker and evaluator.
func NewSpeaker(s string, eval string) *Speaker {
	name, manual, number := parseManualAndNumber(s)

	return &Speaker{
		name:      name,
		evaluator: eval,
		Speech:    NewSpeech(manual, number),
	}
}

// Represents the spreadsheet tabs.
type googleDocsSheet struct {
	boardSheet   *spreadsheet.Sheet
	meetingRoles *spreadsheet.Sheet
}

//  GetSheet reads a Google Docs spreadsheet and returns a sheet with roles and another sheet with the Board members.
func fetchSheet() (googleDocsSheet, error) {
	data, err := ioutil.ReadFile("client_secret.json")
	if err != nil {
		return googleDocsSheet{}, errors.New("cannot read client_secret.json")
	}

	conf, err := google.JWTConfigFromJSON(data, spreadsheet.Scope)
	if err != nil {
		return googleDocsSheet{}, errors.New("problem with google.JWTConfigFromJSON(data, s.Scope)")
	}

	client := conf.Client(context.TODO())

	service := spreadsheet.NewServiceWithClient(client)
	s, err := service.FetchSpreadsheet("1CBlORqCzL6YvyAUZTk8jezvhyuDzjjumghwGKk5VIK8")
	if err != nil {
		return googleDocsSheet{}, errors.New("cannot fetch spread sheet: ")
	}

	roles, err := s.SheetByIndex(0)
	if err != nil {
		return googleDocsSheet{}, errors.New("cannot read s by index 0")
	}

	board, err := s.SheetByIndex(1)
	if err != nil {
		return googleDocsSheet{}, errors.New("cannot read s by index 1")
	}

	return googleDocsSheet{boardSheet: board, meetingRoles: roles}, nil
}

// The number of weeks in the future to capture.
const futureWeeks = 4
const numberOfRoles = 17

// GetFutureWeeks finds the next several weeks after the current week based on the constant futureWeeks.
func getFutureWeeks(sheet *spreadsheet.Sheet, thisWeek int) [][]string {
	week := 0
	var nextSchedule = make([][]string, 0, futureWeeks)

	for i := thisWeek + 1; i < len(sheet.Columns) && week <= futureWeeks; i++ {
		nextWeek := make([]string, numberOfRoles)

		for j := 0; j < numberOfRoles; j++ {
			nextWeek[j] = sheet.Columns[i][j].Value
		}
		nextSchedule = append(nextSchedule, nextWeek)
		week++

	}
	return nextSchedule
}
<commit_msg>pulled the length check out of the loop.<commit_after>package main

import (
	"errors"
	"io/ioutil"
	"regexp"
	"strconv"
	"strings"

	"golang.org/x/net/context"
	"golang.org/x/oauth2/google"
	"gopkg.in/Iwark/spreadsheet.v2"
)

// Represents the Board members of a Toastmasters meeting.
type Board struct {
	president string
	vpe       string
	vpm       string
	vppr      string
	secretary string
	treasurer string
	saa       string
}

// Factory function using a spreadsheet to fill in Board members.
func NewBoard(sheet *spreadsheet.Sheet) *Board {
	return &Board{
		president: sheet.Columns[1][0].Value,
		vpe:       sheet.Columns[1][1].Value,
		vpm:       sheet.Columns[1][2].Value,
		vppr:      sheet.Columns[1][3].Value,
		secretary: sheet.Columns[1][4].Value,
		treasurer: sheet.Columns[1][5].Value,
		saa:       sheet.Columns[1][6].Value,
	}
}

// Represents the editable fields on a Toastmasters agenda.
type AgendaRoles struct {
	toastmaster       string
	ge                string
	timer             string
	ahCounter         string
	grammarian        string
	tableTopicsMaster string
	jokeMaster        string
	speakers          []*Speaker
	boardMembers      *Board
	futureWeeks       [][]string
}

// Factory function to create agenda roles from a google doc based on the date of the meeting.
func NewAgendaRoles(agendaDate string) (*AgendaRoles, error) {
	spreadsheets, err := fetchSheet()
	if err != nil {
		return &AgendaRoles{}, err
	}

	agendaRoles := &AgendaRoles{
		boardMembers: NewBoard(spreadsheets.boardSheet),
	}

	const speakerCellStart = 7
	const speakerCellEnd = 13
	rolesSheet := spreadsheets.meetingRoles
	for i := range rolesSheet.Columns {
		if rolesSheet.Columns[i][0].Value == agendaDate {
			agendaRoles.toastmaster = rolesSheet.Columns[i][1].Value
			agendaRoles.jokeMaster = rolesSheet.Columns[i][2].Value
			agendaRoles.ge = rolesSheet.Columns[i][3].Value
			agendaRoles.timer = rolesSheet.Columns[i][4].Value
			agendaRoles.ahCounter = rolesSheet.Columns[i][5].Value
			agendaRoles.grammarian = rolesSheet.Columns[i][6].Value

			for j := speakerCellStart; j <= speakerCellEnd; j += 2 {
				agendaRoles.speakers = append(agendaRoles.speakers, NewSpeaker(rolesSheet.Columns[i][j].Value,
					rolesSheet.Columns[i][j+1].Value))
			}

			agendaRoles.tableTopicsMaster = rolesSheet.Columns[i][16].Value
			agendaRoles.futureWeeks = getFutureWeeks(rolesSheet, i)
			break
		}
	}
	return agendaRoles, nil
}

//  Represents a Speaker in a Toastmasters meeting.
type Speaker struct {
	name string
	*Speech
	evaluator string
}

// Helper method that returns the first name of a Speaker.
func (s *Speaker) firstName() string {
	return strings.Split(s.name, " ")[0]
}

// Find the Speaker name, manual and number from a string that looks like "Ann Addicks\nCC #9".
func parseManualAndNumber(speaker string) (string, string, int) {
	re := regexp.MustCompile(`([a-zA-Z]+ [a-zA-Z]+)\n([a-zA-Z]+) #(\d{1,2})`)
	result := re.FindStringSubmatch(speaker)
	name := speaker
	var manual string
	var speechNum int

	if len(result) > 0 {
		name = result[1]
		manual = result[2]
		speechNum, _ = strconv.Atoi(result[3])
	}
	return name, manual, speechNum
}

// Factory function to create a Speaker based on the spreadsheet Speaker and evaluator.
func NewSpeaker(s string, eval string) *Speaker {
	name, manual, number := parseManualAndNumber(s)

	return &Speaker{
		name:      name,
		evaluator: eval,
		Speech:    NewSpeech(manual, number),
	}
}

// Represents the spreadsheet tabs.
type googleDocsSheet struct {
	boardSheet   *spreadsheet.Sheet
	meetingRoles *spreadsheet.Sheet
}

//  GetSheet reads a Google Docs spreadsheet and returns a sheet with roles and another sheet with the Board members.
func fetchSheet() (googleDocsSheet, error) {
	data, err := ioutil.ReadFile("client_secret.json")
	if err != nil {
		return googleDocsSheet{}, errors.New("cannot read client_secret.json")
	}

	conf, err := google.JWTConfigFromJSON(data, spreadsheet.Scope)
	if err != nil {
		return googleDocsSheet{}, errors.New("problem with google.JWTConfigFromJSON(data, s.Scope)")
	}

	client := conf.Client(context.TODO())

	service := spreadsheet.NewServiceWithClient(client)
	s, err := service.FetchSpreadsheet("1CBlORqCzL6YvyAUZTk8jezvhyuDzjjumghwGKk5VIK8")
	if err != nil {
		return googleDocsSheet{}, errors.New("cannot fetch spread sheet: ")
	}

	roles, err := s.SheetByIndex(0)
	if err != nil {
		return googleDocsSheet{}, errors.New("cannot read s by index 0")
	}

	board, err := s.SheetByIndex(1)
	if err != nil {
		return googleDocsSheet{}, errors.New("cannot read s by index 1")
	}

	return googleDocsSheet{boardSheet: board, meetingRoles: roles}, nil
}

// The number of weeks in the future to capture.
const futureWeeks = 4
const numberOfRoles = 17

// GetFutureWeeks finds the next several weeks after the current week based on the constant futureWeeks.
func getFutureWeeks(sheet *spreadsheet.Sheet, thisWeek int) [][]string {
	week := 0
	var nextSchedule = make([][]string, 0, futureWeeks)
	colLen := len(sheet.Columns)

	for i := thisWeek + 1; i < colLen && week <= futureWeeks; i++ {
		nextWeek := make([]string, numberOfRoles)

		for j := 0; j < numberOfRoles; j++ {
			nextWeek[j] = sheet.Columns[i][j].Value
		}
		nextSchedule = append(nextSchedule, nextWeek)
		week++

	}
	return nextSchedule
}
<|endoftext|>


<commit_before>package parser

import (
	"fmt"
)

// Error defines a compiler parsing error.
type Error struct {
	*Pos
	S string
}

// Error returns the error string.
func (e *Error) Error() string {
	if e.Pos != nil {
		return fmt.Sprintf("%s: %s", e.Pos, e.S)
	}

	return e.S
}
<commit_msg>error<commit_after>package parser

import (
	"fmt"
)

// Error defines a compiler parsing error.
type Error struct {
	*Pos
	S string
}

// Error returns the error string.
func (e *Error) Error() string {
	if e.Pos != nil {
		return fmt.Sprintf("%s: %s", e.Pos, e.S)
	}

	return fmt.Sprintf("error: %s", e.Error())
}
<|endoftext|>


<commit_before>package parser

import (
	"io"
	"net"
	"net/mail"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"text/scanner"
	"unicode"

	"github.com/yuuki/gokc/log"
)

const (
	EOF = 0
)

var SYMBOL_TABLES = map[string]int{
	"{": LB,
	"}": RB,

	"global_defs":                     GLOBALDEFS,
	"notification_email":              NOTIFICATION_EMAIL,
	"notification_email_from":         NOTIFICATION_EMAIL_FROM,
	"smtp_server":                     SMTP_SERVER,
	"smtp_connect_timeout":            SMTP_CONNECT_TIMEOUT,
	"router_id":                       ROUTER_ID,
	"lvs_id":                          LVS_ID,
	"vrrp_mcast_group4":               VRRP_MCAST_GROUP4,
	"vrrp_mcast_group6":               VRRP_MCAST_GROUP6,
	"vrrp_garp_master_delay":          VRRP_GARP_MASTER_DELAY,
	"vrrp_garp_master_repeat":         VRRP_GARP_MASTER_REPEAT,
	"vrrp_garp_master_refresh":        VRRP_GARP_MASTER_REFRESH,
	"vrrp_garp_master_refresh_repeat": VRRP_GARP_MASTER_REFRESH_REPEAT,
	"vrrp_version":                    VRRP_VERSION,

	"static_ipaddress": STATIC_IPADDRESS,
	"static_routes":    STATIC_ROUTES,
	"static_rules":     STATIC_RULES,

	"vrrp_sync_group": VRRP_SYNC_GROUP,
	"group":           GROUP,

	"vrrp_instance":              VRRP_INSTANCE,
	"use_vmac":                   USE_VMAC,
	"version":                    VERSION,
	"vmac_xmit_base":             VMAC_XMIT_BASE,
	"native_ipv6":                NATIVE_IPV6,
	"interface":                  INTERFACE,
	"mcast_src_ip":               MCAST_SRC_IP,
	"unicast_src_ip":             UNICAST_SRC_IP,
	"unicast_peer":               UNICAST_PEER,
	"lvs_sync_daemon_interface":  LVS_SYNC_DAEMON_INTERFACE,
	"virtual_router_id":          VIRTUAL_ROUTER_ID,
	"nopreempt":                  NOPREEMPT,
	"priority":                   PRIORITY,
	"advert_int":                 ADVERT_INT,
	"virtual_ipaddress":          VIRTUAL_IPADDRESS,
	"virtual_ipaddress_excluded": VIRTUAL_IPADDRESS_EXCLUDED,
	"virtual_routes":             VIRTUAL_ROUTES,
	"state":                      STATE,
	"MASTER":                     MASTER,
	"BACKUP":                     BACKUP,
	"garp_master_delay":          GARP_MASTER_DELAY,
	"smtp_alert":                 SMTP_ALERT,
	"authentication":             AUTHENTICATION,
	"auth_type":                  AUTH_TYPE,
	"auth_pass":                  AUTH_PASS,
	"PASS":                       PASS,
	"AH":                         AH,
	"label":                      LABEL,
	"dev":                        DEV,
	"scope":                      SCOPE,
	"site":                       SITE,
	"link":                       LINK,
	"host":                       HOST,
	"nowhere":                    NOWHERE,
	"global":                     GLOBAL,
	"brd":                        BRD,
	"src":                        SRC,
	"from":                       FROM,
	"to":                         TO,
	"via":                        VIA,
	"gw":                         GW,
	"or":                         OR,
	"table":                      TABLE,
	"metric":                     METRIC,
	"blackhole":                  BLACKHOLE,
	"track_interface":            TRACK_INTERFACE,
	"track_script":               TRACK_SCRIPT,
	"dont_track_primary":         DONT_TRACK_PRIMARY,
	"notify_master":              NOTIFY_MASTER,
	"notify_backup":              NOTIFY_BACKUP,
	"notify_fault":               NOTIFY_FAULT,
	"notify_stop":                NOTIFY_STOP,
	"notify":                     NOTIFY,

	"vrrp_script": VRRP_SCRIPT,
	"script":      SCRIPT,
	"interval":    INTERVAL,
	"timeout":     TIMEOUT,
	"fall":        FALL,
	"rise":        RISE,

	"virtual_server_group": VIRTUAL_SERVER_GROUP,
	"fwmark":               FWMARK,

	"virtual_server": VIRTUAL_SERVER,
	"delay_loop":     DELAY_LOOP,
	"lb_algo":        LB_ALGO,
	"lb_kind":        LB_KIND,
	"lvs_sched":      LVS_SCHED,
	"lvs_method":     LVS_METHOD,
	"rr":             RR,
	"wrr":            WRR,
	"lc":             LC,
	"wlc":            WLC,
	"fo":             FO,
	"ovf":            OVF,
	"lblc":           LBLC,
	"lblcr":          LBLCR,
	"sh":             SH,
	"dh":             DH,
	"sed":            SED,
	"nq":             NQ,
	"NAT":            NAT,
	"DR":             DR,
	"TUN":            TUN,
	"persistence_timeout": PERSISTENCE_TIMEOUT,
	"protocol":            PROTOCOL,
	"TCP":                 TCP,
	"UDP":                 UDP,
	"sorry_server":        SORRY_SERVER,
	"real_server":         REAL_SERVER,
	"weight":              WEIGHT,
	"inhibit_on_failure":  INHIBIT_ON_FAILURE,
	"TCP_CHECK":           TCP_CHECK,
	"HTTP_GET":            HTTP_GET,
	"SSL_GET":             SSL_GET,
	"SMTP_CHECK":          SMTP_CHECK,
	"DNS_CHECK":           DNS_CHECK,
	"MISC_CHECK":          MISC_CHECK,
	"url":                 URL,
	"path":                PATH,
	"digest":              DIGEST,
	"status_code":         STATUS_CODE,
	"connect_timeout":     CONNECT_TIMEOUT,
	"connect_port":        CONNECT_PORT,
	"connect_ip":          CONNECT_IP,
	"bindto":              BINDTO,
	"bind_port":           BIND_PORT,
	"retry":               RETRY,
	"helo_name":           HELO_NAME,
	"delay_before_retry":  DELAY_BEFORE_RETRY,
	"type":                TYPE,
	"name":                NAME,
	"misc_path":           MISC_PATH,
	"misc_timeout":        MISC_TIMEOUT,
	"warmup":              WARMUP,
	"misc_dynamic":        MISC_DYNAMIC,
	"nb_get_retry":        NB_GET_RETRY,
	"virtualhost":         VIRTUALHOST,
	"alpha":               ALPHA,
	"omega":               OMEGA,
	"quorum":              QUORUM,
	"hysteresis":          HYSTERESIS,
	"quorum_up":           QUORUM_UP,
	"quorum_down":         QUORUM_DOWN,
}

type Lexer struct {
	scanner     scanner.Scanner
	tokens      []int
	pos         int
	filename    string
	curFilename string
	e           error
}

type Error struct {
	Message  string
	Filename string
	Line     int
	Column   int
}

func (e *Error) Error() string {
	return e.Message
}

func NewLexer(src io.Reader, filename string) *Lexer {
	var lex Lexer
	lex.scanner.Init(src)
	lex.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats | scanner.ScanChars | scanner.ScanRawStrings | scanner.ScanComments | scanner.SkipComments
	lex.scanner.IsIdentRune = isIdentRune
	lex.tokens = []int{}
	lex.filename = filename
	lex.curFilename = filename
	return &lex
}

func isIdentRune(ch rune, i int) bool {
	return ch == '_' || ch == '.' || ch == '/' || ch == ':' || ch == '-' || ch == '+' || ch == '*' || ch == '?' || ch == '=' || ch == '&' || ch == '@' || unicode.IsLetter(ch) || unicode.IsDigit(ch)
}

func (l *Lexer) scanNextToken() (int, string) {
	token := int(l.scanner.Scan())
	s := l.scanner.TokenText()

	for s == "!" || s == "#" {
		l.skipComments()

		token = int(l.scanner.Scan())
		s = l.scanner.TokenText()
	}

	log.Debugf("token text: %s\n", s)

	return token, s
}

func (l *Lexer) skipComments() {
	ch := l.scanner.Next()
	for ch != '\n' && ch >= 0 {
		ch = l.scanner.Next()
	}
}

func (l *Lexer) scanInclude(rawfilename string) error {
	curDir, err := filepath.Abs(".")
	if err != nil {
		return err
	}

	baseDir := filepath.Dir(l.filename)
	os.Chdir(baseDir)
	defer os.Chdir(curDir)

	rawpaths, err := filepath.Glob(filepath.Join(baseDir, rawfilename))
	if err != nil {
		return err
	}

	if len(rawpaths) < 1 {
		log.Infof("warning: %s: No such file or directory", rawfilename)
	}

	prevScanner := l.scanner
	defer func() { l.scanner = prevScanner }()

	for _, rawpath := range rawpaths {
		l.curFilename = rawpath
		log.Verbosef("--> Parsing ... %s\n", rawpath)

		f, err := os.Open(rawpath)
		if err != nil {
			return err
		}

		l.scanner.Init(f)
		l.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats | scanner.ScanChars | scanner.ScanRawStrings | scanner.ScanComments | scanner.SkipComments
		l.scanner.IsIdentRune = isIdentRune
		l.tokenize()

		f.Close()
	}

	return nil
}

func (l *Lexer) Lex(lval *yySymType) int {
	if len(l.tokens) == l.pos {
		return EOF
	}
	token := l.tokens[l.pos]
	l.pos++
	return token
}

func (l *Lexer) tokenize() {
	for {
		token, s := l.scanNextToken()

		for s == "include" {
			token, s = l.scanNextToken()

			if err := l.scanInclude(s); err != nil {
				l.Error(err.Error())
			}

			token, s = l.scanNextToken()
		}

		if token == scanner.EOF {
			break
		}

		if token == scanner.Ident || token == scanner.String {
			token = STRING
		}

		if _, err := strconv.Atoi(s); err == nil {
			token = NUMBER
		}

		if ip := net.ParseIP(s); ip != nil {
			if ip.To4() != nil {
				token = IPV4
			} else if ip.To16() != nil {
				token = IPV6
			} else {
				log.Infof("warning: %s may be IP address?", s)
			}
		}

		if _, _, err := net.ParseCIDR(s); err == nil {
			token = IP_CIDR
		}

		// IPADDR_RANGE(XXX.YYY.ZZZ.WWW-VVV)
		if ss := strings.Split(s, "-"); len(ss) == 2 {
			if net.ParseIP(ss[0]) != nil {
				if ok, _ := regexp.MatchString(`^[\d]{1,3}$`, ss[1]); ok {
					token = IPADDR_RANGE
				}
			}
		}

		if ok, _ := regexp.MatchString(`^[[:xdigit:]]{32}$`, s); ok {
			token = HEX32
		}

		if ok, _ := regexp.MatchString(`/^([[:alnum:]./-_])*`, s); ok {
			token = PATHSTR
		}

		if _, err := mail.ParseAddress(s); err == nil {
			token = EMAIL
		}

		if _, ok := SYMBOL_TABLES[s]; ok {
			token = SYMBOL_TABLES[s]
		}

		l.tokens = append(l.tokens, token)
	}
}

func (l *Lexer) Error(msg string) {
	l.e = &Error{
		Filename: l.curFilename,
		Line:     l.scanner.Line,
		Column:   l.scanner.Column,
		Message:  msg,
	}
}

func Parse(src io.Reader, filename string) error {
	yyErrorVerbose = true
	l := NewLexer(src, filename)
	l.tokenize()
	if ret := yyParse(l); ret != 0 {
		return l.e
	}
	return l.e
}
<commit_msg>Fix include file not found<commit_after>package parser

import (
	"io"
	"net"
	"net/mail"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"text/scanner"
	"unicode"

	"github.com/yuuki/gokc/log"
)

const (
	EOF = 0
)

var SYMBOL_TABLES = map[string]int{
	"{": LB,
	"}": RB,

	"global_defs":                     GLOBALDEFS,
	"notification_email":              NOTIFICATION_EMAIL,
	"notification_email_from":         NOTIFICATION_EMAIL_FROM,
	"smtp_server":                     SMTP_SERVER,
	"smtp_connect_timeout":            SMTP_CONNECT_TIMEOUT,
	"router_id":                       ROUTER_ID,
	"lvs_id":                          LVS_ID,
	"vrrp_mcast_group4":               VRRP_MCAST_GROUP4,
	"vrrp_mcast_group6":               VRRP_MCAST_GROUP6,
	"vrrp_garp_master_delay":          VRRP_GARP_MASTER_DELAY,
	"vrrp_garp_master_repeat":         VRRP_GARP_MASTER_REPEAT,
	"vrrp_garp_master_refresh":        VRRP_GARP_MASTER_REFRESH,
	"vrrp_garp_master_refresh_repeat": VRRP_GARP_MASTER_REFRESH_REPEAT,
	"vrrp_version":                    VRRP_VERSION,

	"static_ipaddress": STATIC_IPADDRESS,
	"static_routes":    STATIC_ROUTES,
	"static_rules":     STATIC_RULES,

	"vrrp_sync_group": VRRP_SYNC_GROUP,
	"group":           GROUP,

	"vrrp_instance":              VRRP_INSTANCE,
	"use_vmac":                   USE_VMAC,
	"version":                    VERSION,
	"vmac_xmit_base":             VMAC_XMIT_BASE,
	"native_ipv6":                NATIVE_IPV6,
	"interface":                  INTERFACE,
	"mcast_src_ip":               MCAST_SRC_IP,
	"unicast_src_ip":             UNICAST_SRC_IP,
	"unicast_peer":               UNICAST_PEER,
	"lvs_sync_daemon_interface":  LVS_SYNC_DAEMON_INTERFACE,
	"virtual_router_id":          VIRTUAL_ROUTER_ID,
	"nopreempt":                  NOPREEMPT,
	"priority":                   PRIORITY,
	"advert_int":                 ADVERT_INT,
	"virtual_ipaddress":          VIRTUAL_IPADDRESS,
	"virtual_ipaddress_excluded": VIRTUAL_IPADDRESS_EXCLUDED,
	"virtual_routes":             VIRTUAL_ROUTES,
	"state":                      STATE,
	"MASTER":                     MASTER,
	"BACKUP":                     BACKUP,
	"garp_master_delay":          GARP_MASTER_DELAY,
	"smtp_alert":                 SMTP_ALERT,
	"authentication":             AUTHENTICATION,
	"auth_type":                  AUTH_TYPE,
	"auth_pass":                  AUTH_PASS,
	"PASS":                       PASS,
	"AH":                         AH,
	"label":                      LABEL,
	"dev":                        DEV,
	"scope":                      SCOPE,
	"site":                       SITE,
	"link":                       LINK,
	"host":                       HOST,
	"nowhere":                    NOWHERE,
	"global":                     GLOBAL,
	"brd":                        BRD,
	"src":                        SRC,
	"from":                       FROM,
	"to":                         TO,
	"via":                        VIA,
	"gw":                         GW,
	"or":                         OR,
	"table":                      TABLE,
	"metric":                     METRIC,
	"blackhole":                  BLACKHOLE,
	"track_interface":            TRACK_INTERFACE,
	"track_script":               TRACK_SCRIPT,
	"dont_track_primary":         DONT_TRACK_PRIMARY,
	"notify_master":              NOTIFY_MASTER,
	"notify_backup":              NOTIFY_BACKUP,
	"notify_fault":               NOTIFY_FAULT,
	"notify_stop":                NOTIFY_STOP,
	"notify":                     NOTIFY,

	"vrrp_script": VRRP_SCRIPT,
	"script":      SCRIPT,
	"interval":    INTERVAL,
	"timeout":     TIMEOUT,
	"fall":        FALL,
	"rise":        RISE,

	"virtual_server_group": VIRTUAL_SERVER_GROUP,
	"fwmark":               FWMARK,

	"virtual_server": VIRTUAL_SERVER,
	"delay_loop":     DELAY_LOOP,
	"lb_algo":        LB_ALGO,
	"lb_kind":        LB_KIND,
	"lvs_sched":      LVS_SCHED,
	"lvs_method":     LVS_METHOD,
	"rr":             RR,
	"wrr":            WRR,
	"lc":             LC,
	"wlc":            WLC,
	"fo":             FO,
	"ovf":            OVF,
	"lblc":           LBLC,
	"lblcr":          LBLCR,
	"sh":             SH,
	"dh":             DH,
	"sed":            SED,
	"nq":             NQ,
	"NAT":            NAT,
	"DR":             DR,
	"TUN":            TUN,
	"persistence_timeout": PERSISTENCE_TIMEOUT,
	"protocol":            PROTOCOL,
	"TCP":                 TCP,
	"UDP":                 UDP,
	"sorry_server":        SORRY_SERVER,
	"real_server":         REAL_SERVER,
	"weight":              WEIGHT,
	"inhibit_on_failure":  INHIBIT_ON_FAILURE,
	"TCP_CHECK":           TCP_CHECK,
	"HTTP_GET":            HTTP_GET,
	"SSL_GET":             SSL_GET,
	"SMTP_CHECK":          SMTP_CHECK,
	"DNS_CHECK":           DNS_CHECK,
	"MISC_CHECK":          MISC_CHECK,
	"url":                 URL,
	"path":                PATH,
	"digest":              DIGEST,
	"status_code":         STATUS_CODE,
	"connect_timeout":     CONNECT_TIMEOUT,
	"connect_port":        CONNECT_PORT,
	"connect_ip":          CONNECT_IP,
	"bindto":              BINDTO,
	"bind_port":           BIND_PORT,
	"retry":               RETRY,
	"helo_name":           HELO_NAME,
	"delay_before_retry":  DELAY_BEFORE_RETRY,
	"type":                TYPE,
	"name":                NAME,
	"misc_path":           MISC_PATH,
	"misc_timeout":        MISC_TIMEOUT,
	"warmup":              WARMUP,
	"misc_dynamic":        MISC_DYNAMIC,
	"nb_get_retry":        NB_GET_RETRY,
	"virtualhost":         VIRTUALHOST,
	"alpha":               ALPHA,
	"omega":               OMEGA,
	"quorum":              QUORUM,
	"hysteresis":          HYSTERESIS,
	"quorum_up":           QUORUM_UP,
	"quorum_down":         QUORUM_DOWN,
}

type Lexer struct {
	scanner     scanner.Scanner
	tokens      []int
	pos         int
	filename    string
	curFilename string
	e           error
}

type Error struct {
	Message  string
	Filename string
	Line     int
	Column   int
}

func (e *Error) Error() string {
	return e.Message
}

func NewLexer(src io.Reader, filename string) *Lexer {
	var lex Lexer
	lex.scanner.Init(src)
	lex.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats | scanner.ScanChars | scanner.ScanRawStrings | scanner.ScanComments | scanner.SkipComments
	lex.scanner.IsIdentRune = isIdentRune
	lex.tokens = []int{}
	lex.filename = filename
	lex.curFilename = filename
	return &lex
}

func isIdentRune(ch rune, i int) bool {
	return ch == '_' || ch == '.' || ch == '/' || ch == ':' || ch == '-' || ch == '+' || ch == '*' || ch == '?' || ch == '=' || ch == '&' || ch == '@' || unicode.IsLetter(ch) || unicode.IsDigit(ch)
}

func (l *Lexer) scanNextToken() (int, string) {
	token := int(l.scanner.Scan())
	s := l.scanner.TokenText()

	for s == "!" || s == "#" {
		l.skipComments()

		token = int(l.scanner.Scan())
		s = l.scanner.TokenText()
	}

	log.Debugf("token text: %s\n", s)

	return token, s
}

func (l *Lexer) skipComments() {
	ch := l.scanner.Next()
	for ch != '\n' && ch >= 0 {
		ch = l.scanner.Next()
	}
}

func (l *Lexer) scanInclude(rawfilename string) error {
	curDir, err := filepath.Abs(".")
	if err != nil {
		return err
	}

	baseDir := filepath.Dir(l.curFilename)
	os.Chdir(baseDir)
	defer os.Chdir(curDir)

	rawpaths, err := filepath.Glob(filepath.Join(baseDir, rawfilename))
	if err != nil {
		return err
	}

	if len(rawpaths) < 1 {
		log.Infof("warning: %s: No such file or directory", rawfilename)
	}

	prevScanner := l.scanner
	defer func() { l.scanner = prevScanner }()

	for _, rawpath := range rawpaths {
		l.curFilename = rawpath
		log.Verbosef("--> Parsing ... %s\n", rawpath)

		f, err := os.Open(rawpath)
		if err != nil {
			return err
		}

		l.scanner.Init(f)
		l.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats | scanner.ScanChars | scanner.ScanRawStrings | scanner.ScanComments | scanner.SkipComments
		l.scanner.IsIdentRune = isIdentRune
		l.tokenize()

		f.Close()
	}

	return nil
}

func (l *Lexer) Lex(lval *yySymType) int {
	if len(l.tokens) == l.pos {
		return EOF
	}
	token := l.tokens[l.pos]
	l.pos++
	return token
}

func (l *Lexer) tokenize() {
	for {
		token, s := l.scanNextToken()

		for s == "include" {
			token, s = l.scanNextToken()

			if err := l.scanInclude(s); err != nil {
				l.Error(err.Error())
			}

			token, s = l.scanNextToken()
		}

		if token == scanner.EOF {
			break
		}

		if token == scanner.Ident || token == scanner.String {
			token = STRING
		}

		if _, err := strconv.Atoi(s); err == nil {
			token = NUMBER
		}

		if ip := net.ParseIP(s); ip != nil {
			if ip.To4() != nil {
				token = IPV4
			} else if ip.To16() != nil {
				token = IPV6
			} else {
				log.Infof("warning: %s may be IP address?", s)
			}
		}

		if _, _, err := net.ParseCIDR(s); err == nil {
			token = IP_CIDR
		}

		// IPADDR_RANGE(XXX.YYY.ZZZ.WWW-VVV)
		if ss := strings.Split(s, "-"); len(ss) == 2 {
			if net.ParseIP(ss[0]) != nil {
				if ok, _ := regexp.MatchString(`^[\d]{1,3}$`, ss[1]); ok {
					token = IPADDR_RANGE
				}
			}
		}

		if ok, _ := regexp.MatchString(`^[[:xdigit:]]{32}$`, s); ok {
			token = HEX32
		}

		if ok, _ := regexp.MatchString(`/^([[:alnum:]./-_])*`, s); ok {
			token = PATHSTR
		}

		if _, err := mail.ParseAddress(s); err == nil {
			token = EMAIL
		}

		if _, ok := SYMBOL_TABLES[s]; ok {
			token = SYMBOL_TABLES[s]
		}

		l.tokens = append(l.tokens, token)
	}
}

func (l *Lexer) Error(msg string) {
	l.e = &Error{
		Filename: l.curFilename,
		Line:     l.scanner.Line,
		Column:   l.scanner.Column,
		Message:  msg,
	}
}

func Parse(src io.Reader, filename string) error {
	yyErrorVerbose = true
	l := NewLexer(src, filename)
	l.tokenize()
	if ret := yyParse(l); ret != 0 {
		return l.e
	}
	return l.e
}
<|endoftext|>


<commit_before>package spyrun

import ( // {{{
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"sync"
	"time"

	"github.com/naoina/toml"
) // }}}

const ( // {{{
	// SpyRunFile convert to target file.
	SpyRunFile = "\\$SPYRUN_FILE"
) // }}}

/**
 * Toml config.
 */
type tomlConfig struct { // {{{
	Spyconf struct {
		Sleep string `toml:"sleep"`
	}
	SpyTables map[string]spyTable `toml:"spys"`
} // }}}

type spyTable struct { // {{{
	File    string `toml:"file"`
	Command string `toml:"command"`
} // }}}

/**
 * Spyrun config.
 */
type spyMap map[string][]*spyst

type spyst struct { // {{{
	filePath   string
	command    string
	modifyTime time.Time
	mu         *sync.Mutex
} // }}}

type spyrun struct { // {{{
	conf tomlConfig
	spym spyMap
} // }}}

// New Create and return *spyrun.
func New() *spyrun { // {{{
	s := new(spyrun)
	s.spym = make(spyMap)
	return s
} // }}}

// Run run spyrun.
func Run(tomlpath string) error { // {{{
	return New().run(tomlpath)
} // }}}

func (s *spyrun) run(tomlpath string) error { // {{{
	var err error

	err = s.loadToml(tomlpath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to parse toml ! %s", err.Error())
		os.Exit(1)
	}

	err = s.createSpyMapFromSpyTables()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to get spys ! %s", err.Error())
		os.Exit(1)
	}

	ch := make(chan *spyst)
	go s.spyFiles(ch)

	for {
		spyst := <-ch
		log.Printf("[%s] is modified !\n", spyst.filePath)
		go s.executeCommand(spyst)
	}

} // }}}

func (s *spyrun) convertSpyVar(file, command string) (string, error) { // {{{
	var err error

	re := regexp.MustCompile(SpyRunFile)

	if matched := re.MatchString(command); matched {
		command = re.ReplaceAllString(command, file)
	}

	return command, err
} // }}}

func (s *spyrun) createSpyMapFromSpyTables() error { // {{{
	var err error

	for k, v := range s.conf.SpyTables {
		s.spym[k] = make([]*spyst, 0)
		files, err := filepath.Glob(v.File)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to search glob pattern. %s", v.File)
			os.Exit(1)
		}
		for _, file := range files {
			spyst := new(spyst)
			spyst.filePath = file
			fi, err := os.Stat(file)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Failed to get FileInfo. %s [%s]", file, err.Error())
				os.Exit(1)
			}
			spyst.modifyTime = fi.ModTime()
			spyst.command, err = s.convertSpyVar(file, v.Command)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Failed to convert spy variable. %s", v.Command)
				os.Exit(1)
			}
			spyst.mu = new(sync.Mutex)
			log.Printf("%s: {file: [%s], command: [%s]}\n", k, spyst.filePath, spyst.command)
			s.spym[k] = append(s.spym[k], spyst)
		}
	}
	return err
} // }}}

func (s *spyrun) loadToml(tomlpath string) error { // {{{
	var err error

	if _, err = os.Stat(tomlpath); err != nil {
		fmt.Fprintf(os.Stderr, "%s is not found !", tomlpath)
		os.Exit(1)
	}

	f, err := os.Open(tomlpath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to open %s", tomlpath)
		os.Exit(1)
	}
	defer f.Close()

	buf, err := ioutil.ReadAll(f)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to load %s", tomlpath)
		os.Exit(1)
	}

	err = toml.Unmarshal(buf, &s.conf)

	return err
} // }}}

func (s *spyrun) spyFiles(ch chan *spyst) { // {{{
	var err error
	var sleep time.Duration
	if s.conf.Spyconf.Sleep != "" {
		sleep, err = time.ParseDuration(s.conf.Spyconf.Sleep)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to parse sleep duration. %v", err)
			os.Exit(1)
		}
	} else {
		sleep = time.Duration(100) * time.Millisecond
	}
	log.Println("sleep:", sleep)
	for {
		for _, spysts := range s.spym {
			for _, spyst := range spysts {
				fi, err := os.Stat(spyst.filePath)
				if err != nil {
					fmt.Fprintf(os.Stderr, "Failed to get FileInfo. %s, [%s]", spyst.filePath, err.Error())
					os.Exit(1)
				}
				if fi.ModTime() != spyst.modifyTime {
					spyst.modifyTime = fi.ModTime()
					ch <- spyst
				}
			}
		}
		time.Sleep(sleep)
	}
} // }}}

func (s *spyrun) executeCommand(spy *spyst) error { // {{{
	var err error
	spy.mu.Lock()
	defer spy.mu.Unlock()
	var cmd *exec.Cmd
	if runtime.GOOS == "windows" {
		cmd = exec.Command("cmd", "/c", spy.command)
	} else {
		cmd = exec.Command("sh", "-c", spy.command)
	}
	log.Printf("Execute command. [%s]", spy.command)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err != nil {
		fmt.Println(err)
	}

	return err
} // }}}
<commit_msg>Do not os.Exit when failed to get os.FileInfo.<commit_after>package spyrun

import ( // {{{
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"sync"
	"time"

	"github.com/naoina/toml"
) // }}}

const ( // {{{
	// SpyRunFile convert to target file.
	SpyRunFile = "\\$SPYRUN_FILE"
) // }}}

/**
 * Toml config.
 */
type tomlConfig struct { // {{{
	Spyconf struct {
		Sleep string `toml:"sleep"`
	}
	SpyTables map[string]spyTable `toml:"spys"`
} // }}}

type spyTable struct { // {{{
	File    string `toml:"file"`
	Command string `toml:"command"`
} // }}}

/**
 * Spyrun config.
 */
type spyMap map[string][]*spyst

type spyst struct { // {{{
	filePath   string
	command    string
	modifyTime time.Time
	mu         *sync.Mutex
} // }}}

type spyrun struct { // {{{
	conf tomlConfig
	spym spyMap
} // }}}

// New Create and return *spyrun.
func New() *spyrun { // {{{
	s := new(spyrun)
	s.spym = make(spyMap)
	return s
} // }}}

// Run run spyrun.
func Run(tomlpath string) error { // {{{
	return New().run(tomlpath)
} // }}}

func (s *spyrun) run(tomlpath string) error { // {{{
	var err error

	err = s.loadToml(tomlpath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to parse toml ! %s", err.Error())
		os.Exit(1)
	}

	err = s.createSpyMapFromSpyTables()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to get spys ! %s", err.Error())
		os.Exit(1)
	}

	ch := make(chan *spyst)
	go s.spyFiles(ch)

	for {
		spyst := <-ch
		log.Printf("[%s] is modified !\n", spyst.filePath)
		go s.executeCommand(spyst)
	}

} // }}}

func (s *spyrun) convertSpyVar(file, command string) (string, error) { // {{{
	var err error

	re := regexp.MustCompile(SpyRunFile)

	if matched := re.MatchString(command); matched {
		command = re.ReplaceAllString(command, file)
	}

	return command, err
} // }}}

func (s *spyrun) createSpyMapFromSpyTables() error { // {{{
	var err error

	for k, v := range s.conf.SpyTables {
		s.spym[k] = make([]*spyst, 0)
		files, err := filepath.Glob(v.File)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to search glob pattern. %s", v.File)
			os.Exit(1)
		}
		for _, file := range files {
			spyst := new(spyst)
			spyst.filePath = file
			fi, err := os.Stat(file)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Failed to get FileInfo. %s [%s]", file, err.Error())
				os.Exit(1)
			}
			spyst.modifyTime = fi.ModTime()
			spyst.command, err = s.convertSpyVar(file, v.Command)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Failed to convert spy variable. %s", v.Command)
				os.Exit(1)
			}
			spyst.mu = new(sync.Mutex)
			log.Printf("%s: {file: [%s], command: [%s]}\n", k, spyst.filePath, spyst.command)
			s.spym[k] = append(s.spym[k], spyst)
		}
	}
	return err
} // }}}

func (s *spyrun) loadToml(tomlpath string) error { // {{{
	var err error

	if _, err = os.Stat(tomlpath); err != nil {
		fmt.Fprintf(os.Stderr, "%s is not found !", tomlpath)
		os.Exit(1)
	}

	f, err := os.Open(tomlpath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to open %s", tomlpath)
		os.Exit(1)
	}
	defer f.Close()

	buf, err := ioutil.ReadAll(f)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to load %s", tomlpath)
		os.Exit(1)
	}

	err = toml.Unmarshal(buf, &s.conf)

	return err
} // }}}

func (s *spyrun) spyFiles(ch chan *spyst) { // {{{
	var err error
	var sleep time.Duration
	if s.conf.Spyconf.Sleep != "" {
		sleep, err = time.ParseDuration(s.conf.Spyconf.Sleep)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to parse sleep duration. %v", err)
			os.Exit(1)
		}
	} else {
		sleep = time.Duration(100) * time.Millisecond
	}
	log.Println("sleep:", sleep)
	for {
		for _, spysts := range s.spym {
			for _, spyst := range spysts {
				fi, err := os.Stat(spyst.filePath)
				if err != nil {
					fmt.Fprintf(os.Stderr, "Failed to get FileInfo. %s, [%s]", spyst.filePath, err.Error())
					spyst.modifyTime = fi.ModTime()
					ch <- spyst
				} else if fi.ModTime() != spyst.modifyTime {
					spyst.modifyTime = fi.ModTime()
					ch <- spyst
				}
			}
		}
		time.Sleep(sleep)
	}
} // }}}

func (s *spyrun) executeCommand(spy *spyst) error { // {{{
	var err error
	spy.mu.Lock()
	defer spy.mu.Unlock()
	var cmd *exec.Cmd
	if runtime.GOOS == "windows" {
		cmd = exec.Command("cmd", "/c", spy.command)
	} else {
		cmd = exec.Command("sh", "-c", spy.command)
	}
	log.Printf("Execute command. [%s]", spy.command)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err = cmd.Run()
	if err != nil {
		fmt.Println(err)
	}

	return err
} // }}}
<|endoftext|>


<commit_before>package shell

import (
	"bufio"
	"connectordb/plugins"
	"connectordb/streamdb"
	"connectordb/streamdb/operator"
	"connectordb/streamdb/users"
	"fmt"
	"os"
	"strings"
)

const (
	Reset   = "\x1b[0m"
	Bold    = "\x1b[1m"
	Black   = "\x1b[30m"
	Red     = "\x1b[31m"
	Green   = "\x1b[32m"
	Yellow  = "\x1b[33m"
	Blue    = "\x1b[34m"
	Magenta = "\x1b[35m"
	Cyan    = "\x1b[36m"
	White   = "\x1b[37m"

	Password = "\x1b[30;40m" // black on black

	cdbshell = `
   ___                      _           ___  ___   ___ _        _ _
  / __|___ _ _  _ _  ___ __| |_ ___ _ _|   \| _ ) / __| |_  ___| | |
 | (__/ _ \ ' \| ' \/ -_) _|  _/ _ \ '_| |) | _ \ \__ \ ' \/ -_) | |
  \___\___/_||_|_||_\___\__|\__\___/_| |___/|___/ |___/_||_\___|_|_|
`
)

func init() {
	// do some sweet plugin registration!
	plugins.Register("shell", usage, startShellExec)
}

func startShellExec(sdb *streamdb.Database, args []string) error {
	StartShell(sdb)
	return nil
}

func usage() {
	fmt.Println(`shell: runs an interactive shell for connectordb

    Currently only basic utilities are supported, but more will come soon.
    This is the command you want to use to add/modify/delete users, view the
    health of your system and/or do administrative tasks.

    In the future it will be possible to script the shell to make administration
    easier.
`)
}

func StartShell(sdb *streamdb.Database) {
	s := CreateShell(sdb)
	s.Cls()
	s.Motd()
	s.Repl()
}

// The shell we're operating under
type Shell struct {
	VersionString   string
	CopyrightString string
	running         bool
	commands        []ShellCommand
	host            string
	reader          *bufio.Reader
	sdb             *streamdb.Database
	operator        operator.Operator
	operatorName    string // can be changed when we do a su
	pwd             string // the present working directory of path commands
}

func (s *Shell) Repl() {
	for s.running {
		fmt.Printf(s.GetPrompt())
		text := s.ReadLine()
		s.RunCommand(text)

	}
}

func (s *Shell) RunCommand(cmdstring string) {
	cmdstring = strings.TrimSpace(cmdstring)
	command := strings.Split(cmdstring, " ")
	if len(command) == 0 {
		return
	}

	for _, cmd := range s.commands {
		if cmd.Name() == command[0] {
			cmd.Execute(s, command)
			return
		}
	}

	fmt.Printf("Command '%v' not found, use 'help' to list available commands\n", cmdstring)
}

func CreateShell(sdb *streamdb.Database) *Shell {
	var s Shell
	s.VersionString = "ConnectorDB Shell v 1.0"
	s.CopyrightString = "Copyright Joseph Lewis & Daniel Kumor 2015"
	s.running = true
	s.commands = []ShellCommand{
		Help{},
		Exit{},
		Clear{},
		GrantAdmin{},
		RevokeAdmin{},
		AddUser{},
		ListUsers{},
		Cat{},
		Su{},
		ListDevices{},
		Passwd{},
		Rm{},
		Ls{}}
	s.host, _ = os.Hostname()
	s.reader = bufio.NewReader(os.Stdin)
	s.sdb = sdb
	s.operator = sdb.Operator
	s.operatorName = "ConnectorDB"
	s.pwd = ""
	return &s
}

func (s *Shell) GetPrompt() string {
	return Bold + Magenta + s.operatorName + White + "@" + Blue + s.host + White + ":" + Cyan + "~" + White + "> " + Reset
}

// Prints a seperator
func (s *Shell) Seperator() {

	for i := 0; i < 80; i++ {
		fmt.Printf("-")
	}

	fmt.Printf("\n")
}

// Clears the screen (on VT100 terminals)
func (s *Shell) Cls() {
	fmt.Printf("\033[H\033[2J\n")
}

// Prints the message of the day
// In the future, we'll use this like UNIX does as a general alert system
func (s *Shell) Motd() {
	fmt.Printf(Blue + cdbshell + Reset)
	fmt.Println()
	fmt.Printf("%v\n", s.VersionString)
	fmt.Printf("%v\n\n", s.CopyrightString)
}

// Reads a line of input from the shell
func (s *Shell) ReadLine() string {
	str, _ := s.reader.ReadString('\n')
	return strings.TrimSpace(str)
}

// Reads a password from the command line
func (s *Shell) ReadPassword() string {
	fmt.Printf("Password: " + Password)
	passwd := s.ReadLine()
	fmt.Println(Reset)
	return passwd
}

// Reads a password from the command line, return will be blank on failure
func (s *Shell) ReadRepeatPassword() string {
	fmt.Printf("Password: " + Password)
	passwd := s.ReadLine()
	fmt.Println(Reset)

	fmt.Printf("Repeat Password: " + Password)
	passwd2 := s.ReadLine()
	fmt.Println(Reset)

	if passwd != passwd2 {
		fmt.Println(Yellow + "Passwords did not match" + Reset)
		return ""
	}

	return passwd
}

// Prints an error if it exists. Returns true if printed, false if not
func (s *Shell) PrintError(err error) bool {
	if err != nil {
		fmt.Printf(Red+"Error: %v\n"+Reset, err.Error())
	}

	return err != nil
}

// Reads the user, device and stream at a path
func (s *Shell) ReadPath(path string) (usr *users.User, dev *users.Device, stream *operator.Stream) {
	usr, _ = s.operator.ReadUser(path)
	dev, _ = s.operator.ReadDevice(path)
	stream, _ = s.operator.ReadStream(path)

	return usr, dev, stream
}

// prepends the current working place to the give path
func (s *Shell) ResolvePath(path string) string {
	return s.pwd + path
}

// The ShellCommand is an internal command within our internal shell.
type ShellCommand interface {
	// Returns the help string associated with this command.
	Help() string

	// Returns the help for a specific command
	Usage() string

	// Execute the command with the given arguments
	Execute(shell *Shell, args []string)

	// Returns the name of this shell command, should be all lower case
	Name() string
}

// The help command
type Help struct {
}

func (h Help) Help() string {
	return "Prints this dialog"
}

func (h Help) Usage() string {
	return `Displays help information about the built in commands.

	Usage: help [commandname]

	The optional command name will show more detailed information about a given
	command.
`
}

func (h Help) Execute(shell *Shell, args []string) {
	if len(args) == 2 {
		for _, cmd := range shell.commands {
			if cmd.Name() == args[1] {
				fmt.Println(Bold)
				fmt.Printf("%s Help\n"+Reset, args[1])
				fmt.Println("")
				fmt.Printf(cmd.Usage())
				return
			}
		}
		fmt.Printf(Red+"%s not found, listing known commands:\n"+Reset, args[1])
	}

	fmt.Println(Bold)
	fmt.Printf("ConnectorDB Shell Help\n" + Reset)
	fmt.Println("")

	for _, cmd := range shell.commands {
		fmt.Printf("%v\t- %v\n", cmd.Name(), cmd.Help())
	}
	fmt.Println("")
	fmt.Println("Use 'help [commandname]' to show help for a specific command.")
}

func (h Help) Name() string {
	return "help"
}
<commit_msg>Cleared line after password input to clean up security.<commit_after>package shell

import (
	"bufio"
	"connectordb/plugins"
	"connectordb/streamdb"
	"connectordb/streamdb/operator"
	"connectordb/streamdb/users"
	"fmt"
	"os"
	"strings"
)

const (
	Reset   = "\x1b[0m"
	Bold    = "\x1b[1m"
	Black   = "\x1b[30m"
	Red     = "\x1b[31m"
	Green   = "\x1b[32m"
	Yellow  = "\x1b[33m"
	Blue    = "\x1b[34m"
	Magenta = "\x1b[35m"
	Cyan    = "\x1b[36m"
	White   = "\x1b[37m"

	Password      = "\033[30;40m" // black on black
	ClearLastLine = "\033[1A\033[2K\033[1A"

	cdbshell = `
   ___                      _           ___  ___   ___ _        _ _
  / __|___ _ _  _ _  ___ __| |_ ___ _ _|   \| _ ) / __| |_  ___| | |
 | (__/ _ \ ' \| ' \/ -_) _|  _/ _ \ '_| |) | _ \ \__ \ ' \/ -_) | |
  \___\___/_||_|_||_\___\__|\__\___/_| |___/|___/ |___/_||_\___|_|_|
`
)

func init() {
	// do some sweet plugin registration!
	plugins.Register("shell", usage, startShellExec)
}

func startShellExec(sdb *streamdb.Database, args []string) error {
	StartShell(sdb)
	return nil
}

func usage() {
	fmt.Println(`shell: runs an interactive shell for connectordb

    Currently only basic utilities are supported, but more will come soon.
    This is the command you want to use to add/modify/delete users, view the
    health of your system and/or do administrative tasks.

    In the future it will be possible to script the shell to make administration
    easier.
`)
}

func StartShell(sdb *streamdb.Database) {
	s := CreateShell(sdb)
	s.Cls()
	s.Motd()
	s.Repl()
}

// The shell we're operating under
type Shell struct {
	VersionString   string
	CopyrightString string
	running         bool
	commands        []ShellCommand
	host            string
	reader          *bufio.Reader
	sdb             *streamdb.Database
	operator        operator.Operator
	operatorName    string // can be changed when we do a su
	pwd             string // the present working directory of path commands
}

func (s *Shell) Repl() {
	for s.running {
		fmt.Printf(s.GetPrompt())
		text := s.ReadLine()
		s.RunCommand(text)

	}
}

func (s *Shell) RunCommand(cmdstring string) {
	cmdstring = strings.TrimSpace(cmdstring)
	command := strings.Split(cmdstring, " ")
	if len(command) == 0 {
		return
	}

	for _, cmd := range s.commands {
		if cmd.Name() == command[0] {
			cmd.Execute(s, command)
			return
		}
	}

	fmt.Printf("Command '%v' not found, use 'help' to list available commands\n", cmdstring)
}

func CreateShell(sdb *streamdb.Database) *Shell {
	var s Shell
	s.VersionString = "ConnectorDB Shell v 1.0"
	s.CopyrightString = "Copyright Joseph Lewis & Daniel Kumor 2015"
	s.running = true
	s.commands = []ShellCommand{
		Help{},
		Exit{},
		Clear{},
		GrantAdmin{},
		RevokeAdmin{},
		AddUser{},
		ListUsers{},
		Cat{},
		Su{},
		ListDevices{},
		Passwd{},
		Rm{},
		Ls{}}
	s.host, _ = os.Hostname()
	s.reader = bufio.NewReader(os.Stdin)
	s.sdb = sdb
	s.operator = sdb.Operator
	s.operatorName = "ConnectorDB"
	s.pwd = ""
	return &s
}

func (s *Shell) GetPrompt() string {
	return Bold + Magenta + s.operatorName + White + "@" + Blue + s.host + White + ":" + Cyan + "~" + White + "> " + Reset
}

// Prints a seperator
func (s *Shell) Seperator() {

	for i := 0; i < 80; i++ {
		fmt.Printf("-")
	}

	fmt.Printf("\n")
}

// Clears the screen (on VT100 terminals)
func (s *Shell) Cls() {
	fmt.Printf("\033[H\033[2J\n")
}

// Prints the message of the day
// In the future, we'll use this like UNIX does as a general alert system
func (s *Shell) Motd() {
	fmt.Printf(Blue + cdbshell + Reset)
	fmt.Println()
	fmt.Printf("%v\n", s.VersionString)
	fmt.Printf("%v\n\n", s.CopyrightString)
}

// Reads a line of input from the shell
func (s *Shell) ReadLine() string {
	str, _ := s.reader.ReadString('\n')
	return strings.TrimSpace(str)
}

// Reads a password from the command line
func (s *Shell) ReadPassword() string {
	fmt.Printf("Password: " + Password)
	passwd := s.ReadLine()
	fmt.Println(Reset + ClearLastLine)
	return passwd
}

// Reads a password from the command line, return will be blank on failure
func (s *Shell) ReadRepeatPassword() string {
	fmt.Printf("Password: " + Password)
	passwd := s.ReadLine()
	fmt.Println(Reset + ClearLastLine)

	fmt.Printf("Repeat Password: " + Password)
	passwd2 := s.ReadLine()
	fmt.Println(Reset + ClearLastLine)

	if passwd != passwd2 {
		fmt.Println(Yellow + "Passwords did not match" + Reset)
		return ""
	}

	return passwd
}

// Prints an error if it exists. Returns true if printed, false if not
func (s *Shell) PrintError(err error) bool {
	if err != nil {
		fmt.Printf(Red+"Error: %v\n"+Reset, err.Error())
	}

	return err != nil
}

// Reads the user, device and stream at a path
func (s *Shell) ReadPath(path string) (usr *users.User, dev *users.Device, stream *operator.Stream) {
	usr, _ = s.operator.ReadUser(path)
	dev, _ = s.operator.ReadDevice(path)
	stream, _ = s.operator.ReadStream(path)

	return usr, dev, stream
}

// prepends the current working place to the give path
func (s *Shell) ResolvePath(path string) string {
	return s.pwd + path
}

// The ShellCommand is an internal command within our internal shell.
type ShellCommand interface {
	// Returns the help string associated with this command.
	Help() string

	// Returns the help for a specific command
	Usage() string

	// Execute the command with the given arguments
	Execute(shell *Shell, args []string)

	// Returns the name of this shell command, should be all lower case
	Name() string
}

// The help command
type Help struct {
}

func (h Help) Help() string {
	return "Prints this dialog"
}

func (h Help) Usage() string {
	return `Displays help information about the built in commands.

	Usage: help [commandname]

	The optional command name will show more detailed information about a given
	command.
`
}

func (h Help) Execute(shell *Shell, args []string) {
	if len(args) == 2 {
		for _, cmd := range shell.commands {
			if cmd.Name() == args[1] {
				fmt.Println(Bold)
				fmt.Printf("%s Help\n"+Reset, args[1])
				fmt.Println("")
				fmt.Printf(cmd.Usage())
				return
			}
		}
		fmt.Printf(Red+"%s not found, listing known commands:\n"+Reset, args[1])
	}

	fmt.Println(Bold)
	fmt.Printf("ConnectorDB Shell Help\n" + Reset)
	fmt.Println("")

	for _, cmd := range shell.commands {
		fmt.Printf("%v\t- %v\n", cmd.Name(), cmd.Help())
	}
	fmt.Println("")
	fmt.Println("Use 'help [commandname]' to show help for a specific command.")
}

func (h Help) Name() string {
	return "help"
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"sync"
)

func load() <-chan []string {
	out := make(chan []string)

	go func() {
		// out <- []string{"111", "222", "333"}
		// out <- []string{"444", "555", "666"}
		// out <- []string{"777", "888", "999"}

		for i := 0; i < 10; i++ {
			out <- []string{fmt.Sprintf("%d", i)}
		}
		close(out)
	}()

	return out
}

func process(in <-chan []string) <-chan string {
	var wg sync.WaitGroup
	wg.Add(4)

	out := make(chan string)

	work := func() {
		for str := range in {
			for _, val := range str {
				val = val + "!"
				out <- val
			}
		}
		wg.Done()
	}

	go func() {
		for i := 0; i < 4; i++ {
			go work()
		}
	}()

	go func() {
		wg.Wait()
		close(out)
	}()

	return out
}

func save(in <-chan string) <-chan struct{} {
	done := make(chan struct{})

	go func() {
		defer close(done)

		for val := range in {
			fmt.Printf("%#v\n", val)
		}
	}()

	return done
}

func main() {
	in := load()

	out := process(in)

	<-save(out)
}
<commit_msg>remove comments<commit_after>package main

import (
	"fmt"
	"sync"
)

func load() <-chan []string {
	out := make(chan []string)

	go func() {
		for i := 0; i < 10; i++ {
			out <- []string{fmt.Sprintf("%d", i)}
		}
		close(out)
	}()

	return out
}

func process(in <-chan []string) <-chan string {
	var wg sync.WaitGroup
	wg.Add(4)

	out := make(chan string)

	work := func() {
		for str := range in {
			for _, val := range str {
				val = val + "!"
				out <- val
			}
		}
		wg.Done()
	}

	go func() {
		for i := 0; i < 4; i++ {
			go work()
		}
	}()

	go func() {
		wg.Wait()
		close(out)
	}()

	return out
}

func save(in <-chan string) <-chan struct{} {
	done := make(chan struct{})

	go func() {
		defer close(done)

		for val := range in {
			fmt.Printf("%#v\n", val)
		}
	}()

	return done
}

func main() {
	in := load()

	out := process(in)

	<-save(out)
}
<|endoftext|>


<commit_before>package pdf

import (
	"os"
	"testing"

	wk "github.com/SebastiaanKlippert/go-wkhtmltopdf"
)

func createConfig() *ConfigPDF {
	config := ConfigPDF{
		PageSize:    "",
		Orientation: wk.OrientationPortrait,
		Dpi:         300,
		Grayscale:   true,
	}

	return &config
}

func createPDFFromURL(url, output string, config *ConfigPDF) {
	cr := CreateFromURL{
		URL:       url,
		ConfigPDF: config,
	}
	NewPDFGenerator(&cr, output)
}

func createPDFFromFile(filePath, output string, config *ConfigPDF) {
	cr := CreateFromFile{
		FilePath:  filePath,
		ConfigPDF: config,
	}
	NewPDFGenerator(&cr, output)
}

// Though prefix is Test, actually it's just Example
func TestNewPDFGenerator_FromURL(t *testing.T) {
	//2.35s
	url := "https://godoc.org/github.com/SebastiaanKlippert/go-wkhtmltopdf"
	output := "from_url.pdf"

	createPDFFromURL(url, output, createConfig())
}

// Though prefix is Test, actually it's just Example
func TestNewPDFGenerator_FromFile(t *testing.T) {
	//1.47s
	path := os.Getenv("GOPATH") + "/src/github.com/hiromaily/golibs/pdf/cmd/"
	filePath := path + "testfiles/tables/index.html"
	output := "from_file.pdf"

	createPDFFromFile(filePath, output, createConfig())
}
<commit_msg>added skip<commit_after>package pdf

import (
	"os"
	"testing"

	wk "github.com/SebastiaanKlippert/go-wkhtmltopdf"
)

func createConfig() *ConfigPDF {
	config := ConfigPDF{
		PageSize:    "",
		Orientation: wk.OrientationPortrait,
		Dpi:         300,
		Grayscale:   true,
	}

	return &config
}

func createPDFFromURL(url, output string, config *ConfigPDF) {
	cr := CreateFromURL{
		URL:       url,
		ConfigPDF: config,
	}
	NewPDFGenerator(&cr, output)
}

func createPDFFromFile(filePath, output string, config *ConfigPDF) {
	cr := CreateFromFile{
		FilePath:  filePath,
		ConfigPDF: config,
	}
	NewPDFGenerator(&cr, output)
}

// Though prefix is Test, actually it's just Example
func TestNewPDFGenerator_FromURL(t *testing.T) {
	t.SkipNow()
	//2.35s
	url := "https://godoc.org/github.com/SebastiaanKlippert/go-wkhtmltopdf"
	output := "from_url.pdf"

	createPDFFromURL(url, output, createConfig())
}

// Though prefix is Test, actually it's just Example
func TestNewPDFGenerator_FromFile(t *testing.T) {
	t.SkipNow()
	//1.47s
	path := os.Getenv("GOPATH") + "/src/github.com/hiromaily/golibs/pdf/cmd/"
	filePath := path + "testfiles/tables/index.html"
	output := "from_file.pdf"

	createPDFFromFile(filePath, output, createConfig())
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"math/rand"
	"strings"
	"time"
)

const (
	HEIGHT       = 80
	WIDTH        = 180
	UPDATELENGTH = 30000
	ALIVE        = '*'
	DEAD         = ' '
)

var (
	board         = [HEIGHT][WIDTH]int{}
	weightedarray = [10]int{0, 0, 0, 0, 0, 0, 0, 1, 1}
)

func genBoard(board [HEIGHT][WIDTH]int) {
	for x := 0; x < HEIGHT; x++ {
		for y := 0; y < WIDTH; y++ {
			board[x][y] = weightedarray[rand.Intn(10)]
		}
	}
}

func copyBoard(newB [HEIGHT][WIDTH]int, oldB [HEIGHT][WIDTH]int) {
	for x := 0; x < HEIGHT; x++ {
		for y := 0; y < WIDTH; y++ {
			newB[x][y] = oldB[x][y]
		}
	}
}

func clearscreen() {
	fmt.Print(strings.Repeat(string(rune(10)), WIDTH*HEIGHT))
}

func updateBoard(board [HEIGHT][WIDTH]int) {
	var next_board [HEIGHT][WIDTH]int
	copyBoard(next_board, board)
	for x := 0; x < HEIGHT; x++ {
		for y := 0; y < WIDTH; y++ {
			aliveN := 0
			neighbours := []int{
				board[x-1][y+1],
				board[x][y+1],
				board[x+1][y+1],
				board[x+1][y],
				board[x+1][y-1],
				board[x][y-1],
				board[x-1][y-1],
				board[x-1][y],
			}

			for _, cell := range neighbours {
				if cell > 0 {
					aliveN++
				}
			}
			/*
			  Rules
			  =====

			  1. Any live cell with fewer than two live neighbours
			  dies, as if caused by under-population.

			  2. Any live cell with two or three live neighbours lives
			  on to the next generation.

			  3. Any live cell with more than three live neighbours
			  dies, as if by overcrowding.

			  4. Any dead cell with exactly three live neighbours
			  becomes a live cell, as if by reproduction.
			*/
			if board[x][y] == 1 && aliveN < 2 {
				next_board[x][y] = 0
				continue
			}
			if board[x][y] == 1 && (aliveN == 2 || aliveN == 3) {
				continue
			}
			if board[x][y] == 1 && aliveN > 3 {
				next_board[x][y] = 0
				continue
			}
			if board[x][y] != 1 && aliveN == 3 {
				next_board[x][y] = 1
				continue
			}
		}
	}
	copyBoard(board, next_board)
}

func drawBoard(board [HEIGHT][WIDTH]int) {
	for x := 0; x < HEIGHT; x++ {
		for y := 0; y < WIDTH; y++ {
			if board[x][y] == 0 {
				fmt.Print("0")
			} else {
				fmt.Print("X")
			}
		}
		fmt.Println()
	}
}

func checkbounds(x, y int) bool {
	if x+1 >= HEIGHT || x-1 <= 0 {
		return false
	}
	if y+1 >= WIDTH || y-1 <= 0 {
		return false
	}
	return true
}

func main() {
	genBoard(&board)
	drawBoard(board)
	for {
		time.Sleep(10000000)
		updateBoard(board)
		drawBoard(board)
		clearscreen()
	}
}
<commit_msg>Made the board smaller.<commit_after>package main

import (
	"fmt"
	"math/rand"
	"strings"
	"time"
)

const (
	HEIGHT       = 40
	WIDTH        = 80
	UPDATELENGTH = 30000
	ALIVE        = '*'
	DEAD         = ' '
)

var (
	board         = [HEIGHT][WIDTH]int{}
	weightedarray = [10]int{0, 0, 0, 0, 0, 0, 0, 1, 1}
)

func genBoard(board [HEIGHT][WIDTH]int) {
	for x := 0; x < HEIGHT; x++ {
		for y := 0; y < WIDTH; y++ {
			board[x][y] = weightedarray[rand.Intn(10)]
		}
	}
}

func copyBoard(newB [HEIGHT][WIDTH]int, oldB [HEIGHT][WIDTH]int) {
	for x := 0; x < HEIGHT; x++ {
		for y := 0; y < WIDTH; y++ {
			newB[x][y] = oldB[x][y]
		}
	}
}

func clearscreen() {
	fmt.Print(strings.Repeat(string(rune(10)), WIDTH*HEIGHT))
}

func updateBoard(board [HEIGHT][WIDTH]int) {
	var next_board [HEIGHT][WIDTH]int
	copyBoard(next_board, board)
	for x := 0; x < HEIGHT; x++ {
		for y := 0; y < WIDTH; y++ {
			aliveN := 0
			neighbours := []int{
				board[x-1][y+1],
				board[x][y+1],
				board[x+1][y+1],
				board[x+1][y],
				board[x+1][y-1],
				board[x][y-1],
				board[x-1][y-1],
				board[x-1][y],
			}

			for _, cell := range neighbours {
				if cell > 0 {
					aliveN++
				}
			}
			/*
			  Rules
			  =====

			  1. Any live cell with fewer than two live neighbours
			  dies, as if caused by under-population.

			  2. Any live cell with two or three live neighbours lives
			  on to the next generation.

			  3. Any live cell with more than three live neighbours
			  dies, as if by overcrowding.

			  4. Any dead cell with exactly three live neighbours
			  becomes a live cell, as if by reproduction.
			*/
			if board[x][y] == 1 && aliveN < 2 {
				next_board[x][y] = 0
				continue
			}
			if board[x][y] == 1 && (aliveN == 2 || aliveN == 3) {
				continue
			}
			if board[x][y] == 1 && aliveN > 3 {
				next_board[x][y] = 0
				continue
			}
			if board[x][y] != 1 && aliveN == 3 {
				next_board[x][y] = 1
				continue
			}
		}
	}
	copyBoard(board, next_board)
}

func drawBoard(board [HEIGHT][WIDTH]int) {
	for x := 0; x < HEIGHT; x++ {
		for y := 0; y < WIDTH; y++ {
			if board[x][y] == 0 {
				fmt.Print("0")
			} else {
				fmt.Print("X")
			}
		}
		fmt.Println()
	}
}

func checkbounds(x, y int) bool {
	if x+1 >= HEIGHT || x-1 <= 0 {
		return false
	}
	if y+1 >= WIDTH || y-1 <= 0 {
		return false
	}
	return true
}

func main() {
	genBoard(&board)
	drawBoard(board)
	for {
		time.Sleep(10000000)
		updateBoard(board)
		drawBoard(board)
		clearscreen()
	}
}
<|endoftext|>